/** * Resolve the latest value for the {@link ValueDefinition} from the {@link ConfigurationSource} * and encapsulate it in a {@link ValueChangeAction} to be enacted in a subsequent operation. * * @param valueDefinition the value definition to prepare an update for * @param configurationSource the source from which to resolve the value. * @return the change action * @throws ConfigurationException if any problem occurs retrieving the value. */ public ValueChangeAction prepareValueChange( ValueDefinition<?, ?> valueDefinition, ConfigurationSource configurationSource) { String expression = valueDefinition.getExpression(); Class<?> type = valueDefinition.getType(); Object result; boolean available; if (expression != null) { available = configurationSource.isAvailable(expression); } else { available = configurationSource.isAvailable(type); } if (available) { if (valueDefinition instanceof ValueListDefinition) { if (expression != null) { result = configurationSource.retrieveList(expression, type); } else { result = configurationSource.retrieveList(type); } } else { if (expression != null) { result = configurationSource.retrieve(expression, type); } else { result = configurationSource.retrieve(type); } } } else if (valueDefinition.isRequired()) { throw new ValueConfigurationException("No value could be found for", type, expression); } else { // Not required and not available, set to null. How this is handled is assignment specific. result = null; } return new ValueChangeAction(valueDefinition, result); }