Search in sources :

Example 1 with DataList

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

the class CollectionResponseBuilder method buildResponse.

@Override
public PartialRestResponse buildResponse(RoutingResult routingResult, RestLiResponseData responseData) {
    CollectionResponseEnvelope response = responseData.getCollectionResponseEnvelope();
    PartialRestResponse.Builder builder = new PartialRestResponse.Builder();
    CollectionResponse<AnyRecord> collectionResponse = new CollectionResponse<AnyRecord>(AnyRecord.class);
    collectionResponse.setPaging(response.getCollectionResponsePaging());
    DataList elementsMap = (DataList) collectionResponse.data().get(CollectionResponse.ELEMENTS);
    for (RecordTemplate entry : response.getCollectionResponse()) {
        CheckedUtil.addWithoutChecking(elementsMap, entry.data());
    }
    if (response.getCollectionResponseCustomMetadata() != null) {
        collectionResponse.setMetadataRaw(response.getCollectionResponseCustomMetadata().data());
    }
    builder.entity(collectionResponse);
    return builder.headers(responseData.getHeaders()).cookies(responseData.getCookies()).build();
}
Also used : DataList(com.linkedin.data.DataList) AnyRecord(com.linkedin.restli.internal.server.methods.AnyRecord) CollectionResponse(com.linkedin.restli.common.CollectionResponse) RecordTemplate(com.linkedin.data.template.RecordTemplate)

Example 2 with DataList

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

the class ArgumentBuilder method buildDataTemplateArgument.

private static DataTemplate<?> buildDataTemplateArgument(final ResourceContext context, final Parameter<?> param) {
    Object paramValue = context.getStructuredParameter(param.getName());
    DataTemplate<?> paramRecordTemplate;
    if (paramValue == null) {
        return null;
    } else {
        @SuppressWarnings("unchecked") final Class<? extends RecordTemplate> paramType = (Class<? extends RecordTemplate>) param.getType();
        /**
       * It is possible for the paramValue provided by ResourceContext to be coerced to the wrong type.
       * If a query param is a single value param for example www.domain.com/resource?foo=1.
       * Then ResourceContext will parse foo as a String with value = 1.
       * However if a query param contains many values for example www.domain.com/resource?foo=1&foo=2&foo=3
       * Then ResourceContext will parse foo as an DataList with value [1,2,3]
       *
       * So this means if the 'final' type of a query param is an Array and the paramValue we received from
       * ResourceContext is not a DataList we will have to wrap the paramValue inside a DataList
       */
        if (AbstractArrayTemplate.class.isAssignableFrom(paramType) && paramValue.getClass() != DataList.class) {
            paramRecordTemplate = DataTemplateUtil.wrap(new DataList(Arrays.asList(paramValue)), paramType);
        } else {
            paramRecordTemplate = DataTemplateUtil.wrap(paramValue, paramType);
        }
        // Validate against the class schema with FixupMode.STRING_TO_PRIMITIVE to parse the
        // strings into the corresponding primitive types.
        ValidateDataAgainstSchema.validate(paramRecordTemplate.data(), paramRecordTemplate.schema(), new ValidationOptions(RequiredMode.CAN_BE_ABSENT_IF_HAS_DEFAULT, CoercionMode.STRING_TO_PRIMITIVE));
        return paramRecordTemplate;
    }
}
Also used : DataList(com.linkedin.data.DataList) RecordTemplate(com.linkedin.data.template.RecordTemplate) DynamicRecordTemplate(com.linkedin.data.template.DynamicRecordTemplate) AbstractArrayTemplate(com.linkedin.data.template.AbstractArrayTemplate) ValidationOptions(com.linkedin.data.schema.validation.ValidationOptions)

Example 3 with DataList

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

the class AbstractDefaultDataTranslator method translate.

protected Object translate(List<Object> path, Object value, DataSchema dataSchema) {
    dataSchema = dataSchema.getDereferencedDataSchema();
    DataSchema.Type type = dataSchema.getType();
    Object result;
    switch(type) {
        case NULL:
            if (value != Data.NULL) {
                throw new IllegalArgumentException(message(path, "value must be null for null schema"));
            }
            result = value;
            break;
        case BOOLEAN:
            result = ((Boolean) value).booleanValue();
            break;
        case INT:
            result = ((Number) value).intValue();
            break;
        case LONG:
            result = ((Number) value).longValue();
            break;
        case FLOAT:
            result = ((Number) value).floatValue();
            break;
        case DOUBLE:
            result = ((Number) value).doubleValue();
            break;
        case STRING:
            result = (String) value;
            break;
        case BYTES:
            Class<?> clazz = value.getClass();
            if (clazz != String.class && clazz != ByteString.class) {
                throw new IllegalArgumentException(message(path, "bytes value %1$s is not a String or ByteString", value));
            }
            result = value;
            break;
        case ENUM:
            String enumValue = (String) value;
            EnumDataSchema enumDataSchema = (EnumDataSchema) dataSchema;
            if (!enumDataSchema.getSymbols().contains(enumValue)) {
                throw new IllegalArgumentException(message(path, "enum value %1$s not one of %2$s", value, enumDataSchema.getSymbols()));
            }
            result = value;
            break;
        case FIXED:
            clazz = value.getClass();
            ByteString byteString;
            if (clazz == String.class) {
                byteString = ByteString.copyAvroString((String) value, true);
            } else if (clazz == ByteString.class) {
                byteString = (ByteString) value;
            } else {
                throw new IllegalArgumentException(message(path, "fixed value %1$s is not a String or ByteString", value));
            }
            FixedDataSchema fixedDataSchema = (FixedDataSchema) dataSchema;
            if (fixedDataSchema.getSize() != byteString.length()) {
                throw new IllegalArgumentException(message(path, "ByteString size %1$d != FixedDataSchema size %2$d", byteString.length(), fixedDataSchema.getSize()));
            }
            result = byteString;
            break;
        case MAP:
            DataMap map = (DataMap) value;
            DataSchema valueDataSchema = ((MapDataSchema) dataSchema).getValues();
            Map<String, Object> resultMap = new DataMap(map.size() * 2);
            for (Map.Entry<String, Object> entry : map.entrySet()) {
                String key = entry.getKey();
                path.add(key);
                Object entryAvroValue = translate(path, entry.getValue(), valueDataSchema);
                path.remove(path.size() - 1);
                resultMap.put(key, entryAvroValue);
            }
            result = resultMap;
            break;
        case ARRAY:
            DataList list = (DataList) value;
            DataList resultList = new DataList(list.size());
            DataSchema elementDataSchema = ((ArrayDataSchema) dataSchema).getItems();
            for (int i = 0; i < list.size(); i++) {
                path.add(i);
                Object entryAvroValue = translate(path, list.get(i), elementDataSchema);
                path.remove(path.size() - 1);
                resultList.add(entryAvroValue);
            }
            result = resultList;
            break;
        case RECORD:
            DataMap recordMap = (DataMap) value;
            RecordDataSchema recordDataSchema = (RecordDataSchema) dataSchema;
            DataMap resultRecordMap = new DataMap(recordDataSchema.getFields().size() * 2);
            for (RecordDataSchema.Field field : recordDataSchema.getFields()) {
                String fieldName = field.getName();
                Object fieldValue = recordMap.get(fieldName);
                path.add(fieldName);
                Object resultFieldValue = translateField(path, fieldValue, field);
                path.remove(path.size() - 1);
                if (resultFieldValue != null) {
                    resultRecordMap.put(fieldName, resultFieldValue);
                }
            }
            result = resultRecordMap;
            break;
        case UNION:
            result = translateUnion(path, value, (UnionDataSchema) dataSchema);
            break;
        default:
            throw new IllegalStateException(message(path, "schema type unknown %1$s", type));
    }
    return result;
}
Also used : ByteString(com.linkedin.data.ByteString) MapDataSchema(com.linkedin.data.schema.MapDataSchema) ByteString(com.linkedin.data.ByteString) DataMap(com.linkedin.data.DataMap) EnumDataSchema(com.linkedin.data.schema.EnumDataSchema) FixedDataSchema(com.linkedin.data.schema.FixedDataSchema) DataSchema(com.linkedin.data.schema.DataSchema) RecordDataSchema(com.linkedin.data.schema.RecordDataSchema) UnionDataSchema(com.linkedin.data.schema.UnionDataSchema) MapDataSchema(com.linkedin.data.schema.MapDataSchema) ArrayDataSchema(com.linkedin.data.schema.ArrayDataSchema) DataList(com.linkedin.data.DataList) ArrayDataSchema(com.linkedin.data.schema.ArrayDataSchema) UnionDataSchema(com.linkedin.data.schema.UnionDataSchema) EnumDataSchema(com.linkedin.data.schema.EnumDataSchema) FixedDataSchema(com.linkedin.data.schema.FixedDataSchema) RecordDataSchema(com.linkedin.data.schema.RecordDataSchema) DataMap(com.linkedin.data.DataMap) Map(java.util.Map)

Example 4 with DataList

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

the class Patch method executeReorderCommand.

private void executeReorderCommand(Object reorderCommand, DataList dataList, Map<String, String> usedFields, InterpreterContext instrCtx) {
    if (reorderCommand != null) {
        assert reorderCommand.getClass() == DataList.class : reorderCommand.getClass();
        DataList reorders = (DataList) reorderCommand;
        if (reorders.size() > 1) {
            instrCtx.addErrorMessage("Reordering more than one array item is not supported.");
            return;
        }
        if (reorders.size() == 1) {
            assert reorders.get(0).getClass() == DataMap.class;
            DataMap reorder = (DataMap) reorders.get(0);
            int fromIndex = reorder.getInteger(FROM_INDEX);
            int toIndex = reorder.getInteger(TO_INDEX);
            int size = dataList.size();
            if (fromIndex < 0 || toIndex < 0 || fromIndex >= size || toIndex >= size) {
                instrCtx.addErrorMessage("$fromIndex %1$d and $toIndex %2$d must be between 0 and %3$d.", fromIndex, toIndex, size);
                return;
            }
            if (fromIndex != toIndex) {
                int direction = Integer.signum(toIndex - fromIndex);
                Object fromObject = dataList.get(fromIndex);
                int i = fromIndex;
                while (i != toIndex) {
                    // Shift the items between fromIndex and toIndex by one place.
                    CheckedUtil.setWithoutChecking(dataList, i, dataList.get(i + direction));
                    i += direction;
                }
                CheckedUtil.setWithoutChecking(dataList, toIndex, fromObject);
            }
        }
    }
}
Also used : DataList(com.linkedin.data.DataList) DataMap(com.linkedin.data.DataMap)

Example 5 with DataList

use of com.linkedin.data.DataList 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;
    // _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<>();
    DataMap opNode = (DataMap) instruction.getOperation();
    DataComplex dataComplex = instruction.getData();
    if (dataComplex.getClass() == DataMap.class) {
        DataMap dataNode = (DataMap) dataComplex;
        /**
         * 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);
        }
    } else if (dataComplex.getClass() == DataList.class) {
        DataList dataNode = (DataList) dataComplex;
        executeReorderCommand(opNode.get(REORDER_COMMAND), dataNode, usedFields, instrCtx);
    } else {
        instrCtx.addErrorMessage("Unexpected data type %1$s at %2$s.", dataComplex.getClass(), instrCtx.getPath());
    }
}
Also used : DataComplex(com.linkedin.data.DataComplex) DataList(com.linkedin.data.DataList) IdentityHashMap(java.util.IdentityHashMap) HashMap(java.util.HashMap) Instruction(com.linkedin.data.transform.Instruction) DataMap(com.linkedin.data.DataMap)

Aggregations

DataList (com.linkedin.data.DataList)202 DataMap (com.linkedin.data.DataMap)151 Test (org.testng.annotations.Test)109 ByteString (com.linkedin.data.ByteString)72 TestUtil.dataMapFromString (com.linkedin.data.TestUtil.dataMapFromString)34 TestUtil.dataSchemaFromString (com.linkedin.data.TestUtil.dataSchemaFromString)33 ArrayList (java.util.ArrayList)27 ArrayDataSchema (com.linkedin.data.schema.ArrayDataSchema)22 RecordDataSchema (com.linkedin.data.schema.RecordDataSchema)15 DataSchema (com.linkedin.data.schema.DataSchema)14 RecordTemplate (com.linkedin.data.template.RecordTemplate)14 HashMap (java.util.HashMap)13 MapDataSchema (com.linkedin.data.schema.MapDataSchema)12 TestUtil.asReadOnlyDataMap (com.linkedin.data.TestUtil.asReadOnlyDataMap)11 Map (java.util.Map)11 List (java.util.List)10 DataProvider (org.testng.annotations.DataProvider)10 DataComplex (com.linkedin.data.DataComplex)9 EnumDataSchema (com.linkedin.data.schema.EnumDataSchema)5 UnionDataSchema (com.linkedin.data.schema.UnionDataSchema)5