Bug 613: Minimize use of xtend in binding-generator-impl.
authorMartin Vitez <mvitez@cisco.com>
Tue, 1 Apr 2014 08:20:39 +0000 (10:20 +0200)
committerRobert Varga <rovarga@cisco.com>
Wed, 9 Apr 2014 08:47:41 +0000 (08:47 +0000)
Signed-off-by: Martin Vitez <mvitez@cisco.com>
code-generator/binding-generator-impl/src/main/java/org/opendaylight/yangtools/sal/binding/generator/impl/InstanceIdentifierCodecImpl.java [new file with mode: 0644]
code-generator/binding-generator-impl/src/main/java/org/opendaylight/yangtools/sal/binding/generator/impl/InstanceIdentifierCodecImpl.xtend [deleted file]
code-generator/binding-generator-impl/src/main/java/org/opendaylight/yangtools/sal/binding/generator/impl/IntermediateMapping.java [new file with mode: 0644]
code-generator/binding-generator-impl/src/main/java/org/opendaylight/yangtools/sal/binding/generator/impl/IntermediateMapping.xtend [deleted file]
code-generator/binding-generator-impl/src/main/java/org/opendaylight/yangtools/sal/binding/generator/impl/RuntimeGeneratedMappingServiceImpl.java [new file with mode: 0644]
code-generator/binding-generator-impl/src/main/java/org/opendaylight/yangtools/sal/binding/generator/impl/RuntimeGeneratedMappingServiceImpl.xtend [deleted file]
code-generator/binding-generator-impl/src/main/java/org/opendaylight/yangtools/sal/binding/generator/util/JavassistUtils.java [new file with mode: 0644]
code-generator/binding-generator-impl/src/main/java/org/opendaylight/yangtools/sal/binding/generator/util/JavassistUtils.xtend [deleted file]

diff --git a/code-generator/binding-generator-impl/src/main/java/org/opendaylight/yangtools/sal/binding/generator/impl/InstanceIdentifierCodecImpl.java b/code-generator/binding-generator-impl/src/main/java/org/opendaylight/yangtools/sal/binding/generator/impl/InstanceIdentifierCodecImpl.java
new file mode 100644 (file)
index 0000000..0d91bd9
--- /dev/null
@@ -0,0 +1,211 @@
+/**
+ * Copyright (c) 2014 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.yangtools.sal.binding.generator.impl;
+
+import com.google.common.base.Objects;
+import com.google.common.collect.ImmutableList;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.Set;
+import java.util.WeakHashMap;
+import java.util.concurrent.ConcurrentHashMap;
+import org.eclipse.xtext.xbase.lib.Functions.Function0;
+import org.opendaylight.yangtools.concepts.Identifiable;
+import org.opendaylight.yangtools.sal.binding.generator.impl.CodecTypeUtils;
+import org.opendaylight.yangtools.yang.binding.Augmentation;
+import org.opendaylight.yangtools.yang.binding.DataObject;
+import org.opendaylight.yangtools.yang.binding.Identifier;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier.IdentifiableItem;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier.Item;
+import org.opendaylight.yangtools.yang.binding.util.BindingReflections;
+import org.opendaylight.yangtools.yang.common.QName;
+import org.opendaylight.yangtools.yang.data.api.CompositeNode;
+import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier.NodeIdentifier;
+import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier.NodeIdentifierWithPredicates;
+import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier.PathArgument;
+import org.opendaylight.yangtools.yang.data.api.Node;
+import org.opendaylight.yangtools.yang.data.impl.CompositeNodeTOImpl;
+import org.opendaylight.yangtools.yang.data.impl.SimpleNodeTOImpl;
+import org.opendaylight.yangtools.yang.data.impl.codec.CodecRegistry;
+import org.opendaylight.yangtools.yang.data.impl.codec.IdentifierCodec;
+import org.opendaylight.yangtools.yang.data.impl.codec.InstanceIdentifierCodec;
+import org.opendaylight.yangtools.yang.data.impl.codec.ValueWithQName;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class InstanceIdentifierCodecImpl implements InstanceIdentifierCodec {
+    private static final Logger LOG = LoggerFactory.getLogger(InstanceIdentifierCodecImpl.class);
+
+    private final CodecRegistry codecRegistry;
+
+    private final Map<Class<?>, Map<List<QName>, Class<?>>> classToPreviousAugment = Collections
+            .synchronizedMap(new WeakHashMap<Class<?>, Map<List<QName>, Class<?>>>());
+
+    public InstanceIdentifierCodecImpl(final CodecRegistry registry) {
+        this.codecRegistry = registry;
+    }
+
+    @Override
+    public InstanceIdentifier<? extends Object> deserialize(
+            org.opendaylight.yangtools.yang.data.api.InstanceIdentifier input) {
+        Class<?> baType = null;
+        List<org.opendaylight.yangtools.yang.data.api.InstanceIdentifier.PathArgument> biArgs = input.getPath();
+        List<QName> scannedPath = new ArrayList<>(biArgs.size());
+        List<InstanceIdentifier.PathArgument> baArgs = new ArrayList<InstanceIdentifier.PathArgument>(biArgs.size());
+        for (org.opendaylight.yangtools.yang.data.api.InstanceIdentifier.PathArgument biArg : biArgs) {
+
+            scannedPath.add(biArg.getNodeType());
+            org.opendaylight.yangtools.yang.binding.InstanceIdentifier.PathArgument baArg = deserializePathArgument(
+                    biArg, scannedPath);
+            if (baArg != null) {
+                baType = baArg.getType();
+            }
+            Map<List<QName>, Class<?>> injectAugment = classToPreviousAugment.get(baType);
+            if (injectAugment != null) {
+                Class<? extends DataObject> augment = (Class<? extends DataObject>) injectAugment.get(scannedPath);
+                if (augment != null) {
+                    baArgs.add(new Item(augment));
+                }
+            }
+            baArgs.add(baArg);
+        }
+        InstanceIdentifier ret = new InstanceIdentifier(baArgs, (Class<? extends DataObject>) baType);
+        LOG.debug("DOM Instance Identifier {} deserialized to {}", input, ret);
+        return ret;
+    }
+
+    private org.opendaylight.yangtools.yang.binding.InstanceIdentifier.PathArgument _deserializePathArgument(
+            final NodeIdentifier argument, final List<QName> processedPath) {
+        final Class cls = codecRegistry.getClassForPath(processedPath);
+        Item<DataObject> item = new Item<>(cls);
+        return item;
+    }
+
+    private org.opendaylight.yangtools.yang.binding.InstanceIdentifier.PathArgument _deserializePathArgument(
+            final NodeIdentifierWithPredicates argument, final List<QName> processedPath) {
+        final Class type = codecRegistry.getClassForPath(processedPath);
+        final IdentifierCodec codec = codecRegistry
+                .<Identifiable<? extends Object>> getIdentifierCodecForIdentifiable(type);
+        CompositeNode _compositeNode = this.toCompositeNode(argument);
+        ValueWithQName<CompositeNode> deserialize = codec.deserialize(_compositeNode);
+        Object value = null;
+        if (deserialize != null) {
+            value = deserialize.getValue();
+        }
+        return CodecTypeUtils.newIdentifiableItem(type, value);
+    }
+
+    public CompositeNode toCompositeNode(NodeIdentifierWithPredicates predicates) {
+        Set<Map.Entry<QName, Object>> keyValues = predicates.getKeyValues().entrySet();
+        List<Node<?>> values = new ArrayList<>(keyValues.size());
+        for (Map.Entry<QName, Object> keyValue : keyValues) {
+            values.add(new SimpleNodeTOImpl<Object>(keyValue.getKey(), null, keyValue.getValue()));
+        }
+        return new CompositeNodeTOImpl(predicates.getNodeType(), null, values);
+    }
+
+    @Override
+    public org.opendaylight.yangtools.yang.data.api.InstanceIdentifier serialize(InstanceIdentifier<?> input) {
+        Class<?> previousAugmentation = null;
+        List<InstanceIdentifier.PathArgument> pathArgs = input.getPath();
+        QName previousQName = null;
+        List<PathArgument> components = new ArrayList<>(pathArgs.size());
+        List<QName> qnamePath = new ArrayList<>(pathArgs.size());
+        for (InstanceIdentifier.PathArgument baArg : pathArgs) {
+
+            if (!Augmentation.class.isAssignableFrom(baArg.getType())) {
+                org.opendaylight.yangtools.yang.data.api.InstanceIdentifier.PathArgument biArg = serializePathArgument(
+                        baArg, previousQName);
+                previousQName = biArg.getNodeType();
+                components.add(biArg);
+                qnamePath.add(biArg.getNodeType());
+                ImmutableList<QName> immutableList = ImmutableList.copyOf(qnamePath);
+                codecRegistry.putPathToClass(immutableList, baArg.getType());
+                if (previousAugmentation != null) {
+                    updateAugmentationInjection(baArg.getType(), immutableList, previousAugmentation);
+                }
+                previousAugmentation = null;
+            } else {
+                previousQName = codecRegistry.getQNameForAugmentation(baArg.getType());
+                previousAugmentation = baArg.getType();
+            }
+        }
+        org.opendaylight.yangtools.yang.data.api.InstanceIdentifier ret = new org.opendaylight.yangtools.yang.data.api.InstanceIdentifier(
+                components);
+        LOG.debug("Binding Instance Identifier {} serialized to DOM InstanceIdentifier {}", input, ret);
+        return ret;
+    }
+
+    public Class<? extends Object> updateAugmentationInjection(Class<? extends DataObject> class1,
+            ImmutableList<QName> list, Class<?> augmentation) {
+        if (classToPreviousAugment.get(class1) == null) {
+            classToPreviousAugment.put(class1, new ConcurrentHashMap<List<QName>, Class<?>>());
+        }
+        return classToPreviousAugment.get(class1).put(list, augmentation);
+    }
+
+    private PathArgument _serializePathArgument(Item<?> argument, QName previousQname) {
+        Class<?> type = argument.getType();
+        QName qname = BindingReflections.findQName(type);
+        if (previousQname == null || (BindingReflections.isAugmentationChild(argument.getType()))) {
+            return new NodeIdentifier(qname);
+        }
+        return new NodeIdentifier(QName.create(previousQname, qname.getLocalName()));
+    }
+
+    private PathArgument _serializePathArgument(IdentifiableItem argument, QName previousQname) {
+        Map<QName, Object> predicates = new HashMap<>();
+        Class type = argument.getType();
+        IdentifierCodec<? extends Object> keyCodec = codecRegistry.getIdentifierCodecForIdentifiable(type);
+        QName qname = BindingReflections.findQName(type);
+        if (previousQname != null && !(BindingReflections.isAugmentationChild(argument.getType()))) {
+            qname = QName.create(previousQname, qname.getLocalName());
+        }
+        ValueWithQName combinedInput = new ValueWithQName(previousQname, argument.getKey());
+        CompositeNode compositeOutput = keyCodec.serialize(combinedInput);
+        for (Node<?> outputValue : compositeOutput.getValue()) {
+            predicates.put(outputValue.getNodeType(), outputValue.getValue());
+        }
+        if (previousQname == null) {
+            return new NodeIdentifierWithPredicates(qname, predicates);
+        }
+        return new NodeIdentifierWithPredicates(qname, predicates);
+    }
+
+    private org.opendaylight.yangtools.yang.binding.InstanceIdentifier.PathArgument deserializePathArgument(
+            final PathArgument argument, final List<QName> processedPath) {
+        if (argument instanceof NodeIdentifier) {
+            return _deserializePathArgument((NodeIdentifier) argument, processedPath);
+        } else if (argument instanceof NodeIdentifierWithPredicates) {
+            return _deserializePathArgument((NodeIdentifierWithPredicates) argument, processedPath);
+        } else {
+            throw new IllegalArgumentException("Unhandled parameter types: "
+                    + Arrays.<Object> asList(argument, processedPath).toString());
+        }
+    }
+
+    private PathArgument serializePathArgument(
+            final org.opendaylight.yangtools.yang.binding.InstanceIdentifier.PathArgument argument,
+            final QName previousQname) {
+        if (argument instanceof IdentifiableItem) {
+            return _serializePathArgument((IdentifiableItem) argument, previousQname);
+        } else if (argument instanceof Item) {
+            return _serializePathArgument((Item<?>) argument, previousQname);
+        } else {
+            throw new IllegalArgumentException("Unhandled parameter types: "
+                    + Arrays.<Object> asList(argument, previousQname).toString());
+        }
+    }
+
+}
diff --git a/code-generator/binding-generator-impl/src/main/java/org/opendaylight/yangtools/sal/binding/generator/impl/InstanceIdentifierCodecImpl.xtend b/code-generator/binding-generator-impl/src/main/java/org/opendaylight/yangtools/sal/binding/generator/impl/InstanceIdentifierCodecImpl.xtend
deleted file mode 100644 (file)
index 3396f4e..0000000
+++ /dev/null
@@ -1,160 +0,0 @@
-/*
- * Copyright (c) 2014 Cisco Systems, Inc. and others.  All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-package org.opendaylight.yangtools.sal.binding.generator.impl
-
-import com.google.common.collect.ImmutableList
-import java.util.ArrayList
-import java.util.Collections
-import java.util.HashMap
-import java.util.List
-import java.util.Map
-import java.util.WeakHashMap
-import java.util.concurrent.ConcurrentHashMap
-import org.opendaylight.yangtools.yang.binding.Augmentation
-import org.opendaylight.yangtools.yang.binding.DataObject
-import org.opendaylight.yangtools.yang.binding.InstanceIdentifier
-import org.opendaylight.yangtools.yang.binding.InstanceIdentifier.IdentifiableItem
-import org.opendaylight.yangtools.yang.binding.InstanceIdentifier.Item
-import org.opendaylight.yangtools.yang.binding.util.BindingReflections
-import org.opendaylight.yangtools.yang.common.QName
-import org.opendaylight.yangtools.yang.data.api.CompositeNode
-import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier.NodeIdentifier
-import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier.NodeIdentifierWithPredicates
-import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier.PathArgument
-import org.opendaylight.yangtools.yang.data.api.Node
-import org.opendaylight.yangtools.yang.data.impl.CompositeNodeTOImpl
-import org.opendaylight.yangtools.yang.data.impl.SimpleNodeTOImpl
-import org.opendaylight.yangtools.yang.data.impl.codec.CodecRegistry
-import org.opendaylight.yangtools.yang.data.impl.codec.IdentifierCodec
-import org.opendaylight.yangtools.yang.data.impl.codec.InstanceIdentifierCodec
-import org.opendaylight.yangtools.yang.data.impl.codec.ValueWithQName
-import org.slf4j.LoggerFactory
-
-class InstanceIdentifierCodecImpl implements InstanceIdentifierCodec {
-
-    private static val LOG = LoggerFactory.getLogger(InstanceIdentifierCodecImpl);
-    val CodecRegistry codecRegistry;
-
-    val Map<Class<?>, Map<List<QName>, Class<?>>> classToPreviousAugment = Collections.synchronizedMap(new WeakHashMap);
-
-    public new(CodecRegistry registry) {
-        codecRegistry = registry;
-    }
-
-
-    override deserialize(org.opendaylight.yangtools.yang.data.api.InstanceIdentifier input) {
-        var Class<?> baType = null
-        val biArgs = input.path
-        val scannedPath = new ArrayList<QName>(biArgs.size);
-        val baArgs = new ArrayList<InstanceIdentifier.PathArgument>(biArgs.size)
-        for(biArg : biArgs) {
-            scannedPath.add(biArg.nodeType);
-            val baArg = deserializePathArgument(biArg,scannedPath)
-            baType = baArg?.type
-            val injectAugment = classToPreviousAugment.get(baType);
-            if(injectAugment != null) {
-                val augment = injectAugment.get(scannedPath) as Class<? extends DataObject>;
-                if(augment != null) {
-                    baArgs.add(new Item(augment));
-                }
-            }
-            baArgs.add(baArg)
-        }
-        val ret = new InstanceIdentifier(baArgs,baType as Class<? extends DataObject>);
-        LOG.debug("DOM Instance Identifier {} deserialized to {}",input,ret);
-        return ret;
-    }
-
-    private def dispatch InstanceIdentifier.PathArgument deserializePathArgument(NodeIdentifier argument,List<QName> processedPath) {
-        val Class cls = codecRegistry.getClassForPath(processedPath);
-        return new Item(cls);
-    }
-
-
-    private def dispatch InstanceIdentifier.PathArgument deserializePathArgument(NodeIdentifierWithPredicates argument,List<QName> processedPath) {
-        val Class type = codecRegistry.getClassForPath(processedPath);
-        val IdentifierCodec codec = codecRegistry.getIdentifierCodecForIdentifiable(type);
-        val value = codec.deserialize(argument.toCompositeNode())?.value;
-        return CodecTypeUtils.newIdentifiableItem(type,value);
-    }
-
-    def CompositeNode toCompositeNode(NodeIdentifierWithPredicates predicates) {
-        val keyValues = predicates.keyValues.entrySet;
-        val values = new ArrayList<Node<?>>(keyValues.size)
-        for(keyValue : keyValues) {
-            values.add(new SimpleNodeTOImpl(keyValue.key,null,keyValue.value))
-        }
-        return new CompositeNodeTOImpl(predicates.nodeType,null,values);
-    }
-
-    override serialize(InstanceIdentifier<?> input) {
-        var Class<?> previousAugmentation = null
-        val pathArgs = input.path as List<InstanceIdentifier.PathArgument>
-        var QName previousQName = null;
-        val components = new ArrayList<PathArgument>(pathArgs.size);
-        val qnamePath = new ArrayList<QName>(pathArgs.size);
-        for(baArg : pathArgs) {
-
-            if(!Augmentation.isAssignableFrom(baArg.type)) {
-                val biArg = serializePathArgument(baArg,previousQName);
-                previousQName = biArg.nodeType;
-                components.add(biArg);
-                qnamePath.add(biArg.nodeType);
-                val immutableList = ImmutableList.copyOf(qnamePath);
-                codecRegistry.putPathToClass(immutableList,baArg.type);
-                if(previousAugmentation !== null) {
-                    updateAugmentationInjection(baArg.type,immutableList,previousAugmentation)
-                }
-
-                previousAugmentation = null;
-            } else {
-                previousQName = codecRegistry.getQNameForAugmentation(baArg.type as Class<?>);
-                previousAugmentation = baArg.type;
-            }
-        }
-        val ret = new org.opendaylight.yangtools.yang.data.api.InstanceIdentifier(components);
-        LOG.debug("Binding Instance Identifier {} serialized to DOM InstanceIdentifier {}",input,ret);
-        return ret;
-    }
-
-    def updateAugmentationInjection(Class<? extends DataObject> class1, ImmutableList<QName> list, Class<?> augmentation) {
-        if(classToPreviousAugment.get(class1) == null) {
-            classToPreviousAugment.put(class1,new ConcurrentHashMap());
-        }
-        classToPreviousAugment.get(class1).put(list,augmentation);
-    }
-
-    private def dispatch PathArgument serializePathArgument(Item<?> argument, QName previousQname) {
-        val type = argument.type;
-        val qname = BindingReflections.findQName(type);
-        if(previousQname == null || (BindingReflections.isAugmentationChild(argument.type))) {
-            return new NodeIdentifier(qname);
-        }
-        return new NodeIdentifier(QName.create(previousQname,qname.localName));
-    }
-
-    @SuppressWarnings("rawtypes")
-    private def dispatch PathArgument serializePathArgument(IdentifiableItem argument, QName previousQname) {
-        val Map<QName,Object> predicates = new HashMap();
-        val type = argument.type;
-        val keyCodec = codecRegistry.getIdentifierCodecForIdentifiable(type);
-        var QName qname = BindingReflections.findQName(type);
-        if(previousQname != null && !(BindingReflections.isAugmentationChild(argument.type))) {
-            qname = QName.create(previousQname,qname.localName);
-        }
-        val combinedInput =  new ValueWithQName(previousQname,argument.key)
-        val compositeOutput = keyCodec.serialize(combinedInput as ValueWithQName);
-        for(outputValue :compositeOutput.value) {
-            predicates.put(outputValue.nodeType,outputValue.value);
-        }
-        if(previousQname == null) {
-            return new NodeIdentifierWithPredicates(qname,predicates);
-        }
-        return new NodeIdentifierWithPredicates(qname,predicates);
-    }
-}
diff --git a/code-generator/binding-generator-impl/src/main/java/org/opendaylight/yangtools/sal/binding/generator/impl/IntermediateMapping.java b/code-generator/binding-generator-impl/src/main/java/org/opendaylight/yangtools/sal/binding/generator/impl/IntermediateMapping.java
new file mode 100644 (file)
index 0000000..d0020cf
--- /dev/null
@@ -0,0 +1,74 @@
+/**
+ * Copyright (c) 2014 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.yangtools.sal.binding.generator.impl;
+
+import com.google.common.base.Preconditions;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+import java.util.Map;
+import java.util.Map.Entry;
+
+import org.opendaylight.yangtools.yang.common.QName;
+import org.opendaylight.yangtools.yang.data.api.Node;
+import org.opendaylight.yangtools.yang.data.impl.CompositeNodeTOImpl;
+import org.opendaylight.yangtools.yang.data.impl.SimpleNodeTOImpl;
+
+@SuppressWarnings("unchecked")
+public class IntermediateMapping {
+
+    public static Node<? extends Object> toNode(final Map<? extends Object, ? extends Object> map) {
+        if ((map instanceof Node<?>)) {
+            return ((Node<?>) map);
+        }
+        final Map<QName, Object> nodeMap = ((Map<QName, Object>) map);
+        Preconditions.checkArgument(map.size() == 1);
+        final Entry<QName, Object> elem = nodeMap.entrySet().iterator().next();
+        final QName qname = elem.getKey();
+        final Object value = elem.getValue();
+        return toNodeImpl(qname, value);
+    }
+
+    protected static Node<? extends Object> _toNodeImpl(final QName name, final List<? extends Object> objects) {
+        List<Node<? extends Object>> values = new ArrayList<>(objects.size());
+        for (Object obj : objects) {
+            if ((obj instanceof Node<?>)) {
+                values.add(((Node<?>) obj));
+            } else {
+                if ((obj instanceof Map<?, ?>)) {
+                    Node<? extends Object> _node = IntermediateMapping.toNode(((Map<?, ?>) obj));
+                    values.add(_node);
+                }
+            }
+        }
+        return new CompositeNodeTOImpl(name, null, values);
+    }
+
+    protected static Node<? extends Object> _toNodeImpl(final QName name, final Map<QName, Object> object) {
+        throw new UnsupportedOperationException("Unsupported node hierarchy.");
+    }
+
+    protected static Node<? extends Object> _toNodeImpl(final QName name, final Object object) {
+        return new SimpleNodeTOImpl<Object>(name, null, object);
+    }
+
+    public static Node<? extends Object> toNodeImpl(final QName name, final Object objects) {
+        if (objects instanceof List) {
+            return _toNodeImpl(name, (List<?>) objects);
+        } else if (objects instanceof Map) {
+            return _toNodeImpl(name, (Map<QName, Object>) objects);
+        } else if (objects != null) {
+            return _toNodeImpl(name, objects);
+        } else {
+            throw new IllegalArgumentException("Unhandled parameter types: "
+                    + Arrays.<Object> asList(name, objects).toString());
+        }
+    }
+
+}
diff --git a/code-generator/binding-generator-impl/src/main/java/org/opendaylight/yangtools/sal/binding/generator/impl/IntermediateMapping.xtend b/code-generator/binding-generator-impl/src/main/java/org/opendaylight/yangtools/sal/binding/generator/impl/IntermediateMapping.xtend
deleted file mode 100644 (file)
index 9c42275..0000000
+++ /dev/null
@@ -1,55 +0,0 @@
-/*
- * Copyright (c) 2014 Cisco Systems, Inc. and others.  All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-package org.opendaylight.yangtools.sal.binding.generator.impl
-
-import org.opendaylight.yangtools.yang.data.api.Node
-import java.util.Map
-import org.opendaylight.yangtools.yang.common.QName
-import java.util.List
-import java.util.ArrayList
-import org.opendaylight.yangtools.yang.data.impl.CompositeNodeTOImpl
-import org.opendaylight.yangtools.yang.data.impl.SimpleNodeTOImpl
-import com.google.common.base.Preconditions
-
-class IntermediateMapping {
-
-
-
-    static def Node<?> toNode(Map<?,?> map) {
-        if(map instanceof Node<?>) {
-            return map as Node<?>;
-        }
-        val nodeMap = map as Map<QName,Object>;
-        Preconditions.checkArgument(map.size == 1);
-        val elem = nodeMap.entrySet.iterator.next;
-        val qname = elem.key;
-        val value = elem.value;
-        toNodeImpl(qname, value);
-    }
-
-
-    static def dispatch Node<?> toNodeImpl(QName name, List<?> objects) {
-        val values = new ArrayList<Node<?>>(objects.size);
-        for (obj : objects) {
-            if(obj instanceof Node<?>) {
-                values.add(obj as Node<?>);
-            } else if(obj instanceof Map<?,?>) {
-                values.add(toNode(obj as Map<?,?>));
-            }
-        }
-        return new CompositeNodeTOImpl(name, null, values);
-    }
-
-    static def dispatch Node<?> toNodeImpl(QName name, Map<QName, Object> object) {
-        throw new UnsupportedOperationException("Unsupported node hierarchy.");
-    }
-
-    static def dispatch Node<?> toNodeImpl(QName name, Object object) {
-        return new SimpleNodeTOImpl(name, null, object);
-    }
-}
diff --git a/code-generator/binding-generator-impl/src/main/java/org/opendaylight/yangtools/sal/binding/generator/impl/RuntimeGeneratedMappingServiceImpl.java b/code-generator/binding-generator-impl/src/main/java/org/opendaylight/yangtools/sal/binding/generator/impl/RuntimeGeneratedMappingServiceImpl.java
new file mode 100644 (file)
index 0000000..d2fbe8b
--- /dev/null
@@ -0,0 +1,456 @@
+/**
+ * Copyright (c) 2014 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.yangtools.sal.binding.generator.impl;
+
+import com.google.common.base.Objects;
+import com.google.common.base.Optional;
+import com.google.common.collect.HashMultimap;
+import com.google.common.util.concurrent.SettableFuture;
+
+import java.util.AbstractMap.SimpleEntry;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.Set;
+import java.util.concurrent.Callable;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ConcurrentMap;
+import java.util.concurrent.Future;
+
+import javassist.ClassPool;
+
+import org.eclipse.xtext.xbase.lib.Exceptions;
+import org.eclipse.xtext.xbase.lib.Extension;
+import org.opendaylight.yangtools.binding.generator.util.BindingGeneratorUtil;
+import org.opendaylight.yangtools.binding.generator.util.ReferencedTypeImpl;
+import org.opendaylight.yangtools.binding.generator.util.Types;
+import org.opendaylight.yangtools.sal.binding.generator.api.ClassLoadingStrategy;
+import org.opendaylight.yangtools.sal.binding.generator.impl.BindingGeneratorImpl;
+import org.opendaylight.yangtools.sal.binding.generator.impl.GeneratedClassLoadingStrategy;
+import org.opendaylight.yangtools.sal.binding.generator.impl.LazyGeneratedCodecRegistry;
+import org.opendaylight.yangtools.sal.binding.generator.impl.ModuleContext;
+import org.opendaylight.yangtools.sal.binding.generator.impl.SchemaLock;
+import org.opendaylight.yangtools.sal.binding.generator.impl.TransformerGenerator;
+import org.opendaylight.yangtools.sal.binding.generator.util.YangSchemaUtils;
+import org.opendaylight.yangtools.sal.binding.model.api.Type;
+import org.opendaylight.yangtools.sal.binding.model.api.type.builder.GeneratedTypeBuilder;
+import org.opendaylight.yangtools.yang.binding.Augmentation;
+import org.opendaylight.yangtools.yang.binding.BindingMapping;
+import org.opendaylight.yangtools.yang.binding.DataContainer;
+import org.opendaylight.yangtools.yang.binding.DataObject;
+import org.opendaylight.yangtools.yang.binding.RpcService;
+import org.opendaylight.yangtools.yang.common.QName;
+import org.opendaylight.yangtools.yang.data.api.CompositeNode;
+import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier;
+import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier.NodeIdentifierWithPredicates;
+import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier.PathArgument;
+import org.opendaylight.yangtools.yang.data.api.Node;
+import org.opendaylight.yangtools.yang.data.impl.CompositeNodeTOImpl;
+import org.opendaylight.yangtools.yang.data.impl.SimpleNodeTOImpl;
+import org.opendaylight.yangtools.yang.data.impl.codec.AugmentationCodec;
+import org.opendaylight.yangtools.yang.data.impl.codec.BindingIndependentMappingService;
+import org.opendaylight.yangtools.yang.data.impl.codec.CodecRegistry;
+import org.opendaylight.yangtools.yang.data.impl.codec.DataContainerCodec;
+import org.opendaylight.yangtools.yang.data.impl.codec.DeserializationException;
+import org.opendaylight.yangtools.yang.data.impl.codec.ValueWithQName;
+import org.opendaylight.yangtools.yang.model.api.Module;
+import org.opendaylight.yangtools.yang.model.api.RpcDefinition;
+import org.opendaylight.yangtools.yang.model.api.SchemaContext;
+import org.opendaylight.yangtools.yang.model.api.SchemaContextHolder;
+import org.opendaylight.yangtools.yang.model.api.SchemaContextListener;
+import org.opendaylight.yangtools.yang.model.api.SchemaNode;
+import org.opendaylight.yangtools.yang.model.api.SchemaPath;
+import org.opendaylight.yangtools.yang.model.api.TypeDefinition;
+import org.opendaylight.yangtools.yang.model.util.SchemaContextUtil;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class RuntimeGeneratedMappingServiceImpl implements BindingIndependentMappingService, SchemaContextListener,
+        SchemaLock, AutoCloseable, SchemaContextHolder {
+
+    private static final Logger LOG = LoggerFactory.getLogger(RuntimeGeneratedMappingServiceImpl.class);
+
+    private ClassPool pool;
+
+    @Extension
+    private TransformerGenerator binding;
+
+    @Extension
+    private LazyGeneratedCodecRegistry registry;
+
+    private final ConcurrentMap<Type, Type> typeDefinitions = new ConcurrentHashMap<>();
+    private final ConcurrentMap<Type, GeneratedTypeBuilder> typeToDefinition = new ConcurrentHashMap<>();
+    private final ConcurrentMap<Type, SchemaNode> typeToSchemaNode = new ConcurrentHashMap<>();
+    private final ConcurrentMap<Type, Set<QName>> serviceTypeToRpc = new ConcurrentHashMap<>();
+    private final HashMultimap<Type, SettableFuture<Type>> promisedTypes = HashMultimap.create();
+    private final ClassLoadingStrategy classLoadingStrategy;
+    private SchemaContext schemaContext;
+
+    public RuntimeGeneratedMappingServiceImpl() {
+        this(GeneratedClassLoadingStrategy.getTCCLClassLoadingStrategy());
+    }
+
+    public RuntimeGeneratedMappingServiceImpl(ClassLoadingStrategy strat) {
+        classLoadingStrategy = strat;
+    }
+
+    public ClassPool getPool() {
+        return this.pool;
+    }
+
+    public void setPool(final ClassPool pool) {
+        this.pool = pool;
+    }
+
+    @Override
+    public SchemaContext getSchemaContext() {
+        return schemaContext;
+    }
+
+    public void setSchemaContext(final SchemaContext schemaContext) {
+        this.schemaContext = schemaContext;
+    }
+
+    public TransformerGenerator getBinding() {
+        return this.binding;
+    }
+
+    public void setBinding(final TransformerGenerator binding) {
+        this.binding = binding;
+    }
+
+    public LazyGeneratedCodecRegistry getRegistry() {
+        return registry;
+    }
+
+    public void setRegistry(final LazyGeneratedCodecRegistry registry) {
+        this.registry = registry;
+    }
+
+    public ConcurrentMap<Type, GeneratedTypeBuilder> getTypeToDefinition() {
+        return typeToDefinition;
+    }
+
+    public ConcurrentMap<Type, Type> getTypeDefinitions() {
+        return typeDefinitions;
+    }
+
+    public ConcurrentMap<Type, SchemaNode> getTypeToSchemaNode() {
+        return typeToSchemaNode;
+    }
+
+    public ConcurrentMap<Type, Set<QName>> getServiceTypeToRpc() {
+        return serviceTypeToRpc;
+    }
+
+    @Override
+    public void onGlobalContextUpdated(final SchemaContext arg0) {
+        this.setSchemaContext(arg0);
+        this.recreateBindingContext(arg0);
+        LazyGeneratedCodecRegistry _registry = this.getRegistry();
+        _registry.onGlobalContextUpdated(arg0);
+    }
+
+    private void recreateBindingContext(SchemaContext schemaContext) {
+        BindingGeneratorImpl newBinding = new BindingGeneratorImpl();
+        newBinding.generateTypes(schemaContext);
+
+        for (Map.Entry<Module, ModuleContext> entry : newBinding.getModuleContexts().entrySet()) {
+
+            registry.onModuleContextAdded(schemaContext, entry.getKey(), entry.getValue());
+            binding.getPathToType().putAll(entry.getValue().getChildNodes());
+            Module module = entry.getKey();
+            ModuleContext context = entry.getValue();
+            updateBindingFor(context.getChildNodes(), schemaContext);
+            updateBindingFor(context.getCases(), schemaContext);
+            String namespace = BindingGeneratorUtil.moduleNamespaceToPackageName(module);
+
+            if (!module.getRpcs().isEmpty()) {
+                Set<QName> rpcs = new HashSet<>();
+                for (RpcDefinition rpc : module.getRpcs()) {
+                    rpcs.add(rpc.getQName());
+                }
+                Type serviceClass = new ReferencedTypeImpl(namespace, BindingMapping.getClassName(module.getName())
+                        + "Service");
+                serviceTypeToRpc.put(serviceClass, rpcs);
+            }
+
+            Map<SchemaPath, Type> typedefs = context.getTypedefs();
+            for (Map.Entry<SchemaPath, Type> typedef : typedefs.entrySet()) {
+                Type value = typedef.getValue();
+                Type typeRef = new ReferencedTypeImpl(value.getPackageName(), value.getName());
+                binding.getTypeDefinitions().put(typeRef, value);
+                TypeDefinition<?> schemaNode = YangSchemaUtils.findTypeDefinition(schemaContext, typedef.getKey());
+                if (schemaNode != null) {
+
+                    binding.getTypeToSchemaNode().put(typeRef, schemaNode);
+                } else {
+                    LOG.error("Type definition for {} is not available", value);
+                }
+            }
+            List<GeneratedTypeBuilder> augmentations = context.getAugmentations();
+            for (GeneratedTypeBuilder augmentation : augmentations) {
+                binding.getTypeToDefinition().put(augmentation, augmentation);
+            }
+            binding.getTypeToAugmentation().putAll(context.getTypeToAugmentation());
+            for (GeneratedTypeBuilder augmentation : augmentations) {
+                updatePromisedSchemas(augmentation);
+            }
+        }
+    }
+
+    public CompositeNode toDataDom(final DataObject data) {
+        return toCompositeNodeImpl(data);
+    }
+
+    @Override
+    public Entry<InstanceIdentifier, CompositeNode> toDataDom(
+            final Entry<org.opendaylight.yangtools.yang.binding.InstanceIdentifier<? extends DataObject>, DataObject> entry) {
+        try {
+            org.opendaylight.yangtools.yang.data.api.InstanceIdentifier key = toDataDom(entry.getKey());
+            CompositeNode data;
+            if (Augmentation.class.isAssignableFrom(entry.getKey().getTargetType())) {
+                data = toCompositeNodeImplAugument(key, entry.getValue());
+            } else {
+                data = toCompositeNodeImpl(key, entry.getValue());
+            }
+            return new SimpleEntry<org.opendaylight.yangtools.yang.data.api.InstanceIdentifier, CompositeNode>(key,
+                    data);
+
+        } catch (Exception e) {
+            LOG.error("Error during serialization for {}.", entry.getKey(), e);
+            throw e;
+        }
+    }
+
+    private CompositeNode toCompositeNodeImpl(DataObject object) {
+        Class<? extends DataContainer> cls = object.getImplementedInterface();
+        waitForSchema(cls);
+        DataContainerCodec<DataObject> codec = (DataContainerCodec<DataObject>) registry.getCodecForDataObject(cls);
+        return codec.serialize(new ValueWithQName<DataObject>(null, object));
+    }
+
+    private CompositeNode toCompositeNodeImpl(org.opendaylight.yangtools.yang.data.api.InstanceIdentifier identifier,
+            DataObject object) {
+        PathArgument last = identifier.getPath().get(identifier.getPath().size() - 1);
+        Class<? extends DataContainer> cls = object.getImplementedInterface();
+        waitForSchema(cls);
+        DataContainerCodec<DataObject> codec = (DataContainerCodec<DataObject>) registry.getCodecForDataObject(cls);
+        return codec.serialize(new ValueWithQName<DataObject>(last.getNodeType(), object));
+    }
+
+    private CompositeNode toCompositeNodeImplAugument(
+            org.opendaylight.yangtools.yang.data.api.InstanceIdentifier identifier, DataObject object) {
+
+        // val cls = object.implementedInterface;
+        // waitForSchema(cls);
+        org.opendaylight.yangtools.yang.data.api.InstanceIdentifier.PathArgument last = identifier.getPath().get(
+                identifier.getPath().size() - 1);
+        AugmentationCodec codec = registry.getCodecForAugmentation((Class) object.getImplementedInterface());
+        CompositeNode ret = codec.serialize(new ValueWithQName<DataObject>(last.getNodeType(), object));
+        if (last instanceof NodeIdentifierWithPredicates) {
+            NodeIdentifierWithPredicates predicates = (NodeIdentifierWithPredicates) last;
+            List<Node<?>> newNodes = new ArrayList<Node<?>>(predicates.getKeyValues().size());
+            for (Map.Entry<QName, Object> predicate : predicates.getKeyValues().entrySet()) {
+                newNodes.add(new SimpleNodeTOImpl<Object>(predicate.getKey(), null, predicate.getValue()));
+            }
+            newNodes.addAll(ret.getChildren());
+            return new CompositeNodeTOImpl(last.getNodeType(), null, newNodes);
+        }
+        return ret;
+    }
+
+    @Override
+    public void waitForSchema(Class class1) {
+        if (registry.isCodecAvailable(class1)) {
+            return;
+        }
+        Type ref = Types.typeForClass(class1);
+        getSchemaWithRetry(ref);
+    }
+
+    public InstanceIdentifier toDataDom(
+            final org.opendaylight.yangtools.yang.binding.InstanceIdentifier<? extends DataObject> path) {
+        for (final org.opendaylight.yangtools.yang.binding.InstanceIdentifier.PathArgument arg : path.getPath()) {
+            this.waitForSchema(arg.getType());
+        }
+        return registry.getInstanceIdentifierCodec().serialize(path);
+    }
+
+    @Override
+    public DataObject dataObjectFromDataDom(
+            final org.opendaylight.yangtools.yang.binding.InstanceIdentifier<? extends DataObject> path,
+            final CompositeNode node) {
+        return (DataObject) dataObjectFromDataDom(path.getTargetType(), node);
+    }
+
+    @Override
+    public org.opendaylight.yangtools.yang.binding.InstanceIdentifier<? extends Object> fromDataDom(
+            final InstanceIdentifier entry) {
+        try {
+            return tryDeserialization(new Callable<org.opendaylight.yangtools.yang.binding.InstanceIdentifier<? extends Object>>() {
+                @Override
+                public org.opendaylight.yangtools.yang.binding.InstanceIdentifier<? extends Object> call() {
+                    return getRegistry().getInstanceIdentifierCodec().deserialize(entry);
+                }
+            });
+        } catch (Throwable _e) {
+            throw Exceptions.sneakyThrow(_e);
+        }
+    }
+
+    @Override
+    public CodecRegistry getCodecRegistry() {
+        return this.getRegistry();
+    }
+
+    private static <T> T tryDeserialization(Callable<T> deserializationBlock) throws DeserializationException {
+        try {
+            return deserializationBlock.call();
+        } catch (Exception e) {
+            // FIXME: Make this block providing more information.
+            throw new DeserializationException(e);
+        }
+    }
+
+    private void updateBindingFor(Map<SchemaPath, GeneratedTypeBuilder> map, SchemaContext module) {
+        for (Map.Entry<SchemaPath, GeneratedTypeBuilder> entry : map.entrySet()) {
+            SchemaNode schemaNode = SchemaContextUtil.findDataSchemaNode(module, entry.getKey());
+
+            // LOG.info("{} : {}",entry.key,entry.value.fullyQualifiedName)
+            Type typeRef = new ReferencedTypeImpl(entry.getValue().getPackageName(), entry.getValue().getName());
+            typeToDefinition.put(typeRef, entry.getValue());
+            if (schemaNode != null) {
+                typeToSchemaNode.put(typeRef, schemaNode);
+                updatePromisedSchemas(entry.getValue());
+            }
+        }
+    }
+
+    public void init() {
+        binding = new TransformerGenerator(pool);
+        registry = new LazyGeneratedCodecRegistry(this, classLoadingStrategy);
+
+        registry.setGenerator(binding);
+        // binding.staticFieldsInitializer = registry
+        binding.setListener(registry);
+        binding.setTypeToDefinition(typeToDefinition);
+        binding.setTypeToSchemaNode(typeToSchemaNode);
+        binding.setTypeDefinitions(typeDefinitions);
+
+        // if (ctx !== null) {
+        // listenerRegistration = ctx.registerService(SchemaServiceListener,
+        // this, new Hashtable<String, String>());
+        // }
+    }
+
+    @Override
+    public Set<QName> getRpcQNamesFor(Class<? extends RpcService> service) {
+        Set<QName> serviceRef = serviceTypeToRpc.get(new ReferencedTypeImpl(service.getPackage().getName(), service
+                .getSimpleName()));
+        if (serviceRef == null) {
+            serviceRef = Collections.emptySet();
+        }
+        return serviceRef;
+    }
+
+    private void getSchemaWithRetry(Type type) {
+        try {
+            if (typeToDefinition.containsKey(type)) {
+                return;
+            }
+            LOG.info("Thread blocked waiting for schema for: {}", type.getFullyQualifiedName());
+            waitForTypeDefinition(type).get();
+            LOG.info("Schema for {} became available, thread unblocked", type.getFullyQualifiedName());
+        } catch (Throwable t) {
+            Exceptions.sneakyThrow(t);
+        }
+    }
+
+    private Future<Type> waitForTypeDefinition(final Type type) {
+        final SettableFuture<Type> future = SettableFuture.<Type> create();
+        promisedTypes.put(type, future);
+        return future;
+    }
+
+    private void updatePromisedSchemas(Type builder) {
+        Type ref = new ReferencedTypeImpl(builder.getPackageName(), builder.getName());
+        Set<SettableFuture<Type>> futures = promisedTypes.get(ref);
+        if (futures == null || futures.isEmpty()) {
+            return;
+        }
+        for (SettableFuture<Type> future : futures) {
+            future.set(builder);
+        }
+        promisedTypes.removeAll(builder);
+    }
+
+    @Override
+    public void close() throws Exception {
+    }
+
+    @Override
+    public DataContainer dataObjectFromDataDom(final Class<? extends DataContainer> container,
+            final CompositeNode domData) {
+        try {
+            return tryDeserialization(new Callable<DataObject>() {
+                @Override
+                public DataObject call() throws Exception {
+                    if (Objects.equal(domData, null)) {
+                        return null;
+                    }
+                    final DataContainerCodec<? extends DataContainer> transformer = getRegistry()
+                            .getCodecForDataObject(container);
+                    ValueWithQName<? extends DataContainer> deserialize = transformer.deserialize(domData);
+                    DataContainer value = null;
+                    if (deserialize != null) {
+                        value = deserialize.getValue();
+                    }
+                    return ((DataObject) value);
+                }
+            });
+        } catch (Throwable _e) {
+            throw Exceptions.sneakyThrow(_e);
+        }
+    }
+
+    @Override
+    public Optional<Class<? extends RpcService>> getRpcServiceClassFor(String namespace, String revision) {
+        Module module = null;
+        if (schemaContext != null) {
+            module = schemaContext.findModuleByName(namespace, QName.parseRevision(revision));
+        }
+        if (module == null) {
+            return Optional.absent();
+        }
+        try {
+            Optional<Type> rpcTypeName = getRpcServiceType(module);
+            if (rpcTypeName.isPresent()) {
+                Class<?> rpcClass = binding.getClassLoadingStrategy().loadClass(
+                        rpcTypeName.get().getFullyQualifiedName());
+                return Optional.<Class<? extends RpcService>> of((Class<? extends RpcService>) rpcClass);
+            }
+        } catch (Exception e) {
+            LOG.debug("RPC class not present for {},{}", namespace, revision, e);
+        }
+        return Optional.absent();
+    }
+
+    public Optional<Type> getRpcServiceType(Module module) {
+        String namespace = BindingGeneratorUtil.moduleNamespaceToPackageName(module);
+        if (module.getRpcs().isEmpty()) {
+            return Optional.<Type> absent();
+        }
+        return Optional.<Type> of(new ReferencedTypeImpl(namespace, BindingMapping.getClassName(module.getName())
+                + BindingMapping.RPC_SERVICE_SUFFIX));
+    }
+
+}
diff --git a/code-generator/binding-generator-impl/src/main/java/org/opendaylight/yangtools/sal/binding/generator/impl/RuntimeGeneratedMappingServiceImpl.xtend b/code-generator/binding-generator-impl/src/main/java/org/opendaylight/yangtools/sal/binding/generator/impl/RuntimeGeneratedMappingServiceImpl.xtend
deleted file mode 100644 (file)
index 0d052e5..0000000
+++ /dev/null
@@ -1,363 +0,0 @@
-/*
- * Copyright (c) 2014 Cisco Systems, Inc. and others.  All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-package org.opendaylight.yangtools.sal.binding.generator.impl
-
-import com.google.common.base.Optional
-import com.google.common.collect.FluentIterable
-import com.google.common.collect.HashMultimap
-import com.google.common.util.concurrent.SettableFuture
-import java.util.AbstractMap.SimpleEntry
-import java.util.ArrayList
-import java.util.Collections
-import java.util.Map
-import java.util.Map.Entry
-import java.util.Set
-import java.util.concurrent.Callable
-import java.util.concurrent.ConcurrentHashMap
-import java.util.concurrent.ConcurrentMap
-import java.util.concurrent.Future
-import javassist.ClassPool
-import org.opendaylight.yangtools.binding.generator.util.BindingGeneratorUtil
-import org.opendaylight.yangtools.binding.generator.util.ReferencedTypeImpl
-import org.opendaylight.yangtools.binding.generator.util.Types
-import org.opendaylight.yangtools.sal.binding.generator.api.ClassLoadingStrategy
-import org.opendaylight.yangtools.sal.binding.generator.util.YangSchemaUtils
-import org.opendaylight.yangtools.sal.binding.model.api.GeneratedType
-import org.opendaylight.yangtools.sal.binding.model.api.Type
-import org.opendaylight.yangtools.sal.binding.model.api.type.builder.GeneratedTypeBuilder
-import org.opendaylight.yangtools.yang.binding.Augmentation
-import org.opendaylight.yangtools.yang.binding.BindingMapping
-import org.opendaylight.yangtools.yang.binding.DataContainer
-import org.opendaylight.yangtools.yang.binding.DataObject
-import org.opendaylight.yangtools.yang.binding.InstanceIdentifier
-import org.opendaylight.yangtools.yang.binding.RpcService
-import org.opendaylight.yangtools.yang.common.QName
-import org.opendaylight.yangtools.yang.data.api.CompositeNode
-import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier.NodeIdentifierWithPredicates
-import org.opendaylight.yangtools.yang.data.api.Node
-import org.opendaylight.yangtools.yang.data.impl.CompositeNodeTOImpl
-import org.opendaylight.yangtools.yang.data.impl.SimpleNodeTOImpl
-import org.opendaylight.yangtools.yang.data.impl.codec.AugmentationCodec
-import org.opendaylight.yangtools.yang.data.impl.codec.BindingIndependentMappingService
-import org.opendaylight.yangtools.yang.data.impl.codec.DataContainerCodec
-import org.opendaylight.yangtools.yang.data.impl.codec.DeserializationException
-import org.opendaylight.yangtools.yang.data.impl.codec.ValueWithQName
-import org.opendaylight.yangtools.yang.model.api.Module
-import org.opendaylight.yangtools.yang.model.api.SchemaContext
-import org.opendaylight.yangtools.yang.model.api.SchemaContextHolder
-import org.opendaylight.yangtools.yang.model.api.SchemaContextListener
-import org.opendaylight.yangtools.yang.model.api.SchemaNode
-import org.opendaylight.yangtools.yang.model.api.SchemaPath
-import org.opendaylight.yangtools.yang.model.util.SchemaContextUtil
-import org.slf4j.LoggerFactory
-
-class RuntimeGeneratedMappingServiceImpl implements BindingIndependentMappingService, SchemaContextListener,
-SchemaLock, AutoCloseable, SchemaContextHolder {
-
-    @Property
-    ClassPool pool;
-
-    private static val LOG = LoggerFactory.getLogger(RuntimeGeneratedMappingServiceImpl);
-
-    @Property
-    extension TransformerGenerator binding;
-
-    @Property
-    extension LazyGeneratedCodecRegistry registry;
-
-    @Property
-    val ConcurrentMap<Type, Type> typeDefinitions = new ConcurrentHashMap();
-
-    @Property
-    val ConcurrentMap<Type, GeneratedTypeBuilder> typeToDefinition = new ConcurrentHashMap();
-
-    @Property
-    val ConcurrentMap<Type, SchemaNode> typeToSchemaNode = new ConcurrentHashMap();
-
-    @Property
-    val ConcurrentMap<Type, Set<QName>> serviceTypeToRpc = new ConcurrentHashMap();
-
-    val promisedTypes = HashMultimap.<Type, SettableFuture<Type>>create;
-
-    val ClassLoadingStrategy classLoadingStrategy;
-
-    @Property
-    var SchemaContext schemaContext;
-
-    new() {
-        this(GeneratedClassLoadingStrategy.getTCCLClassLoadingStrategy())
-    }
-
-    new(ClassLoadingStrategy strat){
-        classLoadingStrategy = strat
-    }
-
-    //ServiceRegistration<SchemaServiceListener> listenerRegistration
-    override onGlobalContextUpdated(SchemaContext arg0) {
-        schemaContext = arg0
-        recreateBindingContext(arg0);
-        registry.onGlobalContextUpdated(arg0);
-    }
-
-    def recreateBindingContext(SchemaContext schemaContext) {
-        val newBinding = new BindingGeneratorImpl();
-        newBinding.generateTypes(schemaContext);
-
-        for (entry : newBinding.moduleContexts.entrySet) {
-
-            registry.onModuleContextAdded(schemaContext, entry.key, entry.value);
-            binding.pathToType.putAll(entry.value.childNodes)
-            val module = entry.key;
-            val context = entry.value;
-            updateBindingFor(context.childNodes, schemaContext);
-            updateBindingFor(context.cases, schemaContext);
-            val namespace = BindingGeneratorUtil.moduleNamespaceToPackageName(module);
-
-            if (!module.rpcs.empty) {
-                val rpcs = FluentIterable.from(module.rpcs).transform[QName].toSet
-                val serviceClass = new ReferencedTypeImpl(namespace,
-                    BindingGeneratorUtil.parseToClassName(module.name) + "Service");
-                serviceTypeToRpc.put(serviceClass, rpcs);
-            }
-
-            val typedefs = context.typedefs;
-            for (typedef : typedefs.entrySet) {
-                val typeRef = new ReferencedTypeImpl(typedef.value.packageName, typedef.value.name)
-                binding.typeDefinitions.put(typeRef, typedef.value as GeneratedType);
-                val schemaNode = YangSchemaUtils.findTypeDefinition(schemaContext, typedef.key);
-                if (schemaNode != null) {
-
-                    binding.typeToSchemaNode.put(typeRef, schemaNode);
-                } else {
-                    LOG.error("Type definition for {} is not available", typedef.value);
-                }
-
-            }
-            val augmentations = context.augmentations;
-            for (augmentation : augmentations) {
-                binding.typeToDefinition.put(augmentation, augmentation);
-            }
-            binding.typeToAugmentation.putAll(context.typeToAugmentation);
-            for (augmentation : augmentations) {
-                updatePromisedSchemas(augmentation);
-            }
-        }
-    }
-
-    override CompositeNode toDataDom(DataObject data) {
-        toCompositeNodeImpl(data);
-    }
-
-    override Entry<org.opendaylight.yangtools.yang.data.api.InstanceIdentifier, CompositeNode> toDataDom(
-        Entry<InstanceIdentifier<? extends DataObject>, DataObject> entry) {
-
-        try {
-            val key = toDataDom(entry.key)
-            var CompositeNode data;
-            if (Augmentation.isAssignableFrom(entry.key.targetType)) {
-                data = toCompositeNodeImplAugument(key, entry.value);
-            } else {
-                data = toCompositeNodeImpl(key, entry.value);
-            }
-            return new SimpleEntry(key, data);
-
-        } catch (Exception e) {
-            LOG.error("Error during serialization for {}.", entry.key, e);
-            throw e;
-        }
-    }
-
-    private def CompositeNode toCompositeNodeImpl(DataObject object) {
-        val cls = object.implementedInterface;
-        waitForSchema(cls);
-        val codec = registry.getCodecForDataObject(cls) as DataContainerCodec<DataObject>;
-        val ret = codec.serialize(new ValueWithQName(null, object));
-        return ret as CompositeNode;
-    }
-
-    private def CompositeNode toCompositeNodeImpl(org.opendaylight.yangtools.yang.data.api.InstanceIdentifier identifier,
-        DataObject object) {
-        val last = identifier.path.last;
-        val cls = object.implementedInterface;
-        waitForSchema(cls);
-        val codec = registry.getCodecForDataObject(cls) as DataContainerCodec<DataObject>;
-        val ret = codec.serialize(new ValueWithQName(last.nodeType, object));
-        return ret as CompositeNode;
-    }
-
-    private def CompositeNode toCompositeNodeImplAugument(
-        org.opendaylight.yangtools.yang.data.api.InstanceIdentifier identifier, DataObject object) {
-
-        //val cls = object.implementedInterface;
-        //waitForSchema(cls);
-        val last = identifier.path.last;
-        val codec = registry.getCodecForAugmentation(object.implementedInterface as Class) as AugmentationCodec;
-        val ret = codec.serialize(new ValueWithQName(last.nodeType, object));
-        if (last instanceof NodeIdentifierWithPredicates) {
-            val predicates = last as NodeIdentifierWithPredicates;
-            val newNodes = new ArrayList<Node<?>>(predicates.keyValues.size);
-            for (predicate : predicates.keyValues.entrySet) {
-                newNodes.add(new SimpleNodeTOImpl(predicate.key, null, predicate.value));
-            }
-            newNodes.addAll(ret.children);
-            return new CompositeNodeTOImpl(last.nodeType, null, newNodes);
-        }
-        return ret as CompositeNode;
-    }
-
-    override waitForSchema(Class class1) {
-
-        if (registry.isCodecAvailable(class1)) {
-            return;
-        }
-        val ref = Types.typeForClass(class1);
-        getSchemaWithRetry(ref);
-    }
-
-    override org.opendaylight.yangtools.yang.data.api.InstanceIdentifier toDataDom(
-        InstanceIdentifier<? extends DataObject> path) {
-        for (arg : path.path) {
-            waitForSchema(arg.type);
-        }
-        return registry.instanceIdentifierCodec.serialize(path);
-    }
-
-    override dataObjectFromDataDom(InstanceIdentifier<? extends DataObject> path, CompositeNode node) {
-        dataObjectFromDataDom(path.targetType, node) as DataObject;
-    }
-
-    override fromDataDom(org.opendaylight.yangtools.yang.data.api.InstanceIdentifier entry) {
-        return tryDeserialization[ |
-            registry.instanceIdentifierCodec.deserialize(entry);
-        ]
-    }
-
-    override getCodecRegistry() {
-        return getRegistry();
-    }
-
-    private static def <T> T tryDeserialization(Callable<T> deserializationBlock) throws DeserializationException {
-        try {
-            deserializationBlock.call()
-        } catch (Exception e) {
-
-            // FIXME: Make this block providing more information.
-            throw new DeserializationException(e);
-        }
-    }
-
-    private def void updateBindingFor(Map<SchemaPath, GeneratedTypeBuilder> map, SchemaContext module) {
-
-        for (entry : map.entrySet) {
-            val schemaNode = SchemaContextUtil.findDataSchemaNode(module, entry.key);
-
-            //LOG.info("{} : {}",entry.key,entry.value.fullyQualifiedName)
-            val typeRef = new ReferencedTypeImpl(entry.value.packageName, entry.value.name)
-            typeToDefinition.put(typeRef, entry.value);
-            if (schemaNode != null) {
-                typeToSchemaNode.put(typeRef, schemaNode);
-                updatePromisedSchemas(entry.value);
-            }
-
-        }
-    }
-
-    public def void init() {
-        binding = new TransformerGenerator(pool);
-        registry = new LazyGeneratedCodecRegistry(this, classLoadingStrategy)
-
-        registry.generator = binding
-
-        //binding.staticFieldsInitializer = registry
-        binding.listener = registry
-        binding.typeToDefinition = typeToDefinition
-        binding.typeToSchemaNode = typeToSchemaNode
-        binding.typeDefinitions = typeDefinitions
-
-    //        if (ctx !== null) {
-    //            listenerRegistration = ctx.registerService(SchemaServiceListener, this, new Hashtable<String, String>());
-    //        }
-    }
-
-    override getRpcQNamesFor(Class<? extends RpcService> service) {
-        var serviceRef = serviceTypeToRpc.get(new ReferencedTypeImpl(service.package.name, service.simpleName))
-        if (serviceRef == null) {
-            serviceRef = Collections.emptySet()
-        }
-        return serviceRef
-    }
-
-    private def void getSchemaWithRetry(Type type) {
-        if (typeToDefinition.containsKey(type)) {
-            return;
-        }
-        LOG.info("Thread blocked waiting for schema for: {}", type.fullyQualifiedName)
-        type.waitForTypeDefinition.get();
-        LOG.info("Schema for {} became available, thread unblocked", type.fullyQualifiedName)
-    }
-
-    private def Future<Type> waitForTypeDefinition(Type type) {
-        val future = SettableFuture.<Type>create()
-        promisedTypes.put(type, future);
-        return future;
-    }
-
-    private def void updatePromisedSchemas(Type builder) {
-        val ref = new ReferencedTypeImpl(builder.packageName, builder.name);
-        val futures = promisedTypes.get(ref);
-        if (futures === null || futures.empty) {
-            return;
-        }
-        for (future : futures) {
-            future.set(builder);
-        }
-        promisedTypes.removeAll(builder);
-    }
-
-    override close() throws Exception {
-        //listenerRegistration?.unregister();
-    }
-
-    override dataObjectFromDataDom(Class<? extends DataContainer> container, CompositeNode domData) {
-        return tryDeserialization[ |
-            if (domData == null) {
-                return null;
-            }
-            val transformer = registry.getCodecForDataObject(container);
-            val ret = transformer.deserialize(domData)?.value as DataObject;
-            return ret;
-        ]
-    }
-
-    override getRpcServiceClassFor(String namespace, String revision) {
-        val module = schemaContext?.findModuleByName(namespace.toString, QName.parseRevision(revision));
-        if (module == null) {
-            return Optional.absent();
-        }
-        try {
-            val rpcTypeName = module.rpcServiceType;
-            if (rpcTypeName.present) {
-                val rpcClass = binding.classLoadingStrategy.loadClass(rpcTypeName.get.fullyQualifiedName);
-                return Optional.of(rpcClass as Class<? extends RpcService>);
-            }
-        } catch (Exception e) {
-            LOG.debug("RPC class not present for {},{}", namespace, revision, e);
-        }
-        return Optional.absent()
-    }
-
-    def Optional<Type> getRpcServiceType(Module module) {
-        val namespace = BindingGeneratorUtil.moduleNamespaceToPackageName(module);
-        if (module.rpcs.empty) {
-            return Optional.<Type>absent();
-        }
-        return Optional.<Type>of(
-            new ReferencedTypeImpl(namespace,
-                BindingMapping.getClassName(module.name) + BindingMapping.RPC_SERVICE_SUFFIX));
-    }
-}
diff --git a/code-generator/binding-generator-impl/src/main/java/org/opendaylight/yangtools/sal/binding/generator/util/JavassistUtils.java b/code-generator/binding-generator-impl/src/main/java/org/opendaylight/yangtools/sal/binding/generator/util/JavassistUtils.java
new file mode 100644 (file)
index 0000000..74efacb
--- /dev/null
@@ -0,0 +1,191 @@
+/*
+ * Copyright (c) 2014 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.yangtools.sal.binding.generator.util;
+
+import javassist.CtClass;
+import javassist.CtMethod;
+import javassist.ClassPool;
+
+import java.util.Arrays;
+
+import javassist.ClassPath;
+import javassist.CtField;
+import javassist.Modifier;
+import javassist.NotFoundException;
+import javassist.LoaderClassPath;
+import javassist.ClassClassPath;
+
+import java.util.concurrent.locks.Lock;
+import java.util.concurrent.locks.ReentrantLock;
+
+import org.eclipse.xtext.xbase.lib.Conversions;
+import org.eclipse.xtext.xbase.lib.Exceptions;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.google.common.base.Preconditions;
+
+import java.util.List;
+import java.util.Map;
+import java.util.WeakHashMap;
+import java.util.Collections;
+
+public class JavassistUtils {
+
+    private static final Logger LOG = LoggerFactory.getLogger(JavassistUtils.class);
+
+    private final Map<ClassLoader, LoaderClassPath> loaderClassPaths = Collections
+            .synchronizedMap(new WeakHashMap<ClassLoader, LoaderClassPath>());
+    private ClassPool classPool;
+    private final Lock lock = new ReentrantLock();
+
+    public JavassistUtils(ClassPool pool) {
+        classPool = pool;
+    }
+
+    public Lock getLock() {
+        return lock;
+    }
+
+    public void method(final CtClass it, final Class<? extends Object> returnType, final String name,
+            final Class<? extends Object> parameter, final MethodGenerator function1) {
+        try {
+            List<CtClass> _asList = Arrays.<CtClass> asList(asCtClass(parameter));
+            CtMethod _ctMethod = new CtMethod(asCtClass(returnType), name, ((CtClass[]) Conversions.unwrapArray(
+                    _asList, CtClass.class)), it);
+            final CtMethod method = _ctMethod;
+            function1.process(method);
+            it.addMethod(method);
+        } catch (Throwable _e) {
+            throw Exceptions.sneakyThrow(_e);
+        }
+    }
+
+    public void method(final CtClass it, final Class<? extends Object> returnType, final String name,
+            final Class<? extends Object> parameter1, final Class<? extends Object> parameter2,
+            final MethodGenerator function1) {
+        try {
+            List<CtClass> _asList = Arrays.<CtClass> asList(asCtClass(parameter1), asCtClass(parameter2));
+            CtMethod method = new CtMethod(asCtClass(returnType), name, ((CtClass[]) Conversions.unwrapArray(_asList,
+                    CtClass.class)), it);
+            function1.process(method);
+            it.addMethod(method);
+        } catch (Throwable _e) {
+            throw Exceptions.sneakyThrow(_e);
+        }
+    }
+
+    public void staticMethod(final CtClass it, final Class<? extends Object> returnType, final String name,
+            final Class<? extends Object> parameter, final MethodGenerator function1) {
+        try {
+            List<CtClass> _asList = Arrays.<CtClass> asList(asCtClass(parameter));
+            CtMethod _ctMethod = new CtMethod(asCtClass(returnType), name, ((CtClass[]) Conversions.unwrapArray(
+                    _asList, CtClass.class)), it);
+            final CtMethod method = _ctMethod;
+            function1.process(method);
+            it.addMethod(method);
+        } catch (Throwable _e) {
+            throw Exceptions.sneakyThrow(_e);
+        }
+    }
+
+    public void implementMethodsFrom(CtClass target, CtClass source, MethodGenerator function1) {
+        try {
+            for (CtMethod method : source.getMethods()) {
+                if (method.getDeclaringClass() == source) {
+                    CtMethod redeclaredMethod = new CtMethod(method, target, null);
+                    function1.process(redeclaredMethod);
+                    target.addMethod(redeclaredMethod);
+                }
+            }
+        } catch (Throwable t) {
+            Exceptions.sneakyThrow(t);
+        }
+    }
+
+    public CtClass createClass(String fqn, ClassGenerator cls) {
+        CtClass target = classPool.makeClass(fqn);
+        cls.process(target);
+        return target;
+    }
+
+    public CtClass createClass(String fqn, CtClass superInterface, ClassGenerator cls) {
+        CtClass target = classPool.makeClass(fqn);
+        implementsType(target, superInterface);
+        cls.process(target);
+        return target;
+    }
+
+    public void implementsType(final CtClass it, final CtClass supertype) {
+        Preconditions.checkArgument(supertype.isInterface(), "Supertype must be interface");
+        it.addInterface(supertype);
+    }
+
+    public CtClass asCtClass(final Class<? extends Object> class1) {
+        return get(this.classPool, class1);
+    }
+
+    public CtField field(final CtClass it, final String name, final Class<? extends Object> returnValue) {
+        try {
+            final CtField field = new CtField(asCtClass(returnValue), name, it);
+            field.setModifiers(Modifier.PUBLIC);
+            it.addField(field);
+            return field;
+        } catch (Throwable _e) {
+            throw Exceptions.sneakyThrow(_e);
+        }
+    }
+
+    public CtField staticField(final CtClass it, final String name, final Class<? extends Object> returnValue) {
+        try {
+            final CtField field = new CtField(asCtClass(returnValue), name, it);
+            field.setModifiers(Modifier.PUBLIC + Modifier.STATIC);
+            it.addField(field);
+            return field;
+        } catch (Throwable _e) {
+            throw Exceptions.sneakyThrow(_e);
+        }
+    }
+
+    public CtClass get(final ClassPool pool, final Class<? extends Object> cls) {
+        try {
+            return pool.get(cls.getName());
+        } catch (NotFoundException nfe1) {
+            appendClassLoaderIfMissing(cls.getClassLoader());
+            try {
+                return pool.get(cls.getName());
+            } catch (final NotFoundException nfe2) {
+                LOG.warn("Appending ClassClassPath for {}", cls);
+                pool.appendClassPath(new ClassClassPath(cls));
+                try {
+                    return pool.get(cls.getName());
+                } catch (Throwable t) {
+                    throw Exceptions.sneakyThrow(t);
+                }
+            } catch (Throwable t1) {
+                Exceptions.sneakyThrow(t1);
+                return null;
+            }
+        } catch (Throwable t) {
+            Exceptions.sneakyThrow(t);
+            return null;
+        }
+    }
+
+    public void appendClassLoaderIfMissing(ClassLoader loader) {
+        if (loaderClassPaths.containsKey(loader)) {
+            return;
+        }
+        ClassPath ctLoader = new LoaderClassPath(loader);
+        classPool.appendClassPath(ctLoader);
+    }
+
+    public void ensureClassLoader(Class<?> child) {
+        appendClassLoaderIfMissing(child.getClassLoader());
+    }
+}
diff --git a/code-generator/binding-generator-impl/src/main/java/org/opendaylight/yangtools/sal/binding/generator/util/JavassistUtils.xtend b/code-generator/binding-generator-impl/src/main/java/org/opendaylight/yangtools/sal/binding/generator/util/JavassistUtils.xtend
deleted file mode 100644 (file)
index 35f5b21..0000000
+++ /dev/null
@@ -1,135 +0,0 @@
-/*
- * Copyright (c) 2014 Cisco Systems, Inc. and others.  All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-package org.opendaylight.yangtools.sal.binding.generator.util
-
-import javassist.CtClass
-import javassist.CtMethod
-import javassist.ClassPool
-import java.util.Arrays
-import static com.google.common.base.Preconditions.*;
-import javassist.CtField
-import javassist.Modifier
-import javassist.NotFoundException
-import javassist.LoaderClassPath
-import javassist.ClassClassPath
-import java.util.concurrent.locks.Lock
-import java.util.concurrent.locks.ReentrantLock
-import org.slf4j.LoggerFactory
-import java.util.WeakHashMap
-import java.util.Collections
-
-class JavassistUtils {
-
-    private static val LOG = LoggerFactory.getLogger(JavassistUtils);
-
-    private val loaderClassPaths = Collections.synchronizedMap(new WeakHashMap<ClassLoader,LoaderClassPath>());
-
-    ClassPool classPool
-
-    @Property
-    val Lock lock = new ReentrantLock();
-
-    new(ClassPool pool) {
-        classPool = pool;
-    }
-
-    def void method(CtClass it, Class<?> returnType, String name, Class<?> parameter, MethodGenerator function1) {
-        val method = new CtMethod(returnType.asCtClass, name, Arrays.asList(parameter.asCtClass), it);
-        function1.process(method);
-        it.addMethod(method);
-    }
-
-        def void method(CtClass it, Class<?> returnType, String name, Class<?> parameter1, Class<?> parameter2,  MethodGenerator function1) {
-        val method = new CtMethod(returnType.asCtClass, name, Arrays.asList(parameter1.asCtClass,parameter2.asCtClass), it);
-        function1.process(method);
-        it.addMethod(method);
-    }
-
-
-    def void staticMethod(CtClass it, Class<?> returnType, String name, Class<?> parameter, MethodGenerator function1) {
-        val method = new CtMethod(returnType.asCtClass, name, Arrays.asList(parameter.asCtClass), it);
-        function1.process(method);
-        it.addMethod(method);
-    }
-
-    def void implementMethodsFrom(CtClass target, CtClass source, MethodGenerator function1) {
-        for (method : source.methods) {
-            if (method.declaringClass == source) {
-                val redeclaredMethod = new CtMethod(method, target, null);
-                function1.process(redeclaredMethod);
-                target.addMethod(redeclaredMethod);
-            }
-        }
-    }
-
-    def CtClass createClass(String fqn, ClassGenerator cls) {
-
-        val target = classPool.makeClass(fqn);
-        cls.process(target);
-        return target;
-    }
-
-    def CtClass createClass(String fqn, CtClass superInterface, ClassGenerator cls) {
-
-        val target = classPool.makeClass(fqn);
-        target.implementsType(superInterface);
-        cls.process(target);
-        return target;
-    }
-
-    def void implementsType(CtClass it, CtClass supertype) {
-        checkArgument(supertype.interface, "Supertype must be interface");
-        addInterface(supertype);
-    }
-
-    def asCtClass(Class<?> class1) {
-        classPool.get(class1);
-    }
-
-    def CtField field(CtClass it, String name, Class<?> returnValue) {
-        val field = new CtField(returnValue.asCtClass, name, it);
-        field.modifiers = Modifier.PUBLIC
-        addField(field);
-        return field;
-    }
-
-    def CtField staticField(CtClass it, String name, Class<?> returnValue) {
-        val field = new CtField(returnValue.asCtClass, name, it);
-        field.modifiers = Modifier.PUBLIC + Modifier.STATIC
-        addField(field);
-        return field;
-    }
-
-    def get(ClassPool pool, Class<?> cls) {
-        try {
-            return pool.get(cls.name)
-        } catch (NotFoundException e) {
-            appendClassLoaderIfMissing(cls.classLoader)
-            try {
-                return pool.get(cls.name)
-            } catch (NotFoundException ef) {
-                LOG.warn("Appending ClassClassPath for {}",cls);
-                pool.appendClassPath(new ClassClassPath(cls));
-
-                return pool.get(cls.name)
-            }
-        }
-    }
-
-    def void appendClassLoaderIfMissing(ClassLoader loader) {
-        if(loaderClassPaths.containsKey(loader)) {
-            return;
-        }
-        val ctLoader = new LoaderClassPath(loader);
-        classPool.appendClassPath(ctLoader);
-    }
-
-    def void ensureClassLoader(Class<?> child) {
-        appendClassLoaderIfMissing(child.classLoader);
-    }
-}