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