public static class FooRecord extends RecordTemplate { public static final RecordDataSchema SCHEMA = (RecordDataSchema) DataTemplateUtil.parseSchema( "{ \"type\" : \"record\", \"name\" : \"Foo\", \"fields\" : [ { \"name\" : \"bar\", \"type\" : \"string\" } ] }"); public static final RecordDataSchema.Field FIELD_bar = SCHEMA.getField("bar"); public FooRecord() { super(new DataMap(), SCHEMA); } public FooRecord(DataMap map) { super(map, SCHEMA); } public String getBar(GetMode mode) { return obtainDirect(FIELD_bar, String.class, mode); } public void removeBar() { remove(FIELD_bar); } public void setBar(String value) { putDirect(FIELD_bar, String.class, value); } }
@Override public void key(String key) throws IOException { DataSchema newSchema = null; if (_currentSchema != null) { switch (_currentSchema.getType()) { case RECORD: RecordDataSchema recordSchema = (RecordDataSchema) _currentSchema; RecordDataSchema.Field field = recordSchema.getField(key); if (field != null) { newSchema = field.getType(); } break; case UNION: UnionDataSchema unionSchema = (UnionDataSchema) _currentSchema; newSchema = unionSchema.getType(key); break; case MAP: MapDataSchema mapSchema = (MapDataSchema) _currentSchema; newSchema = mapSchema.getValues(); break; } } _pendingSchema = newSchema; super.key(key); }
@Override public void validate(ValidatorContext context) { DataElement element = context.dataElement(); DataSchema schema = element.getSchema(); if (schema != null) { validateSchema(context, schema); } DataElement parentElement = element.getParent(); if (parentElement != null) { DataSchema parentSchema = parentElement.getSchema(); // check if the value belongs to a field in a record // if it belongs to a field, check if the field has // validators. if (parentSchema != null && parentSchema.getType() == DataSchema.Type.RECORD) { Object name = element.getName(); if (name.getClass() == String.class) { RecordDataSchema recordDataSchema = (RecordDataSchema) parentSchema; RecordDataSchema.Field field = recordDataSchema.getField((String) name); if (field != null) { getAndInvokeValidatorList(context, field); } } } } }
public static FieldInfo fieldInfo(RecordTemplate recordTemplate, String fieldName) { RecordDataSchema schema = recordTemplate.schema(); RecordDataSchema.Field field = schema.getField(fieldName); String getterName = methodName( field.getType().getDereferencedType() == DataSchema.Type.BOOLEAN ? "is" : "get", fieldName); try { Method method = recordTemplate.getClass().getMethod(getterName); Class<?> fieldClass = method.getReturnType(); return new FieldInfo(field, fieldClass); } catch (NoSuchMethodException e) { throw new IllegalStateException("Cannot find method " + getterName, e); } }
private void checkRecord(RecordDataSchema older, RecordDataSchema newer) { checkName(older, newer); List<RecordDataSchema.Field> commonFields = new ArrayList<RecordDataSchema.Field>(newer.getFields().size()); List<String> newerRequiredAdded = new CheckerArrayList<String>(); List<String> newerOptionalAdded = new CheckerArrayList<String>(); List<String> requiredToOptional = new CheckerArrayList<String>(); List<String> optionalToRequired = new CheckerArrayList<String>(); List<String> newerRequiredRemoved = new CheckerArrayList<String>(); List<String> newerOptionalRemoved = new CheckerArrayList<String>(); for (RecordDataSchema.Field newerField : newer.getFields()) { String fieldName = newerField.getName(); RecordDataSchema.Field olderField = older.getField(fieldName); if (olderField == null) { (newerField.getOptional() ? newerOptionalAdded : newerRequiredAdded).add(fieldName); } else { commonFields.add(newerField); boolean newerFieldOptional = newerField.getOptional(); if (newerFieldOptional != olderField.getOptional()) { (newerFieldOptional ? requiredToOptional : optionalToRequired).add(fieldName); } } } for (RecordDataSchema.Field olderField : older.getFields()) { String fieldName = olderField.getName(); RecordDataSchema.Field newerField = newer.getField(fieldName); if (newerField == null) { (olderField.getOptional() ? newerOptionalRemoved : newerRequiredRemoved).add(fieldName); } } if (newerRequiredAdded.isEmpty() == false) { appendMessage( CompatibilityMessage.Impact.BREAKS_NEW_READER, "new record added required fields %s", newerRequiredAdded); } if (newerRequiredRemoved.isEmpty() == false) { appendMessage( CompatibilityMessage.Impact.BREAKS_OLD_READER, "new record removed required fields %s", newerRequiredRemoved); } if (optionalToRequired.isEmpty() == false) { appendMessage( CompatibilityMessage.Impact.BREAKS_NEW_READER, "new record changed optional fields to required fields %s", optionalToRequired); } if (requiredToOptional.isEmpty() == false) { appendMessage( CompatibilityMessage.Impact.BREAKS_OLD_READER, "new record changed required fields to optional fields %s", requiredToOptional); } if (newerOptionalAdded.isEmpty() == false) { appendMessage( CompatibilityMessage.Impact.OLD_READER_IGNORES_DATA, "new record added optional fields %s", newerOptionalAdded); } if (newerOptionalRemoved.isEmpty() == false) { appendMessage( CompatibilityMessage.Impact.NEW_READER_IGNORES_DATA, "new record removed optional fields %s", newerOptionalRemoved); } for (RecordDataSchema.Field newerField : commonFields) { String fieldName = newerField.getName(); _path.addLast(fieldName); RecordDataSchema.Field olderField = older.getField(fieldName); assert (olderField != null); check(olderField.getType(), newerField.getType()); _path.removeLast(); } }