/** * serialize a class hierarchy into a file. * * @param file * @param classHierarchy * @throws IOException */ public static void serialize(final File file, final ClassHierarchy classHierarchy) throws IOException { final ClassHierarchyProto.Node node = serializeNode(classHierarchy.getNamespace()); try (final FileOutputStream output = new FileOutputStream(file)) { try (final DataOutputStream dos = new DataOutputStream(output)) { node.writeTo(dos); } } }
/** * Deserialize a class hierarchy from a protocol buffer object. The resulting object is immutable, * and does not make use of reflection to fill in any missing values. This allows it to represent * non-native classes as well as snapshots of Java class hierarchies. */ public ProtocolBufferClassHierarchy(ClassHierarchyProto.Node root) { namespace = new PackageNodeImpl(); if (!root.hasPackageNode()) { throw new IllegalArgumentException("Expected a package node. Got: " + root); } // Register all the classes. for (ClassHierarchyProto.Node child : root.getChildrenList()) { parseSubHierarchy(namespace, child); } buildLookupTable(namespace); // Now, register the implementations for (ClassHierarchyProto.Node child : root.getChildrenList()) { wireUpInheritanceRelationships(child); } }
private static ClassHierarchyProto.Node newNamedParameterNode( String name, String fullName, String simpleArgClassName, String fullArgClassName, boolean isSet, boolean isList, String documentation, // can be null String shortName, // can be null String[] instanceDefault, // can be null Iterable<ClassHierarchyProto.Node> children) { ClassHierarchyProto.NamedParameterNode.Builder namedParameterNodeBuilder = ClassHierarchyProto.NamedParameterNode.newBuilder() .setSimpleArgClassName(simpleArgClassName) .setFullArgClassName(fullArgClassName) .setIsSet(isSet) .setIsList(isList); if (documentation != null) { namedParameterNodeBuilder.setDocumentation(documentation); } if (shortName != null) { namedParameterNodeBuilder.setShortName(shortName); } if (instanceDefault != null) { namedParameterNodeBuilder.addAllInstanceDefault(Arrays.asList(instanceDefault)); } return ClassHierarchyProto.Node.newBuilder() .setName(name) .setFullName(fullName) .setNamedParameterNode(namedParameterNodeBuilder.build()) .addAllChildren(children) .build(); }
private static ClassHierarchyProto.Node newClassNode( String name, String fullName, boolean isInjectionCandidate, boolean isExternalConstructor, boolean isUnit, List<ClassHierarchyProto.ConstructorDef> injectableConstructors, List<ClassHierarchyProto.ConstructorDef> otherConstructors, List<String> implFullNames, Iterable<ClassHierarchyProto.Node> children) { return ClassHierarchyProto.Node.newBuilder() .setName(name) .setFullName(fullName) .setClassNode( ClassHierarchyProto.ClassNode.newBuilder() .setIsInjectionCandidate(isInjectionCandidate) .setIsExternalConstructor(isExternalConstructor) .setIsUnit(isUnit) .addAllInjectableConstructors(injectableConstructors) .addAllOtherConstructors(otherConstructors) .addAllImplFullNames(implFullNames) .build()) .addAllChildren(children) .build(); }
public void validatePlan() throws IOException, BindException, InjectionException { final Tang t = Tang.Factory.getTang(); // TODO Use the AvroClassHierarchySerializer final ClassHierarchyProto.Node root; try (final InputStream chin = new FileInputStream(this.ch)) { root = ClassHierarchyProto.Node.parseFrom(chin); } final ClassHierarchy classHierarchy = new ProtocolBufferClassHierarchy(root); final ConfigurationBuilder cb = t.newConfigurationBuilder(classHierarchy); if (!inConfig.canRead()) { throw new IOException("Cannot read input config file: " + inConfig); } ConfigurationFile.addConfiguration(cb, inConfig); if (target != null) { final Injector i = t.newInjector(cb.build()); final InjectionPlan<?> ip = i.getInjectionPlan(target); if (!ip.isInjectable()) { throw new InjectionException(target + " is not injectable: " + ip.toCantInjectString()); } } ConfigurationFile.writeConfigurationFile(cb.build(), outConfig); // Injector i = t.newInjector(cb.build()); // InjectionPlan<?> ip = i.getInjectionPlan(target); // try (final OutputStream ipout = new FileOutputStream(injectionPlan)) { // new ProtocolBufferInjectionPlan().serialize(ip).writeTo(ipout); // } }
private static ClassHierarchyProto.Node newPackageNode( String name, String fullName, Iterable<ClassHierarchyProto.Node> children) { return ClassHierarchyProto.Node.newBuilder() .setPackageNode(ClassHierarchyProto.PackageNode.newBuilder().build()) .setName(name) .setFullName(fullName) .addAllChildren(children) .build(); }
@SuppressWarnings({"rawtypes", "unchecked"}) private void wireUpInheritanceRelationships(final ClassHierarchyProto.Node n) { if (n.hasClassNode()) { final ClassHierarchyProto.ClassNode 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 (String impl : cn.getImplFullNamesList()) { 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 (ClassHierarchyProto.Node child : n.getChildrenList()) { wireUpInheritanceRelationships(child); } }
private static void parseSubHierarchy(Node parent, ClassHierarchyProto.Node n) { final Node parsed; if (n.hasPackageNode()) { parsed = new PackageNodeImpl(parent, n.getName(), n.getFullName()); } else if (n.hasNamedParameterNode()) { ClassHierarchyProto.NamedParameterNode 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.getInstanceDefaultList().toArray(new String[0])); } else if (n.hasClassNode()) { ClassHierarchyProto.ClassNode cn = n.getClassNode(); List<ConstructorDef<?>> injectableConstructors = new ArrayList<>(); List<ConstructorDef<?>> allConstructors = new ArrayList<>(); for (ClassHierarchyProto.ConstructorDef injectable : cn.getInjectableConstructorsList()) { ConstructorDef<?> def = parseConstructorDef(injectable, true); injectableConstructors.add(def); allConstructors.add(def); } for (ClassHierarchyProto.ConstructorDef other : cn.getOtherConstructorsList()) { ConstructorDef<?> def = parseConstructorDef(other, false); allConstructors.add(def); } @SuppressWarnings("unchecked") ConstructorDef<Object>[] dummy = new ConstructorDef[0]; parsed = new ClassNodeImpl<>( parent, n.getName(), n.getFullName(), cn.getIsUnit(), cn.getIsInjectionCandidate(), cn.getIsExternalConstructor(), injectableConstructors.toArray(dummy), allConstructors.toArray(dummy), cn.getDefaultImplementation()); } else { throw new IllegalStateException("Bad protocol buffer: got abstract node" + n); } for (ClassHierarchyProto.Node child : n.getChildrenList()) { parseSubHierarchy(parsed, child); } }
/** * Deserialize a class hierarchy from a file. The file can be generated from either Java or C# * * @param file * @return * @throws IOException */ public static ClassHierarchy deserialize(final File file) throws IOException { try (final InputStream stream = new FileInputStream(file)) { final ClassHierarchyProto.Node root = ClassHierarchyProto.Node.parseFrom(stream); return new ProtocolBufferClassHierarchy(root); } }