11package ai .timefold .solver .core .impl .domain .variable .descriptor ;
22
3+ import static ai .timefold .solver .core .config .util .ConfigUtils .newInstance ;
4+
35import java .lang .reflect .ParameterizedType ;
4- import java .lang .reflect .Type ;
56import java .util .ArrayList ;
67import java .util .Arrays ;
7- import java .util .Collection ;
88import java .util .Comparator ;
99import java .util .stream .Stream ;
1010
1111import ai .timefold .solver .core .api .domain .solution .PlanningSolution ;
12- import ai .timefold .solver .core .api .domain .valuerange .ValueRange ;
1312import ai .timefold .solver .core .api .domain .valuerange .ValueRangeProvider ;
1413import ai .timefold .solver .core .api .domain .variable .PlanningListVariable ;
1514import ai .timefold .solver .core .api .domain .variable .PlanningVariable ;
@@ -91,8 +90,8 @@ The entityClass (%s) has a @%s annotated property (%s) that has no valueRangePro
9190 }
9291
9392 private MemberAccessor [] findAnonymousValueRangeMemberAccessors (DescriptorPolicy descriptorPolicy ) {
94- boolean supportsValueRangeProviderFromEntity = !isListVariable ();
95- Stream < MemberAccessor > applicableValueRangeProviderAccessors =
93+ var supportsValueRangeProviderFromEntity = !isListVariable ();
94+ var applicableValueRangeProviderAccessors =
9695 supportsValueRangeProviderFromEntity ? Stream .concat (
9796 descriptorPolicy .getAnonymousFromEntityValueRangeProviderSet ().stream (),
9897 descriptorPolicy .getAnonymousFromSolutionValueRangeProviderSet ().stream ())
@@ -103,26 +102,23 @@ private MemberAccessor[] findAnonymousValueRangeMemberAccessors(DescriptorPolicy
103102 * For basic variable, the type is the type of the variable.
104103 * For list variable, the type is List<X>, and we need to know X.
105104 */
106- Class <?> variableType =
105+ var variableType =
107106 isListVariable () ? (Class <?>) ((ParameterizedType ) variableMemberAccessor .getGenericType ())
108107 .getActualTypeArguments ()[0 ] : variableMemberAccessor .getType ();
109108 // We expect either ValueRange, Collection or an array.
110- Type valueRangeType = valueRangeProviderAccessor .getGenericType ();
109+ var valueRangeType = valueRangeProviderAccessor .getGenericType ();
111110 if (valueRangeType instanceof ParameterizedType parameterizedValueRangeType ) {
112- Class <?> rawType = (Class <?>) parameterizedValueRangeType .getRawType ();
113- if (!ValueRange .class .isAssignableFrom (rawType ) && !Collection .class .isAssignableFrom (rawType )) {
114- return false ;
115- }
116- Type [] generics = parameterizedValueRangeType .getActualTypeArguments ();
117- if (generics .length != 1 ) {
118- return false ;
119- }
120- Class <?> valueRangeGenericType = (Class <?>) generics [0 ];
121- return variableType .isAssignableFrom (valueRangeGenericType );
111+ return ConfigUtils
112+ .extractGenericTypeParameter ("solutionClass" ,
113+ entityDescriptor .getSolutionDescriptor ().getSolutionClass (),
114+ valueRangeProviderAccessor .getType (), parameterizedValueRangeType ,
115+ ValueRangeProvider .class , valueRangeProviderAccessor .getName ())
116+ .map (variableType ::isAssignableFrom )
117+ .orElse (false );
122118 } else {
123- Class <?> clz = (Class <?>) valueRangeType ;
119+ var clz = (Class <?>) valueRangeType ;
124120 if (clz .isArray ()) {
125- Class <?> componentType = clz .getComponentType ();
121+ var componentType = clz .getComponentType ();
126122 return variableType .isAssignableFrom (componentType );
127123 }
128124 return false ;
@@ -137,7 +133,7 @@ private MemberAccessor findValueRangeMemberAccessor(DescriptorPolicy descriptorP
137133 } else if (descriptorPolicy .hasFromEntityValueRangeProvider (valueRangeProviderRef )) {
138134 return descriptorPolicy .getFromEntityValueRangeProvider (valueRangeProviderRef );
139135 } else {
140- Collection < String > providerIds = descriptorPolicy .getValueRangeProviderIds ();
136+ var providerIds = descriptorPolicy .getValueRangeProviderIds ();
141137 throw new IllegalArgumentException ("The entityClass (" + entityDescriptor .getEntityClass ()
142138 + ") has a @" + PlanningVariable .class .getSimpleName ()
143139 + " annotated property (" + variableMemberAccessor .getName ()
@@ -183,15 +179,15 @@ protected void processStrength(Class<? extends Comparator> strengthComparatorCla
183179 + ") at the same time." );
184180 }
185181 if (strengthComparatorClass != null ) {
186- Comparator <Object > strengthComparator = ConfigUtils . newInstance (this ::toString ,
182+ Comparator <Object > strengthComparator = newInstance (this ::toString ,
187183 "strengthComparatorClass" , strengthComparatorClass );
188184 increasingStrengthSorter = new ComparatorSelectionSorter <>(strengthComparator ,
189185 SelectionSorterOrder .ASCENDING );
190186 decreasingStrengthSorter = new ComparatorSelectionSorter <>(strengthComparator ,
191187 SelectionSorterOrder .DESCENDING );
192188 }
193189 if (strengthWeightFactoryClass != null ) {
194- SelectionSorterWeightFactory <Solution_ , Object > strengthWeightFactory = ConfigUtils . newInstance (this ::toString ,
190+ SelectionSorterWeightFactory <Solution_ , Object > strengthWeightFactory = newInstance (this ::toString ,
195191 "strengthWeightFactoryClass" , strengthWeightFactoryClass );
196192 increasingStrengthSorter = new WeightFactorySelectionSorter <>(strengthWeightFactory ,
197193 SelectionSorterOrder .ASCENDING );
@@ -241,7 +237,7 @@ public boolean isValueRangeEntityIndependent() {
241237 * is reinitializable if its value is {@code null}.
242238 */
243239 public boolean isReinitializable (Object entity ) {
244- Object value = getValue (entity );
240+ var value = getValue (entity );
245241 return value == null ;
246242 }
247243
0 commit comments