Skip to content

Commit

Permalink
Merge branch '1.5.x'
Browse files Browse the repository at this point in the history
  • Loading branch information
wilkinsona committed Apr 10, 2017
2 parents b099471 + 035cbd9 commit aacdeae
Showing 1 changed file with 92 additions and 46 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@

package org.springframework.boot.autoconfigure.condition;

import java.security.AccessControlException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
Expand Down Expand Up @@ -90,53 +91,30 @@ private ConditionOutcome[] getOutcomes(String[] autoConfigurationClasses,
// additional thread seems to offer the best performance. More threads make
// things worse
int split = autoConfigurationClasses.length / 2;
GetOutcomesThread thread = new GetOutcomesThread(autoConfigurationClasses, 0,
split, autoConfigurationMetadata);
thread.start();
ConditionOutcome[] secondHalf = getOutcomes(autoConfigurationClasses, split,
autoConfigurationClasses.length, autoConfigurationMetadata);
try {
thread.join();
}
catch (InterruptedException ex) {
Thread.currentThread().interrupt();
}
ConditionOutcome[] firstHalf = thread.getResult();
OutcomesResolver firstHalfResolver = createOutcomesResolver(
autoConfigurationClasses, 0, split, autoConfigurationMetadata);
OutcomesResolver secondHalfResolver = new StandardOutcomesResolver(
autoConfigurationClasses, split, autoConfigurationClasses.length,
autoConfigurationMetadata, this.beanClassLoader);
ConditionOutcome[] secondHalf = secondHalfResolver.resolveOutcomes();
ConditionOutcome[] firstHalf = firstHalfResolver.resolveOutcomes();
ConditionOutcome[] outcomes = new ConditionOutcome[autoConfigurationClasses.length];
System.arraycopy(firstHalf, 0, outcomes, 0, firstHalf.length);
System.arraycopy(secondHalf, 0, outcomes, split, secondHalf.length);
return outcomes;
}

private ConditionOutcome[] getOutcomes(final String[] autoConfigurationClasses,
private OutcomesResolver createOutcomesResolver(String[] autoConfigurationClasses,
int start, int end, AutoConfigurationMetadata autoConfigurationMetadata) {
ConditionOutcome[] outcomes = new ConditionOutcome[end - start];
for (int i = start; i < end; i++) {
String autoConfigurationClass = autoConfigurationClasses[i];
Set<String> candidates = autoConfigurationMetadata
.getSet(autoConfigurationClass, "ConditionalOnClass");
if (candidates != null) {
outcomes[i - start] = getOutcome(candidates);
}
}
return outcomes;
}

private ConditionOutcome getOutcome(Set<String> candidates) {
OutcomesResolver outcomesResolver = new StandardOutcomesResolver(
autoConfigurationClasses, start, end, autoConfigurationMetadata,
this.beanClassLoader);
try {
List<String> missing = getMatches(candidates, MatchType.MISSING,
this.beanClassLoader);
if (!missing.isEmpty()) {
return ConditionOutcome
.noMatch(ConditionMessage.forCondition(ConditionalOnClass.class)
.didNotFind("required class", "required classes")
.items(Style.QUOTE, missing));
}
return new ThreadedOutcomesResolver(outcomesResolver);
}
catch (Exception ex) {
// We'll get another chance later
catch (AccessControlException ex) {
return outcomesResolver;
}
return null;
}

@Override
Expand Down Expand Up @@ -262,7 +240,45 @@ private static Class<?> forName(String className, ClassLoader classLoader)

}

private class GetOutcomesThread extends Thread {
private interface OutcomesResolver {

ConditionOutcome[] resolveOutcomes();

}

private static final class ThreadedOutcomesResolver implements OutcomesResolver {

private final Thread thread;

private volatile ConditionOutcome[] outcomes;

private ThreadedOutcomesResolver(final OutcomesResolver outcomesResolver) {
this.thread = new Thread(new Runnable() {

@Override
public void run() {
ThreadedOutcomesResolver.this.outcomes = outcomesResolver
.resolveOutcomes();
}

});
this.thread.start();
}

@Override
public ConditionOutcome[] resolveOutcomes() {
try {
this.thread.join();
}
catch (InterruptedException ex) {
Thread.currentThread().interrupt();
}
return this.outcomes;
}

}

private final class StandardOutcomesResolver implements OutcomesResolver {

private final String[] autoConfigurationClasses;

Expand All @@ -272,25 +288,55 @@ private class GetOutcomesThread extends Thread {

private final AutoConfigurationMetadata autoConfigurationMetadata;

private ConditionOutcome[] outcomes;
private final ClassLoader beanClassLoader;

GetOutcomesThread(String[] autoConfigurationClasses, int start, int end,
AutoConfigurationMetadata autoConfigurationMetadata) {
private StandardOutcomesResolver(String[] autoConfigurationClasses, int start,
int end, AutoConfigurationMetadata autoConfigurationMetadata,
ClassLoader beanClassLoader) {
this.autoConfigurationClasses = autoConfigurationClasses;
this.start = start;
this.end = end;
this.autoConfigurationMetadata = autoConfigurationMetadata;
this.beanClassLoader = beanClassLoader;
}

@Override
public void run() {
this.outcomes = getOutcomes(this.autoConfigurationClasses, this.start,
this.end, this.autoConfigurationMetadata);
public ConditionOutcome[] resolveOutcomes() {
return getOutcomes(this.autoConfigurationClasses, this.start, this.end,
this.autoConfigurationMetadata);
}

public ConditionOutcome[] getResult() {
return this.outcomes;
private ConditionOutcome[] getOutcomes(final String[] autoConfigurationClasses,
int start, int end, AutoConfigurationMetadata autoConfigurationMetadata) {
ConditionOutcome[] outcomes = new ConditionOutcome[end - start];
for (int i = start; i < end; i++) {
String autoConfigurationClass = autoConfigurationClasses[i];
Set<String> candidates = autoConfigurationMetadata
.getSet(autoConfigurationClass, "ConditionalOnClass");
if (candidates != null) {
outcomes[i - start] = getOutcome(candidates);
}
}
return outcomes;
}

private ConditionOutcome getOutcome(Set<String> candidates) {
try {
List<String> missing = getMatches(candidates, MatchType.MISSING,
this.beanClassLoader);
if (!missing.isEmpty()) {
return ConditionOutcome.noMatch(
ConditionMessage.forCondition(ConditionalOnClass.class)
.didNotFind("required class", "required classes")
.items(Style.QUOTE, missing));
}
}
catch (Exception ex) {
// We'll get another chance later
}
return null;
}

}

}

0 comments on commit aacdeae

Please sign in to comment.