Search in sources :

Example 1 with Instruction

use of com.linkedin.data.transform.Instruction 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 2 with Instruction

use of com.linkedin.data.transform.Instruction 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 3 with Instruction

use of com.linkedin.data.transform.Instruction 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)

Example 4 with Instruction

use of com.linkedin.data.transform.Instruction in project rest.li by linkedin.

the class Filter method interpret.

@Override
public void interpret(InterpreterContext instrCtx) {
    _instrCtx = instrCtx;
    final Instruction instruction = _instrCtx.getCurrentInstruction();
    final Object dataValue = instruction.getData();
    final DataMap opNode = getOperation(instruction);
    filter(dataValue, opNode);
}
Also used : Instruction(com.linkedin.data.transform.Instruction) DataMap(com.linkedin.data.DataMap)

Aggregations

DataMap (com.linkedin.data.DataMap)4 Instruction (com.linkedin.data.transform.Instruction)4 HashMap (java.util.HashMap)1 IdentityHashMap (java.util.IdentityHashMap)1