use of com.linkedin.data.schema.TyperefDataSchema in project rest.li by linkedin.
the class CopySchemaUtil method buildSkeletonSchema.
/**
* Create a skeleton schema from the given schema
* For example, if the given schema is a {@link RecordDataSchema}, the skeletonSchema will be an empty {@link RecordDataSchema} with no fields,
* but with its doc, alias and properties copied.
*
* @param schema input schema to be copied
* @return
* @throws CloneNotSupportedException
*/
public static DataSchema buildSkeletonSchema(DataSchema schema) throws CloneNotSupportedException {
switch(schema.getType()) {
case RECORD:
RecordDataSchema newRecordSchema = new RecordDataSchema(new Name(((RecordDataSchema) schema).getFullName()), RecordDataSchema.RecordType.RECORD);
RecordDataSchema originalRecordSchema = (RecordDataSchema) schema;
if (originalRecordSchema.getAliases() != null) {
newRecordSchema.setAliases(originalRecordSchema.getAliases());
}
if (originalRecordSchema.getDoc() != null) {
newRecordSchema.setDoc(originalRecordSchema.getDoc());
}
if (originalRecordSchema.getProperties() != null) {
newRecordSchema.setProperties(originalRecordSchema.getProperties());
}
return newRecordSchema;
case UNION:
UnionDataSchema newUnionDataSchema = new UnionDataSchema();
UnionDataSchema unionDataSchema = (UnionDataSchema) schema;
if (unionDataSchema.getProperties() != null) {
newUnionDataSchema.setProperties(unionDataSchema.getProperties());
}
return newUnionDataSchema;
case TYPEREF:
TyperefDataSchema originalTypeRefSchema = (TyperefDataSchema) schema;
TyperefDataSchema newTypeRefSchema = new TyperefDataSchema(new Name(originalTypeRefSchema.getFullName()));
if (originalTypeRefSchema.getProperties() != null) {
newTypeRefSchema.setProperties(originalTypeRefSchema.getProperties());
}
if (originalTypeRefSchema.getDoc() != null) {
newTypeRefSchema.setDoc(originalTypeRefSchema.getDoc());
}
if (originalTypeRefSchema.getAliases() != null) {
newTypeRefSchema.setAliases(originalTypeRefSchema.getAliases());
}
return newTypeRefSchema;
case ARRAY:
ArrayDataSchema originalArrayDataSchema = (ArrayDataSchema) schema;
// Set null item types for this skeleton
ArrayDataSchema newArrayDataSchema = new ArrayDataSchema(DataSchemaConstants.NULL_DATA_SCHEMA);
if (originalArrayDataSchema.getProperties() != null) {
newArrayDataSchema.setProperties(originalArrayDataSchema.getProperties());
}
return newArrayDataSchema;
case MAP:
MapDataSchema originalMapDataSchema = (MapDataSchema) schema;
// Set null value types for this skeleton
MapDataSchema newMapDataSchema = new MapDataSchema(DataSchemaConstants.NULL_DATA_SCHEMA);
if (originalMapDataSchema.getProperties() != null) {
newMapDataSchema.setProperties(originalMapDataSchema.getProperties());
}
return newMapDataSchema;
case FIXED:
case ENUM:
default:
// Primitive types, FIXED, ENUM: using schema's clone method
return schema.clone();
}
}
use of com.linkedin.data.schema.TyperefDataSchema in project rest.li by linkedin.
the class TestPdlSchemaParser method testTyperefParserLocations.
@Test
public void testTyperefParserLocations() {
PdlSchemaParser parser = new PdlSchemaParser(new DefaultDataSchemaResolver(), true);
parser.parse(getClass().getResourceAsStream("TestTyperefForParserContextLocations.pdl"));
List<DataSchema> topLevelSchemas = parser.topLevelDataSchemas();
Assert.assertEquals(topLevelSchemas.size(), 1, "Expected 1 top-level schema to be parsed.");
TyperefDataSchema topSchema = (TyperefDataSchema) topLevelSchemas.get(0);
Map<Object, PdlSchemaParser.ParseLocation> locations = parser.getParseLocations();
checkParseLocationForTyperef(locations, topSchema);
}
use of com.linkedin.data.schema.TyperefDataSchema in project rest.li by linkedin.
the class TestDataElement method testDataElement.
@Test(dataProvider = "dataElementFactories")
public void testDataElement(DataElementFactory factory) throws IOException {
RecordDataSchema fooSchema = (RecordDataSchema) TestUtil.dataSchemaFromString(fooSchemaText);
ArrayDataSchema arraySchema = (ArrayDataSchema) fooSchema.getField("array").getType();
String fooText = " {" + " \"int\" : 34," + " \"string\" : \"abc\"," + " \"array\" : [" + " { \"int\" : 56 }," + " { \"string\" : \"xyz\" }," + " { \"array\" : [" + " { \"int\" : 78 }" + " ] }" + " ]," + " \"enumField\": \"SYMBOL1\"," + " \"unionField\": {" + " \"string\":\"unionString\"" + " }," + " \"mapField\": {" + " \"key1\":\"value1\"," + " \"key2\":\"value2\"" + " }," + " \"typeRefField\": \"42\"," + " \"typeRefFieldToMap\": {" + " \"key1\":\"value1\"," + " \"key2\":\"value2\"" + " }," + " \"unionWithAliasesField\" : {" + " \"stringFieldInUnionWithAliases\" : \"stringInUnionWithAlias\"" + " }" + " }";
DataMap foo = TestUtil.dataMapFromString(fooText);
DataElement root = factory.create(foo, DataElement.ROOT_NAME, fooSchema, null);
DataElement int1 = factory.create(foo.get("int"), "int", fooSchema.getField("int").getType(), root);
DataElement string1 = factory.create(foo.get("string"), "string", fooSchema.getField("string").getType(), root);
DataElement array1 = factory.create(foo.get("array"), "array", fooSchema.getField("array").getType(), root);
MapDataSchema mapDataSchema = (MapDataSchema) fooSchema.getField("mapField").getType();
StringDataSchema stringDataSchema = (StringDataSchema) mapDataSchema.getValues();
DataElement mapFieldElement = factory.create(foo.get("mapField"), "mapField", mapDataSchema, root);
DataElement mapValueInMapField = factory.create(mapFieldElement.getChild("key1"), "key1", stringDataSchema, mapFieldElement);
EnumDataSchema enumDataSchema = (EnumDataSchema) fooSchema.getField("enumField").getType();
DataElement enumField = factory.create(foo.get("enumField"), "enumField", enumDataSchema, root);
DataElement unionField = factory.create(foo.get("unionField"), "unionField", fooSchema.getField("unionField").getType(), root);
UnionDataSchema unionFieldSchema = (UnionDataSchema) fooSchema.getField("unionField").getType();
DataElement unionFieldString = factory.create(unionField.getChild("string"), "string", unionFieldSchema.getTypeByMemberKey("string"), unionField);
TyperefDataSchema typerefDataSchema = (TyperefDataSchema) fooSchema.getField("typeRefField").getType();
DataElement typeRefField = factory.create(foo.get("typeRefField"), "typeRefField", typerefDataSchema, root);
TyperefDataSchema typeRefToMapDataSchema = (TyperefDataSchema) fooSchema.getField("typeRefFieldToMap").getType();
DataElement typeRefToMapField = factory.create(foo.get("typeRefFieldToMap"), "typeRefFieldToMap", typeRefToMapDataSchema, root);
DataElement mapValueInTypeReffedMapField = factory.create(typeRefToMapField.getChild("key1"), "key1", stringDataSchema, typeRefToMapField);
DataElement unionWithAliasesField = factory.create(foo.get("unionWithAliasesField"), "unionWithAliasesField", fooSchema.getField("unionWithAliasesField").getType(), root);
UnionDataSchema unionWithAliasesSchema = (UnionDataSchema) fooSchema.getField("unionWithAliasesField").getType();
DataElement stringFieldInUnionWithAliases = factory.create(unionWithAliasesField.getChild("stringFieldInUnionWithAliases"), "stringFieldInUnionWithAliases", unionWithAliasesSchema.getTypeByMemberKey("stringFieldInUnionWithAliases"), unionWithAliasesField);
DataElement foo20 = factory.create(array1.getChild(0), 0, arraySchema.getItems(), array1);
DataElement foo21 = factory.create(array1.getChild(1), 1, arraySchema.getItems(), array1);
DataElement foo22 = factory.create(array1.getChild(2), 2, arraySchema.getItems(), array1);
DataElement int20 = factory.create(foo20.getChild("int"), "int", fooSchema.getField("int").getType(), foo20);
DataElement string21 = factory.create(foo21.getChild("string"), "string", fooSchema.getField("string").getType(), foo21);
DataElement array22 = factory.create(foo22.getChild("array"), "array", fooSchema.getField("array").getType(), foo22);
DataElement foo30 = factory.create(array22.getChild(0), 0, arraySchema.getItems(), array22);
DataElement int30 = factory.create(foo30.getChild("int"), "int", fooSchema.getField("int").getType(), foo30);
// test path
Object[][] testPathInput = { { root, foo, fooSchema, new Object[] {}, "" }, { int1, foo.get("int"), DataSchemaConstants.INTEGER_DATA_SCHEMA, new Object[] { "int" }, "/int" }, { string1, foo.get("string"), DataSchemaConstants.STRING_DATA_SCHEMA, new Object[] { "string" }, "/string" }, { array1, foo.get("array"), arraySchema, new Object[] { "array" }, "/array" }, { mapFieldElement, foo.get("mapField"), mapDataSchema, new Object[] { "mapField" }, "/mapField" }, { mapValueInMapField, ((DataMap) foo.get("mapField")).get("key1"), stringDataSchema, new Object[] { "mapField", "key1" }, "/mapField/*" }, { mapValueInTypeReffedMapField, ((DataMap) foo.get("typeRefFieldToMap")).get("key1"), stringDataSchema, new Object[] { "typeRefFieldToMap", "key1" }, "/typeRefFieldToMap/*" }, { enumField, foo.get("enumField"), enumDataSchema, new Object[] { "enumField" }, "/enumField" }, { unionFieldString, ((DataMap) foo.get("unionField")).get("string"), DataSchemaConstants.STRING_DATA_SCHEMA, new Object[] { "unionField", "string" }, "/unionField/string" }, { typeRefField, foo.get("typeRefField"), typerefDataSchema, new Object[] { "typeRefField" }, "/typeRefField" }, { stringFieldInUnionWithAliases, ((DataMap) foo.get("unionWithAliasesField")).get("stringFieldInUnionWithAliases"), DataSchemaConstants.STRING_DATA_SCHEMA, new Object[] { "unionWithAliasesField", "stringFieldInUnionWithAliases" }, "/unionWithAliasesField/stringFieldInUnionWithAliases" }, { foo20, ((DataList) foo.get("array")).get(0), fooSchema, new Object[] { "array", 0 }, "/array/*" }, { foo21, ((DataList) foo.get("array")).get(1), fooSchema, new Object[] { "array", 1 }, "/array/*" }, { foo22, ((DataList) foo.get("array")).get(2), fooSchema, new Object[] { "array", 2 }, "/array/*" }, { int20, ((DataMap) ((DataList) foo.get("array")).get(0)).get("int"), DataSchemaConstants.INTEGER_DATA_SCHEMA, new Object[] { "array", 0, "int" }, "/array/*/int" }, { string21, ((DataMap) ((DataList) foo.get("array")).get(1)).get("string"), DataSchemaConstants.STRING_DATA_SCHEMA, new Object[] { "array", 1, "string" }, "/array/*/string" }, { array22, ((DataMap) ((DataList) foo.get("array")).get(2)).get("array"), arraySchema, new Object[] { "array", 2, "array" }, "/array/*/array" }, { foo30, ((DataList) ((DataMap) ((DataList) foo.get("array")).get(2)).get("array")).get(0), fooSchema, new Object[] { "array", 2, "array", 0 }, "/array/*/array/*" }, { int30, ((DataMap) ((DataList) ((DataMap) ((DataList) foo.get("array")).get(2)).get("array")).get(0)).get("int"), DataSchemaConstants.INTEGER_DATA_SCHEMA, new Object[] { "array", 2, "array", 0, "int" }, "/array/*/array/*/int" } };
ArrayList<Object> pathAsList = new ArrayList<>();
for (Object[] row : testPathInput) {
DataElement element = (DataElement) row[0];
// test value
Object expectedValue = row[1];
assertSame(expectedValue, element.getValue());
// test schema
DataSchema expectedSchema = (DataSchema) row[2];
assertSame(expectedSchema, element.getSchema());
// test name
Object[] expectedPath = (Object[]) row[3];
Object expectedName = expectedPath.length == 0 ? DataElement.ROOT_NAME : expectedPath[expectedPath.length - 1];
assertEquals(expectedName, element.getName());
// test path
Object[] path = element.path();
element.pathAsList(pathAsList);
StringBuilder builder = new StringBuilder();
StringBuilder builder2 = new StringBuilder();
assertEquals(expectedPath.length, path.length);
assertEquals(expectedPath.length, pathAsList.size());
for (int i = 0; i < expectedPath.length; i++) {
assertEquals(path[i], expectedPath[i]);
assertEquals(pathAsList.get(i), expectedPath[i]);
builder.append('*').append(expectedPath[i]);
builder2.append(DataElement.SEPARATOR).append(expectedPath[i]);
}
assertEquals(builder.toString(), element.pathAsString('*'));
assertEquals(builder2.toString(), element.pathAsString());
// test copyChain
DataElement copy = element.copyChain();
assertElementChainEquals(copy, element.copyChain(), null);
// test DataElementUtil.element
DataElement elementFromUtil = DataElementUtil.element(root, path);
assertElementChainEquals(elementFromUtil, element, root);
elementFromUtil = DataElementUtil.element(root, pathAsList);
assertElementChainEquals(elementFromUtil, element, root);
elementFromUtil = DataElementUtil.element(root, element.pathAsString());
assertElementChainEquals(elementFromUtil, element, root);
elementFromUtil = DataElementUtil.element(root, element.pathAsString('*'), '*');
assertElementChainEquals(elementFromUtil, element, root);
elementFromUtil = DataElementUtil.element(root.getValue(), root.getSchema(), path);
assertElementChainEquals(elementFromUtil, element, root);
elementFromUtil = DataElementUtil.element(root.getValue(), root.getSchema(), pathAsList);
assertElementChainEquals(elementFromUtil, element, root);
elementFromUtil = DataElementUtil.element(root.getValue(), root.getSchema(), element.pathAsString());
assertElementChainEquals(elementFromUtil, element, root);
elementFromUtil = DataElementUtil.element(root.getValue(), root.getSchema(), element.pathAsString('*'), '*');
assertElementChainEquals(elementFromUtil, element, root);
// test pathSpec
String pathSpecString = (String) row[4];
assertEquals(element.getSchemaPathSpec().toString(), pathSpecString);
}
}
use of com.linkedin.data.schema.TyperefDataSchema in project rest.li by linkedin.
the class TemplateSpecGenerator method processSchema.
private ClassTemplateSpec processSchema(DataSchema schema, ClassTemplateSpec enclosingClass, String memberName) {
final CustomInfoSpec customInfo = getImmediateCustomInfo(schema);
ClassTemplateSpec result = null;
TyperefDataSchema originalTyperefSchema = null;
while (schema.getType() == DataSchema.Type.TYPEREF) {
final TyperefDataSchema typerefSchema = (TyperefDataSchema) schema;
if (originalTyperefSchema == null) {
originalTyperefSchema = typerefSchema;
}
final ClassTemplateSpec found = _schemaToClassMap.get(schema);
schema = typerefSchema.getRef();
if (schema.getType() == DataSchema.Type.UNION) {
result = (found != null) ? found : generateUnion((UnionDataSchema) schema, typerefSchema);
break;
} else if (found == null) {
generateTyperef(typerefSchema, originalTyperefSchema);
}
}
if (result == null) {
assert schema == schema.getDereferencedDataSchema();
if (schema instanceof ComplexDataSchema) {
final ClassTemplateSpec found = _schemaToClassMap.get(schema);
if (found == null) {
if (schema instanceof NamedDataSchema) {
result = generateNamedSchema((NamedDataSchema) schema);
} else {
result = generateUnnamedComplexSchema(schema, enclosingClass, memberName);
}
} else {
result = found;
}
if (customInfo != null) {
result = customInfo.getCustomClass();
}
} else if (schema instanceof PrimitiveDataSchema) {
result = (customInfo != null) ? customInfo.getCustomClass() : getPrimitiveClassForSchema((PrimitiveDataSchema) schema, enclosingClass, memberName);
}
}
if (result == null) {
throw unrecognizedSchemaType(enclosingClass, memberName, schema);
}
result.setOriginalTyperefSchema(originalTyperefSchema);
return result;
}
use of com.linkedin.data.schema.TyperefDataSchema in project rest.li by linkedin.
the class TemplateSpecGenerator method classNameForUnnamedTraverse.
private ClassInfo classNameForUnnamedTraverse(ClassTemplateSpec enclosingClass, String memberName, DataSchema schema) {
final DataSchema dereferencedDataSchema = schema.getDereferencedDataSchema();
switch(dereferencedDataSchema.getType()) {
case ARRAY:
final ArrayDataSchema arraySchema = (ArrayDataSchema) dereferencedDataSchema;
CustomInfoSpec customInfo = getImmediateCustomInfo(arraySchema.getItems());
if (customInfo != null) {
return new ClassInfo(customInfo.getCustomSchema().getNamespace(), customInfo.getCustomSchema().getName() + ARRAY_SUFFIX, customInfo.getCustomSchema().getPackage());
} else {
final ClassInfo classInfo = classNameForUnnamedTraverse(enclosingClass, memberName, arraySchema.getItems());
// Add just the "Array" suffix first. This is to ensure backwards compatibility with the old codegen logic.
String className = classInfo.name + ARRAY_SUFFIX;
// class name doesn't conflict with ancestor class names.
if (enclosingClass != null && classInfo.namespace.equals(enclosingClass.getFullName())) {
className = resolveInnerClassName(enclosingClass, className, ARRAY_SUFFIX);
}
classInfo.name = className;
return classInfo;
}
case MAP:
final MapDataSchema mapSchema = (MapDataSchema) dereferencedDataSchema;
customInfo = getImmediateCustomInfo(mapSchema.getValues());
if (customInfo != null) {
return new ClassInfo(customInfo.getCustomSchema().getNamespace(), customInfo.getCustomSchema().getName() + MAP_SUFFIX, customInfo.getCustomSchema().getPackage());
} else {
final ClassInfo classInfo = classNameForUnnamedTraverse(enclosingClass, memberName, mapSchema.getValues());
// Add just the "Map" suffix first. This is to ensure backwards compatibility with the old codegen logic.
String className = classInfo.name + MAP_SUFFIX;
// with ancestor class names.
if (enclosingClass != null && classInfo.namespace.equals(enclosingClass.getFullName())) {
className = resolveInnerClassName(enclosingClass, className, MAP_SUFFIX);
}
classInfo.name = className;
return classInfo;
}
case UNION:
if (schema.getType() == DataSchema.Type.TYPEREF) {
DataSchema referencedDataSchema;
TyperefDataSchema typerefDataSchema = (TyperefDataSchema) schema;
while ((referencedDataSchema = typerefDataSchema.getDereferencedDataSchema()) != dereferencedDataSchema) {
typerefDataSchema = (TyperefDataSchema) referencedDataSchema;
}
return new ClassInfo(typerefDataSchema.getNamespace(), CodeUtil.capitalize(typerefDataSchema.getName()), typerefDataSchema.getPackage());
} else {
String className = resolveInnerClassName(enclosingClass, CodeUtil.capitalize(memberName), UNION_SUFFIX);
return new ClassInfo(enclosingClass.getFullName(), className);
}
case FIXED:
case RECORD:
case ENUM:
final NamedDataSchema namedSchema = (NamedDataSchema) dereferencedDataSchema;
// carry package override information for named schema.
return new ClassInfo(namedSchema.getNamespace(), CodeUtil.capitalize(namedSchema.getName()), namedSchema.getPackage());
case BOOLEAN:
return new ClassInfo(_templatePackageName, "Boolean");
case INT:
return new ClassInfo(_templatePackageName, "Integer");
case LONG:
return new ClassInfo(_templatePackageName, "Long");
case FLOAT:
return new ClassInfo(_templatePackageName, "Float");
case DOUBLE:
return new ClassInfo(_templatePackageName, "Double");
case STRING:
return new ClassInfo(_templatePackageName, "String");
case BYTES:
return new ClassInfo(_templatePackageName, "ByteString");
case NULL:
throw nullTypeNotAllowed(enclosingClass, memberName);
default:
throw unrecognizedSchemaType(enclosingClass, memberName, dereferencedDataSchema);
}
}
Aggregations