You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@avro.apache.org by to...@apache.org on 2014/11/18 10:58:22 UTC
svn commit: r1640293 - in /avro/trunk: ./ lang/java/
lang/java/avro/src/main/java/org/apache/avro/
lang/java/avro/src/main/java/org/apache/avro/data/
lang/java/avro/src/main/java/org/apache/avro/io/
lang/java/avro/src/main/java/org/apache/avro/io/parsi...
Author: tomwhite
Date: Tue Nov 18 09:58:21 2014
New Revision: 1640293
URL: http://svn.apache.org/r1640293
Log:
AVRO-1585. Java: Deprecate Jackson classes in public API.
Added:
avro/trunk/lang/java/avro/src/main/java/org/apache/avro/util/internal/
avro/trunk/lang/java/avro/src/main/java/org/apache/avro/util/internal/JacksonUtils.java
avro/trunk/lang/java/avro/src/test/java/org/apache/avro/util/internal/
avro/trunk/lang/java/avro/src/test/java/org/apache/avro/util/internal/TestJacksonUtils.java
Modified:
avro/trunk/CHANGES.txt
avro/trunk/lang/java/avro/src/main/java/org/apache/avro/JsonProperties.java
avro/trunk/lang/java/avro/src/main/java/org/apache/avro/Schema.java
avro/trunk/lang/java/avro/src/main/java/org/apache/avro/data/Json.java
avro/trunk/lang/java/avro/src/main/java/org/apache/avro/io/EncoderFactory.java
avro/trunk/lang/java/avro/src/main/java/org/apache/avro/io/JsonEncoder.java
avro/trunk/lang/java/avro/src/main/java/org/apache/avro/io/parsing/ResolvingGrammarGenerator.java
avro/trunk/lang/java/avro/src/test/java/org/apache/avro/TestSchemaBuilder.java
avro/trunk/lang/java/avro/src/test/java/org/apache/avro/TestSchemaCompatibility.java
avro/trunk/lang/java/avro/src/test/java/org/apache/avro/generic/TestGenericRecordBuilder.java
avro/trunk/lang/java/ipc/src/test/java/org/apache/avro/TestProtocolGeneric.java
avro/trunk/lang/java/ipc/src/test/java/org/apache/avro/TestSchema.java
avro/trunk/lang/java/mapred/src/test/java/org/apache/avro/mapred/TestGenericJob.java
avro/trunk/lang/java/pom.xml
avro/trunk/lang/java/tools/src/main/java/org/apache/avro/tool/RpcReceiveTool.java
Modified: avro/trunk/CHANGES.txt
URL: http://svn.apache.org/viewvc/avro/trunk/CHANGES.txt?rev=1640293&r1=1640292&r2=1640293&view=diff
==============================================================================
--- avro/trunk/CHANGES.txt (original)
+++ avro/trunk/CHANGES.txt Tue Nov 18 09:58:21 2014
@@ -45,6 +45,8 @@ Trunk (not yet released)
AVRO-1551. Java: Add an output encoding option to the compiler
command line tool. (Keegan Witt via cutting)
+ AVRO-1585. Java: Deprecate Jackson classes in public API. (tomwhite)
+
BUG FIXES
AVRO-1553. Java: MapReduce never uses MapOutputValueSchema (tomwhite)
Modified: avro/trunk/lang/java/avro/src/main/java/org/apache/avro/JsonProperties.java
URL: http://svn.apache.org/viewvc/avro/trunk/lang/java/avro/src/main/java/org/apache/avro/JsonProperties.java?rev=1640293&r1=1640292&r2=1640293&view=diff
==============================================================================
--- avro/trunk/lang/java/avro/src/main/java/org/apache/avro/JsonProperties.java (original)
+++ avro/trunk/lang/java/avro/src/main/java/org/apache/avro/JsonProperties.java Tue Nov 18 09:58:21 2014
@@ -23,12 +23,97 @@ import java.util.Map;
import java.util.Set;
import java.io.IOException;
+import org.apache.avro.util.internal.JacksonUtils;
import org.codehaus.jackson.JsonNode;
import org.codehaus.jackson.JsonGenerator;
import org.codehaus.jackson.node.TextNode;
-/** Base class for objects that have Json-valued properties. */
+/**
+ * Base class for objects that have JSON-valued properties. Avro and JSON values are
+ * represented in Java using the following mapping:
+ *
+ * <table>
+ * <th>
+ * <td>Avro type</td>
+ * <td>JSON type</td>
+ * <td>Java type</td>
+ * </th>
+ * <tr>
+ * <td><code>null</code></td>
+ * <td><code>null</code></td>
+ * <td>{@link #NULL_VALUE}</td>
+ * </tr>
+ * <tr>
+ * <td><code>boolean</code></td>
+ * <td>Boolean</td>
+ * <td><code>boolean</code></td>
+ * </tr>
+ * <tr>
+ * <td><code>int</code></td>
+ * <td>Number</td>
+ * <td><code>int</code></td>
+ * </tr>
+ * <tr>
+ * <td><code>long</code></td>
+ * <td>Number</td>
+ * <td><code>long</code></td>
+ * </tr>
+ * <tr>
+ * <td><code>float</code></td>
+ * <td>Number</td>
+ * <td><code>float</code></td>
+ * </tr>
+ * <tr>
+ * <td><code>double</code></td>
+ * <td>Number</td>
+ * <td><code>double</code></td>
+ * </tr>
+ * <tr>
+ * <td><code>bytes</code></td>
+ * <td>String</td>
+ * <td><code>byte[]</code></td>
+ * </tr>
+ * <tr>
+ * <td><code>string</code></td>
+ * <td>String</td>
+ * <td>{@link java.lang.String}</td>
+ * </tr>
+ * <tr>
+ * <td><code>record</code></td>
+ * <td>Object</td>
+ * <td>{@link java.util.Map}</td>
+ * </tr>
+ * <tr>
+ * <td><code>enum</code></td>
+ * <td>String</td>
+ * <td>{@link java.lang.String}</td>
+ * </tr>
+ * <tr>
+ * <td><code>array</code></td>
+ * <td>Array</td>
+ * <td>{@link java.util.Collection}</td>
+ * </tr>
+ * <tr>
+ * <td><code>map</code></td>
+ * <td>Object</td>
+ * <td>{@link java.util.Map}</td>
+ * </tr>
+ * <tr>
+ * <td><code>fixed</code></td>
+ * <td>String</td>
+ * <td><code>byte[]</code></td>
+ * </tr>
+ * </table>
+ *
+ * @see org.apache.avro.data.Json
+ */
public abstract class JsonProperties {
+ public static class Null {
+ private Null() {}
+ }
+ /** A value representing a JSON <code>null</code>. */
+ public static final Null NULL_VALUE = new Null();
+
Map<String,JsonNode> props = new LinkedHashMap<String,JsonNode>(1);
private Set<String> reserved;
@@ -49,12 +134,22 @@ public abstract class JsonProperties {
/**
* Returns the value of the named property in this schema.
* Returns <tt>null</tt> if there is no property with that name.
+ * @deprecated use {@link #getObjectProp(String)}
*/
+ @Deprecated
public synchronized JsonNode getJsonProp(String name) {
return props.get(name);
}
/**
+ * Returns the value of the named property in this schema.
+ * Returns <tt>null</tt> if there is no property with that name.
+ */
+ public synchronized Object getObjectProp(String name) {
+ return JacksonUtils.toObject(props.get(name));
+ }
+
+ /**
* Adds a property with the given name <tt>name</tt> and
* value <tt>value</tt>. Neither <tt>name</tt> nor <tt>value</tt> can be
* <tt>null</tt>. It is illegal to add a property if another with
@@ -75,7 +170,9 @@ public abstract class JsonProperties {
*
* @param name The name of the property to add
* @param value The value for the property to add
+ * @deprecated use {@link #addProp(String, Object)}
*/
+ @Deprecated
public synchronized void addProp(String name, JsonNode value) {
if (reserved.contains(name))
throw new AvroRuntimeException("Can't set reserved property: " + name);
@@ -90,6 +187,10 @@ public abstract class JsonProperties {
throw new AvroRuntimeException("Can't overwrite property: " + name);
}
+ public synchronized void addProp(String name, Object value) {
+ addProp(name, JacksonUtils.toJsonNode(value));
+ }
+
/** Return the defined properties that have string values. */
@Deprecated public Map<String,String> getProps() {
Map<String,String> result = new LinkedHashMap<String,String>();
@@ -107,11 +208,23 @@ public abstract class JsonProperties {
return result;
}
- /** Return the defined properties as an unmodifieable Map. */
+ /**
+ * Return the defined properties as an unmodifieable Map.
+ * @deprecated use {@link #getObjectProps()}
+ */
+ @Deprecated
public Map<String,JsonNode> getJsonProps() {
return Collections.unmodifiableMap(props);
}
+ /** Return the defined properties as an unmodifieable Map. */
+ public Map<String,Object> getObjectProps() {
+ Map<String,Object> result = new LinkedHashMap<String,Object>();
+ for (Map.Entry<String,JsonNode> e : props.entrySet())
+ result.put(e.getKey(), JacksonUtils.toObject(e.getValue()));
+ return result;
+ }
+
void writeProps(JsonGenerator gen) throws IOException {
for (Map.Entry<String,JsonNode> e : props.entrySet())
gen.writeObjectField(e.getKey(), e.getValue());
Modified: avro/trunk/lang/java/avro/src/main/java/org/apache/avro/Schema.java
URL: http://svn.apache.org/viewvc/avro/trunk/lang/java/avro/src/main/java/org/apache/avro/Schema.java?rev=1640293&r1=1640292&r2=1640293&view=diff
==============================================================================
--- avro/trunk/lang/java/avro/src/main/java/org/apache/avro/Schema.java (original)
+++ avro/trunk/lang/java/avro/src/main/java/org/apache/avro/Schema.java Tue Nov 18 09:58:21 2014
@@ -35,6 +35,7 @@ import java.util.List;
import java.util.Map;
import java.util.Set;
+import org.apache.avro.util.internal.JacksonUtils;
import org.codehaus.jackson.JsonFactory;
import org.codehaus.jackson.JsonNode;
import org.codehaus.jackson.JsonParseException;
@@ -132,6 +133,11 @@ public abstract class Schema extends Jso
hashCode = NO_HASHCODE;
}
+ @Override public void addProp(String name, Object value) {
+ super.addProp(name, value);
+ hashCode = NO_HASHCODE;
+ }
+
/** Create an anonymous record schema. */
public static Schema createRecord(List<Field> fields) {
Schema result = createRecord(null, null, null, false);
@@ -362,10 +368,14 @@ public abstract class Schema extends Jso
private final Order order;
private Set<String> aliases;
+ /** @deprecated use {@link #Field(String, Schema, String, Object)} */
+ @Deprecated
public Field(String name, Schema schema, String doc,
JsonNode defaultValue) {
this(name, schema, doc, defaultValue, Order.ASCENDING);
}
+ /** @deprecated use {@link #Field(String, Schema, String, Object, Order)} */
+ @Deprecated
public Field(String name, Schema schema, String doc,
JsonNode defaultValue, Order order) {
super(FIELD_RESERVED);
@@ -375,6 +385,22 @@ public abstract class Schema extends Jso
this.defaultValue = validateDefault(name, schema, defaultValue);
this.order = order;
}
+ /**
+ * @param defaultValue the default value for this field specified using the mapping
+ * in {@link JsonProperties}
+ */
+ public Field(String name, Schema schema, String doc,
+ Object defaultValue) {
+ this(name, schema, doc, defaultValue, Order.ASCENDING);
+ }
+ /**
+ * @param defaultValue the default value for this field specified using the mapping
+ * in {@link JsonProperties}
+ */
+ public Field(String name, Schema schema, String doc,
+ Object defaultValue, Order order) {
+ this(name, schema, doc, JacksonUtils.toJsonNode(defaultValue), order);
+ }
public String name() { return name; };
/** The position of this field within the record. */
public int pos() { return position; }
@@ -382,7 +408,13 @@ public abstract class Schema extends Jso
public Schema schema() { return schema; }
/** Field's documentation within the record, if set. May return null. */
public String doc() { return doc; }
- public JsonNode defaultValue() { return defaultValue; }
+ /** @deprecated use {@link #defaultVal() } */
+ @Deprecated public JsonNode defaultValue() { return defaultValue; }
+ /**
+ * @return the default value for this field specified using the mapping
+ * in {@link JsonProperties}
+ */
+ public Object defaultVal() { return JacksonUtils.toObject(defaultValue); }
public Order order() { return order; }
@Deprecated public Map<String,String> props() { return getProps(); }
public void addAlias(String alias) {
@@ -1313,7 +1345,11 @@ public abstract class Schema extends Jso
return jsonNode != null ? jsonNode.getTextValue() : null;
}
- /** Parses a string as Json. */
+ /**
+ * Parses a string as Json.
+ * @deprecated use {@link org.apache.avro.data.Json#parseJson(String)}
+ */
+ @Deprecated
public static JsonNode parseJson(String s) {
try {
return MAPPER.readTree(FACTORY.createJsonParser(new StringReader(s)));
Modified: avro/trunk/lang/java/avro/src/main/java/org/apache/avro/data/Json.java
URL: http://svn.apache.org/viewvc/avro/trunk/lang/java/avro/src/main/java/org/apache/avro/data/Json.java?rev=1640293&r1=1640292&r2=1640293&view=diff
==============================================================================
--- avro/trunk/lang/java/avro/src/main/java/org/apache/avro/data/Json.java (original)
+++ avro/trunk/lang/java/avro/src/main/java/org/apache/avro/data/Json.java Tue Nov 18 09:58:21 2014
@@ -18,9 +18,14 @@
package org.apache.avro.data;
import java.io.IOException;
+import java.io.StringReader;
import java.util.Iterator;
+import org.apache.avro.util.internal.JacksonUtils;
+import org.codehaus.jackson.JsonFactory;
import org.codehaus.jackson.JsonNode;
+import org.codehaus.jackson.JsonParseException;
+import org.codehaus.jackson.map.ObjectMapper;
import org.codehaus.jackson.node.JsonNodeFactory;
import org.codehaus.jackson.node.LongNode;
import org.codehaus.jackson.node.DoubleNode;
@@ -43,6 +48,9 @@ import org.apache.avro.io.ResolvingDecod
public class Json {
private Json() {} // singleton: no public ctor
+ static final JsonFactory FACTORY = new JsonFactory();
+ static final ObjectMapper MAPPER = new ObjectMapper(FACTORY);
+
/** The schema for Json data. */
public static final Schema SCHEMA;
static {
@@ -54,7 +62,11 @@ public class Json {
}
}
- /** {@link DatumWriter} for arbitrary Json data. */
+ /**
+ * {@link DatumWriter} for arbitrary Json data.
+ * @deprecated use {@link ObjectWriter}
+ */
+ @Deprecated
public static class Writer implements DatumWriter<JsonNode> {
@Override public void setSchema(Schema schema) {
@@ -68,7 +80,11 @@ public class Json {
}
}
- /** {@link DatumReader} for arbitrary Json data. */
+ /**
+ * {@link DatumReader} for arbitrary Json data.
+ * @deprecated use {@link ObjectReader}
+ */
+ @Deprecated
public static class Reader implements DatumReader<JsonNode> {
private Schema written;
private ResolvingDecoder resolver;
@@ -92,10 +108,77 @@ public class Json {
}
}
+ /** {@link DatumWriter} for arbitrary Json data using the object model described
+ * in {@link org.apache.avro.JsonProperties}. */
+ public static class ObjectWriter implements DatumWriter<Object> {
+
+ @Override public void setSchema(Schema schema) {
+ if (!SCHEMA.equals(schema))
+ throw new RuntimeException("Not the Json schema: "+schema);
+ }
+
+ @Override
+ public void write(Object datum, Encoder out) throws IOException {
+ Json.writeObject(datum, out);
+ }
+ }
+
+ /** {@link DatumReader} for arbitrary Json data using the object model described
+ * in {@link org.apache.avro.JsonProperties}. */
+ public static class ObjectReader implements DatumReader<Object> {
+ private Schema written;
+ private ResolvingDecoder resolver;
+
+ @Override public void setSchema(Schema schema) {
+ this.written = SCHEMA.equals(written) ? null : schema;
+ }
+
+ @Override
+ public Object read(Object reuse, Decoder in) throws IOException {
+ if (written == null) // same schema
+ return Json.readObject(in);
+
+ // use a resolver to adapt alternate version of Json schema
+ if (resolver == null)
+ resolver = DecoderFactory.get().resolvingDecoder(written, SCHEMA, null);
+ resolver.configure(in);
+ Object result = Json.readObject(resolver);
+ resolver.drain();
+ return result;
+ }
+ }
+
+ /**
+ * Parses a JSON string and converts it to the object model described in
+ * {@link org.apache.avro.JsonProperties}.
+ */
+ public static Object parseJson(String s) {
+ try {
+ return JacksonUtils.toObject(MAPPER.readTree(FACTORY.createJsonParser(
+ new StringReader(s))));
+ } catch (JsonParseException e) {
+ throw new RuntimeException(e);
+ } catch (IOException e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+ /**
+ * Converts an instance of the object model described in
+ * {@link org.apache.avro.JsonProperties} to a JSON string.
+ */
+ public static String toString(Object datum) {
+ return JacksonUtils.toJsonNode(datum).toString();
+ }
+
/** Note: this enum must be kept aligned with the union in Json.avsc. */
private enum JsonType { LONG, DOUBLE, STRING, BOOLEAN, NULL, ARRAY, OBJECT }
- /** Write Json data as Avro data. */
+ /**
+ * Write Json data as Avro data.
+ * @deprecated internal method
+ */
+ @Deprecated
public static void write(JsonNode node, Encoder out) throws IOException {
switch(node.asToken()) {
case VALUE_NUMBER_INT:
@@ -150,7 +233,11 @@ public class Json {
}
}
- /** Read Json data from Avro data. */
+ /**
+ * Read Json data from Avro data.
+ * @deprecated internal method
+ */
+ @Deprecated
public static JsonNode read(Decoder in) throws IOException {
switch (JsonType.values()[in.readIndex()]) {
case LONG:
@@ -181,4 +268,12 @@ public class Json {
}
}
+ private static void writeObject(Object datum, Encoder out) throws IOException {
+ write(JacksonUtils.toJsonNode(datum), out);
+ }
+
+ private static Object readObject(Decoder in) throws IOException {
+ return JacksonUtils.toObject(read(in));
+ }
+
}
Modified: avro/trunk/lang/java/avro/src/main/java/org/apache/avro/io/EncoderFactory.java
URL: http://svn.apache.org/viewvc/avro/trunk/lang/java/avro/src/main/java/org/apache/avro/io/EncoderFactory.java?rev=1640293&r1=1640292&r2=1640293&view=diff
==============================================================================
--- avro/trunk/lang/java/avro/src/main/java/org/apache/avro/io/EncoderFactory.java (original)
+++ avro/trunk/lang/java/avro/src/main/java/org/apache/avro/io/EncoderFactory.java Tue Nov 18 09:58:21 2014
@@ -320,7 +320,9 @@ public class EncoderFactory {
* The JsonGenerator to write with. Cannot be null.
* @return A JsonEncoder configured with <i>gen</i> and <i>schema</i>
* @throws IOException
+ * @deprecated internal method
*/
+ @Deprecated
public JsonEncoder jsonEncoder(Schema schema, JsonGenerator gen)
throws IOException {
return new JsonEncoder(schema, gen);
Modified: avro/trunk/lang/java/avro/src/main/java/org/apache/avro/io/JsonEncoder.java
URL: http://svn.apache.org/viewvc/avro/trunk/lang/java/avro/src/main/java/org/apache/avro/io/JsonEncoder.java?rev=1640293&r1=1640292&r2=1640293&view=diff
==============================================================================
--- avro/trunk/lang/java/avro/src/main/java/org/apache/avro/io/JsonEncoder.java (original)
+++ avro/trunk/lang/java/avro/src/main/java/org/apache/avro/io/JsonEncoder.java Tue Nov 18 09:58:21 2014
@@ -131,7 +131,9 @@ public class JsonEncoder extends Parsing
* The JsonGenerator to direct output to. Cannot be null.
* @throws IOException
* @return this JsonEncoder
+ * @deprecated internal method
*/
+ @Deprecated
public JsonEncoder configure(JsonGenerator generator) throws IOException {
if (null == generator)
throw new NullPointerException("JsonGenerator cannot be null");
Modified: avro/trunk/lang/java/avro/src/main/java/org/apache/avro/io/parsing/ResolvingGrammarGenerator.java
URL: http://svn.apache.org/viewvc/avro/trunk/lang/java/avro/src/main/java/org/apache/avro/io/parsing/ResolvingGrammarGenerator.java?rev=1640293&r1=1640292&r2=1640293&view=diff
==============================================================================
--- avro/trunk/lang/java/avro/src/main/java/org/apache/avro/io/parsing/ResolvingGrammarGenerator.java (original)
+++ avro/trunk/lang/java/avro/src/main/java/org/apache/avro/io/parsing/ResolvingGrammarGenerator.java Tue Nov 18 09:58:21 2014
@@ -316,8 +316,9 @@ public class ResolvingGrammarGenerator e
* @param s The schema for the object being encoded.
* @param n The Json node to encode.
* @throws IOException
+ * @deprecated internal method
*/
-
+ @Deprecated
public static void encode(Encoder e, Schema s, JsonNode n)
throws IOException {
switch (s.getType()) {
Added: avro/trunk/lang/java/avro/src/main/java/org/apache/avro/util/internal/JacksonUtils.java
URL: http://svn.apache.org/viewvc/avro/trunk/lang/java/avro/src/main/java/org/apache/avro/util/internal/JacksonUtils.java?rev=1640293&view=auto
==============================================================================
--- avro/trunk/lang/java/avro/src/main/java/org/apache/avro/util/internal/JacksonUtils.java (added)
+++ avro/trunk/lang/java/avro/src/main/java/org/apache/avro/util/internal/JacksonUtils.java Tue Nov 18 09:58:21 2014
@@ -0,0 +1,136 @@
+package org.apache.avro.util.internal;
+
+import java.io.IOException;
+import java.io.UnsupportedEncodingException;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Iterator;
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Map;
+import org.apache.avro.AvroRuntimeException;
+import org.apache.avro.JsonProperties;
+import org.apache.avro.Schema;
+import org.codehaus.jackson.JsonGenerator;
+import org.codehaus.jackson.JsonNode;
+import org.codehaus.jackson.map.ObjectMapper;
+import org.codehaus.jackson.util.TokenBuffer;
+
+public class JacksonUtils {
+ static final String BYTES_CHARSET = "ISO-8859-1";
+
+ private JacksonUtils() {
+ }
+
+ public static JsonNode toJsonNode(Object datum) {
+ if (datum == null) {
+ return null;
+ }
+ try {
+ TokenBuffer generator = new TokenBuffer(new ObjectMapper());
+ toJson(datum, generator);
+ return new ObjectMapper().readTree(generator.asParser());
+ } catch (IOException e) {
+ throw new AvroRuntimeException(e);
+ }
+ }
+
+ @SuppressWarnings(value="unchecked")
+ static void toJson(Object datum, JsonGenerator generator) throws IOException {
+ if (datum == JsonProperties.NULL_VALUE) { // null
+ generator.writeNull();
+ } else if (datum instanceof Map) { // record, map
+ generator.writeStartObject();
+ for (Map.Entry<Object,Object> entry : ((Map<Object,Object>) datum).entrySet()) {
+ generator.writeFieldName(entry.getKey().toString());
+ toJson(entry.getValue(), generator);
+ }
+ generator.writeEndObject();
+ } else if (datum instanceof Collection) { // array
+ generator.writeStartArray();
+ for (Object element : (Collection<?>) datum) {
+ toJson(element, generator);
+ }
+ generator.writeEndArray();
+ } else if (datum instanceof byte[]) { // bytes, fixed
+ generator.writeString(new String((byte[]) datum, BYTES_CHARSET));
+ } else if (datum instanceof CharSequence || datum instanceof Enum<?>) { // string, enum
+ generator.writeString(datum.toString());
+ } else if (datum instanceof Double) { // double
+ generator.writeNumber((Double) datum);
+ } else if (datum instanceof Float) { // float
+ generator.writeNumber((Float) datum);
+ } else if (datum instanceof Long) { // long
+ generator.writeNumber((Long) datum);
+ } else if (datum instanceof Integer) { // int
+ generator.writeNumber((Integer) datum);
+ } else if (datum instanceof Boolean) { // boolean
+ generator.writeBoolean((Boolean) datum);
+ }
+ }
+
+ public static Object toObject(JsonNode jsonNode) {
+ return toObject(jsonNode, null);
+ }
+
+ public static Object toObject(JsonNode jsonNode, Schema schema) {
+ if (schema != null && schema.getType().equals(Schema.Type.UNION)) {
+ return toObject(jsonNode, schema.getTypes().get(0));
+ }
+ if (jsonNode == null) {
+ return null;
+ } else if (jsonNode.isNull()) {
+ return JsonProperties.NULL_VALUE;
+ } else if (jsonNode.isBoolean()) {
+ return jsonNode.asBoolean();
+ } else if (jsonNode.isInt()) {
+ if (schema == null || schema.getType().equals(Schema.Type.INT)) {
+ return jsonNode.asInt();
+ } else if (schema.getType().equals(Schema.Type.LONG)) {
+ return jsonNode.asLong();
+ }
+ } else if (jsonNode.isLong()) {
+ return jsonNode.asLong();
+ } else if (jsonNode.isDouble()) {
+ if (schema == null || schema.getType().equals(Schema.Type.DOUBLE)) {
+ return jsonNode.asDouble();
+ } else if (schema.getType().equals(Schema.Type.FLOAT)) {
+ return (float) jsonNode.asDouble();
+ }
+ } else if (jsonNode.isTextual()) {
+ if (schema == null || schema.getType().equals(Schema.Type.STRING) ||
+ schema.getType().equals(Schema.Type.ENUM)) {
+ return jsonNode.asText();
+ } else if (schema.getType().equals(Schema.Type.BYTES)) {
+ try {
+ return jsonNode.getTextValue().getBytes(BYTES_CHARSET);
+ } catch (UnsupportedEncodingException e) {
+ throw new AvroRuntimeException(e);
+ }
+ }
+ } else if (jsonNode.isArray()) {
+ List l = new ArrayList();
+ for (JsonNode node : jsonNode) {
+ l.add(toObject(node, schema == null ? null : schema.getElementType()));
+ }
+ return l;
+ } else if (jsonNode.isObject()) {
+ Map m = new LinkedHashMap();
+ for (Iterator<String> it = jsonNode.getFieldNames(); it.hasNext(); ) {
+ String key = it.next();
+ Schema s = null;
+ if (schema == null) {
+ s = null;
+ } else if (schema.getType().equals(Schema.Type.MAP)) {
+ s = schema.getValueType();
+ } else if (schema.getType().equals(Schema.Type.RECORD)) {
+ s = schema.getField(key).schema();
+ }
+ Object value = toObject(jsonNode.get(key), s);
+ m.put(key, value);
+ }
+ return m;
+ }
+ return null;
+ }
+}
Modified: avro/trunk/lang/java/avro/src/test/java/org/apache/avro/TestSchemaBuilder.java
URL: http://svn.apache.org/viewvc/avro/trunk/lang/java/avro/src/test/java/org/apache/avro/TestSchemaBuilder.java?rev=1640293&r1=1640292&r2=1640293&view=diff
==============================================================================
--- avro/trunk/lang/java/avro/src/test/java/org/apache/avro/TestSchemaBuilder.java (original)
+++ avro/trunk/lang/java/avro/src/test/java/org/apache/avro/TestSchemaBuilder.java Tue Nov 18 09:58:21 2014
@@ -33,7 +33,6 @@ import org.apache.avro.generic.GenericDa
import org.apache.avro.generic.GenericDatumReader;
import org.apache.avro.generic.GenericDatumWriter;
import org.apache.avro.generic.GenericRecordBuilder;
-import org.codehaus.jackson.node.BooleanNode;
import org.codehaus.jackson.node.NullNode;
import org.junit.Assert;
import org.junit.Test;
@@ -70,7 +69,7 @@ public class TestSchemaBuilder {
types.add(Schema.create(Schema.Type.BOOLEAN));
types.add(Schema.create(Schema.Type.NULL));
Schema optional = Schema.createUnion(types);
- Assert.assertEquals(new Schema.Field("f2", optional, null, BooleanNode.getTrue()),
+ Assert.assertEquals(new Schema.Field("f2", optional, null, true),
fields.get(2));
}
Modified: avro/trunk/lang/java/avro/src/test/java/org/apache/avro/TestSchemaCompatibility.java
URL: http://svn.apache.org/viewvc/avro/trunk/lang/java/avro/src/test/java/org/apache/avro/TestSchemaCompatibility.java?rev=1640293&r1=1640292&r2=1640293&view=diff
==============================================================================
--- avro/trunk/lang/java/avro/src/test/java/org/apache/avro/TestSchemaCompatibility.java (original)
+++ avro/trunk/lang/java/avro/src/test/java/org/apache/avro/TestSchemaCompatibility.java Tue Nov 18 09:58:21 2014
@@ -38,7 +38,6 @@ import org.apache.avro.io.DecoderFactory
import org.apache.avro.io.Encoder;
import org.apache.avro.io.EncoderFactory;
import org.apache.avro.util.Utf8;
-import org.codehaus.jackson.node.IntNode;
import org.junit.Test;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -118,13 +117,13 @@ public class TestSchemaCompatibility {
new Field("a", INT_SCHEMA, null, null),
new Field("b", INT_SCHEMA, null, null)));
A_DINT_RECORD1.setFields(list(
- new Field("a", INT_SCHEMA, null, new IntNode(0))));
+ new Field("a", INT_SCHEMA, null, 0)));
A_INT_B_DINT_RECORD1.setFields(list(
new Field("a", INT_SCHEMA, null, null),
- new Field("b", INT_SCHEMA, null, new IntNode(0))));
+ new Field("b", INT_SCHEMA, null, 0)));
A_DINT_B_DINT_RECORD1.setFields(list(
- new Field("a", INT_SCHEMA, null, new IntNode(0)),
- new Field("b", INT_SCHEMA, null, new IntNode(0))));
+ new Field("a", INT_SCHEMA, null, 0),
+ new Field("b", INT_SCHEMA, null, 0)));
}
// Recursive records
@@ -221,7 +220,7 @@ public class TestSchemaCompatibility {
public void testValidateSchemaNewFieldWithDefault() throws Exception {
final List<Schema.Field> readerFields = list(
new Schema.Field("oldfield1", INT_SCHEMA, null, null),
- new Schema.Field("newfield1", INT_SCHEMA, null, IntNode.valueOf(42)));
+ new Schema.Field("newfield1", INT_SCHEMA, null, 42));
final Schema reader = Schema.createRecord(readerFields);
final SchemaCompatibility.SchemaPairCompatibility expectedResult =
new SchemaCompatibility.SchemaPairCompatibility(
Modified: avro/trunk/lang/java/avro/src/test/java/org/apache/avro/generic/TestGenericRecordBuilder.java
URL: http://svn.apache.org/viewvc/avro/trunk/lang/java/avro/src/test/java/org/apache/avro/generic/TestGenericRecordBuilder.java?rev=1640293&r1=1640292&r2=1640293&view=diff
==============================================================================
--- avro/trunk/lang/java/avro/src/test/java/org/apache/avro/generic/TestGenericRecordBuilder.java (original)
+++ avro/trunk/lang/java/avro/src/test/java/org/apache/avro/generic/TestGenericRecordBuilder.java Tue Nov 18 09:58:21 2014
@@ -26,8 +26,6 @@ import org.apache.avro.Schema;
import org.apache.avro.Schema.Field;
import org.apache.avro.Schema.Type;
import org.apache.avro.generic.GenericData.Record;
-import org.codehaus.jackson.node.TextNode;
-import org.codehaus.jackson.node.NullNode;
import org.junit.Assert;
import org.junit.Test;
@@ -100,13 +98,13 @@ public class TestGenericRecordBuilder {
/** Creates a test record schema */
private static Schema recordSchema() {
List<Field> fields = new ArrayList<Field>();
- fields.add(new Field("id", Schema.create(Type.STRING), null, new TextNode("0")));
+ fields.add(new Field("id", Schema.create(Type.STRING), null, "0"));
fields.add(new Field("intField", Schema.create(Type.INT), null, null));
fields.add(new Field("anArray", Schema.createArray(Schema.create(Type.STRING)), null, null));
fields.add(new Field("optionalInt", Schema.createUnion
(Arrays.asList(Schema.create(Type.NULL),
Schema.create(Type.INT))),
- null, NullNode.getInstance()));
+ null, Schema.NULL_VALUE));
Schema schema = Schema.createRecord("Foo", "test", "mytest", false);
schema.setFields(fields);
return schema;
Added: avro/trunk/lang/java/avro/src/test/java/org/apache/avro/util/internal/TestJacksonUtils.java
URL: http://svn.apache.org/viewvc/avro/trunk/lang/java/avro/src/test/java/org/apache/avro/util/internal/TestJacksonUtils.java?rev=1640293&view=auto
==============================================================================
--- avro/trunk/lang/java/avro/src/test/java/org/apache/avro/util/internal/TestJacksonUtils.java (added)
+++ avro/trunk/lang/java/avro/src/test/java/org/apache/avro/util/internal/TestJacksonUtils.java Tue Nov 18 09:58:21 2014
@@ -0,0 +1,84 @@
+package org.apache.avro.util.internal;
+
+import java.util.Collections;
+import org.apache.avro.JsonProperties;
+import org.apache.avro.Schema;
+import org.apache.avro.SchemaBuilder;
+import org.codehaus.jackson.node.ArrayNode;
+import org.codehaus.jackson.node.BooleanNode;
+import org.codehaus.jackson.node.DoubleNode;
+import org.codehaus.jackson.node.IntNode;
+import org.codehaus.jackson.node.JsonNodeFactory;
+import org.codehaus.jackson.node.LongNode;
+import org.codehaus.jackson.node.NullNode;
+import org.codehaus.jackson.node.ObjectNode;
+import org.codehaus.jackson.node.TextNode;
+import org.junit.Test;
+
+import static org.apache.avro.util.internal.JacksonUtils.toJsonNode;
+import static org.apache.avro.util.internal.JacksonUtils.toObject;
+import static org.junit.Assert.assertArrayEquals;
+import static org.junit.Assert.assertEquals;
+
+public class TestJacksonUtils {
+
+ enum Direction {
+ UP, DOWN;
+ }
+
+ @Test
+ public void testToJsonNode() {
+ assertEquals(null, toJsonNode(null));
+ assertEquals(NullNode.getInstance(), toJsonNode(JsonProperties.NULL_VALUE));
+ assertEquals(BooleanNode.TRUE, toJsonNode(true));
+ assertEquals(IntNode.valueOf(1), toJsonNode(1));
+ assertEquals(LongNode.valueOf(2), toJsonNode(2L));
+ assertEquals(DoubleNode.valueOf(1.0), toJsonNode(1.0f));
+ assertEquals(DoubleNode.valueOf(2.0), toJsonNode(2.0));
+ assertEquals(TextNode.valueOf("\u0001\u0002"), toJsonNode(new byte[] { 1, 2 }));
+ assertEquals(TextNode.valueOf("a"), toJsonNode("a"));
+ assertEquals(TextNode.valueOf("UP"), toJsonNode(Direction.UP));
+
+ ArrayNode an = JsonNodeFactory.instance.arrayNode();
+ an.add(1);
+ assertEquals(an, toJsonNode(Collections.singletonList(1)));
+
+ ObjectNode on = JsonNodeFactory.instance.objectNode();
+ on.put("a", 1);
+ assertEquals(on, toJsonNode(Collections.singletonMap("a", 1)));
+ }
+
+ @Test
+ public void testToObject() {
+ assertEquals(null, toObject(null));
+ assertEquals(JsonProperties.NULL_VALUE, toObject(NullNode.getInstance()));
+ assertEquals(true, toObject(BooleanNode.TRUE));
+ assertEquals(1, toObject(IntNode.valueOf(1)));
+ assertEquals(2L, toObject(IntNode.valueOf(2), Schema.create(Schema.Type.LONG)));
+ assertEquals(1.0f, toObject(DoubleNode.valueOf(1.0), Schema.create(Schema.Type.FLOAT)));
+ assertEquals(2.0, toObject(DoubleNode.valueOf(2.0)));
+ assertEquals(TextNode.valueOf("\u0001\u0002"), toJsonNode(new byte[]{1, 2}));
+ assertArrayEquals(new byte[]{1, 2},
+ (byte[]) toObject(TextNode.valueOf("\u0001\u0002"), Schema.create(Schema.Type.BYTES)));
+ assertEquals("a", toObject(TextNode.valueOf("a")));
+ assertEquals("UP", toObject(TextNode.valueOf("UP"),
+ SchemaBuilder.enumeration("Direction").symbols("UP", "DOWN")));
+
+ ArrayNode an = JsonNodeFactory.instance.arrayNode();
+ an.add(1);
+ assertEquals(Collections.singletonList(1), toObject(an));
+
+ ObjectNode on = JsonNodeFactory.instance.objectNode();
+ on.put("a", 1);
+ assertEquals(Collections.singletonMap("a", 1), toObject(on));
+ assertEquals(Collections.singletonMap("a", 1L), toObject(on,
+ SchemaBuilder.record("r").fields().requiredLong("a").endRecord()));
+
+ assertEquals(JsonProperties.NULL_VALUE, toObject(NullNode.getInstance(),
+ SchemaBuilder.unionOf().nullType().and().intType().endUnion()));
+
+ assertEquals("a", toObject(TextNode.valueOf("a"),
+ SchemaBuilder.unionOf().stringType().and().intType().endUnion()));
+ }
+
+}
Modified: avro/trunk/lang/java/ipc/src/test/java/org/apache/avro/TestProtocolGeneric.java
URL: http://svn.apache.org/viewvc/avro/trunk/lang/java/ipc/src/test/java/org/apache/avro/TestProtocolGeneric.java?rev=1640293&r1=1640292&r2=1640293&view=diff
==============================================================================
--- avro/trunk/lang/java/ipc/src/test/java/org/apache/avro/TestProtocolGeneric.java (original)
+++ avro/trunk/lang/java/ipc/src/test/java/org/apache/avro/TestProtocolGeneric.java Tue Nov 18 09:58:21 2014
@@ -44,8 +44,6 @@ import java.util.ArrayList;
import java.util.List;
import java.util.Random;
-import org.codehaus.jackson.node.BooleanNode;
-
public class TestProtocolGeneric {
private static final Logger LOG
= LoggerFactory.getLogger(TestProtocolGeneric.class);
@@ -222,7 +220,7 @@ public class TestProtocolGeneric {
for (Field f : PROTOCOL.getType("TestRecord").getFields())
fields.add(new Field(f.name(), f.schema(), null, null));
fields.add(new Field("extra", Schema.create(Schema.Type.BOOLEAN),
- null, BooleanNode.TRUE));
+ null, true));
Schema record =
Schema.createRecord("TestRecord", null, "org.apache.avro.test", false);
record.setFields(fields);
Modified: avro/trunk/lang/java/ipc/src/test/java/org/apache/avro/TestSchema.java
URL: http://svn.apache.org/viewvc/avro/trunk/lang/java/ipc/src/test/java/org/apache/avro/TestSchema.java?rev=1640293&r1=1640292&r2=1640293&view=diff
==============================================================================
--- avro/trunk/lang/java/ipc/src/test/java/org/apache/avro/TestSchema.java (original)
+++ avro/trunk/lang/java/ipc/src/test/java/org/apache/avro/TestSchema.java Tue Nov 18 09:58:21 2014
@@ -819,21 +819,21 @@ public class TestSchema {
}
public static void checkBinaryJson(String json) throws Exception {
- JsonNode node = Schema.parseJson(json);
+ Object node = Json.parseJson(json);
ByteArrayOutputStream out = new ByteArrayOutputStream();
- DatumWriter<JsonNode> writer = new Json.Writer();
+ DatumWriter<Object> writer = new Json.ObjectWriter();
Encoder encoder = EncoderFactory.get().binaryEncoder(out, null);
encoder = EncoderFactory.get().validatingEncoder(Json.SCHEMA, encoder);
writer.write(node, encoder);
encoder.flush();
byte[] bytes = out.toByteArray();
- DatumReader<JsonNode> reader = new Json.Reader();
+ DatumReader<Object> reader = new Json.ObjectReader();
Decoder decoder = DecoderFactory.get().binaryDecoder(bytes, null);
decoder = DecoderFactory.get().validatingDecoder(Json.SCHEMA, decoder);
- JsonNode decoded = reader.read(null, decoder);
+ Object decoded = reader.read(null, decoder);
- assertEquals("Decoded json does not match.", node.toString(), decoded.toString());
+ assertEquals("Decoded json does not match.", Json.toString(node), Json.toString(decoded));
}
private static final Schema ACTUAL = // an empty record schema
Modified: avro/trunk/lang/java/mapred/src/test/java/org/apache/avro/mapred/TestGenericJob.java
URL: http://svn.apache.org/viewvc/avro/trunk/lang/java/mapred/src/test/java/org/apache/avro/mapred/TestGenericJob.java?rev=1640293&r1=1640292&r2=1640293&view=diff
==============================================================================
--- avro/trunk/lang/java/mapred/src/test/java/org/apache/avro/mapred/TestGenericJob.java (original)
+++ avro/trunk/lang/java/mapred/src/test/java/org/apache/avro/mapred/TestGenericJob.java Tue Nov 18 09:58:21 2014
@@ -47,7 +47,6 @@ import org.apache.hadoop.mapred.Mapper;
import org.apache.hadoop.mapred.OutputCollector;
import org.apache.hadoop.mapred.Reporter;
import org.apache.hadoop.mapred.TextInputFormat;
-import org.codehaus.jackson.node.JsonNodeFactory;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
@@ -61,8 +60,7 @@ public class TestGenericJob {
List<Field> fields = new ArrayList<Schema.Field>();
- fields.add(new Field("Optional", createArraySchema(), "",
- JsonNodeFactory.instance.arrayNode()));
+ fields.add(new Field("Optional", createArraySchema(), "", new ArrayList<Object>()));
Schema recordSchema =
Schema.createRecord("Container", "", "org.apache.avro.mapred", false);
@@ -83,8 +81,7 @@ public class TestGenericJob {
private static Schema createInnerSchema(String name) {
Schema innerrecord = Schema.createRecord(name, "", "", false);
innerrecord.setFields
- (Arrays.asList(new Field(name, Schema.create(Type.LONG), "",
- JsonNodeFactory.instance.numberNode(0l))));
+ (Arrays.asList(new Field(name, Schema.create(Type.LONG), "", 0L)));
return innerrecord;
}
Modified: avro/trunk/lang/java/pom.xml
URL: http://svn.apache.org/viewvc/avro/trunk/lang/java/pom.xml?rev=1640293&r1=1640292&r2=1640293&view=diff
==============================================================================
--- avro/trunk/lang/java/pom.xml (original)
+++ avro/trunk/lang/java/pom.xml Tue Nov 18 09:58:21 2014
@@ -265,6 +265,7 @@
<version>${plugin-tools-javadoc.version}</version>
</tagletArtifact>
</tagletArtifacts>
+ <excludePackageNames>org.apache.avro.compiler.idl,*.internal</excludePackageNames>
</configuration>
</plugin>
<plugin>
Modified: avro/trunk/lang/java/tools/src/main/java/org/apache/avro/tool/RpcReceiveTool.java
URL: http://svn.apache.org/viewvc/avro/trunk/lang/java/tools/src/main/java/org/apache/avro/tool/RpcReceiveTool.java?rev=1640293&r1=1640292&r2=1640293&view=diff
==============================================================================
--- avro/trunk/lang/java/tools/src/main/java/org/apache/avro/tool/RpcReceiveTool.java (original)
+++ avro/trunk/lang/java/tools/src/main/java/org/apache/avro/tool/RpcReceiveTool.java Tue Nov 18 09:58:21 2014
@@ -38,9 +38,6 @@ import org.apache.avro.io.JsonEncoder;
import org.apache.avro.ipc.Ipc;
import org.apache.avro.ipc.Server;
import org.apache.avro.ipc.generic.GenericResponder;
-import org.codehaus.jackson.JsonEncoding;
-import org.codehaus.jackson.JsonFactory;
-import org.codehaus.jackson.JsonGenerator;
/**
* Receives one RPC call and responds. (The moral equivalent
@@ -82,14 +79,11 @@ public class RpcReceiveTool implements T
out.print(message.getName());
out.print("\t");
try {
- JsonGenerator jsonGenerator = new JsonFactory().createJsonGenerator(
- out, JsonEncoding.UTF8);
- JsonEncoder jsonEncoder = EncoderFactory.get().jsonEncoder(message.getRequest(), jsonGenerator);
-
+ JsonEncoder jsonEncoder = EncoderFactory.get().jsonEncoder(message.getRequest(),
+ out);
GenericDatumWriter<Object> writer = new GenericDatumWriter<Object>(
message.getRequest());
writer.write(request, jsonEncoder);
- jsonGenerator.flush();
jsonEncoder.flush();
out.flush();
} catch (IOException e) {