in scim-core/src/main/java/org/apache/directory/scim/core/repository/UpdateRequest.java [327:437]
private List<PatchOperation> handleAttributes(JsonNode valueNode, PatchOperation.Type patchOpType, ParseData parseData) throws IllegalAccessException, JsonProcessingException {
log.trace("in handleAttributes");
List<PatchOperation> operations = new ArrayList<>();
List<String> attributeReferenceList = new ArrayList<>();
FilterExpression valueFilterExpression = null;
List<String> subAttributes = new ArrayList<>();
boolean processingMultiValued = false;
boolean processedMultiValued = false;
boolean done = false;
int i = 0;
for (String pathPart : parseData.pathParts) {
log.trace("path part: {}", pathPart);
if (done) {
throw new RuntimeException("Path should be done... Attribute not supported by the schema: " + pathPart);
} else if (processingMultiValued) {
parseData.traverseObjectsInArray(pathPart, patchOpType);
if (!parseData.isLastIndex(i) || patchOpType != PatchOperation.Type.ADD) {
if (parseData.originalObject instanceof TypedAttribute) {
TypedAttribute typedAttribute = (TypedAttribute) parseData.originalObject;
String type = typedAttribute.getType();
valueFilterExpression = new AttributeComparisonExpression(new AttributeReference("type"), CompareOperator.EQ, type);
} else if (parseData.originalObject instanceof String || parseData.originalObject instanceof Number) {
String toString = parseData.originalObject.toString();
valueFilterExpression = new AttributeComparisonExpression(new AttributeReference("value"), CompareOperator.EQ, toString);
} else if(parseData.originalObject instanceof Enum) {
Enum<?> tempEnum = (Enum<?>)parseData.originalObject;
valueFilterExpression = new AttributeComparisonExpression(new AttributeReference("value"), CompareOperator.EQ, tempEnum.name());
} else {
if (parseData.originalObject != null) {
log.debug("Attribute: {} doesn't implement TypedAttribute, can't create ValueFilterExpression", parseData.originalObject.getClass());
} else {
log.debug("Attribute: null doesn't implement TypedAttribute, can't create ValueFilterExpression");
}
valueFilterExpression = new AttributeComparisonExpression(new AttributeReference("value"), CompareOperator.EQ, "?");
}
processingMultiValued = false;
processedMultiValued = true;
}
} else {
Attribute attribute = parseData.ac.getAttribute(pathPart);
if (attribute != null) {
if (processedMultiValued) {
subAttributes.add(pathPart);
} else {
log.debug("Adding {} to attributeReferenceList", pathPart);
attributeReferenceList.add(pathPart);
}
parseData.traverseObjects(pathPart, attribute);
if (patchOpType == Type.REPLACE &&
(parseData.resourceObject != null && parseData.resourceObject instanceof Collection && !((Collection<?>)parseData.resourceObject).isEmpty()) &&
(parseData.originalObject == null ||
(parseData.originalObject instanceof Collection && ((Collection<?>)parseData.originalObject).isEmpty()))) {
patchOpType = Type.ADD;
}
if (attribute.isMultiValued()) {
processingMultiValued = true;
} else if (attribute.getType() != Attribute.Type.COMPLEX) {
done = true;
}
}
}
++i;
}
if (patchOpType == Type.REPLACE && (parseData.resourceObject == null ||
(parseData.resourceObject instanceof Collection && ((Collection<?>)parseData.resourceObject).isEmpty()))) {
patchOpType = Type.REMOVE;
valueNode = null;
}
if (patchOpType == Type.REPLACE && parseData.originalObject == null) {
patchOpType = Type.ADD;
}
if (!attributeReferenceList.isEmpty()) {
Object value = determineValue(patchOpType, valueNode, parseData);
if (value != null && value instanceof ArrayList) {
List<Object> objList = (List<Object>)value;
if (!objList.isEmpty()) {
Object firstElement = objList.get(0);
if (firstElement instanceof ArrayList) {
objList = (List<Object>) firstElement;
}
for (Object obj : objList) {
PatchOperation operation = buildPatchOperation(patchOpType, parseData, attributeReferenceList, valueFilterExpression, subAttributes, obj);
if (operation != null) {
operations.add(operation);
}
}
}
} else {
PatchOperation operation = buildPatchOperation(patchOpType, parseData, attributeReferenceList, valueFilterExpression, subAttributes, value);
if (operation != null) {
operations.add(operation);
}
}
}
return operations;
}