private List handleAttributes()

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;
  }