[ 
https://issues.apache.org/jira/browse/AVRO-2067?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=16418168#comment-16418168
 ] 

ASF GitHub Bot commented on AVRO-2067:
--------------------------------------

cutting closed pull request #304: AVRO-2067: Add object-value attrs to 
PropBuilder
URL: https://github.com/apache/avro/pull/304
 
 
   

This is a PR merged from a forked repository.
As GitHub hides the original diff on merge, it is displayed below for
the sake of provenance:

As this is a foreign pull request (from a fork), the diff is supplied
below (as it won't show otherwise due to GitHub magic):

diff --git a/lang/java/avro/src/main/java/org/apache/avro/SchemaBuilder.java 
b/lang/java/avro/src/main/java/org/apache/avro/SchemaBuilder.java
index cdc43e032..9c768f279 100644
--- a/lang/java/avro/src/main/java/org/apache/avro/SchemaBuilder.java
+++ b/lang/java/avro/src/main/java/org/apache/avro/SchemaBuilder.java
@@ -30,6 +30,7 @@
 import org.apache.avro.Schema.Field;
 import org.apache.avro.generic.GenericData;
 import org.apache.avro.generic.GenericRecord;
+import org.apache.avro.util.internal.JacksonUtils;
 import org.codehaus.jackson.JsonNode;
 import org.codehaus.jackson.io.JsonStringEncoder;
 import org.codehaus.jackson.map.ObjectMapper;
@@ -339,6 +340,13 @@ public final S prop(String name, String val) {
       return prop(name, TextNode.valueOf(val));
     }
 
+    /**
+     * Set name-value pair properties for this type or field.
+     */
+    public final S prop(String name, Object value) {
+      return prop(name, JacksonUtils.toJsonNode(value));
+    }
+
     // for internal use by the Parser
     final S prop(String name, JsonNode val) {
       if(!hasProps()) {
diff --git 
a/lang/java/avro/src/test/java/org/apache/avro/TestSchemaBuilder.java 
b/lang/java/avro/src/test/java/org/apache/avro/TestSchemaBuilder.java
index 99e8e3097..e250ffef1 100644
--- a/lang/java/avro/src/test/java/org/apache/avro/TestSchemaBuilder.java
+++ b/lang/java/avro/src/test/java/org/apache/avro/TestSchemaBuilder.java
@@ -22,7 +22,9 @@
 import java.nio.ByteBuffer;
 import java.util.ArrayList;
 import java.util.Arrays;
+import java.util.Collection;
 import java.util.HashMap;
+import java.util.Iterator;
 import java.util.List;
 import java.util.Map;
 
@@ -93,6 +95,286 @@ public void testProps() {
     Assert.assertEquals("v2real", s.getProp("p2"));
   }
 
+  @Test
+  public void testObjectProps() {
+    Schema s = SchemaBuilder.builder().intBuilder()
+      .prop("booleanProp", true)
+      .prop("intProp", Integer.MAX_VALUE)
+      .prop("longProp", Long.MAX_VALUE)
+      .prop("floatProp", 1.0f)
+      .prop("doubleProp", Double.MAX_VALUE)
+      .prop("byteProp", new byte[] {0x41, 0x42, 0x43} )
+      .prop("stringProp", "abc" )
+      .endInt();
+
+    //string properties
+    @SuppressWarnings("deprecation")
+    Map<String, String> stringProps = s.getProps();
+    Assert.assertEquals(2, stringProps.size());
+    Assert.assertEquals("ABC", stringProps.get("byteProp"));
+    Assert.assertEquals("abc", stringProps.get("stringProp"));
+
+    //object properties
+    Assert.assertEquals(7, s.getObjectProps().size());
+    Assert.assertTrue(s.getObjectProp("booleanProp") instanceof Boolean);
+    Assert.assertEquals(true, s.getObjectProp("booleanProp"));
+    Assert.assertTrue(s.getObjectProp("intProp") instanceof Integer);
+    Assert.assertEquals(Integer.MAX_VALUE, s.getObjectProp("intProp"));
+    Assert.assertTrue(s.getObjectProp("intProp") instanceof Integer);
+    Assert.assertTrue(s.getObjectProp("longProp") instanceof Long);
+    Assert.assertEquals(Long.MAX_VALUE, s.getObjectProp("longProp"));
+    Assert.assertTrue(s.getObjectProp("floatProp") instanceof Double);
+    //float converts to double
+    Assert.assertEquals(1.0d, s.getObjectProp("floatProp"));
+    Assert.assertTrue(s.getObjectProp("doubleProp") instanceof Double);
+    Assert.assertEquals(Double.MAX_VALUE, s.getObjectProp("doubleProp"));
+    //byte[] converts to string
+    Assert.assertTrue(s.getObjectProp("byteProp") instanceof String);
+    Assert.assertEquals("ABC", s.getObjectProp("byteProp"));
+    Assert.assertTrue(s.getObjectProp("stringProp") instanceof String);
+    Assert.assertEquals("abc", s.getObjectProp("stringProp"));
+  }
+
+  @Test
+  public void testFieldObjectProps() {
+    Schema s = SchemaBuilder.builder().record("MyRecord")
+      .fields().name("myField")
+      .prop("booleanProp", true)
+      .prop("intProp", Integer.MAX_VALUE)
+      .prop("longProp", Long.MAX_VALUE)
+      .prop("floatProp", 1.0f)
+      .prop("doubleProp", Double.MAX_VALUE)
+      .prop("byteProp", new byte[] {0x41, 0x42, 0x43} )
+      .prop("stringProp", "abc" )
+      .type().intType()
+      .noDefault()
+      .endRecord();
+
+    Schema.Field f = s.getField("myField");
+
+    //string properties
+    @SuppressWarnings("deprecation")
+    Map<String, String> stringProps = f.getProps();
+    Assert.assertEquals(2, stringProps.size());
+    Assert.assertEquals("ABC", stringProps.get("byteProp"));
+    Assert.assertEquals("abc", stringProps.get("stringProp"));
+
+    //object properties
+    Assert.assertEquals(7, f.getObjectProps().size());
+    Assert.assertTrue(f.getObjectProp("booleanProp") instanceof Boolean);
+    Assert.assertEquals(true, f.getObjectProp("booleanProp"));
+    Assert.assertTrue(f.getObjectProp("intProp") instanceof Integer);
+    Assert.assertEquals(Integer.MAX_VALUE, f.getObjectProp("intProp"));
+    Assert.assertTrue(f.getObjectProp("intProp") instanceof Integer);
+    Assert.assertTrue(f.getObjectProp("longProp") instanceof Long);
+    Assert.assertEquals(Long.MAX_VALUE, f.getObjectProp("longProp"));
+    Assert.assertTrue(f.getObjectProp("floatProp") instanceof Double);
+    //float converts to double
+    Assert.assertEquals(1.0d, f.getObjectProp("floatProp"));
+    Assert.assertTrue(f.getObjectProp("doubleProp") instanceof Double);
+    Assert.assertEquals(Double.MAX_VALUE, f.getObjectProp("doubleProp"));
+    //byte[] converts to string
+    Assert.assertTrue(f.getObjectProp("byteProp") instanceof String);
+    Assert.assertEquals("ABC", f.getObjectProp("byteProp"));
+    Assert.assertTrue(f.getObjectProp("stringProp") instanceof String);
+    Assert.assertEquals("abc", f.getObjectProp("stringProp"));
+  }
+
+  @Test
+  public void testArrayObjectProp() {
+    List<Object> values = new ArrayList<Object>();
+    values.add(true);
+    values.add(Integer.MAX_VALUE);
+    values.add(Long.MAX_VALUE);
+    values.add(1.0f);
+    values.add(Double.MAX_VALUE);
+    values.add(new byte[] {0x41, 0x42, 0x43});
+    values.add("abc");
+
+    Schema s = SchemaBuilder.builder().intBuilder()
+      .prop("arrayProp", values)
+      .endInt();
+
+    //string properties
+    @SuppressWarnings("deprecation")
+    int size = s.getProps().size();
+    Assert.assertEquals(0, size);
+
+    //object properties
+    Assert.assertEquals(1, s.getObjectProps().size());
+
+    Assert.assertTrue(s.getObjectProp("arrayProp") instanceof Collection);
+    @SuppressWarnings("unchecked")
+    Collection<Object> valueCollection = (Collection<Object>) 
s.getObjectProp("arrayProp");
+    Iterator<Object> iter = valueCollection.iterator();
+    Assert.assertEquals(7, valueCollection.size());
+    Assert.assertEquals(true, iter.next());
+    Assert.assertEquals(Integer.MAX_VALUE, iter.next());
+    Assert.assertEquals(Long.MAX_VALUE, iter.next());
+    //float converts to double
+    Assert.assertEquals(1.0d, iter.next());
+    Assert.assertEquals(Double.MAX_VALUE, iter.next());
+    //byte[] converts to string
+    Assert.assertEquals("ABC", iter.next());
+    Assert.assertEquals("abc", iter.next());
+  }
+
+  @Test
+  public void testFieldArrayObjectProp() {
+    List<Object> values = new ArrayList<Object>();
+    values.add(true);
+    values.add(Integer.MAX_VALUE);
+    values.add(Long.MAX_VALUE);
+    values.add(1.0f);
+    values.add(Double.MAX_VALUE);
+    values.add(new byte[] {0x41, 0x42, 0x43});
+    values.add("abc");
+
+    Schema s = SchemaBuilder.builder().record("MyRecord")
+      .fields().name("myField")
+      .prop("arrayProp", values)
+      .type().intType()
+      .noDefault()
+      .endRecord();
+
+    Schema.Field f = s.getField("myField");
+
+    //string properties
+    @SuppressWarnings("deprecation")
+    int size = f.getProps().size();
+    Assert.assertEquals(0, size);
+
+    //object properties
+    Assert.assertEquals(1, f.getObjectProps().size());
+
+    Assert.assertTrue(f.getObjectProp("arrayProp") instanceof Collection);
+    @SuppressWarnings("unchecked")
+    Collection<Object> valueCollection = (Collection<Object>) 
f.getObjectProp("arrayProp");
+    Iterator<Object> iter = valueCollection.iterator();
+    Assert.assertEquals(7, valueCollection.size());
+    Assert.assertEquals(true, iter.next());
+    Assert.assertEquals(Integer.MAX_VALUE, iter.next());
+    Assert.assertEquals(Long.MAX_VALUE, iter.next());
+    //float converts to double
+    Assert.assertEquals(1.0d, iter.next());
+    Assert.assertEquals(Double.MAX_VALUE, iter.next());
+    //byte[] converts to string
+    Assert.assertEquals("ABC", iter.next());
+    Assert.assertEquals("abc", iter.next());
+  }
+
+  @Test
+  public void testMapObjectProp() {
+    Map<String, Object> values = new HashMap<String, Object>();
+    values.put("booleanKey", true);
+    values.put("intKey", Integer.MAX_VALUE);
+    values.put("longKey", Long.MAX_VALUE);
+    values.put("floatKey", 1.0f);
+    values.put("doubleKey", Double.MAX_VALUE);
+    values.put("byteKey", new byte[] {0x41, 0x42, 0x43});
+    values.put("stringKey", "abc");
+
+    Schema s = SchemaBuilder.builder().intBuilder()
+      .prop("mapProp", values)
+      .endInt();
+
+    //string properties
+    @SuppressWarnings("deprecation")
+    int size = s.getProps().size();
+    Assert.assertEquals(0, size);
+    Assert.assertEquals(1, s.getObjectProps().size());
+
+    //object properties
+    Assert.assertTrue(s.getObjectProp("mapProp") instanceof Map);
+    @SuppressWarnings("unchecked")
+    Map<String, Object> valueMap = (Map<String, Object>) 
s.getObjectProp("mapProp");
+    Assert.assertEquals(values.size(), valueMap.size());
+
+    Assert.assertTrue(valueMap.get("booleanKey") instanceof Boolean);
+    Assert.assertEquals(true, valueMap.get("booleanKey"));
+    Assert.assertTrue(valueMap.get("intKey") instanceof Integer);
+    Assert.assertEquals(Integer.MAX_VALUE, valueMap.get("intKey"));
+    Assert.assertTrue(valueMap.get("longKey") instanceof Long);
+    Assert.assertEquals(Long.MAX_VALUE, valueMap.get("longKey"));
+    //float converts to double
+    Assert.assertTrue(valueMap.get("floatKey") instanceof Double);
+    Assert.assertEquals(1.0d, valueMap.get("floatKey"));
+    Assert.assertTrue(valueMap.get("doubleKey") instanceof Double);
+    Assert.assertEquals(Double.MAX_VALUE, valueMap.get("doubleKey"));
+    //byte[] converts to string
+    Assert.assertTrue(valueMap.get("byteKey") instanceof String);
+    Assert.assertEquals("ABC", valueMap.get("byteKey"));
+    Assert.assertTrue(valueMap.get("stringKey") instanceof String);
+    Assert.assertEquals("abc", valueMap.get("stringKey"));
+  }
+
+  @Test
+  public void testFieldMapObjectProp() {
+    Map<String, Object> values = new HashMap<String, Object>();
+    values.put("booleanKey", true);
+    values.put("intKey", Integer.MAX_VALUE);
+    values.put("longKey", Long.MAX_VALUE);
+    values.put("floatKey", 1.0f);
+    values.put("doubleKey", Double.MAX_VALUE);
+    values.put("byteKey", new byte[] {0x41, 0x42, 0x43});
+    values.put("stringKey", "abc");
+
+    Schema s = SchemaBuilder.builder().record("MyRecord")
+      .fields().name("myField")
+      .prop("mapProp", values)
+      .type().intType()
+      .noDefault()
+      .endRecord();
+
+    Schema.Field f = s.getField("myField");
+
+    //string properties
+    @SuppressWarnings("deprecation")
+    int size = f.getProps().size();
+    Assert.assertEquals(0, size);
+    Assert.assertEquals(1, f.getObjectProps().size());
+
+    //object properties
+    Assert.assertTrue(f.getObjectProp("mapProp") instanceof Map);
+    @SuppressWarnings("unchecked")
+    Map<String, Object> valueMap = (Map<String, Object>) 
f.getObjectProp("mapProp");
+    Assert.assertEquals(values.size(), valueMap.size());
+
+    Assert.assertTrue(valueMap.get("booleanKey") instanceof Boolean);
+    Assert.assertEquals(true, valueMap.get("booleanKey"));
+    Assert.assertTrue(valueMap.get("intKey") instanceof Integer);
+    Assert.assertEquals(Integer.MAX_VALUE, valueMap.get("intKey"));
+    Assert.assertTrue(valueMap.get("longKey") instanceof Long);
+    Assert.assertEquals(Long.MAX_VALUE, valueMap.get("longKey"));
+    //float converts to double
+    Assert.assertTrue(valueMap.get("floatKey") instanceof Double);
+    Assert.assertEquals(1.0d, valueMap.get("floatKey"));
+    Assert.assertTrue(valueMap.get("doubleKey") instanceof Double);
+    Assert.assertEquals(Double.MAX_VALUE, valueMap.get("doubleKey"));
+    //byte[] converts to string
+    Assert.assertTrue(valueMap.get("byteKey") instanceof String);
+    Assert.assertEquals("ABC", valueMap.get("byteKey"));
+    Assert.assertTrue(valueMap.get("stringKey") instanceof String);
+    Assert.assertEquals("abc", valueMap.get("stringKey"));
+  }
+
+  @Test(expected = AvroRuntimeException.class)
+  public void testNullObjectProp() {
+    SchemaBuilder.builder().intBuilder()
+      .prop("nullProp", (Object) null)
+      .endInt();
+  }
+
+  @Test(expected = AvroRuntimeException.class)
+  public void testFieldNullObjectProp() {
+    SchemaBuilder.builder().record("MyRecord")
+      .fields().name("myField")
+      .prop("nullProp", (Object) null)
+      .type().intType()
+      .noDefault()
+      .endRecord();
+  }
+
   @Test
   public void testNamespaces() {
     Schema s1 = SchemaBuilder.record("myrecord")


 

----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on GitHub and use the
URL above to go to the specific comment.
 
For queries about this service, please contact Infrastructure at:
[email protected]


> Add object-value attribute support to SchemaBuilder.PropBuilder
> ---------------------------------------------------------------
>
>                 Key: AVRO-2067
>                 URL: https://issues.apache.org/jira/browse/AVRO-2067
>             Project: Avro
>          Issue Type: Improvement
>          Components: java
>            Reporter: Jeffrey Mullins
>            Assignee: Jeffrey Mullins
>            Priority: Major
>         Attachments: AVRO-2067.patch
>
>
> Add object-value attribute support to _SchemaBuilder.PropBuilder_.
> {code:java}
> public final S prop(String name, Object value) 
> {code}
>     The avro 1.8.2 specification permits the use of undefined schema 
> attributes as metadata:
> {quote}    
> "Attributes not defined in this document are permitted as metadata, but must 
> not affect the format of serialized data."
> {quote}
>     
> The permitted types of attribute values is unclear from the above, but 
> attributes with object values (non-string) are supported when parsing a 
> schema and in the JsonProperties base class from which both Schema and 
> Schema.Field inherit.
>     
> _JsonProperties_ supports object-valued attributes through its _addProp()_ 
> and _getObjectProps()_ methods.
> In our use case, we need to  programmatically normalize and augment 
> user-supplied schemas which may contain attributes with object values like 
> booleans and arrays of strings. The absence of a method in 
> _SchemaBuilder.PropBuilder_ which support object-valued attributes makes this 
> difficult.



--
This message was sent by Atlassian JIRA
(v7.6.3#76005)

Reply via email to