Define AvroClassHierarchy which implements ClassHierarchy interface

Project: http://git-wip-us.apache.org/repos/asf/incubator-reef/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-reef/commit/1d370951
Tree: http://git-wip-us.apache.org/repos/asf/incubator-reef/tree/1d370951
Diff: http://git-wip-us.apache.org/repos/asf/incubator-reef/diff/1d370951

Branch: refs/heads/REEF-395
Commit: 1d37095112b3069ea180988630ed67c66101bdac
Parents: beb1aef
Author: Yunseong Lee <[email protected]>
Authored: Sat Jun 20 02:16:13 2015 +0900
Committer: Yunseong Lee <[email protected]>
Committed: Sat Jun 20 02:16:13 2015 +0900

----------------------------------------------------------------------
 .../implementation/java/AvroClassHierarchy.java | 188 +++++++++++++++++++
 1 file changed, 188 insertions(+)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-reef/blob/1d370951/lang/java/reef-tang/tang/src/main/java/org/apache/reef/tang/implementation/java/AvroClassHierarchy.java
----------------------------------------------------------------------
diff --git 
a/lang/java/reef-tang/tang/src/main/java/org/apache/reef/tang/implementation/java/AvroClassHierarchy.java
 
b/lang/java/reef-tang/tang/src/main/java/org/apache/reef/tang/implementation/java/AvroClassHierarchy.java
new file mode 100644
index 0000000..96ab16c
--- /dev/null
+++ 
b/lang/java/reef-tang/tang/src/main/java/org/apache/reef/tang/implementation/java/AvroClassHierarchy.java
@@ -0,0 +1,188 @@
+package org.apache.reef.tang.implementation.java;
+
+import org.apache.reef.tang.ClassHierarchy;
+import org.apache.reef.tang.annotations.NamedParameter;
+import org.apache.reef.tang.exceptions.NameResolutionException;
+import org.apache.reef.tang.formats.avro.*;
+import org.apache.reef.tang.implementation.types.*;
+import org.apache.reef.tang.types.*;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+
+/**
+ * Implementation of ClassHierarchy for Avro
+ */
+// TODO Should it be a ClassHierarchy?
+public class AvroClassHierarchy implements ClassHierarchy {
+  private final PackageNode namespace;
+  private final HashMap<String, Node> lookupTable = new HashMap<>();
+
+  public AvroClassHierarchy(final AvroNode root) {
+    namespace = new PackageNodeImpl();
+    if (root.getPackageNode() == null) {
+      throw new IllegalArgumentException("Expected a package node. Got: " + 
root);
+    }
+
+    // Register all the classes.
+    for (final AvroNode child : root.getChildren()) {
+      parseSubHierarchy(namespace, child);
+    }
+    buildLookupTable(namespace);
+    // Now, register the implementations
+    for (final AvroNode child : root.getChildren()) {
+      wireUpInheritanceRelationships(child);
+    }
+  }
+
+  private void buildLookupTable(final Node n) {
+    for(final Node child : n.getChildren()) {
+      lookupTable.put(child.getFullName(), child);
+      buildLookupTable(child);
+    }
+  }
+
+  private static ConstructorDef<?> parseConstructorDef(final 
AvroConstructorDef def, final boolean isInjectable) {
+    final List<ConstructorArg> args = new ArrayList<>();
+    for (final AvroConstructorArg arg : def.getConstructorArg()) {
+      final String namedParameterName = arg.getNamedParameterName() == null ? 
null : arg.getNamedParameterName();
+      args.add(new ConstructorArgImpl(arg.getFullArgClassName(), 
namedParameterName,
+              arg.getIsInjectionFuture()));
+    }
+    return new ConstructorDefImpl<>(def.getFullArgClassName(), 
args.toArray(new ConstructorArg[0]),
+            isInjectable);
+  }
+
+  private static void parseSubHierarchy(Node parent, AvroNode n) {
+    final Node parsed;
+    if (n.getPackageNode() != null) {
+      parsed = new PackageNodeImpl(parent, n.getName(), n.getFullName());
+    } else if (n.getNamedParameterNode() != null) {
+      final AvroNamedParameterNode np = n.getNamedParameterNode();
+      parsed = new NamedParameterNodeImpl<Object>(parent, n.getName(), 
n.getFullName(),
+              np.getFullArgClassName(), np.getSimpleArgClassName(), 
np.getIsSet(), np.getIsList(),
+              np.getDocumentation(), np.getShortName(), 
np.getInstanceDefault().toArray(new String[0]));
+    } else if (n.getClassNode() != null) {
+      final AvroClassNode cn = n.getClassNode();
+      final List<ConstructorDef<?>> injectableConstructors = new ArrayList<>();
+      final List<ConstructorDef<?>> allConstructors = new ArrayList<>();
+
+      for (final AvroConstructorDef injectable : 
cn.getInjectableConstructors()) {
+        final ConstructorDef<?> def = parseConstructorDef(injectable, true);
+        injectableConstructors.add(def);
+        allConstructors.add(def);
+      }
+      for (final AvroConstructorDef other : cn.getOtherConstructors()) {
+        final ConstructorDef<?> def = parseConstructorDef(other, false);
+        allConstructors.add(def);
+      }
+      @SuppressWarnings("unchecked")
+      final ConstructorDef<Object>[] dummy = new ConstructorDef[0];
+      final String defaultImpl = cn.getDefaultImplementation() == null ? null 
: cn.getDefaultImplementation();
+      parsed = new ClassNodeImpl<>(parent, n.getName(), n.getFullName(), 
cn.getIsUnit(),
+              cn.getIsInjectionCandidate(), cn.getIsExternalConstructor(), 
injectableConstructors.toArray(dummy),
+              allConstructors.toArray(dummy), defaultImpl);
+    } else {
+      throw new IllegalStateException("Bad protocol buffer: got abstract node" 
+ n);
+    }
+    for (AvroNode child : n.getChildren()) {
+      parseSubHierarchy(parsed, child);
+    }
+  }
+
+
+  @SuppressWarnings({"rawtypes", "unchecked"})
+  private void wireUpInheritanceRelationships(final AvroNode n) {
+    if (n.getClassNode() != null) {
+      final AvroClassNode cn = n.getClassNode();
+      final ClassNode iface;
+      try {
+        iface = (ClassNode) getNode(n.getFullName());
+      } catch (NameResolutionException e) {
+        throw new IllegalStateException("When reading protocol buffer node "
+                + n.getFullName() + " does not exist.  Full record is " + n, 
e);
+      }
+      for (final String impl : cn.getImplFullNames()) {
+        try {
+          iface.putImpl((ClassNode) getNode(impl));
+        } catch (NameResolutionException e) {
+          throw new IllegalStateException("When reading protocol buffer node "
+                  + n + " refers to non-existent implementation:" + impl);
+        } catch (ClassCastException e) {
+          try {
+            throw new IllegalStateException(
+                    "When reading protocol buffer node " + n
+                            + " found implementation" + getNode(impl)
+                            + " which is not a ClassNode!");
+          } catch (NameResolutionException e2) {
+            throw new IllegalStateException(
+                    "Got 'cant happen' exception when producing error message 
for "
+                            + e);
+          }
+        }
+      }
+    }
+
+    for (final AvroNode child : n.getChildren()) {
+      wireUpInheritanceRelationships(child);
+    }
+  }
+
+  @Override
+  public Node getNode(final String fullName) throws NameResolutionException {
+    final Node matchedNode = lookupTable.get(fullName);
+    if (matchedNode != null) {
+      return matchedNode;
+    } else {
+      throw new NameResolutionException(fullName, "");
+    }
+  }
+
+  @Override
+  public boolean isImplementation(final ClassNode<?> inter, final ClassNode<?> 
impl) {
+    return impl.isImplementationOf(inter);
+  }
+
+  @Override
+  public ClassHierarchy merge(ClassHierarchy ch) {
+    if (this == ch) {
+      return this;
+    }
+    if (!(ch instanceof AvroClassHierarchy)) {
+      throw new UnsupportedOperationException(
+              "Cannot merge with class hierarchies of type: " + 
ch.getClass().getName());
+    }
+
+    final AvroClassHierarchy ach = (AvroClassHierarchy) ch;
+    for (final String key : ach.lookupTable.keySet()) {
+      if (!this.lookupTable.containsKey(key)) {
+        this.lookupTable.put(key, ach.lookupTable.get(key));
+        // TODO : Does the order not matter here?
+      }
+    }
+
+    for (final Node n : ch.getNamespace().getChildren()) {
+      if (!this.namespace.contains(n.getFullName())) {
+        if (n instanceof NamedParameter) {
+          final NamedParameterNode np = (NamedParameterNode) n;
+          new NamedParameterNodeImpl<>(this.namespace, np.getName(), 
np.getFullName(), np.getFullArgName(),
+                  np.getSimpleArgName(), np.isSet(), np.isList(), 
np.getDocumentation(), np.getShortName(),
+                  np.getDefaultInstanceAsStrings());
+        } else if (n instanceof ClassNode) {
+          final ClassNode cn = (ClassNode) n;
+          new ClassNodeImpl<>(namespace, cn.getName(), cn.getFullName(), 
cn.isUnit(), cn.isInjectionCandidate(),
+                  cn.isExternalConstructor(), cn.getInjectableConstructors(), 
cn.getAllConstructors(),
+                  cn.getDefaultImplementation());
+        }
+        // TODO What if n is the package node?
+      }
+    }
+    return this;
+  }
+
+  @Override
+  public Node getNamespace() {
+    return namespace;
+  }
+}

Reply via email to