Search in sources :

Example 26 with DataMap

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

the class PdlSchemaParser method addPropertiesAtPath.

/**
   * Adds additional properties to an existing properties map at the location identified by
   * the given path.
   *
   * This allows for properties defined with paths such as:
   *
   * {@literal @}a.b = "x"
   * {@literal @}a.c = "y"
   *
   * to be merged together into a property map like:
   *
   * { "a": { "b": "x", "c": "y" }}
   *
   * Examples:
   *
   * <pre>
   * existing properties        | path  | value         | result
   * ---------------------------|-------|---------------|----------------------------------------
   * {}                         | a.b.c | true          | { "a": { "b": { "c": true } } }
   * { "a": {} }                | a.b   | true          | { "a": { "b": true } }
   * { "a": {} }                | a.b   | { "z": "x" }  | { "a": { "b": { "z": "x" } } }
   * { "a": { "c": "x"}} }      | a.b   | true          | { "a": { "b": true, "c": "x"} } }
   * { "a": { "b": "x"}} }      | a.b   | "y"           | ParseError "Conflicting property: a.b"
   * </pre>
   *
   * The existing properties are traversed using the given path, adding DataMaps as needed to
   * complete the traversal. If any of data elements in the existing properties along the path are
   * not DataMaps, a ParseError is thrown to report the conflict.
   *
   * @param context provides the parsing context for error reporting purposes.
   * @param existingProperties provides the properties to add to.
   * @param path provides the path of the property to insert.
   * @param value provides the value of the property to insert.
   * @throws ParseException if the path of the properties to add conflicts with data already
   * in the properties map or if a property is already exists at the path.
   */
private void addPropertiesAtPath(ParserRuleContext context, Map<String, Object> existingProperties, Iterable<String> path, Object value) throws ParseException {
    Map<String, Object> current = existingProperties;
    Iterator<String> iter = path.iterator();
    while (iter.hasNext()) {
        String pathPart = iter.next();
        if (iter.hasNext()) {
            if (existingProperties.containsKey(pathPart)) {
                Object val = existingProperties.get(pathPart);
                if (!(val instanceof DataMap)) {
                    throw new ParseException(new ParseError(new ParseErrorLocation(context), "Conflicting property: " + path.toString()));
                }
                current = (DataMap) val;
            } else {
                DataMap next = new DataMap();
                current.put(pathPart, next);
                current = next;
            }
        } else {
            if (current.containsKey(pathPart)) {
                throw new ParseException(new ParseError(new ParseErrorLocation(context), "Property already defined: " + path.toString()));
            } else {
                current.put(pathPart, value);
            }
        }
    }
}
Also used : DataMap(com.linkedin.data.DataMap)

Example 27 with DataMap

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

the class PdlSchemaParser method parseEnum.

private EnumDataSchema parseEnum(NamedTypeDeclarationContext context, EnumDeclarationContext enumDecl) throws ParseException {
    Name name = toName(enumDecl.name);
    EnumDataSchema schema = new EnumDataSchema(name);
    bindNameToSchema(name, schema);
    List<EnumSymbolDeclarationContext> symbolDecls = enumDecl.enumDecl.symbolDecls;
    List<String> symbols = new ArrayList<>(symbolDecls.size());
    Map<String, Object> props = setProperties(context, schema);
    Map<String, Object> symbolDocs = new HashMap<>();
    DataMap deprecatedSymbols = new DataMap();
    DataMap symbolProperties = new DataMap();
    for (EnumSymbolDeclarationContext symbolDecl : symbolDecls) {
        symbols.add(symbolDecl.symbol.value);
        if (symbolDecl.doc != null) {
            symbolDocs.put(symbolDecl.symbol.value, symbolDecl.doc.value);
        }
        for (PropDeclarationContext prop : symbolDecl.props) {
            String symbol = symbolDecl.symbol.value;
            Object value = parsePropValue(prop);
            if (prop.name.equals("deprecated")) {
                deprecatedSymbols.put(symbol, value);
            } else {
                List<String> path = new ArrayList<>(prop.path);
                path.add(0, symbol);
                addPropertiesAtPath(prop, symbolProperties, path, value);
            }
        }
    }
    schema.setSymbols(symbols, errorMessageBuilder());
    if (symbolDocs.size() > 0) {
        schema.setSymbolDocs(symbolDocs, errorMessageBuilder());
    }
    if (deprecatedSymbols.size() > 0) {
        props.put("deprecatedSymbols", deprecatedSymbols);
    }
    if (symbolProperties.size() > 0) {
        props.put("symbolProperties", symbolProperties);
    }
    schema.setProperties(props);
    return schema;
}
Also used : EnumSymbolDeclarationContext(com.linkedin.data.grammar.PdlParser.EnumSymbolDeclarationContext) EnumDataSchema(com.linkedin.data.schema.EnumDataSchema) PropDeclarationContext(com.linkedin.data.grammar.PdlParser.PropDeclarationContext) HashMap(java.util.HashMap) ArrayList(java.util.ArrayList) Name(com.linkedin.data.schema.Name) DataMap(com.linkedin.data.DataMap)

Example 28 with DataMap

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

the class AbstractDataElement method getChild.

@Override
public Object getChild(Object childName) {
    Object value = getValue();
    Class<?> valueClass = value.getClass();
    if (valueClass == DataList.class && childName.getClass() == Integer.class) {
        int index = ((Integer) childName);
        DataList list = (DataList) value;
        if (index >= 0 && index < list.size()) {
            return list.get(index);
        }
    } else if (valueClass == DataMap.class && childName.getClass() == String.class) {
        String name = ((String) childName);
        DataMap map = (DataMap) value;
        return map.get(name);
    }
    return null;
}
Also used : DataList(com.linkedin.data.DataList) DataMap(com.linkedin.data.DataMap)

Example 29 with DataMap

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

the class SchemaSampleDataGenerator method buildRecordData.

private static DataMap buildRecordData(ParentSchemas parentSchemas, NamedDataSchema schema, DataGenerationOptions spec) {
    spec = preventRecursionIntoAlreadyTraversedSchemas(parentSchemas, spec, schema);
    parentSchemas.incrementReferences(schema);
    final DataMap data = new DataMap();
    if (schema instanceof RecordDataSchema) {
        for (RecordDataSchema.Field field : ((RecordDataSchema) schema).getFields()) {
            if (!(spec.isRequiredFieldsOnly() && field.getOptional())) {
                final Object value;
                if (spec.isUseDefaults() && field.getDefault() != null) {
                    value = field.getDefault();
                } else {
                    value = buildData(parentSchemas, field.getType(), field.getName(), spec);
                }
                // null is returned for NULL Pegasus type (used in unions, primarily)
                if (value == null) {
                    data.remove(field.getName());
                } else {
                    data.put(field.getName(), value);
                }
            }
        }
    } else if (schema instanceof TyperefDataSchema) {
        data.put("ref", buildData(parentSchemas, schema.getDereferencedDataSchema(), spec));
    } else {
        data.put("value", buildData(parentSchemas, schema, spec));
    }
    parentSchemas.decrementReferences(schema);
    return data;
}
Also used : TyperefDataSchema(com.linkedin.data.schema.TyperefDataSchema) RecordDataSchema(com.linkedin.data.schema.RecordDataSchema) DataMap(com.linkedin.data.DataMap)

Example 30 with DataMap

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

the class DynamicRecordTemplate method putArray.

/**
   * Puts an array field value by doing the necessary unwrapping at the items level.
   * @param field specifies the field to put the value for.
   * @param fieldDef specifies the field definition to put the value for.
   * @param value provides the value to put for the specified field.
   * @param <T> provides the type of the value.
   */
@SuppressWarnings({ "unchecked" })
private <T> void putArray(RecordDataSchema.Field field, FieldDef<T> fieldDef, T value) {
    DataList data = new DataList();
    Class<?> itemType = null;
    ArrayDataSchema arrayDataSchema = null;
    if (fieldDef.getDataSchema() instanceof ArrayDataSchema) {
        arrayDataSchema = (ArrayDataSchema) fieldDef.getDataSchema();
        DataSchema itemSchema = arrayDataSchema.getItems();
        if (itemSchema instanceof TyperefDataSchema) {
            itemType = DataSchemaUtil.dataSchemaTypeToPrimitiveDataSchemaClass(itemSchema.getDereferencedType());
        } else {
            itemType = fieldDef.getType().getComponentType();
        }
    } else {
        throw new IllegalArgumentException("Field " + fieldDef.getName() + " does not have an array schema; although the data is an array.");
    }
    boolean isDataTemplate = DataTemplate.class.isAssignableFrom(itemType);
    List<Object> items;
    if (value instanceof DataList) {
        items = (List<Object>) value;
    } else {
        items = Arrays.asList((Object[]) value);
    }
    for (Object item : items) {
        if (isDataTemplate) {
            Object itemData;
            if (item instanceof DataMap) {
                itemData = item;
            } else {
                itemData = ((DataTemplate) item).data();
            }
            data.add(itemData);
        } else {
            data.add(DataTemplateUtil.coerceInput(item, (Class<Object>) item.getClass(), itemType.isEnum() ? String.class : itemType));
        }
    }
    putDirect(field, DataList.class, data, SetMode.DISALLOW_NULL);
}
Also used : RecordDataSchema(com.linkedin.data.schema.RecordDataSchema) DataSchema(com.linkedin.data.schema.DataSchema) ArrayDataSchema(com.linkedin.data.schema.ArrayDataSchema) TyperefDataSchema(com.linkedin.data.schema.TyperefDataSchema) DataList(com.linkedin.data.DataList) ArrayDataSchema(com.linkedin.data.schema.ArrayDataSchema) TyperefDataSchema(com.linkedin.data.schema.TyperefDataSchema) 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