22
33import java .util .ArrayList ;
44import java .util .Comparator ;
5- import java .util .List ;
65import java .util .Objects ;
6+ import java .util .function .Function ;
77import java .util .stream .Stream ;
88
99import ai .timefold .solver .core .api .domain .solution .PlanningSolution ;
@@ -44,6 +44,7 @@ public EntitySelectorFactory(EntitySelectorConfig entitySelectorConfig) {
4444
4545 public EntityDescriptor <Solution_ > extractEntityDescriptor (HeuristicConfigPolicy <Solution_ > configPolicy ) {
4646 var entityClass = config .getEntityClass ();
47+ var mimicSelectorRef = config .getMimicSelectorRef ();
4748 if (entityClass != null ) {
4849 var solutionDescriptor = configPolicy .getSolutionDescriptor ();
4950 var entityDescriptor = solutionDescriptor .getEntityDescriptorStrict (entityClass );
@@ -56,8 +57,8 @@ Check your solver configuration. If that class (%s) is not in the entityClassSet
5657 solutionDescriptor .getEntityClassSet (), PlanningSolution .class .getSimpleName ()));
5758 }
5859 return entityDescriptor ;
59- } else if (config . getMimicSelectorRef () != null ) {
60- return configPolicy .getEntityMimicRecorder (config . getMimicSelectorRef () ).getEntityDescriptor ();
60+ } else if (mimicSelectorRef != null ) {
61+ return configPolicy .getEntityMimicRecorder (mimicSelectorRef ).getEntityDescriptor ();
6162 } else {
6263 return null ;
6364 }
@@ -118,24 +119,23 @@ protected EntitySelector<Solution_> buildMimicReplaying(HeuristicConfigPolicy<So
118119 config .getSorterClass (), config .getProbabilityWeightFactoryClass (), config .getSelectedCountLimit ())
119120 .anyMatch (Objects ::nonNull );
120121 if (anyConfigurationParameterDefined ) {
121- throw new IllegalArgumentException ("The entitySelectorConfig (" + config
122- + " ) with mimicSelectorRef (" + config . getMimicSelectorRef ()
123- + ") has another property that is not null." );
122+ throw new IllegalArgumentException (
123+ "The entitySelectorConfig (%s ) with mimicSelectorRef (%s) has another property that is not null."
124+ . formatted ( config , config . getMimicSelectorRef ()) );
124125 }
125126 var entityMimicRecorder = configPolicy .getEntityMimicRecorder (config .getMimicSelectorRef ());
126127 if (entityMimicRecorder == null ) {
127- throw new IllegalArgumentException ("The entitySelectorConfig (" + config
128- + " ) has a mimicSelectorRef (" + config . getMimicSelectorRef ()
129- + ") for which no entitySelector with that id exists (in its solver phase)." );
128+ throw new IllegalArgumentException (
129+ "The entitySelectorConfig (%s ) has a mimicSelectorRef (%s) for which no entitySelector with that id exists (in its solver phase)."
130+ . formatted ( config , config . getMimicSelectorRef ()) );
130131 }
131132 return new MimicReplayingEntitySelector <>(entityMimicRecorder );
132133 }
133134
134135 protected boolean determineBaseRandomSelection (EntityDescriptor <Solution_ > entityDescriptor ,
135136 SelectionCacheType resolvedCacheType , SelectionOrder resolvedSelectionOrder ) {
136137 return switch (resolvedSelectionOrder ) {
137- case ORIGINAL -> false ;
138- case SORTED , SHUFFLED , PROBABILISTIC ->
138+ case ORIGINAL , SORTED , SHUFFLED , PROBABILISTIC ->
139139 // baseValueSelector and lower should be ORIGINAL if they are going to get cached completely
140140 false ;
141141 case RANDOM ->
@@ -156,8 +156,8 @@ private EntitySelector<Solution_> buildBaseEntitySelector(EntityDescriptor<Solut
156156 if (minimumCacheType == SelectionCacheType .SOLVER ) {
157157 // TODO Solver cached entities are not compatible with ConstraintStreams and IncrementalScoreDirector
158158 // because between phases the entities get cloned
159- throw new IllegalArgumentException ("The minimumCacheType (" + minimumCacheType
160- + ") is not yet supported. Please use " + SelectionCacheType .PHASE + " instead." );
159+ throw new IllegalArgumentException ("The minimumCacheType (%s) is not supported here. Please use %s instead."
160+ . formatted ( minimumCacheType , SelectionCacheType .PHASE ) );
161161 }
162162 // FromSolutionEntitySelector has an intrinsicCacheType STEP
163163 return new FromSolutionEntitySelector <>(entityDescriptor , minimumCacheType , randomSelection );
@@ -179,10 +179,11 @@ private EntitySelector<Solution_> applyFiltering(EntitySelector<Solution_> entit
179179 ClassInstanceCache instanceCache ) {
180180 var entityDescriptor = entitySelector .getEntityDescriptor ();
181181 if (hasFiltering (entityDescriptor )) {
182- List <SelectionFilter <Solution_ , Object >> filterList = new ArrayList <>(config .getFilterClass () == null ? 1 : 2 );
183- if (config .getFilterClass () != null ) {
182+ var filterClass = config .getFilterClass ();
183+ var filterList = new ArrayList <SelectionFilter <Solution_ , Object >>(filterClass == null ? 1 : 2 );
184+ if (filterClass != null ) {
184185 SelectionFilter <Solution_ , Object > selectionFilter =
185- instanceCache .newInstance (config , "filterClass" , config . getFilterClass () );
186+ instanceCache .newInstance (config , "filterClass" , filterClass );
186187 filterList .add (selectionFilter );
187188 }
188189 // Filter out pinned entities
@@ -198,71 +199,66 @@ private EntitySelector<Solution_> applyFiltering(EntitySelector<Solution_> entit
198199 }
199200
200201 protected void validateSorting (SelectionOrder resolvedSelectionOrder ) {
201- if ((config .getSorterManner () != null || config .getSorterComparatorClass () != null
202- || config .getSorterWeightFactoryClass () != null
203- || config .getSorterOrder () != null || config .getSorterClass () != null )
204- && resolvedSelectionOrder != SelectionOrder .SORTED ) {
205- throw new IllegalArgumentException ("The entitySelectorConfig (" + config
206- + ") with sorterManner (" + config .getSorterManner ()
207- + ") and sorterComparatorClass (" + config .getSorterComparatorClass ()
208- + ") and sorterWeightFactoryClass (" + config .getSorterWeightFactoryClass ()
209- + ") and sorterOrder (" + config .getSorterOrder ()
210- + ") and sorterClass (" + config .getSorterClass ()
211- + ") has a resolvedSelectionOrder (" + resolvedSelectionOrder
212- + ") that is not " + SelectionOrder .SORTED + "." );
213- }
214- if (config .getSorterManner () != null && config .getSorterComparatorClass () != null ) {
215- throw new IllegalArgumentException ("The entitySelectorConfig (" + config
216- + ") has both a sorterManner (" + config .getSorterManner ()
217- + ") and a sorterComparatorClass (" + config .getSorterComparatorClass () + ")." );
218- }
219- if (config .getSorterManner () != null && config .getSorterWeightFactoryClass () != null ) {
220- throw new IllegalArgumentException ("The entitySelectorConfig (" + config
221- + ") has both a sorterManner (" + config .getSorterManner ()
222- + ") and a sorterWeightFactoryClass (" + config .getSorterWeightFactoryClass () + ")." );
223- }
224- if (config .getSorterManner () != null && config .getSorterClass () != null ) {
225- throw new IllegalArgumentException ("The entitySelectorConfig (" + config
226- + ") has both a sorterManner (" + config .getSorterManner ()
227- + ") and a sorterClass (" + config .getSorterClass () + ")." );
228- }
229- if (config .getSorterManner () != null && config .getSorterOrder () != null ) {
230- throw new IllegalArgumentException ("The entitySelectorConfig (" + config
231- + ") with sorterManner (" + config .getSorterManner ()
232- + ") has a non-null sorterOrder (" + config .getSorterOrder () + ")." );
202+ var sorterManner = config .getSorterManner ();
203+ var sorterComparatorClass = config .getSorterComparatorClass ();
204+ var sorterWeightFactoryClass = config .getSorterWeightFactoryClass ();
205+ var sorterOrder = config .getSorterOrder ();
206+ var sorterClass = config .getSorterClass ();
207+ if ((sorterManner != null || sorterComparatorClass != null || sorterWeightFactoryClass != null || sorterOrder != null
208+ || sorterClass != null ) && resolvedSelectionOrder != SelectionOrder .SORTED ) {
209+ throw new IllegalArgumentException ("""
210+ The entitySelectorConfig (%s) with sorterManner (%s) \
211+ and sorterComparatorClass (%s) and sorterWeightFactoryClass (%s) and sorterOrder (%s) and sorterClass (%s) \
212+ has a resolvedSelectionOrder (%s) that is not %s."""
213+ .formatted (config , sorterManner , sorterComparatorClass , sorterWeightFactoryClass , sorterOrder , sorterClass ,
214+ resolvedSelectionOrder , SelectionOrder .SORTED ));
233215 }
234- if (config .getSorterComparatorClass () != null && config .getSorterWeightFactoryClass () != null ) {
235- throw new IllegalArgumentException ("The entitySelectorConfig (" + config
236- + ") has both a sorterComparatorClass (" + config .getSorterComparatorClass ()
237- + ") and a sorterWeightFactoryClass (" + config .getSorterWeightFactoryClass () + ")." );
238- }
239- if (config .getSorterComparatorClass () != null && config .getSorterClass () != null ) {
240- throw new IllegalArgumentException ("The entitySelectorConfig (" + config
241- + ") has both a sorterComparatorClass (" + config .getSorterComparatorClass ()
242- + ") and a sorterClass (" + config .getSorterClass () + ")." );
216+ assertNotSorterMannerAnd (config , "sorterComparatorClass" , EntitySelectorConfig ::getSorterComparatorClass );
217+ assertNotSorterMannerAnd (config , "sorterWeightFactoryClass" , EntitySelectorConfig ::getSorterWeightFactoryClass );
218+ assertNotSorterMannerAnd (config , "sorterClass" , EntitySelectorConfig ::getSorterClass );
219+ assertNotSorterMannerAnd (config , "sorterOrder" , EntitySelectorConfig ::getSorterOrder );
220+ assertNotSorterClassAnd (config , "sorterComparatorClass" , EntitySelectorConfig ::getSorterComparatorClass );
221+ assertNotSorterClassAnd (config , "sorterWeightFactoryClass" , EntitySelectorConfig ::getSorterWeightFactoryClass );
222+ assertNotSorterClassAnd (config , "sorterOrder" , EntitySelectorConfig ::getSorterOrder );
223+ if (sorterComparatorClass != null && sorterWeightFactoryClass != null ) {
224+ throw new IllegalArgumentException (
225+ "The entitySelectorConfig (%s) has both a sorterComparatorClass (%s) and a sorterWeightFactoryClass (%s)."
226+ .formatted (config , sorterComparatorClass , sorterWeightFactoryClass ));
243227 }
244- if (config .getSorterWeightFactoryClass () != null && config .getSorterClass () != null ) {
245- throw new IllegalArgumentException ("The entitySelectorConfig (" + config
246- + ") has both a sorterWeightFactoryClass (" + config .getSorterWeightFactoryClass ()
247- + ") and a sorterClass (" + config .getSorterClass () + ")." );
228+ }
229+
230+ private static void assertNotSorterMannerAnd (EntitySelectorConfig config , String propertyName ,
231+ Function <EntitySelectorConfig , Object > propertyAccessor ) {
232+ var sorterManner = config .getSorterManner ();
233+ var property = propertyAccessor .apply (config );
234+ if (sorterManner != null && property != null ) {
235+ throw new IllegalArgumentException ("The entitySelectorConfig (%s) has both a sorterManner (%s) and a %s (%s)."
236+ .formatted (config , sorterManner , propertyName , property ));
248237 }
249- if (config .getSorterClass () != null && config .getSorterOrder () != null ) {
250- throw new IllegalArgumentException ("The entitySelectorConfig (" + config
251- + ") with sorterClass (" + config .getSorterClass ()
252- + ") has a non-null sorterOrder (" + config .getSorterOrder () + ")." );
238+ }
239+
240+ private static void assertNotSorterClassAnd (EntitySelectorConfig config , String propertyName ,
241+ Function <EntitySelectorConfig , Object > propertyAccessor ) {
242+ var sorterClass = config .getSorterClass ();
243+ var property = propertyAccessor .apply (config );
244+ if (sorterClass != null && property != null ) {
245+ throw new IllegalArgumentException (
246+ "The entitySelectorConfig (%s) with sorterClass (%s) has a non-null %s (%s)."
247+ .formatted (config , sorterClass , propertyName , property ));
253248 }
254249 }
255250
256251 protected EntitySelector <Solution_ > applySorting (SelectionCacheType resolvedCacheType ,
257252 SelectionOrder resolvedSelectionOrder , EntitySelector <Solution_ > entitySelector , ClassInstanceCache instanceCache ) {
258253 if (resolvedSelectionOrder == SelectionOrder .SORTED ) {
259254 SelectionSorter <Solution_ , Object > sorter ;
260- if (config .getSorterManner () != null ) {
255+ var sorterManner = config .getSorterManner ();
256+ if (sorterManner != null ) {
261257 var entityDescriptor = entitySelector .getEntityDescriptor ();
262- if (!EntitySelectorConfig .hasSorter (config . getSorterManner () , entityDescriptor )) {
258+ if (!EntitySelectorConfig .hasSorter (sorterManner , entityDescriptor )) {
263259 return entitySelector ;
264260 }
265- sorter = EntitySelectorConfig .determineSorter (config . getSorterManner () , entityDescriptor );
261+ sorter = EntitySelectorConfig .determineSorter (sorterManner , entityDescriptor );
266262 } else if (config .getSorterComparatorClass () != null ) {
267263 Comparator <Object > sorterComparator =
268264 instanceCache .newInstance (config , "sorterComparatorClass" , config .getSorterComparatorClass ());
@@ -276,12 +272,12 @@ protected EntitySelector<Solution_> applySorting(SelectionCacheType resolvedCach
276272 } else if (config .getSorterClass () != null ) {
277273 sorter = instanceCache .newInstance (config , "sorterClass" , config .getSorterClass ());
278274 } else {
279- throw new IllegalArgumentException ("The entitySelectorConfig (" + config
280- + " ) with resolvedSelectionOrder (" + resolvedSelectionOrder
281- + ") needs a sorterManner (" + config . getSorterManner ()
282- + ") or a sorterComparatorClass (" + config . getSorterComparatorClass ()
283- + ") or a sorterWeightFactoryClass (" + config .getSorterWeightFactoryClass ()
284- + ") or a sorterClass (" + config .getSorterClass () + ")." );
275+ throw new IllegalArgumentException ("""
276+ The entitySelectorConfig (%s ) with resolvedSelectionOrder (%s) needs \
277+ a sorterManner (%s) or a sorterComparatorClass (%s) or a sorterWeightFactoryClass (%s) \
278+ or a sorterClass (%s)."""
279+ . formatted ( config , resolvedSelectionOrder , sorterManner , config .getSorterComparatorClass (),
280+ config .getSorterWeightFactoryClass (), config . getSorterClass ()) );
285281 }
286282 entitySelector = new SortingEntitySelector <>(entitySelector , resolvedCacheType , sorter );
287283 }
0 commit comments