in scim-tools/src/main/java/org/apache/directory/scim/tools/diff/PatchGenerator.java [184:231]
private static Set<PatchOperation> processMultiValuedComplexAttribute(Schema prefixSchema, List<Schema.Attribute> parentAttributes, Schema.Attribute attribute, Object left, Object right) {
Set<PatchOperation> patchOperations = new HashSet<>();
if (!isCollectionOrNull(left) || !isCollectionOrNull(right)) {
throw new IllegalArgumentException("The values of attribute '" + attributePath(prefixSchema, parentAttributes, attribute) + "' must be a Collection.");
}
Collection<Object> leftList = (Collection<Object>) left;
Collection<Object> rightList = (Collection<Object>) right;
if (isNotEmpty(leftList)) {
// Look for items to REMOVE
if (isNotEmpty(rightList)) {
List<Object> removed = new ArrayList<>(leftList);
removed.removeAll(rightList);
removed.forEach(item -> {
patchOperations.add(new PatchOperation()
.setOperation(PatchOperation.Type.REMOVE)
.setPath(new PatchOperationPath(attributeExpression(prefixSchema, parentAttributes, attribute, item))));
});
} else {
// Empty List, remove attribute
patchOperations.add(new PatchOperation()
.setOperation(PatchOperation.Type.REMOVE)
.setPath(new PatchOperationPath(attributeExpression(prefixSchema, parentAttributes, attribute))));
}
}
if (isNotEmpty(rightList)) {
List<Object> added = new ArrayList<>(rightList);
// remove values already present
if (isNotEmpty(leftList)) {
added.removeAll(leftList);
}
added.forEach(item -> {
patchOperations.add(new PatchOperation()
.setOperation(PatchOperation.Type.ADD)
.setPath(new PatchOperationPath(attributeExpression(prefixSchema, parentAttributes, attribute)))
.setValue(item));
});
}
return patchOperations;
}