in core/optaplanner-core-impl/src/main/java/org/optaplanner/core/impl/score/director/ScoreDirectorFactoryFactory.java [86:191]
protected AbstractScoreDirectorFactory<Solution_, Score_> decideMultipleScoreDirectorFactories(
ClassLoader classLoader, SolutionDescriptor<Solution_> solutionDescriptor, EnvironmentMode environmentMode) {
// Load all known Score Director Factories via SPI.
ServiceLoader<ScoreDirectorFactoryService> scoreDirectorFactoryServiceLoader =
ServiceLoader.load(ScoreDirectorFactoryService.class);
Map<ScoreDirectorType, Supplier<AbstractScoreDirectorFactory<Solution_, Score_>>> scoreDirectorFactorySupplierMap =
new EnumMap<>(ScoreDirectorType.class);
boolean isBavet = false;
for (ScoreDirectorFactoryService<Solution_, Score_> service : scoreDirectorFactoryServiceLoader) {
Supplier<AbstractScoreDirectorFactory<Solution_, Score_>> factory =
service.buildScoreDirectorFactory(classLoader, solutionDescriptor, config, environmentMode);
if (service.getSupportedScoreDirectorType() == CONSTRAINT_STREAMS) {
/*
* CS-D will be available if on the classpath and user did not request BAVET.
* CS-B will be available if on the classpath and user did not request DROOLS.
* The following logic deals with the decision of which CS impl to pick if both available.
*/
switch (service.getPriority()) {
case Integer.MAX_VALUE:
if (config.getConstraintStreamImplType() == BAVET) {
// Drools should be skipped.
continue;
} else {
// Drools will be registered as the CS impl.
isBavet = false;
}
break;
case Integer.MIN_VALUE:
if (scoreDirectorFactorySupplierMap.containsKey(CONSTRAINT_STREAMS)) {
/*
* We already have a CS service registered, and it is of a higher priority.
* This means Drools was loaded first, but Bavet is available too.
* Such situation can only happen if the user did not specify an impl type.
* Therefore, we skip Bavet as Drools is the default and already registered.
*/
continue;
} else {
// Bavet will be registered as the CS impl.
isBavet = true;
}
break;
default:
throw new IllegalStateException(
"Impossible state: Unknown service priority (" + service.getPriority() + ")");
}
}
if (factory != null) {
scoreDirectorFactorySupplierMap.put(service.getSupportedScoreDirectorType(), factory);
}
}
Supplier<AbstractScoreDirectorFactory<Solution_, Score_>> easyScoreDirectorFactorySupplier =
scoreDirectorFactorySupplierMap.get(EASY);
Supplier<AbstractScoreDirectorFactory<Solution_, Score_>> constraintStreamScoreDirectorFactorySupplier =
scoreDirectorFactorySupplierMap.get(CONSTRAINT_STREAMS);
Supplier<AbstractScoreDirectorFactory<Solution_, Score_>> incrementalScoreDirectorFactorySupplier =
scoreDirectorFactorySupplierMap.get(INCREMENTAL);
Supplier<AbstractScoreDirectorFactory<Solution_, Score_>> drlScoreDirectorFactorySupplier =
scoreDirectorFactorySupplierMap.get(DRL);
// Every non-null supplier means that ServiceLoader successfully loaded and configured a score director factory.
assertOnlyOneScoreDirectorFactory(easyScoreDirectorFactorySupplier,
constraintStreamScoreDirectorFactorySupplier, incrementalScoreDirectorFactorySupplier,
drlScoreDirectorFactorySupplier);
if (easyScoreDirectorFactorySupplier != null) {
validateNoDroolsAlphaNetworkCompilation();
validateNoGizmoKieBaseSupplier();
return easyScoreDirectorFactorySupplier.get();
} else if (incrementalScoreDirectorFactorySupplier != null) {
validateNoDroolsAlphaNetworkCompilation();
validateNoGizmoKieBaseSupplier();
return incrementalScoreDirectorFactorySupplier.get();
}
if (constraintStreamScoreDirectorFactorySupplier != null) {
if (isBavet) {
validateNoDroolsAlphaNetworkCompilation();
validateNoGizmoKieBaseSupplier();
}
return constraintStreamScoreDirectorFactorySupplier.get();
} else if (config.getConstraintProviderClass() != null) {
String expectedModule = config.getConstraintStreamImplType() == BAVET
? "optaplanner-constraint-streams-bavet"
: "optaplanner-constraint-streams-drools";
throw new IllegalStateException("Constraint Streams requested via constraintProviderClass (" +
config.getConstraintProviderClass() + ") but the supporting classes were not found on the classpath.\n"
+ "Maybe include org.optaplanner:" + expectedModule + " dependency in your project?\n"
+ "Maybe ensure your uberjar bundles META-INF/services from included JAR files?");
}
if (drlScoreDirectorFactorySupplier != null) {
return drlScoreDirectorFactorySupplier.get();
} else {
if (!ConfigUtils.isEmptyCollection(config.getScoreDrlList())
|| !ConfigUtils.isEmptyCollection(config.getScoreDrlFileList())) {
throw new IllegalStateException("DRL constraints requested via scoreDrlList (" + config.getScoreDrlList()
+ ") or scoreDrlFileList (" + config.getScoreDrlFileList() + "), "
+ "but the supporting classes were not found on the classpath.\n"
+ "Maybe include org.optaplanner:optaplanner-constraint-drl dependency in your project?\n"
+ "Maybe ensure your uberjar bundles META-INF/services from included JAR files?");
}
}
throw new IllegalArgumentException("The scoreDirectorFactory lacks configuration for "
+ "either constraintProviderClass, easyScoreCalculatorClass or incrementalScoreCalculatorClass.");
}