in scim-core/src/main/java/org/apache/directory/scim/core/repository/PatchHandlerImpl.java [274:314]
public <T extends ScimResource> void applyMultiValue(T source, Map<String, Object> sourceAsMap, Schema schema, Attribute attribute, ValuePathExpression valuePathExpression, Object value) {
String attributeName = valuePathExpression.getAttributePath().getAttributeName();
if (!valuePathExpression.getAttributePath().hasSubAttribute()) {
throw new UnsupportedFilterException("Invalid filter, expecting patch filter with expression to have a sub-attribute.");
}
// apply expression filter
Collection<Map<String, Object>> items = (Collection<Map<String, Object>>) sourceAsMap.getOrDefault(attributeName, new ArrayList<Map<String, Object>>());
Predicate<Object> pred = FilterExpressions.inMemoryMap(valuePathExpression.getAttributeExpression(), schema);
String subAttributeName = valuePathExpression.getAttributePath().getSubAttributeName();
boolean matchFound = false;
for (Map<String, Object> item : items) {
if (pred.test(item)) {
matchFound = true;
checkMutability(attribute, item.get(subAttributeName));
checkPrimary(subAttributeName, items, value);
item.put(subAttributeName, value);
}
}
// if the value was not added to an existing item, create a new value and add the patch value and the expression
// values for example in the expression `emails[type eq "work"].value` with a patch value of `foo@example.com`
// the map will contain `type: "work", value: "foo@example.com"`
if (!matchFound) {
if (!(valuePathExpression.getAttributeExpression() instanceof AttributeComparisonExpression)) {
throw new UnsupportedFilterException("Attribute cannot be added, only comparison expressions are supported when the existing item does not exist.");
}
AttributeComparisonExpression comparisonExpression = (AttributeComparisonExpression) valuePathExpression.getAttributeExpression();
checkPrimary(subAttributeName, items, value);
// Add a new mutable map
items.add(new HashMap<>(Map.of(
comparisonExpression.getAttributePath().getSubAttributeName(), comparisonExpression.getCompareValue(),
subAttributeName, value)));
}
sourceAsMap.put(attributeName, items);
}