private void processValueRangeAnnotation() { Method propertyGetter = variablePropertyAccessor.getReadMethod(); ValueRange valueRangeAnnotation = propertyGetter.getAnnotation(ValueRange.class); ValueRanges valueRangesAnnotation = propertyGetter.getAnnotation(ValueRanges.class); if (valueRangeAnnotation != null) { if (valueRangesAnnotation != null) { throw new IllegalArgumentException( "The planningEntityClass (" + planningEntityDescriptor.getPlanningEntityClass() + ") has a PlanningVariable annotated property (" + variablePropertyAccessor.getName() + ") that has a @ValueRange and @ValueRanges annotation: fold them into 1 @ValueRanges."); } valueRangeDescriptor = buildValueRangeDescriptor(valueRangeAnnotation); } else { if (valueRangesAnnotation == null) { throw new IllegalArgumentException( "The planningEntityClass (" + planningEntityDescriptor.getPlanningEntityClass() + ") has a PlanningVariable annotated property (" + variablePropertyAccessor.getName() + ") that has no @ValueRange or @ValueRanges annotation."); } List<PlanningValueRangeDescriptor> valueRangeDescriptorList = new ArrayList<PlanningValueRangeDescriptor>(valueRangesAnnotation.value().length); for (ValueRange partialValueRangeAnnotation : valueRangesAnnotation.value()) { valueRangeDescriptorList.add(buildValueRangeDescriptor(partialValueRangeAnnotation)); } valueRangeDescriptor = new CompositePlanningValueRangeDescriptor(this, valueRangeDescriptorList); } }
private void processChained(PlanningVariable planningVariableAnnotation) { chained = planningVariableAnnotation.chained(); if (chained && !variablePropertyAccessor .getPropertyType() .isAssignableFrom(planningEntityDescriptor.getPlanningEntityClass())) { throw new IllegalArgumentException( "The planningEntityClass (" + planningEntityDescriptor.getPlanningEntityClass() + ") has a PlanningVariable annotated property (" + variablePropertyAccessor.getName() + ") with chained (" + chained + ") and propertyType (" + variablePropertyAccessor.getPropertyType() + ") which is not a superclass/interface of or the same as the planningEntityClass (" + planningEntityDescriptor.getPlanningEntityClass() + ")."); } if (chained && nullable) { throw new IllegalArgumentException( "The planningEntityClass (" + planningEntityDescriptor.getPlanningEntityClass() + ") has a PlanningVariable annotated property (" + variablePropertyAccessor.getName() + ") with chained (" + chained + "), which is not compatible with nullable (" + nullable + ")."); } }
private void processNullable(PlanningVariable planningVariableAnnotation) { nullable = planningVariableAnnotation.nullable(); if (nullable && variablePropertyAccessor.getPropertyType().isPrimitive()) { throw new IllegalArgumentException( "The planningEntityClass (" + planningEntityDescriptor.getPlanningEntityClass() + ") has a PlanningVariable annotated property (" + variablePropertyAccessor.getName() + ") with nullable (" + nullable + "), which is not compatible with the primitive propertyType (" + variablePropertyAccessor.getPropertyType() + ")."); } Class<? extends SelectionFilter> reinitializeVariableEntityFilterClass = planningVariableAnnotation.reinitializeVariableEntityFilter(); if (reinitializeVariableEntityFilterClass == PlanningVariable.NullReinitializeVariableEntityFilter.class) { reinitializeVariableEntityFilterClass = null; } if (reinitializeVariableEntityFilterClass != null) { reinitializeVariableEntityFilter = ConfigUtils.newInstance( this, "reinitializeVariableEntityFilterClass", reinitializeVariableEntityFilterClass); } else { reinitializeVariableEntityFilter = new NullValueReinitializeVariableEntityFilter(this); } }
private void processStrength(PlanningVariable planningVariableAnnotation) { Class<? extends Comparator> strengthComparatorClass = planningVariableAnnotation.strengthComparatorClass(); if (strengthComparatorClass == PlanningVariable.NullStrengthComparator.class) { strengthComparatorClass = null; } Class<? extends SelectionSorterWeightFactory> strengthWeightFactoryClass = planningVariableAnnotation.strengthWeightFactoryClass(); if (strengthWeightFactoryClass == PlanningVariable.NullStrengthWeightFactory.class) { strengthWeightFactoryClass = null; } if (strengthComparatorClass != null && strengthWeightFactoryClass != null) { throw new IllegalStateException( "The planningEntityClass (" + planningEntityDescriptor.getPlanningEntityClass() + ") property (" + variablePropertyAccessor.getName() + ") cannot have a strengthComparatorClass (" + strengthComparatorClass.getName() + ") and a strengthWeightFactoryClass (" + strengthWeightFactoryClass.getName() + ") at the same time."); } if (strengthComparatorClass != null) { Comparator<Object> strengthComparator = ConfigUtils.newInstance(this, "strengthComparatorClass", strengthComparatorClass); valueSorter.setStrengthComparator(strengthComparator); } if (strengthWeightFactoryClass != null) { SelectionSorterWeightFactory strengthWeightFactory = ConfigUtils.newInstance(this, "strengthWeightFactoryClass", strengthWeightFactoryClass); valueSorter.setStrengthWeightFactory(strengthWeightFactory); } }
@Override public String toString() { return getClass().getSimpleName() + "(" + variablePropertyAccessor.getName() + " of " + planningEntityDescriptor.getPlanningEntityClass().getName() + ")"; }
private void processPlanningEntityProperty(ValueRange valueRangeAnnotation) { String planningEntityProperty = valueRangeAnnotation.planningEntityProperty(); PlanningEntityDescriptor planningEntityDescriptor = variableDescriptor.getPlanningEntityDescriptor(); rangePropertyAccessor = new ReflectionPropertyAccessor( planningEntityDescriptor.getPropertyDescriptor(planningEntityProperty)); if (rangePropertyAccessor == null) { String exceptionMessage = "The planningEntityClass (" + planningEntityDescriptor.getPlanningEntityClass() + ") has a PlanningVariable annotated property (" + variableDescriptor.getVariableName() + ") that refers to a planningEntityProperty (" + planningEntityProperty + ") that does not exist."; if (planningEntityProperty.length() >= 2 && Character.isUpperCase(planningEntityProperty.charAt(1))) { String correctedPlanningEntityProperty = planningEntityProperty.substring(0, 1).toUpperCase() + planningEntityProperty.substring(1); exceptionMessage += " But it probably needs to be correctedPlanningEntityProperty (" + correctedPlanningEntityProperty + ") instead because the JavaBeans spec states" + " the first letter should be a upper case if the second is upper case."; } throw new IllegalArgumentException(exceptionMessage); } if (!Collection.class.isAssignableFrom(rangePropertyAccessor.getPropertyType())) { throw new IllegalArgumentException( "The planningEntityClass (" + planningEntityDescriptor.getPlanningEntityClass() + ") has a PlanningVariable annotated property (" + variableDescriptor.getVariableName() + ") that refers to a planningEntityProperty (" + planningEntityProperty + ") that does not return a Collection."); } }
public ValueSelector buildValueSelector( EnvironmentMode environmentMode, SolutionDescriptor solutionDescriptor, SelectionOrder inheritedResolvedSelectionOrder, PlanningEntityDescriptor entityDescriptor) { PlanningVariableDescriptor variableDescriptor; if (planningVariableName != null) { variableDescriptor = entityDescriptor.getPlanningVariableDescriptor(planningVariableName); if (variableDescriptor == null) { throw new IllegalArgumentException( "The variableSelectorConfig (" + this + ") has a planningVariableName (" + planningVariableName + ") for planningEntityClass (" + entityDescriptor.getPlanningEntityClass() + ") that is not annotated as a planningVariable.\n" + "Check your planningEntity implementation's annotated methods."); } } else { Collection<PlanningVariableDescriptor> planningVariableDescriptors = entityDescriptor.getPlanningVariableDescriptors(); if (planningVariableDescriptors.size() != 1) { throw new IllegalArgumentException( "The variableSelectorConfig (" + this + ") has no configured planningVariableName (" + planningVariableName + ") for planningEntityClass (" + entityDescriptor.getPlanningEntityClass() + ") and because there are multiple in the planningVariableNameSet (" + entityDescriptor.getPlanningVariableNameSet() + "), it can not be deducted automatically."); } variableDescriptor = planningVariableDescriptors.iterator().next(); } SelectionOrder resolvedSelectionOrder = SelectionOrder.resolveSelectionOrder(selectionOrder, inheritedResolvedSelectionOrder); boolean randomSelection = resolvedSelectionOrder == SelectionOrder.RANDOM && valueProbabilityWeightFactoryClass == null; // TODO we probably want to default this to SelectionCacheType.JUST_IN_TIME SelectionCacheType resolvedCacheType = cacheType == null ? SelectionCacheType.PHASE : cacheType; ValueSelector valueSelector = new FromSolutionPropertyValueSelector( variableDescriptor, randomSelection, resolvedCacheType); // TODO filterclass if (valueProbabilityWeightFactoryClass != null) { if (resolvedSelectionOrder != SelectionOrder.RANDOM) { throw new IllegalArgumentException( "The variableSelectorConfig (" + this + ") with valueProbabilityWeightFactoryClass (" + valueProbabilityWeightFactoryClass + ") has a non-random resolvedSelectionOrder (" + resolvedSelectionOrder + ")."); } SelectionProbabilityWeightFactory valueProbabilityWeightFactory; try { valueProbabilityWeightFactory = valueProbabilityWeightFactoryClass.newInstance(); } catch (InstantiationException e) { throw new IllegalArgumentException( "valueProbabilityWeightFactoryClass (" + valueProbabilityWeightFactoryClass.getName() + ") does not have a public no-arg constructor", e); } catch (IllegalAccessException e) { throw new IllegalArgumentException( "valueProbabilityWeightFactoryClass (" + valueProbabilityWeightFactoryClass.getName() + ") does not have a public no-arg constructor", e); } ProbabilityValueSelector probabilityValueSelector = new ProbabilityValueSelector( valueSelector, resolvedCacheType, valueProbabilityWeightFactory); valueSelector = probabilityValueSelector; } return valueSelector; }