in core/optaplanner-core-impl/src/main/java/org/optaplanner/core/impl/domain/variable/custom/LegacyCustomShadowVariableDescriptor.java [111:209]
private void linkShadowSources(DescriptorPolicy descriptorPolicy) {
CustomShadowVariable shadowVariableAnnotation = variableMemberAccessor
.getAnnotation(CustomShadowVariable.class);
PlanningVariableReference variableListenerRef = shadowVariableAnnotation.variableListenerRef();
if (variableListenerRef.variableName().equals("")) {
variableListenerRef = null;
}
if (variableListenerRef != null) {
EntityDescriptor<Solution_> refEntityDescriptor;
Class<?> refEntityClass = variableListenerRef.entityClass();
if (refEntityClass.equals(PlanningVariableReference.NullEntityClass.class)) {
refEntityDescriptor = entityDescriptor;
} else {
refEntityDescriptor = entityDescriptor.getSolutionDescriptor().findEntityDescriptor(refEntityClass);
if (refEntityDescriptor == null) {
throw new IllegalArgumentException("The entityClass (" + entityDescriptor.getEntityClass()
+ ") has a @" + CustomShadowVariable.class.getSimpleName()
+ " annotated property (" + variableMemberAccessor.getName()
+ ") with a refEntityClass (" + refEntityClass
+ ") which is not a valid planning entity."
+ "\nMaybe check the annotations of the class (" + refEntityClass + ")."
+ "\nMaybe add the class (" + refEntityClass
+ ") among planning entities in the solver configuration.");
}
}
String refVariableName = variableListenerRef.variableName();
VariableDescriptor<Solution_> uncastRefVariableDescriptor = refEntityDescriptor
.getVariableDescriptor(refVariableName);
if (uncastRefVariableDescriptor == null) {
throw new IllegalArgumentException("The entityClass (" + entityDescriptor.getEntityClass()
+ ") has a @" + CustomShadowVariable.class.getSimpleName()
+ " annotated property (" + variableMemberAccessor.getName()
+ ") with refVariableName (" + refVariableName
+ ") which is not a valid planning variable on entityClass ("
+ refEntityDescriptor.getEntityClass() + ").\n"
+ refEntityDescriptor.buildInvalidVariableNameExceptionMessage(refVariableName));
}
if (!(uncastRefVariableDescriptor instanceof LegacyCustomShadowVariableDescriptor)) {
throw new IllegalArgumentException("The entityClass (" + entityDescriptor.getEntityClass()
+ ") has a @" + CustomShadowVariable.class.getSimpleName()
+ " annotated property (" + variableMemberAccessor.getName()
+ ") with refVariable (" + uncastRefVariableDescriptor.getSimpleEntityAndVariableName()
+ ") that lacks a @" + CustomShadowVariable.class.getSimpleName() + " annotation.");
}
refVariableDescriptor = (LegacyCustomShadowVariableDescriptor<Solution_>) uncastRefVariableDescriptor;
if (refVariableDescriptor.isRef()) {
throw new IllegalArgumentException("The entityClass (" + entityDescriptor.getEntityClass()
+ ") has a @" + CustomShadowVariable.class.getSimpleName()
+ " annotated property (" + variableMemberAccessor.getName()
+ ") with refVariable (" + refVariableDescriptor + ") that is a reference itself too.");
}
refVariableDescriptor.registerSinkVariableDescriptor(this);
} else {
PlanningVariableReference[] sources = shadowVariableAnnotation.sources();
sourceVariableDescriptorList = new ArrayList<>(sources.length);
for (PlanningVariableReference source : sources) {
EntityDescriptor<Solution_> sourceEntityDescriptor;
Class<?> sourceEntityClass = source.entityClass();
if (sourceEntityClass.equals(PlanningVariableReference.NullEntityClass.class)) {
sourceEntityDescriptor = entityDescriptor;
} else {
sourceEntityDescriptor = entityDescriptor.getSolutionDescriptor()
.findEntityDescriptor(sourceEntityClass);
if (sourceEntityDescriptor == null) {
throw new IllegalArgumentException("The entityClass (" + entityDescriptor.getEntityClass()
+ ") has a @" + CustomShadowVariable.class.getSimpleName()
+ " annotated property (" + variableMemberAccessor.getName()
+ ") with a sourceEntityClass (" + sourceEntityClass
+ ") which is not a valid planning entity."
+ "\nMaybe check the annotations of the class (" + sourceEntityClass + ")."
+ "\nMaybe add the class (" + sourceEntityClass
+ ") among planning entities in the solver configuration.");
}
}
String sourceVariableName = source.variableName();
VariableDescriptor<Solution_> sourceVariableDescriptor = sourceEntityDescriptor.getVariableDescriptor(
sourceVariableName);
if (sourceVariableDescriptor == null) {
throw new IllegalArgumentException("The entityClass (" + entityDescriptor.getEntityClass()
+ ") has a @" + CustomShadowVariable.class.getSimpleName()
+ " annotated property (" + variableMemberAccessor.getName()
+ ") with sourceVariableName (" + sourceVariableName
+ ") which is not a valid planning variable on entityClass ("
+ sourceEntityDescriptor.getEntityClass() + ").\n"
+ sourceEntityDescriptor.buildInvalidVariableNameExceptionMessage(sourceVariableName));
}
if (sourceVariableDescriptor.isGenuineListVariable()) {
throw new IllegalArgumentException("The entityClass (" + entityDescriptor.getEntityClass()
+ ") has a @" + CustomShadowVariable.class.getSimpleName()
+ " annotated property (" + variableMemberAccessor.getName()
+ ") with sourceVariableName (" + sourceVariableName
+ ") which is a list variable.\n"
+ "Custom shadow variables sourced on list variables are not yet supported.");
}
sourceVariableDescriptor.registerSinkVariableDescriptor(this);
sourceVariableDescriptorList.add(sourceVariableDescriptor);
}
}
}