public ArrayAddExpressionEvaluator( JsonNodeFactory factory, FieldTreeNode context, ArrayAddExpression expr) { this.factory = factory; if (expr.getOp() == UpdateOperator._insert) { // Path should include an index if (expr.getField().isIndex(expr.getField().numSegments() - 1)) { arrayField = expr.getField().prefix(-1); insertionIndex = expr.getField().getIndex(expr.getField().numSegments() - 1); } else { throw new EvaluationError(CrudConstants.ERR_REQUIRED_INSERTION_INDEX + expr.getField()); } } else { arrayField = expr.getField(); insertionIndex = -1; } if (arrayField.nAnys() > 0) { throw new EvaluationError(CrudConstants.ERR_PATTERN_NOT_EXPECTED + arrayField); } FieldTreeNode ftn = context.resolve(arrayField); if (ftn instanceof ArrayField) { fieldMd = (ArrayField) ftn; // Array size field should be at the same level as the array field MutablePath abs = new MutablePath(); fieldMd.getFullPath(abs); absArrayField = abs.mutableCopy(); abs.setLast(abs.getLast() + "#"); // At this point, arraySizeField is derived from metadata, // so it has * as array indexes arraySizeField = abs.immutableCopy(); values = new ArrayList<>(expr.getValues().size()); initializeArrayField(context, expr); } else { throw new EvaluationError(CrudConstants.ERR_REQUIRED_ARRAY + arrayField); } }
private void initializeArrayField(FieldTreeNode context, ArrayAddExpression expr) { for (RValueExpression rvalue : expr.getValues()) { Path refPath = null; FieldTreeNode refMd = null; if (rvalue.getType() == RValueExpression.RValueType._dereference) { refPath = rvalue.getPath(); refMd = context.resolve(refPath); if (refMd == null) { throw new EvaluationError(CrudConstants.ERR_INVALID_DEREFERENCE + refPath); } } ArrayElement element = fieldMd.getElement(); validateArrayElement(element, refMd, rvalue, refPath); values.add( new RValueData( refPath, refMd == null ? null : refMd.getType(), rvalue.getValue(), rvalue.getType())); } }