Search in sources :

Example 1 with DataTemplate

use of com.linkedin.data.template.DataTemplate in project rest.li by linkedin.

the class TestUnionWithAliases method buildUnionData.

private <T> DataMap buildUnionData(String memberAlias, Object memberValue) {
    String key = memberAlias;
    Object value = null;
    if (memberValue instanceof DataTemplate) {
        DataTemplate<?> dataTemplate = (DataTemplate<?>) memberValue;
        value = dataTemplate.data();
    } else if (memberValue instanceof Enum) {
        value = memberValue.toString();
    } else {
        value = memberValue;
    }
    DataMap dataMap = new DataMap();
    dataMap.put(key, value);
    return dataMap;
}
Also used : DataTemplate(com.linkedin.data.template.DataTemplate) ByteString(com.linkedin.data.ByteString) DataMap(com.linkedin.data.DataMap)

Example 2 with DataTemplate

use of com.linkedin.data.template.DataTemplate in project rest.li by linkedin.

the class ArgumentBuilder method buildArrayArgument.

/**
 * Build a method argument from a request parameter that is an array
 *
 * @param context {@link ResourceContext}
 * @param param {@link Parameter}
 * @return argument value in the correct type
 */
private static Object buildArrayArgument(final ResourceContext context, final Parameter<?> param, boolean validateParam) {
    final Object convertedValue;
    if (DataTemplate.class.isAssignableFrom(param.getItemType())) {
        final DataList itemsList = (DataList) context.getStructuredParameter(param.getName());
        convertedValue = Array.newInstance(param.getItemType(), itemsList.size());
        int j = 0;
        for (Object paramData : itemsList) {
            final DataTemplate<?> itemsElem = DataTemplateUtil.wrap(paramData, param.getItemType().asSubclass(DataTemplate.class));
            ArgumentUtils.validateDataAgainstSchema(itemsElem.data(), itemsElem.schema(), validateParam);
            Array.set(convertedValue, j++, itemsElem);
        }
    } else {
        final List<String> itemStringValues = context.getParameterValues(param.getName());
        ArrayDataSchema parameterSchema;
        if (param.getDataSchema() instanceof ArrayDataSchema) {
            parameterSchema = (ArrayDataSchema) param.getDataSchema();
        } else {
            throw new RoutingException("An array schema is expected.", HttpStatus.S_400_BAD_REQUEST.getCode());
        }
        convertedValue = Array.newInstance(param.getItemType(), itemStringValues.size());
        int j = 0;
        for (String itemStringValue : itemStringValues) {
            if (itemStringValue == null) {
                throw new RoutingException("Parameter '" + param.getName() + "' cannot contain null values", HttpStatus.S_400_BAD_REQUEST.getCode());
            }
            try {
                Array.set(convertedValue, j++, ArgumentUtils.convertSimpleValue(itemStringValue, parameterSchema.getItems(), param.getItemType(), false));
            } catch (NumberFormatException e) {
                Class<?> targetClass = DataSchemaUtil.dataSchemaTypeToPrimitiveDataSchemaClass(parameterSchema.getItems().getDereferencedType());
                // thrown from Integer.valueOf or Long.valueOf
                throw new RoutingException(String.format("Array parameter '%s' value '%s' must be of type '%s'", param.getName(), itemStringValue, targetClass.getName()), HttpStatus.S_400_BAD_REQUEST.getCode());
            } catch (IllegalArgumentException e) {
                // thrown from Enum.valueOf
                throw new RoutingException(String.format("Array parameter '%s' value '%s' is invalid", param.getName(), itemStringValue), HttpStatus.S_400_BAD_REQUEST.getCode());
            } catch (TemplateRuntimeException e) {
                // thrown from DataTemplateUtil.coerceOutput
                throw new RoutingException(String.format("Array parameter '%s' value '%s' is invalid. Reason: %s", param.getName(), itemStringValue, e.getMessage()), HttpStatus.S_400_BAD_REQUEST.getCode());
            }
        }
    }
    return convertedValue;
}
Also used : RoutingException(com.linkedin.restli.server.RoutingException) DataTemplate(com.linkedin.data.template.DataTemplate) ByteString(com.linkedin.data.ByteString) DataList(com.linkedin.data.DataList) ArrayDataSchema(com.linkedin.data.schema.ArrayDataSchema) TemplateRuntimeException(com.linkedin.data.template.TemplateRuntimeException)

Example 3 with DataTemplate

use of com.linkedin.data.template.DataTemplate in project rest.li by linkedin.

the class Parameter method getDefaultValue.

public Object getDefaultValue() {
    if (_defaultValueData == null) {
        return null;
    }
    final Object result;
    if (_defaultValueData instanceof String) {
        final String defaultValueString = (String) _defaultValueData;
        try {
            if (getType().isArray()) {
                DataList valueAsDataList = _codec.stringToList(defaultValueString);
                DataSchema itemSchema = ((ArrayDataSchema) getDataSchema()).getItems();
                // Handle custom type arrays. Only single level arrays are supported.
                if (CustomTypeUtil.getJavaCustomTypeClassNameFromSchema(itemSchema) != null) {
                    // First coerce the default value to the de-referenced type.
                    valueAsDataList = new DataList(valueAsDataList.stream().map(val -> DataTemplateUtil.coerceOutput(val, getDataClassFromSchema(itemSchema))).collect(Collectors.toList()));
                }
                result = DataTemplateUtil.convertDataListToArray(valueAsDataList, getItemType());
            } else if (DataTemplate.class.isAssignableFrom(getType())) {
                final Object input;
                if (AbstractArrayTemplate.class.isAssignableFrom(getType())) {
                    input = _codec.stringToList(defaultValueString);
                } else if (AbstractMapTemplate.class.isAssignableFrom(getType()) || UnionTemplate.class.isAssignableFrom(getType()) || RecordTemplate.class.isAssignableFrom(getType())) {
                    input = _codec.stringToMap(defaultValueString);
                } else {
                    input = defaultValueString;
                }
                result = DataTemplateUtil.wrap(input, getType().asSubclass(DataTemplate.class));
                validate((DataTemplate<?>) result, getType());
            } else if (CustomTypeUtil.getJavaCustomTypeClassNameFromSchema(getDataSchema()) != null) {
                // First convert the default value from string to the de-referenced type.
                Object deReferencedResult = ValueConverter.coerceString(defaultValueString, getDataClass());
                // Use the coercer to get the custom type.
                result = DataTemplateUtil.coerceOutput(deReferencedResult, getType());
            } else {
                result = ValueConverter.coerceString(defaultValueString, getType());
            }
        } catch (TemplateOutputCastException e) {
            throw new ResourceConfigException(e.getMessage(), e);
        } catch (IllegalArgumentException e) {
            throw new ResourceConfigException("Default value for parameter of type \"" + getType().getName() + "\" is not supported: " + e.getMessage(), e);
        } catch (IOException e) {
            throw new ResourceConfigException("Default value for parameter of type \"" + getType().getName() + "\" is not supported: " + e.getMessage(), e);
        }
    } else {
        result = _defaultValueData;
    }
    return result;
}
Also used : RecordTemplate(com.linkedin.data.template.RecordTemplate) DataSchemaUtil.getDataClassFromSchema(com.linkedin.data.schema.DataSchemaUtil.getDataClassFromSchema) UnionTemplate(com.linkedin.data.template.UnionTemplate) AbstractMapTemplate(com.linkedin.data.template.AbstractMapTemplate) FieldDef(com.linkedin.data.template.FieldDef) DataTemplate(com.linkedin.data.template.DataTemplate) DataList(com.linkedin.data.DataList) DataSchema(com.linkedin.data.schema.DataSchema) IOException(java.io.IOException) CustomTypeUtil(com.linkedin.util.CustomTypeUtil) Collectors(java.util.stream.Collectors) ActionParam(com.linkedin.restli.server.annotations.ActionParam) ValidationOptions(com.linkedin.data.schema.validation.ValidationOptions) DataMap(com.linkedin.data.DataMap) AbstractArrayTemplate(com.linkedin.data.template.AbstractArrayTemplate) DataTemplateUtil(com.linkedin.data.template.DataTemplateUtil) ResourceConfigException(com.linkedin.restli.server.ResourceConfigException) TemplateOutputCastException(com.linkedin.data.template.TemplateOutputCastException) QueryParam(com.linkedin.restli.server.annotations.QueryParam) ArrayDataSchema(com.linkedin.data.schema.ArrayDataSchema) JacksonDataCodec(com.linkedin.data.codec.JacksonDataCodec) ValidateDataAgainstSchema(com.linkedin.data.schema.validation.ValidateDataAgainstSchema) ValidationResult(com.linkedin.data.schema.validation.ValidationResult) ValueConverter(com.linkedin.restli.internal.common.ValueConverter) DataTemplate(com.linkedin.data.template.DataTemplate) IOException(java.io.IOException) DataSchema(com.linkedin.data.schema.DataSchema) ArrayDataSchema(com.linkedin.data.schema.ArrayDataSchema) DataList(com.linkedin.data.DataList) ArrayDataSchema(com.linkedin.data.schema.ArrayDataSchema) RecordTemplate(com.linkedin.data.template.RecordTemplate) AbstractArrayTemplate(com.linkedin.data.template.AbstractArrayTemplate) TemplateOutputCastException(com.linkedin.data.template.TemplateOutputCastException) ResourceConfigException(com.linkedin.restli.server.ResourceConfigException)

Example 4 with DataTemplate

use of com.linkedin.data.template.DataTemplate in project rest.li by linkedin.

the class ArgumentBuilder method buildArrayArgument.

/**
   * Build a method argument from a request parameter that is an array
   *
   * @param context {@link ResourceContext}
   * @param param {@link Parameter}
   * @return argument value in the correct type
   */
private static Object buildArrayArgument(final ResourceContext context, final Parameter<?> param) {
    final Object convertedValue;
    if (DataTemplate.class.isAssignableFrom(param.getItemType())) {
        final DataList itemsList = (DataList) context.getStructuredParameter(param.getName());
        convertedValue = Array.newInstance(param.getItemType(), itemsList.size());
        int j = 0;
        for (Object paramData : itemsList) {
            final DataTemplate<?> itemsElem = DataTemplateUtil.wrap(paramData, param.getItemType().asSubclass(DataTemplate.class));
            ValidateDataAgainstSchema.validate(itemsElem.data(), itemsElem.schema(), new ValidationOptions(RequiredMode.CAN_BE_ABSENT_IF_HAS_DEFAULT, CoercionMode.STRING_TO_PRIMITIVE));
            Array.set(convertedValue, j++, itemsElem);
        }
    } else {
        final List<String> itemStringValues = context.getParameterValues(param.getName());
        ArrayDataSchema parameterSchema = null;
        if (param.getDataSchema() instanceof ArrayDataSchema) {
            parameterSchema = (ArrayDataSchema) param.getDataSchema();
        } else {
            throw new RoutingException("An array schema is expected.", HttpStatus.S_400_BAD_REQUEST.getCode());
        }
        convertedValue = Array.newInstance(param.getItemType(), itemStringValues.size());
        int j = 0;
        for (String itemStringValue : itemStringValues) {
            if (itemStringValue == null) {
                throw new RoutingException("Parameter '" + param.getName() + "' cannot contain null values", HttpStatus.S_400_BAD_REQUEST.getCode());
            }
            try {
                Array.set(convertedValue, j++, ArgumentUtils.convertSimpleValue(itemStringValue, parameterSchema.getItems(), param.getItemType()));
            } catch (NumberFormatException e) {
                Class<?> targetClass = DataSchemaUtil.dataSchemaTypeToPrimitiveDataSchemaClass(parameterSchema.getItems().getDereferencedType());
                // thrown from Integer.valueOf or Long.valueOf
                throw new RoutingException(String.format("Array parameter '%s' value '%s' must be of type '%s'", param.getName(), itemStringValue, targetClass.getName()), HttpStatus.S_400_BAD_REQUEST.getCode());
            } catch (IllegalArgumentException e) {
                // thrown from Enum.valueOf
                throw new RoutingException(String.format("Array parameter '%s' value '%s' is invalid", param.getName(), itemStringValue), HttpStatus.S_400_BAD_REQUEST.getCode());
            } catch (TemplateRuntimeException e) {
                // thrown from DataTemplateUtil.coerceOutput
                throw new RoutingException(String.format("Array parameter '%s' value '%s' is invalid. Reason: %s", param.getName(), itemStringValue, e.getMessage()), HttpStatus.S_400_BAD_REQUEST.getCode());
            }
        }
    }
    return convertedValue;
}
Also used : RoutingException(com.linkedin.restli.server.RoutingException) DataTemplate(com.linkedin.data.template.DataTemplate) ValidationOptions(com.linkedin.data.schema.validation.ValidationOptions) DataList(com.linkedin.data.DataList) ArrayDataSchema(com.linkedin.data.schema.ArrayDataSchema) TemplateRuntimeException(com.linkedin.data.template.TemplateRuntimeException)

Example 5 with DataTemplate

use of com.linkedin.data.template.DataTemplate in project rest.li by linkedin.

the class ClassNameDataSchemaResolver method locateDataSchema.

@Override
protected NamedDataSchema locateDataSchema(String className, StringBuilder errorMessageBuilder) {
    final DataSchemaLocation location = new ClassNameDataSchemaLocation(className);
    if (isBadLocation(location)) {
        return null;
    }
    final Class<?> clazz;
    try {
        clazz = _classLoader.loadClass(className);
    } catch (ClassNotFoundException e) {
        addBadLocation(location);
        errorMessageBuilder.append(String.format("Unable to locate DataSchema: class \"%s\" not found", className));
        return null;
    }
    final DataSchema schema = DataTemplateUtil.getSchema(clazz);
    if (schema instanceof NamedDataSchema) {
        return (NamedDataSchema) schema;
    }
    if (DataTemplate.class.isAssignableFrom(clazz)) {
        @SuppressWarnings("unchecked") final Class<? extends DataTemplate<?>> clazzWithTyperef = (Class<? extends DataTemplate<?>>) clazz;
        final TyperefInfo typerefInfo = DataTemplateUtil.getTyperefInfo(clazzWithTyperef);
        if (typerefInfo != null) {
            return typerefInfo.getSchema();
        }
    }
    addBadLocation(location);
    errorMessageBuilder.append(String.format("Unable to locate DataSchema: class \"%s\" is not a NamedDataSchema", className));
    return null;
}
Also used : DataSchema(com.linkedin.data.schema.DataSchema) NamedDataSchema(com.linkedin.data.schema.NamedDataSchema) NamedDataSchema(com.linkedin.data.schema.NamedDataSchema) DataTemplate(com.linkedin.data.template.DataTemplate) DataSchemaLocation(com.linkedin.data.schema.DataSchemaLocation) TyperefInfo(com.linkedin.data.template.TyperefInfo)

Aggregations

DataTemplate (com.linkedin.data.template.DataTemplate)8 ByteString (com.linkedin.data.ByteString)5 DataMap (com.linkedin.data.DataMap)5 DataList (com.linkedin.data.DataList)4 ArrayDataSchema (com.linkedin.data.schema.ArrayDataSchema)3 DataSchema (com.linkedin.data.schema.DataSchema)2 ValidationOptions (com.linkedin.data.schema.validation.ValidationOptions)2 RecordTemplate (com.linkedin.data.template.RecordTemplate)2 TemplateRuntimeException (com.linkedin.data.template.TemplateRuntimeException)2 RoutingException (com.linkedin.restli.server.RoutingException)2 InvocationTargetException (java.lang.reflect.InvocationTargetException)2 Method (java.lang.reflect.Method)2 JacksonDataCodec (com.linkedin.data.codec.JacksonDataCodec)1 DataSchemaLocation (com.linkedin.data.schema.DataSchemaLocation)1 DataSchemaUtil.getDataClassFromSchema (com.linkedin.data.schema.DataSchemaUtil.getDataClassFromSchema)1 NamedDataSchema (com.linkedin.data.schema.NamedDataSchema)1 PathSpec (com.linkedin.data.schema.PathSpec)1 ValidateDataAgainstSchema (com.linkedin.data.schema.validation.ValidateDataAgainstSchema)1 ValidationResult (com.linkedin.data.schema.validation.ValidationResult)1 AbstractArrayTemplate (com.linkedin.data.template.AbstractArrayTemplate)1