Skip to content

Commit

Permalink
chore: Address Sonar issues post-nullness (Part 3)
Browse files Browse the repository at this point in the history
# Conflicts:
#	core/src/main/java/ai/timefold/solver/core/impl/heuristic/selector/entity/EntitySelectorFactory.java
#	core/src/main/java/ai/timefold/solver/core/impl/heuristic/selector/move/AbstractMoveSelectorFactory.java
#	core/src/main/java/ai/timefold/solver/core/impl/heuristic/selector/move/generic/list/SubListChangeMoveSelectorFactory.java
#	core/src/main/java/ai/timefold/solver/core/impl/heuristic/selector/value/ValueSelectorFactory.java
#	core/src/main/java/ai/timefold/solver/core/impl/localsearch/decider/forager/LocalSearchForagerFactory.java
  • Loading branch information
triceo committed Nov 12, 2024
1 parent c1694e7 commit f64d980
Show file tree
Hide file tree
Showing 26 changed files with 252 additions and 254 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@

import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.Objects;
import java.util.function.Function;
import java.util.stream.Stream;

import ai.timefold.solver.core.api.domain.solution.PlanningSolution;
Expand Down Expand Up @@ -44,6 +44,7 @@ public EntitySelectorFactory(EntitySelectorConfig entitySelectorConfig) {

public EntityDescriptor<Solution_> extractEntityDescriptor(HeuristicConfigPolicy<Solution_> configPolicy) {
var entityClass = config.getEntityClass();
var mimicSelectorRef = config.getMimicSelectorRef();
if (entityClass != null) {
var solutionDescriptor = configPolicy.getSolutionDescriptor();
var entityDescriptor = solutionDescriptor.getEntityDescriptorStrict(entityClass);
Expand All @@ -56,8 +57,8 @@ Check your solver configuration. If that class (%s) is not in the entityClassSet
solutionDescriptor.getEntityClassSet(), PlanningSolution.class.getSimpleName()));
}
return entityDescriptor;
} else if (config.getMimicSelectorRef() != null) {
return configPolicy.getEntityMimicRecorder(config.getMimicSelectorRef()).getEntityDescriptor();
} else if (mimicSelectorRef != null) {
return configPolicy.getEntityMimicRecorder(mimicSelectorRef).getEntityDescriptor();
} else {
return null;
}
Expand Down Expand Up @@ -118,24 +119,23 @@ protected EntitySelector<Solution_> buildMimicReplaying(HeuristicConfigPolicy<So
config.getSorterClass(), config.getProbabilityWeightFactoryClass(), config.getSelectedCountLimit())
.anyMatch(Objects::nonNull);
if (anyConfigurationParameterDefined) {
throw new IllegalArgumentException("The entitySelectorConfig (" + config
+ ") with mimicSelectorRef (" + config.getMimicSelectorRef()
+ ") has another property that is not null.");
throw new IllegalArgumentException(
"The entitySelectorConfig (%s) with mimicSelectorRef (%s) has another property that is not null."
.formatted(config, config.getMimicSelectorRef()));
}
var entityMimicRecorder = configPolicy.getEntityMimicRecorder(config.getMimicSelectorRef());
if (entityMimicRecorder == null) {
throw new IllegalArgumentException("The entitySelectorConfig (" + config
+ ") has a mimicSelectorRef (" + config.getMimicSelectorRef()
+ ") for which no entitySelector with that id exists (in its solver phase).");
throw new IllegalArgumentException(
"The entitySelectorConfig (%s) has a mimicSelectorRef (%s) for which no entitySelector with that id exists (in its solver phase)."
.formatted(config, config.getMimicSelectorRef()));
}
return new MimicReplayingEntitySelector<>(entityMimicRecorder);
}

protected boolean determineBaseRandomSelection(EntityDescriptor<Solution_> entityDescriptor,
SelectionCacheType resolvedCacheType, SelectionOrder resolvedSelectionOrder) {
return switch (resolvedSelectionOrder) {
case ORIGINAL -> false;
case SORTED, SHUFFLED, PROBABILISTIC ->
case ORIGINAL, SORTED, SHUFFLED, PROBABILISTIC ->
// baseValueSelector and lower should be ORIGINAL if they are going to get cached completely
false;
case RANDOM ->
Expand All @@ -156,8 +156,8 @@ private EntitySelector<Solution_> buildBaseEntitySelector(EntityDescriptor<Solut
if (minimumCacheType == SelectionCacheType.SOLVER) {
// TODO Solver cached entities are not compatible with ConstraintStreams and IncrementalScoreDirector
// because between phases the entities get cloned
throw new IllegalArgumentException("The minimumCacheType (" + minimumCacheType
+ ") is not yet supported. Please use " + SelectionCacheType.PHASE + " instead.");
throw new IllegalArgumentException("The minimumCacheType (%s) is not supported here. Please use %s instead."
.formatted(minimumCacheType, SelectionCacheType.PHASE));
}
// FromSolutionEntitySelector has an intrinsicCacheType STEP
return new FromSolutionEntitySelector<>(entityDescriptor, minimumCacheType, randomSelection);
Expand All @@ -179,10 +179,11 @@ private EntitySelector<Solution_> applyFiltering(EntitySelector<Solution_> entit
ClassInstanceCache instanceCache) {
var entityDescriptor = entitySelector.getEntityDescriptor();
if (hasFiltering(entityDescriptor)) {
List<SelectionFilter<Solution_, Object>> filterList = new ArrayList<>(config.getFilterClass() == null ? 1 : 2);
if (config.getFilterClass() != null) {
var filterClass = config.getFilterClass();
var filterList = new ArrayList<SelectionFilter<Solution_, Object>>(filterClass == null ? 1 : 2);
if (filterClass != null) {
SelectionFilter<Solution_, Object> selectionFilter =
instanceCache.newInstance(config, "filterClass", config.getFilterClass());
instanceCache.newInstance(config, "filterClass", filterClass);
filterList.add(selectionFilter);
}
// Filter out pinned entities
Expand All @@ -198,71 +199,65 @@ private EntitySelector<Solution_> applyFiltering(EntitySelector<Solution_> entit
}

protected void validateSorting(SelectionOrder resolvedSelectionOrder) {
if ((config.getSorterManner() != null || config.getSorterComparatorClass() != null
var sorterManner = config.getSorterManner();
if ((sorterManner != null || config.getSorterComparatorClass() != null
|| config.getSorterWeightFactoryClass() != null
|| config.getSorterOrder() != null || config.getSorterClass() != null)
&& resolvedSelectionOrder != SelectionOrder.SORTED) {
throw new IllegalArgumentException("The entitySelectorConfig (" + config
+ ") with sorterManner (" + config.getSorterManner()
+ ") and sorterComparatorClass (" + config.getSorterComparatorClass()
+ ") and sorterWeightFactoryClass (" + config.getSorterWeightFactoryClass()
+ ") and sorterOrder (" + config.getSorterOrder()
+ ") and sorterClass (" + config.getSorterClass()
+ ") has a resolvedSelectionOrder (" + resolvedSelectionOrder
+ ") that is not " + SelectionOrder.SORTED + ".");
}
if (config.getSorterManner() != null && config.getSorterComparatorClass() != null) {
throw new IllegalArgumentException("The entitySelectorConfig (" + config
+ ") has both a sorterManner (" + config.getSorterManner()
+ ") and a sorterComparatorClass (" + config.getSorterComparatorClass() + ").");
}
if (config.getSorterManner() != null && config.getSorterWeightFactoryClass() != null) {
throw new IllegalArgumentException("The entitySelectorConfig (" + config
+ ") has both a sorterManner (" + config.getSorterManner()
+ ") and a sorterWeightFactoryClass (" + config.getSorterWeightFactoryClass() + ").");
}
if (config.getSorterManner() != null && config.getSorterClass() != null) {
throw new IllegalArgumentException("The entitySelectorConfig (" + config
+ ") has both a sorterManner (" + config.getSorterManner()
+ ") and a sorterClass (" + config.getSorterClass() + ").");
}
if (config.getSorterManner() != null && config.getSorterOrder() != null) {
throw new IllegalArgumentException("The entitySelectorConfig (" + config
+ ") with sorterManner (" + config.getSorterManner()
+ ") has a non-null sorterOrder (" + config.getSorterOrder() + ").");
throw new IllegalArgumentException("""
The entitySelectorConfig (%s) with sorterManner (%s) \
and sorterComparatorClass (%s) and sorterWeightFactoryClass (%s) and sorterOrder (%s) and sorterClass (%s) \
has a resolvedSelectionOrder (%s) that is not %s."""
.formatted(config, sorterManner, config.getSorterComparatorClass(),
config.getSorterWeightFactoryClass(), config.getSorterOrder(), config.getSorterClass(),
resolvedSelectionOrder, SelectionOrder.SORTED));
}
assertNotSorterMannerAnd(config, "sorterComparatorClass", EntitySelectorConfig::getSorterComparatorClass);
assertNotSorterMannerAnd(config, "sorterWeightFactoryClass", EntitySelectorConfig::getSorterWeightFactoryClass);
assertNotSorterMannerAnd(config, "sorterClass", EntitySelectorConfig::getSorterClass);
assertNotSorterMannerAnd(config, "sorterOrder", EntitySelectorConfig::getSorterOrder);
assertNotSorterClassAnd(config, "sorterComparatorClass", EntitySelectorConfig::getSorterComparatorClass);
assertNotSorterClassAnd(config, "sorterWeightFactoryClass", EntitySelectorConfig::getSorterWeightFactoryClass);
assertNotSorterClassAnd(config, "sorterOrder", EntitySelectorConfig::getSorterOrder);
if (config.getSorterComparatorClass() != null && config.getSorterWeightFactoryClass() != null) {
throw new IllegalArgumentException("The entitySelectorConfig (" + config
+ ") has both a sorterComparatorClass (" + config.getSorterComparatorClass()
+ ") and a sorterWeightFactoryClass (" + config.getSorterWeightFactoryClass() + ").");
throw new IllegalArgumentException(
"The entitySelectorConfig (%s) has both a sorterComparatorClass (%s) and a sorterWeightFactoryClass (%s)."
.formatted(config, config.getSorterComparatorClass(), config.getSorterWeightFactoryClass()));
}
if (config.getSorterComparatorClass() != null && config.getSorterClass() != null) {
throw new IllegalArgumentException("The entitySelectorConfig (" + config
+ ") has both a sorterComparatorClass (" + config.getSorterComparatorClass()
+ ") and a sorterClass (" + config.getSorterClass() + ").");
}
if (config.getSorterWeightFactoryClass() != null && config.getSorterClass() != null) {
throw new IllegalArgumentException("The entitySelectorConfig (" + config
+ ") has both a sorterWeightFactoryClass (" + config.getSorterWeightFactoryClass()
+ ") and a sorterClass (" + config.getSorterClass() + ").");
}

private void assertNotSorterMannerAnd(EntitySelectorConfig config, String propertyName,
Function<EntitySelectorConfig, Object> propertyAccessor) {
var sorterManner = config.getSorterManner();
var property = propertyAccessor.apply(config);
if (sorterManner != null && property != null) {
throw new IllegalArgumentException("The entitySelectorConfig (%s) has both a sorterManner (%s) and a %s (%s)."
.formatted(config, sorterManner, propertyName, property));
}
if (config.getSorterClass() != null && config.getSorterOrder() != null) {
throw new IllegalArgumentException("The entitySelectorConfig (" + config
+ ") with sorterClass (" + config.getSorterClass()
+ ") has a non-null sorterOrder (" + config.getSorterOrder() + ").");
}

private void assertNotSorterClassAnd(EntitySelectorConfig config, String propertyName,
Function<EntitySelectorConfig, Object> propertyAccessor) {
var sorterClass = config.getSorterClass();
var property = propertyAccessor.apply(config);
if (sorterClass != null && property != null) {
throw new IllegalArgumentException(
"The entitySelectorConfig (%s) with sorterClass (%s) has a non-null %s (%s)."
.formatted(config, sorterClass, propertyName, property));
}
}

protected EntitySelector<Solution_> applySorting(SelectionCacheType resolvedCacheType,
SelectionOrder resolvedSelectionOrder, EntitySelector<Solution_> entitySelector, ClassInstanceCache instanceCache) {
if (resolvedSelectionOrder == SelectionOrder.SORTED) {
SelectionSorter<Solution_, Object> sorter;
if (config.getSorterManner() != null) {
var sorterManner = config.getSorterManner();
if (sorterManner != null) {
var entityDescriptor = entitySelector.getEntityDescriptor();
if (!EntitySelectorConfig.hasSorter(config.getSorterManner(), entityDescriptor)) {
if (!EntitySelectorConfig.hasSorter(sorterManner, entityDescriptor)) {
return entitySelector;
}
sorter = EntitySelectorConfig.determineSorter(config.getSorterManner(), entityDescriptor);
sorter = EntitySelectorConfig.determineSorter(sorterManner, entityDescriptor);
} else if (config.getSorterComparatorClass() != null) {
Comparator<Object> sorterComparator =
instanceCache.newInstance(config, "sorterComparatorClass", config.getSorterComparatorClass());
Expand All @@ -278,7 +273,7 @@ protected EntitySelector<Solution_> applySorting(SelectionCacheType resolvedCach
} else {
throw new IllegalArgumentException("The entitySelectorConfig (" + config
+ ") with resolvedSelectionOrder (" + resolvedSelectionOrder
+ ") needs a sorterManner (" + config.getSorterManner()
+ ") needs a sorterManner (" + sorterManner
+ ") or a sorterComparatorClass (" + config.getSorterComparatorClass()
+ ") or a sorterWeightFactoryClass (" + config.getSorterWeightFactoryClass()
+ ") or a sorterClass (" + config.getSorterClass() + ").");
Expand Down
Loading

0 comments on commit f64d980

Please sign in to comment.