Fixed bug in resolving of conditional Revision Aware XPath. 03/703/1
authorlsedlak <lsedlak@cisco.com>
Thu, 25 Jul 2013 14:13:09 +0000 (16:13 +0200)
committerlsedlak <lsedlak@cisco.com>
Thu, 25 Jul 2013 14:13:09 +0000 (16:13 +0200)
Fixed implementation in TypeProviderImpl - if leafref references the leaf through the conditional XPath the method will no more returns null but wrapped Type as java.lang.Object.
Added test into GeneratedTypesTest for conditional XPath.
Fixed controller-network-ne.yang - changed name of flow-tables to flow-tables2 - the build should no more fail.
Fixed wrong transformation of yang namespace to java package in case that yang namespace contains numbers right after the "."
Added check into BindingGeneratorUtil - validateJavaPackage.
Refactored and commented SchemaContextUtil.java

Signed-off-by: Lukas Sedlak <lsedlak@cisco.com>
14 files changed:
opendaylight/sal/yang-prototype/code-generator/binding-generator-impl/src/main/java/org/opendaylight/controller/sal/binding/yang/types/TypeProviderImpl.java
opendaylight/sal/yang-prototype/code-generator/binding-generator-impl/src/test/java/org/opendaylight/controller/sal/binding/generator/impl/GeneratedTypesTest.java
opendaylight/sal/yang-prototype/code-generator/binding-generator-impl/src/test/resources/demo-topology.yang
opendaylight/sal/yang-prototype/code-generator/binding-generator-impl/src/test/resources/leafref-test-models/abstract-topology@2013-02-08.yang
opendaylight/sal/yang-prototype/code-generator/binding-generator-util/src/main/java/org/opendaylight/controller/binding/generator/util/BindingGeneratorUtil.java
opendaylight/sal/yang-prototype/code-generator/code-generator-demo/pom.xml [deleted file]
opendaylight/sal/yang-prototype/code-generator/code-generator-demo/src/main/java/org/opendaylight/controller/yang/Demo.java [deleted file]
opendaylight/sal/yang-prototype/code-generator/code-generator-demo/src/main/resources/demo-topology.yang [deleted file]
opendaylight/sal/yang-prototype/code-generator/code-generator-demo/src/main/resources/demo/types1.yang [deleted file]
opendaylight/sal/yang-prototype/code-generator/code-generator-demo/src/main/resources/demo/types2.yang [deleted file]
opendaylight/sal/yang-prototype/code-generator/code-generator-demo/src/main/resources/demo/types3.yang [deleted file]
opendaylight/sal/yang-prototype/code-generator/samples/maven-code-gen-sample/src/main/yang/controller-network-ne.yang
opendaylight/sal/yang-prototype/code-generator/samples/maven-code-gen-sample/src/main/yang/demo-topology.yang [moved from opendaylight/sal/yang-prototype/code-generator/code-generator-demo/src/main/resources/test-topology.yang with 66% similarity]
opendaylight/sal/yang-prototype/yang/yang-model-util/src/main/java/org/opendaylight/controller/yang/model/util/SchemaContextUtil.java

index b6d8de6..f650004 100644 (file)
@@ -221,7 +221,7 @@ public final class TypeProviderImpl implements TypeProvider {
         final String strXPath = xpath.toString();
 
         if (strXPath != null) {
-            if (strXPath.matches(".*//[.* | .*//].*")) {
+            if (strXPath.contains("[")) {
                 returnType = Types.typeForClass(Object.class);
             } else {
                 final Module module = findParentModuleForTypeDefinition(schemaContext, leafrefType);
index ce9f131..a8b3b48 100644 (file)
@@ -8,12 +8,14 @@
 package org.opendaylight.controller.sal.binding.generator.impl;
 
 import static org.junit.Assert.*;
+import static org.junit.Assert.assertEquals;
 
 import java.io.File;
 import java.util.ArrayList;
 import java.util.List;
 import java.util.Set;
 
+import org.junit.Ignore;
 import org.junit.Test;
 import org.opendaylight.controller.sal.binding.generator.api.BindingGenerator;
 import org.opendaylight.controller.sal.binding.model.api.GeneratedProperty;
@@ -73,9 +75,8 @@ public class GeneratedTypesTest {
         assertNotNull(inetTypesPath);
         assertNotNull(yangTypesPath);
 
-        // final SchemaContext context = resolveSchemaContextFromFiles(
-        // topologyPath, interfacesPath, ifTypePath, inetTypesPath,
-        // yangTypesPath);
+        // final SchemaContext context = resolveSchemaContextFromFiles(topologyPath, interfacesPath, ifTypePath,
+        // inetTypesPath, yangTypesPath);
         final SchemaContext context = resolveSchemaContextFromFiles(topologyPath, interfacesPath, inetTypesPath,
                 yangTypesPath);
         assertNotNull(context);
@@ -94,6 +95,7 @@ public class GeneratedTypesTest {
         GeneratedType gtDest = null;
         GeneratedType gtTunnel = null;
         GeneratedTransferObject gtTunnelKey = null;
+        GeneratedType gtTopology = null;
         for (final Type type : genTypes) {
             String name = type.getName();
             if ("InterfaceKey".equals(name)) {
@@ -110,6 +112,8 @@ public class GeneratedTypesTest {
                 gtTunnel = (GeneratedType) type;
             } else if ("TunnelKey".equals(name)) {
                 gtTunnelKey = (GeneratedTransferObject) type;
+            } else if ("Topology".equals(name)) {
+                gtTopology = (GeneratedType) type;
             }
         }
 
@@ -120,6 +124,21 @@ public class GeneratedTypesTest {
         assertNotNull(gtDest);
         assertNotNull(gtTunnel);
         assertNotNull(gtTunnelKey);
+        assertNotNull(gtTopology);
+
+        // Topology
+        final List<MethodSignature> gtTopoMethods = gtTopology.getMethodDefinitions();
+        assertNotNull(gtTopoMethods);
+        MethodSignature condLeafref = null;
+        for (final MethodSignature method : gtTopoMethods) {
+            if (method.getName().equals("getCondLeafref")) {
+                condLeafref = method;
+            }
+        }
+        assertNotNull(condLeafref);
+        Type condLeafRT = condLeafref.getReturnType();
+        assertNotNull(condLeafRT);
+        assertEquals("java.lang.Object", condLeafRT.getFullyQualifiedName());
 
         // InterfaceId
         final List<GeneratedProperty> gtIfcKeyProps = gtIfcKey.getProperties();
@@ -133,8 +152,7 @@ public class GeneratedTypesTest {
         assertNotNull(ifcIdProp);
         Type ifcIdPropType = ifcIdProp.getReturnType();
         assertNotNull(ifcIdPropType);
-        assertFalse(ifcIdPropType.equals("java.lang.Void"));
-        assertEquals(ifcIdPropType.getName(), "String");
+        assertEquals("java.lang.String", ifcIdPropType.getFullyQualifiedName());
 
         // Interface
         final List<MethodSignature> gtIfcMethods = gtIfc.getMethodDefinitions();
@@ -151,14 +169,14 @@ public class GeneratedTypesTest {
         assertNotNull(getIfcKey);
         Type getIfcKeyType = getIfcKey.getReturnType();
         assertNotNull(getIfcKeyType);
-        assertFalse(getIfcKeyType.equals("java.lang.Void"));
-        assertEquals(getIfcKeyType.getName(), "InterfaceKey");
+        assertNotSame("java.lang.Void", getIfcKeyType);
+        assertEquals("InterfaceKey", getIfcKeyType.getName());
 
         assertNotNull(getHigherLayerIf);
         Type getHigherLayerIfType = getHigherLayerIf.getReturnType();
         assertNotNull(getHigherLayerIfType);
-        assertFalse(getHigherLayerIfType.equals("java.lang.Void"));
-        assertEquals(getHigherLayerIfType.getName(), "List");
+        assertNotSame("java.lang.Void", getHigherLayerIfType);
+        assertEquals("List", getHigherLayerIfType.getName());
 
         // NetworkLink
         final List<MethodSignature> gtNetworkLinkMethods = gtNetworkLink.getMethodDefinitions();
@@ -172,8 +190,8 @@ public class GeneratedTypesTest {
         assertNotNull(getIfc);
         Type getIfcType = getIfc.getReturnType();
         assertNotNull(getIfcType);
-        assertFalse(getIfcType.equals("java.lang.Void"));
-        assertEquals(getIfcType.getName(), "String");
+        assertNotSame("java.lang.Void", getIfcType);
+        assertEquals("String", getIfcType.getName());
 
         // SourceNode
         final List<MethodSignature> gtSourceMethods = gtSource.getMethodDefinitions();
@@ -187,8 +205,8 @@ public class GeneratedTypesTest {
         assertNotNull(getIdSource);
         Type getIdType = getIdSource.getReturnType();
         assertNotNull(getIdType);
-        assertFalse(getIdType.equals("java.lang.Void"));
-        assertEquals(getIdType.getName(), "Uri");
+        assertNotSame("java.lang.Void", getIdType);
+        assertEquals("Uri", getIdType.getName());
 
         // DestinationNode
         final List<MethodSignature> gtDestMethods = gtDest.getMethodDefinitions();
@@ -202,8 +220,8 @@ public class GeneratedTypesTest {
         assertNotNull(getIdDest);
         Type getIdDestType = getIdDest.getReturnType();
         assertNotNull(getIdDestType);
-        assertFalse(getIdDestType.equals("java.lang.Void"));
-        assertEquals(getIdDestType.getName(), "Uri");
+        assertNotSame("java.lang.Void", getIdDestType);
+        assertEquals("Uri", getIdDestType.getName());
 
         // Tunnel
         final List<MethodSignature> gtTunnelMethods = gtTunnel.getMethodDefinitions();
@@ -217,8 +235,8 @@ public class GeneratedTypesTest {
         assertNotNull(getTunnelKey);
         Type getTunnelKeyType = getTunnelKey.getReturnType();
         assertNotNull(getTunnelKeyType);
-        assertFalse(getTunnelKeyType.equals("java.lang.Void"));
-        assertEquals(getTunnelKeyType.getName(), "TunnelKey");
+        assertNotSame("java.lang.Void", getTunnelKeyType);
+        assertEquals("TunnelKey", getTunnelKeyType.getName());
 
         // TunnelKey
         final List<GeneratedProperty> gtTunnelKeyProps = gtTunnelKey.getProperties();
@@ -232,8 +250,8 @@ public class GeneratedTypesTest {
         assertNotNull(tunnelId);
         Type tunnelIdType = tunnelId.getReturnType();
         assertNotNull(tunnelIdType);
-        assertFalse(tunnelIdType.equals("java.lang.Void"));
-        assertEquals(tunnelIdType.getName(), "Uri");
+        assertNotSame("java.lang.Void", tunnelIdType);
+        assertEquals("Uri", tunnelIdType.getName());
     }
 
     @Test
@@ -256,14 +274,11 @@ public class GeneratedTypesTest {
         assertEquals(3, simpleContainer.getMethodDefinitions().size());
         assertEquals(2, nestedContainer.getMethodDefinitions().size());
 
-        int setFooMethodCounter = 0;
         int getFooMethodCounter = 0;
         int getBarMethodCounter = 0;
         int getNestedContainerCounter = 0;
 
         String getFooMethodReturnTypeName = "";
-        String setFooMethodInputParamName = "";
-        String setFooMethodInputParamTypeName = "";
         String getBarMethodReturnTypeName = "";
         String getNestedContainerReturnTypeName = "";
         for (final MethodSignature method : simpleContainer.getMethodDefinitions()) {
@@ -272,13 +287,6 @@ public class GeneratedTypesTest {
                 getFooMethodReturnTypeName = method.getReturnType().getName();
             }
 
-            if (method.getName().equals("setFoo")) {
-                setFooMethodCounter++;
-                final MethodSignature.Parameter param = method.getParameters().get(0);
-                setFooMethodInputParamName = param.getName();
-                setFooMethodInputParamTypeName = param.getType().getName();
-            }
-
             if (method.getName().equals("getBar")) {
                 getBarMethodCounter++;
                 getBarMethodReturnTypeName = method.getReturnType().getName();
@@ -290,31 +298,20 @@ public class GeneratedTypesTest {
             }
         }
 
-        assertEquals(getFooMethodCounter, 1);
-        assertEquals(getFooMethodReturnTypeName, "Integer");
-
-        // TODO no setter methods, because 'config' is default true
-        // assertEquals(setFooMethodCounter, 1);
-        // assertEquals(setFooMethodInputParamName, "foo");
-        // assertEquals(setFooMethodInputParamTypeName, "Integer");
+        assertEquals(1, getFooMethodCounter);
+        assertEquals("Integer", getFooMethodReturnTypeName);
 
-        assertEquals(getBarMethodCounter, 1);
-        assertEquals(getBarMethodReturnTypeName, "String");
+        assertEquals(1, getBarMethodCounter);
+        assertEquals("String", getBarMethodReturnTypeName);
 
-        assertEquals(getNestedContainerCounter, 1);
-        assertEquals(getNestedContainerReturnTypeName, "NestedContainer");
+        assertEquals(1, getNestedContainerCounter);
+        assertEquals("NestedContainer", getNestedContainerReturnTypeName);
 
-        setFooMethodCounter = 0;
         getFooMethodCounter = 0;
         getBarMethodCounter = 0;
-        int setBarMethodCounter = 0;
 
         getFooMethodReturnTypeName = "";
-        setFooMethodInputParamName = "";
-        setFooMethodInputParamTypeName = "";
         getBarMethodReturnTypeName = "";
-        String setBarMethodInputParamName = "";
-        String setBarMethodInputParamTypeName = "";
 
         for (final MethodSignature method : nestedContainer.getMethodDefinitions()) {
 
@@ -323,41 +320,17 @@ public class GeneratedTypesTest {
                 getFooMethodReturnTypeName = method.getReturnType().getName();
             }
 
-            if (method.getName().equals("setFoo")) {
-                setFooMethodCounter++;
-                final MethodSignature.Parameter param = method.getParameters().get(0);
-                setFooMethodInputParamName = param.getName();
-                setFooMethodInputParamTypeName = param.getType().getName();
-            }
-
             if (method.getName().equals("getBar")) {
                 getBarMethodCounter++;
                 getBarMethodReturnTypeName = method.getReturnType().getName();
             }
-
-            if (method.getName().equals("setBar")) {
-                setBarMethodCounter++;
-                final MethodSignature.Parameter param = method.getParameters().get(0);
-                setBarMethodInputParamName = param.getName();
-                setBarMethodInputParamTypeName = param.getType().getName();
-            }
         }
 
         assertEquals(1, getFooMethodCounter);
-        assertEquals(getFooMethodReturnTypeName, "Short");
-
-        // TODO no setter methods, because 'config' is default true
-        // assertEquals(1, setFooMethodCounter);
-        // assertEquals(setFooMethodInputParamName, "foo");
-        // assertEquals(setFooMethodInputParamTypeName, "Short");
+        assertEquals("Short", getFooMethodReturnTypeName);
 
         assertEquals(1, getBarMethodCounter);
-        assertEquals(getBarMethodReturnTypeName, "String");
-
-        // TODO no setter methods, because 'config' is default true
-        // assertEquals(1, setBarMethodCounter);
-        // assertEquals(setBarMethodInputParamName, "bar");
-        // assertEquals(setBarMethodInputParamTypeName, "String");
+        assertEquals("String", getBarMethodReturnTypeName);
     }
 
     @Test
@@ -380,14 +353,11 @@ public class GeneratedTypesTest {
         assertEquals(3, simpleContainer.getMethodDefinitions().size());
         assertEquals(2, nestedContainer.getMethodDefinitions().size());
 
-        int setFooMethodCounter = 0;
         int getFooMethodCounter = 0;
         int getBarMethodCounter = 0;
         int getNestedContainerCounter = 0;
 
         String getFooMethodReturnTypeName = "";
-        String setFooMethodInputParamName = "";
-        String setFooMethodInputParamTypeName = "";
         String getBarMethodReturnTypeName = "";
         String getNestedContainerReturnTypeName = "";
         for (final MethodSignature method : simpleContainer.getMethodDefinitions()) {
@@ -396,13 +366,6 @@ public class GeneratedTypesTest {
                 getFooMethodReturnTypeName = method.getReturnType().getName();
             }
 
-            if (method.getName().equals("setFoo")) {
-                setFooMethodCounter++;
-                final MethodSignature.Parameter param = method.getParameters().get(0);
-                setFooMethodInputParamName = param.getName();
-                setFooMethodInputParamTypeName = param.getType().getName();
-            }
-
             if (method.getName().equals("getBar")) {
                 getBarMethodCounter++;
                 getBarMethodReturnTypeName = method.getReturnType().getName();
@@ -415,26 +378,18 @@ public class GeneratedTypesTest {
         }
 
         assertEquals(1, getFooMethodCounter);
-        assertEquals(getFooMethodReturnTypeName, "List");
-
-        // TODO no setter methods, because 'config' is default true
-        // assertEquals(1, setFooMethodCounter);
-        // assertEquals(setFooMethodInputParamName, "foo");
-        // assertEquals(setFooMethodInputParamTypeName, "List");
+        assertEquals("List", getFooMethodReturnTypeName);
 
         assertEquals(1, getBarMethodCounter);
-        assertEquals(getBarMethodReturnTypeName, "String");
+        assertEquals("String", getBarMethodReturnTypeName);
 
         assertEquals(1, getNestedContainerCounter);
-        assertEquals(getNestedContainerReturnTypeName, "NestedContainer");
+        assertEquals("NestedContainer", getNestedContainerReturnTypeName);
 
-        setFooMethodCounter = 0;
         getFooMethodCounter = 0;
         getBarMethodCounter = 0;
 
         getFooMethodReturnTypeName = "";
-        setFooMethodInputParamName = "";
-        setFooMethodInputParamTypeName = "";
         getBarMethodReturnTypeName = "";
 
         for (final MethodSignature method : nestedContainer.getMethodDefinitions()) {
@@ -443,13 +398,6 @@ public class GeneratedTypesTest {
                 getFooMethodReturnTypeName = method.getReturnType().getName();
             }
 
-            if (method.getName().equals("setFoo")) {
-                setFooMethodCounter++;
-                final MethodSignature.Parameter param = method.getParameters().get(0);
-                setFooMethodInputParamName = param.getName();
-                setFooMethodInputParamTypeName = param.getType().getName();
-            }
-
             if (method.getName().equals("getBar")) {
                 getBarMethodCounter++;
                 getBarMethodReturnTypeName = method.getReturnType().getName();
@@ -457,15 +405,10 @@ public class GeneratedTypesTest {
         }
 
         assertEquals(1, getFooMethodCounter);
-        assertEquals(getFooMethodReturnTypeName, "Short");
-
-        // TODO no setter methods, because 'config' is default true
-        // assertEquals(1, setFooMethodCounter);
-        // assertEquals(setFooMethodInputParamName, "foo");
-        // assertEquals(setFooMethodInputParamTypeName, "Short");
+        assertEquals("Short", getFooMethodReturnTypeName);
 
         assertEquals(1, getBarMethodCounter);
-        assertEquals(getBarMethodReturnTypeName, "List");
+        assertEquals("List", getBarMethodReturnTypeName);
     }
 
     @Test
@@ -480,9 +423,6 @@ public class GeneratedTypesTest {
         assertNotNull(genTypes);
         assertEquals(6, genTypes.size());
 
-        int genTypesCount = 0;
-        int genTOsCount = 0;
-
         int listParentContainerMethodsCount = 0;
         int simpleListMethodsCount = 0;
         int listChildContainerMethodsCount = 0;
@@ -517,7 +457,6 @@ public class GeneratedTypesTest {
                 final GeneratedType genType = (GeneratedType) type;
                 if (genType.getName().equals("ListParentContainer")) {
                     listParentContainerMethodsCount = genType.getMethodDefinitions().size();
-                    genTypesCount++;
                 } else if (genType.getName().equals("SimpleList")) {
                     simpleListMethodsCount = genType.getMethodDefinitions().size();
                     final List<MethodSignature> methods = genType.getMethodDefinitions();
@@ -540,13 +479,10 @@ public class GeneratedTypesTest {
                             getBarMethodCount++;
                         }
                     }
-                    genTypesCount++;
                 } else if (genType.getName().equals("ListChildContainer")) {
                     listChildContainerMethodsCount = genType.getMethodDefinitions().size();
-                    genTypesCount++;
                 }
             } else if (type instanceof GeneratedTransferObject) {
-                genTOsCount++;
                 final GeneratedTransferObject genTO = (GeneratedTransferObject) type;
                 final List<GeneratedProperty> properties = genTO.getProperties();
                 final List<GeneratedProperty> hashProps = genTO.getHashCodeIdentifiers();
index 2d6fc26..be31192 100644 (file)
@@ -57,6 +57,12 @@ module abstract-topology {
             UNIQUE topology identifier.";
         }
 
+        leaf cond-leafref {
+            type leafref {
+                path "/tp:topology/tp:network-nodes/tp:network-node[node-id = 'super-node']";
+            }
+        }
+
         container network-nodes {
             list network-node {
                 key "node-id";
index a394edd..0c4683e 100644 (file)
@@ -30,8 +30,11 @@ public final class BindingGeneratorUtil {
             if (packNameParts != null) {
                 final StringBuilder builder = new StringBuilder();
                 for (int i = 0; i < packNameParts.length; ++i) {
-                    if (JAVA_RESERVED_WORDS.contains(packNameParts[i])) {
-                        packNameParts[i] = "_" + packNameParts[i];
+                    final String packNamePart = packNameParts[i];
+                    if (Character.isDigit(packNamePart.charAt(0))) {
+                        packNameParts[i] = "_" + packNamePart;
+                    } else if (JAVA_RESERVED_WORDS.contains(packNamePart)) {
+                        packNameParts[i] = "_" + packNamePart;
                     }
                     if (i > 0) {
                         builder.append(".");
diff --git a/opendaylight/sal/yang-prototype/code-generator/code-generator-demo/pom.xml b/opendaylight/sal/yang-prototype/code-generator/code-generator-demo/pom.xml
deleted file mode 100644 (file)
index d4c5b05..0000000
+++ /dev/null
@@ -1,53 +0,0 @@
-<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"\r
-       xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">\r
-       <modelVersion>4.0.0</modelVersion>\r
-    <groupId>org.opendaylight.controller</groupId>\r
-       <artifactId>code-generator-demo</artifactId>\r
-    <version>1.0</version>\r
-    <packaging>jar</packaging>\r
-\r
-       <dependencies>\r
-               <dependency>\r
-                       <groupId>org.antlr</groupId>\r
-                       <artifactId>antlr4</artifactId>\r
-                       <version>4.0</version>\r
-               </dependency>\r
-               <dependency>\r
-                       <groupId>org.opendaylight.controller</groupId>\r
-                       <artifactId>binding-generator-impl</artifactId>\r
-               </dependency>\r
-               <dependency>\r
-                       <groupId>org.opendaylight.controller</groupId>\r
-                       <artifactId>binding-java-api-generator</artifactId>\r
-               </dependency>\r
-       </dependencies>\r
-\r
-       <build>\r
-               <plugins>\r
-                       <plugin>\r
-                               <artifactId>maven-assembly-plugin</artifactId>\r
-                               <version>2.4</version>\r
-                               <configuration>\r
-                                       <descriptorRefs>\r
-                                               <descriptorRef>jar-with-dependencies</descriptorRef>\r
-                                       </descriptorRefs>\r
-                                       <archive>\r
-                                               <manifest>\r
-                                                       <mainClass>org.opendaylight.controller.yang.Demo</mainClass>\r
-                                               </manifest>\r
-                                       </archive>\r
-                               </configuration>\r
-                               <executions>\r
-                                       <execution>\r
-                                               <id>make-assembly</id>\r
-                                               <phase>package</phase>\r
-                                               <goals>\r
-                                                       <goal>single</goal>\r
-                                               </goals>\r
-                                       </execution>\r
-                               </executions>\r
-                       </plugin>\r
-               </plugins>\r
-       </build>\r
-</project>\r
-\r
diff --git a/opendaylight/sal/yang-prototype/code-generator/code-generator-demo/src/main/java/org/opendaylight/controller/yang/Demo.java b/opendaylight/sal/yang-prototype/code-generator/code-generator-demo/src/main/java/org/opendaylight/controller/yang/Demo.java
deleted file mode 100644 (file)
index ee54887..0000000
+++ /dev/null
@@ -1,93 +0,0 @@
-/*
- * Copyright (c) 2013 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.controller.yang;
-
-import java.io.File;
-import java.util.ArrayList;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Set;
-
-import org.opendaylight.controller.sal.binding.generator.api.BindingGenerator;
-import org.opendaylight.controller.sal.binding.generator.impl.BindingGeneratorImpl;
-import org.opendaylight.controller.sal.binding.model.api.GeneratedTransferObject;
-import org.opendaylight.controller.sal.binding.model.api.GeneratedType;
-import org.opendaylight.controller.sal.binding.model.api.Type;
-import org.opendaylight.controller.sal.java.api.generator.GeneratorJavaFile;
-import org.opendaylight.controller.yang.model.api.Module;
-import org.opendaylight.controller.yang.model.api.SchemaContext;
-import org.opendaylight.controller.yang.parser.impl.YangParserImpl;
-
-public class Demo {
-    private static final String ERR_MSG = "2 parameters expected: 1. -f=<path-to-input-folder>, 2. -o=<output-folder>";
-
-    public static void main(String[] args) throws Exception {
-        if (args.length != 2) {
-            System.err.println(ERR_MSG);
-            return;
-        }
-
-        String inputFilesDir = null;
-        String outputFilesDir = null;
-        if (args[0].startsWith("-f=")) {
-            inputFilesDir = args[0].substring(3);
-        } else {
-            System.err.println("Missing input-folder declaration (-f=)");
-        }
-
-        if (args[1].startsWith("-o=")) {
-            outputFilesDir = args[1].substring(3);
-        } else {
-            System.err.println("Missing output-folder declaration (-o=)");
-        }
-        
-        File resourceDir = new File(inputFilesDir);
-        if (!resourceDir.exists()) {
-            throw new IllegalArgumentException(
-                    "Specified input-folder does not exists: "
-                            + resourceDir.getAbsolutePath());
-        }
-        
-        final File outputFolder = new File(outputFilesDir);
-        if (!outputFolder.exists()) {
-            outputFolder.mkdirs();
-        }
-        
-        String[] dirList = resourceDir.list();
-        List<File> inputFiles = new ArrayList<File>();
-        for (String fileName : dirList) {
-            inputFiles.add(new File(resourceDir, fileName));
-        }
-
-        final YangParserImpl parser = new YangParserImpl();
-        final BindingGenerator bindingGenerator = new BindingGeneratorImpl();
-        final Set<Module> modulesToBuild = parser.parseYangModels(inputFiles);
-
-        final SchemaContext context = parser
-                .resolveSchemaContext(modulesToBuild);
-        final List<Type> types = bindingGenerator.generateTypes(context);
-        final Set<GeneratedType> typesToGenerate = new HashSet<GeneratedType>();
-        final Set<GeneratedTransferObject> tosToGenerate = new HashSet<GeneratedTransferObject>();
-        for (Type type : types) {
-            if (type instanceof GeneratedType && !(type instanceof GeneratedTransferObject)) {
-                typesToGenerate.add((GeneratedType) type);
-            }
-
-            if (type instanceof GeneratedTransferObject) {
-                tosToGenerate.add((GeneratedTransferObject) type);
-            } else if (type instanceof GeneratedType) {
-                typesToGenerate.add((GeneratedType) type);
-            }
-        }
-
-        final GeneratorJavaFile generator = new GeneratorJavaFile(typesToGenerate, tosToGenerate);
-        
-        generator.generateToFile(outputFolder);
-        System.out.println("Modules built: " + modulesToBuild.size());
-    }
-}
diff --git a/opendaylight/sal/yang-prototype/code-generator/code-generator-demo/src/main/resources/demo-topology.yang b/opendaylight/sal/yang-prototype/code-generator/code-generator-demo/src/main/resources/demo-topology.yang
deleted file mode 100644 (file)
index 303edc2..0000000
+++ /dev/null
@@ -1,223 +0,0 @@
-module demo-topology {
-    yang-version 1;
-    namespace "urn:demo.simple-topology";
-    prefix "tp";
-    import simple-list-demo { prefix "simple"; revision-date 2008-01-01; }
-    import controller-network {prefix "cn";}
-       import mount  {prefix "mnt";}
-
-    organization "OPEN DAYLIGHT";
-    contact "http://www.opendaylight.org/";
-
-    description "
-        This module contains the definitions of elements that creates network 
-        topology i.e. definition of network nodes and links. This module is
-        not designed to be used solely for network representation. This module
-        SHOULD be used as base module in defining the network topology.
-    ";
-
-    revision "2013-02-08"{
-        reference " WILL BE DEFINED LATER";
-    }
-    
-    
-    
-    
-    
-    deviation /base:system/base:user/base:type {
-         deviate add {
-             default "admin"; // new users are 'admin' by default
-         }
-     }
-     
-    deviation /base:system/base:name-server {
-         deviate replace {
-             max-elements 3;
-         }
-     }
-     
-     deviation "/base:system" {
-         deviate delete {
-             must "daytime or time";
-         }
-     }
-     
-     
-     
-     
-     
-    
-    grouping target {
-       status "current";
-         leaf address {
-             type inet:ip-address;
-             description "Target IP address";
-         }
-         leaf port {
-             type inet:port-number;
-             description "Target port number";
-         }
-     }
-     
-     augment "/cn:network/cn:topologies/cn:topology" {
-        container prefixes {
-            container "prefix" {
-                leaf id {
-                    type string;
-
-                    description "";
-                }
-
-                leaf-list advertising-node-id {
-                    type cn:node-ref;
-
-                    description "";
-                }
-            }
-        }
-        mnt:mountpoint point  {
-               mnt:target-ref target;
-           
-            } 
-    }
-
-     container peer {
-         container destination {
-             uses target;
-         }
-     }
-
-    container topology {
-    
-       leaf ifType {
-             type enumeration {
-                 enum ethernet;
-                 enum atm;
-             }
-         }
-         leaf ifMTU {
-             type uint32;
-         }
-         must "ifType != 'ethernet' or " +
-              "(ifType = 'ethernet' and ifMTU = 1500)" {
-             error-message "An ethernet MTU must be 1500";
-         }
-    
-       presence "test-presence";
-    
-        description "
-            This is the model of abstract topology which contains only Network
-            Nodes and Network Links. Each topology MUST be identified by
-            unique topology-id for reason that the store could contain many
-            topologies.
-        ";
-
-        leaf topology-id {
-            type string;
-            description "
-                It is presumed that datastore will contain many topologies. To
-                distinguish between topologies it is vital to have UNIQUE
-                topology identifier.
-            ";
-        }
-
-        container network-nodes {
-            list network-node {
-               ordered-by system;
-                description "The list of network nodes defined for topology.";
-
-                key "node-id";
-
-                leaf node-id {
-                    type string;
-                    description "The Topology identifier of network-node.";
-                }
-                
-                list network-interface {
-                    key "interface-id";
-                    
-                    leaf interface-id {
-                        type uint8;
-                    }
-                    
-                    leaf interface-address {
-                        type string;
-                    }
-                }
-                
-                container node-attributes {
-                    description "
-                        Additional attributes that can Network Node contains.
-                    ";
-
-                    leaf geo-latitude {
-                        type decimal64 {
-                            fraction-digits 2;
-                        }
-                        config true;
-                    }
-
-                    leaf geo-longitude {
-                        type decimal64 {
-                            fraction-digits 2;
-                        }
-                        config true;
-                    }
-                }
-            }
-        }
-        
-        container network-links {
-            list network-link {
-                description "
-                    The Network Link which is defined by Local (Source) and
-                    Remote (Destination) Network Nodes. Every link MUST be
-                    defined either by identifier and his local and remote
-                    Network Nodes (in real applications it is common that many
-                    links are originated from one node and end up in same
-                    remote node). To ensure that we would always know to
-                    distinguish between links, every link SHOULD have
-                    identifier.
-                ";
-                key "link-id";
-
-                leaf link-id {
-                    type string;
-                    description "";
-                }
-
-                container source {
-                    leaf node-id {
-                        type string;
-                        description "Source node identifier.";
-                    }
-                }
-
-                container destination {
-                    leaf node-id {
-                        type string;
-                        description "Destination node identifier.";
-                    }
-                }
-
-                container link-attributes {
-                    description "Aditional attributes that can Network Link contains.";
-                }
-            }
-        }
-    }
-    
-    rpc activate-software-image {
-         input {
-             leaf image-name {
-                 type string;
-             }
-         }
-         output {
-             leaf status {
-                 type string;
-             }
-         }
-     }
-     
-}
diff --git a/opendaylight/sal/yang-prototype/code-generator/code-generator-demo/src/main/resources/demo/types1.yang b/opendaylight/sal/yang-prototype/code-generator/code-generator-demo/src/main/resources/demo/types1.yang
deleted file mode 100644 (file)
index 1025298..0000000
+++ /dev/null
@@ -1,80 +0,0 @@
-module types1 {
-       yang-version 1;
-    namespace "urn:simple.container.demo";
-    prefix "t1";
-    
-
-    organization "Cisco";
-
-    contact "WILL-BE-DEFINED-LATER";
-    
-    
-    leaf mybits {
-         type bits {
-             bit disable-nagle {
-                 position 0;
-             }
-             bit auto-sense-speed {
-                 position 1;
-             }
-             bit 10-Mb-only {
-                 position 2;
-             }
-         }
-         default "auto-sense-speed";
-     }
-    
-    container interfaces {
-         list ifEntry {
-             key "ifIndex";
-
-             leaf ifIndex {
-                 type uint32;
-             }
-             leaf ifDescr {
-                 type string;
-             }
-             leaf ifType {
-                 type uint8;
-             }
-             leaf ifMtu {
-                 type int32;
-             }
-         }
-     }
-    
-    
-       container topology {
-               leaf name {
-                       type string;
-               }
-       }
-       
-       
-       
-       
-       
-       
-       
-//     typedef my-string {
-//             type string {
-//                     length "0..4";
-//             pattern "[0-9a-fA-F]*";
-//             }
-//     }
-
-
-//     leaf completed {
-//             type types2:percent;
-//  }
-
-//     leaf testleaf {
-//             type data:my-base-int32-type;
-//     }
-
-//     leaf-list domain-search {
-//             type string;
-//             description "List of domain names to search";
-//     }
-       
-}
diff --git a/opendaylight/sal/yang-prototype/code-generator/code-generator-demo/src/main/resources/demo/types2.yang b/opendaylight/sal/yang-prototype/code-generator/code-generator-demo/src/main/resources/demo/types2.yang
deleted file mode 100644 (file)
index a056bdb..0000000
+++ /dev/null
@@ -1,35 +0,0 @@
-module types2 {
-       yang-version 1;
-    namespace "urn:simple.types.data.demo";
-    prefix "t2";
-    
-    import types1 {
-         prefix "t1";
-     }
-
-    organization "Cisco";
-
-    contact "WILL-BE-DEFINED-LATER";
-
-    description "This is types-data test description";
-
-    revision "2013-02-27" {
-        reference " WILL BE DEFINED LATER";
-    }
-    
-    
-     augment "/t1:interfaces/t1:ifEntry" {
-         when "t1:ifType='ds0'";
-         leaf ds0ChannelNumber {
-             type string;
-         }
-     }
-     
-     typedef my-leaf-ref {
-               type leafref {
-                       path "/t1:topology/t1:name";
-               }
-               description "This type is used for leafs that reference network node instance.";
-       }
-     
-}
diff --git a/opendaylight/sal/yang-prototype/code-generator/code-generator-demo/src/main/resources/demo/types3.yang b/opendaylight/sal/yang-prototype/code-generator/code-generator-demo/src/main/resources/demo/types3.yang
deleted file mode 100644 (file)
index 0d09259..0000000
+++ /dev/null
@@ -1,35 +0,0 @@
-module types3 {
-       yang-version 1;
-    namespace "urn:simple.types3.data.demo";
-    prefix "scd";
-
-    organization "Cisco";
-
-    contact "WILL-BE-DEFINED-LATER";
-
-    description "This is types-data test description";
-
-    revision "2013-02-27" {
-        reference " WILL BE DEFINED LATER";
-    }
-    
-    typedef my-decimal {
-         type decimal64 {
-               fraction-digits 2;
-         }
-    }
-
-       typedef my-base-int32-type {
-         type int32 {
-               range "0..32";
-         }
-    }
-    
-    typedef percent {
-         type uint8 {
-             range "0 .. 100";
-         }
-         description "Percentage";
-       }
-       
-}
index 8b576c3..ca8507f 100644 (file)
@@ -14,7 +14,7 @@ module controller-openflow-ne {
 
     augment "/cn:network/cn:network-elements/cn:network-element" {
 
-        container flow-tables {
+        container flow-tables2 {
             list flow-table {
 
                 key "id";
@@ -1,13 +1,9 @@
-// vi: set smarttab sw=4 tabstop=4:
-module abstract-topology {
+module demo-topology {
        yang-version 1;
-    namespace "pre:simple.test.demo";
+    namespace "urn:model.1demo-275topology.4.5.my";
     prefix "tp";
 
-       import ietf-inet-types { prefix "inet"; }
-    import abstract-prefixes { prefix "abs-pref"; }
-    
-       organization "OPEN DAYLIGHT";
+    organization "OPEN DAYLIGHT";
     contact "http://www.opendaylight.org/";
 
     description "
@@ -16,30 +12,9 @@ module abstract-topology {
                not designed to be used solely for network representation. This module
                SHOULD be used as base module in defining the network topology.
        ";
-    
-    revision "2012-02-08" {
-        reference " WILL BE DEFINED LATER";
-    }
-
-    typedef topology-id-ref {
-       type leafref {
-               path "/tp:topology/tp:topology-id";
-       }
-       description "This type is used for leafs that reference topology identifier instance.";
-    }
 
-       typedef network-node-id-ref {
-               type leafref {
-                       path "/tp:topology/tp:network-nodes/tp:network-node/tp:node-id";
-               }
-               description "This type is used for leafs that reference network node instance.";
-       }
-
-       typedef link-id-ref {
-               type leafref {
-                       path "/tp:topology/tp:network-links/tp:network-link/tp:link-id";
-               }
-               description "This type is used for leafs that reference network link instance.";
+    revision "2013-02-08"{
+               reference " WILL BE DEFINED LATER";
        }
 
        container topology {
@@ -51,7 +26,7 @@ module abstract-topology {
                ";
 
         leaf topology-id {
-            type inet:uri;
+            type string;
             description "
                                It is presumed that datastore will contain many topologies. To
                                distinguish between topologies it is vital to have UNIQUE
@@ -66,14 +41,40 @@ module abstract-topology {
                        key "node-id";
 
                        leaf node-id {
-                               type inet:uri;
+                               type string;
                                description "The Topology identifier of network-node.";
                        }
-
-                   container attributes {
+                
+                list network-interface {
+                    key "interface-id";
+                    
+                    leaf interface-id {
+                        type uint8;
+                    }
+                    
+                    leaf interface-address {
+                        type string;
+                    }
+                }
+                
+                   container node-attributes {
                                        description "
                                                Additional attributes that can Network Node contains.
                                        ";
+
+                                       leaf geo-latitude {
+                                               type decimal64 {
+                                                       fraction-digits 2;
+                                               }
+                                               config true;
+                                       }
+
+                                       leaf geo-longitude {
+                                               type decimal64 {
+                                                       fraction-digits 2;
+                                               }
+                                               config true;
+                                       }
                                }
                }
         }
@@ -93,30 +94,28 @@ module abstract-topology {
                        key "link-id";
 
                        leaf link-id {
-                               type inet:uri;
+                               type string;
                                description "";
                        }
 
                    container source {
                                        leaf node-id {
-                                               type node-id-ref;
+                                               type string;
                                                description "Source node identifier.";
                                        }
                                }
 
                                container destination {
                                        leaf node-id {
-                                               type node-id-ref;
+                                               type string;
                                                description "Destination node identifier.";
                                        }
                                }
 
-                               container attributes {
+                               container link-attributes {
                                        description "Aditional attributes that can Network Link contains.";
                                }
                    }
         }
     }
-
-    //TODO: add base operations
-}
+}
\ No newline at end of file
index 44ef804..1d702c2 100644 (file)
@@ -16,99 +16,254 @@ import java.util.Set;
 import org.opendaylight.controller.yang.common.QName;
 import org.opendaylight.controller.yang.model.api.*;
 
+/**
+ * The Schema Context Util contains support methods for searching through Schema Context modules for specified schema
+ * nodes via Schema Path or Revision Aware XPath. The Schema Context Util is designed as mixin,
+ * so it is not instantiable.
+ *
+ * @author Lukas Sedlak <lsedlak@cisco.com>
+ */
 public final class SchemaContextUtil {
 
     private SchemaContextUtil() {
     }
 
+    /**
+     * Method attempts to find DataSchemaNode in Schema Context via specified Schema Path. The returned
+     * DataSchemaNode from method will be the node at the end of the SchemaPath. If the DataSchemaNode is not present
+     * in the Schema Context the method will return <code>null</code>.
+     * <br>
+     * In case that Schema Context or Schema Path are not specified correctly (i.e. contains <code>null</code>
+     * values) the method will return IllegalArgumentException.
+     *
+     * @throws IllegalArgumentException
+     * 
+     * @param context
+     *            Schema Context
+     * @param schemaPath
+     *            Schema Path to search for
+     * @return DataSchemaNode from the end of the Schema Path or
+     *         <code>null</code> if the Node is not present.
+     */
     public static DataSchemaNode findDataSchemaNode(final SchemaContext context, final SchemaPath schemaPath) {
-        if (schemaPath != null) {
-            final Module module = resolveModuleFromSchemaPath(context, schemaPath);
-            final Queue<QName> prefixedPath = new LinkedList<>(schemaPath.getPath());
+        if (context == null) {
+            throw new IllegalArgumentException("Schema Context reference cannot be NULL!");
+        }
+        if (schemaPath == null) {
+            throw new IllegalArgumentException("Schema Path reference cannot be NULL");
+        }
 
-            if ((module != null) && (prefixedPath != null)) {
-                return findSchemaNodeForGivenPath(context, module, prefixedPath);
-            }
+        final Module module = resolveModuleFromSchemaPath(context, schemaPath);
+        final Queue<QName> prefixedPath = new LinkedList<>(schemaPath.getPath());
+
+        if ((module != null) && (prefixedPath != null)) {
+            return findSchemaNodeForGivenPath(context, module, prefixedPath);
         }
         return null;
     }
 
+    /**
+     * Method attempts to find DataSchemaNode inside of provided Schema Context and Yang Module accordingly to
+     * Non-conditional Revision Aware XPath. The specified Module MUST be present in Schema Context otherwise the
+     * operation would fail and return <code>null</code>.
+     * <br>
+     * The Revision Aware XPath MUST be specified WITHOUT the conditional statement (i.e. without [cond]) in path,
+     * because in this state the Schema Context is completely unaware of data state and will be not able to properly
+     * resolve XPath. If the XPath contains condition the method will return IllegalArgumentException.
+     * <br>
+     * In case that Schema Context or Module or Revision Aware XPath contains <code>null</code> references the method
+     * will throw IllegalArgumentException
+     * <br>
+     * If the Revision Aware XPath is correct and desired Data Schema Node is present in Yang module or in depending
+     * module in Schema Context the method will return specified Data Schema Node, otherwise the operation will fail
+     * and method will return <code>null</code>.
+     *
+     * @throws IllegalArgumentException
+     *
+     * @param context Schema Context
+     * @param module Yang Module
+     * @param nonCondXPath Non Conditional Revision Aware XPath
+     * @return Returns Data Schema Node for specified Schema Context for given Non-conditional Revision Aware XPath,
+     * or <code>null</code> if the DataSchemaNode is not present in Schema Context.
+     */
     public static DataSchemaNode findDataSchemaNode(final SchemaContext context, final Module module,
             final RevisionAwareXPath nonCondXPath) {
-        if (nonCondXPath != null) {
-            final String strXPath = nonCondXPath.toString();
+        if (context == null) {
+            throw new IllegalArgumentException("Schema Context reference cannot be NULL!");
+        }
+        if (module == null) {
+            throw new IllegalArgumentException("Module reference cannot be NULL!");
+        }
+        if (nonCondXPath == null) {
+            throw new IllegalArgumentException("Non Conditional Revision Aware XPath cannot be NULL!");
+        }
 
-            if (strXPath != null) {
-                if (strXPath.matches(".*//[.* | .*//].*")) {
-                    // TODO: function to escape conditions in path
-                }
-                if (nonCondXPath.isAbsolute()) {
-                    final Queue<QName> qnamedPath = xpathToQNamePath(context, module, strXPath);
-                    if (qnamedPath != null) {
-                        final DataSchemaNode dataNode = findSchemaNodeForGivenPath(context, module, qnamedPath);
-                        return dataNode;
-                    }
+        final String strXPath = nonCondXPath.toString();
+        if (strXPath != null) {
+            if (strXPath.contains("[")) {
+                throw new IllegalArgumentException("Revision Aware XPath cannot contains condition!");
+            }
+            if (nonCondXPath.isAbsolute()) {
+                final Queue<QName> qnamedPath = xpathToQNamePath(context, module, strXPath);
+                if (qnamedPath != null) {
+                    final DataSchemaNode dataNode = findSchemaNodeForGivenPath(context, module, qnamedPath);
+                    return dataNode;
                 }
             }
         }
         return null;
     }
 
+    /**
+     * Method attempts to find DataSchemaNode inside of provided Schema Context and Yang Module accordingly to
+     * Non-conditional relative Revision Aware XPath. The specified Module MUST be present in Schema Context otherwise
+     * the operation would fail and return <code>null</code>.
+     * <br>
+     * The relative Revision Aware XPath MUST be specified WITHOUT the conditional statement (i.e. without [cond]) in
+     * path, because in this state the Schema Context is completely unaware of data state and will be not able to
+     * properly resolve XPath. If the XPath contains condition the method will return IllegalArgumentException.
+     * <br>
+     * The Actual Schema Node MUST be specified correctly because from this Schema Node will search starts. If the
+     * Actual Schema Node is not correct the operation will simply fail, because it will be unable to find desired
+     * DataSchemaNode.
+     * <br>
+     * In case that Schema Context or Module or Actual Schema Node or relative Revision Aware XPath contains
+     * <code>null</code> references the method will throw IllegalArgumentException
+     * <br>
+     * If the Revision Aware XPath doesn't have flag <code>isAbsolute == false</code> the method will
+     * throw IllegalArgumentException.
+     * <br>
+     * If the relative Revision Aware XPath is correct and desired Data Schema Node is present in Yang module or in
+     * depending module in Schema Context the method will return specified Data Schema Node,
+     * otherwise the operation will fail
+     * and method will return <code>null</code>.
+     *
+     * @throws IllegalArgumentException
+     *
+     * @param context Schema Context
+     * @param module Yang Module
+     * @param actualSchemaNode Actual Schema Node
+     * @param relativeXPath Relative Non Conditional Revision Aware XPath
+     * @return DataSchemaNode if is present in specified Schema Context for given relative Revision Aware XPath,
+     * otherwise will return <code>null</code>.
+     */
     public static DataSchemaNode findDataSchemaNodeForRelativeXPath(final SchemaContext context, final Module module,
             final SchemaNode actualSchemaNode, final RevisionAwareXPath relativeXPath) {
-        if ((actualSchemaNode != null) && (relativeXPath != null) && !relativeXPath.isAbsolute()) {
+        if (context == null) {
+            throw new IllegalArgumentException("Schema Context reference cannot be NULL!");
+        }
+        if (module == null) {
+            throw new IllegalArgumentException("Module reference cannot be NULL!");
+        }
+        if (actualSchemaNode == null) {
+            throw new IllegalArgumentException("Actual Schema Node reference cannot be NULL!");
+        }
+        if (relativeXPath == null) {
+            throw new IllegalArgumentException("Non Conditional Revision Aware XPath cannot be NULL!");
+        }
+        if (relativeXPath.isAbsolute()) {
+            throw new IllegalArgumentException("Revision Aware XPath MUST be relative i.e. MUST contains ../, "
+                    + "for non relative Revision Aware XPath use findDataSchemaNode method!");
+        }
 
-            final SchemaPath actualNodePath = actualSchemaNode.getPath();
-            if (actualNodePath != null) {
-                final Queue<QName> qnamePath = resolveRelativeXPath(context, module, relativeXPath, actualNodePath);
+        final SchemaPath actualNodePath = actualSchemaNode.getPath();
+        if (actualNodePath != null) {
+            final Queue<QName> qnamePath = resolveRelativeXPath(context, module, relativeXPath, actualNodePath);
 
-                if (qnamePath != null) {
-                    final DataSchemaNode dataNode = findSchemaNodeForGivenPath(context, module, qnamePath);
-                    return dataNode;
-                }
+            if (qnamePath != null) {
+                final DataSchemaNode dataNode = findSchemaNodeForGivenPath(context, module, qnamePath);
+                return dataNode;
             }
         }
-
         return null;
     }
 
+    /**
+     * Retrieve information from Schema Path and returns the module reference to which Schema Node belongs. The
+     * search for correct Module is based on namespace within the last item in Schema Path. If schema context
+     * contains module with namespace specified in last item of Schema Path, then operation will returns Module
+     * reference, otherwise returns <code>null</code>
+     * <br>
+     * If Schema Context or Schema Node contains <code>null</code> references the method will throw IllegalArgumentException
+     *
+     * @throws IllegalArgumentException
+     *
+     * @param context Schema Context
+     * @param schemaPath Schema Path
+     * @return Module reference for given Schema Path if module is present in Schema Context,
+     * otherwise returns <code>null</code>
+     */
     private static Module resolveModuleFromSchemaPath(final SchemaContext context, final SchemaPath schemaPath) {
-        if ((schemaPath != null) && (schemaPath.getPath() != null)) {
-            final List<QName> path = schemaPath.getPath();
-            if (!path.isEmpty()) {
-                final QName qname = path.get(path.size() - 1);
+        if (context == null) {
+            throw new IllegalArgumentException("Schema Context reference cannot be NULL!");
+        }
+        if (schemaPath == null) {
+            throw new IllegalArgumentException("Schema Path reference cannot be NULL");
+        }
 
-                if ((qname != null) && (qname.getNamespace() != null)) {
-                    return context.findModuleByNamespace(qname.getNamespace());
-                }
+        final List<QName> path = schemaPath.getPath();
+        if (!path.isEmpty()) {
+            final QName qname = path.get(path.size() - 1);
+
+            if ((qname != null) && (qname.getNamespace() != null)) {
+                return context.findModuleByNamespace(qname.getNamespace());
             }
         }
+
         return null;
     }
 
+    /**
+     * Returns the Yang Module from specified Schema Context in which the TypeDefinition is declared. If the
+     * TypeDefinition si not present in Schema Context then the method will return <code>null</code>
+     *
+     * If Schema Context or TypeDefinition contains <code>null</code> references the method will throw IllegalArgumentException
+     *
+     * @throws IllegalArgumentException
+     *
+     * @param context Schema Context
+     * @param type Type Definition
+     * @return Yang Module in which the TypeDefinition is declared, if is not present, returns <code>null</code>.
+     */
     public static Module findParentModuleForTypeDefinition(final SchemaContext context, final TypeDefinition<?> type) {
         final SchemaPath schemaPath = type.getPath();
-        if ((schemaPath != null) && (schemaPath.getPath() != null)) {
-            if (type instanceof ExtendedType) {
-                List<QName> path = schemaPath.getPath();
-                final QName qname = path.get(path.size() - 1);
-
-                if ((qname != null) && (qname.getNamespace() != null)) {
-                    return context.findModuleByNamespace(qname.getNamespace());
-                }
-            } else {
-                List<QName> path = schemaPath.getPath();
-                final QName qname = path.get(path.size() - 2);
+        if (schemaPath == null) {
+            throw new IllegalArgumentException("Schema Path reference cannot be 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.");
+        }
 
-                if ((qname != null) && (qname.getNamespace() != null)) {
-                    return context.findModuleByNamespace(qname.getNamespace());
-                }
+        if (type instanceof ExtendedType) {
+            final QName qname = qnamedPath.get(qnamedPath.size() - 1);
+            if ((qname != null) && (qname.getNamespace() != null)) {
+                return context.findModuleByNamespace(qname.getNamespace());
+            }
+        } else {
+            final QName qname = qnamedPath.get(qnamedPath.size() - 2);
+            if ((qname != null) && (qname.getNamespace() != null)) {
+                return context.findModuleByNamespace(qname.getNamespace());
             }
-
         }
         return null;
     }
 
+    /**
+     * Returns parent Yang Module for specified Schema Context in which Schema Node is declared. If the Schema Node
+     * is not present in Schema Context the operation will return <code>null</code>.
+     * <br>
+     * If Schema Context or Schema Node contains <code>null</code> references the method will throw IllegalArgumentException
+     *
+     * @throws IllegalArgumentException
+     *
+     * @param context Schema Context
+     * @param schemaNode Schema Node
+     * @return Yang Module for specified Schema Context and Schema Node, if Schema Node is NOT present,
+     * the method will returns <code>null</code>
+     */
     public static Module findParentModule(final SchemaContext context, final SchemaNode schemaNode) {
         if (context == null) {
             throw new IllegalArgumentException("Schema Context reference cannot be NULL!");
@@ -132,120 +287,246 @@ public final class SchemaContextUtil {
         return context.findModuleByNamespace(qname.getNamespace());
     }
 
+    /**
+     * Method will attempt to find DataSchemaNode from specified Module and Queue of QNames through the Schema
+     * Context. The QNamed path could be defined across multiple modules in Schema Context so the method is called
+     * recursively. If the QNamed path contains QNames that are not part of any Module or Schema Context Path the
+     * operation will fail and returns <code>null</code>
+     * <br>
+     * If Schema Context, Module or Queue of QNames refers to <code>null</code> values,
+     * the method will throws IllegalArgumentException
+     *
+     * @throws IllegalArgumentException
+     *
+     * @param context Schema Context
+     * @param module Yang Module
+     * @param qnamedPath Queue of QNames
+     * @return DataSchemaNode if is present in Module(s) for specified Schema Context and given QNamed Path,
+     * otherwise will return <code>null</code>.
+     */
     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;
-            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 if (schemaNode instanceof ChoiceNode) {
-                            final ChoiceNode choice = (ChoiceNode) schemaNode;
-                            qnamedPath.poll();
-                            if (!qnamedPath.isEmpty()) {
-                                childNodeQName = qnamedPath.peek();
-                                nextNode = choice.getCaseNodeByName(childNodeQName);
-                                schemaNode = (DataSchemaNode)nextNode;
-                            }
-                        } else {
-                            nextNode = null;
+        if (context == null) {
+            throw new IllegalArgumentException("Schema Context reference cannot be NULL!");
+        }
+        if (module == null) {
+            throw new IllegalArgumentException("Module reference cannot be NULL!");
+        }
+        if (module.getNamespace() == null) {
+            throw new IllegalArgumentException("Namespace for Module cannot contains NULL reference!");
+        }
+        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.");
+        }
+
+        DataNodeContainer nextNode = module;
+        final URI moduleNamespace = module.getNamespace();
+
+        QName childNodeQName;
+        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 if (schemaNode instanceof ChoiceNode) {
+                        final ChoiceNode choice = (ChoiceNode) schemaNode;
+                        qnamedPath.poll();
+                        if (!qnamedPath.isEmpty()) {
+                            childNodeQName = qnamedPath.peek();
+                            nextNode = choice.getCaseNodeByName(childNodeQName);
+                            schemaNode = (DataSchemaNode) nextNode;
                         }
-                    } else if (!childNodeNamespace.equals(moduleNamespace)) {
-                        final Module nextModule = context.findModuleByNamespace(childNodeNamespace);
-                        schemaNode = findSchemaNodeForGivenPath(context, nextModule, qnamedPath);
-                        return schemaNode;
+                    } else {
+                        nextNode = null;
                     }
-                    qnamedPath.poll();
+                } else if (!childNodeNamespace.equals(moduleNamespace)) {
+                    final Module nextModule = context.findModuleByNamespace(childNodeNamespace);
+                    schemaNode = findSchemaNodeForGivenPath(context, nextModule, qnamedPath);
+                    return schemaNode;
                 }
+                qnamedPath.poll();
             }
-            return schemaNode;
         }
-        return null;
+        return schemaNode;
     }
 
+    /**
+     * Transforms string representation of XPath to Queue of QNames. The XPath is split by "/" and for each part of
+     * XPath is assigned correct module in Schema Path.
+     * <br>
+     * If Schema Context, Parent Module or XPath string contains <code>null</code> values,
+     * the method will throws IllegalArgumentException
+     *
+     * @throws IllegalArgumentException
+     *
+     * @param context Schema Context
+     * @param parentModule Parent Module
+     * @param xpath XPath String
+     * @return
+     */
     private static Queue<QName> xpathToQNamePath(final SchemaContext context, final Module parentModule,
             final String xpath) {
-        final Queue<QName> path = new LinkedList<>();
-        if (xpath != null) {
-            final String[] prefixedPath = xpath.split("/");
+        if (context == null) {
+            throw new IllegalArgumentException("Schema Context reference cannot be NULL!");
+        }
+        if (parentModule == null) {
+            throw new IllegalArgumentException("Parent Module reference cannot be NULL!");
+        }
+        if (xpath == null) {
+            throw new IllegalArgumentException("XPath string reference cannot be NULL!");
+        }
 
-            for (int i = 0; i < prefixedPath.length; ++i) {
-                if (!prefixedPath[i].isEmpty()) {
-                    path.add(stringPathPartToQName(context, parentModule, prefixedPath[i]));
-                }
+        final Queue<QName> path = new LinkedList<>();
+        final String[] prefixedPath = xpath.split("/");
+        for (int i = 0; i < prefixedPath.length; ++i) {
+            if (!prefixedPath[i].isEmpty()) {
+                path.add(stringPathPartToQName(context, parentModule, prefixedPath[i]));
             }
         }
         return path;
     }
 
+    /**
+     * Transforms part of Prefixed Path as java String to QName.
+     * <br>
+     * If the string contains module prefix separated by ":" (i.e. mod:container) this module is provided from from
+     * Parent Module list of imports. If the Prefixed module is present in Schema Context the QName can be
+     * constructed.
+     * <br>
+     * If the Prefixed Path Part does not contains prefix the Parent's Module namespace is taken for construction of
+     * QName.
+     * <br>
+     * If Schema Context, Parent Module or Prefixed Path Part refers to <code>null</code> the method will throw
+     * IllegalArgumentException
+     *
+     * @throws IllegalArgumentException
+     *
+     * @param context Schema Context
+     * @param parentModule Parent Module
+     * @param prefixedPathPart Prefixed Path Part string
+     * @return QName from prefixed Path Part String.
+     */
     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);
+        if (context == null) {
+            throw new IllegalArgumentException("Schema Context reference cannot be NULL!");
+        }
+        if (parentModule == null) {
+            throw new IllegalArgumentException("Parent Module reference cannot be NULL!");
+        }
+        if (prefixedPathPart == null) {
+            throw new IllegalArgumentException("Prefixed Path Part cannot be 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;
     }
 
+    /**
+     * Method will attempt to resolve and provide Module reference for specified module prefix. Each Yang module
+     * could contains multiple imports which MUST be associated with corresponding module prefix. The method simply
+     * looks into module imports and returns the module that is bounded with specified prefix. If the prefix is not
+     * present in module or the prefixed module is not present in specified Schema Context,
+     * the method will return <code>null</code>.
+     * <br>
+     * If String prefix is the same as prefix of the specified Module the reference to this module is returned.
+     * <br>
+     * If Schema Context, Module or Prefix are referring to <code>null</code> the method will return
+     * IllegalArgumentException
+     *
+     * @throws IllegalArgumentException
+     *
+     * @param context Schema Context
+     * @param module Yang Module
+     * @param prefix Module Prefix
+     * @return Module for given prefix in specified Schema Context if is present, otherwise returns <code>null</code>
+     */
     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;
-            }
+        if (context == null) {
+            throw new IllegalArgumentException("Schema Context reference cannot be NULL!");
+        }
+        if (module == null) {
+            throw new IllegalArgumentException("Module reference cannot be NULL!");
+        }
+        if (prefix == null) {
+            throw new IllegalArgumentException("Prefix string cannot be NULL!");
+        }
 
-            final Set<ModuleImport> imports = module.getImports();
+        if (prefix.equals(module.getPrefix())) {
+            return module;
+        }
 
-            for (final ModuleImport mi : imports) {
-                if (prefix.equals(mi.getPrefix())) {
-                    return context.findModuleByName(mi.getModuleName(), mi.getRevision());
-                }
+        final Set<ModuleImport> imports = module.getImports();
+        for (final ModuleImport mi : imports) {
+            if (prefix.equals(mi.getPrefix())) {
+                return context.findModuleByName(mi.getModuleName(), mi.getRevision());
             }
         }
         return null;
     }
 
+    /**
+     * @throws IllegalArgumentException
+     *
+     * @param context Schema Context
+     * @param module Yang Module
+     * @param relativeXPath Non conditional Revision Aware Relative XPath
+     * @param leafrefSchemaPath Schema Path for Leafref
+     * @return
+     */
     private static Queue<QName> resolveRelativeXPath(final SchemaContext context, final Module module,
             final RevisionAwareXPath relativeXPath, final SchemaPath leafrefSchemaPath) {
         final Queue<QName> absolutePath = new LinkedList<>();
+        if (context == null) {
+            throw new IllegalArgumentException("Schema Context reference cannot be NULL!");
+        }
+        if (module == null) {
+            throw new IllegalArgumentException("Module reference cannot be NULL!");
+        }
+        if (relativeXPath == null) {
+            throw new IllegalArgumentException("Non Conditional Revision Aware XPath cannot be NULL!");
+        }
+        if (relativeXPath.isAbsolute()) {
+            throw new IllegalArgumentException("Revision Aware XPath MUST be relative i.e. MUST contains ../, "
+                    + "for non relative Revision Aware XPath use findDataSchemaNode method!");
+        }
+        if (leafrefSchemaPath == null) {
+            throw new IllegalArgumentException("Schema Path reference for Leafref cannot be NULL!");
+        }
 
-        if ((module != null) && (relativeXPath != null) && !relativeXPath.isAbsolute() && (leafrefSchemaPath != null)) {
-            final String strXPath = relativeXPath.toString();
-            if (strXPath != null) {
-                final String[] xpaths = strXPath.split("/");
-
-                if (xpaths != null) {
-                    int colCount = 0;
-                    while (xpaths[colCount].contains("..")) {
-                        ++colCount;
+        final String strXPath = relativeXPath.toString();
+        if (strXPath != null) {
+            final String[] xpaths = strXPath.split("/");
+            if (xpaths != null) {
+                int colCount = 0;
+                while (xpaths[colCount].contains("..")) {
+                    ++colCount;
+                }
+                final List<QName> path = leafrefSchemaPath.getPath();
+                if (path != null) {
+                    int lenght = path.size() - colCount - 1;
+                    for (int i = 0; i < lenght; ++i) {
+                        absolutePath.add(path.get(i));
                     }
-                    final List<QName> path = leafrefSchemaPath.getPath();
-                    if (path != null) {
-                        int lenght = path.size() - colCount - 1;
-                        for (int i = 0; i < lenght; ++i) {
-                            absolutePath.add(path.get(i));
-                        }
-                        for (int i = colCount; i < xpaths.length; ++i) {
-                            absolutePath.add(stringPathPartToQName(context, module, xpaths[i]));
-                        }
+                    for (int i = colCount; i < xpaths.length; ++i) {
+                        absolutePath.add(stringPathPartToQName(context, module, xpaths[i]));
                     }
                 }
             }

©2013 OpenDaylight, A Linux Foundation Collaborative Project. All Rights Reserved.
OpenDaylight is a registered trademark of The OpenDaylight Project, Inc.
Linux Foundation and OpenDaylight are registered trademarks of the Linux Foundation.
Linux is a registered trademark of Linus Torvalds.