public void applyMultiValue()

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