Repository: avro Updated Branches: refs/heads/master c04a17c86 -> edd8edda0
AVRO-1971: Allow alias annotation on fields This closes #175 Project: http://git-wip-us.apache.org/repos/asf/avro/repo Commit: http://git-wip-us.apache.org/repos/asf/avro/commit/edd8edda Tree: http://git-wip-us.apache.org/repos/asf/avro/tree/edd8edda Diff: http://git-wip-us.apache.org/repos/asf/avro/diff/edd8edda Branch: refs/heads/master Commit: edd8edda0659f802e203e36bcb9d8ec51d821f26 Parents: c04a17c Author: baunz <[email protected]> Authored: Sun Dec 18 21:48:33 2016 +0100 Committer: Gabor Szadovszky <[email protected]> Committed: Fri Jun 16 09:01:32 2017 +0200 ---------------------------------------------------------------------- CHANGES.txt | 2 ++ .../java/org/apache/avro/reflect/AvroAlias.java | 2 +- .../org/apache/avro/reflect/ReflectData.java | 15 +++++++++++ .../org/apache/avro/reflect/TestReflect.java | 28 +++++++++++++++++++- 4 files changed, 45 insertions(+), 2 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/avro/blob/edd8edda/CHANGES.txt ---------------------------------------------------------------------- diff --git a/CHANGES.txt b/CHANGES.txt index d908348..c387de6 100644 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -50,6 +50,8 @@ Trunk (not yet released) AVRO-1723. Add support for forward declarations in avro IDL (Zoltan Farcas via thiru) + AVRO-1971: Allow alias annotation on fields (Johannes Schulte via gabor) + BUG FIXES AVRO-1741: Python3: Fix error when codec is not in the header. http://git-wip-us.apache.org/repos/asf/avro/blob/edd8edda/lang/java/avro/src/main/java/org/apache/avro/reflect/AvroAlias.java ---------------------------------------------------------------------- diff --git a/lang/java/avro/src/main/java/org/apache/avro/reflect/AvroAlias.java b/lang/java/avro/src/main/java/org/apache/avro/reflect/AvroAlias.java index d613350..66f51e8 100644 --- a/lang/java/avro/src/main/java/org/apache/avro/reflect/AvroAlias.java +++ b/lang/java/avro/src/main/java/org/apache/avro/reflect/AvroAlias.java @@ -28,7 +28,7 @@ import java.lang.annotation.Target; * named by the alias. */ @Retention(RetentionPolicy.RUNTIME) -@Target(ElementType.TYPE) +@Target({ElementType.TYPE, ElementType.FIELD}) public @interface AvroAlias { String NULL = "NOT A VALID NAMESPACE"; http://git-wip-us.apache.org/repos/asf/avro/blob/edd8edda/lang/java/avro/src/main/java/org/apache/avro/reflect/ReflectData.java ---------------------------------------------------------------------- diff --git a/lang/java/avro/src/main/java/org/apache/avro/reflect/ReflectData.java b/lang/java/avro/src/main/java/org/apache/avro/reflect/ReflectData.java index 60095ad..eb9f5fb 100644 --- a/lang/java/avro/src/main/java/org/apache/avro/reflect/ReflectData.java +++ b/lang/java/avro/src/main/java/org/apache/avro/reflect/ReflectData.java @@ -633,6 +633,9 @@ public class ReflectData extends SpecificData { if (f.name().equals(fieldName)) throw new AvroTypeException("double field entry: "+ fieldName); } + + consumeFieldAlias(field, recordField); + fields.add(recordField); } if (error) // add Throwable message @@ -877,6 +880,18 @@ public class ReflectData extends SpecificData { } } + + private void consumeFieldAlias(Field field, Schema.Field recordField) { + AvroAlias alias = field.getAnnotation(AvroAlias.class); + if (alias != null) { + if (!alias.space().equals(AvroAlias.NULL)) { + throw new AvroRuntimeException( + "Namespaces are not allowed on field aliases. " + "Offending field: " + recordField.name()); + } + recordField.addAlias(alias.alias()); + } + } + @Override public Object createFixed(Object old, Schema schema) { // SpecificData will try to instantiate the type returned by getClass, but http://git-wip-us.apache.org/repos/asf/avro/blob/edd8edda/lang/java/avro/src/test/java/org/apache/avro/reflect/TestReflect.java ---------------------------------------------------------------------- diff --git a/lang/java/avro/src/test/java/org/apache/avro/reflect/TestReflect.java b/lang/java/avro/src/test/java/org/apache/avro/reflect/TestReflect.java index 8b23730..afe7f08 100644 --- a/lang/java/avro/src/test/java/org/apache/avro/reflect/TestReflect.java +++ b/lang/java/avro/src/test/java/org/apache/avro/reflect/TestReflect.java @@ -39,6 +39,7 @@ import org.apache.avro.AvroRuntimeException; import org.apache.avro.AvroTypeException; import org.apache.avro.Protocol; import org.apache.avro.Schema; +import org.apache.avro.SchemaBuilder; import org.apache.avro.Schema.Field; import org.apache.avro.generic.GenericData; import org.apache.avro.io.Decoder; @@ -1029,12 +1030,37 @@ public class TestReflect { private static class AliasC { } @Test - public void testAvroAlias() { + public void testAvroAliasOnClass() { check(AliasA.class, "{\"type\":\"record\",\"name\":\"AliasA\",\"namespace\":\"org.apache.avro.reflect.TestReflect$\",\"fields\":[],\"aliases\":[\"b.a\"]}"); check(AliasB.class, "{\"type\":\"record\",\"name\":\"AliasB\",\"namespace\":\"org.apache.avro.reflect.TestReflect$\",\"fields\":[],\"aliases\":[\"a\"]}"); check(AliasC.class, "{\"type\":\"record\",\"name\":\"AliasC\",\"namespace\":\"org.apache.avro.reflect.TestReflect$\",\"fields\":[],\"aliases\":[\"a\"]}"); } + private static class ClassWithAliasOnField { + @AvroAlias(alias = "aliasName") + int primitiveField; + } + + private static class ClassWithAliasAndNamespaceOnField { + @AvroAlias(alias = "aliasName", space = "forbidden.space.entry") + int primitiveField; + } + + @Test + public void testAvroAliasOnField() { + + Schema expectedSchema = SchemaBuilder.record(ClassWithAliasOnField.class.getSimpleName()) + .namespace("org.apache.avro.reflect.TestReflect$").fields().name("primitiveField").aliases("aliasName") + .type(Schema.create(org.apache.avro.Schema.Type.INT)).noDefault().endRecord(); + + check(ClassWithAliasOnField.class, expectedSchema.toString()); + } + + @Test(expected = AvroRuntimeException.class) + public void namespaceDefinitionOnFieldAliasMustThrowException() { + ReflectData.get().getSchema(ClassWithAliasAndNamespaceOnField.class); + } + private static class DefaultTest { @AvroDefault("1") int foo;
