Added more tests and fixed a couple of bugs. Also formatted the code
Project: http://git-wip-us.apache.org/repos/asf/avro/repo Commit: http://git-wip-us.apache.org/repos/asf/avro/commit/91320154 Tree: http://git-wip-us.apache.org/repos/asf/avro/tree/91320154 Diff: http://git-wip-us.apache.org/repos/asf/avro/diff/91320154 Branch: refs/heads/master Commit: 9132015450a2ad6f56cd582b393e8f1b8df573c9 Parents: ce0bad5 Author: Thiruvalluvan M G <[email protected]> Authored: Sun Apr 30 21:02:02 2017 +0530 Committer: Thiruvalluvan M G <[email protected]> Committed: Sun Apr 30 23:31:29 2017 +0530 ---------------------------------------------------------------------- .../avro/compiler/idl/ResolvingVisitor.java | 1 - .../avro/compiler/idl/SchemaResolver.java | 27 +- .../avro/compiler/schema/CloningVisitor.java | 87 ++--- .../avro/compiler/schema/SchemaVisitor.java | 41 +-- .../compiler/schema/SchemaVisitorAction.java | 71 ++-- .../apache/avro/compiler/schema/Schemas.java | 47 +-- .../avro/compiler/idl/SchemaResolverTest.java | 44 --- .../org/apache/avro/compiler/idl/TestCycle.java | 6 +- .../avro/compiler/idl/TestSchemaResolver.java | 72 ++++ .../avro/compiler/schema/SchemasTest.java | 87 ----- .../avro/compiler/schema/TestSchemas.java | 347 +++++++++++++++++++ 11 files changed, 552 insertions(+), 278 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/avro/blob/91320154/lang/java/compiler/src/main/java/org/apache/avro/compiler/idl/ResolvingVisitor.java ---------------------------------------------------------------------- diff --git a/lang/java/compiler/src/main/java/org/apache/avro/compiler/idl/ResolvingVisitor.java b/lang/java/compiler/src/main/java/org/apache/avro/compiler/idl/ResolvingVisitor.java index e201598..35fb44b 100644 --- a/lang/java/compiler/src/main/java/org/apache/avro/compiler/idl/ResolvingVisitor.java +++ b/lang/java/compiler/src/main/java/org/apache/avro/compiler/idl/ResolvingVisitor.java @@ -16,7 +16,6 @@ import org.apache.avro.compiler.schema.Schemas; * this visitor will create a clone of the original Schema and will also resolve all unresolved schemas * * by default. what attributes are copied is customizable. - * @author zoly */ public final class ResolvingVisitor implements SchemaVisitor<Schema> { http://git-wip-us.apache.org/repos/asf/avro/blob/91320154/lang/java/compiler/src/main/java/org/apache/avro/compiler/idl/SchemaResolver.java ---------------------------------------------------------------------- diff --git a/lang/java/compiler/src/main/java/org/apache/avro/compiler/idl/SchemaResolver.java b/lang/java/compiler/src/main/java/org/apache/avro/compiler/idl/SchemaResolver.java index f456a18..596523c 100644 --- a/lang/java/compiler/src/main/java/org/apache/avro/compiler/idl/SchemaResolver.java +++ b/lang/java/compiler/src/main/java/org/apache/avro/compiler/idl/SchemaResolver.java @@ -16,12 +16,14 @@ package org.apache.avro.compiler.idl; import avro.shaded.com.google.common.base.Function; + import java.util.ArrayList; import java.util.Collection; import java.util.Collections; import java.util.IdentityHashMap; import java.util.List; import java.util.Map; + import org.apache.avro.Protocol; import org.apache.avro.Schema; import org.apache.avro.compiler.schema.Schemas; @@ -44,29 +46,32 @@ final class SchemaResolver { * Create a schema to represent a "unresolved" schema. * (used to represent a schema where the definition is not known at the time) * This concept might be generalizable... + * * @param name * @return */ static Schema unresolvedSchema(final String name) { Schema schema = Schema.createRecord(UR_SCHEMA_NAME, "unresolved schema", - UR_SCHEMA_NS, false, Collections.EMPTY_LIST); + UR_SCHEMA_NS, false, Collections.EMPTY_LIST); schema.addProp(UR_SCHEMA_ATTR, name); return schema; } /** * Is this a unresolved schema. + * * @param schema * @return */ static boolean isUnresolvedSchema(final Schema schema) { return (schema.getType() == Schema.Type.RECORD && schema.getProp(UR_SCHEMA_ATTR) != null - && UR_SCHEMA_NAME.equals(schema.getName()) - && UR_SCHEMA_NS.equals(schema.getNamespace())); + && UR_SCHEMA_NAME.equals(schema.getName()) + && UR_SCHEMA_NS.equals(schema.getNamespace())); } /** * get the unresolved schema name. + * * @param schema * @return */ @@ -74,16 +79,12 @@ final class SchemaResolver { if (!isUnresolvedSchema(schema)) { throw new IllegalArgumentException("Not a unresolved schema: " + schema); } - String name = schema.getProp(UR_SCHEMA_ATTR); - if (name == null) { - throw new IllegalArgumentException("Schema " + schema + " must have attribute: " + UR_SCHEMA_ATTR); - } else { - return name; - } + return schema.getProp(UR_SCHEMA_ATTR); } /** * Will clone the provided protocol while resolving all unreferenced schemas + * * @param protocol * @return */ @@ -105,13 +106,13 @@ final class SchemaResolver { if (value.isOneWay()) { Schema replacement = resolve(replacements, value.getRequest(), protocol); nvalue = result.createMessage(value.getName(), value.getDoc(), - value.getObjectProps(), replacement); + value.getObjectProps(), replacement); } else { Schema request = resolve(replacements, value.getRequest(), protocol); Schema response = resolve(replacements, value.getResponse(), protocol); Schema errors = resolve(replacements, value.getErrors(), protocol); nvalue = result.createMessage(value.getName(), value.getDoc(), - value.getObjectProps(), request, response, errors); + value.getObjectProps(), request, response, errors); } result.getMessages().put(entry.getKey(), nvalue); } @@ -120,11 +121,11 @@ final class SchemaResolver { } private static Schema resolve(final IdentityHashMap<Schema, Schema> replacements, - final Schema request, final Protocol protocol) { + final Schema request, final Protocol protocol) { Schema replacement = replacements.get(request); if (replacement == null) { replacement = Schemas.visit(request, new ResolvingVisitor(request, replacements, - new SymbolTable(protocol))); + new SymbolTable(protocol))); } return replacement; } http://git-wip-us.apache.org/repos/asf/avro/blob/91320154/lang/java/compiler/src/main/java/org/apache/avro/compiler/schema/CloningVisitor.java ---------------------------------------------------------------------- diff --git a/lang/java/compiler/src/main/java/org/apache/avro/compiler/schema/CloningVisitor.java b/lang/java/compiler/src/main/java/org/apache/avro/compiler/schema/CloningVisitor.java index 8c6423b..ccc222a 100644 --- a/lang/java/compiler/src/main/java/org/apache/avro/compiler/schema/CloningVisitor.java +++ b/lang/java/compiler/src/main/java/org/apache/avro/compiler/schema/CloningVisitor.java @@ -4,13 +4,14 @@ package org.apache.avro.compiler.schema; import java.util.ArrayList; import java.util.IdentityHashMap; import java.util.List; + import org.apache.avro.Schema; + import static org.apache.avro.Schema.Type.RECORD; /** * this visitor will create a clone of the original Schema with docs and other nonesential fields stripped * by default. what attributes are copied is customizable. - * @author zoly */ public final class CloningVisitor implements SchemaVisitor<Schema> { @@ -24,11 +25,13 @@ public final class CloningVisitor implements SchemaVisitor<Schema> { public interface PropertyCopier { void copy(Schema first, Schema second); + void copy(Schema.Field first, Schema.Field second); } /** * copy only serialization necessary fields. + * * @param root */ public CloningVisitor(final Schema root) { @@ -41,7 +44,7 @@ public final class CloningVisitor implements SchemaVisitor<Schema> { @Override public void copy(final Schema.Field first, final Schema.Field second) { - Schemas.copyAliases(first, second); + Schemas.copyAliases(first, second); } }, false, root); } @@ -74,14 +77,14 @@ public final class CloningVisitor implements SchemaVisitor<Schema> { case NULL: case STRING: newSchema = Schema.create(type); - break; + break; case ENUM: newSchema = Schema.createEnum(terminal.getName(), copyDocs ? terminal.getDoc() : null, - terminal.getNamespace(), terminal.getEnumSymbols()); + terminal.getNamespace(), terminal.getEnumSymbols()); break; case FIXED: newSchema = Schema.createFixed(terminal.getName(), copyDocs ? terminal.getDoc() : null, - terminal.getNamespace(), terminal.getFixedSize()); + terminal.getNamespace(), terminal.getFixedSize()); break; default: throw new IllegalStateException("Unsupported schema " + terminal); @@ -94,52 +97,52 @@ public final class CloningVisitor implements SchemaVisitor<Schema> { @Override public SchemaVisitorAction visitNonTerminal(final Schema nt) { Schema.Type type = nt.getType(); - if (type == RECORD) { - Schema newSchema = Schema.createRecord(nt.getName(), copyDocs ? nt.getDoc() : null, - nt.getNamespace(), nt.isError()); - copyProperties.copy(nt, newSchema); - replace.put(nt, newSchema); + if (type == RECORD) { + Schema newSchema = Schema.createRecord(nt.getName(), copyDocs ? nt.getDoc() : null, + nt.getNamespace(), nt.isError()); + copyProperties.copy(nt, newSchema); + replace.put(nt, newSchema); } return SchemaVisitorAction.CONTINUE; } @Override public SchemaVisitorAction afterVisitNonTerminal(final Schema nt) { - Schema.Type type = nt.getType(); - Schema newSchema; - switch (type) { - case RECORD: - newSchema = replace.get(nt); - List<Schema.Field> fields = nt.getFields(); - List<Schema.Field> newFields = new ArrayList<Schema.Field>(fields.size()); - for (Schema.Field field : fields) { + Schema.Type type = nt.getType(); + Schema newSchema; + switch (type) { + case RECORD: + newSchema = replace.get(nt); + List<Schema.Field> fields = nt.getFields(); + List<Schema.Field> newFields = new ArrayList<Schema.Field>(fields.size()); + for (Schema.Field field : fields) { Schema.Field newField = new Schema.Field(field.name(), replace.get(field.schema()), - copyDocs ? field.doc() : null, field.defaultVal(), field.order()); + copyDocs ? field.doc() : null, field.defaultVal(), field.order()); copyProperties.copy(field, newField); newFields.add(newField); - } - newSchema.setFields(newFields); - return SchemaVisitorAction.CONTINUE; - case UNION: - List<Schema> types = nt.getTypes(); - List<Schema> newTypes = new ArrayList<Schema>(types.size()); - for (Schema sch : types) { - newTypes.add(replace.get(sch)); - } - newSchema = Schema.createUnion(newTypes); - break; - case ARRAY: - newSchema = Schema.createArray(replace.get(nt.getElementType())); - break; - case MAP: - newSchema = Schema.createMap(replace.get(nt.getValueType())); - break; - default: - throw new IllegalStateException("Illegal type " + type + ", schema " + nt); - } - copyProperties.copy(nt, newSchema); - replace.put(nt, newSchema); - return SchemaVisitorAction.CONTINUE; + } + newSchema.setFields(newFields); + return SchemaVisitorAction.CONTINUE; + case UNION: + List<Schema> types = nt.getTypes(); + List<Schema> newTypes = new ArrayList<Schema>(types.size()); + for (Schema sch : types) { + newTypes.add(replace.get(sch)); + } + newSchema = Schema.createUnion(newTypes); + break; + case ARRAY: + newSchema = Schema.createArray(replace.get(nt.getElementType())); + break; + case MAP: + newSchema = Schema.createMap(replace.get(nt.getValueType())); + break; + default: + throw new IllegalStateException("Illegal type " + type + ", schema " + nt); + } + copyProperties.copy(nt, newSchema); + replace.put(nt, newSchema); + return SchemaVisitorAction.CONTINUE; } @Override http://git-wip-us.apache.org/repos/asf/avro/blob/91320154/lang/java/compiler/src/main/java/org/apache/avro/compiler/schema/SchemaVisitor.java ---------------------------------------------------------------------- diff --git a/lang/java/compiler/src/main/java/org/apache/avro/compiler/schema/SchemaVisitor.java b/lang/java/compiler/src/main/java/org/apache/avro/compiler/schema/SchemaVisitor.java index 4198355..8000314 100644 --- a/lang/java/compiler/src/main/java/org/apache/avro/compiler/schema/SchemaVisitor.java +++ b/lang/java/compiler/src/main/java/org/apache/avro/compiler/schema/SchemaVisitor.java @@ -1,33 +1,31 @@ - /* - * Copyright (c) 2001 - 2016, Zoltan Farkas All Rights Reserved. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - */ +/* +* Copyright (c) 2001 - 2016, Zoltan Farkas All Rights Reserved. +* +* This library is free software; you can redistribute it and/or +* modify it under the terms of the GNU Lesser General Public +* License as published by the Free Software Foundation; either +* version 2.1 of the License, or (at your option) any later version. +* +* This library is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU Lesser General Public +* License along with this program; if not, write to the Free Software +* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ package org.apache.avro.compiler.schema; import org.apache.avro.Schema; -/** - * @author zoly - */ public interface SchemaVisitor<T> { /** * Invoked for schemas that do not have "child" schemas (like string, int ...) * or for a previously encountered schema with children, * which will be treated as a terminal. (to avoid circular recursion) + * * @param terminal * @return */ @@ -35,6 +33,7 @@ public interface SchemaVisitor<T> { /** * Invoked for schema with children before proceeding to visit the children. + * * @param nonTerminal * @return */ @@ -42,6 +41,7 @@ public interface SchemaVisitor<T> { /** * Invoked for schemas with children after its children have been visited. + * * @param nonTerminal * @return */ @@ -50,6 +50,7 @@ public interface SchemaVisitor<T> { /** * Invoked when visiting is complete. + * * @return a value which will be returned by the visit method. */ T get(); http://git-wip-us.apache.org/repos/asf/avro/blob/91320154/lang/java/compiler/src/main/java/org/apache/avro/compiler/schema/SchemaVisitorAction.java ---------------------------------------------------------------------- diff --git a/lang/java/compiler/src/main/java/org/apache/avro/compiler/schema/SchemaVisitorAction.java b/lang/java/compiler/src/main/java/org/apache/avro/compiler/schema/SchemaVisitorAction.java index 81157aa..305ffbd 100644 --- a/lang/java/compiler/src/main/java/org/apache/avro/compiler/schema/SchemaVisitorAction.java +++ b/lang/java/compiler/src/main/java/org/apache/avro/compiler/schema/SchemaVisitorAction.java @@ -1,44 +1,41 @@ - /* - * Copyright (c) 2001 - 2016, Zoltan Farkas All Rights Reserved. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - */ +/* +* Copyright (c) 2001 - 2016, Zoltan Farkas All Rights Reserved. +* +* This library is free software; you can redistribute it and/or +* modify it under the terms of the GNU Lesser General Public +* License as published by the Free Software Foundation; either +* version 2.1 of the License, or (at your option) any later version. +* +* This library is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU Lesser General Public +* License along with this program; if not, write to the Free Software +* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ package org.apache.avro.compiler.schema; -/** - * @author zoly - */ public enum SchemaVisitorAction { - /** - * continue visit. - */ - CONTINUE, - /** - * terminate visit. - */ - TERMINATE, - /** - * when returned from pre non terminal visit method the children of the non terminal are skipped. - * afterVisitNonTerminal for the current schema will not be invoked. - */ - SKIP_SUBTREE, - /** - * Skip visiting the siblings of this schema. - */ - SKIP_SIBLINGS; + /** + * continue visit. + */ + CONTINUE, + /** + * terminate visit. + */ + TERMINATE, + /** + * when returned from pre non terminal visit method the children of the non terminal are skipped. + * afterVisitNonTerminal for the current schema will not be invoked. + */ + SKIP_SUBTREE, + /** + * Skip visiting the siblings of this schema. + */ + SKIP_SIBLINGS; } http://git-wip-us.apache.org/repos/asf/avro/blob/91320154/lang/java/compiler/src/main/java/org/apache/avro/compiler/schema/Schemas.java ---------------------------------------------------------------------- diff --git a/lang/java/compiler/src/main/java/org/apache/avro/compiler/schema/Schemas.java b/lang/java/compiler/src/main/java/org/apache/avro/compiler/schema/Schemas.java index 0196a71..ac39d88 100644 --- a/lang/java/compiler/src/main/java/org/apache/avro/compiler/schema/Schemas.java +++ b/lang/java/compiler/src/main/java/org/apache/avro/compiler/schema/Schemas.java @@ -3,6 +3,7 @@ package org.apache.avro.compiler.schema; import avro.shaded.com.google.common.base.Function; import avro.shaded.com.google.common.base.Supplier; import avro.shaded.com.google.common.collect.Lists; + import java.util.ArrayDeque; import java.util.Arrays; import java.util.Deque; @@ -10,6 +11,7 @@ import java.util.IdentityHashMap; import java.util.Iterator; import java.util.Map; import java.util.Set; + import org.apache.avro.JsonProperties; import org.apache.avro.LogicalType; import org.apache.avro.Schema; @@ -18,8 +20,6 @@ import org.apache.avro.compiler.specific.SpecificCompiler; /** * Avro Schema utilities, to traverse... - * - * @author zoly */ public final class Schemas { @@ -73,7 +73,7 @@ public final class Schemas { public static String getJavaClassName(final Schema schema) { String namespace = schema.getNamespace(); - if (namespace == null || namespace.isEmpty()) { + if (namespace == null) { return SpecificCompiler.mangle(schema.getName()); } else { return namespace + '.' + SpecificCompiler.mangle(schema.getName()); @@ -105,12 +105,9 @@ public final class Schemas { case SKIP_SUBTREE: throw new UnsupportedOperationException(); case SKIP_SIBLINGS: - //CHECKSTYLE:OFF InnerAssignment - while ((current = dq.getLast()) instanceof Schema) { - // just skip + while (dq.getLast() instanceof Schema) { + dq.removeLast(); } - //CHECKSTYLE:ON - dq.addLast(current); break; case TERMINATE: return visitor.get(); @@ -129,12 +126,12 @@ public final class Schemas { break; case RECORD: terminate = visitNonTerminal(visitor, schema, dq, - Lists.transform(Lists.reverse(schema.getFields()), new Function<Field, Schema>() { - @Override - public Schema apply(Field f) { - return f.schema(); - } - })); + Lists.transform(Lists.reverse(schema.getFields()), new Function<Field, Schema>() { + @Override + public Schema apply(Field f) { + return f.schema(); + } + })); visited.put(schema, schema); break; case UNION: @@ -173,8 +170,8 @@ public final class Schemas { } private static boolean visitNonTerminal(final SchemaVisitor visitor, - final Schema schema, final Deque<Object> dq, - final Iterable<Schema> itSupp) { + final Schema schema, final Deque<Object> dq, + final Iterable<Schema> itSupp) { SchemaVisitorAction action = visitor.visitNonTerminal(schema); switch (action) { case CONTINUE: @@ -199,13 +196,9 @@ public final class Schemas { }); break; case SKIP_SIBLINGS: - Object current; - //CHECKSTYLE:OFF InnerAssignment - while ((current = dq.getLast()) instanceof Schema) { - // just skip + while (!dq.isEmpty() && dq.getLast() instanceof Schema) { + dq.removeLast(); } - //CHECKSTYLE:ON - dq.addLast(current); break; case TERMINATE: return true; @@ -216,7 +209,7 @@ public final class Schemas { } private static boolean visitTerminal(final SchemaVisitor visitor, final Schema schema, - final Deque<Object> dq) { + final Deque<Object> dq) { SchemaVisitorAction action = visitor.visitTerminal(schema); switch (action) { case CONTINUE: @@ -224,13 +217,9 @@ public final class Schemas { case SKIP_SUBTREE: throw new UnsupportedOperationException("Invalid action " + action + " for " + schema); case SKIP_SIBLINGS: - Object current; - //CHECKSTYLE:OFF InnerAssignment - while ((current = dq.getLast()) instanceof Schema) { - // just skip + while (!dq.isEmpty() && dq.getLast() instanceof Schema) { + dq.removeLast(); } - //CHECKSTYLE:ON - dq.addLast(current); break; case TERMINATE: return true; http://git-wip-us.apache.org/repos/asf/avro/blob/91320154/lang/java/compiler/src/test/java/org/apache/avro/compiler/idl/SchemaResolverTest.java ---------------------------------------------------------------------- diff --git a/lang/java/compiler/src/test/java/org/apache/avro/compiler/idl/SchemaResolverTest.java b/lang/java/compiler/src/test/java/org/apache/avro/compiler/idl/SchemaResolverTest.java deleted file mode 100644 index 61212f7..0000000 --- a/lang/java/compiler/src/test/java/org/apache/avro/compiler/idl/SchemaResolverTest.java +++ /dev/null @@ -1,44 +0,0 @@ -/* - * Copyright 2017 The Apache Software Foundation. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.apache.avro.compiler.idl; - -import java.io.File; -import java.io.IOException; -import java.net.MalformedURLException; -import org.apache.avro.Protocol; -import org.junit.Assert; -import org.junit.Test; - -/** - * - * @author zoly - */ -public class SchemaResolverTest { - - - @Test - public void testResolving() throws ParseException, MalformedURLException, IOException { - File file = new File("."); - String currentWorkPath = file.getAbsolutePath(); - String testIdl = currentWorkPath + File.separator + "src" + File.separator + "test" - + File.separator + "idl" + File.separator + "cycle.avdl"; - Idl compiler = new Idl(new File(testIdl)); - Protocol protocol = compiler.CompilationUnit(); - System.out.println(protocol); - Assert.assertEquals(5, protocol.getTypes().size()); - } - -} http://git-wip-us.apache.org/repos/asf/avro/blob/91320154/lang/java/compiler/src/test/java/org/apache/avro/compiler/idl/TestCycle.java ---------------------------------------------------------------------- diff --git a/lang/java/compiler/src/test/java/org/apache/avro/compiler/idl/TestCycle.java b/lang/java/compiler/src/test/java/org/apache/avro/compiler/idl/TestCycle.java index bc76959..89a04d6 100644 --- a/lang/java/compiler/src/test/java/org/apache/avro/compiler/idl/TestCycle.java +++ b/lang/java/compiler/src/test/java/org/apache/avro/compiler/idl/TestCycle.java @@ -39,14 +39,10 @@ import org.junit.Test; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -/** - * - * @author zoly - */ public class TestCycle { private static final Logger LOG = LoggerFactory.getLogger(TestCycle.class); - + @Test public void testCycleGeneration() throws ParseException, IOException { final ClassLoader cl = Thread.currentThread().getContextClassLoader(); http://git-wip-us.apache.org/repos/asf/avro/blob/91320154/lang/java/compiler/src/test/java/org/apache/avro/compiler/idl/TestSchemaResolver.java ---------------------------------------------------------------------- diff --git a/lang/java/compiler/src/test/java/org/apache/avro/compiler/idl/TestSchemaResolver.java b/lang/java/compiler/src/test/java/org/apache/avro/compiler/idl/TestSchemaResolver.java new file mode 100644 index 0000000..0f7c98f --- /dev/null +++ b/lang/java/compiler/src/test/java/org/apache/avro/compiler/idl/TestSchemaResolver.java @@ -0,0 +1,72 @@ +/* + * Copyright 2017 The Apache Software Foundation. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.avro.compiler.idl; + +import java.io.File; +import java.io.IOException; +import java.net.MalformedURLException; + +import org.apache.avro.Protocol; +import org.apache.avro.Schema; +import org.apache.avro.SchemaBuilder; +import org.junit.Assert; +import org.junit.Test; + +public class TestSchemaResolver { + + + @Test + public void testResolving() throws ParseException, MalformedURLException, IOException { + File file = new File("."); + String currentWorkPath = file.getAbsolutePath(); + String testIdl = currentWorkPath + File.separator + "src" + File.separator + "test" + + File.separator + "idl" + File.separator + "cycle.avdl"; + Idl compiler = new Idl(new File(testIdl)); + Protocol protocol = compiler.CompilationUnit(); + System.out.println(protocol); + Assert.assertEquals(5, protocol.getTypes().size()); + } + + @Test(expected = IllegalArgumentException.class) + public void testIsUnresolvedSchemaError1() { + // No "org.apache.avro.compiler.idl.unresolved.name" property + Schema s = SchemaBuilder.record("R").fields().endRecord(); + SchemaResolver.getUnresolvedSchemaName(s); + } + + @Test(expected = IllegalArgumentException.class) + public void testIsUnresolvedSchemaError2() { + // No "UnresolvedSchema" property + Schema s = SchemaBuilder.record("R") + .prop("org.apache.avro.compiler.idl.unresolved.name", "x").fields().endRecord(); + SchemaResolver.getUnresolvedSchemaName(s); + } + + @Test(expected = IllegalArgumentException.class) + public void testIsUnresolvedSchemaError3() { + // Namespace not "org.apache.avro.compiler". + Schema s = SchemaBuilder.record("UnresolvedSchema") + .prop("org.apache.avro.compiler.idl.unresolved.name", "x") + .fields().endRecord(); + SchemaResolver.getUnresolvedSchemaName(s); + } + + @Test(expected = IllegalArgumentException.class) + public void testGetUnresolvedSchemaNameError() { + Schema s = SchemaBuilder.fixed("a").size(10); + SchemaResolver.getUnresolvedSchemaName(s); + } +} http://git-wip-us.apache.org/repos/asf/avro/blob/91320154/lang/java/compiler/src/test/java/org/apache/avro/compiler/schema/SchemasTest.java ---------------------------------------------------------------------- diff --git a/lang/java/compiler/src/test/java/org/apache/avro/compiler/schema/SchemasTest.java b/lang/java/compiler/src/test/java/org/apache/avro/compiler/schema/SchemasTest.java deleted file mode 100644 index 545901e..0000000 --- a/lang/java/compiler/src/test/java/org/apache/avro/compiler/schema/SchemasTest.java +++ /dev/null @@ -1,87 +0,0 @@ -/* - * Copyright 2017 The Apache Software Foundation. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.apache.avro.compiler.schema; - -import org.apache.avro.Schema; -import org.apache.avro.SchemaCompatibility; -import org.junit.Assert; -import org.junit.Test; - -public class SchemasTest { - - private static final String SCHEMA = "{\"type\":\"record\",\"name\":\"SampleNode\",\"doc\":\"caca\"," - + "\"namespace\":\"org.spf4j.ssdump2.avro\",\n" + - " \"fields\":[\n" + - " {\"name\":\"count\",\"type\":\"int\",\"default\":0,\"doc\":\"caca\"},\n" + - " {\"name\":\"subNodes\",\"type\":\n" + - " {\"type\":\"array\",\"items\":{\n" + - " \"type\":\"record\",\"name\":\"SamplePair\",\n" + - " \"fields\":[\n" + - " {\"name\":\"method\",\"type\":\n" + - " {\"type\":\"record\",\"name\":\"Method\",\n" + - " \"fields\":[\n" + - " {\"name\":\"declaringClass\",\"type\":{\"type\":\"string\",\"avro.java.string\":\"String\"}},\n" + - " {\"name\":\"methodName\",\"type\":{\"type\":\"string\",\"avro.java.string\":\"String\"}}\n" + - " ]}},\n" + - " {\"name\":\"node\",\"type\":\"SampleNode\"}]}}}]}"; - - private static class PrintingVisitor implements SchemaVisitor { - - - @Override - public SchemaVisitorAction visitTerminal(Schema terminal) { - System.out.println("Terminal: " + terminal.getFullName()); - return SchemaVisitorAction.CONTINUE; - } - - @Override - public SchemaVisitorAction visitNonTerminal(Schema terminal) { - System.out.println("NONTerminal start: " + terminal.getFullName()); - return SchemaVisitorAction.CONTINUE; - } - - @Override - public SchemaVisitorAction afterVisitNonTerminal(Schema terminal) { - System.out.println("NONTerminal end: " + terminal.getFullName()); - return SchemaVisitorAction.CONTINUE; - } - - @Override - public Object get() { - return null; - } - } - - - - @Test - public void textCloning() { - Schema recSchema = new Schema.Parser().parse(SCHEMA); - Schemas.visit(recSchema, new PrintingVisitor()); - - - Schema trimmed = Schemas.visit(recSchema, new CloningVisitor(recSchema)); - Assert.assertNull(trimmed.getDoc()); - Assert.assertNotNull(recSchema.getDoc()); - - SchemaCompatibility.SchemaCompatibilityType compat = - SchemaCompatibility.checkReaderWriterCompatibility(trimmed, recSchema).getType(); - Assert.assertEquals(SchemaCompatibility.SchemaCompatibilityType.COMPATIBLE, compat); - compat = SchemaCompatibility.checkReaderWriterCompatibility(recSchema, trimmed).getType(); - Assert.assertEquals(SchemaCompatibility.SchemaCompatibilityType.COMPATIBLE, compat); - } - -} http://git-wip-us.apache.org/repos/asf/avro/blob/91320154/lang/java/compiler/src/test/java/org/apache/avro/compiler/schema/TestSchemas.java ---------------------------------------------------------------------- diff --git a/lang/java/compiler/src/test/java/org/apache/avro/compiler/schema/TestSchemas.java b/lang/java/compiler/src/test/java/org/apache/avro/compiler/schema/TestSchemas.java new file mode 100644 index 0000000..230da60 --- /dev/null +++ b/lang/java/compiler/src/test/java/org/apache/avro/compiler/schema/TestSchemas.java @@ -0,0 +1,347 @@ +/* + * Copyright 2017 The Apache Software Foundation. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.avro.compiler.schema; + +import org.apache.avro.Schema; +import org.apache.avro.SchemaCompatibility; +import org.junit.Assert; +import org.junit.Test; + +public class TestSchemas { + + private static final String SCHEMA = "{\"type\":\"record\",\"name\":\"SampleNode\",\"doc\":\"caca\"," + + "\"namespace\":\"org.spf4j.ssdump2.avro\",\n" + + " \"fields\":[\n" + + " {\"name\":\"count\",\"type\":\"int\",\"default\":0,\"doc\":\"caca\"},\n" + + " {\"name\":\"kind1\",\"type\":{\"type\":\"enum\", \"name\": \"Kind1\", \"symbols\": [\"A1\", \"B1\"]}},\n" + + " {\"name\":\"kind2\",\"type\":{\"type\":\"enum\", \"name\": \"Kind2\", \"symbols\": [\"A2\", \"B2\"], \"doc\": \"doc\"}},\n" + + " {\"name\":\"pat\",\"type\":{\"type\":\"fixed\", \"name\": \"FixedPattern\", \"size\": 10}},\n" + + " {\"name\":\"uni\",\"type\":[\"int\", \"double\"]},\n" + + " {\"name\":\"mp\",\"type\":{\"type\":\"map\", \"values\": \"int\"}},\n" + + " {\"name\":\"subNodes\",\"type\":\n" + + " {\"type\":\"array\",\"items\":{\n" + + " \"type\":\"record\",\"name\":\"SamplePair\",\n" + + " \"fields\":[\n" + + " {\"name\":\"method\",\"type\":\n" + + " {\"type\":\"record\",\"name\":\"Method\",\n" + + " \"fields\":[\n" + + " {\"name\":\"declaringClass\",\"type\":{\"type\":\"string\",\"avro.java.string\":\"String\"}},\n" + + " {\"name\":\"methodName\",\"type\":{\"type\":\"string\",\"avro.java.string\":\"String\"}}\n" + + " ]}},\n" + + " {\"name\":\"node\",\"type\":\"SampleNode\"}]}}}" + + "]}"; + + private static class PrintingVisitor implements SchemaVisitor { + + + @Override + public SchemaVisitorAction visitTerminal(Schema terminal) { + System.out.println("Terminal: " + terminal.getFullName()); + return SchemaVisitorAction.CONTINUE; + } + + @Override + public SchemaVisitorAction visitNonTerminal(Schema terminal) { + System.out.println("NONTerminal start: " + terminal.getFullName()); + return SchemaVisitorAction.CONTINUE; + } + + @Override + public SchemaVisitorAction afterVisitNonTerminal(Schema terminal) { + System.out.println("NONTerminal end: " + terminal.getFullName()); + return SchemaVisitorAction.CONTINUE; + } + + @Override + public Object get() { + return null; + } + } + + + @Test + public void textCloning() { + Schema recSchema = new Schema.Parser().parse(SCHEMA); + Schemas.visit(recSchema, new PrintingVisitor()); + + + CloningVisitor cv = new CloningVisitor(recSchema); + Schema trimmed = Schemas.visit(recSchema, cv); + Assert.assertNull(trimmed.getDoc()); + Assert.assertNotNull(recSchema.getDoc()); + + SchemaCompatibility.SchemaCompatibilityType compat = + SchemaCompatibility.checkReaderWriterCompatibility(trimmed, recSchema).getType(); + Assert.assertEquals(SchemaCompatibility.SchemaCompatibilityType.COMPATIBLE, compat); + compat = SchemaCompatibility.checkReaderWriterCompatibility(recSchema, trimmed).getType(); + Assert.assertEquals(SchemaCompatibility.SchemaCompatibilityType.COMPATIBLE, compat); + Assert.assertNotNull(cv.toString()); + } + + @Test + public void textCloningCopyDocs() { + Schema recSchema = new Schema.Parser().parse(SCHEMA); + Schemas.visit(recSchema, new PrintingVisitor()); + + + Schema trimmed = Schemas.visit(recSchema, new CloningVisitor(new CloningVisitor.PropertyCopier() { + @Override + public void copy(final Schema first, final Schema second) { + Schemas.copyLogicalTypes(first, second); + Schemas.copyAliases(first, second); + } + + @Override + public void copy(final Schema.Field first, final Schema.Field second) { + Schemas.copyAliases(first, second); + } + }, true, recSchema)); + Assert.assertEquals("caca", trimmed.getDoc()); + Assert.assertNotNull(recSchema.getDoc()); + + SchemaCompatibility.SchemaCompatibilityType compat = + SchemaCompatibility.checkReaderWriterCompatibility(trimmed, recSchema).getType(); + Assert.assertEquals(SchemaCompatibility.SchemaCompatibilityType.COMPATIBLE, compat); + compat = SchemaCompatibility.checkReaderWriterCompatibility(recSchema, trimmed).getType(); + Assert.assertEquals(SchemaCompatibility.SchemaCompatibilityType.COMPATIBLE, compat); + } + + @Test(expected = IllegalStateException.class) + public void testCloningError1() { + // Visit Terminal with union + Schema recordSchema = new Schema.Parser().parse( + "{\"type\": \"record\", \"name\": \"R\", \"fields\":[{\"name\": \"f1\", \"type\": [\"int\", \"long\"]}]}"); + new CloningVisitor(recordSchema).visitTerminal(recordSchema.getField("f1").schema()); + } + + @Test(expected = IllegalStateException.class) + public void testCloningError2() { + // After visit Non-terminal with int + Schema recordSchema = new Schema.Parser().parse( + "{\"type\": \"record\", \"name\": \"R\", \"fields\":[{\"name\": \"f1\", \"type\": \"int\"}]}"); + new CloningVisitor(recordSchema).afterVisitNonTerminal(recordSchema.getField("f1").schema()); + } + + @Test + public void testHasGeneratedJavaClass() { + Assert.assertTrue(Schemas.hasGeneratedJavaClass( + new Schema.Parser().parse("{\"type\": \"fixed\", \"name\": \"N\", \"size\": 10}"))); + Assert.assertFalse(Schemas.hasGeneratedJavaClass(new Schema.Parser().parse("{\"type\": \"int\"}"))); + } + + @Test + public void testGetJavaClassName() { + Assert.assertEquals("N", Schemas.getJavaClassName( + new Schema.Parser().parse("{\"type\": \"fixed\", \"name\": \"N\", \"size\": 10}"))); + Assert.assertEquals("N", Schemas.getJavaClassName( + new Schema.Parser().parse("{\"type\": \"fixed\", \"name\": \"N\", \"size\": 10, \"namespace\": \"\"}"))); + Assert.assertEquals("com.example.N", Schemas.getJavaClassName( + new Schema.Parser().parse("{\"type\": \"fixed\", \"name\": \"N\", \"size\": 10, \"namespace\": \"com.example\"}"))); + } + + private static class TestVisitor implements SchemaVisitor<String> { + StringBuilder sb = new StringBuilder(); + + public SchemaVisitorAction visitTerminal(Schema terminal) { + sb.append(terminal); + return SchemaVisitorAction.CONTINUE; + } + + public SchemaVisitorAction visitNonTerminal(Schema nonTerminal) { + String n = nonTerminal.getName(); + sb.append(n).append('.'); + if (n.startsWith("t")) { + return SchemaVisitorAction.TERMINATE; + } else if (n.startsWith("ss")) { + return SchemaVisitorAction.SKIP_SIBLINGS; + } else if (n.startsWith("st")) { + return SchemaVisitorAction.SKIP_SUBTREE; + } else { + return SchemaVisitorAction.CONTINUE; + } + } + + public SchemaVisitorAction afterVisitNonTerminal(Schema nonTerminal) { + sb.append("!"); + String n = nonTerminal.getName(); + if (n.startsWith("ct")) { + return SchemaVisitorAction.TERMINATE; + } else if (n.startsWith("css")) { + return SchemaVisitorAction.SKIP_SIBLINGS; + } else if (n.startsWith("cst")) { + return SchemaVisitorAction.SKIP_SUBTREE; + } else { + return SchemaVisitorAction.CONTINUE; + } + } + + public String get() { + return sb.toString(); + } + } + + @Test + public void testVisit1() { + String s1 = "{\"type\": \"record\", \"name\": \"t1\", \"fields\": [" + + "{\"name\": \"f1\", \"type\": \"int\"}" + + "]}"; + Assert.assertEquals("t1.", Schemas.visit(new Schema.Parser().parse(s1), new TestVisitor())); + } + + @Test + public void testVisit2() { + String s2 = "{\"type\": \"record\", \"name\": \"c1\", \"fields\": [" + + "{\"name\": \"f1\", \"type\": \"int\"}" + + "]}"; + Assert.assertEquals("c1.\"int\"!", Schemas.visit(new Schema.Parser().parse(s2), new TestVisitor())); + + } + + @Test + public void testVisit3() { + String s3 = "{\"type\": \"record\", \"name\": \"ss1\", \"fields\": [" + + "{\"name\": \"f1\", \"type\": \"int\"}" + + "]}"; + Assert.assertEquals("ss1.", Schemas.visit(new Schema.Parser().parse(s3), new TestVisitor())); + + } + + @Test + public void testVisit4() { + String s4 = "{\"type\": \"record\", \"name\": \"st1\", \"fields\": [" + + "{\"name\": \"f1\", \"type\": \"int\"}" + + "]}"; + Assert.assertEquals("st1.!", Schemas.visit(new Schema.Parser().parse(s4), new TestVisitor())); + + } + + @Test + public void testVisit5() { + String s5 = "{\"type\": \"record\", \"name\": \"c1\", \"fields\": [" + + "{\"name\": \"f1\", \"type\": {\"type\": \"record\", \"name\": \"c2\", \"fields\": " + + "[{\"name\": \"f11\", \"type\": \"int\"}]}}," + + "{\"name\": \"f2\", \"type\": \"long\"}" + + "]}"; + Assert.assertEquals("c1.c2.\"int\"!\"long\"!", + Schemas.visit(new Schema.Parser().parse(s5), new TestVisitor())); + + } + + @Test + public void testVisit6() { + String s6 = "{\"type\": \"record\", \"name\": \"c1\", \"fields\": [" + + "{\"name\": \"f1\", \"type\": {\"type\": \"record\", \"name\": \"ss2\", \"fields\": " + + "[{\"name\": \"f11\", \"type\": \"int\"}]}}," + + "{\"name\": \"f2\", \"type\": \"long\"}" + + "]}"; + Assert.assertEquals("c1.ss2.!", + Schemas.visit(new Schema.Parser().parse(s6), new TestVisitor())); + + } + + @Test + public void testVisit7() { + String s7 = "{\"type\": \"record\", \"name\": \"c1\", \"fields\": [" + + "{\"name\": \"f1\", \"type\": {\"type\": \"record\", \"name\": \"css2\", \"fields\": " + + "[{\"name\": \"f11\", \"type\": \"int\"}]}}," + + "{\"name\": \"f2\", \"type\": \"long\"}" + + "]}"; + Assert.assertEquals("c1.css2.\"int\"!!", + Schemas.visit(new Schema.Parser().parse(s7), new TestVisitor())); + } + + @Test(expected = UnsupportedOperationException.class) + public void testVisit8() { + String s8 = "{\"type\": \"record\", \"name\": \"c1\", \"fields\": [" + + "{\"name\": \"f1\", \"type\": {\"type\": \"record\", \"name\": \"cst2\", \"fields\": " + + "[{\"name\": \"f11\", \"type\": \"int\"}]}}," + + "{\"name\": \"f2\", \"type\": \"int\"}" + + "]}"; + Schemas.visit(new Schema.Parser().parse(s8), new TestVisitor()); + } + + @Test + public void testVisit9() { + String s9 = "{\"type\": \"record\", \"name\": \"c1\", \"fields\": [" + + "{\"name\": \"f1\", \"type\": {\"type\": \"record\", \"name\": \"ct2\", \"fields\": " + + "[{\"name\": \"f11\", \"type\": \"int\"}]}}," + + "{\"name\": \"f2\", \"type\": \"long\"}" + + "]}"; + Assert.assertEquals("c1.ct2.\"int\"!", Schemas.visit(new Schema.Parser().parse(s9), new TestVisitor())); + } + + + @Test(expected = UnsupportedOperationException.class) + public void testVisit10() { + String s10 = "{\"type\": \"record\", \"name\": \"c1\", \"fields\": [" + + "{\"name\": \"f1\", \"type\": {\"type\": \"record\", \"name\": \"ct2\", \"fields\": " + + "[{\"name\": \"f11\", \"type\": \"int\"}]}}," + + "{\"name\": \"f2\", \"type\": \"int\"}" + + "]}"; + Schemas.visit(new Schema.Parser().parse(s10), + new TestVisitor() { + public SchemaVisitorAction visitTerminal(Schema terminal) { + return SchemaVisitorAction.SKIP_SUBTREE; + } + }); + } + + @Test + public void testVisit11() { + String s11 = "{\"type\": \"record\", \"name\": \"c1\", \"fields\": [" + + "{\"name\": \"f1\", \"type\": {\"type\": \"record\", \"name\": \"c2\", \"fields\": " + + "[{\"name\": \"f11\", \"type\": \"int\"},{\"name\": \"f12\", \"type\": \"double\"}" + + "]}}," + + "{\"name\": \"f2\", \"type\": \"long\"}" + + "]}"; + Assert.assertEquals("c1.c2.\"int\".!\"long\".!", Schemas.visit(new Schema.Parser().parse(s11), + new TestVisitor() { + public SchemaVisitorAction visitTerminal(Schema terminal) { + sb.append(terminal).append('.'); + return SchemaVisitorAction.SKIP_SIBLINGS; + } + })); + } + + + @Test + public void testVisit12() { + String s12 = "{\"type\": \"record\", \"name\": \"c1\", \"fields\": [" + + "{\"name\": \"f1\", \"type\": {\"type\": \"record\", \"name\": \"ct2\", \"fields\": " + + "[{\"name\": \"f11\", \"type\": \"int\"}]}}," + + "{\"name\": \"f2\", \"type\": \"long\"}" + + "]}"; + Assert.assertEquals("c1.ct2.\"int\".", Schemas.visit(new Schema.Parser().parse(s12), + new TestVisitor() { + public SchemaVisitorAction visitTerminal(Schema terminal) { + sb.append(terminal).append('.'); + return SchemaVisitorAction.TERMINATE; + } + })); + } + + @Test + public void testVisit13() { + String s12 = "{\"type\": \"int\"}"; + Assert.assertEquals("\"int\".", Schemas.visit(new Schema.Parser().parse(s12), + new TestVisitor() { + public SchemaVisitorAction visitTerminal(Schema terminal) { + sb.append(terminal).append('.'); + return SchemaVisitorAction.SKIP_SIBLINGS; + } + })); + } +}
