Author: cutting
Date: Fri Aug 12 20:47:23 2011
New Revision: 1157245
URL: http://svn.apache.org/viewvc?rev=1157245&view=rev
Log:
AVRO-874. Java: Improved Schema parsing API and permit IDL imports to depend on
names defined in prior imports.
Added:
avro/trunk/lang/java/compiler/src/test/idl/input/baseball.avdl
avro/trunk/lang/java/compiler/src/test/idl/input/player.avsc
avro/trunk/lang/java/compiler/src/test/idl/input/position.avsc
avro/trunk/lang/java/compiler/src/test/idl/output/baseball.avpr
Modified:
avro/trunk/CHANGES.txt
avro/trunk/lang/java/avro/src/main/java/org/apache/avro/Schema.java
avro/trunk/lang/java/compiler/src/main/javacc/org/apache/avro/compiler/idl/idl.jj
Modified: avro/trunk/CHANGES.txt
URL:
http://svn.apache.org/viewvc/avro/trunk/CHANGES.txt?rev=1157245&r1=1157244&r2=1157245&view=diff
==============================================================================
--- avro/trunk/CHANGES.txt (original)
+++ avro/trunk/CHANGES.txt Fri Aug 12 20:47:23 2011
@@ -35,6 +35,9 @@ Avro 1.6.0 (unreleased)
AVRO-873. Java: Permit passing classloader to SpecificDatumReader.
(Michael Armbrust via cutting)
+ AVRO-874. Java: Improved Schema parsing API and permit IDL imports
+ to depend on names defined in prior imports. (cutting)
+
BUG FIXES
AVRO-824. Java: Fix usage message of BinaryFragmentToJsonTool.
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=1157245&r1=1157244&r2=1157245&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 Fri Aug
12 20:47:23 2011
@@ -874,6 +874,73 @@ public abstract class Schema {
public NullSchema() { super(Type.NULL); }
}
+ /** A parser for JSON-format schemas. Each named schema parsed with a parser
+ * is added to the names known to the parser so that subsequently parsed
+ * schemas may refer to it by name. */
+ public static class Parser {
+ private Names names = new Names();
+ private boolean validate = true;
+
+ /** Adds the provided types to the set of defined, named types known to
+ * this parser. */
+ public Parser addTypes(Map<String,Schema> types) {
+ for (Schema s : types.values())
+ names.add(s);
+ return this;
+ }
+
+ /** Returns the set of defined, named types known to this parser. */
+ public Map<String,Schema> getTypes() {
+ Map<String,Schema> result = new LinkedHashMap<String,Schema>();
+ for (Schema s : names.values())
+ result.put(s.getFullName(), s);
+ return result;
+ }
+
+ /** Enable or disable name validation. */
+ public Parser setValidate(boolean validate) {
+ this.validate = validate;
+ return this;
+ }
+
+ /** True iff names are validated. True by default. */
+ public boolean getValidate() { return this.validate; }
+
+ /** Parse a schema from the provided file.
+ * If named, the schema is added to the names known to this parser. */
+ public Schema parse(File file) throws IOException {
+ return parse(FACTORY.createJsonParser(file));
+ }
+
+ /** Parse a schema from the provided stream.
+ * If named, the schema is added to the names known to this parser. */
+ public Schema parse(InputStream in) throws IOException {
+ return parse(FACTORY.createJsonParser(in));
+ }
+
+ /** Parse a schema from the provided string.
+ * If named, the schema is added to the names known to this parser. */
+ public Schema parse(String s) {
+ try {
+ return parse(FACTORY.createJsonParser(new StringReader(s)));
+ } catch (IOException e) {
+ throw new SchemaParseException(e);
+ }
+ }
+
+ private Schema parse(JsonParser parser) throws IOException {
+ boolean saved = validateNames.get();
+ try {
+ validateNames.set(validate);
+ return Schema.parse(MAPPER.readTree(parser), names);
+ } catch (JsonParseException e) {
+ throw new SchemaParseException(e);
+ } finally {
+ validateNames.set(saved);
+ }
+ }
+ }
+
/**
* Constructs a Schema object from JSON schema file <tt>file</tt>.
* The contents of <tt>file</tt> is expected to be in UTF-8 format.
@@ -881,14 +948,10 @@ public abstract class Schema {
* @return The freshly built Schema.
* @throws IOException if there was trouble reading the contents
* @throws JsonParseException if the contents are invalid
+ * @deprecated use {@link Schema.Parser} instead.
*/
public static Schema parse(File file) throws IOException {
- JsonParser parser = FACTORY.createJsonParser(file);
- try {
- return Schema.parse(MAPPER.readTree(parser), new Names());
- } catch (JsonParseException e) {
- throw new SchemaParseException(e);
- }
+ return new Parser().parse(file);
}
/**
@@ -898,32 +961,25 @@ public abstract class Schema {
* @return The freshly built Schema.
* @throws IOException if there was trouble reading the contents
* @throws JsonParseException if the contents are invalid
+ * @deprecated use {@link Schema.Parser} instead.
*/
public static Schema parse(InputStream in) throws IOException {
- JsonParser parser = FACTORY.createJsonParser(in);
- try {
- return Schema.parse(MAPPER.readTree(parser), new Names());
- } catch (JsonParseException e) {
- throw new SchemaParseException(e);
- }
+ return new Parser().parse(in);
}
- /** Construct a schema from <a href="http://json.org/">JSON</a> text. */
+ /** Construct a schema from <a href="http://json.org/">JSON</a> text.
+ * @deprecated use {@link Schema.Parser} instead.
+ */
public static Schema parse(String jsonSchema) {
- return parse(parseJson(jsonSchema), new Names());
+ return new Parser().parse(jsonSchema);
}
/** Construct a schema from <a href="http://json.org/">JSON</a> text.
* @param validate true if names should be validated, false if not.
+ * @deprecated use {@link Schema.Parser} instead.
*/
public static Schema parse(String jsonSchema, boolean validate) {
- boolean saved = validateNames.get();
- try {
- validateNames.set(validate);
- return parse(jsonSchema);
- } finally {
- validateNames.set(saved);
- }
+ return new Parser().setValidate(validate).parse(jsonSchema);
}
static final Map<String,Type> PRIMITIVES = new HashMap<String,Type>();
Modified:
avro/trunk/lang/java/compiler/src/main/javacc/org/apache/avro/compiler/idl/idl.jj
URL:
http://svn.apache.org/viewvc/avro/trunk/lang/java/compiler/src/main/javacc/org/apache/avro/compiler/idl/idl.jj?rev=1157245&r1=1157244&r2=1157245&view=diff
==============================================================================
---
avro/trunk/lang/java/compiler/src/main/javacc/org/apache/avro/compiler/idl/idl.jj
(original)
+++
avro/trunk/lang/java/compiler/src/main/javacc/org/apache/avro/compiler/idl/idl.jj
Fri Aug 12 20:47:23 2011
@@ -1110,9 +1110,8 @@ void ProtocolBody(Protocol p):
names.put(s.getFullName(), s);
p.getMessages().putAll(importProtocol.getMessages());
})
- | schema = ImportSchema() {
- names.put(schema.getFullName(), schema);
- })
+ | schema = ImportSchema()
+ )
| message = MessageDeclaration(p) {
p.getMessages().put(message.getName(), message);
@@ -1162,7 +1161,11 @@ Schema ImportSchema() : {
<SCHEMA> importFile = JsonString() ";"
{
try {
- return Schema.parse(new File(inputDir, importFile));
+ Parser parser = new Schema.Parser();
+ parser.addTypes(names); // inherit names
+ Schema value = parser.parse(new File(inputDir, importFile));
+ names = parser.getTypes(); // update names
+ return value;
} catch (IOException e) {
throw error("Error importing "+importFile+": "+e, token);
}
Added: avro/trunk/lang/java/compiler/src/test/idl/input/baseball.avdl
URL:
http://svn.apache.org/viewvc/avro/trunk/lang/java/compiler/src/test/idl/input/baseball.avdl?rev=1157245&view=auto
==============================================================================
--- avro/trunk/lang/java/compiler/src/test/idl/input/baseball.avdl (added)
+++ avro/trunk/lang/java/compiler/src/test/idl/input/baseball.avdl Fri Aug 12
20:47:23 2011
@@ -0,0 +1,5 @@
+@namespace("avro.examples.baseball")
+protocol Baseball {
+ import schema "position.avsc";
+ import schema "player.avsc";
+}
Added: avro/trunk/lang/java/compiler/src/test/idl/input/player.avsc
URL:
http://svn.apache.org/viewvc/avro/trunk/lang/java/compiler/src/test/idl/input/player.avsc?rev=1157245&view=auto
==============================================================================
--- avro/trunk/lang/java/compiler/src/test/idl/input/player.avsc (added)
+++ avro/trunk/lang/java/compiler/src/test/idl/input/player.avsc Fri Aug 12
20:47:23 2011
@@ -0,0 +1,8 @@
+{"type":"record", "name":"Player", "namespace": "avro.examples.baseball",
+ "fields": [
+ {"name": "number", "type": "int"},
+ {"name": "first_name", "type": "string"},
+ {"name": "last_name", "type": "string"},
+ {"name": "position", "type": {"type": "array", "items": "Position"} }
+ ]
+}
Added: avro/trunk/lang/java/compiler/src/test/idl/input/position.avsc
URL:
http://svn.apache.org/viewvc/avro/trunk/lang/java/compiler/src/test/idl/input/position.avsc?rev=1157245&view=auto
==============================================================================
--- avro/trunk/lang/java/compiler/src/test/idl/input/position.avsc (added)
+++ avro/trunk/lang/java/compiler/src/test/idl/input/position.avsc Fri Aug 12
20:47:23 2011
@@ -0,0 +1,3 @@
+{"type":"enum", "name": "Position", "namespace": "avro.examples.baseball",
+ "symbols": ["P", "C", "B1", "B2", "B3", "SS", "LF", "CF", "RF", "DH"]
+}
Added: avro/trunk/lang/java/compiler/src/test/idl/output/baseball.avpr
URL:
http://svn.apache.org/viewvc/avro/trunk/lang/java/compiler/src/test/idl/output/baseball.avpr?rev=1157245&view=auto
==============================================================================
--- avro/trunk/lang/java/compiler/src/test/idl/output/baseball.avpr (added)
+++ avro/trunk/lang/java/compiler/src/test/idl/output/baseball.avpr Fri Aug 12
20:47:23 2011
@@ -0,0 +1,30 @@
+{
+ "protocol" : "Baseball",
+ "namespace" : "avro.examples.baseball",
+ "types" : [ {
+ "type" : "enum",
+ "name" : "Position",
+ "symbols" : [ "P", "C", "B1", "B2", "B3", "SS", "LF", "CF", "RF", "DH" ]
+ }, {
+ "type" : "record",
+ "name" : "Player",
+ "fields" : [ {
+ "name" : "number",
+ "type" : "int"
+ }, {
+ "name" : "first_name",
+ "type" : "string"
+ }, {
+ "name" : "last_name",
+ "type" : "string"
+ }, {
+ "name" : "position",
+ "type" : {
+ "type" : "array",
+ "items" : "Position"
+ }
+ } ]
+ } ],
+ "messages" : {
+ }
+}