Search in sources :

Example 6 with DataMap

use of com.linkedin.data.DataMap in project rest.li by linkedin.

the class MaskComposition method interpret.

@Override
public void interpret(InterpreterContext instrCtx) {
    Instruction instruction = instrCtx.getCurrentInstruction();
    if ((!(instruction.getData().getClass() == DataMap.class)) || (!(instruction.getOperation().getClass() == DataMap.class))) {
        instrCtx.addErrorMessage("data and operation in composition instruction have to be of type DataMap, instruction: %1$s", instruction);
    } else {
        DataMap data = (DataMap) instruction.getData();
        DataMap op = (DataMap) instruction.getOperation();
        Object opWildcard = op.get(FilterConstants.WILDCARD);
        Object dataWildcard = data.get(FilterConstants.WILDCARD);
        if ((opWildcard != null && opWildcard.equals(FilterConstants.NEGATIVE)) || (dataWildcard != null && dataWildcard.equals(FilterConstants.NEGATIVE))) {
            handleNegativeWildcard(data);
        } else {
            //process array range
            composeArrayRange(data, op, instrCtx);
            // process all fields
            for (Entry<String, Object> entry : op.entrySet()) {
                String fieldName = entry.getKey();
                Object opMask = entry.getValue();
                Object dataMask = data.get(fieldName);
                if (!fieldName.equals(FilterConstants.START) && !fieldName.equals(FilterConstants.COUNT)) {
                    composeField(fieldName, opMask, dataMask, data, dataWildcard, instrCtx);
                }
            }
        }
    }
}
Also used : Instruction(com.linkedin.data.transform.Instruction) DataMap(com.linkedin.data.DataMap)

Example 7 with DataMap

use of com.linkedin.data.DataMap in project rest.li by linkedin.

the class MaskComposition method composeField.

/**
   * This method handles logic for single field composition.
   * @return true if operation was successful and false otherwise
   */
private boolean composeField(final String fieldName, /**
                             * opMask is not final, because operation side of instruction should not be
                             * changed, so whenever it has to be merged with 1, clone is created
                             */
Object opMask, final Object dataMask, final DataMap data, final Object dataWildcard, InterpreterContext instrCtx) {
    instrCtx.setCurrentField(fieldName);
    boolean failed = false;
    if (dataMask == null) {
        // avoid copying 1 if there exist wildcard with value 1
        if (!opMask.equals(FilterConstants.POSITIVE) || !isMarkedAsMergedWith1(data))
            // missing fields are copied
            data.put(fieldName, opMask);
    } else if (dataMask instanceof Integer) {
        //if it is positive, then
        if (((Integer) dataMask).equals(FilterConstants.POSITIVE)) {
            if (opMask instanceof Integer) {
                Integer merged = merge((Integer) dataMask, (Integer) opMask, instrCtx);
                if (merged != null)
                    data.put(fieldName, merged);
                else
                    failed = true;
            } else if (opMask.getClass() == DataMap.class) {
                opMask = cloneDataMap((DataMap) opMask, instrCtx);
                if (opMask != null) {
                    if (!mergeWith1((DataMap) opMask, data, fieldName))
                        data.put(fieldName, opMask);
                } else
                    failed = true;
            } else {
                instrCtx.addErrorMessage("field mask value of unsupported type: %1$s", opMask.getClass().getName());
                failed = true;
            }
        }
    } else if (dataMask.getClass() == DataMap.class) {
        if (opMask instanceof Integer) {
            if (((Integer) opMask).equals(FilterConstants.NEGATIVE))
                data.put(fieldName, FilterConstants.NEGATIVE);
            else
                mergeWith1((DataMap) dataMask, data, fieldName);
        } else if (opMask.getClass() == DataMap.class)
            instrCtx.scheduleInstruction(new Instruction((DataMap) opMask, (DataMap) dataMask, instrCtx.getPath()));
        else {
            instrCtx.addErrorMessage("field mask value of unsupported type: %1$s", opMask.getClass().getName());
            failed = true;
        }
    } else {
        instrCtx.addErrorMessage("field mask value of unsupported type: %1$s", dataMask.getClass().getName());
        failed = true;
    }
    //return true if operation was successful and false otherwise
    return !failed;
}
Also used : Instruction(com.linkedin.data.transform.Instruction) DataMap(com.linkedin.data.DataMap)

Example 8 with DataMap

use of com.linkedin.data.DataMap in project rest.li by linkedin.

the class MaskTree method addOperation.

/**
   * Add an operation to this {@link MaskTree}, given a path indicating the field to which the operation
   * applies and a {@link MaskOperation} representing the operation to be applied.
   * @param path the path of the field to which the operation applies
   * @param op the MaskOperation to be performed on the field
   */
public void addOperation(PathSpec path, MaskOperation op) {
    List<String> segments = path.getPathComponents();
    final DataMap fieldMask = new DataMap();
    //map variable contains DataMap, into which current segment will be put
    DataMap map = fieldMask;
    for (int ii = 0; ii < segments.size() - 1; ++ii) {
        String segment = Escaper.escapePathSegment(segments.get(ii));
        DataMap childMap = new DataMap();
        map.put(segment, childMap);
        map = childMap;
    }
    String lastSegment = Escaper.escapePathSegment(segments.get(segments.size() - 1));
    map.put(lastSegment, op.getRepresentation());
    //compose existing tree with mask for specific field
    try {
        new DataComplexProcessor(new MaskComposition(), fieldMask, _representation).run(false);
    } catch (DataProcessingException e) {
        throw new IllegalStateException("error while building mask tree", e);
    }
}
Also used : MaskComposition(com.linkedin.data.transform.filter.MaskComposition) DataComplexProcessor(com.linkedin.data.transform.DataComplexProcessor) DataMap(com.linkedin.data.DataMap) DataProcessingException(com.linkedin.data.transform.DataProcessingException)

Example 9 with DataMap

use of com.linkedin.data.DataMap in project rest.li by linkedin.

the class MaskTree method getOperationsImpl.

private void getOperationsImpl(DataMap data, PathSpec path, Map<PathSpec, MaskOperation> result) {
    for (Map.Entry<String, Object> entry : data.entrySet()) {
        String segment = Escaper.unescapePathSegment(entry.getKey());
        PathSpec subpath = new PathSpec(path.getPathComponents(), segment);
        Object value = entry.getValue();
        if (value instanceof Integer) {
            if (value.equals(MaskOperation.NEGATIVE_MASK_OP.getRepresentation())) {
                result.put(subpath, MaskOperation.NEGATIVE_MASK_OP);
            } else if (value.equals(MaskOperation.POSITIVE_MASK_OP.getRepresentation())) {
                result.put(subpath, MaskOperation.POSITIVE_MASK_OP);
            } else {
                throw new IllegalStateException("invalid mask tree");
            }
        } else if (value.getClass() == DataMap.class) {
            getOperationsImpl((DataMap) value, subpath, result);
        } else {
            throw new IllegalStateException("invalid mask tree");
        }
    }
}
Also used : DataMap(com.linkedin.data.DataMap) Map(java.util.Map) HashMap(java.util.HashMap) PathSpec(com.linkedin.data.schema.PathSpec) DataMap(com.linkedin.data.DataMap)

Example 10 with DataMap

use of com.linkedin.data.DataMap in project rest.li by linkedin.

the class Patch method interpret.

/**
   * Interpret and execute the current instruction based on the
   * interpreter context.
   *
   * @param instrCtx the current interpreter context
   */
public void interpret(final InterpreterContext instrCtx) {
    Instruction instruction = instrCtx.getCurrentInstruction();
    // operation's node is always DataMap
    assert instruction.getOperation().getClass() == DataMap.class;
    // data's node is always DataMap
    assert instruction.getData().getClass() == DataMap.class;
    //_usedFields variable is used to keep track of fields, which were already used
    //at this nodes. The reason for it is that if field should not be used in more than
    //one operation e.g. $set and $delete, because such patch becomes ambiguous.
    //Each operation, upon being executed updates this variable.
    final Map<String, String> usedFields = new HashMap<String, String>();
    DataMap opNode = (DataMap) instruction.getOperation();
    DataMap dataNode = (DataMap) instruction.getData();
    /**
     * Apply all supported operations here. _usedFields is used to keep track of fields
     * that operations were applied to.
     */
    executeSetCommand(opNode.get(SET_COMMAND), dataNode, usedFields, instrCtx);
    executeDeleteCommand(opNode.get(DELETE_COMMAND), dataNode, usedFields, instrCtx);
    // iterate over children
    for (Entry<String, Object> entry : opNode.entrySet()) processChild(dataNode, entry.getKey(), entry.getValue(), usedFields, instrCtx);
}
Also used : IdentityHashMap(java.util.IdentityHashMap) HashMap(java.util.HashMap) Instruction(com.linkedin.data.transform.Instruction) DataMap(com.linkedin.data.DataMap)

Aggregations

DataMap (com.linkedin.data.DataMap)471 Test (org.testng.annotations.Test)238 DataList (com.linkedin.data.DataList)130 ByteString (com.linkedin.data.ByteString)110 HashMap (java.util.HashMap)56 TestUtil.dataMapFromString (com.linkedin.data.TestUtil.dataMapFromString)49 RecordDataSchema (com.linkedin.data.schema.RecordDataSchema)47 TestUtil.dataSchemaFromString (com.linkedin.data.TestUtil.dataSchemaFromString)46 DataSchema (com.linkedin.data.schema.DataSchema)45 Map (java.util.Map)45 ArrayList (java.util.ArrayList)31 MaskTree (com.linkedin.data.transform.filter.request.MaskTree)23 PathSpec (com.linkedin.data.schema.PathSpec)21 RecordTemplate (com.linkedin.data.template.RecordTemplate)21 DataProvider (org.testng.annotations.DataProvider)20 HashSet (java.util.HashSet)19 ArrayDataSchema (com.linkedin.data.schema.ArrayDataSchema)18 PatchTree (com.linkedin.data.transform.patch.request.PatchTree)18 CompoundKey (com.linkedin.restli.common.CompoundKey)18 IOException (java.io.IOException)18