>.subPillarSequenceComparatorClass",
+ "justification": "Internal protected fields; safe."
+ }
]
}
}
diff --git a/core/src/main/java/ai/timefold/solver/core/api/score/stream/test/MultiConstraintAssertion.java b/core/src/main/java/ai/timefold/solver/core/api/score/stream/test/MultiConstraintAssertion.java
index 8fa4afeae61..c042e5a8054 100644
--- a/core/src/main/java/ai/timefold/solver/core/api/score/stream/test/MultiConstraintAssertion.java
+++ b/core/src/main/java/ai/timefold/solver/core/api/score/stream/test/MultiConstraintAssertion.java
@@ -3,9 +3,10 @@
import ai.timefold.solver.core.api.score.Score;
import ai.timefold.solver.core.api.score.stream.ConstraintProvider;
-import org.jspecify.annotations.NonNull;
+import org.jspecify.annotations.NullMarked;
import org.jspecify.annotations.Nullable;
+@NullMarked
public interface MultiConstraintAssertion {
/**
@@ -14,7 +15,7 @@ public interface MultiConstraintAssertion {
* @param score total score calculated for the given set of facts
* @throws AssertionError when the expected score does not match the calculated score
*/
- default void scores(@NonNull Score> score) {
+ default void scores(Score> score) {
scores(score, null);
}
@@ -25,7 +26,7 @@ default void scores(@NonNull Score> score) {
* @param message description of the scenario being asserted
* @throws AssertionError when the expected score does not match the calculated score
*/
- void scores(@NonNull Score> score, @Nullable String message);
+ void scores(Score> score, @Nullable String message);
/**
* Returns the {@link Score} produced by all constraints in the {@link ConstraintProvider} for the given set of facts.
@@ -39,16 +40,15 @@ default void scores(@NonNull Score> score) {
* {@snippet :
* HardSoftScore scoreA = constraintVerifier.verifyThat()
* .givenSolution(solutionA)
- * .score();
+ * .getScore();
* HardSoftScore scoreB = constraintVerifier.verifyThat()
* .givenSolution(solutionB)
- * .score();
+ * .getScore();
* assertThat(scoreA).isGreaterThan(scoreB);
* }
*
* @return the score produced by all constraints for the given facts, never null
*/
- @NonNull
- > S score();
+ > S getScore();
}
diff --git a/core/src/main/java/ai/timefold/solver/core/api/score/stream/test/SingleConstraintAssertion.java b/core/src/main/java/ai/timefold/solver/core/api/score/stream/test/SingleConstraintAssertion.java
index 1bbe7efbe77..b5b9b44f6ca 100644
--- a/core/src/main/java/ai/timefold/solver/core/api/score/stream/test/SingleConstraintAssertion.java
+++ b/core/src/main/java/ai/timefold/solver/core/api/score/stream/test/SingleConstraintAssertion.java
@@ -7,9 +7,10 @@
import ai.timefold.solver.core.api.score.stream.Constraint;
import ai.timefold.solver.core.api.score.stream.ConstraintJustification;
-import org.jspecify.annotations.NonNull;
+import org.jspecify.annotations.NullMarked;
import org.jspecify.annotations.Nullable;
+@NullMarked
public interface SingleConstraintAssertion {
/**
@@ -19,9 +20,8 @@ public interface SingleConstraintAssertion {
* @param message description of the scenario being asserted
* @throws AssertionError when the expected penalty is not observed
*/
- @NonNull
SingleConstraintAssertion justifiesWith(@Nullable String message,
- @NonNull ConstraintJustification @NonNull... justifications);
+ ConstraintJustification... justifications);
/**
* Asserts that the {@link Constraint} being tested, given a set of facts, results in a given
@@ -30,7 +30,7 @@ SingleConstraintAssertion justifiesWith(@Nullable String message,
* @param justifications the expected justifications.
* @throws AssertionError when the expected penalty is not observed
*/
- default @NonNull SingleConstraintAssertion justifiesWith(@NonNull ConstraintJustification @NonNull... justifications) {
+ default SingleConstraintAssertion justifiesWith(ConstraintJustification... justifications) {
return justifiesWith(null, justifications);
}
@@ -41,9 +41,8 @@ SingleConstraintAssertion justifiesWith(@Nullable String message,
* @param message description of the scenario being asserted
* @throws AssertionError when the expected penalty is not observed
*/
- @NonNull
SingleConstraintAssertion justifiesWithExactly(@Nullable String message,
- @NonNull ConstraintJustification @NonNull... justifications);
+ ConstraintJustification... justifications);
/**
* Asserts that the {@link Constraint} being tested, given a set of facts, results in a given
@@ -52,8 +51,8 @@ SingleConstraintAssertion justifiesWithExactly(@Nullable String message,
* @param justifications the expected justifications.
* @throws AssertionError when the expected penalty is not observed
*/
- default @NonNull SingleConstraintAssertion
- justifiesWithExactly(@NonNull ConstraintJustification @NonNull... justifications) {
+ default SingleConstraintAssertion
+ justifiesWithExactly(ConstraintJustification... justifications) {
return justifiesWithExactly(null, justifications);
}
@@ -126,7 +125,7 @@ default void penalizesBy(long matchWeightTotal) {
* @param matchWeightTotal at least 0, expected sum of match weights of matches of the constraint.
* @throws AssertionError when the expected penalty is not observed
*/
- default void penalizesBy(@NonNull BigDecimal matchWeightTotal) {
+ default void penalizesBy(BigDecimal matchWeightTotal) {
penalizesBy(null, matchWeightTotal);
}
@@ -137,7 +136,7 @@ default void penalizesBy(@NonNull BigDecimal matchWeightTotal) {
* @param matchWeightTotal at least 0, expected sum of match weights of matches of the constraint.
* @throws AssertionError when the expected penalty is not observed
*/
- void penalizesBy(@Nullable String message, @NonNull BigDecimal matchWeightTotal);
+ void penalizesBy(@Nullable String message, BigDecimal matchWeightTotal);
/**
* Asserts that the {@link Constraint} being tested, given a set of facts, results in a given number of penalties.
@@ -232,7 +231,7 @@ default void rewardsWith(long matchWeightTotal) {
* @param matchWeightTotal at least 0, expected sum of match weights of matches of the constraint.
* @throws AssertionError when the expected reward is not observed
*/
- default void rewardsWith(@NonNull BigDecimal matchWeightTotal) {
+ default void rewardsWith(BigDecimal matchWeightTotal) {
rewardsWith(null, matchWeightTotal);
}
@@ -243,7 +242,7 @@ default void rewardsWith(@NonNull BigDecimal matchWeightTotal) {
* @param matchWeightTotal at least 0, expected sum of match weights of matches of the constraint.
* @throws AssertionError when the expected reward is not observed
*/
- void rewardsWith(@Nullable String message, @NonNull BigDecimal matchWeightTotal);
+ void rewardsWith(@Nullable String message, BigDecimal matchWeightTotal);
/**
* Asserts that the {@link Constraint} being tested, given a set of facts, results in a given number of rewards.
@@ -341,7 +340,7 @@ default void penalizesByMoreThan(long matchWeightTotal) {
* @param matchWeightTotal at least 0, expected sum of match weights of matches of the constraint.
* @throws AssertionError when the expected penalty is not observed
*/
- default void penalizesByMoreThan(@NonNull BigDecimal matchWeightTotal) {
+ default void penalizesByMoreThan(BigDecimal matchWeightTotal) {
penalizesByMoreThan(null, matchWeightTotal);
}
@@ -352,7 +351,7 @@ default void penalizesByMoreThan(@NonNull BigDecimal matchWeightTotal) {
* @param matchWeightTotal at least 0, expected sum of match weights of matches of the constraint.
* @throws AssertionError when the expected penalty is not observed
*/
- void penalizesByMoreThan(@Nullable String message, @NonNull BigDecimal matchWeightTotal);
+ void penalizesByMoreThan(@Nullable String message, BigDecimal matchWeightTotal);
/**
* Asserts that the {@link Constraint} being tested, given a set of facts,
@@ -431,7 +430,7 @@ default void rewardsWithMoreThan(long matchWeightTotal) {
* @param matchWeightTotal at least 0, expected sum of match weights of matches of the constraint.
* @throws AssertionError when the expected reward is not observed
*/
- default void rewardsWithMoreThan(@NonNull BigDecimal matchWeightTotal) {
+ default void rewardsWithMoreThan(BigDecimal matchWeightTotal) {
rewardsWithMoreThan(null, matchWeightTotal);
}
@@ -442,7 +441,7 @@ default void rewardsWithMoreThan(@NonNull BigDecimal matchWeightTotal) {
* @param matchWeightTotal at least 0, expected sum of match weights of matches of the constraint.
* @throws AssertionError when the expected reward is not observed
*/
- void rewardsWithMoreThan(@Nullable String message, @NonNull BigDecimal matchWeightTotal);
+ void rewardsWithMoreThan(@Nullable String message, BigDecimal matchWeightTotal);
/**
* Asserts that the {@link Constraint} being tested, given a set of facts,
@@ -522,7 +521,7 @@ default void penalizesByLessThan(long matchWeightTotal) {
* @param matchWeightTotal at least 1, expected sum of match weights of matches of the constraint.
* @throws AssertionError when the expected penalty is not observed
*/
- default void penalizesByLessThan(@NonNull BigDecimal matchWeightTotal) {
+ default void penalizesByLessThan(BigDecimal matchWeightTotal) {
penalizesByLessThan(null, matchWeightTotal);
}
@@ -533,7 +532,7 @@ default void penalizesByLessThan(@NonNull BigDecimal matchWeightTotal) {
* @param matchWeightTotal at least 1, expected sum of match weights of matches of the constraint.
* @throws AssertionError when the expected penalty is not observed
*/
- void penalizesByLessThan(@Nullable String message, @NonNull BigDecimal matchWeightTotal);
+ void penalizesByLessThan(@Nullable String message, BigDecimal matchWeightTotal);
/**
* Asserts that the {@link Constraint} being tested, given a set of facts,
@@ -612,7 +611,7 @@ default void rewardsWithLessThan(long matchWeightTotal) {
* @param matchWeightTotal at least 1, expected sum of match weights of matches of the constraint.
* @throws AssertionError when the expected reward is not observed
*/
- default void rewardsWithLessThan(@NonNull BigDecimal matchWeightTotal) {
+ default void rewardsWithLessThan(BigDecimal matchWeightTotal) {
rewardsWithLessThan(null, matchWeightTotal);
}
@@ -623,7 +622,7 @@ default void rewardsWithLessThan(@NonNull BigDecimal matchWeightTotal) {
* @param matchWeightTotal at least 1, expected sum of match weights of matches of the constraint.
* @throws AssertionError when the expected reward is not observed
*/
- void rewardsWithLessThan(@Nullable String message, @NonNull BigDecimal matchWeightTotal);
+ void rewardsWithLessThan(@Nullable String message, BigDecimal matchWeightTotal);
/**
* Asserts that the {@link Constraint} being tested, given a set of facts,
@@ -662,22 +661,21 @@ default void rewardsLessThan(long times) {
* {@snippet :
* HardSoftScore scoreA = constraintVerifier.verifyThat(MyConstraints::roomConflict)
* .given(entity1, entity2)
- * .score();
+ * .getScore();
* HardSoftScore scoreB = constraintVerifier.verifyThat(MyConstraints::roomConflict)
* .given(entity3, entity4)
- * .score();
+ * .getScore();
* assertThat(scoreA).isLessThan(scoreB);
* }
*
* @return the score produced by this single constraint for the given facts, never null
*/
- @NonNull
- > S score();
+ > S getScore();
/**
* Returns the match weight total of the {@link Constraint} being tested for the given set of facts.
*
- * Unlike {@link #score()}, which returns the full score (match weight × constraint weight),
+ * Unlike {@link #getScore()}, which returns the full score (match weight × constraint weight),
* this method returns only the match weight — the same number you would pass
* to assertion methods like {@link #penalizesBy(int)} or {@link #rewardsWith(int)}.
*
@@ -687,19 +685,18 @@ default void rewardsLessThan(long times) {
* Usage example:
*
* {@snippet :
- * Number impactA = constraintVerifier.verifyThat(MyConstraints::roomConflict)
+ * var impactA = constraintVerifier.verifyThat(MyConstraints::roomConflict)
* .given(entity1, entity2)
- * .impact();
- * Number impactB = constraintVerifier.verifyThat(MyConstraints::roomConflict)
+ * .getImpact();
+ * var impactB = constraintVerifier.verifyThat(MyConstraints::roomConflict)
* .given(entity3, entity4)
- * .impact();
+ * .getImpact();
* assertThat(impactA.intValue()).isGreaterThan(impactB.intValue());
* }
*
* @return the match weight total produced by this single constraint, never null.
* Positive for rewards, negative for penalties, zero when there is no impact.
*/
- @NonNull
- Number impact();
+ Number getImpact();
}
diff --git a/core/src/main/java/ai/timefold/solver/core/config/constructionheuristic/placer/QueuedValuePlacerConfig.java b/core/src/main/java/ai/timefold/solver/core/config/constructionheuristic/placer/QueuedValuePlacerConfig.java
index b2d5703158e..6899b2644f3 100644
--- a/core/src/main/java/ai/timefold/solver/core/config/constructionheuristic/placer/QueuedValuePlacerConfig.java
+++ b/core/src/main/java/ai/timefold/solver/core/config/constructionheuristic/placer/QueuedValuePlacerConfig.java
@@ -30,7 +30,7 @@ public final class QueuedValuePlacerConfig extends EntityPlacerConfig entityClass = null;
+ private String entityClass = null;
@XmlElement(name = "valueSelector")
private ValueSelectorConfig valueSelectorConfig = null;
@@ -50,11 +50,11 @@ public final class QueuedValuePlacerConfig extends EntityPlacerConfig getEntityClass() {
- return entityClass;
+ return ConfigUtils.resolveClass(entityClass, "entityClass", this);
}
public void setEntityClass(@Nullable Class> entityClass) {
- this.entityClass = entityClass;
+ this.entityClass = entityClass == null ? null : entityClass.getName();
}
public @Nullable ValueSelectorConfig getValueSelectorConfig() {
@@ -78,7 +78,7 @@ public void setMoveSelectorConfig(@Nullable MoveSelectorConfig moveSelectorConfi
// ************************************************************************
public @NonNull QueuedValuePlacerConfig withEntityClass(@NonNull Class> entityClass) {
- this.setEntityClass(entityClass);
+ this.entityClass = entityClass.getName();
return this;
}
@@ -98,7 +98,7 @@ public void setMoveSelectorConfig(@Nullable MoveSelectorConfig moveSelectorConfi
@Override
public @NonNull QueuedValuePlacerConfig inherit(@NonNull QueuedValuePlacerConfig inheritedConfig) {
- entityClass = ConfigUtils.inheritOverwritableProperty(entityClass, inheritedConfig.getEntityClass());
+ entityClass = ConfigUtils.inheritOverwritableProperty(entityClass, inheritedConfig.entityClass);
valueSelectorConfig = ConfigUtils.inheritConfig(valueSelectorConfig, inheritedConfig.getValueSelectorConfig());
setMoveSelectorConfig(
ConfigUtils.inheritOverwritableProperty(getMoveSelectorConfig(), inheritedConfig.getMoveSelectorConfig()));
@@ -112,7 +112,7 @@ public void setMoveSelectorConfig(@Nullable MoveSelectorConfig moveSelectorConfi
@Override
public void visitReferencedClasses(@NonNull Consumer> classVisitor) {
- classVisitor.accept(entityClass);
+ classVisitor.accept(getEntityClass());
if (valueSelectorConfig != null) {
valueSelectorConfig.visitReferencedClasses(classVisitor);
}
diff --git a/core/src/main/java/ai/timefold/solver/core/config/heuristic/selector/common/nearby/NearbySelectionConfig.java b/core/src/main/java/ai/timefold/solver/core/config/heuristic/selector/common/nearby/NearbySelectionConfig.java
index d92d4ff475b..ba6a8930744 100644
--- a/core/src/main/java/ai/timefold/solver/core/config/heuristic/selector/common/nearby/NearbySelectionConfig.java
+++ b/core/src/main/java/ai/timefold/solver/core/config/heuristic/selector/common/nearby/NearbySelectionConfig.java
@@ -44,7 +44,7 @@ public final class NearbySelectionConfig extends SelectorConfig nearbyDistanceMeterClass = null;
+ private String nearbyDistanceMeterClass = null;
private NearbySelectionDistributionType nearbySelectionDistributionType = null;
@@ -85,11 +85,11 @@ public void setOriginValueSelectorConfig(@Nullable ValueSelectorConfig originVal
}
public @Nullable Class extends NearbyDistanceMeter> getNearbyDistanceMeterClass() {
- return nearbyDistanceMeterClass;
+ return ConfigUtils.resolveClass(nearbyDistanceMeterClass, "nearbyDistanceMeterClass", this);
}
public void setNearbyDistanceMeterClass(@Nullable Class extends NearbyDistanceMeter> nearbyDistanceMeterClass) {
- this.nearbyDistanceMeterClass = nearbyDistanceMeterClass;
+ this.nearbyDistanceMeterClass = nearbyDistanceMeterClass == null ? null : nearbyDistanceMeterClass.getName();
}
public @Nullable NearbySelectionDistributionType getNearbySelectionDistributionType() {
@@ -189,7 +189,7 @@ public void setBetaDistributionBeta(@Nullable Double betaDistributionBeta) {
public @NonNull NearbySelectionConfig
withNearbyDistanceMeterClass(@NonNull Class extends NearbyDistanceMeter> nearbyDistanceMeterClass) {
- this.setNearbyDistanceMeterClass(nearbyDistanceMeterClass);
+ this.nearbyDistanceMeterClass = nearbyDistanceMeterClass.getName();
return this;
}
@@ -316,7 +316,7 @@ has a resolvedCacheType (%s) that is cached."""
originValueSelectorConfig = ConfigUtils.inheritConfig(originValueSelectorConfig,
inheritedConfig.getOriginValueSelectorConfig());
nearbyDistanceMeterClass = ConfigUtils.inheritOverwritableProperty(nearbyDistanceMeterClass,
- inheritedConfig.getNearbyDistanceMeterClass());
+ inheritedConfig.nearbyDistanceMeterClass);
nearbySelectionDistributionType = ConfigUtils.inheritOverwritableProperty(nearbySelectionDistributionType,
inheritedConfig.getNearbySelectionDistributionType());
blockDistributionSizeMinimum = ConfigUtils.inheritOverwritableProperty(blockDistributionSizeMinimum,
@@ -355,7 +355,7 @@ public void visitReferencedClasses(@NonNull Consumer> classVisitor) {
if (originValueSelectorConfig != null) {
originValueSelectorConfig.visitReferencedClasses(classVisitor);
}
- classVisitor.accept(nearbyDistanceMeterClass);
+ classVisitor.accept(getNearbyDistanceMeterClass());
}
@Override
diff --git a/core/src/main/java/ai/timefold/solver/core/config/heuristic/selector/entity/EntitySelectorConfig.java b/core/src/main/java/ai/timefold/solver/core/config/heuristic/selector/entity/EntitySelectorConfig.java
index 4de7462968b..ea9b3298f0a 100644
--- a/core/src/main/java/ai/timefold/solver/core/config/heuristic/selector/entity/EntitySelectorConfig.java
+++ b/core/src/main/java/ai/timefold/solver/core/config/heuristic/selector/entity/EntitySelectorConfig.java
@@ -55,7 +55,7 @@ public static EntitySelectorConfig newMimicSelectorConfig(String mimicSelectorRe
private String mimicSelectorRef = null;
@Nullable
- private Class> entityClass = null;
+ private String entityClass = null;
@Nullable
private SelectionCacheType cacheType = null;
@Nullable
@@ -66,21 +66,21 @@ public static EntitySelectorConfig newMimicSelectorConfig(String mimicSelectorRe
private NearbySelectionConfig nearbySelectionConfig = null;
@Nullable
- private Class extends SelectionFilter> filterClass = null;
+ private String filterClass = null;
@Nullable
private EntitySorterManner sorterManner = null;
@Nullable
- private Class extends Comparator> comparatorClass = null;
+ private String comparatorClass = null;
@Nullable
- private Class extends ComparatorFactory> comparatorFactoryClass = null;
+ private String comparatorFactoryClass = null;
@Nullable
private SelectionSorterOrder sorterOrder = null;
@Nullable
- private Class extends SelectionSorter> sorterClass = null;
+ private String sorterClass = null;
@Nullable
- private Class extends SelectionProbabilityWeightFactory> probabilityWeightFactoryClass = null;
+ private String probabilityWeightFactoryClass = null;
@Nullable
private Long selectedCountLimit = null;
@@ -88,8 +88,8 @@ public static EntitySelectorConfig newMimicSelectorConfig(String mimicSelectorRe
public EntitySelectorConfig() {
}
- public EntitySelectorConfig(Class> entityClass) {
- this.entityClass = entityClass;
+ public EntitySelectorConfig(@Nullable Class> entityClass) {
+ this.entityClass = entityClass == null ? null : entityClass.getName();
}
public EntitySelectorConfig(@Nullable EntitySelectorConfig inheritedConfig) {
@@ -115,11 +115,11 @@ public void setMimicSelectorRef(@Nullable String mimicSelectorRef) {
}
public @Nullable Class> getEntityClass() {
- return entityClass;
+ return ConfigUtils.resolveClass(entityClass, "entityClass", this);
}
public void setEntityClass(@Nullable Class> entityClass) {
- this.entityClass = entityClass;
+ this.entityClass = entityClass == null ? null : entityClass.getName();
}
public @Nullable SelectionCacheType getCacheType() {
@@ -147,11 +147,11 @@ public void setNearbySelectionConfig(@Nullable NearbySelectionConfig nearbySelec
}
public @Nullable Class extends SelectionFilter> getFilterClass() {
- return filterClass;
+ return ConfigUtils.resolveClass(filterClass, "filterClass", this);
}
public void setFilterClass(@Nullable Class extends SelectionFilter> filterClass) {
- this.filterClass = filterClass;
+ this.filterClass = filterClass == null ? null : filterClass.getName();
}
public @Nullable EntitySorterManner getSorterManner() {
@@ -163,19 +163,19 @@ public void setSorterManner(@Nullable EntitySorterManner sorterManner) {
}
public @Nullable Class extends Comparator> getComparatorClass() {
- return comparatorClass;
+ return ConfigUtils.resolveClass(comparatorClass, "comparatorClass", this);
}
public void setComparatorClass(@Nullable Class extends Comparator> comparatorClass) {
- this.comparatorClass = comparatorClass;
+ this.comparatorClass = comparatorClass == null ? null : comparatorClass.getName();
}
public @Nullable Class extends ComparatorFactory> getComparatorFactoryClass() {
- return comparatorFactoryClass;
+ return ConfigUtils.resolveClass(comparatorFactoryClass, "comparatorFactoryClass", this);
}
public void setComparatorFactoryClass(@Nullable Class extends ComparatorFactory> comparatorFactoryClass) {
- this.comparatorFactoryClass = comparatorFactoryClass;
+ this.comparatorFactoryClass = comparatorFactoryClass == null ? null : comparatorFactoryClass.getName();
}
public @Nullable SelectionSorterOrder getSorterOrder() {
@@ -187,20 +187,21 @@ public void setSorterOrder(@Nullable SelectionSorterOrder sorterOrder) {
}
public @Nullable Class extends SelectionSorter> getSorterClass() {
- return sorterClass;
+ return ConfigUtils.resolveClass(sorterClass, "sorterClass", this);
}
public void setSorterClass(@Nullable Class extends SelectionSorter> sorterClass) {
- this.sorterClass = sorterClass;
+ this.sorterClass = sorterClass == null ? null : sorterClass.getName();
}
public @Nullable Class extends SelectionProbabilityWeightFactory> getProbabilityWeightFactoryClass() {
- return probabilityWeightFactoryClass;
+ return ConfigUtils.resolveClass(probabilityWeightFactoryClass, "probabilityWeightFactoryClass", this);
}
public void setProbabilityWeightFactoryClass(
@Nullable Class extends SelectionProbabilityWeightFactory> probabilityWeightFactoryClass) {
- this.probabilityWeightFactoryClass = probabilityWeightFactoryClass;
+ this.probabilityWeightFactoryClass =
+ probabilityWeightFactoryClass == null ? null : probabilityWeightFactoryClass.getName();
}
public @Nullable Long getSelectedCountLimit() {
@@ -226,7 +227,7 @@ public EntitySelectorConfig withMimicSelectorRef(String mimicSelectorRef) {
}
public EntitySelectorConfig withEntityClass(Class> entityClass) {
- this.setEntityClass(entityClass);
+ this.entityClass = entityClass.getName();
return this;
}
@@ -246,7 +247,7 @@ public EntitySelectorConfig withNearbySelectionConfig(NearbySelectionConfig near
}
public EntitySelectorConfig withFilterClass(Class extends SelectionFilter> filterClass) {
- this.setFilterClass(filterClass);
+ this.filterClass = filterClass.getName();
return this;
}
@@ -256,13 +257,12 @@ public EntitySelectorConfig withSorterManner(EntitySorterManner sorterManner) {
}
public EntitySelectorConfig withComparatorClass(Class extends Comparator> comparatorClass) {
- this.setComparatorClass(comparatorClass);
+ this.comparatorClass = comparatorClass.getName();
return this;
}
- public EntitySelectorConfig
- withComparatorFactoryClass(Class extends ComparatorFactory> comparatorFactoryClass) {
- this.setComparatorFactoryClass(comparatorFactoryClass);
+ public EntitySelectorConfig withComparatorFactoryClass(Class extends ComparatorFactory> comparatorFactoryClass) {
+ this.comparatorFactoryClass = comparatorFactoryClass.getName();
return this;
}
@@ -272,13 +272,13 @@ public EntitySelectorConfig withSorterOrder(SelectionSorterOrder sorterOrder) {
}
public EntitySelectorConfig withSorterClass(Class extends SelectionSorter> sorterClass) {
- this.setSorterClass(sorterClass);
+ this.sorterClass = sorterClass.getName();
return this;
}
public EntitySelectorConfig
withProbabilityWeightFactoryClass(Class extends SelectionProbabilityWeightFactory> factoryClass) {
- this.setProbabilityWeightFactoryClass(factoryClass);
+ this.probabilityWeightFactoryClass = factoryClass.getName();
return this;
}
@@ -297,24 +297,24 @@ public EntitySelectorConfig inherit(EntitySelectorConfig inheritedConfig) {
mimicSelectorRef = ConfigUtils.inheritOverwritableProperty(mimicSelectorRef,
inheritedConfig.getMimicSelectorRef());
entityClass = ConfigUtils.inheritOverwritableProperty(entityClass,
- inheritedConfig.getEntityClass());
+ inheritedConfig.entityClass);
nearbySelectionConfig = ConfigUtils.inheritConfig(nearbySelectionConfig, inheritedConfig.getNearbySelectionConfig());
cacheType = ConfigUtils.inheritOverwritableProperty(cacheType, inheritedConfig.getCacheType());
selectionOrder = ConfigUtils.inheritOverwritableProperty(selectionOrder, inheritedConfig.getSelectionOrder());
filterClass = ConfigUtils.inheritOverwritableProperty(
- filterClass, inheritedConfig.getFilterClass());
+ filterClass, inheritedConfig.filterClass);
sorterManner = ConfigUtils.inheritOverwritableProperty(
sorterManner, inheritedConfig.getSorterManner());
comparatorClass = ConfigUtils.inheritOverwritableProperty(
- comparatorClass, inheritedConfig.getComparatorClass());
+ comparatorClass, inheritedConfig.comparatorClass);
comparatorFactoryClass = ConfigUtils.inheritOverwritableProperty(
- comparatorFactoryClass, inheritedConfig.getComparatorFactoryClass());
+ comparatorFactoryClass, inheritedConfig.comparatorFactoryClass);
sorterOrder = ConfigUtils.inheritOverwritableProperty(
sorterOrder, inheritedConfig.getSorterOrder());
sorterClass = ConfigUtils.inheritOverwritableProperty(
- sorterClass, inheritedConfig.getSorterClass());
+ sorterClass, inheritedConfig.sorterClass);
probabilityWeightFactoryClass = ConfigUtils.inheritOverwritableProperty(
- probabilityWeightFactoryClass, inheritedConfig.getProbabilityWeightFactoryClass());
+ probabilityWeightFactoryClass, inheritedConfig.probabilityWeightFactoryClass);
selectedCountLimit = ConfigUtils.inheritOverwritableProperty(
selectedCountLimit, inheritedConfig.getSelectedCountLimit());
return this;
@@ -327,15 +327,15 @@ public EntitySelectorConfig copyConfig() {
@Override
public void visitReferencedClasses(Consumer> classVisitor) {
- classVisitor.accept(entityClass);
+ classVisitor.accept(getEntityClass());
if (nearbySelectionConfig != null) {
nearbySelectionConfig.visitReferencedClasses(classVisitor);
}
- classVisitor.accept(filterClass);
- classVisitor.accept(comparatorClass);
- classVisitor.accept(comparatorFactoryClass);
- classVisitor.accept(sorterClass);
- classVisitor.accept(probabilityWeightFactoryClass);
+ classVisitor.accept(getFilterClass());
+ classVisitor.accept(getComparatorClass());
+ classVisitor.accept(getComparatorFactoryClass());
+ classVisitor.accept(getSorterClass());
+ classVisitor.accept(getProbabilityWeightFactoryClass());
}
@Override
diff --git a/core/src/main/java/ai/timefold/solver/core/config/heuristic/selector/move/MoveSelectorConfig.java b/core/src/main/java/ai/timefold/solver/core/config/heuristic/selector/move/MoveSelectorConfig.java
index cc3a0cae656..332c073abf4 100644
--- a/core/src/main/java/ai/timefold/solver/core/config/heuristic/selector/move/MoveSelectorConfig.java
+++ b/core/src/main/java/ai/timefold/solver/core/config/heuristic/selector/move/MoveSelectorConfig.java
@@ -77,19 +77,19 @@ public abstract class MoveSelectorConfig filterClass = null;
+ protected String filterClass = null;
@Nullable
- protected Class extends Comparator> comparatorClass = null;
+ protected String comparatorClass = null;
@Nullable
- protected Class extends ComparatorFactory> comparatorFactoryClass = null;
+ protected String comparatorFactoryClass = null;
@Nullable
protected SelectionSorterOrder sorterOrder = null;
@Nullable
- protected Class extends SelectionSorter> sorterClass = null;
+ protected String sorterClass = null;
@Nullable
- protected Class extends SelectionProbabilityWeightFactory> probabilityWeightFactoryClass = null;
+ protected String probabilityWeightFactoryClass = null;
@Nullable
protected Long selectedCountLimit = null;
@@ -118,27 +118,27 @@ public void setSelectionOrder(@Nullable SelectionOrder selectionOrder) {
}
public @Nullable Class extends SelectionFilter> getFilterClass() {
- return filterClass;
+ return ConfigUtils.resolveClass(filterClass, "filterClass", this);
}
public void setFilterClass(@Nullable Class extends SelectionFilter> filterClass) {
- this.filterClass = filterClass;
+ this.filterClass = filterClass == null ? null : filterClass.getName();
}
public @Nullable Class extends Comparator> getComparatorClass() {
- return comparatorClass;
+ return ConfigUtils.resolveClass(comparatorClass, "comparatorClass", this);
}
public void setComparatorClass(@Nullable Class extends Comparator> comparatorClass) {
- this.comparatorClass = comparatorClass;
+ this.comparatorClass = comparatorClass == null ? null : comparatorClass.getName();
}
public @Nullable Class extends ComparatorFactory> getComparatorFactoryClass() {
- return comparatorFactoryClass;
+ return ConfigUtils.resolveClass(comparatorFactoryClass, "comparatorFactoryClass", this);
}
public void setComparatorFactoryClass(@Nullable Class extends ComparatorFactory> comparatorFactoryClass) {
- this.comparatorFactoryClass = comparatorFactoryClass;
+ this.comparatorFactoryClass = comparatorFactoryClass == null ? null : comparatorFactoryClass.getName();
}
public @Nullable SelectionSorterOrder getSorterOrder() {
@@ -150,20 +150,21 @@ public void setSorterOrder(@Nullable SelectionSorterOrder sorterOrder) {
}
public @Nullable Class extends SelectionSorter> getSorterClass() {
- return sorterClass;
+ return ConfigUtils.resolveClass(sorterClass, "sorterClass", this);
}
public void setSorterClass(@Nullable Class extends SelectionSorter> sorterClass) {
- this.sorterClass = sorterClass;
+ this.sorterClass = sorterClass == null ? null : sorterClass.getName();
}
public @Nullable Class extends SelectionProbabilityWeightFactory> getProbabilityWeightFactoryClass() {
- return probabilityWeightFactoryClass;
+ return ConfigUtils.resolveClass(probabilityWeightFactoryClass, "probabilityWeightFactoryClass", this);
}
public void setProbabilityWeightFactoryClass(
@Nullable Class extends SelectionProbabilityWeightFactory> probabilityWeightFactoryClass) {
- this.probabilityWeightFactoryClass = probabilityWeightFactoryClass;
+ this.probabilityWeightFactoryClass = probabilityWeightFactoryClass == null ? null
+ : probabilityWeightFactoryClass.getName();
}
public @Nullable Long getSelectedCountLimit() {
@@ -197,18 +198,18 @@ public Config_ withSelectionOrder(SelectionOrder selectionOrder) {
}
public Config_ withFilterClass(Class extends SelectionFilter> filterClass) {
- this.filterClass = filterClass;
+ this.filterClass = filterClass.getName();
return (Config_) this;
}
public Config_ withComparatorClass(Class extends Comparator> comparatorClass) {
- this.setComparatorClass(comparatorClass);
+ this.comparatorClass = comparatorClass.getName();
return (Config_) this;
}
public Config_
withComparatorFactoryClass(Class extends ComparatorFactory> comparatorFactoryClass) {
- this.setComparatorFactoryClass(comparatorFactoryClass);
+ this.comparatorFactoryClass = comparatorFactoryClass.getName();
return (Config_) this;
}
@@ -218,13 +219,13 @@ public Config_ withSorterOrder(SelectionSorterOrder sorterOrder) {
}
public Config_ withSorterClass(Class extends SelectionSorter> sorterClass) {
- this.sorterClass = sorterClass;
+ this.sorterClass = sorterClass.getName();
return (Config_) this;
}
public Config_ withProbabilityWeightFactoryClass(
Class extends SelectionProbabilityWeightFactory> probabilityWeightFactoryClass) {
- this.probabilityWeightFactoryClass = probabilityWeightFactoryClass;
+ this.probabilityWeightFactoryClass = probabilityWeightFactoryClass.getName();
return (Config_) this;
}
@@ -261,27 +262,24 @@ public void inheritFolded(MoveSelectorConfig> foldedConfig) {
}
protected void visitCommonReferencedClasses(Consumer> classVisitor) {
- classVisitor.accept(filterClass);
- classVisitor.accept(comparatorClass);
- classVisitor.accept(comparatorFactoryClass);
- classVisitor.accept(sorterClass);
- classVisitor.accept(probabilityWeightFactoryClass);
+ classVisitor.accept(getFilterClass());
+ classVisitor.accept(getComparatorClass());
+ classVisitor.accept(getComparatorFactoryClass());
+ classVisitor.accept(getSorterClass());
+ classVisitor.accept(getProbabilityWeightFactoryClass());
}
private void inheritCommon(MoveSelectorConfig> inheritedConfig) {
cacheType = ConfigUtils.inheritOverwritableProperty(cacheType, inheritedConfig.getCacheType());
selectionOrder = ConfigUtils.inheritOverwritableProperty(selectionOrder, inheritedConfig.getSelectionOrder());
- filterClass = ConfigUtils.inheritOverwritableProperty(filterClass, inheritedConfig.getFilterClass());
- comparatorClass = ConfigUtils.inheritOverwritableProperty(
- comparatorClass, inheritedConfig.getComparatorClass());
+ filterClass = ConfigUtils.inheritOverwritableProperty(filterClass, inheritedConfig.filterClass);
+ comparatorClass = ConfigUtils.inheritOverwritableProperty(comparatorClass, inheritedConfig.comparatorClass);
comparatorFactoryClass = ConfigUtils.inheritOverwritableProperty(
- comparatorFactoryClass, inheritedConfig.getComparatorFactoryClass());
- sorterOrder = ConfigUtils.inheritOverwritableProperty(
- sorterOrder, inheritedConfig.getSorterOrder());
- sorterClass = ConfigUtils.inheritOverwritableProperty(
- sorterClass, inheritedConfig.getSorterClass());
+ comparatorFactoryClass, inheritedConfig.comparatorFactoryClass);
+ sorterOrder = ConfigUtils.inheritOverwritableProperty(sorterOrder, inheritedConfig.getSorterOrder());
+ sorterClass = ConfigUtils.inheritOverwritableProperty(sorterClass, inheritedConfig.sorterClass);
probabilityWeightFactoryClass = ConfigUtils.inheritOverwritableProperty(
- probabilityWeightFactoryClass, inheritedConfig.getProbabilityWeightFactoryClass());
+ probabilityWeightFactoryClass, inheritedConfig.probabilityWeightFactoryClass);
selectedCountLimit = ConfigUtils.inheritOverwritableProperty(
selectedCountLimit, inheritedConfig.getSelectedCountLimit());
diff --git a/core/src/main/java/ai/timefold/solver/core/config/heuristic/selector/move/composite/UnionMoveSelectorConfig.java b/core/src/main/java/ai/timefold/solver/core/config/heuristic/selector/move/composite/UnionMoveSelectorConfig.java
index c3cfba4b5c6..7d76c53baed 100644
--- a/core/src/main/java/ai/timefold/solver/core/config/heuristic/selector/move/composite/UnionMoveSelectorConfig.java
+++ b/core/src/main/java/ai/timefold/solver/core/config/heuristic/selector/move/composite/UnionMoveSelectorConfig.java
@@ -71,7 +71,7 @@ public final class UnionMoveSelectorConfig
})
private List moveSelectorConfigList = null;
- private Class extends SelectionProbabilityWeightFactory> selectorProbabilityWeightFactoryClass = null;
+ private String selectorProbabilityWeightFactoryClass = null;
// ************************************************************************
// Constructors and simple getters/setters
@@ -93,12 +93,13 @@ public void setMoveSelectorList(@Nullable List<@NonNull MoveSelectorConfig> move
}
public @Nullable Class extends SelectionProbabilityWeightFactory> getSelectorProbabilityWeightFactoryClass() {
- return selectorProbabilityWeightFactoryClass;
+ return ConfigUtils.resolveClass(selectorProbabilityWeightFactoryClass, "selectorProbabilityWeightFactoryClass", this);
}
public void setSelectorProbabilityWeightFactoryClass(
@Nullable Class extends SelectionProbabilityWeightFactory> selectorProbabilityWeightFactoryClass) {
- this.selectorProbabilityWeightFactoryClass = selectorProbabilityWeightFactoryClass;
+ this.selectorProbabilityWeightFactoryClass = selectorProbabilityWeightFactoryClass == null ? null
+ : selectorProbabilityWeightFactoryClass.getName();
}
// ************************************************************************
@@ -118,7 +119,7 @@ public void setSelectorProbabilityWeightFactoryClass(
public @NonNull UnionMoveSelectorConfig withSelectorProbabilityWeightFactoryClass(
@NonNull Class extends SelectionProbabilityWeightFactory> selectorProbabilityWeightFactoryClass) {
- this.selectorProbabilityWeightFactoryClass = selectorProbabilityWeightFactoryClass;
+ this.selectorProbabilityWeightFactoryClass = selectorProbabilityWeightFactoryClass.getName();
return this;
}
@@ -139,7 +140,7 @@ public void extractLeafMoveSelectorConfigsIntoList(@NonNull List<@NonNull MoveSe
moveSelectorConfigList =
ConfigUtils.inheritMergeableListConfig(moveSelectorConfigList, inheritedConfig.getMoveSelectorList());
selectorProbabilityWeightFactoryClass = ConfigUtils.inheritOverwritableProperty(
- selectorProbabilityWeightFactoryClass, inheritedConfig.getSelectorProbabilityWeightFactoryClass());
+ selectorProbabilityWeightFactoryClass, inheritedConfig.selectorProbabilityWeightFactoryClass);
return this;
}
@@ -154,7 +155,7 @@ public void visitReferencedClasses(@NonNull Consumer> classVisitor) {
if (moveSelectorConfigList != null) {
moveSelectorConfigList.forEach(ms -> ms.visitReferencedClasses(classVisitor));
}
- classVisitor.accept(selectorProbabilityWeightFactoryClass);
+ classVisitor.accept(getSelectorProbabilityWeightFactoryClass());
}
@Override
diff --git a/core/src/main/java/ai/timefold/solver/core/config/heuristic/selector/move/factory/MoveIteratorFactoryConfig.java b/core/src/main/java/ai/timefold/solver/core/config/heuristic/selector/move/factory/MoveIteratorFactoryConfig.java
index 20466934232..633f9fcc377 100644
--- a/core/src/main/java/ai/timefold/solver/core/config/heuristic/selector/move/factory/MoveIteratorFactoryConfig.java
+++ b/core/src/main/java/ai/timefold/solver/core/config/heuristic/selector/move/factory/MoveIteratorFactoryConfig.java
@@ -22,18 +22,18 @@ public final class MoveIteratorFactoryConfig extends MoveSelectorConfig moveIteratorFactoryClass = null;
+ private String moveIteratorFactoryClass = null;
@XmlJavaTypeAdapter(JaxbCustomPropertiesAdapter.class)
@Nullable
private Map moveIteratorFactoryCustomProperties = null;
public @Nullable Class extends MoveIteratorFactory> getMoveIteratorFactoryClass() {
- return moveIteratorFactoryClass;
+ return ConfigUtils.resolveClass(moveIteratorFactoryClass, "moveIteratorFactoryClass", this);
}
public void setMoveIteratorFactoryClass(@Nullable Class extends MoveIteratorFactory> moveIteratorFactoryClass) {
- this.moveIteratorFactoryClass = moveIteratorFactoryClass;
+ this.moveIteratorFactoryClass = moveIteratorFactoryClass == null ? null : moveIteratorFactoryClass.getName();
}
public @Nullable Map getMoveIteratorFactoryCustomProperties() {
@@ -50,7 +50,7 @@ public void setMoveIteratorFactoryCustomProperties(@Nullable Map
public @NonNull MoveIteratorFactoryConfig
withMoveIteratorFactoryClass(@NonNull Class extends MoveIteratorFactory> moveIteratorFactoryClass) {
- this.setMoveIteratorFactoryClass(moveIteratorFactoryClass);
+ this.moveIteratorFactoryClass = moveIteratorFactoryClass.getName();
return this;
}
@@ -64,7 +64,7 @@ public void setMoveIteratorFactoryCustomProperties(@Nullable Map
public @NonNull MoveIteratorFactoryConfig inherit(@NonNull MoveIteratorFactoryConfig inheritedConfig) {
super.inherit(inheritedConfig);
moveIteratorFactoryClass = ConfigUtils.inheritOverwritableProperty(
- moveIteratorFactoryClass, inheritedConfig.getMoveIteratorFactoryClass());
+ moveIteratorFactoryClass, inheritedConfig.moveIteratorFactoryClass);
moveIteratorFactoryCustomProperties = ConfigUtils.inheritMergeableMapProperty(
moveIteratorFactoryCustomProperties, inheritedConfig.getMoveIteratorFactoryCustomProperties());
return this;
@@ -78,7 +78,7 @@ public void setMoveIteratorFactoryCustomProperties(@Nullable Map
@Override
public void visitReferencedClasses(@NonNull Consumer> classVisitor) {
visitCommonReferencedClasses(classVisitor);
- classVisitor.accept(moveIteratorFactoryClass);
+ classVisitor.accept(getMoveIteratorFactoryClass());
}
@Override
diff --git a/core/src/main/java/ai/timefold/solver/core/config/heuristic/selector/move/factory/MoveListFactoryConfig.java b/core/src/main/java/ai/timefold/solver/core/config/heuristic/selector/move/factory/MoveListFactoryConfig.java
index 8f1973dc367..63246477ee1 100644
--- a/core/src/main/java/ai/timefold/solver/core/config/heuristic/selector/move/factory/MoveListFactoryConfig.java
+++ b/core/src/main/java/ai/timefold/solver/core/config/heuristic/selector/move/factory/MoveListFactoryConfig.java
@@ -22,17 +22,17 @@ public final class MoveListFactoryConfig extends MoveSelectorConfig moveListFactoryClass = null;
+ private String moveListFactoryClass = null;
@XmlJavaTypeAdapter(JaxbCustomPropertiesAdapter.class)
private Map moveListFactoryCustomProperties = null;
public @Nullable Class extends MoveListFactory> getMoveListFactoryClass() {
- return moveListFactoryClass;
+ return ConfigUtils.resolveClass(moveListFactoryClass, "moveListFactoryClass", this);
}
public void setMoveListFactoryClass(@Nullable Class extends MoveListFactory> moveListFactoryClass) {
- this.moveListFactoryClass = moveListFactoryClass;
+ this.moveListFactoryClass = moveListFactoryClass == null ? null : moveListFactoryClass.getName();
}
public @Nullable Map getMoveListFactoryCustomProperties() {
@@ -49,7 +49,7 @@ public void setMoveListFactoryCustomProperties(@Nullable Map mov
public @NonNull MoveListFactoryConfig
withMoveListFactoryClass(@NonNull Class extends MoveListFactory> moveListFactoryClass) {
- this.setMoveListFactoryClass(moveListFactoryClass);
+ this.moveListFactoryClass = moveListFactoryClass.getName();
return this;
}
@@ -67,7 +67,7 @@ public void setMoveListFactoryCustomProperties(@Nullable Map mov
public @NonNull MoveListFactoryConfig inherit(@NonNull MoveListFactoryConfig inheritedConfig) {
super.inherit(inheritedConfig);
moveListFactoryClass = ConfigUtils.inheritOverwritableProperty(
- moveListFactoryClass, inheritedConfig.getMoveListFactoryClass());
+ moveListFactoryClass, inheritedConfig.moveListFactoryClass);
moveListFactoryCustomProperties = ConfigUtils.inheritMergeableMapProperty(
moveListFactoryCustomProperties, inheritedConfig.getMoveListFactoryCustomProperties());
return this;
@@ -81,7 +81,7 @@ public void setMoveListFactoryCustomProperties(@Nullable Map mov
@Override
public void visitReferencedClasses(@NonNull Consumer> classVisitor) {
visitCommonReferencedClasses(classVisitor);
- classVisitor.accept(moveListFactoryClass);
+ classVisitor.accept(getMoveListFactoryClass());
}
@Override
diff --git a/core/src/main/java/ai/timefold/solver/core/config/heuristic/selector/move/generic/AbstractPillarMoveSelectorConfig.java b/core/src/main/java/ai/timefold/solver/core/config/heuristic/selector/move/generic/AbstractPillarMoveSelectorConfig.java
index 335ccd72b0d..1e7fdfd7fef 100644
--- a/core/src/main/java/ai/timefold/solver/core/config/heuristic/selector/move/generic/AbstractPillarMoveSelectorConfig.java
+++ b/core/src/main/java/ai/timefold/solver/core/config/heuristic/selector/move/generic/AbstractPillarMoveSelectorConfig.java
@@ -22,7 +22,7 @@ public abstract class AbstractPillarMoveSelectorConfig {
protected SubPillarType subPillarType = null;
- protected Class extends Comparator> subPillarSequenceComparatorClass = null;
+ protected String subPillarSequenceComparatorClass = null;
@XmlElement(name = "pillarSelector")
protected PillarSelectorConfig pillarSelectorConfig = null;
@@ -35,12 +35,13 @@ public void setSubPillarType(final @Nullable SubPillarType subPillarType) {
}
public @Nullable Class extends Comparator> getSubPillarSequenceComparatorClass() {
- return subPillarSequenceComparatorClass;
+ return ConfigUtils.resolveClass(subPillarSequenceComparatorClass, "subPillarSequenceComparatorClass", this);
}
public void
setSubPillarSequenceComparatorClass(final @Nullable Class extends Comparator> subPillarSequenceComparatorClass) {
- this.subPillarSequenceComparatorClass = subPillarSequenceComparatorClass;
+ this.subPillarSequenceComparatorClass =
+ subPillarSequenceComparatorClass == null ? null : subPillarSequenceComparatorClass.getName();
}
public @Nullable PillarSelectorConfig getPillarSelectorConfig() {
@@ -62,7 +63,7 @@ public void setPillarSelectorConfig(@Nullable PillarSelectorConfig pillarSelecto
public @NonNull Config_
withSubPillarSequenceComparatorClass(@NonNull Class extends Comparator> subPillarSequenceComparatorClass) {
- this.setSubPillarSequenceComparatorClass(subPillarSequenceComparatorClass);
+ this.subPillarSequenceComparatorClass = subPillarSequenceComparatorClass.getName();
return (Config_) this;
}
@@ -76,7 +77,7 @@ public void setPillarSelectorConfig(@Nullable PillarSelectorConfig pillarSelecto
super.inherit(inheritedConfig);
subPillarType = ConfigUtils.inheritOverwritableProperty(subPillarType, inheritedConfig.getSubPillarType());
subPillarSequenceComparatorClass = ConfigUtils.inheritOverwritableProperty(subPillarSequenceComparatorClass,
- inheritedConfig.getSubPillarSequenceComparatorClass());
+ inheritedConfig.subPillarSequenceComparatorClass);
pillarSelectorConfig = ConfigUtils.inheritConfig(pillarSelectorConfig, inheritedConfig.getPillarSelectorConfig());
return (Config_) this;
}
@@ -84,7 +85,7 @@ public void setPillarSelectorConfig(@Nullable PillarSelectorConfig pillarSelecto
@Override
protected void visitCommonReferencedClasses(@NonNull Consumer> classVisitor) {
super.visitCommonReferencedClasses(classVisitor);
- classVisitor.accept(subPillarSequenceComparatorClass);
+ classVisitor.accept(getSubPillarSequenceComparatorClass());
if (pillarSelectorConfig != null) {
pillarSelectorConfig.visitReferencedClasses(classVisitor);
}
diff --git a/core/src/main/java/ai/timefold/solver/core/config/heuristic/selector/move/generic/MultistageMoveSelectorConfig.java b/core/src/main/java/ai/timefold/solver/core/config/heuristic/selector/move/generic/MultistageMoveSelectorConfig.java
index 150281fb821..9f2129437af 100644
--- a/core/src/main/java/ai/timefold/solver/core/config/heuristic/selector/move/generic/MultistageMoveSelectorConfig.java
+++ b/core/src/main/java/ai/timefold/solver/core/config/heuristic/selector/move/generic/MultistageMoveSelectorConfig.java
@@ -8,6 +8,7 @@
import ai.timefold.solver.core.config.util.ConfigUtils;
import org.jspecify.annotations.NonNull;
+import org.jspecify.annotations.Nullable;
@XmlType(propOrder = {
"stageProviderClass",
@@ -17,30 +18,29 @@
public final class MultistageMoveSelectorConfig extends MoveSelectorConfig {
public static final String XML_ELEMENT_NAME = "multistageMoveSelector";
- private Class> stageProviderClass;
+ private String stageProviderClass;
- private Class> entityClass = null;
+ private String entityClass = null;
private String variableName = null;
// **************************
// Getters/Setters
// **************************
- public Class> getStageProviderClass() {
- return stageProviderClass;
+ public @Nullable Class> getStageProviderClass() {
+ return ConfigUtils.resolveClass(stageProviderClass, "stageProviderClass", this);
}
- public void setStageProviderClass(
- Class> stageProviderClass) {
- this.stageProviderClass = stageProviderClass;
+ public void setStageProviderClass(Class> stageProviderClass) {
+ this.stageProviderClass = stageProviderClass == null ? null : stageProviderClass.getName();
}
- public Class> getEntityClass() {
- return entityClass;
+ public @Nullable Class> getEntityClass() {
+ return ConfigUtils.resolveClass(entityClass, "entityClass", this);
}
public void setEntityClass(Class> entityClass) {
- this.entityClass = entityClass;
+ this.entityClass = entityClass == null ? null : entityClass.getName();
}
public String getVariableName() {
@@ -57,12 +57,12 @@ public void setVariableName(String variableName) {
public @NonNull MultistageMoveSelectorConfig withStageProviderClass(
@NonNull Class> stageProviderClass) {
- this.setStageProviderClass(stageProviderClass);
+ this.stageProviderClass = stageProviderClass.getName();
return this;
}
public @NonNull MultistageMoveSelectorConfig withEntityClass(@NonNull Class> entityClass) {
- this.setEntityClass(entityClass);
+ this.entityClass = entityClass.getName();
return this;
}
@@ -87,7 +87,7 @@ public boolean hasNearbySelectionConfig() {
@Override
public void visitReferencedClasses(@NonNull Consumer> classVisitor) {
- classVisitor.accept(stageProviderClass);
+ classVisitor.accept(getStageProviderClass());
}
@Override
@@ -96,9 +96,9 @@ public void visitReferencedClasses(@NonNull Consumer> classVisitor) {
super.inherit(inheritedConfig);
stageProviderClass =
ConfigUtils.inheritOverwritableProperty(stageProviderClass,
- inheritedConfig.getStageProviderClass());
+ inheritedConfig.stageProviderClass);
entityClass =
- ConfigUtils.inheritOverwritableProperty(entityClass, inheritedConfig.getEntityClass());
+ ConfigUtils.inheritOverwritableProperty(entityClass, inheritedConfig.entityClass);
variableName =
ConfigUtils.inheritOverwritableProperty(variableName, inheritedConfig.getVariableName());
return this;
diff --git a/core/src/main/java/ai/timefold/solver/core/config/heuristic/selector/move/generic/list/ListMultistageMoveSelectorConfig.java b/core/src/main/java/ai/timefold/solver/core/config/heuristic/selector/move/generic/list/ListMultistageMoveSelectorConfig.java
index d6f1e61545a..11fe5837ebb 100644
--- a/core/src/main/java/ai/timefold/solver/core/config/heuristic/selector/move/generic/list/ListMultistageMoveSelectorConfig.java
+++ b/core/src/main/java/ai/timefold/solver/core/config/heuristic/selector/move/generic/list/ListMultistageMoveSelectorConfig.java
@@ -8,6 +8,7 @@
import ai.timefold.solver.core.config.util.ConfigUtils;
import org.jspecify.annotations.NonNull;
+import org.jspecify.annotations.Nullable;
@XmlType(propOrder = {
"stageProviderClass"
@@ -15,19 +16,18 @@
public final class ListMultistageMoveSelectorConfig extends MoveSelectorConfig {
public static final String XML_ELEMENT_NAME = "listMultistageMoveSelector";
- private Class> stageProviderClass;
+ private String stageProviderClass;
// **************************
// Getters/Setters
// **************************
- public Class> getStageProviderClass() {
- return stageProviderClass;
+ public @Nullable Class> getStageProviderClass() {
+ return ConfigUtils.resolveClass(stageProviderClass, "stageProviderClass", this);
}
- public void setStageProviderClass(
- Class> stageProviderClass) {
- this.stageProviderClass = stageProviderClass;
+ public void setStageProviderClass(Class> stageProviderClass) {
+ this.stageProviderClass = stageProviderClass == null ? null : stageProviderClass.getName();
}
// **************************
@@ -36,7 +36,7 @@ public void setStageProviderClass(
public @NonNull ListMultistageMoveSelectorConfig withStageProviderClass(
@NonNull Class> stageProviderClass) {
- this.setStageProviderClass(stageProviderClass);
+ this.stageProviderClass = stageProviderClass.getName();
return this;
}
@@ -56,7 +56,7 @@ public boolean hasNearbySelectionConfig() {
@Override
public void visitReferencedClasses(@NonNull Consumer> classVisitor) {
- classVisitor.accept(stageProviderClass);
+ classVisitor.accept(getStageProviderClass());
}
@Override
@@ -65,7 +65,7 @@ public void visitReferencedClasses(@NonNull Consumer> classVisitor) {
super.inherit(inheritedConfig);
stageProviderClass =
ConfigUtils.inheritOverwritableProperty(stageProviderClass,
- inheritedConfig.getStageProviderClass());
+ inheritedConfig.stageProviderClass);
return this;
}
}
diff --git a/core/src/main/java/ai/timefold/solver/core/config/heuristic/selector/value/ValueSelectorConfig.java b/core/src/main/java/ai/timefold/solver/core/config/heuristic/selector/value/ValueSelectorConfig.java
index 7bca8979033..72893962dd7 100644
--- a/core/src/main/java/ai/timefold/solver/core/config/heuristic/selector/value/ValueSelectorConfig.java
+++ b/core/src/main/java/ai/timefold/solver/core/config/heuristic/selector/value/ValueSelectorConfig.java
@@ -51,7 +51,7 @@ public final class ValueSelectorConfig extends SelectorConfig downcastEntityClass = null;
+ private String downcastEntityClass = null;
@XmlAttribute
@Nullable
private String variableName = null;
@@ -66,21 +66,21 @@ public final class ValueSelectorConfig extends SelectorConfig filterClass = null;
+ private String filterClass = null;
@Nullable
private ValueSorterManner sorterManner = null;
@Nullable
- private Class extends Comparator> comparatorClass = null;
+ private String comparatorClass = null;
@Nullable
- private Class extends ComparatorFactory> comparatorFactoryClass = null;
+ private String comparatorFactoryClass = null;
@Nullable
private SelectionSorterOrder sorterOrder = null;
@Nullable
- private Class extends SelectionSorter> sorterClass = null;
+ private String sorterClass = null;
@Nullable
- private Class extends SelectionProbabilityWeightFactory> probabilityWeightFactoryClass = null;
+ private String probabilityWeightFactoryClass = null;
@Nullable
private Long selectedCountLimit = null;
@@ -115,11 +115,11 @@ public void setMimicSelectorRef(@Nullable String mimicSelectorRef) {
}
public @Nullable Class> getDowncastEntityClass() {
- return downcastEntityClass;
+ return ConfigUtils.resolveClass(downcastEntityClass, "downcastEntityClass", this);
}
public void setDowncastEntityClass(@Nullable Class> downcastEntityClass) {
- this.downcastEntityClass = downcastEntityClass;
+ this.downcastEntityClass = downcastEntityClass == null ? null : downcastEntityClass.getName();
}
public @Nullable String getVariableName() {
@@ -155,11 +155,11 @@ public void setNearbySelectionConfig(@Nullable NearbySelectionConfig nearbySelec
}
public @Nullable Class extends SelectionFilter> getFilterClass() {
- return filterClass;
+ return ConfigUtils.resolveClass(filterClass, "filterClass", this);
}
public void setFilterClass(@Nullable Class extends SelectionFilter> filterClass) {
- this.filterClass = filterClass;
+ this.filterClass = filterClass == null ? null : filterClass.getName();
}
public @Nullable ValueSorterManner getSorterManner() {
@@ -171,19 +171,19 @@ public void setSorterManner(@Nullable ValueSorterManner sorterManner) {
}
public @Nullable Class extends Comparator> getComparatorClass() {
- return comparatorClass;
+ return ConfigUtils.resolveClass(comparatorClass, "comparatorClass", this);
}
public void setComparatorClass(@Nullable Class extends Comparator> comparatorClass) {
- this.comparatorClass = comparatorClass;
+ this.comparatorClass = comparatorClass == null ? null : comparatorClass.getName();
}
public @Nullable Class extends ComparatorFactory> getComparatorFactoryClass() {
- return comparatorFactoryClass;
+ return ConfigUtils.resolveClass(comparatorFactoryClass, "comparatorFactoryClass", this);
}
public void setComparatorFactoryClass(@Nullable Class extends ComparatorFactory> comparatorFactoryClass) {
- this.comparatorFactoryClass = comparatorFactoryClass;
+ this.comparatorFactoryClass = comparatorFactoryClass == null ? null : comparatorFactoryClass.getName();
}
public @Nullable SelectionSorterOrder getSorterOrder() {
@@ -195,20 +195,21 @@ public void setSorterOrder(@Nullable SelectionSorterOrder sorterOrder) {
}
public @Nullable Class extends SelectionSorter> getSorterClass() {
- return sorterClass;
+ return ConfigUtils.resolveClass(sorterClass, "sorterClass", this);
}
public void setSorterClass(@Nullable Class extends SelectionSorter> sorterClass) {
- this.sorterClass = sorterClass;
+ this.sorterClass = sorterClass == null ? null : sorterClass.getName();
}
public @Nullable Class extends SelectionProbabilityWeightFactory> getProbabilityWeightFactoryClass() {
- return probabilityWeightFactoryClass;
+ return ConfigUtils.resolveClass(probabilityWeightFactoryClass, "probabilityWeightFactoryClass", this);
}
public void setProbabilityWeightFactoryClass(
@Nullable Class extends SelectionProbabilityWeightFactory> probabilityWeightFactoryClass) {
- this.probabilityWeightFactoryClass = probabilityWeightFactoryClass;
+ this.probabilityWeightFactoryClass =
+ probabilityWeightFactoryClass == null ? null : probabilityWeightFactoryClass.getName();
}
public @Nullable Long getSelectedCountLimit() {
@@ -234,7 +235,7 @@ public ValueSelectorConfig withMimicSelectorRef(String mimicSelectorRef) {
}
public ValueSelectorConfig withDowncastEntityClass(Class> entityClass) {
- this.setDowncastEntityClass(entityClass);
+ this.downcastEntityClass = entityClass.getName();
return this;
}
@@ -259,7 +260,7 @@ public ValueSelectorConfig withNearbySelectionConfig(NearbySelectionConfig nearb
}
public ValueSelectorConfig withFilterClass(Class extends SelectionFilter> filterClass) {
- this.setFilterClass(filterClass);
+ this.filterClass = filterClass.getName();
return this;
}
@@ -269,13 +270,12 @@ public ValueSelectorConfig withSorterManner(ValueSorterManner sorterManner) {
}
public ValueSelectorConfig withComparatorClass(Class extends Comparator> comparatorClass) {
- this.setComparatorClass(comparatorClass);
+ this.comparatorClass = comparatorClass.getName();
return this;
}
- public ValueSelectorConfig
- withComparatorFactoryClass(Class extends ComparatorFactory> comparatorFactoryClass) {
- this.setComparatorFactoryClass(comparatorFactoryClass);
+ public ValueSelectorConfig withComparatorFactoryClass(Class extends ComparatorFactory> comparatorFactoryClass) {
+ this.comparatorFactoryClass = comparatorFactoryClass.getName();
return this;
}
@@ -285,13 +285,13 @@ public ValueSelectorConfig withSorterOrder(SelectionSorterOrder sorterOrder) {
}
public ValueSelectorConfig withSorterClass(Class extends SelectionSorter> sorterClass) {
- this.setSorterClass(sorterClass);
+ this.sorterClass = sorterClass.getName();
return this;
}
public ValueSelectorConfig
withProbabilityWeightFactoryClass(Class extends SelectionProbabilityWeightFactory> factoryClass) {
- this.setProbabilityWeightFactoryClass(factoryClass);
+ this.probabilityWeightFactoryClass = factoryClass.getName();
return this;
}
@@ -310,24 +310,24 @@ public ValueSelectorConfig inherit(ValueSelectorConfig inheritedConfig) {
mimicSelectorRef = ConfigUtils.inheritOverwritableProperty(mimicSelectorRef,
inheritedConfig.getMimicSelectorRef());
downcastEntityClass = ConfigUtils.inheritOverwritableProperty(downcastEntityClass,
- inheritedConfig.getDowncastEntityClass());
+ inheritedConfig.downcastEntityClass);
variableName = ConfigUtils.inheritOverwritableProperty(variableName, inheritedConfig.getVariableName());
nearbySelectionConfig = ConfigUtils.inheritConfig(nearbySelectionConfig, inheritedConfig.getNearbySelectionConfig());
- filterClass = ConfigUtils.inheritOverwritableProperty(filterClass, inheritedConfig.getFilterClass());
+ filterClass = ConfigUtils.inheritOverwritableProperty(filterClass, inheritedConfig.filterClass);
cacheType = ConfigUtils.inheritOverwritableProperty(cacheType, inheritedConfig.getCacheType());
selectionOrder = ConfigUtils.inheritOverwritableProperty(selectionOrder, inheritedConfig.getSelectionOrder());
sorterManner = ConfigUtils.inheritOverwritableProperty(
sorterManner, inheritedConfig.getSorterManner());
comparatorClass = ConfigUtils.inheritOverwritableProperty(
- comparatorClass, inheritedConfig.getComparatorClass());
+ comparatorClass, inheritedConfig.comparatorClass);
comparatorFactoryClass = ConfigUtils.inheritOverwritableProperty(
- comparatorFactoryClass, inheritedConfig.getComparatorFactoryClass());
+ comparatorFactoryClass, inheritedConfig.comparatorFactoryClass);
sorterOrder = ConfigUtils.inheritOverwritableProperty(
sorterOrder, inheritedConfig.getSorterOrder());
sorterClass = ConfigUtils.inheritOverwritableProperty(
- sorterClass, inheritedConfig.getSorterClass());
+ sorterClass, inheritedConfig.sorterClass);
probabilityWeightFactoryClass = ConfigUtils.inheritOverwritableProperty(
- probabilityWeightFactoryClass, inheritedConfig.getProbabilityWeightFactoryClass());
+ probabilityWeightFactoryClass, inheritedConfig.probabilityWeightFactoryClass);
selectedCountLimit = ConfigUtils.inheritOverwritableProperty(
selectedCountLimit, inheritedConfig.getSelectedCountLimit());
return this;
@@ -340,15 +340,15 @@ public ValueSelectorConfig copyConfig() {
@Override
public void visitReferencedClasses(Consumer> classVisitor) {
- classVisitor.accept(downcastEntityClass);
+ classVisitor.accept(getDowncastEntityClass());
if (nearbySelectionConfig != null) {
nearbySelectionConfig.visitReferencedClasses(classVisitor);
}
- classVisitor.accept(filterClass);
- classVisitor.accept(comparatorClass);
- classVisitor.accept(comparatorFactoryClass);
- classVisitor.accept(sorterClass);
- classVisitor.accept(probabilityWeightFactoryClass);
+ classVisitor.accept(getFilterClass());
+ classVisitor.accept(getComparatorClass());
+ classVisitor.accept(getComparatorFactoryClass());
+ classVisitor.accept(getSorterClass());
+ classVisitor.accept(getProbabilityWeightFactoryClass());
}
@Override
diff --git a/core/src/main/java/ai/timefold/solver/core/config/localsearch/LocalSearchPhaseConfig.java b/core/src/main/java/ai/timefold/solver/core/config/localsearch/LocalSearchPhaseConfig.java
index 5e1aea0440d..1dcad0c1371 100644
--- a/core/src/main/java/ai/timefold/solver/core/config/localsearch/LocalSearchPhaseConfig.java
+++ b/core/src/main/java/ai/timefold/solver/core/config/localsearch/LocalSearchPhaseConfig.java
@@ -74,7 +74,7 @@ public final class LocalSearchPhaseConfig extends PhaseConfig neighborhoodProviderClass = null;
+ private String neighborhoodProviderClass = null;
@XmlElement(name = "acceptor")
private LocalSearchAcceptorConfig acceptorConfig = null;
@XmlElement(name = "forager")
@@ -110,7 +110,7 @@ public void setMoveSelectorConfig(@Nullable MoveSelectorConfig moveSelectorConfi
*/
@SuppressWarnings("unchecked")
public @Nullable Class extends NeighborhoodProvider> getNeighborhoodProviderClass() {
- return (Class extends NeighborhoodProvider>) neighborhoodProviderClass;
+ return ConfigUtils.resolveClass(neighborhoodProviderClass, "neighborhoodProviderClass", this);
}
/**
@@ -118,7 +118,7 @@ public void setMoveSelectorConfig(@Nullable MoveSelectorConfig moveSelectorConfi
*/
@SuppressWarnings("rawtypes")
public void setNeighborhoodProviderClass(@Nullable Class extends NeighborhoodProvider> neighborhoodProviderClass) {
- this.neighborhoodProviderClass = neighborhoodProviderClass;
+ this.neighborhoodProviderClass = neighborhoodProviderClass == null ? null : neighborhoodProviderClass.getName();
}
public @Nullable LocalSearchAcceptorConfig getAcceptorConfig() {
@@ -156,7 +156,7 @@ public void setForagerConfig(@Nullable LocalSearchForagerConfig foragerConfig) {
*/
public @NonNull LocalSearchPhaseConfig
withMoveProviderClass(@NonNull Class extends NeighborhoodProvider>> moveProviderClass) {
- this.neighborhoodProviderClass = moveProviderClass;
+ this.neighborhoodProviderClass = moveProviderClass.getName();
return this;
}
@@ -177,8 +177,8 @@ public void setForagerConfig(@Nullable LocalSearchForagerConfig foragerConfig) {
inheritedConfig.getLocalSearchType());
setMoveSelectorConfig(ConfigUtils.inheritOverwritableProperty(
getMoveSelectorConfig(), inheritedConfig.getMoveSelectorConfig()));
- setNeighborhoodProviderClass(ConfigUtils.inheritOverwritableProperty(getNeighborhoodProviderClass(),
- inheritedConfig.getNeighborhoodProviderClass()));
+ neighborhoodProviderClass = ConfigUtils.inheritOverwritableProperty(neighborhoodProviderClass,
+ inheritedConfig.neighborhoodProviderClass);
acceptorConfig = ConfigUtils.inheritConfig(acceptorConfig, inheritedConfig.getAcceptorConfig());
foragerConfig = ConfigUtils.inheritConfig(foragerConfig, inheritedConfig.getForagerConfig());
return this;
@@ -198,7 +198,7 @@ public void visitReferencedClasses(@NonNull Consumer> classVisitor) {
moveSelectorConfig.visitReferencedClasses(classVisitor);
}
if (neighborhoodProviderClass != null) {
- classVisitor.accept(neighborhoodProviderClass);
+ classVisitor.accept(getNeighborhoodProviderClass());
}
if (acceptorConfig != null) {
acceptorConfig.visitReferencedClasses(classVisitor);
diff --git a/core/src/main/java/ai/timefold/solver/core/config/partitionedsearch/PartitionedSearchPhaseConfig.java b/core/src/main/java/ai/timefold/solver/core/config/partitionedsearch/PartitionedSearchPhaseConfig.java
index 71e70b15d48..6a53bd231a3 100644
--- a/core/src/main/java/ai/timefold/solver/core/config/partitionedsearch/PartitionedSearchPhaseConfig.java
+++ b/core/src/main/java/ai/timefold/solver/core/config/partitionedsearch/PartitionedSearchPhaseConfig.java
@@ -37,7 +37,7 @@ public final class PartitionedSearchPhaseConfig extends PhaseConfig> solutionPartitionerClass = null;
+ private String solutionPartitionerClass = null;
@XmlJavaTypeAdapter(JaxbCustomPropertiesAdapter.class)
private Map solutionPartitionerCustomProperties = null;
@@ -58,11 +58,11 @@ public final class PartitionedSearchPhaseConfig extends PhaseConfig> getSolutionPartitionerClass() {
- return solutionPartitionerClass;
+ return ConfigUtils.resolveClass(solutionPartitionerClass, "solutionPartitionerClass", this);
}
public void setSolutionPartitionerClass(@Nullable Class extends SolutionPartitioner>> solutionPartitionerClass) {
- this.solutionPartitionerClass = solutionPartitionerClass;
+ this.solutionPartitionerClass = solutionPartitionerClass == null ? null : solutionPartitionerClass.getName();
}
public @Nullable Map getSolutionPartitionerCustomProperties() {
@@ -119,7 +119,7 @@ public void setPhaseConfigList(@Nullable List<@NonNull PhaseConfig> phaseConfigL
public @NonNull PartitionedSearchPhaseConfig withSolutionPartitionerClass(
@NonNull Class extends SolutionPartitioner>> solutionPartitionerClass) {
- this.setSolutionPartitionerClass(solutionPartitionerClass);
+ this.solutionPartitionerClass = solutionPartitionerClass.getName();
return this;
}
@@ -148,7 +148,7 @@ public void setPhaseConfigList(@Nullable List<@NonNull PhaseConfig> phaseConfigL
public @NonNull PartitionedSearchPhaseConfig inherit(@NonNull PartitionedSearchPhaseConfig inheritedConfig) {
super.inherit(inheritedConfig);
solutionPartitionerClass = ConfigUtils.inheritOverwritableProperty(solutionPartitionerClass,
- inheritedConfig.getSolutionPartitionerClass());
+ inheritedConfig.solutionPartitionerClass);
solutionPartitionerCustomProperties = ConfigUtils.inheritMergeableMapProperty(
solutionPartitionerCustomProperties, inheritedConfig.getSolutionPartitionerCustomProperties());
runnablePartThreadLimit = ConfigUtils.inheritOverwritableProperty(runnablePartThreadLimit,
@@ -168,7 +168,7 @@ public void visitReferencedClasses(@NonNull Consumer> classVisitor) {
if (terminationConfig != null) {
terminationConfig.visitReferencedClasses(classVisitor);
}
- classVisitor.accept(solutionPartitionerClass);
+ classVisitor.accept(getSolutionPartitionerClass());
if (phaseConfigList != null) {
phaseConfigList.forEach(pc -> pc.visitReferencedClasses(classVisitor));
}
diff --git a/core/src/main/java/ai/timefold/solver/core/config/phase/custom/CustomPhaseConfig.java b/core/src/main/java/ai/timefold/solver/core/config/phase/custom/CustomPhaseConfig.java
index 0b2062fbd2b..e9ba02129d6 100644
--- a/core/src/main/java/ai/timefold/solver/core/config/phase/custom/CustomPhaseConfig.java
+++ b/core/src/main/java/ai/timefold/solver/core/config/phase/custom/CustomPhaseConfig.java
@@ -1,7 +1,6 @@
package ai.timefold.solver.core.config.phase.custom;
import java.util.Arrays;
-import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.Objects;
@@ -34,7 +33,7 @@ public final class CustomPhaseConfig extends PhaseConfig {
@XmlElement(name = "customPhaseCommandClass")
@Nullable
- private List> customPhaseCommandClassList = null;
+ private List customPhaseCommandClassList = null;
@XmlJavaTypeAdapter(JaxbCustomPropertiesAdapter.class)
@Nullable
@@ -49,11 +48,15 @@ public final class CustomPhaseConfig extends PhaseConfig {
// ************************************************************************
public @Nullable List> getCustomPhaseCommandClassList() {
- return customPhaseCommandClassList;
+ if (customPhaseCommandClassList == null) {
+ return null;
+ }
+ return ConfigUtils.resolveClasses(customPhaseCommandClassList, "customPhaseCommandClass", this);
}
public void setCustomPhaseCommandClassList(@Nullable List> customPhaseCommandClassList) {
- this.customPhaseCommandClassList = customPhaseCommandClassList;
+ this.customPhaseCommandClassList = customPhaseCommandClassList == null ? null
+ : customPhaseCommandClassList.stream().map(Class::getName).toList();
}
public @Nullable Map getCustomProperties() {
@@ -77,7 +80,7 @@ public void setCustomPhaseCommandList(@Nullable List extends PhaseCommand> cus
// ************************************************************************
public CustomPhaseConfig withCustomPhaseCommandClassList(List> customPhaseCommandClassList) {
- this.customPhaseCommandClassList = customPhaseCommandClassList;
+ this.customPhaseCommandClassList = customPhaseCommandClassList.stream().map(Class::getName).toList();
return this;
}
@@ -87,11 +90,10 @@ public CustomPhaseConfig withCustomProperties(Map customProperti
}
public CustomPhaseConfig withCustomPhaseCommandList(List extends PhaseCommand> customPhaseCommandList) {
- boolean hasNullCommand = Objects.requireNonNullElse(customPhaseCommandList, Collections.emptyList())
- .stream().anyMatch(Objects::isNull);
+ var hasNullCommand = customPhaseCommandList.stream().anyMatch(Objects::isNull);
if (hasNullCommand) {
- throw new IllegalArgumentException(
- "Custom phase commands (" + customPhaseCommandList + ") must not contain a null element.");
+ throw new IllegalArgumentException("Custom phase commands (%s) must not contain a null element."
+ .formatted(customPhaseCommandList));
}
this.customPhaseCommandList = List.copyOf(customPhaseCommandList);
return this;
@@ -106,7 +108,7 @@ public CustomPhaseConfig withCustomPhaseCommands(PhaseCommand> classVisitor) {
terminationConfig.visitReferencedClasses(classVisitor);
}
if (customPhaseCommandClassList != null) {
- customPhaseCommandClassList.forEach(classVisitor);
+ getCustomPhaseCommandClassList().forEach(classVisitor);
}
}
diff --git a/core/src/main/java/ai/timefold/solver/core/config/score/director/ScoreDirectorFactoryConfig.java b/core/src/main/java/ai/timefold/solver/core/config/score/director/ScoreDirectorFactoryConfig.java
index 1fcb443c2ec..8d897b4e638 100644
--- a/core/src/main/java/ai/timefold/solver/core/config/score/director/ScoreDirectorFactoryConfig.java
+++ b/core/src/main/java/ai/timefold/solver/core/config/score/director/ScoreDirectorFactoryConfig.java
@@ -31,12 +31,12 @@
})
public final class ScoreDirectorFactoryConfig extends AbstractConfig {
- private Class extends EasyScoreCalculator> easyScoreCalculatorClass = null;
+ private String easyScoreCalculatorClass = null;
@XmlJavaTypeAdapter(JaxbCustomPropertiesAdapter.class)
private Map easyScoreCalculatorCustomProperties = null;
- private Class extends ConstraintProvider> constraintProviderClass = null;
+ private String constraintProviderClass = null;
@XmlJavaTypeAdapter(JaxbCustomPropertiesAdapter.class)
private Map constraintProviderCustomProperties = null;
@@ -44,7 +44,7 @@ public final class ScoreDirectorFactoryConfig extends AbstractConfig incrementalScoreCalculatorClass = null;
+ private String incrementalScoreCalculatorClass = null;
@XmlJavaTypeAdapter(JaxbCustomPropertiesAdapter.class)
private Map incrementalScoreCalculatorCustomProperties = null;
@@ -60,11 +60,11 @@ public final class ScoreDirectorFactoryConfig extends AbstractConfig getEasyScoreCalculatorClass() {
- return easyScoreCalculatorClass;
+ return ConfigUtils.resolveClass(easyScoreCalculatorClass, "easyScoreCalculatorClass", this);
}
public void setEasyScoreCalculatorClass(@Nullable Class extends EasyScoreCalculator> easyScoreCalculatorClass) {
- this.easyScoreCalculatorClass = easyScoreCalculatorClass;
+ this.easyScoreCalculatorClass = easyScoreCalculatorClass == null ? null : easyScoreCalculatorClass.getName();
}
public @Nullable Map<@NonNull String, @NonNull String> getEasyScoreCalculatorCustomProperties() {
@@ -77,11 +77,11 @@ public void setEasyScoreCalculatorCustomProperties(
}
public @Nullable Class extends ConstraintProvider> getConstraintProviderClass() {
- return constraintProviderClass;
+ return ConfigUtils.resolveClass(constraintProviderClass, "constraintProviderClass", this);
}
public void setConstraintProviderClass(@Nullable Class extends ConstraintProvider> constraintProviderClass) {
- this.constraintProviderClass = constraintProviderClass;
+ this.constraintProviderClass = constraintProviderClass == null ? null : constraintProviderClass.getName();
}
public @Nullable Map<@NonNull String, @NonNull String> getConstraintProviderCustomProperties() {
@@ -111,12 +111,13 @@ public void setConstraintStreamProfilingEnabled(Boolean constraintStreamProfilin
}
public @Nullable Class extends IncrementalScoreCalculator> getIncrementalScoreCalculatorClass() {
- return incrementalScoreCalculatorClass;
+ return ConfigUtils.resolveClass(incrementalScoreCalculatorClass, "incrementalScoreCalculatorClass", this);
}
public void setIncrementalScoreCalculatorClass(
@Nullable Class extends IncrementalScoreCalculator> incrementalScoreCalculatorClass) {
- this.incrementalScoreCalculatorClass = incrementalScoreCalculatorClass;
+ this.incrementalScoreCalculatorClass =
+ incrementalScoreCalculatorClass == null ? null : incrementalScoreCalculatorClass.getName();
}
public @Nullable Map<@NonNull String, @NonNull String> getIncrementalScoreCalculatorCustomProperties() {
@@ -150,7 +151,7 @@ public void setAssertionScoreDirectorFactory(@Nullable ScoreDirectorFactoryConfi
public @NonNull ScoreDirectorFactoryConfig
withEasyScoreCalculatorClass(@NonNull Class extends EasyScoreCalculator> easyScoreCalculatorClass) {
- this.easyScoreCalculatorClass = easyScoreCalculatorClass;
+ this.easyScoreCalculatorClass = easyScoreCalculatorClass.getName();
return this;
}
@@ -163,7 +164,7 @@ public void setAssertionScoreDirectorFactory(@Nullable ScoreDirectorFactoryConfi
public @NonNull ScoreDirectorFactoryConfig
withConstraintProviderClass(@NonNull Class extends ConstraintProvider> constraintProviderClass) {
- this.constraintProviderClass = constraintProviderClass;
+ this.constraintProviderClass = constraintProviderClass.getName();
return this;
}
@@ -189,7 +190,7 @@ public void setAssertionScoreDirectorFactory(@Nullable ScoreDirectorFactoryConfi
public @NonNull ScoreDirectorFactoryConfig
withIncrementalScoreCalculatorClass(
@NonNull Class extends IncrementalScoreCalculator> incrementalScoreCalculatorClass) {
- this.incrementalScoreCalculatorClass = incrementalScoreCalculatorClass;
+ this.incrementalScoreCalculatorClass = incrementalScoreCalculatorClass.getName();
return this;
}
@@ -214,11 +215,11 @@ public void setAssertionScoreDirectorFactory(@Nullable ScoreDirectorFactoryConfi
@Override
public @NonNull ScoreDirectorFactoryConfig inherit(@NonNull ScoreDirectorFactoryConfig inheritedConfig) {
easyScoreCalculatorClass = ConfigUtils.inheritOverwritableProperty(
- easyScoreCalculatorClass, inheritedConfig.getEasyScoreCalculatorClass());
+ easyScoreCalculatorClass, inheritedConfig.easyScoreCalculatorClass);
easyScoreCalculatorCustomProperties = ConfigUtils.inheritMergeableMapProperty(
easyScoreCalculatorCustomProperties, inheritedConfig.getEasyScoreCalculatorCustomProperties());
constraintProviderClass = ConfigUtils.inheritOverwritableProperty(
- constraintProviderClass, inheritedConfig.getConstraintProviderClass());
+ constraintProviderClass, inheritedConfig.constraintProviderClass);
constraintProviderCustomProperties = ConfigUtils.inheritMergeableMapProperty(
constraintProviderCustomProperties, inheritedConfig.getConstraintProviderCustomProperties());
constraintStreamAutomaticNodeSharing = ConfigUtils.inheritOverwritableProperty(constraintStreamAutomaticNodeSharing,
@@ -226,7 +227,7 @@ public void setAssertionScoreDirectorFactory(@Nullable ScoreDirectorFactoryConfi
constraintStreamProfilingEnabled = ConfigUtils.inheritOverwritableProperty(constraintStreamProfilingEnabled,
inheritedConfig.getConstraintStreamProfilingEnabled());
incrementalScoreCalculatorClass = ConfigUtils.inheritOverwritableProperty(
- incrementalScoreCalculatorClass, inheritedConfig.getIncrementalScoreCalculatorClass());
+ incrementalScoreCalculatorClass, inheritedConfig.incrementalScoreCalculatorClass);
incrementalScoreCalculatorCustomProperties = ConfigUtils.inheritMergeableMapProperty(
incrementalScoreCalculatorCustomProperties, inheritedConfig.getIncrementalScoreCalculatorCustomProperties());
initializingScoreTrend = ConfigUtils.inheritOverwritableProperty(
@@ -243,9 +244,9 @@ public void setAssertionScoreDirectorFactory(@Nullable ScoreDirectorFactoryConfi
@Override
public void visitReferencedClasses(@NonNull Consumer> classVisitor) {
- classVisitor.accept(easyScoreCalculatorClass);
- classVisitor.accept(constraintProviderClass);
- classVisitor.accept(incrementalScoreCalculatorClass);
+ classVisitor.accept(getEasyScoreCalculatorClass());
+ classVisitor.accept(getConstraintProviderClass());
+ classVisitor.accept(getIncrementalScoreCalculatorClass());
if (assertionScoreDirectorFactory != null) {
assertionScoreDirectorFactory.visitReferencedClasses(classVisitor);
}
diff --git a/core/src/main/java/ai/timefold/solver/core/config/solver/SolverConfig.java b/core/src/main/java/ai/timefold/solver/core/config/solver/SolverConfig.java
index cef89d74d48..ed43fb1bceb 100644
--- a/core/src/main/java/ai/timefold/solver/core/config/solver/SolverConfig.java
+++ b/core/src/main/java/ai/timefold/solver/core/config/solver/SolverConfig.java
@@ -19,6 +19,7 @@
import java.util.Set;
import java.util.concurrent.ThreadFactory;
import java.util.function.Consumer;
+import java.util.stream.Collectors;
import jakarta.xml.bind.annotation.XmlElement;
import jakarta.xml.bind.annotation.XmlElements;
@@ -215,12 +216,12 @@ public final class SolverConfig extends AbstractConfig {
private Long randomSeed = null;
private String moveThreadCount = null;
private Integer moveThreadBufferSize = null;
- private Class extends ThreadFactory> threadFactoryClass = null;
+ private String threadFactoryClass = null;
- private Class> solutionClass = null;
+ private String solutionClass = null;
@XmlElement(name = "entityClass")
- private List> entityClassList = null;
+ private List entityClassList = null;
@XmlTransient
private Map gizmoMemberAccessorMap = null;
@XmlTransient
@@ -232,7 +233,7 @@ public final class SolverConfig extends AbstractConfig {
@XmlElement(name = "termination")
private TerminationConfig terminationConfig;
- private Class extends NearbyDistanceMeter, ?>> nearbyDistanceMeterClass = null;
+ private String nearbyDistanceMeterClass = null;
@XmlElements({
@XmlElement(name = ConstructionHeuristicPhaseConfig.XML_ELEMENT_NAME,
@@ -364,27 +365,31 @@ public void setMoveThreadBufferSize(@Nullable Integer moveThreadBufferSize) {
}
public @Nullable Class extends ThreadFactory> getThreadFactoryClass() {
- return threadFactoryClass;
+ return ConfigUtils.resolveClass(threadFactoryClass, "threadFactoryClass", this);
}
public void setThreadFactoryClass(@Nullable Class extends ThreadFactory> threadFactoryClass) {
- this.threadFactoryClass = threadFactoryClass;
+ this.threadFactoryClass = threadFactoryClass == null ? null : threadFactoryClass.getName();
}
public @Nullable Class> getSolutionClass() {
- return solutionClass;
+ return ConfigUtils.resolveClass(solutionClass, "solutionClass", this);
}
public void setSolutionClass(@Nullable Class> solutionClass) {
- this.solutionClass = solutionClass;
+ this.solutionClass = solutionClass == null ? null : solutionClass.getName();
}
public @Nullable List> getEntityClassList() {
- return entityClassList;
+ if (entityClassList == null) {
+ return null;
+ }
+ return ConfigUtils.resolveClasses(entityClassList, "entityClass", this);
}
public void setEntityClassList(@Nullable List> entityClassList) {
- this.entityClassList = entityClassList;
+ this.entityClassList = entityClassList == null ? null
+ : entityClassList.stream().map(Class::getName).collect(Collectors.toList());
}
public @Nullable Map<@NonNull String, @NonNull MemberAccessor> getGizmoMemberAccessorMap() {
@@ -420,11 +425,11 @@ public void setTerminationConfig(@Nullable TerminationConfig terminationConfig)
}
public @Nullable Class extends NearbyDistanceMeter, ?>> getNearbyDistanceMeterClass() {
- return nearbyDistanceMeterClass;
+ return ConfigUtils.resolveClass(nearbyDistanceMeterClass, "nearbyDistanceMeterClass", this);
}
public void setNearbyDistanceMeterClass(@Nullable Class extends NearbyDistanceMeter, ?>> nearbyDistanceMeterClass) {
- this.nearbyDistanceMeterClass = nearbyDistanceMeterClass;
+ this.nearbyDistanceMeterClass = nearbyDistanceMeterClass == null ? null : nearbyDistanceMeterClass.getName();
}
public @Nullable List<@NonNull PhaseConfig> getPhaseConfigList() {
@@ -478,22 +483,22 @@ public void setMonitoringConfig(@Nullable MonitoringConfig monitoringConfig) {
}
public @NonNull SolverConfig withThreadFactoryClass(@NonNull Class extends ThreadFactory> threadFactoryClass) {
- this.threadFactoryClass = threadFactoryClass;
+ this.threadFactoryClass = threadFactoryClass.getName();
return this;
}
public @NonNull SolverConfig withSolutionClass(@NonNull Class> solutionClass) {
- this.solutionClass = solutionClass;
+ this.solutionClass = solutionClass.getName();
return this;
}
public @NonNull SolverConfig withEntityClassList(@NonNull List> entityClassList) {
- this.entityClassList = entityClassList;
+ this.entityClassList = entityClassList.stream().map(Class::getName).collect(Collectors.toList());
return this;
}
public @NonNull SolverConfig withEntityClasses(@NonNull Class>... entityClasses) {
- this.entityClassList = Arrays.asList(entityClasses);
+ this.entityClassList = Arrays.stream(entityClasses).map(Class::getName).collect(Collectors.toList());
return this;
}
@@ -576,7 +581,7 @@ public void setMonitoringConfig(@Nullable MonitoringConfig monitoringConfig) {
public @NonNull SolverConfig
withNearbyDistanceMeterClass(@NonNull Class extends NearbyDistanceMeter, ?>> distanceMeterClass) {
- this.nearbyDistanceMeterClass = distanceMeterClass;
+ this.nearbyDistanceMeterClass = distanceMeterClass.getName();
return this;
}
@@ -656,10 +661,10 @@ public void offerRandomSeedFromSubSingleIndex(long subSingleIndex) {
moveThreadBufferSize = ConfigUtils.inheritOverwritableProperty(moveThreadBufferSize,
inheritedConfig.getMoveThreadBufferSize());
threadFactoryClass = ConfigUtils.inheritOverwritableProperty(threadFactoryClass,
- inheritedConfig.getThreadFactoryClass());
- solutionClass = ConfigUtils.inheritOverwritableProperty(solutionClass, inheritedConfig.getSolutionClass());
+ inheritedConfig.threadFactoryClass);
+ solutionClass = ConfigUtils.inheritOverwritableProperty(solutionClass, inheritedConfig.solutionClass);
entityClassList = ConfigUtils.inheritMergeableListProperty(entityClassList,
- inheritedConfig.getEntityClassList());
+ inheritedConfig.entityClassList);
gizmoMemberAccessorMap = ConfigUtils.inheritMergeableMapProperty(
gizmoMemberAccessorMap, inheritedConfig.getGizmoMemberAccessorMap());
gizmoSolutionClonerMap = ConfigUtils.inheritMergeableMapProperty(
@@ -669,7 +674,7 @@ public void offerRandomSeedFromSubSingleIndex(long subSingleIndex) {
inheritedConfig.getScoreDirectorFactoryConfig());
terminationConfig = ConfigUtils.inheritConfig(terminationConfig, inheritedConfig.getTerminationConfig());
nearbyDistanceMeterClass = ConfigUtils.inheritOverwritableProperty(nearbyDistanceMeterClass,
- inheritedConfig.getNearbyDistanceMeterClass());
+ inheritedConfig.nearbyDistanceMeterClass);
phaseConfigList = ConfigUtils.inheritMergeableListConfig(phaseConfigList, inheritedConfig.getPhaseConfigList());
monitoringConfig = ConfigUtils.inheritConfig(monitoringConfig, inheritedConfig.getMonitoringConfig());
return this;
@@ -682,16 +687,16 @@ public void offerRandomSeedFromSubSingleIndex(long subSingleIndex) {
@Override
public void visitReferencedClasses(@NonNull Consumer> classVisitor) {
- classVisitor.accept(threadFactoryClass);
- classVisitor.accept(solutionClass);
+ classVisitor.accept(getThreadFactoryClass());
+ classVisitor.accept(getSolutionClass());
if (entityClassList != null) {
- entityClassList.forEach(classVisitor);
+ getEntityClassList().forEach(classVisitor);
}
if (scoreDirectorFactoryConfig != null) {
scoreDirectorFactoryConfig.visitReferencedClasses(classVisitor);
}
if (nearbyDistanceMeterClass != null) {
- classVisitor.accept(nearbyDistanceMeterClass);
+ classVisitor.accept(getNearbyDistanceMeterClass());
}
if (terminationConfig != null) {
terminationConfig.visitReferencedClasses(classVisitor);
diff --git a/core/src/main/java/ai/timefold/solver/core/config/solver/SolverManagerConfig.java b/core/src/main/java/ai/timefold/solver/core/config/solver/SolverManagerConfig.java
index bb90c94ead3..56fbd61fa84 100644
--- a/core/src/main/java/ai/timefold/solver/core/config/solver/SolverManagerConfig.java
+++ b/core/src/main/java/ai/timefold/solver/core/config/solver/SolverManagerConfig.java
@@ -24,7 +24,7 @@ public final class SolverManagerConfig extends AbstractConfig threadFactoryClass = null;
+ private String threadFactoryClass = null;
// Future features:
// throttlingDelay
@@ -46,11 +46,11 @@ public void setParallelSolverCount(@Nullable String parallelSolverCount) {
}
public @Nullable Class extends ThreadFactory> getThreadFactoryClass() {
- return threadFactoryClass;
+ return ConfigUtils.resolveClass(threadFactoryClass, "threadFactoryClass", this);
}
public void setThreadFactoryClass(@Nullable Class extends ThreadFactory> threadFactoryClass) {
- this.threadFactoryClass = threadFactoryClass;
+ this.threadFactoryClass = threadFactoryClass == null ? null : threadFactoryClass.getName();
}
// ************************************************************************
@@ -63,7 +63,7 @@ public void setThreadFactoryClass(@Nullable Class extends ThreadFactory> threa
}
public @NonNull SolverManagerConfig withThreadFactoryClass(@NonNull Class extends ThreadFactory> threadFactoryClass) {
- this.threadFactoryClass = threadFactoryClass;
+ this.threadFactoryClass = threadFactoryClass.getName();
return this;
}
@@ -109,7 +109,7 @@ private static int resolveParallelSolverCountAutomatically(int availableProcesso
parallelSolverCount = ConfigUtils.inheritOverwritableProperty(parallelSolverCount,
inheritedConfig.getParallelSolverCount());
threadFactoryClass = ConfigUtils.inheritOverwritableProperty(threadFactoryClass,
- inheritedConfig.getThreadFactoryClass());
+ inheritedConfig.threadFactoryClass);
return this;
}
@@ -120,7 +120,7 @@ private static int resolveParallelSolverCountAutomatically(int availableProcesso
@Override
public void visitReferencedClasses(@NonNull Consumer> classVisitor) {
- classVisitor.accept(threadFactoryClass);
+ classVisitor.accept(getThreadFactoryClass());
}
}
diff --git a/core/src/main/java/ai/timefold/solver/core/config/util/ConfigUtils.java b/core/src/main/java/ai/timefold/solver/core/config/util/ConfigUtils.java
index 0b542e33ebf..f0773b0c32a 100644
--- a/core/src/main/java/ai/timefold/solver/core/config/util/ConfigUtils.java
+++ b/core/src/main/java/ai/timefold/solver/core/config/util/ConfigUtils.java
@@ -45,6 +45,39 @@ public class ConfigUtils {
private static final AlphabeticMemberComparator alphabeticMemberComparator = new AlphabeticMemberComparator();
+ @SuppressWarnings("unchecked")
+ public static @Nullable Class resolveClass(@Nullable String className, @NonNull String fieldName,
+ @NonNull Object context) {
+ if (className == null) {
+ return null;
+ }
+ var trimmedClassName = className.strip();
+ if (trimmedClassName.isEmpty()) {
+ return null;
+ }
+ var classloader = Objects.requireNonNullElse(Thread.currentThread().getContextClassLoader(),
+ ConfigUtils.class.getClassLoader());
+ try {
+ return (Class) Class.forName(trimmedClassName, false, classloader);
+ } catch (ClassNotFoundException e) {
+ throw new IllegalArgumentException(
+ "The %s (%s) of %s cannot be found.".formatted(fieldName, trimmedClassName, context), e);
+ }
+ }
+
+ @SuppressWarnings({ "unchecked", "rawtypes" })
+ public static List> resolveClasses(List<@Nullable String> classList, @NonNull String fieldName,
+ @NonNull Object context) {
+ return (List) classList.stream()
+ .map(cn -> ConfigUtils.resolveClass(cn, fieldName, context))
+ .peek(clz -> {
+ if (clz == null) {
+ throw new IllegalArgumentException(
+ "The %s of %s cannot be null or empty.".formatted(fieldName, context));
+ }
+ }).toList();
+ }
+
/**
* Create a new instance of clazz from a config's property.
*
diff --git a/core/src/main/java/ai/timefold/solver/core/impl/neighborhood/stream/BiRandomMoveIterator.java b/core/src/main/java/ai/timefold/solver/core/impl/neighborhood/stream/BiRandomMoveIterator.java
index 2144b5ef14d..85d00e2cabc 100644
--- a/core/src/main/java/ai/timefold/solver/core/impl/neighborhood/stream/BiRandomMoveIterator.java
+++ b/core/src/main/java/ai/timefold/solver/core/impl/neighborhood/stream/BiRandomMoveIterator.java
@@ -1,7 +1,9 @@
package ai.timefold.solver.core.impl.neighborhood.stream;
import java.util.ArrayList;
+import java.util.HashMap;
import java.util.Iterator;
+import java.util.Map;
import java.util.NoSuchElementException;
import java.util.Objects;
import java.util.random.RandomGenerator;
@@ -60,18 +62,23 @@ final class BiRandomMoveIterator implements Iterator context;
private final RandomGenerator workingRandom;
+ /**
+ * We cannot cache the right iterator on the left tuple,
+ * because that cache would survive across steps and the right iterator would be invalid by then.
+ * The alternative would be worse than this map,
+ * likely requiring some loop over tuples at step end, clearing the cache.
+ */
+ private final Map, Iterator>> leftTupleToRightIteratorMap = new HashMap<>();
// Fields required for iteration.
private final Iterator> leftTupleIterator;
- private final int rightIteratorStoreIndex;
private @Nullable Move nextMove;
public BiRandomMoveIterator(BiMoveStreamContext context, RandomGenerator workingRandom) {
this.context = Objects.requireNonNull(context);
this.workingRandom = Objects.requireNonNull(workingRandom);
- var leftDatasetInstance = context.getLeftDatasetInstance();
- this.rightIteratorStoreIndex = leftDatasetInstance.getRightIteratorStoreIndex();
- this.leftTupleIterator = leftDatasetInstance.randomIterator(workingRandom);
+ this.leftTupleIterator = context.getLeftDatasetInstance()
+ .randomIterator(workingRandom);
}
@Override
@@ -82,10 +89,9 @@ public boolean hasNext() {
while (leftTupleIterator.hasNext()) {
var leftTuple = leftTupleIterator.next();
- var rightEmpty = pickNextMove(leftTuple);
- if (rightEmpty) {
+ if (!pickNextMove(leftTuple)) {
leftTupleIterator.remove();
- leftTuple.setStore(rightIteratorStoreIndex, null);
+ leftTupleToRightIteratorMap.remove(leftTuple);
}
if (nextMove != null) {
if (nextMove instanceof AbstractSelectorBasedMove legacyMove) {
@@ -101,17 +107,20 @@ Please refactor your code (%s) to use the new Move API."""
}
private boolean pickNextMove(UniTuple leftTuple) {
- var rightTupleIterator = (Iterator>) leftTuple.getStore(rightIteratorStoreIndex);
+ var rightTupleIterator = leftTupleToRightIteratorMap.get(leftTuple);
if (rightTupleIterator == null) {
rightTupleIterator = createRightTupleIterator(leftTuple);
- leftTuple.setStore(rightIteratorStoreIndex, rightTupleIterator);
+ if (!rightTupleIterator.hasNext()) {
+ return false;
+ }
+ leftTupleToRightIteratorMap.put(leftTuple, rightTupleIterator);
}
if (!rightTupleIterator.hasNext()) {
- return true;
+ return false;
}
nextMove = context.buildMove(leftTuple.getA(), rightTupleIterator.next().getA());
rightTupleIterator.remove();
- return false;
+ return true;
}
private Iterator> createRightTupleIterator(UniTuple leftTuple) {
diff --git a/core/src/main/java/ai/timefold/solver/core/impl/neighborhood/stream/enumerating/common/AbstractLeftDataset.java b/core/src/main/java/ai/timefold/solver/core/impl/neighborhood/stream/enumerating/common/AbstractLeftDataset.java
index c96bbebbb9e..c1d28919f4c 100644
--- a/core/src/main/java/ai/timefold/solver/core/impl/neighborhood/stream/enumerating/common/AbstractLeftDataset.java
+++ b/core/src/main/java/ai/timefold/solver/core/impl/neighborhood/stream/enumerating/common/AbstractLeftDataset.java
@@ -12,7 +12,6 @@ protected AbstractLeftDataset(AbstractUniEnumeratingStream parent)
super(parent);
}
- public abstract AbstractLeftDatasetInstance> instantiate(int rightSequenceStoreIndex,
- int entryStoreIndex);
+ public abstract AbstractLeftDatasetInstance> instantiate(int entryStoreIndex);
}
diff --git a/core/src/main/java/ai/timefold/solver/core/impl/neighborhood/stream/enumerating/common/AbstractLeftDatasetInstance.java b/core/src/main/java/ai/timefold/solver/core/impl/neighborhood/stream/enumerating/common/AbstractLeftDatasetInstance.java
index 0c32c5967b6..3005eb611fb 100644
--- a/core/src/main/java/ai/timefold/solver/core/impl/neighborhood/stream/enumerating/common/AbstractLeftDatasetInstance.java
+++ b/core/src/main/java/ai/timefold/solver/core/impl/neighborhood/stream/enumerating/common/AbstractLeftDatasetInstance.java
@@ -15,15 +15,9 @@ public abstract class AbstractLeftDatasetInstance {
private final ElementAwareArrayList tupleList = new ElementAwareArrayList<>();
- private final int rightIteratorStoreIndex;
- protected AbstractLeftDatasetInstance(AbstractDataset parent, int rightIteratorStoreIndex, int entryStoreIndex) {
+ protected AbstractLeftDatasetInstance(AbstractDataset parent, int entryStoreIndex) {
super(parent, entryStoreIndex);
- this.rightIteratorStoreIndex = rightIteratorStoreIndex;
- }
-
- public int getRightIteratorStoreIndex() {
- return rightIteratorStoreIndex;
}
@Override
diff --git a/core/src/main/java/ai/timefold/solver/core/impl/neighborhood/stream/enumerating/uni/LeftTerminalUniEnumeratingStream.java b/core/src/main/java/ai/timefold/solver/core/impl/neighborhood/stream/enumerating/uni/LeftTerminalUniEnumeratingStream.java
index 042d46ab4d5..ba9a24935e4 100644
--- a/core/src/main/java/ai/timefold/solver/core/impl/neighborhood/stream/enumerating/uni/LeftTerminalUniEnumeratingStream.java
+++ b/core/src/main/java/ai/timefold/solver/core/impl/neighborhood/stream/enumerating/uni/LeftTerminalUniEnumeratingStream.java
@@ -22,9 +22,7 @@ public LeftTerminalUniEnumeratingStream(EnumeratingStreamFactory enum
@Override
public void buildNode(DataNodeBuildHelper buildHelper) {
assertEmptyChildStreamList();
- var datasetInstance = dataset.instantiate(
- buildHelper.reserveTupleStoreIndex(parent.getTupleSource()),
- buildHelper.reserveTupleStoreIndex(parent.getTupleSource()));
+ var datasetInstance = dataset.instantiate(buildHelper.reserveTupleStoreIndex(parent.getTupleSource()));
buildHelper.putInsertUpdateRetract(this, datasetInstance);
}
diff --git a/core/src/main/java/ai/timefold/solver/core/impl/neighborhood/stream/enumerating/uni/UniLeftDataset.java b/core/src/main/java/ai/timefold/solver/core/impl/neighborhood/stream/enumerating/uni/UniLeftDataset.java
index fc5fa00ad7c..dc86e802fb2 100644
--- a/core/src/main/java/ai/timefold/solver/core/impl/neighborhood/stream/enumerating/uni/UniLeftDataset.java
+++ b/core/src/main/java/ai/timefold/solver/core/impl/neighborhood/stream/enumerating/uni/UniLeftDataset.java
@@ -14,8 +14,8 @@ public UniLeftDataset(AbstractUniEnumeratingStream parent) {
}
@Override
- public UniLeftDatasetInstance instantiate(int rightIteratorStoreIndex, int entryStoreIndex) {
- return new UniLeftDatasetInstance<>(this, rightIteratorStoreIndex, entryStoreIndex);
+ public UniLeftDatasetInstance instantiate(int entryStoreIndex) {
+ return new UniLeftDatasetInstance<>(this, entryStoreIndex);
}
@Override
diff --git a/core/src/main/java/ai/timefold/solver/core/impl/neighborhood/stream/enumerating/uni/UniLeftDatasetInstance.java b/core/src/main/java/ai/timefold/solver/core/impl/neighborhood/stream/enumerating/uni/UniLeftDatasetInstance.java
index 1d28040edbe..b11e75b5420 100644
--- a/core/src/main/java/ai/timefold/solver/core/impl/neighborhood/stream/enumerating/uni/UniLeftDatasetInstance.java
+++ b/core/src/main/java/ai/timefold/solver/core/impl/neighborhood/stream/enumerating/uni/UniLeftDatasetInstance.java
@@ -10,8 +10,8 @@
public final class UniLeftDatasetInstance
extends AbstractLeftDatasetInstance> {
- public UniLeftDatasetInstance(AbstractDataset parent, int rightIteratorStoreIndex, int entryStoreIndex) {
- super(parent, rightIteratorStoreIndex, entryStoreIndex);
+ public UniLeftDatasetInstance(AbstractDataset parent, int entryStoreIndex) {
+ super(parent, entryStoreIndex);
}
}
diff --git a/core/src/main/java/ai/timefold/solver/core/impl/score/stream/test/AbstractMultiConstraintAssertion.java b/core/src/main/java/ai/timefold/solver/core/impl/score/stream/test/AbstractMultiConstraintAssertion.java
index e5a816a319f..ac674a6fba0 100644
--- a/core/src/main/java/ai/timefold/solver/core/impl/score/stream/test/AbstractMultiConstraintAssertion.java
+++ b/core/src/main/java/ai/timefold/solver/core/impl/score/stream/test/AbstractMultiConstraintAssertion.java
@@ -59,7 +59,7 @@ public void scores(@NonNull Score> score, String message) {
@Override
@SuppressWarnings("unchecked")
- public > S score() {
+ public > S getScore() {
ensureInitialized();
return (S) actualScore.raw();
}
diff --git a/core/src/main/java/ai/timefold/solver/core/impl/score/stream/test/AbstractSingleConstraintAssertion.java b/core/src/main/java/ai/timefold/solver/core/impl/score/stream/test/AbstractSingleConstraintAssertion.java
index 794a455d055..0f31c2a34ea 100644
--- a/core/src/main/java/ai/timefold/solver/core/impl/score/stream/test/AbstractSingleConstraintAssertion.java
+++ b/core/src/main/java/ai/timefold/solver/core/impl/score/stream/test/AbstractSingleConstraintAssertion.java
@@ -254,13 +254,13 @@ public void rewardsWithLessThan(@Nullable String message, @NonNull BigDecimal ma
@Override
@SuppressWarnings("unchecked")
- public > S score() {
+ public > S getScore() {
ensureInitialized();
return (S) actualScore.raw();
}
@Override
- public Number impact() {
+ public Number getImpact() {
ensureInitialized();
return deduceImpact().key();
}
diff --git a/core/src/test/java/ai/timefold/solver/core/impl/score/stream/test/MultiConstraintAssertionTest.java b/core/src/test/java/ai/timefold/solver/core/impl/score/stream/test/MultiConstraintAssertionTest.java
index b1dbe2dfcea..0fa5e0fe112 100644
--- a/core/src/test/java/ai/timefold/solver/core/impl/score/stream/test/MultiConstraintAssertionTest.java
+++ b/core/src/test/java/ai/timefold/solver/core/impl/score/stream/test/MultiConstraintAssertionTest.java
@@ -71,7 +71,7 @@ void checksScore() {
}
@Test
- void scoreReturnsTypedScoreWithGivenFacts() {
+ void getScoreReturnsTypedScoreWithGivenFacts() {
var constraintVerifier = ConstraintVerifier.build(new TestdataConstraintVerifierConstraintProvider(),
TestdataConstraintVerifierExtendedSolution.class,
TestdataConstraintVerifierFirstEntity.class,
@@ -81,7 +81,7 @@ void scoreReturnsTypedScoreWithGivenFacts() {
HardSoftScore score = constraintVerifier
.verifyThat()
.given(entity)
- .score();
+ .getScore();
assertThat(score).isNotNull();
assertThat(score).isInstanceOf(HardSoftScore.class);
@@ -91,7 +91,7 @@ void scoreReturnsTypedScoreWithGivenFacts() {
}
@Test
- void scoreEnablesRelativeComparisonWithGivenFacts() {
+ void getScoreEnablesRelativeComparisonWithGivenFacts() {
var constraintVerifier = ConstraintVerifier.build(new TestdataConstraintVerifierConstraintProvider(),
TestdataConstraintVerifierExtendedSolution.class,
TestdataConstraintVerifierFirstEntity.class,
@@ -106,11 +106,11 @@ void scoreEnablesRelativeComparisonWithGivenFacts() {
HardSoftScore scoreA = constraintVerifier
.verifyThat()
.given(entityA)
- .score();
+ .getScore();
HardSoftScore scoreB = constraintVerifier
.verifyThat()
.given(entityB1, entityB2)
- .score();
+ .getScore();
assertThat(scoreA).isGreaterThan(scoreB);
}
diff --git a/core/src/test/java/ai/timefold/solver/core/impl/score/stream/test/SingleConstraintAssertionTest.java b/core/src/test/java/ai/timefold/solver/core/impl/score/stream/test/SingleConstraintAssertionTest.java
index 559b43601d2..888a9090f56 100644
--- a/core/src/test/java/ai/timefold/solver/core/impl/score/stream/test/SingleConstraintAssertionTest.java
+++ b/core/src/test/java/ai/timefold/solver/core/impl/score/stream/test/SingleConstraintAssertionTest.java
@@ -587,35 +587,35 @@ void impactsByLessThan() {
}
@Test
- void impactEnablesRelativeComparison() {
+ void getImpactEnablesRelativeComparison() {
var entityA = new TestdataConstraintVerifierFirstEntity("A", new TestdataValue());
var solution = TestdataConstraintVerifierSolution.generateSolution(2, 3);
- Number impactA = constraintVerifier
+ var impactA = constraintVerifier
.verifyThat(TestdataConstraintVerifierConstraintProvider::penalizeEveryEntity)
.given(entityA)
- .impact();
- Number impactB = constraintVerifier
+ .getImpact();
+ var impactB = constraintVerifier
.verifyThat(TestdataConstraintVerifierConstraintProvider::penalizeEveryEntity)
.given(solution.getEntityList().toArray())
- .impact();
+ .getImpact();
assertThat(impactB.intValue()).isGreaterThan(impactA.intValue());
}
@Test
- void scoreEnablesRelativeComparisonForRewards() {
+ void getScoreEnablesRelativeComparisonForRewards() {
var entityA = new TestdataConstraintVerifierFirstEntity("A", new TestdataValue());
var solution = TestdataConstraintVerifierSolution.generateSolution(2, 3);
HardSoftScore scoreA = constraintVerifier
.verifyThat(TestdataConstraintVerifierConstraintProvider::rewardEveryEntity)
.given(entityA)
- .score();
+ .getScore();
HardSoftScore scoreB = constraintVerifier
.verifyThat(TestdataConstraintVerifierConstraintProvider::rewardEveryEntity)
.given(solution.getEntityList().toArray())
- .score();
+ .getScore();
assertThat(scoreA).isNotNull();
assertThat(scoreA).isInstanceOf(HardSoftScore.class);
@@ -631,18 +631,18 @@ void scoreEnablesRelativeComparisonForRewards() {
}
@Test
- void scoreComparesGivenSolutions() {
+ void getScoreComparesGivenSolutions() {
var smallSolution = TestdataConstraintVerifierExtendedSolution.generateSolution(2, 2);
var largeSolution = TestdataConstraintVerifierExtendedSolution.generateSolution(2, 4);
HardSoftScore smallScore = constraintVerifier
.verifyThat(TestdataConstraintVerifierConstraintProvider::penalizeEveryEntity)
.givenSolution(smallSolution)
- .score();
+ .getScore();
HardSoftScore largeScore = constraintVerifier
.verifyThat(TestdataConstraintVerifierConstraintProvider::penalizeEveryEntity)
.givenSolution(largeSolution)
- .score();
+ .getScore();
assertThat(smallScore).isGreaterThan(largeScore);
}
diff --git a/docs/src/modules/ROOT/pages/quickstart/quarkus-vehicle-routing/quarkus-vehicle-routing-quickstart.adoc b/docs/src/modules/ROOT/pages/quickstart/quarkus-vehicle-routing/quarkus-vehicle-routing-quickstart.adoc
index 513b1d06505..54bc2c06002 100644
--- a/docs/src/modules/ROOT/pages/quickstart/quarkus-vehicle-routing/quarkus-vehicle-routing-quickstart.adoc
+++ b/docs/src/modules/ROOT/pages/quickstart/quarkus-vehicle-routing/quarkus-vehicle-routing-quickstart.adoc
@@ -535,7 +535,7 @@ Add some dependencies in your `pom.xml`:
----
io.quarkus
- quarkus-junit5
+ quarkus-junit
test
----
diff --git a/docs/src/modules/ROOT/pages/quickstart/quarkus/quarkus-quickstart.adoc b/docs/src/modules/ROOT/pages/quickstart/quarkus/quarkus-quickstart.adoc
index b28a5a31c1a..7f3f9df8dea 100644
--- a/docs/src/modules/ROOT/pages/quickstart/quarkus/quarkus-quickstart.adoc
+++ b/docs/src/modules/ROOT/pages/quickstart/quarkus/quarkus-quickstart.adoc
@@ -236,7 +236,7 @@ Add the subsequent dependency in your `pom.xml`:
----
io.quarkus
- quarkus-junit5
+ quarkus-junit
test
----
@@ -247,7 +247,7 @@ Gradle::
Add the subsequent dependency to your `build.gradle`:
[source,groovy,subs=attributes+]
----
- testImplementation "io.quarkus:quarkus-junit5"
+ testImplementation "io.quarkus:quarkus-junit"
----
--
====
diff --git a/quarkus-integration/quarkus-benchmark/deployment/pom.xml b/quarkus-integration/quarkus-benchmark/deployment/pom.xml
index c8bc7f9f60b..4917a5e572e 100644
--- a/quarkus-integration/quarkus-benchmark/deployment/pom.xml
+++ b/quarkus-integration/quarkus-benchmark/deployment/pom.xml
@@ -33,7 +33,7 @@
io.quarkus
- quarkus-junit5-internal
+ quarkus-junit-internal
test
diff --git a/quarkus-integration/quarkus-benchmark/integration-test/pom.xml b/quarkus-integration/quarkus-benchmark/integration-test/pom.xml
index cfb84e7d59d..e0d27325f1e 100644
--- a/quarkus-integration/quarkus-benchmark/integration-test/pom.xml
+++ b/quarkus-integration/quarkus-benchmark/integration-test/pom.xml
@@ -40,7 +40,7 @@
io.quarkus
- quarkus-junit5
+ quarkus-junit
test
diff --git a/quarkus-integration/quarkus-jackson/integration-test/pom.xml b/quarkus-integration/quarkus-jackson/integration-test/pom.xml
index d8b4ebef73d..5f37102389b 100644
--- a/quarkus-integration/quarkus-jackson/integration-test/pom.xml
+++ b/quarkus-integration/quarkus-jackson/integration-test/pom.xml
@@ -44,7 +44,7 @@
io.quarkus
- quarkus-junit5
+ quarkus-junit
test
diff --git a/quarkus-integration/quarkus/deployment/pom.xml b/quarkus-integration/quarkus/deployment/pom.xml
index d2d867802c4..02711fe73d9 100644
--- a/quarkus-integration/quarkus/deployment/pom.xml
+++ b/quarkus-integration/quarkus/deployment/pom.xml
@@ -30,7 +30,7 @@
io.quarkus
- quarkus-junit5-internal
+ quarkus-junit-internal
test
diff --git a/quarkus-integration/quarkus/devui-integration-test/pom.xml b/quarkus-integration/quarkus/devui-integration-test/pom.xml
index f732c75ed5b..913c423814e 100644
--- a/quarkus-integration/quarkus/devui-integration-test/pom.xml
+++ b/quarkus-integration/quarkus/devui-integration-test/pom.xml
@@ -40,7 +40,7 @@
io.quarkus
- quarkus-junit5
+ quarkus-junit
test
@@ -50,7 +50,7 @@
io.quarkus
- quarkus-junit5-internal
+ quarkus-junit-internal
test
diff --git a/quarkus-integration/quarkus/reflection-integration-test/pom.xml b/quarkus-integration/quarkus/reflection-integration-test/pom.xml
index 7444fd65692..92601b08297 100644
--- a/quarkus-integration/quarkus/reflection-integration-test/pom.xml
+++ b/quarkus-integration/quarkus/reflection-integration-test/pom.xml
@@ -36,7 +36,7 @@
io.quarkus
- quarkus-junit5
+ quarkus-junit
test
diff --git a/tools/benchmark/src/main/java/ai/timefold/solver/benchmark/config/PlannerBenchmarkConfig.java b/tools/benchmark/src/main/java/ai/timefold/solver/benchmark/config/PlannerBenchmarkConfig.java
index 24be1ca01cd..0c1b46558d6 100644
--- a/tools/benchmark/src/main/java/ai/timefold/solver/benchmark/config/PlannerBenchmarkConfig.java
+++ b/tools/benchmark/src/main/java/ai/timefold/solver/benchmark/config/PlannerBenchmarkConfig.java
@@ -27,6 +27,7 @@
import ai.timefold.solver.benchmark.impl.io.jaxb.PlannerBenchmarkConfigIO;
import ai.timefold.solver.benchmark.impl.report.BenchmarkReport;
import ai.timefold.solver.core.config.solver.SolverConfig;
+import ai.timefold.solver.core.config.util.ConfigUtils;
import ai.timefold.solver.core.impl.io.jaxb.TimefoldXmlSerializationException;
import org.jspecify.annotations.NonNull;
@@ -418,7 +419,7 @@ A classpath resource should not start with a slash (/). A templateResource adher
private String name = null;
private File benchmarkDirectory = null;
- private Class extends ThreadFactory> threadFactoryClass = null;
+ private String threadFactoryClass = null;
private String parallelBenchmarkCount = null;
private Long warmUpMillisecondsSpentLimit = null;
private Long warmUpSecondsSpentLimit = null;
@@ -477,11 +478,11 @@ public void setBenchmarkDirectory(@Nullable File benchmarkDirectory) {
}
public @Nullable Class extends ThreadFactory> getThreadFactoryClass() {
- return threadFactoryClass;
+ return ConfigUtils.resolveClass(threadFactoryClass, "threadFactoryClass", this);
}
public void setThreadFactoryClass(@Nullable Class extends ThreadFactory> threadFactoryClass) {
- this.threadFactoryClass = threadFactoryClass;
+ this.threadFactoryClass = threadFactoryClass == null ? null : threadFactoryClass.getName();
}
/**
@@ -592,7 +593,7 @@ public void setSolverBenchmarkConfigList(@Nullable List<@NonNull SolverBenchmark
}
public @NonNull PlannerBenchmarkConfig withThreadFactoryClass(@NonNull Class extends ThreadFactory> threadFactoryClass) {
- this.setThreadFactoryClass(threadFactoryClass);
+ this.threadFactoryClass = threadFactoryClass.getName();
return this;
}
diff --git a/tools/benchmark/src/main/java/ai/timefold/solver/benchmark/config/ProblemBenchmarksConfig.java b/tools/benchmark/src/main/java/ai/timefold/solver/benchmark/config/ProblemBenchmarksConfig.java
index 9490c236c6e..903a11ba2c0 100644
--- a/tools/benchmark/src/main/java/ai/timefold/solver/benchmark/config/ProblemBenchmarksConfig.java
+++ b/tools/benchmark/src/main/java/ai/timefold/solver/benchmark/config/ProblemBenchmarksConfig.java
@@ -28,7 +28,7 @@
})
public class ProblemBenchmarksConfig extends AbstractConfig {
- private Class extends SolutionFileIO>> solutionFileIOClass = null;
+ private String solutionFileIOClass = null;
private Boolean writeOutputSolutionEnabled = null;
@@ -48,11 +48,11 @@ public class ProblemBenchmarksConfig extends AbstractConfig> getSolutionFileIOClass() {
- return solutionFileIOClass;
+ return ConfigUtils.resolveClass(solutionFileIOClass, "solutionFileIOClass", this);
}
public void setSolutionFileIOClass(@Nullable Class extends SolutionFileIO>> solutionFileIOClass) {
- this.solutionFileIOClass = solutionFileIOClass;
+ this.solutionFileIOClass = solutionFileIOClass == null ? null : solutionFileIOClass.getName();
}
public @Nullable Boolean getWriteOutputSolutionEnabled() {
@@ -101,7 +101,7 @@ public void setSingleStatisticTypeList(@Nullable List<@NonNull SingleStatisticTy
public @NonNull ProblemBenchmarksConfig
withSolutionFileIOClass(@NonNull Class extends SolutionFileIO>> solutionFileIOClass) {
- this.setSolutionFileIOClass(solutionFileIOClass);
+ this.solutionFileIOClass = solutionFileIOClass.getName();
return this;
}
@@ -179,7 +179,7 @@ public void setSingleStatisticTypeList(@Nullable List<@NonNull SingleStatisticTy
@Override
public @NonNull ProblemBenchmarksConfig inherit(@NonNull ProblemBenchmarksConfig inheritedConfig) {
solutionFileIOClass = ConfigUtils.inheritOverwritableProperty(solutionFileIOClass,
- inheritedConfig.getSolutionFileIOClass());
+ inheritedConfig.solutionFileIOClass);
writeOutputSolutionEnabled = ConfigUtils.inheritOverwritableProperty(writeOutputSolutionEnabled,
inheritedConfig.getWriteOutputSolutionEnabled());
inputSolutionFileList = ConfigUtils.inheritMergeableListProperty(inputSolutionFileList,
@@ -200,7 +200,7 @@ public void setSingleStatisticTypeList(@Nullable List<@NonNull SingleStatisticTy
@Override
public void visitReferencedClasses(@NonNull Consumer> classVisitor) {
- classVisitor.accept(solutionFileIOClass);
+ classVisitor.accept(getSolutionFileIOClass());
}
}
diff --git a/tools/benchmark/src/main/java/ai/timefold/solver/benchmark/config/report/BenchmarkReportConfig.java b/tools/benchmark/src/main/java/ai/timefold/solver/benchmark/config/report/BenchmarkReportConfig.java
index 6e46cdd5592..76cda618258 100644
--- a/tools/benchmark/src/main/java/ai/timefold/solver/benchmark/config/report/BenchmarkReportConfig.java
+++ b/tools/benchmark/src/main/java/ai/timefold/solver/benchmark/config/report/BenchmarkReportConfig.java
@@ -28,8 +28,8 @@ public class BenchmarkReportConfig extends AbstractConfig
@XmlJavaTypeAdapter(JaxbLocaleAdapter.class)
private Locale locale = null;
private SolverRankingType solverRankingType = null;
- private Class extends Comparator> solverRankingComparatorClass = null;
- private Class extends SolverRankingWeightFactory> solverRankingWeightFactoryClass = null;
+ private String solverRankingComparatorClass = null;
+ private String solverRankingWeightFactoryClass = null;
public BenchmarkReportConfig() {
}
@@ -55,21 +55,23 @@ public void setSolverRankingType(@Nullable SolverRankingType solverRankingType)
}
public @Nullable Class extends Comparator> getSolverRankingComparatorClass() {
- return solverRankingComparatorClass;
+ return ConfigUtils.resolveClass(solverRankingComparatorClass, "solverRankingComparatorClass", this);
}
public void setSolverRankingComparatorClass(
@Nullable Class extends Comparator> solverRankingComparatorClass) {
- this.solverRankingComparatorClass = solverRankingComparatorClass;
+ this.solverRankingComparatorClass = solverRankingComparatorClass == null ? null
+ : solverRankingComparatorClass.getName();
}
public @Nullable Class extends SolverRankingWeightFactory> getSolverRankingWeightFactoryClass() {
- return solverRankingWeightFactoryClass;
+ return ConfigUtils.resolveClass(solverRankingWeightFactoryClass, "solverRankingWeightFactoryClass", this);
}
public void setSolverRankingWeightFactoryClass(
@Nullable Class extends SolverRankingWeightFactory> solverRankingWeightFactoryClass) {
- this.solverRankingWeightFactoryClass = solverRankingWeightFactoryClass;
+ this.solverRankingWeightFactoryClass = solverRankingWeightFactoryClass == null ? null
+ : solverRankingWeightFactoryClass.getName();
}
public @Nullable Locale determineLocale() {
@@ -92,13 +94,13 @@ public void setSolverRankingWeightFactoryClass(
public @NonNull BenchmarkReportConfig withSolverRankingComparatorClass(
@NonNull Class extends Comparator> solverRankingComparatorClass) {
- this.setSolverRankingComparatorClass(solverRankingComparatorClass);
+ this.solverRankingComparatorClass = solverRankingComparatorClass.getName();
return this;
}
public @NonNull BenchmarkReportConfig withSolverRankingWeightFactoryClass(
@NonNull Class extends SolverRankingWeightFactory> solverRankingWeightFactoryClass) {
- this.setSolverRankingWeightFactoryClass(solverRankingWeightFactoryClass);
+ this.solverRankingWeightFactoryClass = solverRankingWeightFactoryClass.getName();
return this;
}
@@ -108,9 +110,9 @@ public void setSolverRankingWeightFactoryClass(
solverRankingType = ConfigUtils.inheritOverwritableProperty(solverRankingType,
inheritedConfig.getSolverRankingType());
solverRankingComparatorClass = ConfigUtils.inheritOverwritableProperty(solverRankingComparatorClass,
- inheritedConfig.getSolverRankingComparatorClass());
+ inheritedConfig.solverRankingComparatorClass);
solverRankingWeightFactoryClass = ConfigUtils.inheritOverwritableProperty(solverRankingWeightFactoryClass,
- inheritedConfig.getSolverRankingWeightFactoryClass());
+ inheritedConfig.solverRankingWeightFactoryClass);
return this;
}
@@ -121,8 +123,8 @@ public void setSolverRankingWeightFactoryClass(
@Override
public void visitReferencedClasses(@NonNull Consumer> classVisitor) {
- classVisitor.accept(solverRankingComparatorClass);
- classVisitor.accept(solverRankingWeightFactoryClass);
+ classVisitor.accept(getSolverRankingComparatorClass());
+ classVisitor.accept(getSolverRankingWeightFactoryClass());
}
}