*
* @param name the name of the reference to follow
* @return the referenced resource
*/
public ResourceImpl getReference(String name) {
ReferenceModel reference = resourceModel.getReference(name);
if (reference == null) {
throw new IllegalArgumentException("No reference named " + name);
}
if (reference.isMultiValued()) {
throw new IllegalArgumentException(
"The " + name + " reference is multi-valued. You must use "
+ "the getMultiReference method to resolve it.");
}
Map<String, Object> ids = new HashMap<>();
if (reference.getIdentifierMappings() != null) {
for (FlatMapping mapping : reference.getIdentifierMappings()) {
Object value = identifiers.get(mapping.getSource());
if (value == null) {
throw new IllegalStateException(
"The " + name + " reference model has a mapping "
+ "for the " + mapping.getSource() + " identifier, "
+ "but this resource doesn't have an identifier of "
+ "that name!");
}
ids.put(mapping.getTarget(), value);
}
}
if (reference.getAttributeMappings() != null) {
for (PathSourceMapping mapping
: reference.getAttributeMappings()) {
// AttributeMapping inside a resource reference has to be
// single-valued
if (mapping.isMultiValued()) {
throw new IllegalStateException(
"The " + name + " reference model has an invalid "
+ "attribute-mapping where the attribute source "
+ mapping.getSource() + " is multi-valued.");
}
Object value = getAttributeDataByPath(mapping.getSource());
if (value == null) {
// TODO: Check whether the identifier is nullable; if so
// it may be fine for this to be null...
return null;
}
ids.put(mapping.getTarget(), value);
}
}
ResourceModel refTypeModel =
serviceModel.getResource(reference.getType());
return new ResourceImpl(serviceModel, refTypeModel, client, ids);
}