Added support for resolving augmentations. 76/676/1
authorlsedlak <lsedlak@cisco.com>
Mon, 20 May 2013 16:35:22 +0000 (18:35 +0200)
committerMartin Vitez <mvitez@cisco.com>
Wed, 24 Jul 2013 11:44:52 +0000 (13:44 +0200)
Added implementation into BindingGeneratorImpl to support generation of augmentati statements from yang models.
Added AugmentedTypeTest and augmented-test-models for testing of agumentation functionality.

Added ability to generate Java Interfaces that extends generic types.
Added Augmentation and Augmentable interfaces into yang-binding project.

Fixed bug in bad equals resolving in AbstractBaseType in binding-generator-util;
Added ReferencedTypeImpl into binding-generator-util;

Added findParentModule static method into SchemaContextUtil for resolving Module from SchemaNode in Schema Tree;
Added DATA_OBJECT, augmentableTypeFor and augmentationTypeFor into Types for referencing of Augmentable<T>, Augmentation<T> and DataObject interfaces defined in yang-binding;

Fixed incorrect resolving of namespaces and package names during generation of interfaces from yang lists;
Fixed bug in TypeProvider in resolving of extended types extended from multiple extended types;
Added ControllerTest and controller-models as test resources;
Changed position of revision date during package generation -> Now revision date comes after namespace;

Change-Id: I687925a622853bb6c9a809f17efd980c2960ae39
Signed-off-by: Lukas Sedlak <lsedlak@cisco.com>
Signed-off-by: Tony Tkacik <ttkacik@cisco.com>
pom.xml
yang-binding/src/main/java/org/opendaylight/controller/yang/binding/Augmentable.java [new file with mode: 0644]
yang-binding/src/main/java/org/opendaylight/controller/yang/binding/Augmentation.java [new file with mode: 0644]
yang-common/pom.xml
yang-model-util/src/main/java/org/opendaylight/controller/yang/model/util/DataNodeIterator.java
yang-model-util/src/main/java/org/opendaylight/controller/yang/model/util/SchemaContextUtil.java

diff --git a/pom.xml b/pom.xml
index 0ac2bbe569b010475810db978d5685de9ebe1d75..4710c9f0e8ccb1e2e9b4c132c870e6a84b4ee014 100644 (file)
--- a/pom.xml
+++ b/pom.xml
@@ -7,9 +7,7 @@
                <version>0.5-SNAPSHOT</version>
        </parent>
 
-       <groupId>org.opendaylight.controller</groupId>
        <artifactId>yang</artifactId>
-       <version>0.5-SNAPSHOT</version>
        <packaging>pom</packaging>
        <modules>
                <module>yang-common</module>
                <module>../code-generator/maven-yang-plugin-it</module>
 
        </modules>
-       <dependencies>
-
-               <dependency>
-                       <groupId>junit</groupId>
-                       <artifactId>junit</artifactId>
-                       <scope>test</scope>
-                       <optional>true</optional>
-               </dependency>
-               <dependency>
-                       <groupId>org.slf4j</groupId>
-                       <artifactId>slf4j-api</artifactId>
-               </dependency>
-               <dependency>
-                       <groupId>org.slf4j</groupId>
-                       <artifactId>slf4j-simple</artifactId>
-               </dependency>
-       </dependencies>
        <build>
                <plugins>
                        <plugin>
diff --git a/yang-binding/src/main/java/org/opendaylight/controller/yang/binding/Augmentable.java b/yang-binding/src/main/java/org/opendaylight/controller/yang/binding/Augmentable.java
new file mode 100644 (file)
index 0000000..297e5bc
--- /dev/null
@@ -0,0 +1,6 @@
+package org.opendaylight.controller.yang.binding;
+
+public interface Augmentable<T> {
+
+    <E extends Augmentation<T>> E getAugmentation(Class<E> augmentationType);
+}
diff --git a/yang-binding/src/main/java/org/opendaylight/controller/yang/binding/Augmentation.java b/yang-binding/src/main/java/org/opendaylight/controller/yang/binding/Augmentation.java
new file mode 100644 (file)
index 0000000..42574c9
--- /dev/null
@@ -0,0 +1,5 @@
+package org.opendaylight.controller.yang.binding;
+
+public interface Augmentation<T> {
+    
+}
index f296579fcc95936dc0897d1f3254ec2688913480..796c482ddcfe056bd4fa38a664facdeefdfaff9b 100644 (file)
@@ -6,4 +6,11 @@
     <version>0.5-SNAPSHOT</version>\r
   </parent>\r
   <artifactId>yang-common</artifactId>\r
+  <dependencies>\r
+       <dependency>\r
+               <groupId>org.slf4j</groupId>\r
+               <artifactId>slf4j-simple</artifactId>\r
+               <version>1.7.5</version>\r
+       </dependency>\r
+  </dependencies>\r
 </project>
\ No newline at end of file
index b4eaed775c7d6f24f905b51e559888fa9033b674..df111acf0854603d453f1c1bd6cefb40a449d48c 100644 (file)
@@ -15,26 +15,28 @@ import org.opendaylight.controller.yang.model.api.ListSchemaNode;
 public class DataNodeIterator implements Iterator<DataSchemaNode> {
     
     private final DataNodeContainer container;
-    private final List<ListSchemaNode> allLists;
-    private final List<ContainerSchemaNode> allContainers;
-    private final List<LeafSchemaNode> allLeafs;
-    private final List<LeafListSchemaNode> allLeafLists;
-    private final List<DataSchemaNode> allChilds;
+    private List<ListSchemaNode> allLists;
+    private List<ContainerSchemaNode> allContainers;
+    private List<LeafSchemaNode> allLeafs;
+    private List<LeafListSchemaNode> allLeafLists;
+    private List<DataSchemaNode> allChilds;
     
     public DataNodeIterator(final DataNodeContainer container) {
         if (container == null) {
-            throw new IllegalArgumentException("Data Node Container MUST be specified!");
+            throw new IllegalArgumentException("Data Node Container MUST be specified and cannot be NULL!");
         }
         
+        init();
+        this.container = container;
+        traverse(this.container);
+    }
+    
+    private void init() {
         this.allContainers = new ArrayList<ContainerSchemaNode>();
         this.allLists = new ArrayList<ListSchemaNode>();
         this.allLeafs = new ArrayList<LeafSchemaNode>();
         this.allLeafLists = new ArrayList<LeafListSchemaNode>();
         this.allChilds = new ArrayList<DataSchemaNode>();
-        
-        this.container = container;
-        
-        traverse(this.container);
     }
     
     public List<ContainerSchemaNode> allContainers() {
@@ -54,10 +56,10 @@ public class DataNodeIterator implements Iterator<DataSchemaNode> {
     }
     
     private void traverse(final DataNodeContainer dataNode) {
-        if (!containChildDataNodeContainer(dataNode)) {
+        if (dataNode == null) {
             return;
         }
-
+        
         final Set<DataSchemaNode> childs = dataNode.getChildNodes();
         if (childs != null) {
             for (DataSchemaNode childNode : childs) {
@@ -81,33 +83,9 @@ public class DataNodeIterator implements Iterator<DataSchemaNode> {
                     allLeafLists.add(leafList);
                 }
             }
+            return;
         }
     }
-
-    /**
-     * Returns <code>true</code> if and only if the child node contain at least
-     * one child container schema node or child list schema node, otherwise will
-     * always returns <code>false</code>
-     * 
-     * @param container
-     * @return <code>true</code> if and only if the child node contain at least
-     *         one child container schema node or child list schema node,
-     *         otherwise will always returns <code>false</code>
-     */
-    private boolean containChildDataNodeContainer(
-            final DataNodeContainer container) {
-        if (container != null) {
-            final Set<DataSchemaNode> childs = container.getChildNodes();
-            if ((childs != null) && (childs.size() > 0)) {
-                for (final DataSchemaNode childNode : childs) {
-                    if (childNode instanceof DataNodeContainer) {
-                        return true;
-                    }
-                }
-            }
-        }
-        return false;
-    }
     
     @Override
     public boolean hasNext() {
index 8554f682198f73c95f78eb3f5cdf413131e4e2f9..39865a9ddf4e00eb3a9977687dfdfaa6411a7484 100644 (file)
@@ -7,6 +7,7 @@
  */
 package org.opendaylight.controller.yang.model.util;
 
+import java.net.URI;
 import java.util.LinkedList;
 import java.util.List;
 import java.util.Queue;
@@ -26,42 +27,35 @@ import org.opendaylight.controller.yang.model.api.SchemaPath;
 
 public final class SchemaContextUtil {
 
-    private final SchemaContext context;
+    private SchemaContextUtil() {}
 
-    public SchemaContextUtil(final SchemaContext context) {
-        this.context = context;
-    }
-    
-    public SchemaContext getContext() {
-        return context;
-    }
-    
-    public DataSchemaNode findDataSchemaNode(final SchemaPath schemaPath) {
+    public static DataSchemaNode findDataSchemaNode(final SchemaContext context, final SchemaPath schemaPath) {
         if (schemaPath != null) {
-            final Module module = resolveModuleFromSchemaPath(schemaPath);
-            final Queue<String> prefixedPath = schemaPathToQueuedPath(schemaPath);
-            
+            final Module module = resolveModuleFromSchemaPath(context, schemaPath);
+            final Queue<QName> prefixedPath = new LinkedList<QName>(schemaPath.getPath()); 
+
             if ((module != null) && (prefixedPath != null)) {
-                return findSchemaNodeForGivenPath(module, prefixedPath);
+                return findSchemaNodeForGivenPath(context, module, prefixedPath);
             }
         }
         return null;
     }
-    
-    public DataSchemaNode findDataSchemaNode(final Module module,
+
+    public static DataSchemaNode findDataSchemaNode(final SchemaContext context, final Module module,
             final RevisionAwareXPath nonCondXPath) {
         if (nonCondXPath != null) {
             final String strXPath = nonCondXPath.toString();
 
             if (strXPath != null) {
                 if (strXPath.matches(".*//[.* | .*//].*")) {
-                    // TODO: function to escape conditions in path   
+                    // TODO: function to escape conditions in path
                 }
                 if (nonCondXPath.isAbsolute()) {
-                    final Queue<String> queuedPath = xpathToQueuedPath(strXPath);
-                    if (queuedPath != null) {
-                        final DataSchemaNode dataNode = findSchemaNodeForGivenPath(
-                                module, queuedPath);
+                    final Queue<QName> qnamedPath = xpathToQNamePath(context, module,
+                            strXPath);
+                    if (qnamedPath != null) {
+                        final DataSchemaNode dataNode = findSchemaNodeForGivenPath(context, 
+                                module, qnamedPath);
                         return dataNode;
                     }
                 }
@@ -70,7 +64,7 @@ public final class SchemaContextUtil {
         return null;
     }
 
-    public DataSchemaNode findDataSchemaNodeForRelativeXPath(
+    public static DataSchemaNode findDataSchemaNodeForRelativeXPath(final SchemaContext context, 
             final Module module, final SchemaNode actualSchemaNode,
             final RevisionAwareXPath relativeXPath) {
         if ((actualSchemaNode != null) && (relativeXPath != null)
@@ -78,12 +72,12 @@ public final class SchemaContextUtil {
 
             final SchemaPath actualNodePath = actualSchemaNode.getPath();
             if (actualNodePath != null) {
-                final Queue<String> queuedPath = resolveRelativeXPath(
+                final Queue<QName> qnamePath = resolveRelativeXPath(context, module, 
                         relativeXPath, actualNodePath);
 
-                if (queuedPath != null) {
-                    final DataSchemaNode dataNode = findSchemaNodeForGivenPath(
-                            module, queuedPath);
+                if (qnamePath != null) {
+                    final DataSchemaNode dataNode = findSchemaNodeForGivenPath(context, 
+                            module, qnamePath);
                     return dataNode;
                 }
             }
@@ -91,148 +85,138 @@ public final class SchemaContextUtil {
 
         return null;
     }
-    
-    public Module resolveModuleFromSchemaPath(final SchemaPath schemaPath) {
+
+    public static Module resolveModuleFromSchemaPath(final SchemaContext context, final SchemaPath schemaPath) {
         if ((schemaPath != null) && (schemaPath.getPath() != null)) {
             final QName qname = schemaPath.getPath().get(0);
 
             if ((qname != null) && (qname.getNamespace() != null)) {
-                return context
-                        .findModuleByNamespace(qname.getNamespace());
+                return context.findModuleByNamespace(qname.getNamespace());
             }
         }
         return null;
     }
-    
-    /**
-     * Search which starts from root of Module.
-     * 
-     * @param module
-     * @param prefixedPath
-     * @return
-     */
-    private DataSchemaNode findSchemaNodeForGivenPath(final Module module,
-            final Queue<String> prefixedPath) {
-        if ((module != null) && (prefixedPath != null)) {
-            DataNodeContainer nextContainer = module;
-            final String modulePrefix = module.getPrefix();
 
-            String childNodeName = null;
-            DataSchemaNode schemaNode = null;
-            while ((nextContainer != null) && (prefixedPath.size() > 0)) {
-                childNodeName = prefixedPath.poll();
-                if (childNodeName.contains(":")) {
-                    final String[] prefixedChildNode = childNodeName.split(":");
-                    if ((modulePrefix != null)
-                            && modulePrefix.equals(prefixedChildNode[0])) {
+    public static Module findParentModule(final SchemaContext context, final SchemaNode schemaNode) {
+        if (context == null) {
+            throw new IllegalArgumentException("Schema Context reference cannot be NULL!");
+        }
+        if (schemaNode == null) {
+            throw new IllegalArgumentException("Schema Node cannot be NULL!");
+        }
 
-                        childNodeName = prefixedChildNode[1];
-                    } else {
-                        final Module nextModule = resolveModuleForPrefix(
-                                prefixedChildNode[0], module);
-                        final Queue<String> nextModulePrefixedPath = new LinkedList<String>();
-                        nextModulePrefixedPath.add(childNodeName);
-                        nextModulePrefixedPath.addAll(prefixedPath);
-                        prefixedPath.clear();
+        final SchemaPath schemaPath = schemaNode.getPath();
+        if (schemaPath == null) {
+            throw new IllegalStateException("Schema Path for Schema Node is not " +
+                    "set properly (Schema Path is NULL)");
+        }
+        final List<QName> qnamedPath = schemaPath.getPath();
+        if (qnamedPath == null || qnamedPath.isEmpty()) {
+            throw new IllegalStateException("Schema Path contains invalid state of path parts." +
+                    "The Schema Path MUST contain at least ONE QName which defines namespace and Local name" +
+                    "of path.");
+        }
+        final QName qname = qnamedPath.get(0);
+        return context.findModuleByNamespace(qname.getNamespace());
+    }
 
-                        schemaNode = findSchemaNodeForGivenPath(nextModule,
-                                nextModulePrefixedPath);
+    private static DataSchemaNode findSchemaNodeForGivenPath(final SchemaContext context, final Module module,
+            final Queue<QName> qnamedPath) {
+        if ((module != null) && (module.getNamespace() != null)
+                && (qnamedPath != null)) {
+            DataNodeContainer nextNode = module;
+            final URI moduleNamespace = module.getNamespace();
 
+            QName childNodeQName = null;
+            DataSchemaNode schemaNode = null;
+            while ((nextNode != null) && !qnamedPath.isEmpty()) {
+                childNodeQName = qnamedPath.peek();
+                if (childNodeQName != null) {
+                    final URI childNodeNamespace = childNodeQName.getNamespace();
+                    
+                    schemaNode = nextNode.getDataChildByName(childNodeQName);
+                    if (schemaNode != null) {
+                        if (schemaNode instanceof ContainerSchemaNode) {
+                            nextNode = (ContainerSchemaNode) schemaNode;
+                        } else if (schemaNode instanceof ListSchemaNode) {
+                            nextNode = (ListSchemaNode) schemaNode;
+                        } else {
+                            nextNode = null;
+                        }
+                    } else if (!childNodeNamespace.equals(moduleNamespace)) {
+                        final Module nextModule = context
+                                .findModuleByNamespace(childNodeNamespace);
+                        schemaNode = findSchemaNodeForGivenPath(context, nextModule,
+                                qnamedPath);
                         return schemaNode;
                     }
-                }
-
-                schemaNode = nextContainer.getDataChildByName(childNodeName);
-                if (schemaNode instanceof ContainerSchemaNode) {
-                    nextContainer = (ContainerSchemaNode) schemaNode;
-                } else if (schemaNode instanceof ListSchemaNode) {
-                    nextContainer = (ListSchemaNode) schemaNode;
-                } else {
-                    return schemaNode;
+                    qnamedPath.poll();
                 }
             }
+            return schemaNode;
         }
         return null;
     }
 
-    private Module resolveModuleForPrefix(final String prefix,
-            final Module parent) {
-        if ((prefix != null) && (parent != null)) {
-            final Set<ModuleImport> imports = parent.getImports();
+    private static Queue<QName> xpathToQNamePath(final SchemaContext context, final Module parentModule,
+            final String xpath) {
+        final Queue<QName> path = new LinkedList<QName>();
+        if (xpath != null) {
+            final String[] prefixedPath = xpath.split("/");
 
-            if (imports != null) {
-                for (final ModuleImport impModule : imports) {
-                    final String impModPrefix = impModule.getPrefix();
-                    if ((impModPrefix != null) && prefix.equals(impModPrefix)) {
-                        return resolveModuleFromContext(prefix,
-                                impModule.getModuleName());
-                    }
+            for (int i = 0; i < prefixedPath.length; ++i) {
+                if (!prefixedPath[i].isEmpty()) {
+                    path.add(stringPathPartToQName(context, parentModule, prefixedPath[i]));
                 }
             }
         }
-        return null;
+        return path;
     }
 
-    private Module resolveModuleFromContext(final String prefix,
-            final String moduleName) {
-        final Set<Module> modules = context.getModules();
-
-        if ((prefix != null) && (moduleName != null) && (modules != null)) {
-            for (Module module : modules) {
-                if ((module != null) && prefix.equals(module.getPrefix())
-                        && moduleName.equals(module.getName())) {
-                    return module;
+    private static QName stringPathPartToQName(final SchemaContext context, final Module parentModule,
+            final String prefixedPathPart) {
+        if (parentModule != null && prefixedPathPart != null) {
+            if (prefixedPathPart.contains(":")) {
+                final String[] prefixedName = prefixedPathPart.split(":");
+                final Module module = resolveModuleForPrefix(context, parentModule,
+                        prefixedName[0]);
+                if (module != null) {
+                    return new QName(module.getNamespace(), module
+                            .getRevision(), prefixedName[1]);
                 }
+            } else {
+                return new QName(parentModule.getNamespace(),
+                        parentModule.getRevision(), prefixedPathPart);
             }
         }
         return null;
     }
 
-    private Queue<String> xpathToQueuedPath(final String xpath) {
-        final Queue<String> retQueue = new LinkedList<String>();
-        if ((xpath != null)) {
-            final String[] prefixedPath = xpath.split("/");
-
-            if (prefixedPath != null) {
-                for (int i = 0; i < prefixedPath.length; ++i) {
-                    if (!prefixedPath[i].isEmpty()) {
-                        retQueue.add(prefixedPath[i]);
-                    }
-                }
+    private static Module resolveModuleForPrefix(final SchemaContext context, final Module module,
+            final String prefix) {
+        if ((module != null) && (prefix != null)) {
+            if (prefix.equals(module.getPrefix())) {
+                return module;
             }
-        }
-        return retQueue;
-    }
-    
-    private Queue<String> schemaPathToQueuedPath(final SchemaPath schemaPath) {
-        final Queue<String> retQueue = new LinkedList<String>();
-        if ((schemaPath != null) && (schemaPath.getPath() != null)) {
-            final List<QName> listPath = schemaPath.getPath();
-            
-            for (final QName qname : listPath) {
-                if (qname != null) {
-                    final String prefix = qname.getPrefix();
-                    final String localName = qname.getLocalName();
-                    
-                    final StringBuilder builder = new StringBuilder();
-                    if (prefix != null) {
-                        builder.append(prefix);
-                        builder.append(":");
-                    }
-                    builder.append(localName);
-                    retQueue.add(builder.toString());
+
+            final Set<ModuleImport> imports = module.getImports();
+
+            for (final ModuleImport mi : imports) {
+                if (prefix.equals(mi.getPrefix())) {
+                    return context.findModuleByName(mi.getModuleName(),
+                            mi.getRevision());
                 }
             }
         }
-        return retQueue;
+        return null;
     }
-    
-    private Queue<String> resolveRelativeXPath(
+
+    private static Queue<QName> resolveRelativeXPath(final SchemaContext context, final Module module,
             final RevisionAwareXPath relativeXPath,
             final SchemaPath leafrefSchemaPath) {
-        final Queue<String> absolutePath = new LinkedList<String>();
+        final Queue<QName> absolutePath = new LinkedList<QName>();
 
-        if ((relativeXPath != null) && !relativeXPath.isAbsolute()
+        if ((module != null) && (relativeXPath != null) && !relativeXPath.isAbsolute()
                 && (leafrefSchemaPath != null)) {
             final String strXPath = relativeXPath.toString();
             if (strXPath != null) {
@@ -247,10 +231,10 @@ public final class SchemaContextUtil {
                     if (path != null) {
                         int lenght = path.size() - colCount;
                         for (int i = 0; i < lenght; ++i) {
-                            absolutePath.add(path.get(i).getLocalName());
+                            absolutePath.add(path.get(i));
                         }
                         for (int i = colCount; i < xpaths.length; ++i) {
-                            absolutePath.add(xpaths[i]);
+                            absolutePath.add(stringPathPartToQName(context, module, xpaths[i]));
                         }
                     }
                 }