use of com.linkedin.data.schema.DataSchema in project rest.li by linkedin.
the class JavaDataTemplateGenerator method generateMap.
protected void generateMap(JDefinedClass mapClass, MapTemplateSpec mapSpec) throws JClassAlreadyExistsException {
final JClass valueJClass = generate(mapSpec.getValueClass());
final JClass dataJClass = generate(mapSpec.getValueDataClass());
if (CodeUtil.isDirectType(mapSpec.getSchema().getValues())) {
mapClass._extends(_directMapBaseClass.narrow(valueJClass));
} else {
extendWrappingMapBaseClass(valueJClass, mapClass);
}
final DataSchema bareSchema = new MapDataSchema(schemaForArrayItemsOrMapValues(mapSpec.getCustomInfo(), mapSpec.getSchema().getValues()));
final JVar schemaField = generateSchemaField(mapClass, bareSchema);
generateConstructorWithNoArg(mapClass, _dataMapClass);
generateConstructorWithInitialCapacity(mapClass, _dataMapClass);
generateConstructorWithInitialCapacityAndLoadFactor(mapClass);
generateConstructorWithMap(mapClass, valueJClass);
generateConstructorWithArg(mapClass, schemaField, _dataMapClass, valueJClass, dataJClass);
if (_pathSpecMethods) {
generatePathSpecMethodsForCollection(mapClass, mapSpec.getSchema(), valueJClass, "values");
}
generateCustomClassInitialization(mapClass, mapSpec.getCustomInfo());
if (_copierMethods) {
generateCopierMethods(mapClass);
}
}
use of com.linkedin.data.schema.DataSchema in project rest.li by linkedin.
the class PegasusDataTemplateGenerator method run.
public static GeneratorResult run(String resolverPath, String defaultPackage, final boolean generateImported, String targetDirectoryPath, String[] sources) throws IOException {
final DataSchemaParser schemaParser = new DataSchemaParser(resolverPath);
final TemplateSpecGenerator specGenerator = new TemplateSpecGenerator(schemaParser.getSchemaResolver());
final JavaDataTemplateGenerator dataTemplateGenerator = new JavaDataTemplateGenerator(defaultPackage);
for (DataSchema predefinedSchema : JavaDataTemplateGenerator.PredefinedJavaClasses.keySet()) {
specGenerator.registerDefinedSchema(predefinedSchema);
}
final DataSchemaParser.ParseResult parseResult = schemaParser.parseSources(sources);
for (Map.Entry<DataSchema, DataSchemaLocation> entry : parseResult.getSchemaAndLocations().entrySet()) {
specGenerator.generate(entry.getKey(), entry.getValue());
}
for (ClassTemplateSpec spec : specGenerator.getGeneratedSpecs()) {
dataTemplateGenerator.generate(spec);
}
final JavaCodeUtil.PersistentClassChecker checker = new DataTemplatePersistentClassChecker(generateImported, specGenerator, dataTemplateGenerator, parseResult.getSourceFiles());
final File targetDirectory = new File(targetDirectoryPath);
final List<File> targetFiles = JavaCodeUtil.targetFiles(targetDirectory, dataTemplateGenerator.getCodeModel(), JavaCodeUtil.classLoaderFromResolverPath(schemaParser.getResolverPath()), checker);
final List<File> modifiedFiles;
if (FileUtil.upToDate(parseResult.getSourceFiles(), targetFiles)) {
modifiedFiles = Collections.emptyList();
_log.info("Target files are up-to-date: " + targetFiles);
} else {
modifiedFiles = targetFiles;
_log.info("Generating " + targetFiles.size() + " files: " + targetFiles);
validateDefinedClassRegistration(dataTemplateGenerator.getCodeModel(), dataTemplateGenerator.getGeneratedClasses().keySet());
dataTemplateGenerator.getCodeModel().build(new FileCodeWriter(targetDirectory, true));
}
return new DefaultGeneratorResult(parseResult.getSourceFiles(), targetFiles, modifiedFiles);
}
use of com.linkedin.data.schema.DataSchema in project rest.li by linkedin.
the class TestValidation method testValidationWithFixupAbsentWithDefault.
@Test
public void testValidationWithFixupAbsentWithDefault() throws IOException, CloneNotSupportedException {
String schemaText = "{ \"type\" : \"record\", \"name\" : \"foo\", \"fields\" : \n" + "[ { \"name\" : \"bar\", \"type\" : { \"name\" : \"barType\", \"type\" : \"record\", \"fields\" : [ \n" + "{ \"name\" : \"boolean\", \"type\" : \"boolean\", \"default\" : true }, \n" + "{ \"name\" : \"int\", \"type\" : \"int\", \"default\" : 1 }, \n" + "{ \"name\" : \"long\", \"type\" : \"long\", \"default\" : 2 }, \n" + "{ \"name\" : \"float\", \"type\" : \"float\", \"default\" : 3.0 }, \n" + "{ \"name\" : \"double\", \"type\" : \"double\", \"default\" : 4.0 }, \n" + "{ \"name\" : \"string\", \"type\" : \"string\", \"default\" : \"cow\" }, \n" + "{ \"name\" : \"bytes\", \"type\" : \"bytes\", \"default\" : \"dog\" }, \n" + "{ \"name\" : \"array\", \"type\" : { \"type\" : \"array\", \"items\" : \"int\" }, \"default\" : [ -1, -2, -3 ] }, \n" + "{ \"name\" : \"enum\", \"type\" : { \"type\" : \"enum\", \"name\" : \"enumType\", \"symbols\" : [ \"apple\", \"orange\", \"banana\" ] }, \"default\" : \"apple\" }, \n" + "{ \"name\" : \"fixed\", \"type\" : { \"type\" : \"fixed\", \"name\" : \"fixedType\", \"size\" : 4 }, \"default\" : \"1234\" }, \n" + "{ \"name\" : \"map\", \"type\" : { \"type\" : \"map\", \"values\" : \"int\" }, \"default\" : { \"1\" : 1, \"2\" : 2 } }, \n" + "{ \"name\" : \"record\", \"type\" : { \"type\" : \"record\", \"name\" : \"recordType\", \"fields\" : [ { \"name\" : \"int\", \"type\" : \"int\" } ] }, \"default\" : { \"int\" : 1 } }, \n" + "{ \"name\" : \"union\", \"type\" : [ \"int\", \"recordType\", \"enumType\", \"fixedType\" ], \"default\" : { \"enumType\" : \"orange\" } }, \n" + "{ \"name\" : \"unionWithNull\", \"type\" : [ \"null\", \"enumType\", \"fixedType\" ], \"default\" : null }, \n" + "{ \"name\" : \"optionalInt\", \"type\" : \"int\", \"optional\" : true }, \n" + "{ \"name\" : \"optionalDefaultInt\", \"type\" : \"int\", \"optional\" : true, \"default\" : 42 } \n" + "] } } ] }";
String key = "bar";
DataSchema schema = dataSchemaFromString(schemaText);
Assert.assertTrue(schema != null);
Object[][][] input = { { { new ValidationOptions(RequiredMode.FIXUP_ABSENT_WITH_DEFAULT) }, { new DataMap(), new DataMap(asMap("boolean", true, "int", 1, "long", 2L, "float", 3.0f, "double", 4.0, "string", "cow", "bytes", ByteString.copyAvroString("dog", false), "array", new DataList(asList(-1, -2, -3)), "enum", "apple", "fixed", ByteString.copyAvroString("1234", false), "map", new DataMap(asMap("1", 1, "2", 2)), "record", new DataMap(asMap("int", 1)), "union", new DataMap(asMap("enumType", "orange")), "unionWithNull", Data.NULL)) } } };
testValidationWithNormalCoercion(schema, key, input);
}
use of com.linkedin.data.schema.DataSchema in project rest.li by linkedin.
the class TestAnyRecordValidator method testAnyRecordValidation.
@Test
public void testAnyRecordValidation() throws IOException {
Object[][] inputs = { { // DataMap is empty
ANYRECORD_SCHEMA, "{" + "}", new AnyRecordValidator.Parameter(false, null), ResultFlag.NOT_VALID, new String[] { "expects data to be a DataMap with one entry" } }, { // DataMap has more than one entry
ANYRECORD_SCHEMA, "{" + " \"a\" : 1," + " \"b\" : 2" + "}", new AnyRecordValidator.Parameter(false, null), ResultFlag.NOT_VALID, new String[] { "expects data to be a DataMap with one entry" } }, { // no resolver, any type schema need not be valid
ANYRECORD_SCHEMA, "{" + " \"abc\" : { }\n" + "}", new AnyRecordValidator.Parameter(false, null), ResultFlag.VALID, new String[] { "INFO", "cannot obtain schema for \"abc\", no resolver" } }, { // no resolver, any type schema must be valid
ANYRECORD_SCHEMA, "{" + " \"abc\" : { }\n" + "}", new AnyRecordValidator.Parameter(true, null), ResultFlag.NOT_VALID, new String[] { "ERROR", "cannot obtain schema for \"abc\", no resolver" } }, { // no resolver but schema exists, any type schema must be valid
ANYRECORD_SCHEMA, "{" + " \"com.linkedin.Foo\" : { }\n" + "}", new AnyRecordValidator.Parameter(true, null), ResultFlag.NOT_VALID, new String[] { "ERROR", "cannot obtain schema for \"com.linkedin.Foo\", no resolver" } }, { // schema exists, any type schema must be valid
ANYRECORD_SCHEMA, "{" + " \"com.linkedin.Foo\" : { }\n" + "}", new AnyRecordValidator.Parameter(true, _resolver), ResultFlag.VALID, new String[] {} }, { // resolver cannot resolve name to schema, any type schema must be valid
ANYRECORD_SCHEMA, "{" + " \"com.linkedin.DoesNotExist\" : { }\n" + "}", new AnyRecordValidator.Parameter(true, _resolver), ResultFlag.NOT_VALID, new String[] { "ERROR", "cannot obtain schema for \"com.linkedin.DoesNotExist\" (" + RESOLVER_ERROR_MESSAGE + ")" } }, { // resolver cannot resolve name to schema, any type schema need not be valid
ANYRECORD_SCHEMA, "{" + " \"com.linkedin.DoesNotExist\" : { }\n" + "}", new AnyRecordValidator.Parameter(false, _resolver), ResultFlag.VALID, new String[] { "INFO", "cannot obtain schema for \"com.linkedin.DoesNotExist\" (" + RESOLVER_ERROR_MESSAGE + ")" } }, { // type schema is valid and any data is valid, any type schema must be valid
ANYRECORD_SCHEMA, "{" + " \"com.linkedin.Bar\" : { \"b\" : \"hello\" }\n" + "}", new AnyRecordValidator.Parameter(true, _resolver), ResultFlag.VALID, new String[] {} }, { // type schema is valid and any data is not valid, any type schema must be valid
ANYRECORD_SCHEMA, "{" + " \"com.linkedin.Bar\" : { \"b\" : 1 }\n" + "}", new AnyRecordValidator.Parameter(true, _resolver), ResultFlag.NOT_VALID, new String[] { "ERROR", "1 cannot be coerced to String" } }, { // type schema is valid and any data is not valid, any type schema must be valid
ANYRECORD_SCHEMA, "{" + " \"com.linkedin.Bar\" : { \"b\" : 1 }\n" + "}", new AnyRecordValidator.Parameter(false, _resolver), ResultFlag.NOT_VALID, new String[] { "ERROR", "1 cannot be coerced to String" } }, { // AnyRecord is field, must sure that the field is being validated
ANYRECORDCLIENT_SCHEMA, "{" + " \"required\" : {\n" + " \"com.linkedin.Bar\" : { \"b\" : 1 }\n" + " }\n" + "}", new AnyRecordValidator.Parameter(true, _resolver), ResultFlag.NOT_VALID, new String[] { "ERROR", "/required/com.linkedin.Bar/b", "1 cannot be coerced to String" } }, { // AnyRecord within AnyRecord, make sure nested AnyRecord is validated
ANYRECORDCLIENT_SCHEMA, "{" + " \"required\" : {\n" + " \"com.linkedin.data.schema.validator.AnyRecord\" : {\n" + " \"com.linkedin.Bar\" : { \"b\" : 1 }\n" + " }\n" + " }\n" + "}", new AnyRecordValidator.Parameter(true, _resolver), ResultFlag.NOT_VALID, new String[] { "ERROR", "/required/com.linkedin.data.schema.validator.AnyRecord/com.linkedin.Bar/b", "1 cannot be coerced to String" } } };
final boolean debug = false;
ValidationOptions options = new ValidationOptions();
for (Object[] row : inputs) {
int i = 0;
DataSchema schema = (DataSchema) row[i++];
Object object = TestUtil.dataMapFromString((String) row[i++]);
AnyRecordValidator.Parameter anyRecordValidatorParameter = (AnyRecordValidator.Parameter) row[i++];
AnyRecordValidator.setParameter(options, anyRecordValidatorParameter);
DataSchemaAnnotationValidator validator = new DataSchemaAnnotationValidator(schema);
if (debug)
TestUtil.out.println(validator);
ValidationResult result = ValidateDataAgainstSchema.validate(object, schema, options, validator);
checkValidationResult(result, row, i, debug);
}
}
use of com.linkedin.data.schema.DataSchema in project rest.li by linkedin.
the class TestValidator method testInitializationClassLookup.
@Test
public void testInitializationClassLookup() throws IOException {
Object[][] input = { { // Validator class provided in key-to-class map
"{\n" + " \"name\" : \"Foo\",\n" + " \"type\" : \"typeref\",\n" + " \"ref\" : \"int\", \n" + " \"validate\" : {\"regex\" : { \"regex\" : \"[0-9]+\" } }\n" + "}\n" }, { // Validator class name provided by key
"{\n" + " \"name\" : \"Foo\",\n" + " \"type\" : \"typeref\",\n" + " \"ref\" : \"int\",\n" + " \"validate\" : { \"" + FooValidator.class.getName() + "\" : { } }\n" + "}\n" }, { // class name is derived by capitializing 1st character of key and appending "Validator"
"{\n" + " \"name\" : \"Foo\",\n" + " \"type\" : \"typeref\",\n" + " \"ref\" : \"int\", \n" + " \"validate\" : { \"noop\" : { } }\n" + "}\n" } };
for (Object[] row : input) {
String schemaText = (String) row[0];
DataSchema schema = dataSchemaFromString(schemaText);
DataSchemaAnnotationValidator annotationValidator = new DataSchemaAnnotationValidator();
annotationValidator.init(schema);
assertTrue(annotationValidator.isInitOk());
assertTrue(annotationValidator.getInitMessages().isEmpty());
}
}
Aggregations