Merge "Cache Sync for HostTracker"
authorAlessandro Boch <aboch@cisco.com>
Wed, 3 Jul 2013 17:21:19 +0000 (17:21 +0000)
committerGerrit Code Review <gerrit@opendaylight.org>
Wed, 3 Jul 2013 17:21:19 +0000 (17:21 +0000)
84 files changed:
opendaylight/forwardingrulesmanager/api/src/main/java/org/opendaylight/controller/forwardingrulesmanager/FlowEntryInstall.java
opendaylight/forwardingrulesmanager/implementation/src/main/java/org/opendaylight/controller/forwardingrulesmanager/internal/Activator.java
opendaylight/forwardingrulesmanager/implementation/src/main/java/org/opendaylight/controller/forwardingrulesmanager/internal/ForwardingRulesManagerImpl.java
opendaylight/northbound/integrationtest/src/test/java/org/opendaylight/controller/northbound/integrationtest/NorthboundIT.java
opendaylight/sal/api/src/main/java/org/opendaylight/controller/sal/core/Latency.java
opendaylight/sal/yang-prototype/code-generator/binding-generator-impl/src/main/java/org/opendaylight/controller/sal/binding/generator/impl/BindingGeneratorImpl.java
opendaylight/sal/yang-prototype/code-generator/binding-generator-impl/src/test/java/org/opendaylight/controller/sal/binding/generator/impl/ChoiceCaseGenTypesTest.java [new file with mode: 0644]
opendaylight/sal/yang-prototype/code-generator/binding-generator-impl/src/test/resources/binary-type-test-models/binary-type-test.yang
opendaylight/sal/yang-prototype/code-generator/binding-generator-impl/src/test/resources/choice-case-type-test-models/augment-monitoring@2013-07-01.yang [new file with mode: 0644]
opendaylight/sal/yang-prototype/code-generator/binding-generator-impl/src/test/resources/choice-case-type-test-models/ietf-inet-types@2010-09-24.yang [new file with mode: 0644]
opendaylight/sal/yang-prototype/code-generator/binding-generator-impl/src/test/resources/choice-case-type-test-models/ietf-netconf-monitoring@2010-10-04.yang [new file with mode: 0644]
opendaylight/sal/yang-prototype/code-generator/binding-generator-impl/src/test/resources/choice-case-type-test-models/ietf-yang-types@2010-09-24.yang [new file with mode: 0644]
opendaylight/sal/yang-prototype/code-generator/binding-generator-util/src/main/java/org/opendaylight/controller/binding/generator/util/generated/type/builder/AbstractTypeMemberBuilder.java
opendaylight/sal/yang-prototype/code-generator/binding-java-api-generator/src/main/java/org/opendaylight/controller/sal/java/api/generator/ClassCodeGenerator.java
opendaylight/sal/yang-prototype/code-generator/binding-java-api-generator/src/main/java/org/opendaylight/controller/sal/java/api/generator/EnumGenerator.java
opendaylight/sal/yang-prototype/code-generator/binding-java-api-generator/src/main/java/org/opendaylight/controller/sal/java/api/generator/GeneratorJavaFile.java
opendaylight/sal/yang-prototype/code-generator/binding-java-api-generator/src/main/java/org/opendaylight/controller/sal/java/api/generator/GeneratorUtil.java
opendaylight/sal/yang-prototype/code-generator/binding-java-api-generator/src/main/java/org/opendaylight/controller/sal/java/api/generator/InterfaceGenerator.java
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/controller-network.yang
opendaylight/sal/yang-prototype/code-generator/samples/maven-code-gen-sample/src/main/yang/controller-openflow-ipv6.yang
opendaylight/sal/yang-prototype/code-generator/samples/maven-code-gen-sample/src/main/yang/controller-openflow.yang
opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/main/java/org/opendaylight/controller/yang/parser/builder/api/AbstractDataNodeContainerBuilder.java
opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/main/java/org/opendaylight/controller/yang/parser/builder/api/AbstractSchemaNodeBuilder.java
opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/main/java/org/opendaylight/controller/yang/parser/builder/api/AbstractTypeAwareBuilder.java
opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/main/java/org/opendaylight/controller/yang/parser/builder/api/Builder.java
opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/main/java/org/opendaylight/controller/yang/parser/builder/api/GroupingBuilder.java
opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/main/java/org/opendaylight/controller/yang/parser/builder/api/TypeDefinitionAwareBuilder.java [deleted file]
opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/main/java/org/opendaylight/controller/yang/parser/builder/impl/AnyXmlBuilder.java
opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/main/java/org/opendaylight/controller/yang/parser/builder/impl/AugmentationSchemaBuilderImpl.java
opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/main/java/org/opendaylight/controller/yang/parser/builder/impl/ChoiceBuilder.java
opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/main/java/org/opendaylight/controller/yang/parser/builder/impl/ChoiceCaseBuilder.java
opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/main/java/org/opendaylight/controller/yang/parser/builder/impl/ConstraintsBuilder.java
opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/main/java/org/opendaylight/controller/yang/parser/builder/impl/ContainerSchemaNodeBuilder.java
opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/main/java/org/opendaylight/controller/yang/parser/builder/impl/DeviationBuilder.java
opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/main/java/org/opendaylight/controller/yang/parser/builder/impl/ExtensionBuilder.java
opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/main/java/org/opendaylight/controller/yang/parser/builder/impl/FeatureBuilder.java
opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/main/java/org/opendaylight/controller/yang/parser/builder/impl/GroupingBuilderImpl.java
opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/main/java/org/opendaylight/controller/yang/parser/builder/impl/IdentitySchemaNodeBuilder.java
opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/main/java/org/opendaylight/controller/yang/parser/builder/impl/IdentityrefTypeBuilder.java
opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/main/java/org/opendaylight/controller/yang/parser/builder/impl/LeafListSchemaNodeBuilder.java
opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/main/java/org/opendaylight/controller/yang/parser/builder/impl/LeafSchemaNodeBuilder.java
opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/main/java/org/opendaylight/controller/yang/parser/builder/impl/ListSchemaNodeBuilder.java
opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/main/java/org/opendaylight/controller/yang/parser/builder/impl/ModuleBuilder.java
opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/main/java/org/opendaylight/controller/yang/parser/builder/impl/NotificationBuilder.java
opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/main/java/org/opendaylight/controller/yang/parser/builder/impl/RpcDefinitionBuilder.java
opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/main/java/org/opendaylight/controller/yang/parser/builder/impl/TypeDefinitionBuilderImpl.java
opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/main/java/org/opendaylight/controller/yang/parser/builder/impl/UnionTypeBuilder.java
opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/main/java/org/opendaylight/controller/yang/parser/builder/impl/UnknownSchemaNodeBuilder.java
opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/main/java/org/opendaylight/controller/yang/parser/builder/impl/UsesNodeBuilderImpl.java
opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/main/java/org/opendaylight/controller/yang/parser/impl/YangParserImpl.java
opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/main/java/org/opendaylight/controller/yang/parser/impl/YangParserListenerImpl.java
opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/main/java/org/opendaylight/controller/yang/parser/util/Comparators.java [new file with mode: 0644]
opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/main/java/org/opendaylight/controller/yang/parser/util/ModuleDependencySort.java
opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/main/java/org/opendaylight/controller/yang/parser/util/ParserUtils.java
opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/main/java/org/opendaylight/controller/yang/parser/util/RefineHolder.java
opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/main/java/org/opendaylight/controller/yang/parser/util/YangModelBuilderUtil.java
opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/test/java/org/opendaylight/controller/yang/parser/impl/YangParserNegativeTest.java
opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/test/java/org/opendaylight/controller/yang/parser/impl/YangParserTest.java
opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/test/java/org/opendaylight/controller/yang/parser/util/ModuleDependencySortTest.java
opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/test/resources/model/testfile1.yang
opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/test/resources/model/testfile3.yang
opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/test/resources/negative-scenario/duplicity/container-leaf.yang [new file with mode: 0644]
opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/test/resources/negative-scenario/duplicity/container-list.yang [new file with mode: 0644]
opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/test/resources/negative-scenario/duplicity/container.yang [new file with mode: 0644]
opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/test/resources/negative-scenario/duplicity/identity.yang [new file with mode: 0644]
opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/test/resources/negative-scenario/duplicity/typedef.yang [new file with mode: 0644]
opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/test/resources/negative-scenario/testfile0.yang
opendaylight/sal/yang-prototype/yang/yang-binding/src/main/java/org/opendaylight/controller/yang/binding/InstanceIdentifier.java [new file with mode: 0644]
opendaylight/sal/yang-prototype/yang/yang-model-api/src/main/java/org/opendaylight/controller/yang/model/api/AugmentationSchema.java
opendaylight/sal/yang-prototype/yang/yang-model-api/src/main/java/org/opendaylight/controller/yang/model/api/DataNodeContainer.java
opendaylight/sal/yang-prototype/yang/yang-model-api/src/main/java/org/opendaylight/controller/yang/model/api/GroupingDefinition.java
opendaylight/sal/yang-prototype/yang/yang-model-api/src/main/java/org/opendaylight/controller/yang/model/api/Module.java
opendaylight/sal/yang-prototype/yang/yang-model-api/src/main/java/org/opendaylight/controller/yang/model/api/UsesNode.java
opendaylight/samples/simpleforwarding/pom.xml
opendaylight/samples/simpleforwarding/src/main/java/org/opendaylight/controller/samples/simpleforwarding/HostNodePair.java [moved from opendaylight/samples/simpleforwarding/src/main/java/org/opendaylight/controller/samples/simpleforwarding/internal/HostNodePair.java with 97% similarity]
opendaylight/samples/simpleforwarding/src/main/java/org/opendaylight/controller/samples/simpleforwarding/internal/SimpleForwardingImpl.java
opendaylight/samples/simpleforwarding/src/test/java/org/opendaylight/controller/samples/simpleforwarding/internal/HostSwitchTest.java
opendaylight/switchmanager/api/src/main/java/org/opendaylight/controller/switchmanager/SpanConfig.java
opendaylight/switchmanager/api/src/main/java/org/opendaylight/controller/switchmanager/SubnetConfig.java
opendaylight/switchmanager/api/src/main/java/org/opendaylight/controller/switchmanager/SwitchConfig.java
opendaylight/switchmanager/implementation/src/main/java/org/opendaylight/controller/switchmanager/internal/SwitchManagerImpl.java
opendaylight/web/root/src/main/resources/WEB-INF/jsp/main.jsp
opendaylight/web/root/src/main/resources/css/one.less

index ebb5a7bb2457125d8c3c27ea795a820377354eef..ee2113db8287066f7337a147ade4e7d9048bf2ea 100644 (file)
@@ -34,7 +34,7 @@ public class FlowEntryInstall implements Serializable {
     public FlowEntryInstall(FlowEntry original, ContainerFlow cFlow) {
         this.original = original;
         this.cFlow = cFlow;
-        this.install = (cFlow == null) ? original.clone() : original.mergeWith(cFlow);
+        this.install = (cFlow == null) ? original.clone() : original.clone().mergeWith(cFlow);
         deletePending = false;
         requestId = 0;
     }
index 2b161e9be7018365f6fee3ca7dcdb989e6257da4..f6fc0012ad4219f368373cb10284e1c401e96a0f 100644 (file)
@@ -22,7 +22,6 @@ import org.opendaylight.controller.sal.core.IContainer;
 import org.opendaylight.controller.sal.core.IContainerListener;
 import org.opendaylight.controller.sal.flowprogrammer.IFlowProgrammerListener;
 import org.opendaylight.controller.sal.flowprogrammer.IFlowProgrammerService;
-import org.opendaylight.controller.sal.utils.GlobalConstants;
 import org.opendaylight.controller.switchmanager.IInventoryListener;
 import org.opendaylight.controller.switchmanager.ISwitchManager;
 import org.opendaylight.controller.switchmanager.ISwitchManagerAware;
@@ -41,6 +40,7 @@ public class Activator extends ComponentActivatorAbstractBase {
      * are done by the ComponentActivatorAbstractBase.
      *
      */
+    @Override
     public void init() {
 
     }
@@ -50,6 +50,7 @@ public class Activator extends ComponentActivatorAbstractBase {
      * ComponentActivatorAbstractBase
      *
      */
+    @Override
     public void destroy() {
 
     }
@@ -63,6 +64,7 @@ public class Activator extends ComponentActivatorAbstractBase {
      *         instantiated in order to get an fully working implementation
      *         Object
      */
+    @Override
     public Object[] getImplementations() {
         Object[] res = { ForwardingRulesManagerImpl.class };
         return res;
@@ -83,26 +85,20 @@ public class Activator extends ComponentActivatorAbstractBase {
      *            per-container different behavior if needed, usually should not
      *            be the case though.
      */
+    @Override
     public void configureInstance(Component c, Object imp, String containerName) {
         if (imp.equals(ForwardingRulesManagerImpl.class)) {
             String interfaces[] = null;
             Dictionary<String, Set<String>> props = new Hashtable<String, Set<String>>();
             Set<String> propSet = new HashSet<String>();
-            propSet.add("staticFlows");
+            propSet.add("frm.flowsSaveEvent");
             props.put("cachenames", propSet);
 
             // export the service
-            if (containerName.equals(GlobalConstants.DEFAULT.toString())) {
-                interfaces = new String[] { IContainerListener.class.getName(), ISwitchManagerAware.class.getName(),
-                        IForwardingRulesManager.class.getName(), IInventoryListener.class.getName(),
-                        ICacheUpdateAware.class.getName(), IConfigurationContainerAware.class.getName(),
-                        IFlowProgrammerListener.class.getName() };
-            } else {
-                interfaces = new String[] { ISwitchManagerAware.class.getName(),
-                        IForwardingRulesManager.class.getName(), IInventoryListener.class.getName(),
-                        ICacheUpdateAware.class.getName(), IConfigurationContainerAware.class.getName(),
-                        IFlowProgrammerListener.class.getName() };
-            }
+            interfaces = new String[] { IContainerListener.class.getName(), ISwitchManagerAware.class.getName(),
+                    IForwardingRulesManager.class.getName(), IInventoryListener.class.getName(),
+                    ICacheUpdateAware.class.getName(), IConfigurationContainerAware.class.getName(),
+                    IFlowProgrammerListener.class.getName() };
 
             c.setInterface(interfaces, props);
 
index d4588d620b6a7f0900dc50df39aab3ac43efa215..7fae181ba632c0aa51a26d96dccd93698d313eab 100644 (file)
@@ -929,16 +929,21 @@ public class ForwardingRulesManagerImpl implements IForwardingRulesManager, Port
      * on the network node
      */
     private void updateFlowsContainerFlow() {
+        Set<FlowEntry> toReInstall = new HashSet<FlowEntry>();
+        // First remove all installed entries
         for (ConcurrentMap.Entry<FlowEntryInstall, FlowEntryInstall> entry : installedSwView.entrySet()) {
             FlowEntryInstall current = entry.getValue();
-            FlowEntry reInstall = current.getOriginal();
+            // Store the original entry
+            toReInstall.add(current.getOriginal());
             // Remove the old couples. No validity checks to be run, use the
             // internal remove
             this.removeEntryInternal(current, false);
-
+        }
+        // Then reinstall the original entries
+        for (FlowEntry entry : toReInstall) {
             // Reinstall the original flow entries, via the regular path: new
             // cFlow merge + validations
-            this.installFlowEntry(reInstall);
+            this.installFlowEntry(entry);
         }
     }
 
@@ -1131,7 +1136,7 @@ public class ForwardingRulesManagerImpl implements IForwardingRulesManager, Port
             return;
         }
 
-        log.debug("FRM allocateCaches for Container {}", container);
+        log.debug("Allocating caches for Container {}", container.getName());
 
         try {
             clusterContainerService.createCache("frm.originalSwView",
@@ -1165,9 +1170,9 @@ public class ForwardingRulesManagerImpl implements IForwardingRulesManager, Port
                     EnumSet.of(IClusterServices.cacheMode.NON_TRANSACTIONAL));
 
         } catch (CacheConfigException cce) {
-            log.error("FRM CacheConfigException");
+            log.error("CacheConfigException");
         } catch (CacheExistException cce) {
-            log.error("FRM CacheExistException");
+            log.error("CacheExistException");
         }
     }
 
@@ -1180,76 +1185,76 @@ public class ForwardingRulesManagerImpl implements IForwardingRulesManager, Port
             return;
         }
 
-        log.debug("FRM retrieveCaches for Container {}", container);
+        log.debug("Retrieving Caches for Container {}", container.getName());
 
         map = clusterContainerService.getCache("frm.originalSwView");
         if (map != null) {
             originalSwView = (ConcurrentMap<FlowEntry, FlowEntry>) map;
         } else {
-            log.error("FRM Cache frm.originalSwView allocation failed for Container {}", container.getName());
+            log.error("Retrieval of frm.originalSwView cache failed for Container {}", container.getName());
         }
 
         map = clusterContainerService.getCache("frm.installedSwView");
         if (map != null) {
             installedSwView = (ConcurrentMap<FlowEntryInstall, FlowEntryInstall>) map;
         } else {
-            log.error("FRM Cache frm.installedSwView allocation failed for Container {}", container.getName());
+            log.error("Retrieval of frm.installedSwView cache failed for Container {}", container.getName());
         }
 
         map = clusterContainerService.getCache("frm.nodeFlows");
         if (map != null) {
             nodeFlows = (ConcurrentMap<Node, List<FlowEntryInstall>>) map;
         } else {
-            log.error("FRM Cache frm.nodeFlows allocation failed for Container {}", container.getName());
+            log.error("Retrieval of cache failed for Container {}", container.getName());
         }
 
         map = clusterContainerService.getCache("frm.groupFlows");
         if (map != null) {
             groupFlows = (ConcurrentMap<String, List<FlowEntryInstall>>) map;
         } else {
-            log.error("FRM Cache frm.groupFlows allocation failed for Container {}", container.getName());
+            log.error("Retrieval of frm.groupFlows cache failed for Container {}", container.getName());
         }
 
         map = clusterContainerService.getCache("frm.staticFlows");
         if (map != null) {
             staticFlows = (ConcurrentMap<Integer, FlowConfig>) map;
         } else {
-            log.error("FRM Cache frm.staticFlows allocation failed for Container {}", container.getName());
+            log.error("Retrieval of frm.staticFlows cache failed for Container {}", container.getName());
         }
 
         map = clusterContainerService.getCache("frm.flowsSaveEvent");
         if (map != null) {
             flowsSaveEvent = (ConcurrentMap<Long, String>) map;
         } else {
-            log.error("FRM Cache frm.flowsSaveEvent allocation failed for Container {}", container.getName());
+            log.error("Retrieval of frm.flowsSaveEvent cache failed for Container {}", container.getName());
         }
 
         map = clusterContainerService.getCache("frm.staticFlowsOrdinal");
         if (map != null) {
             staticFlowsOrdinal = (ConcurrentMap<Integer, Integer>) map;
         } else {
-            log.error("FRM Cache frm.staticFlowsOrdinal allocation failed for Container {}", container.getName());
+            log.error("Retrieval of frm.staticFlowsOrdinal cache failed for Container {}", container.getName());
         }
 
         map = clusterContainerService.getCache("frm.portGroupConfigs");
         if (map != null) {
             portGroupConfigs = (ConcurrentMap<String, PortGroupConfig>) map;
         } else {
-            log.error("FRM Cache frm.portGroupConfigs allocation failed for Container {}", container.getName());
+            log.error("Retrieval of frm.portGroupConfigs cache failed for Container {}", container.getName());
         }
 
         map = clusterContainerService.getCache("frm.portGroupData");
         if (map != null) {
             portGroupData = (ConcurrentMap<PortGroupConfig, Map<Node, PortGroup>>) map;
         } else {
-            log.error("FRM Cache frm.portGroupData allocation failed for Container {}", container.getName());
+            log.error("Retrieval of frm.portGroupData allocation failed for Container {}", container.getName());
         }
 
         map = clusterContainerService.getCache("frm.TSPolicies");
         if (map != null) {
             TSPolicies = (ConcurrentMap<String, Object>) map;
         } else {
-            log.error("FRM Cache frm.TSPolicies allocation failed for Container {}", container.getName());
+            log.error("Retrieval of frm.TSPolicies cache failed for Container {}", container.getName());
         }
 
     }
@@ -1444,7 +1449,7 @@ public class ForwardingRulesManagerImpl implements IForwardingRulesManager, Port
         }
 
         // Program the network node
-        Status status = this.removeEntry(config.getFlowEntry(), false);
+        Status status = this.uninstallFlowEntry(config.getFlowEntry());
 
         // Update configuration database if programming was successful
         if (status.isSuccess()) {
@@ -1543,7 +1548,7 @@ public class ForwardingRulesManagerImpl implements IForwardingRulesManager, Port
         // If flow is installed, program the network node
         status = new Status(StatusCode.SUCCESS, "Saved in config");
         if (oldFlowConfig.installInHw()) {
-            status = this.modifyEntry(oldFlowConfig.getFlowEntry(), newFlowConfig.getFlowEntry(), false);
+            status = this.modifyFlowEntry(oldFlowConfig.getFlowEntry(), newFlowConfig.getFlowEntry());
         }
 
         // Update configuration database if programming was successful
@@ -1588,16 +1593,14 @@ public class ForwardingRulesManagerImpl implements IForwardingRulesManager, Port
         }
         if (target != null) {
             // Program the network node
-            Status status;
-            if (target.installInHw()) {
-                status = this.removeEntry(target.getFlowEntry(), false);
-            } else {
-                status = this.addEntry(target.getFlowEntry(), false);
+            Status status = (target.installInHw()) ? this.uninstallFlowEntry(target.getFlowEntry()) : this
+                    .installFlowEntry(target.getFlowEntry());
+            if (status.isSuccess()) {
+                // Update Configuration database
+                target.setStatus(SUCCESS);
+                target.toggleInstallation();
+                staticFlows.put(key, target);
             }
-            // Update Configuration database
-            target.setStatus(SUCCESS);
-            target.toggleInstallation();
-            staticFlows.put(key, target);
             return status;
         }
 
@@ -2219,12 +2222,19 @@ public class ForwardingRulesManagerImpl implements IForwardingRulesManager, Port
 
     @Override
     public void tagUpdated(String containerName, Node n, short oldTag, short newTag, UpdateType t) {
-
+        if (!container.getName().equals(containerName)) {
+            return;
+        }
     }
 
     @Override
-    public void containerFlowUpdated(String containerName, ContainerFlow previousFlow, ContainerFlow currentFlow,
+    public void containerFlowUpdated(String containerName, ContainerFlow previous, ContainerFlow current,
             UpdateType t) {
+        if (!container.getName().equals(containerName)) {
+            return;
+        }
+        log.trace("Container {}: Updating installed flows because of container flow change: {} {}",
+                container.getName(), t, current);
         /*
          * Whether it is an addition or removal, we have to recompute the merged
          * flows entries taking into account all the current container flows
@@ -2235,11 +2245,17 @@ public class ForwardingRulesManagerImpl implements IForwardingRulesManager, Port
 
     @Override
     public void nodeConnectorUpdated(String containerName, NodeConnector p, UpdateType t) {
-        // No action
+        if (!container.getName().equals(containerName)) {
+            return;
+        }
     }
 
     @Override
     public void containerModeUpdated(UpdateType update) {
+        // Only default container instance reacts on this event
+        if (!container.getName().equals(GlobalConstants.DEFAULT.toString())) {
+            return;
+        }
         switch (update) {
         case ADDED:
             this.inContainerMode = true;
index 103a515607a49b043475ca59925c545d6d439586..797bca798f7d811c491e318bc4fddda1d9710899 100644 (file)
@@ -24,7 +24,11 @@ import java.io.OutputStreamWriter;
 import java.net.HttpURLConnection;
 import java.net.URL;
 import java.nio.charset.Charset;
+import java.util.ArrayList;
 import java.util.Arrays;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
 
 import org.apache.commons.codec.binary.Base64;
 
@@ -34,10 +38,17 @@ import org.codehaus.jettison.json.JSONObject;
 import org.codehaus.jettison.json.JSONTokener;
 
 import org.opendaylight.controller.hosttracker.IfIptoHost;
+import org.opendaylight.controller.sal.core.Bandwidth;
 import org.opendaylight.controller.sal.core.ConstructionException;
+import org.opendaylight.controller.sal.core.Edge;
+import org.opendaylight.controller.sal.core.Latency;
 import org.opendaylight.controller.sal.core.Node;
 import org.opendaylight.controller.sal.core.NodeConnector;
+import org.opendaylight.controller.sal.core.Property;
+import org.opendaylight.controller.sal.core.State;
 import org.opendaylight.controller.sal.core.UpdateType;
+import org.opendaylight.controller.sal.topology.IListenTopoUpdates;
+import org.opendaylight.controller.sal.topology.TopoEdgeUpdate;
 import org.opendaylight.controller.switchmanager.IInventoryListener;
 import org.opendaylight.controller.usermanager.IUserManager;
 
@@ -49,6 +60,9 @@ public class NorthboundIT {
     private BundleContext bc;
     private IUserManager users = null;
     private IInventoryListener invtoryListener = null;
+    private IListenTopoUpdates topoUpdates = null;
+
+    private Boolean debugMsg = false;
 
     private String stateToString(int state) {
         switch (state) {
@@ -73,20 +87,17 @@ public class NorthboundIT {
         for (int i = 0; i < b.length; i++) {
             int state = b[i].getState();
             if (state != Bundle.ACTIVE && state != Bundle.RESOLVED) {
-                log.debug("Bundle:" + b[i].getSymbolicName() + " state:"
-                        + stateToString(state));
+                log.debug("Bundle:" + b[i].getSymbolicName() + " state:" + stateToString(state));
                 debugit = true;
             }
         }
         if (debugit) {
-            log.debug("Do some debugging because some bundle is "
-                    + "unresolved");
+            log.debug("Do some debugging because some bundle is " + "unresolved");
         }
         // Assert if true, if false we are good to go!
         assertFalse(debugit);
 
-        ServiceReference r = bc.getServiceReference(IUserManager.class
-                .getName());
+        ServiceReference r = bc.getServiceReference(IUserManager.class.getName());
         if (r != null) {
             this.users = (IUserManager) bc.getService(r);
         }
@@ -101,6 +112,14 @@ public class NorthboundIT {
         // If inventoryListener is null, cannot run hosttracker tests.
         assertNotNull(this.invtoryListener);
 
+        r = bc.getServiceReference(IListenTopoUpdates.class.getName());
+        if (r != null) {
+            this.topoUpdates = (IListenTopoUpdates) bc.getService(r);
+        }
+
+        // If topologyManager is null, cannot run topology North tests.
+        assertNotNull(this.topoUpdates);
+
     }
 
     // static variable to pass response code from getJsonResult()
@@ -118,6 +137,12 @@ public class NorthboundIT {
         // initialize response code to indicate error
         httpResponseCode = 400;
 
+        if (debugMsg) {
+            System.out.println("HTTP method: " + method + " url: " + restUrl.toString());
+            if (body != null)
+                System.out.println("body: " + body);
+        }
+
         try {
             URL url = new URL(restUrl);
             this.users.getAuthorizationList();
@@ -126,18 +151,15 @@ public class NorthboundIT {
             byte[] authEncBytes = Base64.encodeBase64(authString.getBytes());
             String authStringEnc = new String(authEncBytes);
 
-            HttpURLConnection connection = (HttpURLConnection) url
-                    .openConnection();
+            HttpURLConnection connection = (HttpURLConnection) url.openConnection();
             connection.setRequestMethod(method);
-            connection.setRequestProperty("Authorization", "Basic "
-                    + authStringEnc);
+            connection.setRequestProperty("Authorization", "Basic " + authStringEnc);
             connection.setRequestProperty("Content-Type", "application/json");
             connection.setRequestProperty("Accept", "application/json");
 
             if (body != null) {
                 connection.setDoOutput(true);
-                OutputStreamWriter wr = new OutputStreamWriter(
-                        connection.getOutputStream());
+                OutputStreamWriter wr = new OutputStreamWriter(connection.getOutputStream());
                 wr.write(body);
                 wr.flush();
             }
@@ -149,9 +171,13 @@ public class NorthboundIT {
             if (httpResponseCode > 299)
                 return httpResponseCode.toString();
 
+            if (debugMsg) {
+                System.out.println("HTTP response code: " + connection.getResponseCode());
+                System.out.println("HTTP response message: " + connection.getResponseMessage());
+            }
+
             InputStream is = connection.getInputStream();
-            BufferedReader rd = new BufferedReader(new InputStreamReader(is,
-                    Charset.forName("UTF-8")));
+            BufferedReader rd = new BufferedReader(new InputStreamReader(is, Charset.forName("UTF-8")));
             StringBuilder sb = new StringBuilder();
             int cp;
             while ((cp = rd.read()) != -1) {
@@ -165,10 +191,9 @@ public class NorthboundIT {
         }
     }
 
-    private void testNodeProperties(JSONObject node, Integer nodeId,
-            String nodeType, Integer timestamp, String timestampName,
-            Integer actionsValue, Integer capabilitiesValue,
-            Integer tablesValue, Integer buffersValue) throws JSONException {
+    private void testNodeProperties(JSONObject node, Integer nodeId, String nodeType, Integer timestamp,
+            String timestampName, Integer actionsValue, Integer capabilitiesValue, Integer tablesValue,
+            Integer buffersValue) throws JSONException {
 
         JSONObject nodeInfo = node.getJSONObject("node");
         Assert.assertEquals(nodeId, (Integer) nodeInfo.getInt("@id"));
@@ -179,51 +204,39 @@ public class NorthboundIT {
         if (timestamp == null || timestampName == null) {
             Assert.assertFalse(properties.has("timeStamp"));
         } else {
-            Assert.assertEquals(
-                    timestamp,
-                    (Integer) properties.getJSONObject("timeStamp").getInt(
-                            "timestamp"));
-            Assert.assertEquals(
-                    timestampName,
-                    properties.getJSONObject("timeStamp").getString(
-                            "timestampName"));
+            Assert.assertEquals(timestamp, (Integer) properties.getJSONObject("timeStamp").getInt("timestamp"));
+            Assert.assertEquals(timestampName, properties.getJSONObject("timeStamp").getString("timestampName"));
         }
         if (actionsValue == null) {
             Assert.assertFalse(properties.has("actions"));
         } else {
-            Assert.assertEquals(actionsValue, (Integer) properties
-                    .getJSONObject("actions").getInt("actionsValue"));
+            Assert.assertEquals(actionsValue, (Integer) properties.getJSONObject("actions").getInt("actionsValue"));
         }
         if (capabilitiesValue == null) {
             Assert.assertFalse(properties.has("capabilities"));
         } else {
-            Assert.assertEquals(capabilitiesValue, (Integer) properties
-                    .getJSONObject("capabilities").getInt("capabilitiesValue"));
+            Assert.assertEquals(capabilitiesValue,
+                    (Integer) properties.getJSONObject("capabilities").getInt("capabilitiesValue"));
         }
         if (tablesValue == null) {
             Assert.assertFalse(properties.has("tables"));
         } else {
-            Assert.assertEquals(tablesValue, (Integer) properties
-                    .getJSONObject("tables").getInt("tablesValue"));
+            Assert.assertEquals(tablesValue, (Integer) properties.getJSONObject("tables").getInt("tablesValue"));
         }
         if (buffersValue == null) {
             Assert.assertFalse(properties.has("buffers"));
         } else {
-            Assert.assertEquals(buffersValue, (Integer) properties
-                    .getJSONObject("buffers").getInt("buffersValue"));
+            Assert.assertEquals(buffersValue, (Integer) properties.getJSONObject("buffers").getInt("buffersValue"));
         }
     }
 
-    private void testNodeConnectorProperties(
-            JSONObject nodeConnectorProperties, Integer ncId, String ncType,
-            Integer nodeId, String nodeType, Integer state,
-            Integer capabilities, Integer bandwidth) throws JSONException {
+    private void testNodeConnectorProperties(JSONObject nodeConnectorProperties, Integer ncId, String ncType,
+            Integer nodeId, String nodeType, Integer state, Integer capabilities, Integer bandwidth)
+            throws JSONException {
 
-        JSONObject nodeConnector = nodeConnectorProperties
-                .getJSONObject("nodeconnector");
+        JSONObject nodeConnector = nodeConnectorProperties.getJSONObject("nodeconnector");
         JSONObject node = nodeConnector.getJSONObject("node");
-        JSONObject properties = nodeConnectorProperties
-                .getJSONObject("properties");
+        JSONObject properties = nodeConnectorProperties.getJSONObject("properties");
 
         Assert.assertEquals(ncId, (Integer) nodeConnector.getInt("@id"));
         Assert.assertEquals(ncType, nodeConnector.getString("@type"));
@@ -232,30 +245,25 @@ public class NorthboundIT {
         if (state == null) {
             Assert.assertFalse(properties.has("state"));
         } else {
-            Assert.assertEquals(
-                    state,
-                    (Integer) properties.getJSONObject("state").getInt(
-                            "stateValue"));
+            Assert.assertEquals(state, (Integer) properties.getJSONObject("state").getInt("stateValue"));
         }
         if (capabilities == null) {
             Assert.assertFalse(properties.has("capabilities"));
         } else {
-            Assert.assertEquals(capabilities, (Integer) properties
-                    .getJSONObject("capabilities").getInt("capabilitiesValue"));
+            Assert.assertEquals(capabilities,
+                    (Integer) properties.getJSONObject("capabilities").getInt("capabilitiesValue"));
         }
         if (bandwidth == null) {
             Assert.assertFalse(properties.has("bandwidth"));
         } else {
-            Assert.assertEquals(
-                    bandwidth,
-                    (Integer) properties.getJSONObject("bandwidth").getInt(
-                            "bandwidthValue"));
+            Assert.assertEquals(bandwidth, (Integer) properties.getJSONObject("bandwidth").getInt("bandwidthValue"));
         }
 
     }
 
     @Test
     public void testSubnetsNorthbound() throws JSONException {
+        System.out.println("Starting Subnets JAXB client.");
         String baseURL = "http://127.0.0.1:8080/controller/nb/v2/subnet/";
 
         String name1 = "testSubnet1";
@@ -274,10 +282,8 @@ public class NorthboundIT {
         Assert.assertEquals(404, httpResponseCode.intValue());
 
         // Test POST subnet1
-        String queryParameter = new QueryParameter("subnetName", name1).add(
-                "subnet", subnet1).getString();
-        result = getJsonResult(baseURL + "default/" + name1 + queryParameter,
-                "POST");
+        String queryParameter = new QueryParameter("subnetName", name1).add("subnet", subnet1).getString();
+        result = getJsonResult(baseURL + "default/" + name1 + queryParameter, "POST");
         Assert.assertEquals(201, httpResponseCode.intValue());
 
         // Test GET subnet1
@@ -289,10 +295,8 @@ public class NorthboundIT {
         Assert.assertEquals(subnet1, json.getString("@subnet"));
 
         // Test POST subnet2
-        queryParameter = new QueryParameter("subnetName", name2).add("subnet",
-                subnet2).getString();
-        result = getJsonResult(baseURL + "default/" + name2 + queryParameter,
-                "POST");
+        queryParameter = new QueryParameter("subnetName", name2).add("subnet", subnet2).getString();
+        result = getJsonResult(baseURL + "default/" + name2 + queryParameter, "POST");
         Assert.assertEquals(201, httpResponseCode.intValue());
 
         // Test GET all subnets in default container
@@ -326,6 +330,7 @@ public class NorthboundIT {
 
     @Test
     public void testStaticRoutingNorthbound() throws JSONException {
+        System.out.println("Starting StaticRouting JAXB client.");
         String baseURL = "http://127.0.0.1:8080/controller/nb/v2/staticroute/";
 
         String name1 = "testRoute1";
@@ -342,16 +347,13 @@ public class NorthboundIT {
         Assert.assertEquals("{}", result);
 
         // Test insert static route
-        String requestBody = "{\"name\":\"" + name1 + "\", \"prefix\":\""
-                + prefix1 + "\", \"nextHop\":\"" + nextHop1 + "\"}";
-        result = getJsonResult(baseURL + "default/" + name1, "POST",
-                requestBody);
+        String requestBody = "{\"name\":\"" + name1 + "\", \"prefix\":\"" + prefix1 + "\", \"nextHop\":\"" + nextHop1
+                + "\"}";
+        result = getJsonResult(baseURL + "default/" + name1, "POST", requestBody);
         Assert.assertEquals(201, httpResponseCode.intValue());
 
-        requestBody = "{\"name\":\"" + name2 + "\", \"prefix\":\"" + prefix2
-                + "\", \"nextHop\":\"" + nextHop2 + "\"}";
-        result = getJsonResult(baseURL + "default/" + name2, "POST",
-                requestBody);
+        requestBody = "{\"name\":\"" + name2 + "\", \"prefix\":\"" + prefix2 + "\", \"nextHop\":\"" + nextHop2 + "\"}";
+        result = getJsonResult(baseURL + "default/" + name2, "POST", requestBody);
         Assert.assertEquals(201, httpResponseCode.intValue());
 
         // Test Get all static routes
@@ -406,6 +408,7 @@ public class NorthboundIT {
 
     @Test
     public void testSwitchManager() throws JSONException {
+        System.out.println("Starting SwitchManager JAXB client.");
         String baseURL = "http://127.0.0.1:8080/controller/nb/v2/switch/default/";
 
         // define Node/NodeConnector attributes for test
@@ -436,22 +439,19 @@ public class NorthboundIT {
         // Test for first node
         JSONObject node = getJsonInstance(json, "nodeProperties", nodeId_1);
         Assert.assertNotNull(node);
-        testNodeProperties(node, nodeId_1, nodeType, timestamp_1,
-                timestampName_1, actionsValue_1, capabilitiesValue_1,
+        testNodeProperties(node, nodeId_1, nodeType, timestamp_1, timestampName_1, actionsValue_1, capabilitiesValue_1,
                 tablesValue_1, buffersValue_1);
 
         // Test 2nd node, properties of 2nd node same as first node
         node = getJsonInstance(json, "nodeProperties", nodeId_2);
         Assert.assertNotNull(node);
-        testNodeProperties(node, nodeId_2, nodeType, timestamp_1,
-                timestampName_1, actionsValue_1, capabilitiesValue_1,
+        testNodeProperties(node, nodeId_2, nodeType, timestamp_1, timestampName_1, actionsValue_1, capabilitiesValue_1,
                 tablesValue_1, buffersValue_1);
 
         // Test 3rd node, properties of 3rd node same as first node
         node = getJsonInstance(json, "nodeProperties", nodeId_3);
         Assert.assertNotNull(node);
-        testNodeProperties(node, nodeId_3, nodeType, timestamp_1,
-                timestampName_1, actionsValue_1, capabilitiesValue_1,
+        testNodeProperties(node, nodeId_3, nodeType, timestamp_1, timestampName_1, actionsValue_1, capabilitiesValue_1,
                 tablesValue_1, buffersValue_1);
 
         // Test GET nodeConnectors of a node
@@ -459,12 +459,10 @@ public class NorthboundIT {
         result = getJsonResult(baseURL + "node/STUB/" + nodeId_1);
         jt = new JSONTokener(result);
         json = new JSONObject(jt);
-        JSONObject nodeConnectorProperties = json
-                .getJSONObject("nodeConnectorProperties");
+        JSONObject nodeConnectorProperties = json.getJSONObject("nodeConnectorProperties");
 
-        testNodeConnectorProperties(nodeConnectorProperties, nodeConnectorId_1,
-                ncType, nodeId_1, nodeType, ncState, ncCapabilities,
-                ncBandwidth);
+        testNodeConnectorProperties(nodeConnectorProperties, nodeConnectorId_1, ncType, nodeId_1, nodeType, ncState,
+                ncCapabilities, ncBandwidth);
 
         // Test second node
         result = getJsonResult(baseURL + "node/STUB/" + nodeId_2);
@@ -472,9 +470,8 @@ public class NorthboundIT {
         json = new JSONObject(jt);
         nodeConnectorProperties = json.getJSONObject("nodeConnectorProperties");
 
-        testNodeConnectorProperties(nodeConnectorProperties, nodeConnectorId_2,
-                ncType, nodeId_2, nodeType, ncState, ncCapabilities,
-                ncBandwidth);
+        testNodeConnectorProperties(nodeConnectorProperties, nodeConnectorId_2, ncType, nodeId_2, nodeType, ncState,
+                ncCapabilities, ncBandwidth);
 
         // Test third node
         result = getJsonResult(baseURL + "node/STUB/" + nodeId_3);
@@ -482,14 +479,12 @@ public class NorthboundIT {
         json = new JSONObject(jt);
 
         nodeConnectorProperties = json.getJSONObject("nodeConnectorProperties");
-        testNodeConnectorProperties(nodeConnectorProperties, nodeConnectorId_3,
-                ncType, nodeId_3, nodeType, ncState, ncCapabilities,
-                ncBandwidth);
+        testNodeConnectorProperties(nodeConnectorProperties, nodeConnectorId_3, ncType, nodeId_3, nodeType, ncState,
+                ncCapabilities, ncBandwidth);
 
         // Test delete node property
         // Delete timestamp property from node1
-        result = getJsonResult(baseURL + "node/STUB/" + nodeId_1
-                + "/property/timeStamp", "DELETE");
+        result = getJsonResult(baseURL + "node/STUB/" + nodeId_1 + "/property/timeStamp", "DELETE");
         Assert.assertEquals(200, httpResponseCode.intValue());
 
         // Check node1
@@ -498,13 +493,11 @@ public class NorthboundIT {
         json = new JSONObject(jt);
         node = getJsonInstance(json, "nodeProperties", nodeId_1);
         Assert.assertNotNull(node);
-        testNodeProperties(node, nodeId_1, nodeType, null, null,
-                actionsValue_1, capabilitiesValue_1, tablesValue_1,
+        testNodeProperties(node, nodeId_1, nodeType, null, null, actionsValue_1, capabilitiesValue_1, tablesValue_1,
                 buffersValue_1);
 
         // Delete actions property from node2
-        result = getJsonResult(baseURL + "node/STUB/" + nodeId_2
-                + "/property/actions", "DELETE");
+        result = getJsonResult(baseURL + "node/STUB/" + nodeId_2 + "/property/actions", "DELETE");
         Assert.assertEquals(200, httpResponseCode.intValue());
 
         // Check node2
@@ -513,17 +506,14 @@ public class NorthboundIT {
         json = new JSONObject(jt);
         node = getJsonInstance(json, "nodeProperties", nodeId_2);
         Assert.assertNotNull(node);
-        testNodeProperties(node, nodeId_2, nodeType, timestamp_1,
-                timestampName_1, null, capabilitiesValue_1, tablesValue_1,
-                buffersValue_1);
+        testNodeProperties(node, nodeId_2, nodeType, timestamp_1, timestampName_1, null, capabilitiesValue_1,
+                tablesValue_1, buffersValue_1);
 
         // Test add property to node
         // Add Tier and Bandwidth property to node1
-        result = getJsonResult(baseURL + "node/STUB/" + nodeId_1
-                + "/property/tier/1001", "PUT");
+        result = getJsonResult(baseURL + "node/STUB/" + nodeId_1 + "/property/tier/1001", "PUT");
         Assert.assertEquals(201, httpResponseCode.intValue());
-        result = getJsonResult(baseURL + "node/STUB/" + nodeId_1
-                + "/property/bandwidth/1002", "PUT");
+        result = getJsonResult(baseURL + "node/STUB/" + nodeId_1 + "/property/bandwidth/1002", "PUT");
         Assert.assertEquals(201, httpResponseCode.intValue());
 
         // Test for first node
@@ -532,15 +522,13 @@ public class NorthboundIT {
         json = new JSONObject(jt);
         node = getJsonInstance(json, "nodeProperties", nodeId_1);
         Assert.assertNotNull(node);
-        Assert.assertEquals(1001, node.getJSONObject("properties")
-                .getJSONObject("tier").getInt("tierValue"));
-        Assert.assertEquals(1002, node.getJSONObject("properties")
-                .getJSONObject("bandwidth").getInt("bandwidthValue"));
+        Assert.assertEquals(1001, node.getJSONObject("properties").getJSONObject("tier").getInt("tierValue"));
+        Assert.assertEquals(1002, node.getJSONObject("properties").getJSONObject("bandwidth").getInt("bandwidthValue"));
 
         // Test delete nodeConnector property
         // Delete state property of nodeconnector1
-        result = getJsonResult(baseURL + "nodeconnector/STUB/" + nodeId_1
-                + "/STUB/" + nodeConnectorId_1 + "/property/state", "DELETE");
+        result = getJsonResult(baseURL + "nodeconnector/STUB/" + nodeId_1 + "/STUB/" + nodeConnectorId_1
+                + "/property/state", "DELETE");
         Assert.assertEquals(200, httpResponseCode.intValue());
 
         result = getJsonResult(baseURL + "node/STUB/" + nodeId_1);
@@ -548,13 +536,12 @@ public class NorthboundIT {
         json = new JSONObject(jt);
         nodeConnectorProperties = json.getJSONObject("nodeConnectorProperties");
 
-        testNodeConnectorProperties(nodeConnectorProperties, nodeConnectorId_1,
-                ncType, nodeId_1, nodeType, null, ncCapabilities, ncBandwidth);
+        testNodeConnectorProperties(nodeConnectorProperties, nodeConnectorId_1, ncType, nodeId_1, nodeType, null,
+                ncCapabilities, ncBandwidth);
 
         // Delete capabilities property of nodeconnector2
-        result = getJsonResult(baseURL + "nodeconnector/STUB/" + nodeId_2
-                + "/STUB/" + nodeConnectorId_2 + "/property/capabilities",
-                "DELETE");
+        result = getJsonResult(baseURL + "nodeconnector/STUB/" + nodeId_2 + "/STUB/" + nodeConnectorId_2
+                + "/property/capabilities", "DELETE");
         Assert.assertEquals(200, httpResponseCode.intValue());
 
         result = getJsonResult(baseURL + "node/STUB/" + nodeId_2);
@@ -562,16 +549,15 @@ public class NorthboundIT {
         json = new JSONObject(jt);
         nodeConnectorProperties = json.getJSONObject("nodeConnectorProperties");
 
-        testNodeConnectorProperties(nodeConnectorProperties, nodeConnectorId_2,
-                ncType, nodeId_2, nodeType, ncState, null, ncBandwidth);
+        testNodeConnectorProperties(nodeConnectorProperties, nodeConnectorId_2, ncType, nodeId_2, nodeType, ncState,
+                null, ncBandwidth);
 
         // Test PUT nodeConnector property
         int newBandwidth = 1001;
 
         // Add Name/Bandwidth property to nodeConnector1
-        result = getJsonResult(baseURL + "nodeconnector/STUB/" + nodeId_1
-                + "/STUB/" + nodeConnectorId_1 + "/property/bandwidth/"
-                + newBandwidth, "PUT");
+        result = getJsonResult(baseURL + "nodeconnector/STUB/" + nodeId_1 + "/STUB/" + nodeConnectorId_1
+                + "/property/bandwidth/" + newBandwidth, "PUT");
         Assert.assertEquals(201, httpResponseCode.intValue());
 
         result = getJsonResult(baseURL + "node/STUB/" + nodeId_1);
@@ -581,18 +567,16 @@ public class NorthboundIT {
 
         // Check for new bandwidth value, state value removed from previous
         // test
-        testNodeConnectorProperties(nodeConnectorProperties, nodeConnectorId_1,
-                ncType, nodeId_1, nodeType, null, ncCapabilities, newBandwidth);
+        testNodeConnectorProperties(nodeConnectorProperties, nodeConnectorId_1, ncType, nodeId_1, nodeType, null,
+                ncCapabilities, newBandwidth);
 
     }
 
     @Test
     public void testStatistics() throws JSONException {
-        String actionTypes[] = { "drop", "loopback", "flood", "floodAll",
-                "controller", "swPath", "hwPath", "output", "setDlSrc",
-                "setDlDst", "setDlType", "setVlanId", "setVlanPcp",
-                "setVlanCfi", "popVlan", "pushVlan", "setNwSrc", "setNwDst",
-                "setNwTos", "setTpSrc", "setTpDst" };
+        String actionTypes[] = { "drop", "loopback", "flood", "floodAll", "controller", "swPath", "hwPath", "output",
+                "setDlSrc", "setDlDst", "setDlType", "setVlanId", "setVlanPcp", "setVlanCfi", "popVlan", "pushVlan",
+                "setNwSrc", "setNwDst", "setNwTos", "setTpSrc", "setTpDst" };
         System.out.println("Starting Statistics JAXB client.");
 
         String baseURL = "http://127.0.0.1:8080/controller/nb/v2/statistics/default/";
@@ -600,12 +584,11 @@ public class NorthboundIT {
         String result = getJsonResult(baseURL + "flowstats");
         JSONTokener jt = new JSONTokener(result);
         JSONObject json = new JSONObject(jt);
-        JSONObject flowStatistics = getJsonInstance(json, "flowStatistics",
-                0xCAFE);
+        JSONObject flowStatistics = getJsonInstance(json, "flowStatistics", 0xCAFE);
         JSONObject node = flowStatistics.getJSONObject("node");
         // test that node was returned properly
         Assert.assertTrue(node.getInt("@id") == 0xCAFE);
-        Assert.assertTrue(node.getString("@type").equals("STUB"));
+        Assert.assertEquals(node.getString("@type"), "STUB");
 
         // test that flow statistics results are correct
         JSONArray flowStats = flowStatistics.getJSONArray("flowStat");
@@ -620,12 +603,11 @@ public class NorthboundIT {
         result = getJsonResult(baseURL + "portstats");
         jt = new JSONTokener(result);
         json = new JSONObject(jt);
-        JSONObject portStatistics = getJsonInstance(json, "portStatistics",
-                0xCAFE);
+        JSONObject portStatistics = getJsonInstance(json, "portStatistics", 0xCAFE);
         JSONObject node2 = portStatistics.getJSONObject("node");
         // test that node was returned properly
         Assert.assertTrue(node2.getInt("@id") == 0xCAFE);
-        Assert.assertTrue(node2.getString("@type").equals("STUB"));
+        Assert.assertEquals(node2.getString("@type"), "STUB");
 
         // test that port statistic results are correct
         JSONObject portStat = portStatistics.getJSONObject("portStat");
@@ -649,7 +631,7 @@ public class NorthboundIT {
         node = json.getJSONObject("node");
         // test that node was returned properly
         Assert.assertTrue(node.getInt("@id") == 0xCAFE);
-        Assert.assertTrue(node.getString("@type").equals("STUB"));
+        Assert.assertEquals(node.getString("@type"), "STUB");
 
         // test that flow statistics results are correct
         flowStats = json.getJSONArray("flowStat");
@@ -664,7 +646,7 @@ public class NorthboundIT {
         node2 = json.getJSONObject("node");
         // test that node was returned properly
         Assert.assertTrue(node2.getInt("@id") == 0xCAFE);
-        Assert.assertTrue(node2.getString("@type").equals("STUB"));
+        Assert.assertEquals(node2.getString("@type"), "STUB");
 
         // test that port statistic results are correct
         portStat = json.getJSONObject("portStat");
@@ -682,8 +664,7 @@ public class NorthboundIT {
         Assert.assertTrue(portStat.getInt("collisionCount") == 4);
     }
 
-    private void testFlowStat(JSONObject flowStat, String actionType)
-            throws JSONException {
+    private void testFlowStat(JSONObject flowStat, String actionType) throws JSONException {
         Assert.assertTrue(flowStat.getInt("tableId") == 1);
         Assert.assertTrue(flowStat.getInt("durationSeconds") == 40);
         Assert.assertTrue(flowStat.getInt("durationNanoseconds") == 400);
@@ -697,8 +678,7 @@ public class NorthboundIT {
         Assert.assertTrue(flow.getInt("hardTimeout") == 2000);
         Assert.assertTrue(flow.getInt("id") == 12345);
 
-        JSONObject match = (flow.getJSONObject("match")
-                .getJSONObject("matchField"));
+        JSONObject match = (flow.getJSONObject("match").getJSONObject("matchField"));
         Assert.assertTrue(match.getString("type").equals("NW_DST"));
         Assert.assertTrue(match.getString("value").equals("1.1.1.1"));
 
@@ -715,8 +695,7 @@ public class NorthboundIT {
         }
 
         if (act.getString("@type").equals("setDlSrc")) {
-            byte srcMatch[] = { (byte) 5, (byte) 4, (byte) 3, (byte) 2,
-                    (byte) 1 };
+            byte srcMatch[] = { (byte) 5, (byte) 4, (byte) 3, (byte) 2, (byte) 1 };
             String src = act.getString("address");
             byte srcBytes[] = new byte[5];
             srcBytes[0] = Byte.parseByte(src.substring(0, 2));
@@ -728,8 +707,7 @@ public class NorthboundIT {
         }
 
         if (act.getString("@type").equals("setDlDst")) {
-            byte dstMatch[] = { (byte) 1, (byte) 2, (byte) 3, (byte) 4,
-                    (byte) 5 };
+            byte dstMatch[] = { (byte) 1, (byte) 2, (byte) 3, (byte) 4, (byte) 5 };
             String dst = act.getString("address");
             byte dstBytes[] = new byte[5];
             dstBytes[0] = Byte.parseByte(dst.substring(0, 2));
@@ -775,6 +753,7 @@ public class NorthboundIT {
 
     @Test
     public void testFlowProgrammer() throws JSONException {
+        System.out.println("Starting FlowProgrammer JAXB client.");
         String baseURL = "http://127.0.0.1:8080/controller/nb/v2/flow/default/";
         // Attempt to get a flow that doesn't exit. Should return 404
         // status.
@@ -792,12 +771,12 @@ public class NorthboundIT {
         Assert.assertTrue(httpResponseCode == 200);
         JSONTokener jt = new JSONTokener(result);
         JSONObject json = new JSONObject(jt);
-        Assert.assertTrue(json.getString("name").equals("test1"));
-        Assert.assertTrue(json.getString("actions").equals("DROP"));
-        Assert.assertTrue(json.getString("installInHw").equals("true"));
+        Assert.assertEquals(json.getString("name"), "test1");
+        Assert.assertEquals(json.getString("actions"), "DROP");
+        Assert.assertEquals(json.getString("installInHw"), "true");
         JSONObject node = json.getJSONObject("node");
-        Assert.assertTrue(node.getString("@type").equals("STUB"));
-        Assert.assertTrue(node.getString("@id").equals("51966"));
+        Assert.assertEquals(node.getString("@type"), "STUB");
+        Assert.assertEquals(node.getString("@id"), "51966");
         // test adding same flow again fails due to repeat name..return 409
         // code
         result = getJsonResult(baseURL + "STUB/51966/test1", "POST", fc);
@@ -844,8 +823,7 @@ public class NorthboundIT {
     // This is specifically written for statistics manager northbound REST
     // interface
     // array_name should be either "flowStatistics" or "portStatistics"
-    private JSONObject getJsonInstance(JSONObject json, String array_name,
-            Integer nodeId) throws JSONException {
+    private JSONObject getJsonInstance(JSONObject json, String array_name, Integer nodeId) throws JSONException {
         JSONObject result = null;
         if (json.get(array_name) instanceof JSONArray) {
             JSONArray json_array = json.getJSONArray(array_name);
@@ -914,29 +892,21 @@ public class NorthboundIT {
         String baseURL = "http://127.0.0.1:8080/controller/nb/v2/host/default";
 
         // test POST method: addHost()
-        String queryParameter = new QueryParameter("dataLayerAddress",
-                dataLayerAddress_1).add("nodeType", nodeType_1)
-                .add("nodeId", nodeId_1.toString())
-                .add("nodeConnectorType", nodeConnectorType_1)
-                .add("nodeConnectorId", nodeConnectorId_1.toString())
-                .add("vlan", vlan_1).getString();
+        String queryParameter = new QueryParameter("dataLayerAddress", dataLayerAddress_1).add("nodeType", nodeType_1)
+                .add("nodeId", nodeId_1.toString()).add("nodeConnectorType", nodeConnectorType_1)
+                .add("nodeConnectorId", nodeConnectorId_1.toString()).add("vlan", vlan_1).getString();
 
-        String result = getJsonResult(baseURL + "/" + networkAddress_1
-                + queryParameter, "POST");
-        Assert.assertTrue(httpResponseCode.intValue() == (Integer) 201);
+        String result = getJsonResult(baseURL + "/" + networkAddress_1 + queryParameter, "POST");
+        Assert.assertTrue(httpResponseCode == 201);
 
         // vlan is not passed through query parameter but should be
         // defaulted to "0"
-        queryParameter = new QueryParameter("dataLayerAddress",
-                dataLayerAddress_2).add("nodeType", nodeType_2)
-                .add("nodeId", nodeId_2.toString())
-                .add("nodeConnectorType", nodeConnectorType_2)
-                .add("nodeConnectorId", nodeConnectorId_2.toString())
-                .getString();
+        queryParameter = new QueryParameter("dataLayerAddress", dataLayerAddress_2).add("nodeType", nodeType_2)
+                .add("nodeId", nodeId_2.toString()).add("nodeConnectorType", nodeConnectorType_2)
+                .add("nodeConnectorId", nodeConnectorId_2.toString()).getString();
 
-        result = getJsonResult(baseURL + "/" + networkAddress_2
-                + queryParameter, "POST");
-        Assert.assertTrue(httpResponseCode.intValue() == (Integer) 201);
+        result = getJsonResult(baseURL + "/" + networkAddress_2 + queryParameter, "POST");
+        Assert.assertTrue(httpResponseCode == 201);
 
         // define variables for decoding returned strings
         String networkAddress;
@@ -945,7 +915,7 @@ public class NorthboundIT {
         // the two hosts should be in inactive host DB
         // test GET method: getInactiveHosts()
         result = getJsonResult(baseURL + "/inactive", "GET");
-        Assert.assertTrue(httpResponseCode.intValue() == (Integer) 200);
+        Assert.assertTrue(httpResponseCode == 200);
 
         JSONTokener jt = new JSONTokener(result);
         JSONObject json = new JSONObject(jt);
@@ -963,27 +933,19 @@ public class NorthboundIT {
 
             networkAddress = host_jo.getString("networkAddress");
             if (networkAddress.equalsIgnoreCase(networkAddress_1)) {
-                Assert.assertTrue(dl_jo.getString("macAddress")
-                        .equalsIgnoreCase(dataLayerAddress_1));
-                Assert.assertTrue(nc_jo.getString("@type").equalsIgnoreCase(
-                        nodeConnectorType_1));
-                Assert.assertTrue(Integer.parseInt(nc_jo.getString("@id")) == nodeConnectorId_1);
-                Assert.assertTrue(node_jo.getString("@type").equalsIgnoreCase(
-                        nodeType_1));
-                Assert.assertTrue(Integer.parseInt(node_jo.getString("@id")) == nodeId_1);
-                Assert.assertTrue(host_jo.getString("vlan").equalsIgnoreCase(
-                        vlan_1));
+                Assert.assertTrue(dl_jo.getString("macAddress").equalsIgnoreCase(dataLayerAddress_1));
+                Assert.assertTrue(nc_jo.getString("@type").equalsIgnoreCase(nodeConnectorType_1));
+                Assert.assertTrue(nc_jo.getInt("@id") == nodeConnectorId_1);
+                Assert.assertTrue(node_jo.getString("@type").equalsIgnoreCase(nodeType_1));
+                Assert.assertTrue(node_jo.getInt("@id") == nodeId_1);
+                Assert.assertTrue(host_jo.getString("vlan").equalsIgnoreCase(vlan_1));
             } else if (networkAddress.equalsIgnoreCase(networkAddress_2)) {
-                Assert.assertTrue(dl_jo.getString("macAddress")
-                        .equalsIgnoreCase(dataLayerAddress_2));
-                Assert.assertTrue(nc_jo.getString("@type").equalsIgnoreCase(
-                        nodeConnectorType_2));
-                Assert.assertTrue(Integer.parseInt(nc_jo.getString("@id")) == nodeConnectorId_2);
-                Assert.assertTrue(node_jo.getString("@type").equalsIgnoreCase(
-                        nodeType_2));
-                Assert.assertTrue(Integer.parseInt(node_jo.getString("@id")) == nodeId_2);
-                Assert.assertTrue(host_jo.getString("vlan").equalsIgnoreCase(
-                        vlan_2));
+                Assert.assertTrue(dl_jo.getString("macAddress").equalsIgnoreCase(dataLayerAddress_2));
+                Assert.assertTrue(nc_jo.getString("@type").equalsIgnoreCase(nodeConnectorType_2));
+                Assert.assertTrue(nc_jo.getInt("@id") == nodeConnectorId_2);
+                Assert.assertTrue(node_jo.getString("@type").equalsIgnoreCase(nodeType_2));
+                Assert.assertTrue(node_jo.getInt("@id") == nodeId_2);
+                Assert.assertTrue(host_jo.getString("vlan").equalsIgnoreCase(vlan_2));
             } else {
                 Assert.assertTrue(false);
             }
@@ -991,7 +953,7 @@ public class NorthboundIT {
 
         // test GET method: getActiveHosts() - no host expected
         result = getJsonResult(baseURL, "GET");
-        Assert.assertTrue(httpResponseCode.intValue() == (Integer) 200);
+        Assert.assertTrue(httpResponseCode == 200);
 
         jt = new JSONTokener(result);
         json = new JSONObject(jt);
@@ -1004,8 +966,7 @@ public class NorthboundIT {
         try {
             nd = new Node(nodeType_1, nodeId_1);
             ndc = new NodeConnector(nodeConnectorType_1, nodeConnectorId_1, nd);
-            this.invtoryListener.notifyNodeConnector(ndc, UpdateType.ADDED,
-                    null);
+            this.invtoryListener.notifyNodeConnector(ndc, UpdateType.ADDED, null);
         } catch (ConstructionException e) {
             ndc = null;
             nd = null;
@@ -1014,7 +975,7 @@ public class NorthboundIT {
         // verify the host shows up in active host DB
 
         result = getJsonResult(baseURL, "GET");
-        Assert.assertTrue(httpResponseCode.intValue() == (Integer) 200);
+        Assert.assertTrue(httpResponseCode == 200);
 
         jt = new JSONTokener(result);
         json = new JSONObject(jt);
@@ -1024,7 +985,7 @@ public class NorthboundIT {
         // test GET method for getHostDetails()
 
         result = getJsonResult(baseURL + "/" + networkAddress_1, "GET");
-        Assert.assertTrue(httpResponseCode.intValue() == (Integer) 200);
+        Assert.assertTrue(httpResponseCode == 200);
 
         jt = new JSONTokener(result);
         json = new JSONObject(jt);
@@ -1035,28 +996,24 @@ public class NorthboundIT {
         nc_jo = json.getJSONObject("nodeConnector");
         node_jo = nc_jo.getJSONObject("node");
 
-        Assert.assertTrue(json.getString("networkAddress").equalsIgnoreCase(
-                networkAddress_1));
-        Assert.assertTrue(dl_jo.getString("macAddress").equalsIgnoreCase(
-                dataLayerAddress_1));
-        Assert.assertTrue(nc_jo.getString("@type").equalsIgnoreCase(
-                nodeConnectorType_1));
+        Assert.assertTrue(json.getString("networkAddress").equalsIgnoreCase(networkAddress_1));
+        Assert.assertTrue(dl_jo.getString("macAddress").equalsIgnoreCase(dataLayerAddress_1));
+        Assert.assertTrue(nc_jo.getString("@type").equalsIgnoreCase(nodeConnectorType_1));
         Assert.assertTrue(Integer.parseInt(nc_jo.getString("@id")) == nodeConnectorId_1);
-        Assert.assertTrue(node_jo.getString("@type").equalsIgnoreCase(
-                nodeType_1));
+        Assert.assertTrue(node_jo.getString("@type").equalsIgnoreCase(nodeType_1));
         Assert.assertTrue(Integer.parseInt(node_jo.getString("@id")) == nodeId_1);
         Assert.assertTrue(json.getString("vlan").equalsIgnoreCase(vlan_1));
 
         // test DELETE method for deleteFlow()
 
         result = getJsonResult(baseURL + "/" + networkAddress_1, "DELETE");
-        Assert.assertTrue(httpResponseCode.intValue() == (Integer) 200);
+        Assert.assertTrue(httpResponseCode == 200);
 
         // verify host_1 removed from active host DB
         // test GET method: getActiveHosts() - no host expected
 
         result = getJsonResult(baseURL, "GET");
-        Assert.assertTrue(httpResponseCode.intValue() == (Integer) 200);
+        Assert.assertTrue(httpResponseCode == 200);
 
         jt = new JSONTokener(result);
         json = new JSONObject(jt);
@@ -1065,8 +1022,7 @@ public class NorthboundIT {
 
     }
 
-    private Boolean hostInJson(JSONObject json, String hostIp)
-            throws JSONException {
+    private Boolean hostInJson(JSONObject json, String hostIp) throws JSONException {
         // input JSONObject may be empty
         if (json.length() == 0) {
             return false;
@@ -1085,19 +1041,202 @@ public class NorthboundIT {
         }
     }
 
+    @Test
+    public void testTopology() throws JSONException, ConstructionException {
+        System.out.println("Starting Topology JAXB client.");
+        String baseURL = "http://127.0.0.1:8080/controller/nb/v2/topology/default";
+
+        // === test GET method for getTopology()
+        short state_1 = State.EDGE_UP, state_2 = State.EDGE_DOWN;
+        long bw_1 = Bandwidth.BW10Gbps, bw_2 = Bandwidth.BW100Mbps;
+        long lat_1 = Latency.LATENCY100ns, lat_2 = Latency.LATENCY1ms;
+        String nodeType = "STUB";
+        String nodeConnType = "STUB";
+        int headNC1_nodeId = 1, headNC1_nodeConnId = 11;
+        int tailNC1_nodeId = 2, tailNC1_nodeConnId = 22;
+        int headNC2_nodeId = 2, headNC2_nodeConnId = 21;
+        int tailNC2_nodeId = 1, tailNC2_nodeConnId = 12;
+
+        List<TopoEdgeUpdate> topoedgeupdateList = new ArrayList<TopoEdgeUpdate>();
+        NodeConnector headnc1 = new NodeConnector(nodeConnType, headNC1_nodeConnId, new Node(nodeType, headNC1_nodeId));
+        NodeConnector tailnc1 = new NodeConnector(nodeConnType, tailNC1_nodeConnId, new Node(nodeType, tailNC1_nodeId));
+        Edge e1 = new Edge(tailnc1, headnc1);
+        Set<Property> props_1 = new HashSet<Property>();
+        props_1.add(new State(state_1));
+        props_1.add(new Bandwidth(bw_1));
+        props_1.add(new Latency(lat_1));
+        TopoEdgeUpdate teu1 = new TopoEdgeUpdate(e1, props_1, UpdateType.ADDED);
+        topoedgeupdateList.add(teu1);
+
+        NodeConnector headnc2 = new NodeConnector(nodeConnType, headNC2_nodeConnId, new Node(nodeType, headNC2_nodeId));
+        NodeConnector tailnc2 = new NodeConnector(nodeConnType, tailNC2_nodeConnId, new Node(nodeType, tailNC2_nodeId));
+        Edge e2 = new Edge(tailnc2, headnc2);
+        Set<Property> props_2 = new HashSet<Property>();
+        props_2.add(new State(state_2));
+        props_2.add(new Bandwidth(bw_2));
+        props_2.add(new Latency(lat_2));
+
+        TopoEdgeUpdate teu2 = new TopoEdgeUpdate(e2, props_2, UpdateType.ADDED);
+        topoedgeupdateList.add(teu2);
+
+        topoUpdates.edgeUpdate(topoedgeupdateList);
+
+        // HTTP request
+        String result = getJsonResult(baseURL, "GET");
+        Assert.assertTrue(httpResponseCode == 200);
+        if (debugMsg) {
+            System.out.println("Get Topology: " + result);
+        }
+
+        // returned data must be an array of edges
+        JSONTokener jt = new JSONTokener(result);
+        JSONObject json = new JSONObject(jt);
+        Assert.assertTrue(json.get("edgeProperties") instanceof JSONArray);
+        JSONArray ja = json.getJSONArray("edgeProperties");
+
+        for (int i = 0; i < ja.length(); i++) {
+            JSONObject edgeProp = ja.getJSONObject(i);
+            JSONObject edge = edgeProp.getJSONObject("edge");
+            JSONObject tailNC = edge.getJSONObject("tailNodeConnector");
+            JSONObject tailNode = tailNC.getJSONObject("node");
+
+            JSONObject headNC = edge.getJSONObject("headNodeConnector");
+            JSONObject headNode = headNC.getJSONObject("node");
+            JSONObject Props = edgeProp.getJSONObject("properties");
+            JSONObject bandw = Props.getJSONObject("bandwidth");
+            JSONObject stt = Props.getJSONObject("state");
+            JSONObject ltc = Props.getJSONObject("latency");
+
+            if (headNC.getInt("@id") == headNC1_nodeConnId) {
+                Assert.assertEquals(headNode.getString("@type"), nodeType);
+                Assert.assertEquals(headNode.getLong("@id"), headNC1_nodeId);
+                Assert.assertEquals(headNC.getString("@type"), nodeConnType);
+                Assert.assertEquals(tailNode.getString("@type"),nodeType);
+                Assert.assertEquals(tailNode.getString("@type"), nodeConnType);
+                Assert.assertEquals(tailNC.getLong("@id"), tailNC1_nodeConnId);
+                Assert.assertEquals(bandw.getLong("bandwidthValue"), bw_1);
+                Assert.assertTrue((short) stt.getInt("stateValue") == state_1);
+                Assert.assertEquals(ltc.getLong("latencyValue"), lat_1);
+            } else if (headNC.getInt("@id") == headNC2_nodeConnId) {
+                Assert.assertEquals(headNode.getString("@type"),nodeType);
+                Assert.assertEquals(headNode.getLong("@id"), headNC2_nodeId);
+                Assert.assertEquals(headNC.getString("@type"), nodeConnType);
+                Assert.assertEquals(tailNode.getString("@type"), nodeType);
+                Assert.assertTrue(tailNode.getInt("@id") == tailNC2_nodeId);
+                Assert.assertEquals(tailNC.getString("@type"), nodeConnType);
+                Assert.assertEquals(tailNC.getLong("@id"), tailNC2_nodeConnId);
+                Assert.assertEquals(bandw.getLong("bandwidthValue"), bw_2);
+                Assert.assertTrue((short) stt.getInt("stateValue") == state_2);
+                Assert.assertEquals(ltc.getLong("latencyValue"), lat_2);
+            }
+        }
+
+        // === test POST method for addUserLink()
+        // define 2 sample nodeConnectors for user link configuration tests
+        String nodeType_1 = "STUB";
+        Integer nodeId_1 = 3366;
+        String nodeConnectorType_1 = "STUB";
+        Integer nodeConnectorId_1 = 12;
+
+        String nodeType_2 = "STUB";
+        Integer nodeId_2 = 4477;
+        String nodeConnectorType_2 = "STUB";
+        Integer nodeConnectorId_2 = 34;
+
+        JSONObject jo = new JSONObject()
+                .append("name", "userLink_1")
+                .append("srcNodeConnector",
+                        nodeConnectorType_1 + "|" + nodeConnectorId_1 + "@" + nodeType_1 + "|" + nodeId_1)
+                .append("dstNodeConnector",
+                        nodeConnectorType_2 + "|" + nodeConnectorId_2 + "@" + nodeType_2 + "|" + nodeId_2);
+        // execute HTTP request and verify response code
+        result = getJsonResult(baseURL + "/userLink", "POST", jo.toString());
+        Assert.assertTrue(httpResponseCode == 201);
+
+        // === test GET method for getUserLinks()
+        result = getJsonResult(baseURL + "/userLink", "GET");
+        Assert.assertTrue(httpResponseCode == 200);
+        if (debugMsg) {
+            System.out.println("result:" + result);
+        }
+
+        jt = new JSONTokener(result);
+        json = new JSONObject(jt);
+
+        // should have at least one object returned
+        Assert.assertFalse(json.length() == 0);
+        JSONObject userlink = new JSONObject();
+
+        if (json.get("userLinks") instanceof JSONArray) {
+            ja = json.getJSONArray("userLinks");
+            int i;
+            for (i = 0; i < ja.length(); i++) {
+                userlink = ja.getJSONObject(i);
+                if (userlink.getString("name").equalsIgnoreCase("userLink_1"))
+                    break;
+            }
+            Assert.assertFalse(i == ja.length());
+        } else {
+            userlink = json.getJSONObject("userLinks");
+            Assert.assertTrue(userlink.getString("name").equalsIgnoreCase("userLink_1"));
+        }
+
+        String[] level_1, level_2;
+        level_1 = userlink.getString("srcNodeConnector").split("\\@");
+        level_2 = level_1[0].split("\\|");
+        Assert.assertTrue(level_2[0].equalsIgnoreCase(nodeConnectorType_1));
+        Assert.assertTrue(Integer.parseInt(level_2[1]) == nodeConnectorId_1);
+        level_2 = level_1[1].split("\\|");
+        Assert.assertTrue(level_2[0].equalsIgnoreCase(nodeType_1));
+        Assert.assertTrue(Integer.parseInt(level_2[1]) == nodeId_1);
+        level_1 = userlink.getString("dstNodeConnector").split("\\@");
+        level_2 = level_1[0].split("\\|");
+        Assert.assertTrue(level_2[0].equalsIgnoreCase(nodeConnectorType_2));
+        Assert.assertTrue(Integer.parseInt(level_2[1]) == nodeConnectorId_2);
+        level_2 = level_1[1].split("\\|");
+        Assert.assertTrue(level_2[0].equalsIgnoreCase(nodeType_2));
+        Assert.assertTrue(Integer.parseInt(level_2[1]) == nodeId_2);
+
+        // === test DELETE method for deleteUserLink()
+        String userName = "userLink_1";
+        result = getJsonResult(baseURL + "/userLink/" + userName, "DELETE");
+        Assert.assertTrue(httpResponseCode == 200);
+
+        // execute another getUserLinks() request to verify that userLink_1 is
+        // removed
+        result = getJsonResult(baseURL + "/userLink", "GET");
+        Assert.assertTrue(httpResponseCode == 200);
+        if (debugMsg) {
+            System.out.println("result:" + result);
+        }
+        jt = new JSONTokener(result);
+        json = new JSONObject(jt);
+
+        if (json.length() != 0) {
+            if (json.get("userLinks") instanceof JSONArray) {
+                ja = json.getJSONArray("userLinks");
+                for (int i = 0; i < ja.length(); i++) {
+                    userlink = ja.getJSONObject(i);
+                    Assert.assertFalse(userlink.getString("name").equalsIgnoreCase("userLink_1"));
+                }
+            } else {
+                userlink = json.getJSONObject("userLinks");
+                Assert.assertFalse(userlink.getString("name").equalsIgnoreCase("userLink_1"));
+            }
+        }
+    }
+
     // Configure the OSGi container
     @Configuration
     public Option[] config() {
         return options(
                 //
                 systemProperty("logback.configurationFile").value(
-                        "file:" + PathUtils.getBaseDir()
-                                + "/src/test/resources/logback.xml"),
+                        "file:" + PathUtils.getBaseDir() + "/src/test/resources/logback.xml"),
                 // To start OSGi console for inspection remotely
                 systemProperty("osgi.console").value("2401"),
-                systemProperty("org.eclipse.gemini.web.tomcat.config.path")
-                        .value(PathUtils.getBaseDir()
-                                + "/src/test/resources/tomcat-server.xml"),
+                systemProperty("org.eclipse.gemini.web.tomcat.config.path").value(
+                        PathUtils.getBaseDir() + "/src/test/resources/tomcat-server.xml"),
 
                 // setting default level. Jersey bundles will need to be started
                 // earlier.
@@ -1113,90 +1252,52 @@ public class NorthboundIT {
                 mavenBundle("ch.qos.logback", "logback-core", "1.0.9"),
                 mavenBundle("ch.qos.logback", "logback-classic", "1.0.9"),
                 mavenBundle("org.apache.commons", "commons-lang3", "3.1"),
-                mavenBundle("org.apache.felix",
-                        "org.apache.felix.dependencymanager", "3.1.0"),
+                mavenBundle("org.apache.felix", "org.apache.felix.dependencymanager", "3.1.0"),
 
                 // the plugin stub to get data for the tests
-                mavenBundle("org.opendaylight.controller",
-                        "protocol_plugins.stub", "0.4.0-SNAPSHOT"),
+                mavenBundle("org.opendaylight.controller", "protocol_plugins.stub", "0.4.0-SNAPSHOT"),
 
                 // List all the opendaylight modules
-                mavenBundle("org.opendaylight.controller", "security",
-                        "0.4.0-SNAPSHOT").noStart(),
-                mavenBundle("org.opendaylight.controller", "sal",
-                        "0.5.0-SNAPSHOT"),
-                mavenBundle("org.opendaylight.controller",
-                        "sal.implementation", "0.4.0-SNAPSHOT"),
-                mavenBundle("org.opendaylight.controller", "statisticsmanager",
-                        "0.4.0-SNAPSHOT"),
-                mavenBundle("org.opendaylight.controller",
-                        "statisticsmanager.implementation", "0.4.0-SNAPSHOT"),
-                mavenBundle("org.opendaylight.controller", "containermanager",
-                        "0.4.0-SNAPSHOT"),
-                mavenBundle("org.opendaylight.controller",
-                        "containermanager.implementation", "0.4.0-SNAPSHOT"),
-                mavenBundle("org.opendaylight.controller",
-                        "forwardingrulesmanager", "0.4.0-SNAPSHOT"),
-                mavenBundle("org.opendaylight.controller",
-                        "forwardingrulesmanager.implementation",
-                        "0.4.0-SNAPSHOT"),
-                mavenBundle("org.opendaylight.controller", "arphandler",
-                        "0.4.0-SNAPSHOT"),
-                mavenBundle("org.opendaylight.controller",
-                        "clustering.services", "0.4.0-SNAPSHOT"),
-                mavenBundle("org.opendaylight.controller",
-                        "clustering.services-implementation", "0.4.0-SNAPSHOT"),
-                mavenBundle("org.opendaylight.controller", "switchmanager",
-                        "0.4.0-SNAPSHOT"),
-                mavenBundle("org.opendaylight.controller",
-                        "switchmanager.implementation", "0.4.0-SNAPSHOT"),
-                mavenBundle("org.opendaylight.controller", "configuration",
-                        "0.4.0-SNAPSHOT"),
-                mavenBundle("org.opendaylight.controller",
-                        "configuration.implementation", "0.4.0-SNAPSHOT"),
-                mavenBundle("org.opendaylight.controller", "hosttracker",
-                        "0.4.0-SNAPSHOT"),
-                mavenBundle("org.opendaylight.controller",
-                        "hosttracker.implementation", "0.4.0-SNAPSHOT"),
-                mavenBundle("org.opendaylight.controller", "arphandler",
-                        "0.4.0-SNAPSHOT"),
-                mavenBundle("org.opendaylight.controller",
-                        "routing.dijkstra_implementation", "0.4.0-SNAPSHOT"),
-                mavenBundle("org.opendaylight.controller", "topologymanager",
-                        "0.4.0-SNAPSHOT"),
-
-                mavenBundle("org.opendaylight.controller", "usermanager",
-                        "0.4.0-SNAPSHOT"),
-                mavenBundle("org.opendaylight.controller",
-                        "usermanager.implementation", "0.4.0-SNAPSHOT"),
-                mavenBundle("org.opendaylight.controller", "logging.bridge",
-                        "0.4.0-SNAPSHOT"),
-                mavenBundle("org.opendaylight.controller", "clustering.test",
-                        "0.4.0-SNAPSHOT"),
-
-                mavenBundle("org.opendaylight.controller",
-                        "forwarding.staticrouting", "0.4.0-SNAPSHOT"),
+                mavenBundle("org.opendaylight.controller", "security", "0.4.0-SNAPSHOT").noStart(),
+                mavenBundle("org.opendaylight.controller", "sal", "0.5.0-SNAPSHOT"),
+                mavenBundle("org.opendaylight.controller", "sal.implementation", "0.4.0-SNAPSHOT"),
+                mavenBundle("org.opendaylight.controller", "statisticsmanager", "0.4.0-SNAPSHOT"),
+                mavenBundle("org.opendaylight.controller", "statisticsmanager.implementation", "0.4.0-SNAPSHOT"),
+                mavenBundle("org.opendaylight.controller", "containermanager", "0.4.0-SNAPSHOT"),
+                mavenBundle("org.opendaylight.controller", "containermanager.implementation", "0.4.0-SNAPSHOT"),
+                mavenBundle("org.opendaylight.controller", "forwardingrulesmanager", "0.4.0-SNAPSHOT"),
+                mavenBundle("org.opendaylight.controller", "forwardingrulesmanager.implementation", "0.4.0-SNAPSHOT"),
+                mavenBundle("org.opendaylight.controller", "arphandler", "0.4.0-SNAPSHOT"),
+                mavenBundle("org.opendaylight.controller", "clustering.services", "0.4.0-SNAPSHOT"),
+                mavenBundle("org.opendaylight.controller", "clustering.services-implementation", "0.4.0-SNAPSHOT"),
+                mavenBundle("org.opendaylight.controller", "switchmanager", "0.4.0-SNAPSHOT"),
+                mavenBundle("org.opendaylight.controller", "switchmanager.implementation", "0.4.0-SNAPSHOT"),
+                mavenBundle("org.opendaylight.controller", "configuration", "0.4.0-SNAPSHOT"),
+                mavenBundle("org.opendaylight.controller", "configuration.implementation", "0.4.0-SNAPSHOT"),
+                mavenBundle("org.opendaylight.controller", "hosttracker", "0.4.0-SNAPSHOT"),
+                mavenBundle("org.opendaylight.controller", "hosttracker.implementation", "0.4.0-SNAPSHOT"),
+                mavenBundle("org.opendaylight.controller", "arphandler", "0.4.0-SNAPSHOT"),
+                mavenBundle("org.opendaylight.controller", "routing.dijkstra_implementation", "0.4.0-SNAPSHOT"),
+                mavenBundle("org.opendaylight.controller", "topologymanager", "0.4.0-SNAPSHOT"),
+
+                mavenBundle("org.opendaylight.controller", "usermanager", "0.4.0-SNAPSHOT"),
+                mavenBundle("org.opendaylight.controller", "usermanager.implementation", "0.4.0-SNAPSHOT"),
+                mavenBundle("org.opendaylight.controller", "logging.bridge", "0.4.0-SNAPSHOT"),
+                mavenBundle("org.opendaylight.controller", "clustering.test", "0.4.0-SNAPSHOT"),
+
+                mavenBundle("org.opendaylight.controller", "forwarding.staticrouting", "0.4.0-SNAPSHOT"),
 
                 // Northbound bundles
-                mavenBundle("org.opendaylight.controller",
-                        "commons.northbound", "0.4.0-SNAPSHOT"),
-                mavenBundle("org.opendaylight.controller",
-                        "forwarding.staticrouting.northbound", "0.4.0-SNAPSHOT"),
-                mavenBundle("org.opendaylight.controller",
-                        "statistics.northbound", "0.4.0-SNAPSHOT"),
-                mavenBundle("org.opendaylight.controller",
-                        "topology.northbound", "0.4.0-SNAPSHOT"),
-                mavenBundle("org.opendaylight.controller",
-                        "hosttracker.northbound", "0.4.0-SNAPSHOT"),
-                mavenBundle("org.opendaylight.controller",
-                        "switchmanager.northbound", "0.4.0-SNAPSHOT"),
-                mavenBundle("org.opendaylight.controller",
-                        "flowprogrammer.northbound", "0.4.0-SNAPSHOT"),
-                mavenBundle("org.opendaylight.controller",
-                        "subnets.northbound", "0.4.0-SNAPSHOT"),
-
-                mavenBundle("org.codehaus.jackson", "jackson-mapper-asl",
-                        "1.9.8"),
+                mavenBundle("org.opendaylight.controller", "commons.northbound", "0.4.0-SNAPSHOT"),
+                mavenBundle("org.opendaylight.controller", "forwarding.staticrouting.northbound", "0.4.0-SNAPSHOT"),
+                mavenBundle("org.opendaylight.controller", "statistics.northbound", "0.4.0-SNAPSHOT"),
+                mavenBundle("org.opendaylight.controller", "topology.northbound", "0.4.0-SNAPSHOT"),
+                mavenBundle("org.opendaylight.controller", "hosttracker.northbound", "0.4.0-SNAPSHOT"),
+                mavenBundle("org.opendaylight.controller", "switchmanager.northbound", "0.4.0-SNAPSHOT"),
+                mavenBundle("org.opendaylight.controller", "flowprogrammer.northbound", "0.4.0-SNAPSHOT"),
+                mavenBundle("org.opendaylight.controller", "subnets.northbound", "0.4.0-SNAPSHOT"),
+
+                mavenBundle("org.codehaus.jackson", "jackson-mapper-asl", "1.9.8"),
                 mavenBundle("org.codehaus.jackson", "jackson-core-asl", "1.9.8"),
                 mavenBundle("org.codehaus.jackson", "jackson-jaxrs", "1.9.8"),
                 mavenBundle("org.codehaus.jettison", "jettison", "1.3.3"),
@@ -1205,154 +1306,93 @@ public class NorthboundIT {
 
                 mavenBundle("commons-fileupload", "commons-fileupload", "1.2.2"),
 
-                mavenBundle("equinoxSDK381", "javax.servlet",
-                        "3.0.0.v201112011016"),
-                mavenBundle("equinoxSDK381", "javax.servlet.jsp",
-                        "2.2.0.v201112011158"),
-                mavenBundle("equinoxSDK381", "org.eclipse.equinox.ds",
-                        "1.4.0.v20120522-1841"),
+                mavenBundle("equinoxSDK381", "javax.servlet", "3.0.0.v201112011016"),
+                mavenBundle("equinoxSDK381", "javax.servlet.jsp", "2.2.0.v201112011158"),
+                mavenBundle("equinoxSDK381", "org.eclipse.equinox.ds", "1.4.0.v20120522-1841"),
                 mavenBundle("orbit", "javax.xml.rpc", "1.1.0.v201005080400"),
-                mavenBundle("equinoxSDK381", "org.eclipse.equinox.util",
-                        "1.0.400.v20120522-2049"),
-                mavenBundle("equinoxSDK381", "org.eclipse.osgi.services",
-                        "3.3.100.v20120522-1822"),
-                mavenBundle("equinoxSDK381", "org.apache.felix.gogo.command",
-                        "0.8.0.v201108120515"),
-                mavenBundle("equinoxSDK381", "org.apache.felix.gogo.runtime",
-                        "0.8.0.v201108120515"),
-                mavenBundle("equinoxSDK381", "org.apache.felix.gogo.shell",
-                        "0.8.0.v201110170705"),
-                mavenBundle("equinoxSDK381", "org.eclipse.equinox.cm",
-                        "1.0.400.v20120522-1841"),
-                mavenBundle("equinoxSDK381", "org.eclipse.equinox.console",
-                        "1.0.0.v20120522-1841"),
-                mavenBundle("equinoxSDK381", "org.eclipse.equinox.launcher",
-                        "1.3.0.v20120522-1813"),
-
-                mavenBundle("geminiweb", "org.eclipse.gemini.web.core",
-                        "2.2.0.RELEASE"),
-                mavenBundle("geminiweb", "org.eclipse.gemini.web.extender",
-                        "2.2.0.RELEASE"),
-                mavenBundle("geminiweb", "org.eclipse.gemini.web.tomcat",
-                        "2.2.0.RELEASE"),
-                mavenBundle("geminiweb",
-                        "org.eclipse.virgo.kernel.equinox.extensions",
-                        "3.6.0.RELEASE").noStart(),
-                mavenBundle("geminiweb", "org.eclipse.virgo.util.common",
-                        "3.6.0.RELEASE"),
-                mavenBundle("geminiweb", "org.eclipse.virgo.util.io",
-                        "3.6.0.RELEASE"),
-                mavenBundle("geminiweb", "org.eclipse.virgo.util.math",
-                        "3.6.0.RELEASE"),
-                mavenBundle("geminiweb", "org.eclipse.virgo.util.osgi",
-                        "3.6.0.RELEASE"),
-                mavenBundle("geminiweb",
-                        "org.eclipse.virgo.util.osgi.manifest", "3.6.0.RELEASE"),
-                mavenBundle("geminiweb",
-                        "org.eclipse.virgo.util.parser.manifest",
-                        "3.6.0.RELEASE"),
-
-                mavenBundle("org.apache.felix",
-                        "org.apache.felix.dependencymanager", "3.1.0"),
-                mavenBundle("org.apache.felix",
-                        "org.apache.felix.dependencymanager.shell", "3.0.1"),
+                mavenBundle("equinoxSDK381", "org.eclipse.equinox.util", "1.0.400.v20120522-2049"),
+                mavenBundle("equinoxSDK381", "org.eclipse.osgi.services", "3.3.100.v20120522-1822"),
+                mavenBundle("equinoxSDK381", "org.apache.felix.gogo.command", "0.8.0.v201108120515"),
+                mavenBundle("equinoxSDK381", "org.apache.felix.gogo.runtime", "0.8.0.v201108120515"),
+                mavenBundle("equinoxSDK381", "org.apache.felix.gogo.shell", "0.8.0.v201110170705"),
+                mavenBundle("equinoxSDK381", "org.eclipse.equinox.cm", "1.0.400.v20120522-1841"),
+                mavenBundle("equinoxSDK381", "org.eclipse.equinox.console", "1.0.0.v20120522-1841"),
+                mavenBundle("equinoxSDK381", "org.eclipse.equinox.launcher", "1.3.0.v20120522-1813"),
+
+                mavenBundle("geminiweb", "org.eclipse.gemini.web.core", "2.2.0.RELEASE"),
+                mavenBundle("geminiweb", "org.eclipse.gemini.web.extender", "2.2.0.RELEASE"),
+                mavenBundle("geminiweb", "org.eclipse.gemini.web.tomcat", "2.2.0.RELEASE"),
+                mavenBundle("geminiweb", "org.eclipse.virgo.kernel.equinox.extensions", "3.6.0.RELEASE").noStart(),
+                mavenBundle("geminiweb", "org.eclipse.virgo.util.common", "3.6.0.RELEASE"),
+                mavenBundle("geminiweb", "org.eclipse.virgo.util.io", "3.6.0.RELEASE"),
+                mavenBundle("geminiweb", "org.eclipse.virgo.util.math", "3.6.0.RELEASE"),
+                mavenBundle("geminiweb", "org.eclipse.virgo.util.osgi", "3.6.0.RELEASE"),
+                mavenBundle("geminiweb", "org.eclipse.virgo.util.osgi.manifest", "3.6.0.RELEASE"),
+                mavenBundle("geminiweb", "org.eclipse.virgo.util.parser.manifest", "3.6.0.RELEASE"),
+
+                mavenBundle("org.apache.felix", "org.apache.felix.dependencymanager", "3.1.0"),
+                mavenBundle("org.apache.felix", "org.apache.felix.dependencymanager.shell", "3.0.1"),
 
                 mavenBundle("com.google.code.gson", "gson", "2.1"),
-                mavenBundle("org.jboss.spec.javax.transaction",
-                        "jboss-transaction-api_1.1_spec", "1.0.1.Final"),
-                mavenBundle("org.apache.felix", "org.apache.felix.fileinstall",
-                        "3.1.6"),
+                mavenBundle("org.jboss.spec.javax.transaction", "jboss-transaction-api_1.1_spec", "1.0.1.Final"),
+                mavenBundle("org.apache.felix", "org.apache.felix.fileinstall", "3.1.6"),
                 mavenBundle("org.apache.commons", "commons-lang3", "3.1"),
                 mavenBundle("commons-codec", "commons-codec"),
-                mavenBundle("virgomirror",
-                        "org.eclipse.jdt.core.compiler.batch",
-                        "3.8.0.I20120518-2145"),
-                mavenBundle("eclipselink", "javax.persistence",
-                        "2.0.4.v201112161009"),
+                mavenBundle("virgomirror", "org.eclipse.jdt.core.compiler.batch", "3.8.0.I20120518-2145"),
+                mavenBundle("eclipselink", "javax.persistence", "2.0.4.v201112161009"),
 
                 mavenBundle("orbit", "javax.activation", "1.1.0.v201211130549"),
                 mavenBundle("orbit", "javax.annotation", "1.1.0.v201209060031"),
                 mavenBundle("orbit", "javax.ejb", "3.1.1.v201204261316"),
                 mavenBundle("orbit", "javax.el", "2.2.0.v201108011116"),
-                mavenBundle("orbit", "javax.mail.glassfish",
-                        "1.4.1.v201108011116"),
+                mavenBundle("orbit", "javax.mail.glassfish", "1.4.1.v201108011116"),
                 mavenBundle("orbit", "javax.xml.rpc", "1.1.0.v201005080400"),
-                mavenBundle("orbit", "org.apache.catalina",
-                        "7.0.32.v201211201336"),
+                mavenBundle("orbit", "org.apache.catalina", "7.0.32.v201211201336"),
                 // these are bundle fragments that can't be started on its own
-                mavenBundle("orbit", "org.apache.catalina.ha",
-                        "7.0.32.v201211201952").noStart(),
-                mavenBundle("orbit", "org.apache.catalina.tribes",
-                        "7.0.32.v201211201952").noStart(),
-                mavenBundle("orbit", "org.apache.coyote",
-                        "7.0.32.v201211201952").noStart(),
-                mavenBundle("orbit", "org.apache.jasper",
-                        "7.0.32.v201211201952").noStart(),
+                mavenBundle("orbit", "org.apache.catalina.ha", "7.0.32.v201211201952").noStart(),
+                mavenBundle("orbit", "org.apache.catalina.tribes", "7.0.32.v201211201952").noStart(),
+                mavenBundle("orbit", "org.apache.coyote", "7.0.32.v201211201952").noStart(),
+                mavenBundle("orbit", "org.apache.jasper", "7.0.32.v201211201952").noStart(),
 
                 mavenBundle("orbit", "org.apache.el", "7.0.32.v201211081135"),
-                mavenBundle("orbit", "org.apache.juli.extras",
-                        "7.0.32.v201211081135"),
-                mavenBundle("orbit", "org.apache.tomcat.api",
-                        "7.0.32.v201211081135"),
-                mavenBundle("orbit", "org.apache.tomcat.util",
-                        "7.0.32.v201211201952").noStart(),
-                mavenBundle("orbit", "javax.servlet.jsp.jstl",
-                        "1.2.0.v201105211821"),
-                mavenBundle("orbit", "javax.servlet.jsp.jstl.impl",
-                        "1.2.0.v201210211230"),
+                mavenBundle("orbit", "org.apache.juli.extras", "7.0.32.v201211081135"),
+                mavenBundle("orbit", "org.apache.tomcat.api", "7.0.32.v201211081135"),
+                mavenBundle("orbit", "org.apache.tomcat.util", "7.0.32.v201211201952").noStart(),
+                mavenBundle("orbit", "javax.servlet.jsp.jstl", "1.2.0.v201105211821"),
+                mavenBundle("orbit", "javax.servlet.jsp.jstl.impl", "1.2.0.v201210211230"),
 
                 mavenBundle("org.ops4j.pax.exam", "pax-exam-container-native"),
                 mavenBundle("org.ops4j.pax.exam", "pax-exam-junit4"),
                 mavenBundle("org.ops4j.pax.exam", "pax-exam-link-mvn"),
                 mavenBundle("org.ops4j.pax.url", "pax-url-aether"),
 
-                mavenBundle("org.springframework", "org.springframework.asm",
-                        "3.1.3.RELEASE"),
-                mavenBundle("org.springframework", "org.springframework.aop",
-                        "3.1.3.RELEASE"),
-                mavenBundle("org.springframework",
-                        "org.springframework.context", "3.1.3.RELEASE"),
-                mavenBundle("org.springframework",
-                        "org.springframework.context.support", "3.1.3.RELEASE"),
-                mavenBundle("org.springframework", "org.springframework.core",
-                        "3.1.3.RELEASE"),
-                mavenBundle("org.springframework", "org.springframework.beans",
-                        "3.1.3.RELEASE"),
-                mavenBundle("org.springframework",
-                        "org.springframework.expression", "3.1.3.RELEASE"),
-                mavenBundle("org.springframework", "org.springframework.web",
-                        "3.1.3.RELEASE"),
-
-                mavenBundle("org.aopalliance",
-                        "com.springsource.org.aopalliance", "1.0.0"),
-                mavenBundle("org.springframework",
-                        "org.springframework.web.servlet", "3.1.3.RELEASE"),
-                mavenBundle("org.springframework.security",
-                        "spring-security-config", "3.1.3.RELEASE"),
-                mavenBundle("org.springframework.security",
-                        "spring-security-core", "3.1.3.RELEASE"),
-                mavenBundle("org.springframework.security",
-                        "spring-security-web", "3.1.3.RELEASE"),
-                mavenBundle("org.springframework.security",
-                        "spring-security-taglibs", "3.1.3.RELEASE"),
-                mavenBundle("org.springframework",
-                        "org.springframework.transaction", "3.1.3.RELEASE"),
-
-                mavenBundle("org.ow2.chameleon.management", "chameleon-mbeans",
-                        "1.0.0"),
-                mavenBundle("org.opendaylight.controller.thirdparty",
-                        "net.sf.jung2", "2.0.1-SNAPSHOT"),
-                mavenBundle("org.opendaylight.controller.thirdparty",
-                        "com.sun.jersey.jersey-servlet", "1.17-SNAPSHOT"),
+                mavenBundle("org.springframework", "org.springframework.asm", "3.1.3.RELEASE"),
+                mavenBundle("org.springframework", "org.springframework.aop", "3.1.3.RELEASE"),
+                mavenBundle("org.springframework", "org.springframework.context", "3.1.3.RELEASE"),
+                mavenBundle("org.springframework", "org.springframework.context.support", "3.1.3.RELEASE"),
+                mavenBundle("org.springframework", "org.springframework.core", "3.1.3.RELEASE"),
+                mavenBundle("org.springframework", "org.springframework.beans", "3.1.3.RELEASE"),
+                mavenBundle("org.springframework", "org.springframework.expression", "3.1.3.RELEASE"),
+                mavenBundle("org.springframework", "org.springframework.web", "3.1.3.RELEASE"),
+
+                mavenBundle("org.aopalliance", "com.springsource.org.aopalliance", "1.0.0"),
+                mavenBundle("org.springframework", "org.springframework.web.servlet", "3.1.3.RELEASE"),
+                mavenBundle("org.springframework.security", "spring-security-config", "3.1.3.RELEASE"),
+                mavenBundle("org.springframework.security", "spring-security-core", "3.1.3.RELEASE"),
+                mavenBundle("org.springframework.security", "spring-security-web", "3.1.3.RELEASE"),
+                mavenBundle("org.springframework.security", "spring-security-taglibs", "3.1.3.RELEASE"),
+                mavenBundle("org.springframework", "org.springframework.transaction", "3.1.3.RELEASE"),
+
+                mavenBundle("org.ow2.chameleon.management", "chameleon-mbeans", "1.0.0"),
+                mavenBundle("org.opendaylight.controller.thirdparty", "net.sf.jung2", "2.0.1-SNAPSHOT"),
+                mavenBundle("org.opendaylight.controller.thirdparty", "com.sun.jersey.jersey-servlet", "1.17-SNAPSHOT"),
 
                 // Jersey needs to be started before the northbound application
                 // bundles, using a lower start level
                 mavenBundle("com.sun.jersey", "jersey-client", "1.17"),
-                mavenBundle("com.sun.jersey", "jersey-server", "1.17")
-                        .startLevel(2),
-                mavenBundle("com.sun.jersey", "jersey-core", "1.17")
-                        .startLevel(2),
-                mavenBundle("com.sun.jersey", "jersey-json", "1.17")
-                        .startLevel(2), junitBundles());
+                mavenBundle("com.sun.jersey", "jersey-server", "1.17").startLevel(2),
+                mavenBundle("com.sun.jersey", "jersey-core", "1.17").startLevel(2),
+                mavenBundle("com.sun.jersey", "jersey-json", "1.17").startLevel(2), junitBundles());
     }
+
 }
index 61e3872669b67f6a01f955bf2d15780635e0c84a..818002a21e042f87da32f5e14573e1b502ffc328 100644 (file)
@@ -9,6 +9,7 @@
 
 package org.opendaylight.controller.sal.core;
 
+import javax.xml.bind.annotation.XmlElement;
 import javax.xml.bind.annotation.XmlRootElement;
 
 /**
@@ -21,7 +22,9 @@ import javax.xml.bind.annotation.XmlRootElement;
 @XmlRootElement
 public class Latency extends Property {
     private static final long serialVersionUID = 1L;
-    private long latency;
+
+    @XmlElement
+    private long latencyValue;
 
     public static final long LATENCYUNK = 0;
     public static final long LATENCY1ns = (long) Math.pow(10, 3);
@@ -40,37 +43,37 @@ public class Latency extends Property {
      */
     private Latency() {
         super(LatencyPropName);
-        this.latency = LATENCYUNK;
+        this.latencyValue = LATENCYUNK;
     }
 
     public Latency(long latency) {
         super(LatencyPropName);
-        this.latency = latency;
+        this.latencyValue = latency;
     }
 
     public Latency(int latency) {
         super(LatencyPropName);
-        this.latency = (long) latency;
+        this.latencyValue = (long) latency;
     }
 
     public Latency(short latency) {
         super(LatencyPropName);
-        this.latency = (long) latency;
+        this.latencyValue = (long) latency;
     }
 
     public Latency clone() {
-        return new Latency(this.latency);
+        return new Latency(this.latencyValue);
     }
 
     public long getValue() {
-        return this.latency;
+        return this.latencyValue;
     }
 
     @Override
     public int hashCode() {
         final int prime = 31;
         int result = super.hashCode();
-        result = prime * result + (int) (latency ^ (latency >>> 32));
+        result = prime * result + (int) (latencyValue ^ (latencyValue >>> 32));
         return result;
     }
 
@@ -83,7 +86,7 @@ public class Latency extends Property {
         if (getClass() != obj.getClass())
             return false;
         Latency other = (Latency) obj;
-        if (latency != other.latency)
+        if (latencyValue != other.latencyValue)
             return false;
         return true;
     }
@@ -93,16 +96,16 @@ public class Latency extends Property {
         StringBuffer sb = new StringBuffer();
 
         sb.append("Latency[");
-        if (this.latency == 0) {
+        if (this.latencyValue == 0) {
             sb.append("UnKnown");
-        } else if (this.latency < LATENCY1ns) {
-            sb.append(this.latency + "psec");
-        } else if (this.latency < LATENCY1us) {
-            sb.append(Long.toString(this.latency / LATENCY1ns) + "nsec");
-        } else if (this.latency < LATENCY1ms) {
-            sb.append(Long.toString(this.latency / LATENCY1us) + "usec");
-        } else if (this.latency < LATENCY1s) {
-            sb.append(Long.toString(this.latency / LATENCY1ms) + "msec");
+        } else if (this.latencyValue < LATENCY1ns) {
+            sb.append(this.latencyValue + "psec");
+        } else if (this.latencyValue < LATENCY1us) {
+            sb.append(Long.toString(this.latencyValue / LATENCY1ns) + "nsec");
+        } else if (this.latencyValue < LATENCY1ms) {
+            sb.append(Long.toString(this.latencyValue / LATENCY1us) + "usec");
+        } else if (this.latencyValue < LATENCY1s) {
+            sb.append(Long.toString(this.latencyValue / LATENCY1ms) + "msec");
         }
 
         sb.append("]");
index 2235bfb2a32c7dd3fa75b887939af0e428b99827..8b680509ddbc587ead6a16d59a320d738c40041c 100644 (file)
@@ -7,13 +7,22 @@
  */
 package org.opendaylight.controller.sal.binding.generator.impl;
 
+import static org.opendaylight.controller.binding.generator.util.BindingGeneratorUtil.*;
+import static org.opendaylight.controller.yang.model.util.SchemaContextUtil.findDataSchemaNode;
+import static org.opendaylight.controller.yang.model.util.SchemaContextUtil.findParentModule;
+
+import java.util.*;
+import java.util.concurrent.Future;
+
 import org.opendaylight.controller.binding.generator.util.ReferencedTypeImpl;
 import org.opendaylight.controller.binding.generator.util.Types;
 import org.opendaylight.controller.binding.generator.util.generated.type.builder.GeneratedTOBuilderImpl;
 import org.opendaylight.controller.binding.generator.util.generated.type.builder.GeneratedTypeBuilderImpl;
 import org.opendaylight.controller.sal.binding.generator.api.BindingGenerator;
 import org.opendaylight.controller.sal.binding.generator.spi.TypeProvider;
-import org.opendaylight.controller.sal.binding.model.api.*;
+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.binding.model.api.type.builder.*;
 import org.opendaylight.controller.sal.binding.yang.types.TypeProviderImpl;
 import org.opendaylight.controller.yang.binding.Notification;
@@ -26,13 +35,6 @@ import org.opendaylight.controller.yang.model.util.DataNodeIterator;
 import org.opendaylight.controller.yang.model.util.ExtendedType;
 import org.opendaylight.controller.yang.model.util.SchemaContextUtil;
 
-import java.util.*;
-import java.util.concurrent.Future;
-
-import static org.opendaylight.controller.binding.generator.util.BindingGeneratorUtil.*;
-import static org.opendaylight.controller.yang.model.util.SchemaContextUtil.findDataSchemaNode;
-import static org.opendaylight.controller.yang.model.util.SchemaContextUtil.findParentModule;
-
 public final class BindingGeneratorImpl implements BindingGenerator {
 
     private Map<String, Map<String, GeneratedTypeBuilder>> genTypeBuilders;
@@ -46,12 +48,10 @@ public final class BindingGeneratorImpl implements BindingGenerator {
     @Override
     public List<Type> generateTypes(final SchemaContext context) {
         if (context == null) {
-            throw new IllegalArgumentException("Schema Context reference "
-                    + "cannot be NULL!");
+            throw new IllegalArgumentException("Schema Context reference cannot be NULL!");
         }
         if (context.getModules() == null) {
-            throw new IllegalStateException("Schema Context does not contain "
-                    + "defined modules!");
+            throw new IllegalStateException("Schema Context does not contain defined modules!");
         }
 
         final List<Type> generatedTypes = new ArrayList<>();
@@ -64,6 +64,7 @@ public final class BindingGeneratorImpl implements BindingGenerator {
             generatedTypes.addAll(allTypeDefinitionsToGenTypes(module));
             generatedTypes.addAll(allContainersToGenTypes(module));
             generatedTypes.addAll(allListsToGenTypes(module));
+            generatedTypes.addAll(allChoicesToGenTypes(module));
             generatedTypes.addAll(allAugmentsToGenTypes(module));
             generatedTypes.addAll(allRPCMethodsToGenType(module));
             generatedTypes.addAll(allNotificationsToGenType(module));
@@ -74,19 +75,15 @@ public final class BindingGeneratorImpl implements BindingGenerator {
     }
 
     @Override
-    public List<Type> generateTypes(final SchemaContext context,
-            final Set<Module> modules) {
+    public List<Type> generateTypes(final SchemaContext context, final Set<Module> modules) {
         if (context == null) {
-            throw new IllegalArgumentException("Schema Context reference "
-                    + "cannot be NULL!");
+            throw new IllegalArgumentException("Schema Context reference cannot be NULL!");
         }
         if (context.getModules() == null) {
-            throw new IllegalStateException("Schema Context does not contain "
-                    + "defined modules!");
+            throw new IllegalStateException("Schema Context does not contain defined modules!");
         }
         if (modules == null) {
-            throw new IllegalArgumentException("Sef of Modules cannot be "
-                    + "NULL!");
+            throw new IllegalArgumentException("Sef of Modules cannot be NULL!");
         }
 
         final List<Type> filteredGenTypes = new ArrayList<>();
@@ -101,11 +98,11 @@ public final class BindingGeneratorImpl implements BindingGenerator {
             generatedTypes.addAll(allTypeDefinitionsToGenTypes(contextModule));
             generatedTypes.addAll(allContainersToGenTypes(contextModule));
             generatedTypes.addAll(allListsToGenTypes(contextModule));
+            generatedTypes.addAll(allChoicesToGenTypes(contextModule));
             generatedTypes.addAll(allAugmentsToGenTypes(contextModule));
             generatedTypes.addAll(allRPCMethodsToGenType(contextModule));
             generatedTypes.addAll(allNotificationsToGenType(contextModule));
-            generatedTypes.addAll(allIdentitiesToGenTypes(contextModule,
-                    context));
+            generatedTypes.addAll(allIdentitiesToGenTypes(contextModule, context));
             generatedTypes.addAll(allGroupingsToGenTypes(contextModule));
 
             if (modules.contains(contextModule)) {
@@ -117,24 +114,20 @@ public final class BindingGeneratorImpl implements BindingGenerator {
 
     private List<Type> allTypeDefinitionsToGenTypes(final Module module) {
         if (module == null) {
-            throw new IllegalArgumentException(
-                    "Module reference cannot be NULL!");
+            throw new IllegalArgumentException("Module reference cannot be NULL!");
         }
         if (module.getName() == null) {
             throw new IllegalArgumentException("Module name cannot be NULL!");
         }
         if (module.getTypeDefinitions() == null) {
-            throw new IllegalArgumentException("Type Definitions for module "
-                    + module.getName() + " cannot be NULL!");
+            throw new IllegalArgumentException("Type Definitions for module " + module.getName() + " cannot be NULL!");
         }
 
-        final Set<TypeDefinition<?>> typeDefinitions = module
-                .getTypeDefinitions();
+        final Set<TypeDefinition<?>> typeDefinitions = module.getTypeDefinitions();
         final List<Type> generatedTypes = new ArrayList<>();
         for (final TypeDefinition<?> typedef : typeDefinitions) {
             if (typedef != null) {
-                final Type type = ((TypeProviderImpl) typeProvider)
-                        .generatedTypeForExtendedDefinitionType(typedef);
+                final Type type = ((TypeProviderImpl) typeProvider).generatedTypeForExtendedDefinitionType(typedef);
                 if ((type != null) && !generatedTypes.contains(type)) {
                     generatedTypes.add(type);
                 }
@@ -145,8 +138,7 @@ public final class BindingGeneratorImpl implements BindingGenerator {
 
     private List<Type> allContainersToGenTypes(final Module module) {
         if (module == null) {
-            throw new IllegalArgumentException(
-                    "Module reference cannot be NULL!");
+            throw new IllegalArgumentException("Module reference cannot be NULL!");
         }
 
         if (module.getName() == null) {
@@ -154,9 +146,8 @@ public final class BindingGeneratorImpl implements BindingGenerator {
         }
 
         if (module.getChildNodes() == null) {
-            throw new IllegalArgumentException("Reference to Set of Child "
-                    + "Nodes in module " + module.getName() + " cannot be "
-                    + "NULL!");
+            throw new IllegalArgumentException("Reference to Set of Child Nodes in module " + module.getName()
+                    + " cannot be NULL!");
         }
 
         final List<Type> generatedTypes = new ArrayList<>();
@@ -171,8 +162,7 @@ public final class BindingGeneratorImpl implements BindingGenerator {
 
     private List<Type> allListsToGenTypes(final Module module) {
         if (module == null) {
-            throw new IllegalArgumentException(
-                    "Module reference cannot be NULL!");
+            throw new IllegalArgumentException("Module reference cannot be NULL!");
         }
 
         if (module.getName() == null) {
@@ -180,9 +170,8 @@ public final class BindingGeneratorImpl implements BindingGenerator {
         }
 
         if (module.getChildNodes() == null) {
-            throw new IllegalArgumentException("Reference to Set of Child "
-                    + "Nodes in module " + module.getName() + " cannot be "
-                    + "NULL!");
+            throw new IllegalArgumentException("Reference to Set of Child Nodes in module " + module.getName()
+                    + " cannot be NULL!");
         }
 
         final List<Type> generatedTypes = new ArrayList<>();
@@ -197,88 +186,94 @@ public final class BindingGeneratorImpl implements BindingGenerator {
         return generatedTypes;
     }
 
-    private List<Type> allAugmentsToGenTypes(final Module module) {
+    private List<GeneratedType> allChoicesToGenTypes(final Module module) {
         if (module == null) {
-            throw new IllegalArgumentException(
-                    "Module reference cannot be NULL!");
+            throw new IllegalArgumentException("Module reference cannot be NULL!");
         }
-
         if (module.getName() == null) {
             throw new IllegalArgumentException("Module name cannot be NULL!");
         }
 
+        final DataNodeIterator it = new DataNodeIterator(module);
+        final List<ChoiceNode> choiceNodes = it.allChoices();
+        final String basePackageName = moduleNamespaceToPackageName(module);
+
+        final List<GeneratedType> generatedTypes = new ArrayList<>();
+        for (final ChoiceNode choice : choiceNodes) {
+            if (choice != null) {
+                generatedTypes.addAll(choiceToGeneratedType(basePackageName, choice));
+            }
+        }
+        return generatedTypes;
+    }
+
+    private List<Type> allAugmentsToGenTypes(final Module module) {
+        if (module == null) {
+            throw new IllegalArgumentException("Module reference cannot be NULL!");
+        }
+        if (module.getName() == null) {
+            throw new IllegalArgumentException("Module name cannot be NULL!");
+        }
         if (module.getChildNodes() == null) {
-            throw new IllegalArgumentException("Reference to Set of "
-                    + "Augmentation Definitions in module " + module.getName()
-                    + " cannot be NULL!");
+            throw new IllegalArgumentException("Reference to Set of Augmentation Definitions in module "
+                    + module.getName() + " cannot be NULL!");
         }
 
         final List<Type> generatedTypes = new ArrayList<>();
         final String basePackageName = moduleNamespaceToPackageName(module);
         final List<AugmentationSchema> augmentations = resolveAugmentations(module);
         for (final AugmentationSchema augment : augmentations) {
-            generatedTypes.addAll(augmentationToGenTypes(basePackageName,
-                    augment));
+            generatedTypes.addAll(augmentationToGenTypes(basePackageName, augment));
         }
         return generatedTypes;
     }
 
     private List<AugmentationSchema> resolveAugmentations(final Module module) {
         if (module == null) {
-            throw new IllegalArgumentException(
-                    "Module reference cannot be NULL!");
+            throw new IllegalArgumentException("Module reference cannot be NULL!");
         }
         if (module.getAugmentations() == null) {
             throw new IllegalStateException("Augmentations Set cannot be NULL!");
         }
 
         final Set<AugmentationSchema> augmentations = module.getAugmentations();
-        final List<AugmentationSchema> sortedAugmentations = new ArrayList<>(
-                augmentations);
-        Collections.sort(sortedAugmentations,
-                new Comparator<AugmentationSchema>() {
-
-                    @Override
-                    public int compare(AugmentationSchema augSchema1,
-                            AugmentationSchema augSchema2) {
-
-                        if (augSchema1.getTargetPath().getPath().size() > augSchema2
-                                .getTargetPath().getPath().size()) {
-                            return 1;
-                        } else if (augSchema1.getTargetPath().getPath().size() < augSchema2
-                                .getTargetPath().getPath().size()) {
-                            return -1;
-                        }
-                        return 0;
+        final List<AugmentationSchema> sortedAugmentations = new ArrayList<>(augmentations);
+        Collections.sort(sortedAugmentations, new Comparator<AugmentationSchema>() {
 
-                    }
-                });
+            @Override
+            public int compare(AugmentationSchema augSchema1, AugmentationSchema augSchema2) {
+
+                if (augSchema1.getTargetPath().getPath().size() > augSchema2.getTargetPath().getPath().size()) {
+                    return 1;
+                } else if (augSchema1.getTargetPath().getPath().size() < augSchema2.getTargetPath().getPath().size()) {
+                    return -1;
+                }
+                return 0;
+
+            }
+        });
 
         return sortedAugmentations;
     }
 
     private GeneratedType moduleToDataType(final Module module) {
         if (module == null) {
-            throw new IllegalArgumentException(
-                    "Module reference cannot be NULL!");
+            throw new IllegalArgumentException("Module reference cannot be NULL!");
         }
 
-        final GeneratedTypeBuilder moduleDataTypeBuilder = moduleTypeBuilder(
-                module, "Data");
+        final GeneratedTypeBuilder moduleDataTypeBuilder = moduleTypeBuilder(module, "Data");
 
         final String basePackageName = moduleNamespaceToPackageName(module);
         if (moduleDataTypeBuilder != null) {
             final Set<DataSchemaNode> dataNodes = module.getChildNodes();
-            resolveDataSchemaNodes(basePackageName, moduleDataTypeBuilder,
-                    dataNodes);
+            resolveDataSchemaNodes(basePackageName, moduleDataTypeBuilder, dataNodes);
         }
         return moduleDataTypeBuilder.toInstance();
     }
 
     private List<Type> allRPCMethodsToGenType(final Module module) {
         if (module == null) {
-            throw new IllegalArgumentException(
-                    "Module reference cannot be NULL!");
+            throw new IllegalArgumentException("Module reference cannot be NULL!");
         }
 
         if (module.getName() == null) {
@@ -286,24 +281,20 @@ public final class BindingGeneratorImpl implements BindingGenerator {
         }
 
         if (module.getChildNodes() == null) {
-            throw new IllegalArgumentException("Reference to Set of "
-                    + "RPC Method Definitions in module " + module.getName()
-                    + " cannot be NULL!");
+            throw new IllegalArgumentException("Reference to Set of RPC Method Definitions in module "
+                    + module.getName() + " cannot be NULL!");
         }
 
         final String basePackageName = moduleNamespaceToPackageName(module);
         final Set<RpcDefinition> rpcDefinitions = module.getRpcs();
         final List<Type> genRPCTypes = new ArrayList<>();
-        final GeneratedTypeBuilder interfaceBuilder = moduleTypeBuilder(module,
-                "Service");
+        final GeneratedTypeBuilder interfaceBuilder = moduleTypeBuilder(module, "Service");
         final Type future = Types.typeForClass(Future.class);
         for (final RpcDefinition rpc : rpcDefinitions) {
             if (rpc != null) {
 
-                String rpcName = parseToClassName(rpc.getQName()
-                        .getLocalName());
-                MethodSignatureBuilder method = interfaceBuilder
-                        .addMethod(rpcName);
+                String rpcName = parseToClassName(rpc.getQName().getLocalName());
+                MethodSignatureBuilder method = interfaceBuilder.addMethod(rpcName);
 
                 final List<DataNodeIterator> rpcInOut = new ArrayList<>();
 
@@ -312,8 +303,7 @@ public final class BindingGeneratorImpl implements BindingGenerator {
 
                 if (input != null) {
                     rpcInOut.add(new DataNodeIterator(input));
-                    GeneratedTypeBuilder inType = addRawInterfaceDefinition(
-                            basePackageName, input, rpcName);
+                    GeneratedTypeBuilder inType = addRawInterfaceDefinition(basePackageName, input, rpcName);
                     resolveDataSchemaNodes(basePackageName, inType, input.getChildNodes());
                     Type inTypeInstance = inType.toInstance();
                     genRPCTypes.add(inTypeInstance);
@@ -324,30 +314,26 @@ public final class BindingGeneratorImpl implements BindingGenerator {
                 if (output != null) {
                     rpcInOut.add(new DataNodeIterator(output));
 
-                    GeneratedTypeBuilder outType = addRawInterfaceDefinition(
-                            basePackageName, output, rpcName);
+                    GeneratedTypeBuilder outType = addRawInterfaceDefinition(basePackageName, output, rpcName);
                     resolveDataSchemaNodes(basePackageName, outType, output.getChildNodes());
                     outTypeInstance = outType.toInstance();
                     genRPCTypes.add(outTypeInstance);
 
                 }
 
-                final Type rpcRes = Types.parameterizedTypeFor(
-                        Types.typeForClass(RpcResult.class), outTypeInstance);
+                final Type rpcRes = Types.parameterizedTypeFor(Types.typeForClass(RpcResult.class), outTypeInstance);
                 method.setReturnType(Types.parameterizedTypeFor(future, rpcRes));
                 for (DataNodeIterator it : rpcInOut) {
                     List<ContainerSchemaNode> nContainers = it.allContainers();
                     if ((nContainers != null) && !nContainers.isEmpty()) {
                         for (final ContainerSchemaNode container : nContainers) {
-                            genRPCTypes.add(containerToGenType(basePackageName,
-                                    container));
+                            genRPCTypes.add(containerToGenType(basePackageName, container));
                         }
                     }
                     List<ListSchemaNode> nLists = it.allLists();
                     if ((nLists != null) && !nLists.isEmpty()) {
                         for (final ListSchemaNode list : nLists) {
-                            genRPCTypes.addAll(listToGenType(basePackageName,
-                                    list));
+                            genRPCTypes.addAll(listToGenType(basePackageName, list));
                         }
                     }
                 }
@@ -359,8 +345,7 @@ public final class BindingGeneratorImpl implements BindingGenerator {
 
     private List<Type> allNotificationsToGenType(final Module module) {
         if (module == null) {
-            throw new IllegalArgumentException(
-                    "Module reference cannot be NULL!");
+            throw new IllegalArgumentException("Module reference cannot be NULL!");
         }
 
         if (module.getName() == null) {
@@ -368,15 +353,13 @@ public final class BindingGeneratorImpl implements BindingGenerator {
         }
 
         if (module.getChildNodes() == null) {
-            throw new IllegalArgumentException("Reference to Set of "
-                    + "Notification Definitions in module " + module.getName()
-                    + " cannot be NULL!");
+            throw new IllegalArgumentException("Reference to Set of Notification Definitions in module "
+                    + module.getName() + " cannot be NULL!");
         }
 
         final String basePackageName = moduleNamespaceToPackageName(module);
         final List<Type> genNotifyTypes = new ArrayList<>();
-        final Set<NotificationDefinition> notifications = module
-                .getNotifications();
+        final Set<NotificationDefinition> notifications = module.getNotifications();
 
         for (final NotificationDefinition notification : notifications) {
             if (notification != null) {
@@ -384,29 +367,25 @@ public final class BindingGeneratorImpl implements BindingGenerator {
 
                 // Containers
                 for (ContainerSchemaNode node : it.allContainers()) {
-                    genNotifyTypes
-                            .add(containerToGenType(basePackageName, node));
+                    genNotifyTypes.add(containerToGenType(basePackageName, node));
                 }
                 // Lists
                 for (ListSchemaNode node : it.allLists()) {
                     genNotifyTypes.addAll(listToGenType(basePackageName, node));
                 }
-                final GeneratedTypeBuilder notificationTypeBuilder = addRawInterfaceDefinition(
-                        basePackageName, notification);
-                notificationTypeBuilder.addImplementsType(Types
-                        .typeForClass(Notification.class));
+                final GeneratedTypeBuilder notificationTypeBuilder = addDefaultInterfaceDefinition(basePackageName,
+                        notification);
+                notificationTypeBuilder.addImplementsType(Types.typeForClass(Notification.class));
                 // Notification object
-                resolveDataSchemaNodes(basePackageName,
-                        notificationTypeBuilder, notification.getChildNodes());
+                resolveDataSchemaNodes(basePackageName, notificationTypeBuilder, notification.getChildNodes());
                 genNotifyTypes.add(notificationTypeBuilder.toInstance());
             }
         }
         return genNotifyTypes;
     }
 
-    private List<Type> allIdentitiesToGenTypes(final Module module,
-            final SchemaContext context) {
-        List<Type> genTypes = new ArrayList<Type>();
+    private List<Type> allIdentitiesToGenTypes(final Module module, final SchemaContext context) {
+        List<Type> genTypes = new ArrayList<>();
 
         final Set<IdentitySchemaNode> schemaIdentities = module.getIdentities();
 
@@ -414,38 +393,30 @@ public final class BindingGeneratorImpl implements BindingGenerator {
 
         if (schemaIdentities != null && !schemaIdentities.isEmpty()) {
             for (final IdentitySchemaNode identity : schemaIdentities) {
-                genTypes.add(identityToGenType(basePackageName, identity,
-                        context));
+                genTypes.add(identityToGenType(basePackageName, identity, context));
             }
         }
         return genTypes;
     }
 
-    private GeneratedType identityToGenType(final String basePackageName,
-            IdentitySchemaNode identity, SchemaContext context) {
+    private GeneratedType identityToGenType(final String basePackageName, final IdentitySchemaNode identity,
+            final SchemaContext context) {
         if (identity == null) {
             return null;
         }
 
-        final String packageName = packageNameForGeneratedType(basePackageName,
-                identity.getPath());
-
-        final String genTypeName = parseToClassName(identity.getQName()
-                .getLocalName());
-        final GeneratedTOBuilderImpl newType = new GeneratedTOBuilderImpl(
-                packageName, genTypeName);
+        final String packageName = packageNameForGeneratedType(basePackageName, identity.getPath());
+        final String genTypeName = parseToClassName(identity.getQName().getLocalName());
+        final GeneratedTOBuilderImpl newType = new GeneratedTOBuilderImpl(packageName, genTypeName);
 
         IdentitySchemaNode baseIdentity = identity.getBaseIdentity();
         if (baseIdentity != null) {
-            Module baseIdentityParentModule = SchemaContextUtil.findParentModule(
-                    context, baseIdentity);
+            Module baseIdentityParentModule = SchemaContextUtil.findParentModule(context, baseIdentity);
 
             final String returnTypePkgName = moduleNamespaceToPackageName(baseIdentityParentModule);
-            final String returnTypeName = parseToClassName(baseIdentity
-                    .getQName().getLocalName());
+            final String returnTypeName = parseToClassName(baseIdentity.getQName().getLocalName());
 
-            GeneratedTransferObject gto = new GeneratedTOBuilderImpl(
-                    returnTypePkgName, returnTypeName).toInstance();
+            GeneratedTransferObject gto = new GeneratedTOBuilderImpl(returnTypePkgName, returnTypeName).toInstance();
             newType.setExtendsType(gto);
         } else {
             newType.setExtendsType(Types.getBaseIdentityTO());
@@ -454,10 +425,10 @@ public final class BindingGeneratorImpl implements BindingGenerator {
         return newType.toInstance();
     }
 
-    private List<Type> allGroupingsToGenTypes(Module module) {
+    private List<Type> allGroupingsToGenTypes(final Module module) {
         final List<Type> genTypes = new ArrayList<>();
         final String basePackageName = moduleNamespaceToPackageName(module);
-        Set<GroupingDefinition> groupings = module.getGroupings();
+        final Set<GroupingDefinition> groupings = module.getGroupings();
         if (groupings != null && !groupings.isEmpty()) {
             for (final GroupingDefinition grouping : groupings) {
                 genTypes.add(groupingToGenType(basePackageName, grouping));
@@ -466,24 +437,20 @@ public final class BindingGeneratorImpl implements BindingGenerator {
         return genTypes;
     }
 
-    private GeneratedType groupingToGenType(final String basePackageName,
-            GroupingDefinition grouping) {
+    private GeneratedType groupingToGenType(final String basePackageName, GroupingDefinition grouping) {
         if (grouping == null) {
             return null;
         }
 
-        final String packageName = packageNameForGeneratedType(basePackageName,
-                grouping.getPath());
+        final String packageName = packageNameForGeneratedType(basePackageName, grouping.getPath());
         final Set<DataSchemaNode> schemaNodes = grouping.getChildNodes();
-        final GeneratedTypeBuilder typeBuilder = addRawInterfaceDefinition(
-                packageName, grouping);
+        final GeneratedTypeBuilder typeBuilder = addDefaultInterfaceDefinition(packageName, grouping);
 
         resolveDataSchemaNodes(basePackageName, typeBuilder, schemaNodes);
         return typeBuilder.toInstance();
     }
 
-    private EnumTypeDefinition enumTypeDefFromExtendedType(
-            final TypeDefinition<?> typeDefinition) {
+    private EnumTypeDefinition enumTypeDefFromExtendedType(final TypeDefinition<?> typeDefinition) {
         if (typeDefinition != null) {
             if (typeDefinition.getBaseType() instanceof EnumTypeDefinition) {
                 return (EnumTypeDefinition) typeDefinition.getBaseType();
@@ -494,16 +461,13 @@ public final class BindingGeneratorImpl implements BindingGenerator {
         return null;
     }
 
-    private EnumBuilder resolveInnerEnumFromTypeDefinition(
-            final EnumTypeDefinition enumTypeDef, final String enumName,
+    private EnumBuilder resolveInnerEnumFromTypeDefinition(final EnumTypeDefinition enumTypeDef, final String enumName,
             final GeneratedTypeBuilder typeBuilder) {
-        if ((enumTypeDef != null) && (typeBuilder != null)
-                && (enumTypeDef.getQName() != null)
+        if ((enumTypeDef != null) && (typeBuilder != null) && (enumTypeDef.getQName() != null)
                 && (enumTypeDef.getQName().getLocalName() != null)) {
 
             final String enumerationName = parseToClassName(enumName);
-            final EnumBuilder enumBuilder = typeBuilder
-                    .addEnumeration(enumerationName);
+            final EnumBuilder enumBuilder = typeBuilder.addEnumeration(enumerationName);
 
             if (enumBuilder != null) {
                 final List<EnumPair> enums = enumTypeDef.getValues();
@@ -511,8 +475,7 @@ public final class BindingGeneratorImpl implements BindingGenerator {
                     int listIndex = 0;
                     for (final EnumPair enumPair : enums) {
                         if (enumPair != null) {
-                            final String enumPairName = parseToClassName(enumPair
-                                    .getName());
+                            final String enumPairName = parseToClassName(enumPair.getName());
                             Integer enumPairValue = enumPair.getValue();
 
                             if (enumPairValue == null) {
@@ -529,11 +492,9 @@ public final class BindingGeneratorImpl implements BindingGenerator {
         return null;
     }
 
-    private GeneratedTypeBuilder moduleTypeBuilder(final Module module,
-            final String postfix) {
+    private GeneratedTypeBuilder moduleTypeBuilder(final Module module, final String postfix) {
         if (module == null) {
-            throw new IllegalArgumentException(
-                    "Module reference cannot be NULL!");
+            throw new IllegalArgumentException("Module reference cannot be NULL!");
         }
         String packageName = moduleNamespaceToPackageName(module);
         final String moduleName = parseToClassName(module.getName()) + postfix;
@@ -542,18 +503,15 @@ public final class BindingGeneratorImpl implements BindingGenerator {
 
     }
 
-    private List<Type> augmentationToGenTypes(final String augmentPackageName,
-            final AugmentationSchema augSchema) {
+    private List<Type> augmentationToGenTypes(final String augmentPackageName, final AugmentationSchema augSchema) {
         if (augmentPackageName == null) {
             throw new IllegalArgumentException("Package Name cannot be NULL!");
         }
         if (augSchema == null) {
-            throw new IllegalArgumentException(
-                    "Augmentation Schema cannot be NULL!");
+            throw new IllegalArgumentException("Augmentation Schema cannot be NULL!");
         }
         if (augSchema.getTargetPath() == null) {
-            throw new IllegalStateException(
-                    "Augmentation Schema does not contain Target Path (Target Path is NULL).");
+            throw new IllegalStateException("Augmentation Schema does not contain Target Path (Target Path is NULL).");
         }
 
         final List<Type> genTypes = new ArrayList<>();
@@ -561,80 +519,62 @@ public final class BindingGeneratorImpl implements BindingGenerator {
         // EVERY augmented interface will extends Augmentation<T> interface
         // and DataObject interface!!!
         final SchemaPath targetPath = augSchema.getTargetPath();
-        final DataSchemaNode targetSchemaNode = findDataSchemaNode(
-                schemaContext, targetPath);
+        final DataSchemaNode targetSchemaNode = findDataSchemaNode(schemaContext, targetPath);
         if ((targetSchemaNode != null) && (targetSchemaNode.getQName() != null)
                 && (targetSchemaNode.getQName().getLocalName() != null)) {
-            final Module targetModule = findParentModule(schemaContext,
-                    targetSchemaNode);
+            final Module targetModule = findParentModule(schemaContext, targetSchemaNode);
 
             final String targetBasePackage = moduleNamespaceToPackageName(targetModule);
-            final String targetPackageName = packageNameForGeneratedType(
-                    targetBasePackage, targetSchemaNode.getPath());
+            final String targetPackageName = packageNameForGeneratedType(targetBasePackage, targetSchemaNode.getPath());
 
-            final String targetSchemaNodeName = targetSchemaNode.getQName()
-                    .getLocalName();
+            final String targetSchemaNodeName = targetSchemaNode.getQName().getLocalName();
             final Set<DataSchemaNode> augChildNodes = augSchema.getChildNodes();
-            final GeneratedTypeBuilder augTypeBuilder = addRawAugmentGenTypeDefinition(
-                    augmentPackageName, targetPackageName,
-                    targetSchemaNodeName, augSchema);
+            final GeneratedTypeBuilder augTypeBuilder = addRawAugmentGenTypeDefinition(augmentPackageName,
+                    targetPackageName, targetSchemaNodeName, augSchema);
             if (augTypeBuilder != null) {
                 genTypes.add(augTypeBuilder.toInstance());
             }
-            genTypes.addAll(augmentationBodyToGenTypes(augmentPackageName,
-                    augChildNodes));
+            genTypes.addAll(augmentationBodyToGenTypes(augmentPackageName, augChildNodes));
 
         }
         return genTypes;
     }
 
-    private GeneratedTypeBuilder addRawAugmentGenTypeDefinition(
-            final String augmentPackageName, final String targetPackageName,
-            final String targetSchemaNodeName,
-            final AugmentationSchema augSchema) {
+    private GeneratedTypeBuilder addRawAugmentGenTypeDefinition(final String augmentPackageName,
+            final String targetPackageName, final String targetSchemaNodeName, final AugmentationSchema augSchema) {
         final String targetTypeName = parseToClassName(targetSchemaNodeName);
-        Map<String, GeneratedTypeBuilder> augmentBuilders = genTypeBuilders
-                .get(augmentPackageName);
+        Map<String, GeneratedTypeBuilder> augmentBuilders = genTypeBuilders.get(augmentPackageName);
         if (augmentBuilders == null) {
             augmentBuilders = new HashMap<>();
             genTypeBuilders.put(augmentPackageName, augmentBuilders);
         }
 
-        final String augTypeName = augGenTypeName(augmentBuilders,
-                targetTypeName);
-        final Type targetTypeRef = new ReferencedTypeImpl(targetPackageName,
-                targetTypeName);
+        final String augTypeName = augGenTypeName(augmentBuilders, targetTypeName);
+        final Type targetTypeRef = new ReferencedTypeImpl(targetPackageName, targetTypeName);
         final Set<DataSchemaNode> augChildNodes = augSchema.getChildNodes();
 
-        final GeneratedTypeBuilder augTypeBuilder = new GeneratedTypeBuilderImpl(
-                augmentPackageName, augTypeName);
+        final GeneratedTypeBuilder augTypeBuilder = new GeneratedTypeBuilderImpl(augmentPackageName, augTypeName);
 
         augTypeBuilder.addImplementsType(Types.DATA_OBJECT);
-        augTypeBuilder.addImplementsType(Types
-                .augmentationTypeFor(targetTypeRef));
+        augTypeBuilder.addImplementsType(Types.augmentationTypeFor(targetTypeRef));
 
-        augSchemaNodeToMethods(augmentPackageName, augTypeBuilder,
-                augChildNodes);
+        augSchemaNodeToMethods(augmentPackageName, augTypeBuilder, augChildNodes);
         augmentBuilders.put(augTypeName, augTypeBuilder);
         return augTypeBuilder;
     }
 
-    private List<Type> augmentationBodyToGenTypes(
-            final String augBasePackageName,
+    private List<Type> augmentationBodyToGenTypes(final String augBasePackageName,
             final Set<DataSchemaNode> augChildNodes) {
         final List<Type> genTypes = new ArrayList<>();
         final List<DataNodeIterator> augSchemaIts = new ArrayList<>();
         for (final DataSchemaNode childNode : augChildNodes) {
             if (childNode instanceof DataNodeContainer) {
-                augSchemaIts.add(new DataNodeIterator(
-                        (DataNodeContainer) childNode));
+                augSchemaIts.add(new DataNodeIterator((DataNodeContainer) childNode));
 
                 if (childNode instanceof ContainerSchemaNode) {
-                    genTypes.add(containerToGenType(augBasePackageName,
-                            (ContainerSchemaNode) childNode));
+                    genTypes.add(containerToGenType(augBasePackageName, (ContainerSchemaNode) childNode));
                 } else if (childNode instanceof ListSchemaNode) {
-                    genTypes.addAll(listToGenType(augBasePackageName,
-                            (ListSchemaNode) childNode));
+                    genTypes.addAll(listToGenType(augBasePackageName, (ListSchemaNode) childNode));
                 }
             }
         }
@@ -645,8 +585,7 @@ public final class BindingGeneratorImpl implements BindingGenerator {
 
             if ((augContainers != null) && !augContainers.isEmpty()) {
                 for (final ContainerSchemaNode container : augContainers) {
-                    genTypes.add(containerToGenType(augBasePackageName,
-                            container));
+                    genTypes.add(containerToGenType(augBasePackageName, container));
                 }
             }
             if ((augLists != null) && !augLists.isEmpty()) {
@@ -658,9 +597,7 @@ public final class BindingGeneratorImpl implements BindingGenerator {
         return genTypes;
     }
 
-    private String augGenTypeName(
-            final Map<String, GeneratedTypeBuilder> builders,
-            final String genTypeName) {
+    private String augGenTypeName(final Map<String, GeneratedTypeBuilder> builders, final String genTypeName) {
         String augTypeName = genTypeName;
 
         int index = 1;
@@ -671,77 +608,134 @@ public final class BindingGeneratorImpl implements BindingGenerator {
         return augTypeName;
     }
 
-    private GeneratedType containerToGenType(final String basePackageName,
-            ContainerSchemaNode containerNode) {
+    private GeneratedType containerToGenType(final String basePackageName, ContainerSchemaNode containerNode) {
         if (containerNode == null) {
             return null;
         }
 
-        final String packageName = packageNameForGeneratedType(basePackageName,
-                containerNode.getPath());
+        final String packageName = packageNameForGeneratedType(basePackageName, containerNode.getPath());
         final Set<DataSchemaNode> schemaNodes = containerNode.getChildNodes();
-        final GeneratedTypeBuilder typeBuilder = addRawInterfaceDefinition(
-                packageName, containerNode);
+        final GeneratedTypeBuilder typeBuilder = addDefaultInterfaceDefinition(packageName, containerNode);
 
         resolveDataSchemaNodes(basePackageName, typeBuilder, schemaNodes);
         return typeBuilder.toInstance();
     }
 
-    private GeneratedTypeBuilder resolveDataSchemaNodes(
-            final String basePackageName,
-            final GeneratedTypeBuilder typeBuilder,
-            final Set<DataSchemaNode> schemaNodes) {
-
+    private GeneratedTypeBuilder resolveDataSchemaNodes(final String basePackageName,
+            final GeneratedTypeBuilder typeBuilder, final Set<DataSchemaNode> schemaNodes) {
         if ((schemaNodes != null) && (typeBuilder != null)) {
             for (final DataSchemaNode schemaNode : schemaNodes) {
                 if (schemaNode.isAugmenting()) {
                     continue;
                 }
-                addSchemaNodeToBuilderAsMethod(basePackageName, schemaNode,
-                        typeBuilder);
+                addSchemaNodeToBuilderAsMethod(basePackageName, schemaNode, typeBuilder);
             }
         }
         return typeBuilder;
     }
 
-    private GeneratedTypeBuilder augSchemaNodeToMethods(
-            final String basePackageName,
-            final GeneratedTypeBuilder typeBuilder,
-            final Set<DataSchemaNode> schemaNodes) {
-
+    private GeneratedTypeBuilder augSchemaNodeToMethods(final String basePackageName,
+            final GeneratedTypeBuilder typeBuilder, final Set<DataSchemaNode> schemaNodes) {
         if ((schemaNodes != null) && (typeBuilder != null)) {
             for (final DataSchemaNode schemaNode : schemaNodes) {
                 if (schemaNode.isAugmenting()) {
-                    addSchemaNodeToBuilderAsMethod(basePackageName, schemaNode,
-                            typeBuilder);
+                    addSchemaNodeToBuilderAsMethod(basePackageName, schemaNode, typeBuilder);
                 }
             }
         }
         return typeBuilder;
     }
 
-    private void addSchemaNodeToBuilderAsMethod(final String basePackageName,
-            final DataSchemaNode schemaNode,
+    private void addSchemaNodeToBuilderAsMethod(final String basePackageName, final DataSchemaNode schemaNode,
             final GeneratedTypeBuilder typeBuilder) {
         if (schemaNode != null && typeBuilder != null) {
             if (schemaNode instanceof LeafSchemaNode) {
-                resolveLeafSchemaNodeAsMethod(typeBuilder,
-                        (LeafSchemaNode) schemaNode);
+                resolveLeafSchemaNodeAsMethod(typeBuilder, (LeafSchemaNode) schemaNode);
             } else if (schemaNode instanceof LeafListSchemaNode) {
-                resolveLeafListSchemaNode(typeBuilder,
-                        (LeafListSchemaNode) schemaNode);
+                resolveLeafListSchemaNode(typeBuilder, (LeafListSchemaNode) schemaNode);
             } else if (schemaNode instanceof ContainerSchemaNode) {
-                resolveContainerSchemaNode(basePackageName, typeBuilder,
-                        (ContainerSchemaNode) schemaNode);
+                resolveContainerSchemaNode(basePackageName, typeBuilder, (ContainerSchemaNode) schemaNode);
             } else if (schemaNode instanceof ListSchemaNode) {
-                resolveListSchemaNode(basePackageName, typeBuilder,
-                        (ListSchemaNode) schemaNode);
+                resolveListSchemaNode(basePackageName, typeBuilder, (ListSchemaNode) schemaNode);
+            } else if (schemaNode instanceof ChoiceNode) {
+                resolveChoiceSchemaNode(basePackageName, typeBuilder, (ChoiceNode) schemaNode);
             }
         }
     }
 
-    private boolean resolveLeafSchemaNodeAsMethod(
-            final GeneratedTypeBuilder typeBuilder, final LeafSchemaNode leaf) {
+    private void resolveChoiceSchemaNode(final String basePackageName, final GeneratedTypeBuilder typeBuilder,
+            final ChoiceNode choiceNode) {
+        if (basePackageName == null) {
+            throw new IllegalArgumentException("Base Package Name cannot be NULL!");
+        }
+        if (typeBuilder == null) {
+            throw new IllegalArgumentException("Generated Type Builder cannot be NULL!");
+        }
+        if (choiceNode == null) {
+            throw new IllegalArgumentException("Choice Schema Node cannot be NULL!");
+        }
+
+        final String choiceName = choiceNode.getQName().getLocalName();
+        if (choiceName != null) {
+            final String packageName = packageNameForGeneratedType(basePackageName, choiceNode.getPath());
+            final GeneratedTypeBuilder choiceType = addDefaultInterfaceDefinition(packageName, choiceNode);
+            constructGetter(typeBuilder, choiceName, choiceNode.getDescription(), choiceType);
+        }
+    }
+
+    private List<GeneratedType> choiceToGeneratedType(final String basePackageName, final ChoiceNode choiceNode) {
+        if (basePackageName == null) {
+            throw new IllegalArgumentException("Base Package Name cannot be NULL!");
+        }
+        if (choiceNode == null) {
+            throw new IllegalArgumentException("Choice Schema Node cannot be NULL!");
+        }
+
+        final List<GeneratedType> generatedTypes = new ArrayList<>();
+        final String packageName = packageNameForGeneratedType(basePackageName, choiceNode.getPath());
+        final GeneratedTypeBuilder choiceTypeBuilder = addRawInterfaceDefinition(packageName, choiceNode);
+        choiceTypeBuilder.addImplementsType(Types.DATA_OBJECT);
+        final GeneratedType choiceType = choiceTypeBuilder.toInstance();
+
+        generatedTypes.add(choiceType);
+        final Set<ChoiceCaseNode> caseNodes = choiceNode.getCases();
+        if ((caseNodes != null) && !caseNodes.isEmpty()) {
+            generatedTypes.addAll(generateTypesFromChoiceCases(basePackageName, choiceType, caseNodes));
+        }
+        return generatedTypes;
+    }
+
+    private List<GeneratedType> generateTypesFromChoiceCases(final String basePackageName, final Type refChoiceType,
+            final Set<ChoiceCaseNode> caseNodes) {
+        if (basePackageName == null) {
+            throw new IllegalArgumentException("Base Package Name cannot be NULL!");
+        }
+        if (refChoiceType == null) {
+            throw new IllegalArgumentException("Referenced Choice Type cannot be NULL!");
+        }
+        if (caseNodes == null) {
+            throw new IllegalArgumentException("Set of Choice Case Nodes cannot be NULL!");
+        }
+
+        final List<GeneratedType> generatedTypes = new ArrayList<>();
+        for (final ChoiceCaseNode caseNode : caseNodes) {
+            if (caseNode != null) {
+                final String packageName = packageNameForGeneratedType(basePackageName, caseNode.getPath());
+                final GeneratedTypeBuilder caseTypeBuilder = addDefaultInterfaceDefinition(packageName, caseNode);
+                caseTypeBuilder.addImplementsType(refChoiceType);
+
+                final Set<DataSchemaNode> childNodes = caseNode.getChildNodes();
+                if (childNodes != null) {
+                    resolveDataSchemaNodes(basePackageName, caseTypeBuilder, childNodes);
+                }
+                generatedTypes.add(caseTypeBuilder.toInstance());
+            }
+        }
+
+        return generatedTypes;
+    }
+
+    private boolean resolveLeafSchemaNodeAsMethod(final GeneratedTypeBuilder typeBuilder, final LeafSchemaNode leaf) {
         if ((leaf != null) && (typeBuilder != null)) {
             final String leafName = leaf.getQName().getLocalName();
             String leafDesc = leaf.getDescription();
@@ -754,26 +748,21 @@ public final class BindingGeneratorImpl implements BindingGenerator {
 
                 Type returnType = null;
                 if (!(typeDef instanceof EnumTypeDefinition)) {
-                    returnType = typeProvider
-                            .javaTypeForSchemaDefinitionType(typeDef);
+                    returnType = typeProvider.javaTypeForSchemaDefinitionType(typeDef);
                 } else {
                     final EnumTypeDefinition enumTypeDef = enumTypeDefFromExtendedType(typeDef);
-                    final EnumBuilder enumBuilder = resolveInnerEnumFromTypeDefinition(
-                            enumTypeDef, leafName, typeBuilder);
+                    final EnumBuilder enumBuilder = resolveInnerEnumFromTypeDefinition(enumTypeDef, leafName,
+                            typeBuilder);
 
                     if (enumBuilder != null) {
-                        returnType = new ReferencedTypeImpl(
-                                enumBuilder.getPackageName(),
-                                enumBuilder.getName());
+                        returnType = new ReferencedTypeImpl(enumBuilder.getPackageName(), enumBuilder.getName());
                     }
-                    ((TypeProviderImpl) typeProvider).putReferencedType(
-                            leaf.getPath(), returnType);
+                    ((TypeProviderImpl) typeProvider).putReferencedType(leaf.getPath(), returnType);
                 }
                 if (returnType != null) {
                     constructGetter(typeBuilder, leafName, leafDesc, returnType);
                     if (!leaf.isConfiguration()) {
-                        constructSetter(typeBuilder, leafName, leafDesc,
-                                returnType);
+                        constructSetter(typeBuilder, leafName, leafDesc, returnType);
                     }
                     return true;
                 }
@@ -782,8 +771,7 @@ public final class BindingGeneratorImpl implements BindingGenerator {
         return false;
     }
 
-    private boolean resolveLeafSchemaNodeAsProperty(
-            final GeneratedTOBuilder toBuilder, final LeafSchemaNode leaf,
+    private boolean resolveLeafSchemaNodeAsProperty(final GeneratedTOBuilder toBuilder, final LeafSchemaNode leaf,
             boolean isReadOnly) {
         if ((leaf != null) && (toBuilder != null)) {
             final String leafName = leaf.getQName().getLocalName();
@@ -796,12 +784,10 @@ public final class BindingGeneratorImpl implements BindingGenerator {
                 final TypeDefinition<?> typeDef = leaf.getType();
 
                 // TODO: properly resolve enum types
-                final Type returnType = typeProvider
-                        .javaTypeForSchemaDefinitionType(typeDef);
+                final Type returnType = typeProvider.javaTypeForSchemaDefinitionType(typeDef);
 
                 if (returnType != null) {
-                    final GeneratedPropertyBuilder propBuilder = toBuilder
-                            .addProperty(parseToClassName(leafName));
+                    final GeneratedPropertyBuilder propBuilder = toBuilder.addProperty(parseToClassName(leafName));
 
                     propBuilder.setReadOnly(isReadOnly);
                     propBuilder.setReturnType(returnType);
@@ -818,9 +804,7 @@ public final class BindingGeneratorImpl implements BindingGenerator {
         return false;
     }
 
-    private boolean resolveLeafListSchemaNode(
-            final GeneratedTypeBuilder typeBuilder,
-            final LeafListSchemaNode node) {
+    private boolean resolveLeafListSchemaNode(final GeneratedTypeBuilder typeBuilder, final LeafListSchemaNode node) {
         if ((node != null) && (typeBuilder != null)) {
             final String nodeName = node.getQName().getLocalName();
             String nodeDesc = node.getDescription();
@@ -830,8 +814,7 @@ public final class BindingGeneratorImpl implements BindingGenerator {
 
             if (nodeName != null) {
                 final TypeDefinition<?> type = node.getType();
-                final Type listType = Types.listTypeFor(typeProvider
-                        .javaTypeForSchemaDefinitionType(type));
+                final Type listType = Types.listTypeFor(typeProvider.javaTypeForSchemaDefinitionType(type));
 
                 constructGetter(typeBuilder, nodeName, nodeDesc, listType);
                 if (!node.isConfiguration()) {
@@ -843,19 +826,16 @@ public final class BindingGeneratorImpl implements BindingGenerator {
         return false;
     }
 
-    private boolean resolveContainerSchemaNode(final String basePackageName,
-            final GeneratedTypeBuilder typeBuilder,
+    private boolean resolveContainerSchemaNode(final String basePackageName, final GeneratedTypeBuilder typeBuilder,
             final ContainerSchemaNode containerNode) {
         if ((containerNode != null) && (typeBuilder != null)) {
             final String nodeName = containerNode.getQName().getLocalName();
 
             if (nodeName != null) {
-                final String packageName = packageNameForGeneratedType(
-                        basePackageName, containerNode.getPath());
+                final String packageName = packageNameForGeneratedType(basePackageName, containerNode.getPath());
 
-                final GeneratedTypeBuilder rawGenType = addRawInterfaceDefinition(
-                        packageName, containerNode);
-                constructGetter(typeBuilder, nodeName, "", rawGenType);
+                final GeneratedTypeBuilder rawGenType = addDefaultInterfaceDefinition(packageName, containerNode);
+                constructGetter(typeBuilder, nodeName, containerNode.getDescription(), rawGenType);
 
                 return true;
             }
@@ -863,22 +843,17 @@ public final class BindingGeneratorImpl implements BindingGenerator {
         return false;
     }
 
-    private boolean resolveListSchemaNode(final String basePackageName,
-            final GeneratedTypeBuilder typeBuilder,
+    private boolean resolveListSchemaNode(final String basePackageName, final GeneratedTypeBuilder typeBuilder,
             final ListSchemaNode schemaNode) {
         if ((schemaNode != null) && (typeBuilder != null)) {
             final String listName = schemaNode.getQName().getLocalName();
 
             if (listName != null) {
-                final String packageName = packageNameForGeneratedType(
-                        basePackageName, schemaNode.getPath());
-                final GeneratedTypeBuilder rawGenType = addRawInterfaceDefinition(
-                        packageName, schemaNode);
-                constructGetter(typeBuilder, listName, "",
-                        Types.listTypeFor(rawGenType));
+                final String packageName = packageNameForGeneratedType(basePackageName, schemaNode.getPath());
+                final GeneratedTypeBuilder rawGenType = addDefaultInterfaceDefinition(packageName, schemaNode);
+                constructGetter(typeBuilder, listName, schemaNode.getDescription(), Types.listTypeFor(rawGenType));
                 if (!schemaNode.isConfiguration()) {
-                    constructSetter(typeBuilder, listName, "",
-                            Types.listTypeFor(rawGenType));
+                    constructSetter(typeBuilder, listName, schemaNode.getDescription(), Types.listTypeFor(rawGenType));
                 }
                 return true;
             }
@@ -886,43 +861,66 @@ public final class BindingGeneratorImpl implements BindingGenerator {
         return false;
     }
 
-    private GeneratedTypeBuilder addRawInterfaceDefinition(
-            final String packageName, final SchemaNode schemaNode) {
+    /**
+     * Method instantiates new Generated Type Builder and sets the implements definitions of Data Object and
+     * Augmentable.
+     *
+     * @param packageName Generated Type Package Name
+     * @param schemaNode Schema Node definition
+     * @return Generated Type Builder instance for Schema Node definition
+     */
+    private GeneratedTypeBuilder addDefaultInterfaceDefinition(final String packageName, final SchemaNode schemaNode) {
+        final GeneratedTypeBuilder builder = addRawInterfaceDefinition(packageName, schemaNode, "");
+        builder.addImplementsType(Types.DATA_OBJECT);
+        builder.addImplementsType(Types.augmentableTypeFor(builder));
+        return builder;
+    }
+
+    /**
+     *
+     * @param packageName
+     * @param schemaNode
+     * @return
+     */
+    private GeneratedTypeBuilder addRawInterfaceDefinition(final String packageName, final SchemaNode schemaNode) {
         return addRawInterfaceDefinition(packageName, schemaNode, "");
     }
 
-    private GeneratedTypeBuilder addRawInterfaceDefinition(
-            final String packageName, final SchemaNode schemaNode,
+    private GeneratedTypeBuilder addRawInterfaceDefinition(final String packageName, final SchemaNode schemaNode,
             final String prefix) {
         if (schemaNode == null) {
-            return null;
+            throw new IllegalArgumentException("Data Schema Node cannot be NULL!");
+        }
+        if (packageName == null) {
+            throw new IllegalArgumentException("Package Name for Generated Type cannot be NULL!");
+        }
+        if (schemaNode.getQName() == null) {
+            throw new IllegalArgumentException("QName for Data Schema Node cannot be NULL!");
         }
-
         final String schemaNodeName = schemaNode.getQName().getLocalName();
+        if (schemaNodeName == null) {
+            throw new IllegalArgumentException("Local Name of QName for Data Schema Node cannot be NULL!");
+        }
 
-        if ((packageName != null) && (schemaNodeName != null)) {
-            final String genTypeName = prefix + parseToClassName(schemaNodeName)
-                    ;
-            final GeneratedTypeBuilder newType = new GeneratedTypeBuilderImpl(
-                    packageName, genTypeName);
-
-            newType.addImplementsType(Types.DATA_OBJECT);
-            newType.addImplementsType(Types.augmentableTypeFor(newType));
+        final String genTypeName;
+        if (prefix == null) {
+            genTypeName = parseToClassName(schemaNodeName);
+        } else {
+            genTypeName = prefix + parseToClassName(schemaNodeName);
+        }
 
-            if (!genTypeBuilders.containsKey(packageName)) {
-                final Map<String, GeneratedTypeBuilder> builders = new HashMap<>();
+        final GeneratedTypeBuilder newType = new GeneratedTypeBuilderImpl(packageName, genTypeName);
+        if (!genTypeBuilders.containsKey(packageName)) {
+            final Map<String, GeneratedTypeBuilder> builders = new HashMap<>();
+            builders.put(genTypeName, newType);
+            genTypeBuilders.put(packageName, builders);
+        } else {
+            final Map<String, GeneratedTypeBuilder> builders = genTypeBuilders.get(packageName);
+            if (!builders.containsKey(genTypeName)) {
                 builders.put(genTypeName, newType);
-                genTypeBuilders.put(packageName, builders);
-            } else {
-                final Map<String, GeneratedTypeBuilder> builders = genTypeBuilders
-                        .get(packageName);
-                if (!builders.containsKey(genTypeName)) {
-                    builders.put(genTypeName, newType);
-                }
             }
-            return newType;
         }
-        return null;
+        return newType;
     }
 
     private String getterMethodName(final String methodName) {
@@ -939,12 +937,9 @@ public final class BindingGeneratorImpl implements BindingGenerator {
         return method.toString();
     }
 
-    private MethodSignatureBuilder constructGetter(
-            final GeneratedTypeBuilder interfaceBuilder,
-            final String schemaNodeName, final String comment,
-            final Type returnType) {
-        final MethodSignatureBuilder getMethod = interfaceBuilder
-                .addMethod(getterMethodName(schemaNodeName));
+    private MethodSignatureBuilder constructGetter(final GeneratedTypeBuilder interfaceBuilder,
+            final String schemaNodeName, final String comment, final Type returnType) {
+        final MethodSignatureBuilder getMethod = interfaceBuilder.addMethod(getterMethodName(schemaNodeName));
 
         getMethod.setComment(comment);
         getMethod.setReturnType(returnType);
@@ -952,39 +947,29 @@ public final class BindingGeneratorImpl implements BindingGenerator {
         return getMethod;
     }
 
-    private MethodSignatureBuilder constructSetter(
-            final GeneratedTypeBuilder interfaceBuilder,
-            final String schemaNodeName, final String comment,
-            final Type parameterType) {
-        final MethodSignatureBuilder setMethod = interfaceBuilder
-                .addMethod(setterMethodName(schemaNodeName));
+    private MethodSignatureBuilder constructSetter(final GeneratedTypeBuilder interfaceBuilder,
+            final String schemaNodeName, final String comment, final Type parameterType) {
+        final MethodSignatureBuilder setMethod = interfaceBuilder.addMethod(setterMethodName(schemaNodeName));
 
         setMethod.setComment(comment);
-        setMethod.addParameter(parameterType,
-                parseToValidParamName(schemaNodeName));
+        setMethod.addParameter(parameterType, parseToValidParamName(schemaNodeName));
         setMethod.setReturnType(Types.voidType());
 
         return setMethod;
     }
 
-    private List<Type> listToGenType(final String basePackageName,
-            final ListSchemaNode list) {
+    private List<Type> listToGenType(final String basePackageName, final ListSchemaNode list) {
         if (basePackageName == null) {
-            throw new IllegalArgumentException(
-                    "Package Name for Generated Type cannot be NULL!");
+            throw new IllegalArgumentException("Package Name for Generated Type cannot be NULL!");
         }
         if (list == null) {
-            throw new IllegalArgumentException(
-                    "List Schema Node cannot be NULL!");
+            throw new IllegalArgumentException("List Schema Node cannot be NULL!");
         }
 
-        final String packageName = packageNameForGeneratedType(basePackageName,
-                list.getPath());
-        final GeneratedTypeBuilder typeBuilder = resolveListTypeBuilder(
-                packageName, list);
+        final String packageName = packageNameForGeneratedType(basePackageName, list.getPath());
+        final GeneratedTypeBuilder typeBuilder = resolveListTypeBuilder(packageName, list);
         final List<String> listKeys = listKeys(list);
-        GeneratedTOBuilder genTOBuilder = resolveListKeyTOBuilder(packageName,
-                list, listKeys);
+        GeneratedTOBuilder genTOBuilder = resolveListKeyTOBuilder(packageName, list, listKeys);
 
         final Set<DataSchemaNode> schemaNodes = list.getChildNodes();
 
@@ -992,24 +977,19 @@ public final class BindingGeneratorImpl implements BindingGenerator {
             if (schemaNode.isAugmenting()) {
                 continue;
             }
-            addSchemaNodeToListBuilders(basePackageName, schemaNode,
-                    typeBuilder, genTOBuilder, listKeys);
+            addSchemaNodeToListBuilders(basePackageName, schemaNode, typeBuilder, genTOBuilder, listKeys);
         }
         return typeBuildersToGenTypes(typeBuilder, genTOBuilder);
     }
 
-    private void addSchemaNodeToListBuilders(final String basePackageName,
-            final DataSchemaNode schemaNode,
-            final GeneratedTypeBuilder typeBuilder,
-            final GeneratedTOBuilder genTOBuilder, final List<String> listKeys) {
+    private void addSchemaNodeToListBuilders(final String basePackageName, final DataSchemaNode schemaNode,
+            final GeneratedTypeBuilder typeBuilder, final GeneratedTOBuilder genTOBuilder, final List<String> listKeys) {
         if (schemaNode == null) {
-            throw new IllegalArgumentException(
-                    "Data Schema Node cannot be NULL!");
+            throw new IllegalArgumentException("Data Schema Node cannot be NULL!");
         }
 
         if (typeBuilder == null) {
-            throw new IllegalArgumentException(
-                    "Generated Type Builder cannot be NULL!");
+            throw new IllegalArgumentException("Generated Type Builder cannot be NULL!");
         }
 
         if (schemaNode instanceof LeafSchemaNode) {
@@ -1020,30 +1000,23 @@ public final class BindingGeneratorImpl implements BindingGenerator {
                 resolveLeafSchemaNodeAsProperty(genTOBuilder, leaf, true);
             }
         } else if (schemaNode instanceof LeafListSchemaNode) {
-            resolveLeafListSchemaNode(typeBuilder,
-                    (LeafListSchemaNode) schemaNode);
+            resolveLeafListSchemaNode(typeBuilder, (LeafListSchemaNode) schemaNode);
         } else if (schemaNode instanceof ContainerSchemaNode) {
-            resolveContainerSchemaNode(basePackageName, typeBuilder,
-                    (ContainerSchemaNode) schemaNode);
+            resolveContainerSchemaNode(basePackageName, typeBuilder, (ContainerSchemaNode) schemaNode);
         } else if (schemaNode instanceof ListSchemaNode) {
-            resolveListSchemaNode(basePackageName, typeBuilder,
-                    (ListSchemaNode) schemaNode);
+            resolveListSchemaNode(basePackageName, typeBuilder, (ListSchemaNode) schemaNode);
         }
     }
 
-    private List<Type> typeBuildersToGenTypes(
-            final GeneratedTypeBuilder typeBuilder,
-            GeneratedTOBuilder genTOBuilder) {
+    private List<Type> typeBuildersToGenTypes(final GeneratedTypeBuilder typeBuilder, GeneratedTOBuilder genTOBuilder) {
         final List<Type> genTypes = new ArrayList<>();
         if (typeBuilder == null) {
-            throw new IllegalArgumentException(
-                    "Generated Type Builder cannot be NULL!");
+            throw new IllegalArgumentException("Generated Type Builder cannot be NULL!");
         }
 
         if (genTOBuilder != null) {
             final GeneratedTransferObject genTO = genTOBuilder.toInstance();
-            constructGetter(typeBuilder, genTO.getName(),
-                    "Returns Primary Key of Yang List Type", genTO);
+            constructGetter(typeBuilder, genTO.getName(), "Returns Primary Key of Yang List Type", genTO);
             genTypes.add(genTO);
         }
         genTypes.add(typeBuilder.toInstance());
@@ -1054,14 +1027,12 @@ public final class BindingGeneratorImpl implements BindingGenerator {
      * @param list
      * @return
      */
-    private GeneratedTOBuilder resolveListKey(final String packageName,
-            final ListSchemaNode list) {
+    private GeneratedTOBuilder resolveListKey(final String packageName, final ListSchemaNode list) {
         final String listName = list.getQName().getLocalName() + "Key";
         return schemaNodeToTransferObjectBuilder(packageName, list, listName);
     }
 
-    private boolean isPartOfListKey(final LeafSchemaNode leaf,
-            final List<String> keys) {
+    private boolean isPartOfListKey(final LeafSchemaNode leaf, final List<String> keys) {
         if ((leaf != null) && (keys != null) && (leaf.getQName() != null)) {
             final String leafName = leaf.getQName().getLocalName();
             if (keys.contains(leafName)) {
@@ -1084,34 +1055,29 @@ public final class BindingGeneratorImpl implements BindingGenerator {
         return listKeys;
     }
 
-    private GeneratedTypeBuilder resolveListTypeBuilder(
-            final String packageName, final ListSchemaNode list) {
+    private GeneratedTypeBuilder resolveListTypeBuilder(final String packageName, final ListSchemaNode list) {
         if (packageName == null) {
-            throw new IllegalArgumentException(
-                    "Package Name for Generated Type cannot be NULL!");
+            throw new IllegalArgumentException("Package Name for Generated Type cannot be NULL!");
         }
         if (list == null) {
-            throw new IllegalArgumentException(
-                    "List Schema Node cannot be NULL!");
+            throw new IllegalArgumentException("List Schema Node cannot be NULL!");
         }
 
         final String schemaNodeName = list.getQName().getLocalName();
         final String genTypeName = parseToClassName(schemaNodeName);
 
         GeneratedTypeBuilder typeBuilder = null;
-        final Map<String, GeneratedTypeBuilder> builders = genTypeBuilders
-                .get(packageName);
+        final Map<String, GeneratedTypeBuilder> builders = genTypeBuilders.get(packageName);
         if (builders != null) {
             typeBuilder = builders.get(genTypeName);
         }
         if (typeBuilder == null) {
-            typeBuilder = addRawInterfaceDefinition(packageName, list);
+            typeBuilder = addDefaultInterfaceDefinition(packageName, list);
         }
         return typeBuilder;
     }
 
-    private GeneratedTOBuilder resolveListKeyTOBuilder(
-            final String packageName, final ListSchemaNode list,
+    private GeneratedTOBuilder resolveListKeyTOBuilder(final String packageName, final ListSchemaNode list,
             final List<String> listKeys) {
         GeneratedTOBuilder genTOBuilder = null;
         if (listKeys.size() > 0) {
diff --git a/opendaylight/sal/yang-prototype/code-generator/binding-generator-impl/src/test/java/org/opendaylight/controller/sal/binding/generator/impl/ChoiceCaseGenTypesTest.java b/opendaylight/sal/yang-prototype/code-generator/binding-generator-impl/src/test/java/org/opendaylight/controller/sal/binding/generator/impl/ChoiceCaseGenTypesTest.java
new file mode 100644 (file)
index 0000000..e800b5b
--- /dev/null
@@ -0,0 +1,60 @@
+/*
+ * 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.sal.binding.generator.impl;
+
+import java.io.File;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Set;
+
+import org.junit.BeforeClass;
+import org.junit.Test;
+import org.opendaylight.controller.sal.binding.generator.api.BindingGenerator;
+import org.opendaylight.controller.sal.binding.model.api.Type;
+import org.opendaylight.controller.yang.model.api.Module;
+import org.opendaylight.controller.yang.model.api.SchemaContext;
+import org.opendaylight.controller.yang.model.parser.api.YangModelParser;
+import org.opendaylight.controller.yang.parser.impl.YangParserImpl;
+
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
+
+public class ChoiceCaseGenTypesTest {
+
+    private final static List<File> yangModels = new ArrayList<>();
+    private final static String yangModelsFolder = AugmentedTypeTest.class.getResource("/choice-case-type-test-models")
+            .getPath();
+
+    @BeforeClass
+    public static void loadTestResources() {
+        final File augFolder = new File(yangModelsFolder);
+        for (final File fileEntry : augFolder.listFiles()) {
+            if (fileEntry.isFile()) {
+                yangModels.add(fileEntry);
+            }
+        }
+    }
+
+    @Test
+    public void choiceCaseResolvingTypeTest() {
+        final YangModelParser parser = new YangParserImpl();
+        final Set<Module> modules = parser.parseYangModels(yangModels);
+        final SchemaContext context = parser.resolveSchemaContext(modules);
+
+        assertNotNull("context is null", context);
+        final BindingGenerator bindingGen = new BindingGeneratorImpl();
+        final List<Type> genTypes = bindingGen.generateTypes(context);
+
+        assertNotNull("genTypes is null", genTypes);
+        assertFalse("genTypes is empty", genTypes.isEmpty());
+
+        //Expected 23 types from ietf-netconf-monitoring
+        //Expected 14 types from ietf-yang-types
+        //Expected 14 types from ietf-inet-types
+    }
+}
index f0cb1236ae8d8a33efc0b0989cbe108c44dda958..14735c3e5f59f2d2a676d564b46cf6dedf8a8546 100644 (file)
@@ -48,7 +48,7 @@ module binary-type-test {
             type bin:restricted-binary;
         }
 
-        leaf-list binary-list {
+        leaf-list binary-leaf-list {
             type binary {
                 length 256;
             }
diff --git a/opendaylight/sal/yang-prototype/code-generator/binding-generator-impl/src/test/resources/choice-case-type-test-models/augment-monitoring@2013-07-01.yang b/opendaylight/sal/yang-prototype/code-generator/binding-generator-impl/src/test/resources/choice-case-type-test-models/augment-monitoring@2013-07-01.yang
new file mode 100644 (file)
index 0000000..17cf07c
--- /dev/null
@@ -0,0 +1,88 @@
+module augment-monitoring {
+    yang-version 1;
+    namespace "urn:ietf:params:xml:ns:yang:augment-monitoring";
+    prefix "amon";
+
+    import ietf-netconf-monitoring { prefix nm; }
+
+    organization "OPEN DAYLIGHT";
+    contact "http://www.opendaylight.org/";
+
+    revision "2013-07-01" {
+            reference "NO REF";
+    }
+
+    augment "/nm:netconf-state/nm:datastores/nm:datastore/nm:locks/nm:lock-type" {
+        case autonomous-lock {
+            container autonomous-def {
+                leaf lock-id {
+                    type int32;
+                }
+
+                leaf lock-time {
+                    type uint32;
+                }
+            }
+        }
+
+        case anonymous-lock {
+            leaf lock-time {
+                type uint32;
+            }
+        }
+
+        leaf leaf-aug-case {
+            type string;
+        }
+    }
+
+    augment "/nm:netconf-state/nm:datastores/nm:datastore/nm:locks/nm:lock-type/nm:partial-lock" {
+        choice aug-case-by-choice {
+            case foo {
+                leaf foo {
+                    type string;
+                }
+            }
+
+            case bar {
+                leaf bar {
+                    type boolean;
+                }
+            }
+        }
+    }
+
+    augment "/nm:netconf-state/nm:datastores/nm:datastore" {
+        choice storage-format {
+            case xml {
+                container xml-def {
+                    leaf file-name {
+                        type string;
+                    }
+                }
+            }
+
+            case yang {
+                leaf yang-file-name {
+                    type string;
+                }
+            }
+
+            case unknown-files {
+                list files {
+                    key "file-name";
+
+                    leaf file-name {
+                        type string;
+                    }
+
+                    container file-data {
+                        leaf utf8-data {
+                            type string;
+                        }
+                    }
+                }
+            }
+        }
+    }
+}
\ No newline at end of file
diff --git a/opendaylight/sal/yang-prototype/code-generator/binding-generator-impl/src/test/resources/choice-case-type-test-models/ietf-inet-types@2010-09-24.yang b/opendaylight/sal/yang-prototype/code-generator/binding-generator-impl/src/test/resources/choice-case-type-test-models/ietf-inet-types@2010-09-24.yang
new file mode 100644 (file)
index 0000000..de20feb
--- /dev/null
@@ -0,0 +1,418 @@
+ module ietf-inet-types {
+
+   namespace "urn:ietf:params:xml:ns:yang:ietf-inet-types";
+   prefix "inet";
+
+   organization
+    "IETF NETMOD (NETCONF Data Modeling Language) Working Group";
+
+   contact
+    "WG Web:   <http://tools.ietf.org/wg/netmod/>
+     WG List:  <mailto:netmod@ietf.org>
+
+     WG Chair: David Partain
+               <mailto:david.partain@ericsson.com>
+
+     WG Chair: David Kessens
+               <mailto:david.kessens@nsn.com>
+
+     Editor:   Juergen Schoenwaelder
+               <mailto:j.schoenwaelder@jacobs-university.de>";
+
+   description
+    "This module contains a collection of generally useful derived
+     YANG data types for Internet addresses and related things.
+
+     Copyright (c) 2010 IETF Trust and the persons identified as
+     authors of the code.  All rights reserved.
+
+     Redistribution and use in source and binary forms, with or without
+     modification, is permitted pursuant to, and subject to the license
+     terms contained in, the Simplified BSD License set forth in Section
+     4.c of the IETF Trust's Legal Provisions Relating to IETF Documents
+     (http://trustee.ietf.org/license-info).
+
+     This version of this YANG module is part of RFC 6021; see
+     the RFC itself for full legal notices.";
+
+   revision 2010-09-24 {
+     description
+      "Initial revision.";
+     reference
+      "RFC 6021: Common YANG Data Types";
+   }
+
+   /*** collection of protocol field related types ***/
+
+   typedef ip-version {
+     type enumeration {
+       enum unknown {
+         value "0";
+         description
+          "An unknown or unspecified version of the Internet protocol.";
+       }
+       enum ipv4 {
+         value "1";
+         description
+          "The IPv4 protocol as defined in RFC 791.";
+       }
+       enum ipv6 {
+         value "2";
+         description
+          "The IPv6 protocol as defined in RFC 2460.";
+       }
+     }
+     description
+      "This value represents the version of the IP protocol.
+
+       In the value set and its semantics, this type is equivalent
+       to the InetVersion textual convention of the SMIv2.";
+     reference
+      "RFC  791: Internet Protocol
+       RFC 2460: Internet Protocol, Version 6 (IPv6) Specification
+       RFC 4001: Textual Conventions for Internet Network Addresses";
+   }
+
+   typedef dscp {
+     type uint8 {
+       range "0..63";
+     }
+     description
+      "The dscp type represents a Differentiated Services Code-Point
+       that may be used for marking packets in a traffic stream.
+
+       In the value set and its semantics, this type is equivalent
+       to the Dscp textual convention of the SMIv2.";
+     reference
+      "RFC 3289: Management Information Base for the Differentiated
+                 Services Architecture
+       RFC 2474: Definition of the Differentiated Services Field
+                 (DS Field) in the IPv4 and IPv6 Headers
+       RFC 2780: IANA Allocation Guidelines For Values In
+                 the Internet Protocol and Related Headers";
+   }
+
+   typedef ipv6-flow-label {
+     type uint32 {
+       range "0..1048575";
+     }
+     description
+      "The flow-label type represents flow identifier or Flow Label
+       in an IPv6 packet header that may be used to discriminate
+       traffic flows.
+
+       In the value set and its semantics, this type is equivalent
+       to the IPv6FlowLabel textual convention of the SMIv2.";
+     reference
+      "RFC 3595: Textual Conventions for IPv6 Flow Label
+       RFC 2460: Internet Protocol, Version 6 (IPv6) Specification";
+   }
+
+   typedef port-number {
+     type uint16 {
+       range "0..65535";
+     }
+     description
+      "The port-number type represents a 16-bit port number of an
+       Internet transport layer protocol such as UDP, TCP, DCCP, or
+       SCTP.  Port numbers are assigned by IANA.  A current list of
+       all assignments is available from <http://www.iana.org/>.
+
+       Note that the port number value zero is reserved by IANA.  In
+       situations where the value zero does not make sense, it can
+       be excluded by subtyping the port-number type.
+
+       In the value set and its semantics, this type is equivalent
+       to the InetPortNumber textual convention of the SMIv2.";
+     reference
+      "RFC  768: User Datagram Protocol
+       RFC  793: Transmission Control Protocol
+       RFC 4960: Stream Control Transmission Protocol
+       RFC 4340: Datagram Congestion Control Protocol (DCCP)
+       RFC 4001: Textual Conventions for Internet Network Addresses";
+   }
+
+   /*** collection of autonomous system related types ***/
+
+   typedef as-number {
+     type uint32;
+     description
+      "The as-number type represents autonomous system numbers
+       which identify an Autonomous System (AS).  An AS is a set
+       of routers under a single technical administration, using
+       an interior gateway protocol and common metrics to route
+       packets within the AS, and using an exterior gateway
+       protocol to route packets to other ASs'.  IANA maintains
+       the AS number space and has delegated large parts to the
+       regional registries.
+
+       Autonomous system numbers were originally limited to 16
+       bits.  BGP extensions have enlarged the autonomous system
+       number space to 32 bits.  This type therefore uses an uint32
+       base type without a range restriction in order to support
+       a larger autonomous system number space.
+
+       In the value set and its semantics, this type is equivalent
+       to the InetAutonomousSystemNumber textual convention of
+       the SMIv2.";
+     reference
+      "RFC 1930: Guidelines for creation, selection, and registration
+                 of an Autonomous System (AS)
+       RFC 4271: A Border Gateway Protocol 4 (BGP-4)
+       RFC 4893: BGP Support for Four-octet AS Number Space
+       RFC 4001: Textual Conventions for Internet Network Addresses";
+   }
+
+   /*** collection of IP address and hostname related types ***/
+
+   typedef ip-address {
+     type union {
+       type inet:ipv4-address;
+       type inet:ipv6-address;
+     }
+     description
+      "The ip-address type represents an IP address and is IP
+       version neutral.  The format of the textual representations
+       implies the IP version.";
+   }
+
+   typedef ipv4-address {
+     type string {
+       pattern
+         '(([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])\.){3}'
+       +  '([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])'
+       + '(%[\p{N}\p{L}]+)?';
+     }
+     description
+       "The ipv4-address type represents an IPv4 address in
+        dotted-quad notation.  The IPv4 address may include a zone
+        index, separated by a % sign.
+
+        The zone index is used to disambiguate identical address
+        values.  For link-local addresses, the zone index will
+        typically be the interface index number or the name of an
+        interface.  If the zone index is not present, the default
+        zone of the device will be used.
+
+        The canonical format for the zone index is the numerical
+        format";
+   }
+
+   typedef ipv6-address {
+     type string {
+       pattern '((:|[0-9a-fA-F]{0,4}):)([0-9a-fA-F]{0,4}:){0,5}'
+             + '((([0-9a-fA-F]{0,4}:)?(:|[0-9a-fA-F]{0,4}))|'
+             + '(((25[0-5]|2[0-4][0-9]|[01]?[0-9]?[0-9])\.){3}'
+             + '(25[0-5]|2[0-4][0-9]|[01]?[0-9]?[0-9])))'
+             + '(%[\p{N}\p{L}]+)?';
+       pattern '(([^:]+:){6}(([^:]+:[^:]+)|(.*\..*)))|'
+             + '((([^:]+:)*[^:]+)?::(([^:]+:)*[^:]+)?)'
+             + '(%.+)?';
+     }
+     description
+      "The ipv6-address type represents an IPv6 address in full,
+       mixed, shortened, and shortened-mixed notation.  The IPv6
+       address may include a zone index, separated by a % sign.
+
+       The zone index is used to disambiguate identical address
+       values.  For link-local addresses, the zone index will
+       typically be the interface index number or the name of an
+       interface.  If the zone index is not present, the default
+       zone of the device will be used.
+
+       The canonical format of IPv6 addresses uses the compressed
+       format described in RFC 4291, Section 2.2, item 2 with the
+       following additional rules: the :: substitution must be
+       applied to the longest sequence of all-zero 16-bit chunks
+       in an IPv6 address.  If there is a tie, the first sequence
+       of all-zero 16-bit chunks is replaced by ::.  Single
+       all-zero 16-bit chunks are not compressed.  The canonical
+       format uses lowercase characters and leading zeros are
+       not allowed.  The canonical format for the zone index is
+       the numerical format as described in RFC 4007, Section
+       11.2.";
+     reference
+      "RFC 4291: IP Version 6 Addressing Architecture
+       RFC 4007: IPv6 Scoped Address Architecture
+       RFC 5952: A Recommendation for IPv6 Address Text Representation";
+   }
+
+   typedef ip-prefix {
+     type union {
+       type inet:ipv4-prefix;
+       type inet:ipv6-prefix;
+     }
+     description
+      "The ip-prefix type represents an IP prefix and is IP
+       version neutral.  The format of the textual representations
+       implies the IP version.";
+   }
+
+   typedef ipv4-prefix {
+     type string {
+       pattern
+          '(([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])\.){3}'
+        +  '([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])'
+        + '/(([0-9])|([1-2][0-9])|(3[0-2]))';
+     }
+     description
+      "The ipv4-prefix type represents an IPv4 address prefix.
+       The prefix length is given by the number following the
+       slash character and must be less than or equal to 32.
+
+       A prefix length value of n corresponds to an IP address
+       mask that has n contiguous 1-bits from the most
+       significant bit (MSB) and all other bits set to 0.
+
+       The canonical format of an IPv4 prefix has all bits of
+       the IPv4 address set to zero that are not part of the
+       IPv4 prefix.";
+   }
+
+   typedef ipv6-prefix {
+     type string {
+       pattern '((:|[0-9a-fA-F]{0,4}):)([0-9a-fA-F]{0,4}:){0,5}'
+             + '((([0-9a-fA-F]{0,4}:)?(:|[0-9a-fA-F]{0,4}))|'
+             + '(((25[0-5]|2[0-4][0-9]|[01]?[0-9]?[0-9])\.){3}'
+             + '(25[0-5]|2[0-4][0-9]|[01]?[0-9]?[0-9])))'
+             + '(/(([0-9])|([0-9]{2})|(1[0-1][0-9])|(12[0-8])))';
+       pattern '(([^:]+:){6}(([^:]+:[^:]+)|(.*\..*)))|'
+             + '((([^:]+:)*[^:]+)?::(([^:]+:)*[^:]+)?)'
+             + '(/.+)';
+     }
+     description
+      "The ipv6-prefix type represents an IPv6 address prefix.
+       The prefix length is given by the number following the
+       slash character and must be less than or equal 128.
+
+       A prefix length value of n corresponds to an IP address
+       mask that has n contiguous 1-bits from the most
+       significant bit (MSB) and all other bits set to 0.
+
+       The IPv6 address should have all bits that do not belong
+       to the prefix set to zero.
+
+       The canonical format of an IPv6 prefix has all bits of
+       the IPv6 address set to zero that are not part of the
+       IPv6 prefix.  Furthermore, IPv6 address is represented
+       in the compressed format described in RFC 4291, Section
+       2.2, item 2 with the following additional rules: the ::
+       substitution must be applied to the longest sequence of
+       all-zero 16-bit chunks in an IPv6 address.  If there is
+       a tie, the first sequence of all-zero 16-bit chunks is
+       replaced by ::.  Single all-zero 16-bit chunks are not
+       compressed.  The canonical format uses lowercase
+       characters and leading zeros are not allowed.";
+     reference
+      "RFC 4291: IP Version 6 Addressing Architecture";
+   }
+
+   /*** collection of domain name and URI types ***/
+
+   typedef domain-name {
+     type string {
+       pattern '((([a-zA-Z0-9_]([a-zA-Z0-9\-_]){0,61})?[a-zA-Z0-9]\.)*'
+            +  '([a-zA-Z0-9_]([a-zA-Z0-9\-_]){0,61})?[a-zA-Z0-9]\.?)'
+            +  '|\.';
+       length "1..253";
+     }
+     description
+      "The domain-name type represents a DNS domain name.  The
+       name SHOULD be fully qualified whenever possible.
+
+       Internet domain names are only loosely specified.  Section
+       3.5 of RFC 1034 recommends a syntax (modified in Section
+       2.1 of RFC 1123).  The pattern above is intended to allow
+       for current practice in domain name use, and some possible
+       future expansion.  It is designed to hold various types of
+       domain names, including names used for A or AAAA records
+       (host names) and other records, such as SRV records.  Note
+       that Internet host names have a stricter syntax (described
+       in RFC 952) than the DNS recommendations in RFCs 1034 and
+       1123, and that systems that want to store host names in
+       schema nodes using the domain-name type are recommended to
+       adhere to this stricter standard to ensure interoperability.
+
+       The encoding of DNS names in the DNS protocol is limited
+       to 255 characters.  Since the encoding consists of labels
+       prefixed by a length bytes and there is a trailing NULL
+       byte, only 253 characters can appear in the textual dotted
+       notation.
+
+       The description clause of schema nodes using the domain-name
+       type MUST describe when and how these names are resolved to
+       IP addresses.  Note that the resolution of a domain-name value
+       may require to query multiple DNS records (e.g., A for IPv4
+       and AAAA for IPv6).  The order of the resolution process and
+       which DNS record takes precedence can either be defined
+       explicitely or it may depend on the configuration of the
+       resolver.
+
+       Domain-name values use the US-ASCII encoding.  Their canonical
+       format uses lowercase US-ASCII characters.  Internationalized
+       domain names MUST be encoded in punycode as described in RFC
+       3492";
+     reference
+      "RFC  952: DoD Internet Host Table Specification
+       RFC 1034: Domain Names - Concepts and Facilities
+       RFC 1123: Requirements for Internet Hosts -- Application
+                 and Support
+       RFC 2782: A DNS RR for specifying the location of services
+                 (DNS SRV)
+       RFC 3492: Punycode: A Bootstring encoding of Unicode for
+                 Internationalized Domain Names in Applications
+                 (IDNA)
+       RFC 5891: Internationalizing Domain Names in Applications
+                 (IDNA): Protocol";
+   }
+
+   typedef host {
+     type union {
+       type inet:ip-address;
+       type inet:domain-name;
+     }
+     description
+      "The host type represents either an IP address or a DNS
+       domain name.";
+   }
+
+   typedef uri {
+     type string;
+     description
+      "The uri type represents a Uniform Resource Identifier
+       (URI) as defined by STD 66.
+
+       Objects using the uri type MUST be in US-ASCII encoding,
+       and MUST be normalized as described by RFC 3986 Sections
+       6.2.1, 6.2.2.1, and 6.2.2.2.  All unnecessary
+       percent-encoding is removed, and all case-insensitive
+       characters are set to lowercase except for hexadecimal
+       digits, which are normalized to uppercase as described in
+       Section 6.2.2.1.
+
+       The purpose of this normalization is to help provide
+       unique URIs.  Note that this normalization is not
+       sufficient to provide uniqueness.  Two URIs that are
+       textually distinct after this normalization may still be
+       equivalent.
+
+       Objects using the uri type may restrict the schemes that
+       they permit.  For example, 'data:' and 'urn:' schemes
+       might not be appropriate.
+
+       A zero-length URI is not a valid URI.  This can be used to
+       express 'URI absent' where required.
+
+       In the value set and its semantics, this type is equivalent
+       to the Uri SMIv2 textual convention defined in RFC 5017.";
+     reference
+      "RFC 3986: Uniform Resource Identifier (URI): Generic Syntax
+       RFC 3305: Report from the Joint W3C/IETF URI Planning Interest
+                 Group: Uniform Resource Identifiers (URIs), URLs,
+                 and Uniform Resource Names (URNs): Clarifications
+                 and Recommendations
+       RFC 5017: MIB Textual Conventions for Uniform Resource
+                 Identifiers (URIs)";
+   }
+
+ }
diff --git a/opendaylight/sal/yang-prototype/code-generator/binding-generator-impl/src/test/resources/choice-case-type-test-models/ietf-netconf-monitoring@2010-10-04.yang b/opendaylight/sal/yang-prototype/code-generator/binding-generator-impl/src/test/resources/choice-case-type-test-models/ietf-netconf-monitoring@2010-10-04.yang
new file mode 100644 (file)
index 0000000..695fb1d
--- /dev/null
@@ -0,0 +1,254 @@
+module ietf-netconf-monitoring {
+
+  namespace "urn:ietf:params:xml:ns:yang:ietf-netconf-monitoring";
+  prefix "ncm";
+
+  import ietf-yang-types { prefix yang; }
+  import ietf-inet-types { prefix inet; }
+
+  organization
+    "IETF NETCONF (Network Configuration) Working Group";
+
+  contact
+    "WG Web:   <http://tools.ietf.org/wg/netconf/>
+     WG List:  <mailto:netconf@ietf.org>
+
+     WG Chair: Mehmet Ersue
+               <mailto:mehmet.ersue@nsn.com>
+
+     WG Chair: Bert Wijnen
+               <mailto:bertietf@bwijnen.net>
+
+     Editor:   Mark Scott
+               <mailto:mark.scott@ericsson.com>
+
+     Editor:   Martin Bjorklund
+               <mailto:mbj@tail-f.com>";
+
+  description
+    "NETCONF Monitoring Module.
+     All elements in this module are read-only.
+
+     Copyright (c) 2010 IETF Trust and the persons identified as
+     authors of the code. All rights reserved.
+
+     Redistribution and use in source and binary forms, with or
+     without modification, is permitted pursuant to, and subject
+     to the license terms contained in, the Simplified BSD
+     License set forth in Section 4.c of the IETF Trust's
+     Legal Provisions Relating to IETF Documents
+     (http://trustee.ietf.org/license-info).
+
+     This version of this YANG module is part of RFC 6022; see
+     the RFC itself for full legal notices.";
+
+  revision 2010-10-04 {
+    description
+      "Initial revision.";
+    reference
+      "RFC 6022: YANG Module for NETCONF Monitoring";
+  }
+
+  typedef tls-fingerprint-type {
+    type string {
+      pattern '([0-9a-fA-F]){2}(:([0-9a-fA-F]){2})*';
+    }
+    description
+      "A cryptographic signature (fingerprint) value that can be used to
+       uniquely reference other data of potentially arbitrary length.";
+  }
+
+  typedef netconf-datastore-type {
+    type enumeration {
+      enum running;
+      enum candidate;
+      enum startup;
+    }
+    description
+      "Enumeration of possible NETCONF datastore types.";
+    reference
+      "RFC 4741: NETCONF Configuration Protocol";
+  }
+
+  container netconf-state {
+    config false;
+    description
+      "The netconf-state container is the root of the monitoring
+       data model.";
+
+    container datastores {
+      description
+        "Contains the list of NETCONF configuration datastores.";
+
+      list datastore {
+        key name;
+        description
+          "List of NETCONF configuration datastores supported by
+           the NETCONF server and related information.";
+
+        leaf name {
+          type netconf-datastore-type;
+          description
+            "Name of the datastore associated with this list entry.";
+        }
+        container locks {
+          presence
+            "This container is present only if the datastore
+             is locked.";
+          description
+            "The NETCONF <lock> and <partial-lock> operations allow
+             a client to lock specific resources in a datastore.  The
+             NETCONF server will prevent changes to the locked
+             resources by all sessions except the one that acquired
+             the lock(s).
+
+             Monitoring information is provided for each datastore
+             entry including details such as the session that acquired
+             the lock, the type of lock (global or partial) and the
+             list of locked resources.  Multiple locks per datastore
+             are supported.";
+
+          choice lock-type {
+            description
+              "Indicates if a global lock or a set of partial locks
+               are set.";
+
+            case global-lock {
+                container global-lock {
+                description
+                  "Present if the global lock is set.";
+
+                leaf locked-by-session {
+                  type uint32;
+                  mandatory true;
+                  description
+                    "The session ID of the session that has locked
+                     this resource.  Both a global lock and a partial
+                     lock MUST contain the NETCONF session-id.
+
+                     If the lock is held by a session that is not managed
+                      by the NETCONF server (e.g., a CLI session), a session
+                     id of 0 (zero) is reported.";
+                  reference
+                    "RFC 4741: NETCONF Configuration Protocol";
+                }
+                leaf locked-time {
+                  type yang:date-and-time;
+                  mandatory true;
+                  description
+                    "The date and time of when the resource was
+                      locked.";
+                }
+
+                container capabilities {
+                  description
+                  "Contains the list of NETCONF capabilities supported by the
+                      server.";
+
+                  leaf-list capability {
+                      type inet:uri;
+                        description
+                          "List of NETCONF capabilities supported by the server.";
+                  }
+                }
+              }
+            }
+
+            case partial-lock {
+              list partial-lock {
+                  key lock-id;
+                  description
+                    "List of partial locks.";
+                  reference
+                    "RFC 5717: Partial Lock Remote Procedure Call (RPC) for
+                     NETCONF";
+
+                  leaf lock-id {
+                    type uint32;
+                    description
+                      "This is the lock id returned in the <partial-lock>
+                       response.";
+                  }
+                  leaf-list select {
+                    type yang:xpath1.0;
+                    min-elements 1;
+                    description
+                      "The xpath expression that was used to request
+                       the lock.  The select expression indicates the
+                       original intended scope of the lock.";
+                  }
+                  leaf-list locked-node {
+                    type string;
+                    description
+                      "The list of instance-identifiers (i.e., the
+                       locked nodes). The scope of the partial lock is defined by the list
+                       of locked nodes.";
+                  }
+              }
+            }
+
+            case fingerprint {
+              choice algorithm-and-hash {
+                  mandatory true;
+                  case md5 {
+                    leaf md5 {
+                      type tls-fingerprint-type;
+                    }
+                  }
+                  
+                  case sha1 {
+                    leaf sha1 {
+                      type tls-fingerprint-type;
+                    }
+                  }
+                  
+                  case sha224 {
+                    leaf sha224 {
+                      type tls-fingerprint-type;
+                    }
+                  }
+                  
+                  case sha256 {
+                    leaf sha256 {
+                      type tls-fingerprint-type;
+                    }
+                  }
+                  
+                  case sha384 {
+                    leaf sha384 {
+                      type tls-fingerprint-type;
+                    }
+                  }                
+                  
+                  case sha512 {
+                    leaf sha512 {
+                      type tls-fingerprint-type;
+                    }
+                  }
+                  
+                  description
+                    "Specifies the signature algorithm and cryptographic
+                      signature (fingerprint) used to identify an X.509
+                      certificate.
+
+                      Implementations of this YANG module MAY, but are not
+                      required to, implement all of these cryptographic signature
+                      algorithms.  Implementations of this YANG module MUST
+                      implement at least one of these cryptographic signature
+                      algorithms.
+
+                      The available choices may be extended in the future as
+                      stronger cryptographic signature algorithms become
+                      available and are deemed necessary.";
+
+                  reference
+                    "RFC 5246: The Transport Layer Security (TLS) Protocol
+                      Version 1.2; Section 7.4.1.4.1,  Signature Algorithms";
+              }  // choice algorithm-and-hash
+            }
+          }
+        }
+      }
+    }
+  }
+}
diff --git a/opendaylight/sal/yang-prototype/code-generator/binding-generator-impl/src/test/resources/choice-case-type-test-models/ietf-yang-types@2010-09-24.yang b/opendaylight/sal/yang-prototype/code-generator/binding-generator-impl/src/test/resources/choice-case-type-test-models/ietf-yang-types@2010-09-24.yang
new file mode 100644 (file)
index 0000000..e9d88ab
--- /dev/null
@@ -0,0 +1,396 @@
+ module ietf-yang-types {
+
+   namespace "urn:ietf:params:xml:ns:yang:ietf-yang-types";
+   prefix "yang";
+
+   organization
+    "IETF NETMOD (NETCONF Data Modeling Language) Working Group";
+
+   contact
+    "WG Web:   <http://tools.ietf.org/wg/netmod/>
+     WG List:  <mailto:netmod@ietf.org>
+
+     WG Chair: David Partain
+               <mailto:david.partain@ericsson.com>
+
+     WG Chair: David Kessens
+               <mailto:david.kessens@nsn.com>
+
+     Editor:   Juergen Schoenwaelder
+               <mailto:j.schoenwaelder@jacobs-university.de>";
+
+   description
+    "This module contains a collection of generally useful derived
+     YANG data types.
+
+     Copyright (c) 2010 IETF Trust and the persons identified as
+     authors of the code.  All rights reserved.
+
+     Redistribution and use in source and binary forms, with or without
+     modification, is permitted pursuant to, and subject to the license
+     terms contained in, the Simplified BSD License set forth in Section
+     4.c of the IETF Trust's Legal Provisions Relating to IETF Documents
+     (http://trustee.ietf.org/license-info).
+
+     This version of this YANG module is part of RFC 6021; see
+     the RFC itself for full legal notices.";
+
+   revision 2010-09-24 {
+     description
+      "Initial revision.";
+     reference
+      "RFC 6021: Common YANG Data Types";
+   }
+
+   /*** collection of counter and gauge types ***/
+
+   typedef counter32 {
+     type uint32;
+     description
+      "The counter32 type represents a non-negative integer
+       that monotonically increases until it reaches a
+       maximum value of 2^32-1 (4294967295 decimal), when it
+       wraps around and starts increasing again from zero.
+
+       Counters have no defined 'initial' value, and thus, a
+       single value of a counter has (in general) no information
+       content.  Discontinuities in the monotonically increasing
+       value normally occur at re-initialization of the
+       management system, and at other times as specified in the
+       description of a schema node using this type.  If such
+       other times can occur, for example, the creation of
+       a schema node of type counter32 at times other than
+       re-initialization, then a corresponding schema node
+       should be defined, with an appropriate type, to indicate
+       the last discontinuity.
+
+       The counter32 type should not be used for configuration
+       schema nodes.  A default statement SHOULD NOT be used in
+       combination with the type counter32.
+
+       In the value set and its semantics, this type is equivalent
+       to the Counter32 type of the SMIv2.";
+     reference
+      "RFC 2578: Structure of Management Information Version 2 (SMIv2)";
+   }
+
+   typedef zero-based-counter32 {
+     type yang:counter32;
+     default "0";
+     description
+      "The zero-based-counter32 type represents a counter32
+       that has the defined 'initial' value zero.
+
+       A schema node of this type will be set to zero (0) on creation
+       and will thereafter increase monotonically until it reaches
+       a maximum value of 2^32-1 (4294967295 decimal), when it
+       wraps around and starts increasing again from zero.
+
+       Provided that an application discovers a new schema node
+       of this type within the minimum time to wrap, it can use the
+       'initial' value as a delta.  It is important for a management
+       station to be aware of this minimum time and the actual time
+       between polls, and to discard data if the actual time is too
+       long or there is no defined minimum time.
+
+       In the value set and its semantics, this type is equivalent
+       to the ZeroBasedCounter32 textual convention of the SMIv2.";
+     reference
+       "RFC 4502: Remote Network Monitoring Management Information
+                  Base Version 2";
+   }
+
+   typedef counter64 {
+     type uint64;
+     description
+      "The counter64 type represents a non-negative integer
+       that monotonically increases until it reaches a
+       maximum value of 2^64-1 (18446744073709551615 decimal),
+       when it wraps around and starts increasing again from zero.
+
+       Counters have no defined 'initial' value, and thus, a
+       single value of a counter has (in general) no information
+       content.  Discontinuities in the monotonically increasing
+       value normally occur at re-initialization of the
+       management system, and at other times as specified in the
+       description of a schema node using this type.  If such
+       other times can occur, for example, the creation of
+       a schema node of type counter64 at times other than
+       re-initialization, then a corresponding schema node
+       should be defined, with an appropriate type, to indicate
+       the last discontinuity.
+
+       The counter64 type should not be used for configuration
+       schema nodes.  A default statement SHOULD NOT be used in
+       combination with the type counter64.
+
+       In the value set and its semantics, this type is equivalent
+       to the Counter64 type of the SMIv2.";
+     reference
+      "RFC 2578: Structure of Management Information Version 2 (SMIv2)";
+   }
+
+   typedef zero-based-counter64 {
+     type yang:counter64;
+     default "0";
+     description
+      "The zero-based-counter64 type represents a counter64 that
+       has the defined 'initial' value zero.
+
+       A schema node of this type will be set to zero (0) on creation
+       and will thereafter increase monotonically until it reaches
+       a maximum value of 2^64-1 (18446744073709551615 decimal),
+       when it wraps around and starts increasing again from zero.
+
+       Provided that an application discovers a new schema node
+       of this type within the minimum time to wrap, it can use the
+       'initial' value as a delta.  It is important for a management
+       station to be aware of this minimum time and the actual time
+       between polls, and to discard data if the actual time is too
+       long or there is no defined minimum time.
+
+       In the value set and its semantics, this type is equivalent
+       to the ZeroBasedCounter64 textual convention of the SMIv2.";
+     reference
+      "RFC 2856: Textual Conventions for Additional High Capacity
+                 Data Types";
+   }
+
+   typedef gauge32 {
+     type uint32;
+     description
+      "The gauge32 type represents a non-negative integer, which
+       may increase or decrease, but shall never exceed a maximum
+       value, nor fall below a minimum value.  The maximum value
+       cannot be greater than 2^32-1 (4294967295 decimal), and
+       the minimum value cannot be smaller than 0.  The value of
+       a gauge32 has its maximum value whenever the information
+       being modeled is greater than or equal to its maximum
+       value, and has its minimum value whenever the information
+       being modeled is smaller than or equal to its minimum value.
+       If the information being modeled subsequently decreases
+       below (increases above) the maximum (minimum) value, the
+       gauge32 also decreases (increases).
+
+       In the value set and its semantics, this type is equivalent
+       to the Gauge32 type of the SMIv2.";
+     reference
+      "RFC 2578: Structure of Management Information Version 2 (SMIv2)";
+   }
+
+   typedef gauge64 {
+     type uint64;
+     description
+      "The gauge64 type represents a non-negative integer, which
+       may increase or decrease, but shall never exceed a maximum
+       value, nor fall below a minimum value.  The maximum value
+       cannot be greater than 2^64-1 (18446744073709551615), and
+       the minimum value cannot be smaller than 0.  The value of
+       a gauge64 has its maximum value whenever the information
+       being modeled is greater than or equal to its maximum
+       value, and has its minimum value whenever the information
+       being modeled is smaller than or equal to its minimum value.
+       If the information being modeled subsequently decreases
+       below (increases above) the maximum (minimum) value, the
+       gauge64 also decreases (increases).
+
+       In the value set and its semantics, this type is equivalent
+       to the CounterBasedGauge64 SMIv2 textual convention defined
+       in RFC 2856";
+     reference
+      "RFC 2856: Textual Conventions for Additional High Capacity
+                 Data Types";
+   }
+
+   /*** collection of identifier related types ***/
+
+   typedef object-identifier {
+     type string {
+       pattern '(([0-1](\.[1-3]?[0-9]))|(2\.(0|([1-9]\d*))))'
+             + '(\.(0|([1-9]\d*)))*';
+     }
+     description
+      "The object-identifier type represents administratively
+       assigned names in a registration-hierarchical-name tree.
+
+       Values of this type are denoted as a sequence of numerical
+       non-negative sub-identifier values.  Each sub-identifier
+       value MUST NOT exceed 2^32-1 (4294967295).  Sub-identifiers
+       are separated by single dots and without any intermediate
+       whitespace.
+
+       The ASN.1 standard restricts the value space of the first
+       sub-identifier to 0, 1, or 2.  Furthermore, the value space
+       of the second sub-identifier is restricted to the range
+       0 to 39 if the first sub-identifier is 0 or 1.  Finally,
+       the ASN.1 standard requires that an object identifier
+       has always at least two sub-identifier.  The pattern
+       captures these restrictions.
+
+       Although the number of sub-identifiers is not limited,
+       module designers should realize that there may be
+       implementations that stick with the SMIv2 limit of 128
+       sub-identifiers.
+
+       This type is a superset of the SMIv2 OBJECT IDENTIFIER type
+       since it is not restricted to 128 sub-identifiers.  Hence,
+       this type SHOULD NOT be used to represent the SMIv2 OBJECT
+       IDENTIFIER type, the object-identifier-128 type SHOULD be
+       used instead.";
+     reference
+      "ISO9834-1: Information technology -- Open Systems
+       Interconnection -- Procedures for the operation of OSI
+       Registration Authorities: General procedures and top
+       arcs of the ASN.1 Object Identifier tree";
+   }
+
+
+
+
+   typedef object-identifier-128 {
+     type object-identifier {
+       pattern '\d*(\.\d*){1,127}';
+     }
+     description
+      "This type represents object-identifiers restricted to 128
+       sub-identifiers.
+
+       In the value set and its semantics, this type is equivalent
+       to the OBJECT IDENTIFIER type of the SMIv2.";
+     reference
+      "RFC 2578: Structure of Management Information Version 2 (SMIv2)";
+   }
+
+   /*** collection of date and time related types ***/
+
+   typedef date-and-time {
+     type string {
+       pattern '\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}(\.\d+)?'
+             + '(Z|[\+\-]\d{2}:\d{2})';
+     }
+     description
+      "The date-and-time type is a profile of the ISO 8601
+       standard for representation of dates and times using the
+       Gregorian calendar.  The profile is defined by the
+       date-time production in Section 5.6 of RFC 3339.
+
+       The date-and-time type is compatible with the dateTime XML
+       schema type with the following notable exceptions:
+
+       (a) The date-and-time type does not allow negative years.
+
+       (b) The date-and-time time-offset -00:00 indicates an unknown
+           time zone (see RFC 3339) while -00:00 and +00:00 and Z all
+           represent the same time zone in dateTime.
+
+       (c) The canonical format (see below) of data-and-time values
+           differs from the canonical format used by the dateTime XML
+           schema type, which requires all times to be in UTC using the
+           time-offset 'Z'.
+
+       This type is not equivalent to the DateAndTime textual
+       convention of the SMIv2 since RFC 3339 uses a different
+       separator between full-date and full-time and provides
+       higher resolution of time-secfrac.
+
+       The canonical format for date-and-time values with a known time
+       zone uses a numeric time zone offset that is calculated using
+       the device's configured known offset to UTC time.  A change of
+       the device's offset to UTC time will cause date-and-time values
+       to change accordingly.  Such changes might happen periodically
+       in case a server follows automatically daylight saving time
+       (DST) time zone offset changes.  The canonical format for
+       date-and-time values with an unknown time zone (usually referring
+       to the notion of local time) uses the time-offset -00:00.";
+     reference
+      "RFC 3339: Date and Time on the Internet: Timestamps
+       RFC 2579: Textual Conventions for SMIv2
+       XSD-TYPES: XML Schema Part 2: Datatypes Second Edition";
+   }
+
+   typedef timeticks {
+     type uint32;
+     description
+      "The timeticks type represents a non-negative integer that
+       represents the time, modulo 2^32 (4294967296 decimal), in
+       hundredths of a second between two epochs.  When a schema
+       node is defined that uses this type, the description of
+       the schema node identifies both of the reference epochs.
+
+       In the value set and its semantics, this type is equivalent
+       to the TimeTicks type of the SMIv2.";
+     reference
+      "RFC 2578: Structure of Management Information Version 2 (SMIv2)";
+   }
+
+   typedef timestamp {
+     type yang:timeticks;
+     description
+      "The timestamp type represents the value of an associated
+       timeticks schema node at which a specific occurrence happened.
+       The specific occurrence must be defined in the description
+       of any schema node defined using this type.  When the specific
+       occurrence occurred prior to the last time the associated
+       timeticks attribute was zero, then the timestamp value is
+       zero.  Note that this requires all timestamp values to be
+       reset to zero when the value of the associated timeticks
+       attribute reaches 497+ days and wraps around to zero.
+
+       The associated timeticks schema node must be specified
+       in the description of any schema node using this type.
+
+       In the value set and its semantics, this type is equivalent
+       to the TimeStamp textual convention of the SMIv2.";
+     reference
+      "RFC 2579: Textual Conventions for SMIv2";
+   }
+
+   /*** collection of generic address types ***/
+
+   typedef phys-address {
+     type string {
+       pattern '([0-9a-fA-F]{2}(:[0-9a-fA-F]{2})*)?';
+     }
+     description
+      "Represents media- or physical-level addresses represented
+       as a sequence octets, each octet represented by two hexadecimal
+       numbers.  Octets are separated by colons.  The canonical
+       representation uses lowercase characters.
+
+       In the value set and its semantics, this type is equivalent
+       to the PhysAddress textual convention of the SMIv2.";
+     reference
+      "RFC 2579: Textual Conventions for SMIv2";
+   }
+
+   typedef mac-address {
+     type string {
+       pattern '[0-9a-fA-F]{2}(:[0-9a-fA-F]{2}){5}';
+     }
+     description
+      "The mac-address type represents an IEEE 802 MAC address.
+       The canonical representation uses lowercase characters.
+
+       In the value set and its semantics, this type is equivalent
+       to the MacAddress textual convention of the SMIv2.";
+     reference
+      "IEEE 802: IEEE Standard for Local and Metropolitan Area
+                 Networks: Overview and Architecture
+       RFC 2579: Textual Conventions for SMIv2";
+   }
+
+   /*** collection of XML specific types ***/
+
+   typedef xpath1.0 {
+     type string;
+     description
+      "This type represents an XPATH 1.0 expression.
+
+       When a schema node is defined that uses this type, the
+       description of the schema node MUST specify the XPath
+       context in which the XPath expression is evaluated.";
+     reference
+      "XPATH: XML Path Language (XPath) Version 1.0";
+   }
+
+ }
\ No newline at end of file
index 391c3afb7a16a8020b2737f0fab13d73f00b2a34..677c5e283c537a375e02e058e4ac8bc822845b24 100644 (file)
@@ -87,7 +87,7 @@ abstract class AbstractTypeMemberBuilder implements TypeMemberBuilder {
     @Override
     public void setComment(String comment) {
         if (comment == null) {
-            throw new IllegalArgumentException("Comment string cannot be null!");
+            this.comment = "";
         }
         this.comment = comment;
     }
index b95ac48928b20d410de55ba5093046dd9de08abb..b8f988bff395354d46e7cd4049f434cd400bf070 100644 (file)
@@ -12,22 +12,15 @@ import static org.opendaylight.controller.sal.java.api.generator.Constants.*;
 import java.io.IOException;
 import java.io.StringWriter;
 import java.io.Writer;
-import java.util.LinkedHashMap;
 import java.util.List;
 import java.util.Map;
 
 import org.opendaylight.controller.binding.generator.util.TypeConstants;
-import org.opendaylight.controller.sal.binding.model.api.CodeGenerator;
-import org.opendaylight.controller.sal.binding.model.api.Constant;
-import org.opendaylight.controller.sal.binding.model.api.Enumeration;
-import org.opendaylight.controller.sal.binding.model.api.GeneratedProperty;
-import org.opendaylight.controller.sal.binding.model.api.GeneratedTransferIdentityObject;
-import org.opendaylight.controller.sal.binding.model.api.GeneratedTransferObject;
-import org.opendaylight.controller.sal.binding.model.api.Type;
+import org.opendaylight.controller.sal.binding.model.api.*;
 
 public final class ClassCodeGenerator implements CodeGenerator {
 
-    private Map<String, LinkedHashMap<String, Integer>> imports;
+    private Map<String, String> imports;
 
     @Override
     public Writer generate(Type type) throws IOException {
@@ -93,26 +86,24 @@ public final class ClassCodeGenerator implements CodeGenerator {
                             writer.write(GeneratorUtil.createSetter(field, TAB, imports, currentPkg) + NL);
                         }
                     }
-                }
-                writer.write(NL);
+                    writer.write(NL);
 
-                if (!genTO.getHashCodeIdentifiers().isEmpty()) {
-                    writer.write(GeneratorUtil.createHashCode(genTO.getHashCodeIdentifiers(), TAB) + NL);
-                }
+                    if (!genTO.getHashCodeIdentifiers().isEmpty()) {
+                        writer.write(GeneratorUtil.createHashCode(genTO.getHashCodeIdentifiers(), TAB) + NL);
+                    }
 
-                if (!genTO.getEqualsIdentifiers().isEmpty()) {
-                    writer.write(GeneratorUtil.createEquals(genTO, genTO.getEqualsIdentifiers(), TAB) + NL);
-                }
+                    if (!genTO.getEqualsIdentifiers().isEmpty()) {
+                        writer.write(GeneratorUtil.createEquals(genTO, genTO.getEqualsIdentifiers(), TAB) + NL);
+                    }
 
-                if (!genTO.getToStringIdentifiers().isEmpty()) {
-                    writer.write(GeneratorUtil.createToString(genTO, genTO.getToStringIdentifiers(), TAB) + NL);
+                    if (!genTO.getToStringIdentifiers().isEmpty()) {
+                        writer.write(GeneratorUtil.createToString(genTO, genTO.getToStringIdentifiers(), TAB) + NL);
+                    }
 
+                    writer.write(RCB);
                 }
-
-                writer.write(RCB);
             }
         }
         return writer;
     }
-
 }
index 33d2917339a389c9d411af9e9b5ce5a90bd48796..760365d171ae3fcf017537978c2f915269cd50a6 100644 (file)
@@ -7,7 +7,7 @@
  */
 package org.opendaylight.controller.sal.java.api.generator;
 
-import static org.opendaylight.controller.sal.java.api.generator.Constants.*;
+import static org.opendaylight.controller.sal.java.api.generator.Constants.NL;
 
 import java.io.IOException;
 import java.io.StringWriter;
@@ -19,30 +19,29 @@ import org.opendaylight.controller.sal.binding.model.api.Type;
 
 public class EnumGenerator implements CodeGenerator {
 
-       @Override
-       public Writer generate(Type type) throws IOException {
-               final Writer writer = new StringWriter();
+    @Override
+    public Writer generate(Type type) throws IOException {
+        final Writer writer = new StringWriter();
 
-               if (type instanceof Enumeration) {
-                       Enumeration enums = (Enumeration) type;
-                       writer.write(GeneratorUtil.createPackageDeclaration(enums
-                                       .getPackageName()));
-                       writer.write(NL + NL);
-                       writer.write(GeneratorUtil.createEnum(enums, ""));
-               }
+        if (type instanceof Enumeration) {
+            Enumeration enums = (Enumeration) type;
+            writer.write(GeneratorUtil.createPackageDeclaration(enums.getPackageName()));
+            writer.write(NL + NL);
+            writer.write(GeneratorUtil.createEnum(enums, ""));
+        }
 
-               return writer;
-       }
+        return writer;
+    }
 
-       public Writer generateInnerEnumeration(Type type, String indent) throws IOException {
-               final Writer writer = new StringWriter();
+    public Writer generateInnerEnumeration(Type type, String indent) throws IOException {
+        final Writer writer = new StringWriter();
 
-               if (type instanceof Enumeration) {
-                       Enumeration enums = (Enumeration) type;
-                       writer.write(GeneratorUtil.createEnum(enums, indent));
-               }
+        if (type instanceof Enumeration) {
+            Enumeration enums = (Enumeration) type;
+            writer.write(GeneratorUtil.createEnum(enums, indent));
+        }
 
-               return writer;
-       }
+        return writer;
+    }
 
 }
index ab103b471e8fc076609308078aa1bba98b3f3a11..55b8d777b790522fea9ec27d0919ec3bac36e766 100644 (file)
@@ -7,38 +7,28 @@
  */
 package org.opendaylight.controller.sal.java.api.generator;
 
-import java.io.BufferedWriter;
-import java.io.File;
-import java.io.FileWriter;
-import java.io.IOException;
-import java.io.Writer;
+import java.io.*;
 import java.util.ArrayList;
 import java.util.HashSet;
 import java.util.List;
 import java.util.Set;
 
-import org.opendaylight.controller.sal.binding.model.api.CodeGenerator;
-import org.opendaylight.controller.sal.binding.model.api.Enumeration;
-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.binding.model.api.*;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
 public final class GeneratorJavaFile {
 
-    private static final Logger log = LoggerFactory
-            .getLogger(GeneratorJavaFile.class);
+    private static final Logger log = LoggerFactory.getLogger(GeneratorJavaFile.class);
     private final CodeGenerator interfaceGenerator;
     private final ClassCodeGenerator classGenerator;
     private final EnumGenerator enumGenerator;
-    
+
     private final Set<GeneratedType> genTypes;
     private final Set<GeneratedTransferObject> genTransferObjects;
-    private final Set<Enumeration> enumerations; 
+    private final Set<Enumeration> enumerations;
 
-    public GeneratorJavaFile(final CodeGenerator codeGenerator,
-            final Set<GeneratedType> types) {
+    public GeneratorJavaFile(final CodeGenerator codeGenerator, final Set<GeneratedType> types) {
         this.interfaceGenerator = codeGenerator;
         this.genTypes = types;
         this.genTransferObjects = new HashSet<>();
@@ -47,13 +37,12 @@ public final class GeneratorJavaFile {
         this.enumGenerator = new EnumGenerator();
     }
 
-    public GeneratorJavaFile(final Set<GeneratedType> types,
-            final Set<GeneratedTransferObject> genTransferObjects,
+    public GeneratorJavaFile(final Set<GeneratedType> types, final Set<GeneratedTransferObject> genTransferObjects,
             final Set<Enumeration> enumerations) {
         this.interfaceGenerator = new InterfaceGenerator();
         this.classGenerator = new ClassCodeGenerator();
         this.enumGenerator = new EnumGenerator();
-        
+
         this.genTypes = types;
         this.genTransferObjects = genTransferObjects;
         this.enumerations = enumerations;
@@ -62,52 +51,46 @@ public final class GeneratorJavaFile {
     public List<File> generateToFile(final File parentDirectory) throws IOException {
         final List<File> result = new ArrayList<>();
         for (GeneratedType type : genTypes) {
-            final File genFile = generateTypeToJavaFile(parentDirectory, type,
-                    interfaceGenerator);
+            final File genFile = generateTypeToJavaFile(parentDirectory, type, interfaceGenerator);
 
             if (genFile != null) {
                 result.add(genFile);
             }
         }
         for (GeneratedTransferObject transferObject : genTransferObjects) {
-            final File genFile = generateTypeToJavaFile(parentDirectory,
-                    transferObject, classGenerator);
+            final File genFile = generateTypeToJavaFile(parentDirectory, transferObject, classGenerator);
 
             if (genFile != null) {
                 result.add(genFile);
             }
         }
-        
+
         for (Enumeration enumeration : enumerations) {
-            final File genFile = generateTypeToJavaFile(parentDirectory,
-                    enumeration, enumGenerator);
+            final File genFile = generateTypeToJavaFile(parentDirectory, enumeration, enumGenerator);
 
             if (genFile != null) {
                 result.add(genFile);
             }
         }
-        
+
         return result;
     }
 
-    private File generateTypeToJavaFile(final File parentDir, final Type type,
-            final CodeGenerator generator) throws IOException {
+    private File generateTypeToJavaFile(final File parentDir, final Type type, final CodeGenerator generator)
+            throws IOException {
         if (parentDir == null) {
             log.warn("Parent Directory not specified, files will be generated "
                     + "accordingly to generated Type package path.");
         }
         if (type == null) {
-            log.error("Cannot generate Type into Java File because " +
-                       "Generated Type is NULL!");
+            log.error("Cannot generate Type into Java File because " + "Generated Type is NULL!");
             throw new IllegalArgumentException("Generated Type Cannot be NULL!");
         }
         if (generator == null) {
-            log.error("Cannot generate Type into Java File because " +
-                       "Code Generator instance is NULL!");
+            log.error("Cannot generate Type into Java File because " + "Code Generator instance is NULL!");
             throw new IllegalArgumentException("Code Generator Cannot be NULL!");
         }
-        final File packageDir = packageToDirectory(parentDir,
-                type.getPackageName());
+        final File packageDir = packageToDirectory(parentDir, type.getPackageName());
 
         if (!packageDir.exists()) {
             packageDir.mkdirs();
@@ -127,8 +110,7 @@ public final class GeneratorJavaFile {
         return file;
     }
 
-    private File packageToDirectory(final File parentDirectory,
-            final String packageName) {
+    private File packageToDirectory(final File parentDirectory, final String packageName) {
         if (packageName == null) {
             throw new IllegalArgumentException("Package Name cannot be NULL!");
         }
index 16074c7e98ba0b1fac549c2c1fa6c42c67abe71c..ec908560e4108ced2b832b57887b1afce26d91bf 100644 (file)
@@ -10,25 +10,15 @@ package org.opendaylight.controller.sal.java.api.generator;
 import static org.opendaylight.controller.sal.java.api.generator.Constants.*;
 
 import java.util.ArrayList;
-import java.util.HashMap;
 import java.util.LinkedHashMap;
 import java.util.List;
 import java.util.Map;
 
 import org.opendaylight.controller.binding.generator.util.TypeConstants;
+import org.opendaylight.controller.sal.binding.model.api.*;
 import org.opendaylight.controller.binding.generator.util.Types;
-import org.opendaylight.controller.sal.binding.model.api.AnnotationType;
-import org.opendaylight.controller.sal.binding.model.api.Constant;
-import org.opendaylight.controller.sal.binding.model.api.Enumeration;
 import org.opendaylight.controller.sal.binding.model.api.Enumeration.Pair;
-import org.opendaylight.controller.sal.binding.model.api.GeneratedProperty;
-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.MethodSignature;
 import org.opendaylight.controller.sal.binding.model.api.MethodSignature.Parameter;
-import org.opendaylight.controller.sal.binding.model.api.ParameterizedType;
-import org.opendaylight.controller.sal.binding.model.api.Type;
-import org.opendaylight.controller.sal.binding.model.api.WildcardType;
 
 public final class GeneratorUtil {
 
@@ -36,12 +26,12 @@ public final class GeneratorUtil {
     }
 
     public static String createIfcDeclaration(final GeneratedType genType, final String indent,
-            final Map<String, LinkedHashMap<String, Integer>> availableImports) {
+            final Map<String, String> availableImports) {
         return createFileDeclaration(IFC, genType, indent, availableImports, false);
     }
 
     public static String createClassDeclaration(final GeneratedTransferObject genTransferObject, final String indent,
-            final Map<String, LinkedHashMap<String, Integer>> availableImports, boolean isIdentity) {
+            final Map<String, String> availableImports, boolean isIdentity) {
         return createFileDeclaration(CLASS, genTransferObject, indent, availableImports, isIdentity);
     }
 
@@ -50,7 +40,7 @@ public final class GeneratorUtil {
     }
 
     private static String createFileDeclaration(final String type, final GeneratedType genType, final String indent,
-            final Map<String, LinkedHashMap<String, Integer>> availableImports, boolean isIdentity) {
+            final Map<String, String> availableImports, boolean isIdentity) {
         final StringBuilder builder = new StringBuilder();
         final String currentPkg = genType.getPackageName();
 
@@ -95,7 +85,6 @@ public final class GeneratorUtil {
                 builder.append(getExplicitType(genImplements.get(i), availableImports, currentPkg));
             }
         }
-
         builder.append(GAP + LCB);
         return builder.toString();
     }
@@ -153,7 +142,7 @@ public final class GeneratorUtil {
     }
 
     public static String createConstant(final Constant constant, final String indent,
-            final Map<String, LinkedHashMap<String, Integer>> availableImports, final String currentPkg) {
+            final Map<String, String> availableImports, final String currentPkg) {
         final StringBuilder builder = new StringBuilder();
         if (constant == null)
             throw new IllegalArgumentException();
@@ -189,7 +178,7 @@ public final class GeneratorUtil {
     }
 
     public static String createField(final GeneratedProperty property, final String indent,
-            Map<String, LinkedHashMap<String, Integer>> availableImports, final String currentPkg) {
+            final Map<String, String> availableImports, final String currentPkg) {
         final StringBuilder builder = new StringBuilder();
         if (!property.getAnnotations().isEmpty()) {
             final List<AnnotationType> annotations = property.getAnnotations();
@@ -211,7 +200,7 @@ public final class GeneratorUtil {
      * @return
      */
     public static String createMethodDeclaration(final MethodSignature method, final String indent,
-            Map<String, LinkedHashMap<String, Integer>> availableImports, final String currentPkg) {
+            Map<String, String> availableImports, final String currentPkg) {
         final StringBuilder builder = new StringBuilder();
 
         if (method == null) {
@@ -258,7 +247,7 @@ public final class GeneratorUtil {
     }
 
     public static String createConstructor(GeneratedTransferObject genTransferObject, final String indent,
-            Map<String, LinkedHashMap<String, Integer>> availableImports, boolean isIdentity) {
+            final Map<String, String> availableImports, boolean isIdentity) {
         final StringBuilder builder = new StringBuilder();
 
         final String currentPkg = genTransferObject.getPackageName();
@@ -333,7 +322,7 @@ public final class GeneratorUtil {
     }
 
     public static String createGetter(final GeneratedProperty property, final String indent,
-            Map<String, LinkedHashMap<String, Integer>> availableImports, final String currentPkg) {
+            final Map<String, String> availableImports, final String currentPkg) {
         final StringBuilder builder = new StringBuilder();
 
         final Type type = property.getReturnType();
@@ -353,7 +342,7 @@ public final class GeneratorUtil {
     }
 
     public static String createSetter(final GeneratedProperty property, final String indent,
-            Map<String, LinkedHashMap<String, Integer>> availableImports, String currentPkg) {
+            final Map<String, String> availableImports, final String currentPkg) {
         final StringBuilder builder = new StringBuilder();
 
         final Type type = property.getReturnType();
@@ -388,7 +377,7 @@ public final class GeneratorUtil {
 
     public static String createEquals(final GeneratedTransferObject type, final List<GeneratedProperty> properties,
             final String indent) {
-        StringBuilder builder = new StringBuilder();
+        final StringBuilder builder = new StringBuilder();
         final String indent1 = indent + TAB;
         final String indent2 = indent1 + TAB;
         final String indent3 = indent2 + TAB;
@@ -407,7 +396,7 @@ public final class GeneratorUtil {
         String typeStr = type.getName();
         builder.append(indent1 + typeStr + " other = (" + typeStr + ") obj;" + NL);
 
-        for (GeneratedProperty property : properties) {
+        for (final GeneratedProperty property : properties) {
             String fieldName = property.getName();
             builder.append(indent1 + "if (" + fieldName + " == null) {" + NL);
             builder.append(indent2 + "if (other." + fieldName + " != null) {" + NL);
@@ -419,7 +408,6 @@ public final class GeneratorUtil {
         }
 
         builder.append(indent1 + "return true;" + NL);
-
         builder.append(indent + RCB + NL);
         return builder.toString();
     }
@@ -441,7 +429,7 @@ public final class GeneratorUtil {
         builder.append(" [");
 
         boolean first = true;
-        for (GeneratedProperty property : properties) {
+        for (final GeneratedProperty property : properties) {
             if (first) {
                 builder.append(property.getName());
                 builder.append("=\");");
@@ -514,22 +502,30 @@ public final class GeneratorUtil {
         return builder.toString();
     }
 
-    private static String getExplicitType(final Type type,
-            Map<String, LinkedHashMap<String, Integer>> availableImports, final String currentPkg) {
+    private static String getExplicitType(final Type type, final Map<String, String> imports, final String currentPkg) {
         if (type == null) {
             throw new IllegalArgumentException("Type parameter MUST be specified and cannot be NULL!");
         }
-        String packageName = type.getPackageName();
-
-        LinkedHashMap<String, Integer> imports = availableImports.get(type.getName());
+        if (type.getName() == null) {
+            throw new IllegalArgumentException("Type name cannot be NULL!");
+        }
+        if (type.getPackageName() == null) {
+            throw new IllegalArgumentException("Type cannot have Package Name referenced as NULL!");
+        }
+        if (imports == null) {
+            throw new IllegalArgumentException("Imports Map cannot be NULL!");
+        }
 
-        if ((imports != null && packageName.equals(findMaxValue(imports).get(0))) || packageName.equals(currentPkg)) {
+        final String typePackageName = type.getPackageName();
+        final String typeName = type.getName();
+        final String importedPackageName = imports.get(typeName);
+        if (typePackageName.equals(importedPackageName) || typePackageName.equals(currentPkg)) {
             final StringBuilder builder = new StringBuilder(type.getName());
             if (type instanceof ParameterizedType) {
-                ParameterizedType pType = (ParameterizedType) type;
-                Type[] pTypes = pType.getActualTypeArguments();
+                final ParameterizedType pType = (ParameterizedType) type;
+                final Type[] pTypes = pType.getActualTypeArguments();
                 builder.append("<");
-                builder.append(getParameters(pTypes, availableImports, currentPkg));
+                builder.append(getParameters(pTypes, imports, currentPkg));
                 builder.append(">");
             }
             if (builder.toString().equals("Void")) {
@@ -538,21 +534,20 @@ public final class GeneratorUtil {
             return builder.toString();
         } else {
             final StringBuilder builder = new StringBuilder();
-            if (packageName.startsWith("java.lang")) {
+            if (typePackageName.startsWith("java.lang")) {
                 builder.append(type.getName());
             } else {
-                if (!packageName.isEmpty()) {
-                    builder.append(packageName + "." + type.getName());
+                if (!typePackageName.isEmpty()) {
+                    builder.append(typePackageName + "." + type.getName());
                 } else {
                     builder.append(type.getName());
                 }
-
             }
             if (type instanceof ParameterizedType) {
-                ParameterizedType pType = (ParameterizedType) type;
-                Type[] pTypes = pType.getActualTypeArguments();
+                final ParameterizedType pType = (ParameterizedType) type;
+                final Type[] pTypes = pType.getActualTypeArguments();
                 builder.append("<");
-                builder.append(getParameters(pTypes, availableImports, currentPkg));
+                builder.append(getParameters(pTypes, imports, currentPkg));
                 builder.append(">");
             }
             if (builder.toString().equals("Void")) {
@@ -562,14 +557,13 @@ public final class GeneratorUtil {
         }
     }
 
-    private static String getParameters(final Type[] pTypes,
-            Map<String, LinkedHashMap<String, Integer>> availableImports, String currentPkg) {
+    private static String getParameters(final Type[] pTypes, Map<String, String> availableImports, String currentPkg) {
         final StringBuilder builder = new StringBuilder();
         for (int i = 0; i < pTypes.length; i++) {
-            Type t = pTypes[i];
+            final Type t = pTypes[i];
 
             String separator = COMMA;
-            if (i + 1 == pTypes.length) {
+            if (i == (pTypes.length - 1)) {
                 separator = "";
             }
 
@@ -577,30 +571,11 @@ public final class GeneratorUtil {
             if (t instanceof WildcardType) {
                 wildcardParam = "? extends ";
             }
-
             builder.append(wildcardParam + getExplicitType(t, availableImports, currentPkg) + separator);
         }
         return builder.toString();
     }
 
-    private static List<String> findMaxValue(LinkedHashMap<String, Integer> imports) {
-        final List<String> result = new ArrayList<String>();
-
-        int maxValue = 0;
-        int currentValue = 0;
-        for (Map.Entry<String, Integer> entry : imports.entrySet()) {
-            currentValue = entry.getValue();
-            if (currentValue > maxValue) {
-                result.clear();
-                result.add(entry.getKey());
-                maxValue = currentValue;
-            } else if (currentValue == maxValue) {
-                result.add(entry.getKey());
-            }
-        }
-        return result;
-    }
-
     private static void createComment(final StringBuilder builder, final String comment, final String indent) {
         if (comment != null && comment.length() > 0) {
             builder.append(indent + "/*" + NL);
@@ -609,104 +584,115 @@ public final class GeneratorUtil {
         }
     }
 
-    public static Map<String, LinkedHashMap<String, Integer>> createImports(GeneratedType genType) {
-        final Map<String, LinkedHashMap<String, Integer>> imports = new HashMap<String, LinkedHashMap<String, Integer>>();
-        final String genTypePkg = genType.getPackageName();
+    public static Map<String, String> createImports(final GeneratedType genType) {
+        if (genType == null) {
+            throw new IllegalArgumentException("Generated Type cannot be NULL!");
+        }
 
+        final Map<String, String> imports = new LinkedHashMap<>();
         final List<Constant> constants = genType.getConstantDefinitions();
         final List<MethodSignature> methods = genType.getMethodDefinitions();
-        List<Type> impl = genType.getImplements();
+        final List<Type> impl = genType.getImplements();
 
         // IMPLEMENTATIONS
         if (impl != null) {
-            for (Type t : impl) {
-                addTypeToImports(t, imports, genTypePkg);
+            for (final Type type : impl) {
+                putTypeIntoImports(genType, type, imports);
             }
         }
 
         // CONSTANTS
         if (constants != null) {
-            for (Constant c : constants) {
-                Type ct = c.getType();
-                addTypeToImports(ct, imports, genTypePkg);
+            for (final Constant constant : constants) {
+                final Type constantType = constant.getType();
+                putTypeIntoImports(genType, constantType, imports);
+            }
+        }
+
+        // REGULAR EXPRESSION
+        if (genType instanceof GeneratedTransferObject) {
+            if (isConstantInTO(TypeConstants.PATTERN_CONSTANT_NAME, (GeneratedTransferObject) genType)) {
+                putTypeIntoImports(genType, Types.typeForClass(java.util.regex.Pattern.class), imports);
+                putTypeIntoImports(genType, Types.typeForClass(java.util.Arrays.class), imports);
+                putTypeIntoImports(genType, Types.typeForClass(java.util.ArrayList.class), imports);
             }
         }
 
         // METHODS
         if (methods != null) {
-            for (MethodSignature m : methods) {
-                Type ct = m.getReturnType();
-                addTypeToImports(ct, imports, genTypePkg);
-                for (MethodSignature.Parameter p : m.getParameters()) {
-                    addTypeToImports(p.getType(), imports, genTypePkg);
+            for (final MethodSignature method : methods) {
+                final Type methodReturnType = method.getReturnType();
+                putTypeIntoImports(genType, methodReturnType, imports);
+                for (final MethodSignature.Parameter methodParam : method.getParameters()) {
+                    putTypeIntoImports(genType, methodParam.getType(), imports);
                 }
             }
         }
 
         // PROPERTIES
         if (genType instanceof GeneratedTransferObject) {
-            GeneratedTransferObject genTO = (GeneratedTransferObject) genType;
-
-            List<GeneratedProperty> props = genTO.getProperties();
-            if (props != null) {
-                for (GeneratedProperty prop : props) {
-                    Type pt = prop.getReturnType();
-                    addTypeToImports(pt, imports, genTypePkg);
+            final GeneratedTransferObject genTO = (GeneratedTransferObject) genType;
+            final List<GeneratedProperty> properties = genTO.getProperties();
+            if (properties != null) {
+                for (GeneratedProperty property : properties) {
+                    final Type propertyType = property.getReturnType();
+                    putTypeIntoImports(genType, propertyType, imports);
                 }
             }
         }
 
-        // REGULAR EXPRESSION
-        if (genType instanceof GeneratedTransferObject) {
-            if (isConstantInTO(TypeConstants.PATTERN_CONSTANT_NAME, (GeneratedTransferObject) genType)) {
-                addTypeToImports(Types.typeForClass(java.util.regex.Pattern.class), imports, genTypePkg);
-                addTypeToImports(Types.typeForClass(java.util.Arrays.class), imports, genTypePkg);
-                addTypeToImports(Types.typeForClass(java.util.ArrayList.class), imports, genTypePkg);
-            }
-        }
-
         return imports;
     }
 
-    private static void addTypeToImports(Type type, Map<String, LinkedHashMap<String, Integer>> importedTypes,
-            String genTypePkg) {
-        String typeName = type.getName();
-        String typePkg = type.getPackageName();
-        if (typePkg.startsWith("java.lang") || typePkg.equals(genTypePkg) || typePkg.isEmpty()) {
-            return;
+    private static void putTypeIntoImports(final GeneratedType parentGenType, final Type type,
+            final Map<String, String> imports) {
+        if (parentGenType == null) {
+            throw new IllegalArgumentException("Parent Generated Type parameter MUST be specified and cannot be "
+                    + "NULL!");
         }
-        LinkedHashMap<String, Integer> packages = importedTypes.get(typeName);
-        if (packages == null) {
-            packages = new LinkedHashMap<String, Integer>();
-            packages.put(typePkg, 1);
-            importedTypes.put(typeName, packages);
-        } else {
-            Integer occurrence = packages.get(typePkg);
-            if (occurrence == null) {
-                packages.put(typePkg, 1);
-            } else {
-                occurrence++;
-                packages.put(typePkg, occurrence);
-            }
+        if (parentGenType.getName() == null) {
+            throw new IllegalArgumentException("Parent Generated Type name cannot be NULL!");
+        }
+        if (parentGenType.getPackageName() == null) {
+            throw new IllegalArgumentException("Parent Generated Type cannot have Package Name referenced as NULL!");
+        }
+        if (type == null) {
+            throw new IllegalArgumentException("Type parameter MUST be specified and cannot be NULL!");
+        }
+        if (type.getName() == null) {
+            throw new IllegalArgumentException("Type name cannot be NULL!");
+        }
+        if (type.getPackageName() == null) {
+            throw new IllegalArgumentException("Type cannot have Package Name referenced as NULL!");
         }
 
+        final String typeName = type.getName();
+        final String typePackageName = type.getPackageName();
+        final String parentTypeName = parentGenType.getName();
+        final String parentTypePackageName = parentGenType.getPackageName();
+        if (typeName.equals(parentTypeName) || typePackageName.startsWith("java.lang")
+                || typePackageName.equals(parentTypePackageName) || typePackageName.isEmpty()) {
+            return;
+        }
+        if (!imports.containsKey(typeName)) {
+            imports.put(typeName, typePackageName);
+        }
         if (type instanceof ParameterizedType) {
-            ParameterizedType pt = (ParameterizedType) type;
-            Type[] params = pt.getActualTypeArguments();
+            final ParameterizedType paramType = (ParameterizedType) type;
+            final Type[] params = paramType.getActualTypeArguments();
             for (Type param : params) {
-                addTypeToImports(param, importedTypes, genTypePkg);
+                putTypeIntoImports(parentGenType, param, imports);
             }
         }
     }
 
-    public static List<String> createImportLines(Map<String, LinkedHashMap<String, Integer>> imports) {
-        List<String> importLines = new ArrayList<String>();
+    public static List<String> createImportLines(final Map<String, String> imports) {
+        final List<String> importLines = new ArrayList<>();
 
-        for (Map.Entry<String, LinkedHashMap<String, Integer>> entry : imports.entrySet()) {
-            String typeName = entry.getKey();
-            LinkedHashMap<String, Integer> typePkgMap = entry.getValue();
-            String typePkg = typePkgMap.keySet().iterator().next();
-            importLines.add("import " + typePkg + "." + typeName + SC);
+        for (Map.Entry<String, String> entry : imports.entrySet()) {
+            final String typeName = entry.getKey();
+            final String packageName = entry.getValue();
+            importLines.add("import " + packageName + "." + typeName + SC);
         }
         return importLines;
     }
@@ -723,5 +709,4 @@ public final class GeneratorUtil {
         }
         return false;
     }
-
 }
index 16d63efe1b527fe48d7da11cb468ab4bda54da7d..fe0b24f890711969f4a6c446597919101caa2581 100644 (file)
@@ -12,97 +12,81 @@ import static org.opendaylight.controller.sal.java.api.generator.Constants.*;
 import java.io.IOException;
 import java.io.StringWriter;
 import java.io.Writer;
-import java.util.LinkedHashMap;
 import java.util.List;
 import java.util.Map;
 
-import org.opendaylight.controller.sal.binding.model.api.CodeGenerator;
-import org.opendaylight.controller.sal.binding.model.api.Constant;
-import org.opendaylight.controller.sal.binding.model.api.Enumeration;
-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.MethodSignature;
-import org.opendaylight.controller.sal.binding.model.api.Type;
+import org.opendaylight.controller.sal.binding.model.api.*;
 
 public final class InterfaceGenerator implements CodeGenerator {
 
-       private Map<String, LinkedHashMap<String, Integer>> imports;
+    private Map<String, String> imports;
 
-       private String generateEnums(List<Enumeration> enums) {
-               String result = "";
-               if (enums != null) {
-                       EnumGenerator enumGenerator = new EnumGenerator();
-                       for (Enumeration en : enums) {
-                               try {
-                                       result = result
-                                                       + (enumGenerator.generateInnerEnumeration(en, TAB).toString() + NL);
-                               } catch (IOException e) {
-                                       e.printStackTrace();
-                               }
-                       }
-               }
-               return result;
-       }
+    private String generateEnums(List<Enumeration> enums) {
+        String result = "";
+        if (enums != null) {
+            EnumGenerator enumGenerator = new EnumGenerator();
+            for (Enumeration en : enums) {
+                try {
+                    result = result + (enumGenerator.generateInnerEnumeration(en, TAB).toString() + NL);
+                } catch (IOException e) {
+                    e.printStackTrace();
+                }
+            }
+        }
+        return result;
+    }
 
-       private String generateConstants(List<Constant> constants, String pkgName) {
-               String result = "";
-               if (constants != null) {
-                       for (Constant c : constants) {
-                               result = result
-                                               + GeneratorUtil
-                                                               .createConstant(c, TAB, imports, pkgName) + NL;
-                       }
-                       result.concat(NL);
-               }
-               return result;
-       }
+    private String generateConstants(List<Constant> constants, String pkgName) {
+        String result = "";
+        if (constants != null) {
+            for (Constant c : constants) {
+                result = result + GeneratorUtil.createConstant(c, TAB, imports, pkgName) + NL;
+            }
+            result.concat(NL);
+        }
+        return result;
+    }
 
-       public String generateMethods(List<MethodSignature> methods, String pkgName) {
-               String result = "";
+    public String generateMethods(List<MethodSignature> methods, String pkgName) {
+        String result = "";
 
-               if (methods != null) {
-                       for (MethodSignature m : methods) {
-                               result = result
-                                               + GeneratorUtil.createMethodDeclaration(m, TAB,
-                                                               imports, pkgName) + NL;
-                       }
-                       result = result + NL;
-               }
-               return result;
-       }
+        if (methods != null) {
+            for (MethodSignature m : methods) {
+                result = result + GeneratorUtil.createMethodDeclaration(m, TAB, imports, pkgName) + NL;
+            }
+            result = result + NL;
+        }
+        return result;
+    }
 
-       public Writer generate(Type type) throws IOException {
-               Writer writer = new StringWriter();
-               if (type instanceof GeneratedType
-                               && !(type instanceof GeneratedTransferObject)) {
-                       GeneratedType genType = (GeneratedType) type;
-                       imports = GeneratorUtil.createImports(genType);
+    public Writer generate(Type type) throws IOException {
+        Writer writer = new StringWriter();
+        if (type instanceof GeneratedType && !(type instanceof GeneratedTransferObject)) {
+            final GeneratedType genType = (GeneratedType) type;
+            imports = GeneratorUtil.createImports(genType);
 
-                       final String currentPkg = genType.getPackageName();
-                       final List<Constant> constants = genType.getConstantDefinitions();
-                       final List<MethodSignature> methods = genType
-                                       .getMethodDefinitions();
-                       final List<Enumeration> enums = genType.getEnumerations();
+            final String currentPkg = genType.getPackageName();
+            final List<Constant> constants = genType.getConstantDefinitions();
+            final List<MethodSignature> methods = genType.getMethodDefinitions();
+            final List<Enumeration> enums = genType.getEnumerations();
 
-                       writer.write(GeneratorUtil.createPackageDeclaration(genType
-                                       .getPackageName()));
-                       writer.write(NL);
+            writer.write(GeneratorUtil.createPackageDeclaration(genType.getPackageName()));
+            writer.write(NL);
 
-                       List<String> importLines = GeneratorUtil.createImportLines(imports);
-                       for (String line : importLines) {
-                               writer.write(line + NL);
-                       }
-                       writer.write(NL);
-                       writer.write(GeneratorUtil.createIfcDeclaration(genType, "",
-                                       imports));
-                       writer.write(NL);
+            final List<String> importLines = GeneratorUtil.createImportLines(imports);
+            for (String line : importLines) {
+                writer.write(line + NL);
+            }
+            writer.write(NL);
+            writer.write(GeneratorUtil.createIfcDeclaration(genType, "", imports));
+            writer.write(NL);
 
-                       writer.write(generateEnums(enums));
-                       writer.write(generateConstants(constants, currentPkg));
-                       writer.write(generateMethods(methods, currentPkg));
+            writer.write(generateEnums(enums));
+            writer.write(generateConstants(constants, currentPkg));
+            writer.write(generateMethods(methods, currentPkg));
 
-                       writer.write(RCB);
-               }
-               return writer;
-       }
+            writer.write(RCB);
+        }
+        return writer;
+    }
 }
index 41102aed44dd4503c04762ea568e5d75ce4dbb81..8b576c3ce96a43d29480acb1cfe6f7a810666b4e 100644 (file)
@@ -1,54 +1,54 @@
 module controller-openflow-ne {
-       yang-version 1;
-       namespace "urn:opendaylight:controller:network:openflow";
-       prefix "of";
-       
-       import controller-network {
-               prefix cn;
-       }
-       import ietf-inet-types { prefix "inet"; }
-       
-       revision 2013-06-07 {
-          description "Initial demo";
-       }
+    yang-version 1;
+    namespace "urn:opendaylight:controller:network:openflow";
+    prefix "of";
+    
+    import controller-network {
+        prefix cn;
+    }
+    import ietf-inet-types { prefix "inet"; }
+    
+    revision 2013-06-07 {
+       description "Initial demo";
+    }
 
-       augment "/cn:network/cn:network-elements/cn:network-element" {
+    augment "/cn:network/cn:network-elements/cn:network-element" {
 
-               container flow-tables {
-                       list flow-table {
+        container flow-tables {
+            list flow-table {
 
-                               key "id";
-                               leaf id {
-                                       type int32;
-                               }
+                key "id";
+                leaf id {
+                    type int32;
+                }
 
-                               container flows {
-                                       list flow {
-                                               key "name";
-                                               leaf name {
-                                                       type string;
-                                               }
-                                               container match {
-                                                       leaf input-port {
-                                                               type cn:tp-ref;
-                                                       }
-                                                       leaf nl-src {
-                                                               type inet:ipv4-address;
-                                                       }
-                                                       leaf nl-dst {
-                                                               type inet:ipv4-address;
-                                                       }
-                                               }
-                                               container actions {
-                                                       list action {
-                                                               leaf type {
-                                                                       type string;
-                                                               }
-                                                       }
-                                               }
-                                       }
-                               }
-                       }
-               }
-       }
+                container flows {
+                    list flow {
+                        key "name";
+                        leaf name {
+                            type string;
+                        }
+                        container match {
+                            leaf input-port {
+                                type cn:tp-ref;
+                            }
+                            leaf nl-src {
+                                type inet:ipv4-address;
+                            }
+                            leaf nl-dst {
+                                type inet:ipv4-address;
+                            }
+                        }
+                        container actions {
+                            list action {
+                                leaf type {
+                                    type string;
+                                }
+                            }
+                        }
+                    }
+                }
+            }
+        }
+    }
 }
\ No newline at end of file
index 600e87d2679c8e2ad0cf3e2eb2481327631f21ca..ce0b6b08241f3444292e774839c5428defeac1c9 100644 (file)
 module controller-network {
-       yang-version 1;
-       namespace "urn:opendaylight:controller:network";
-       prefix "topos";
-       
-       import ietf-inet-types { prefix "inet"; }
-       
-       revision 2013-05-20 {
-          description "Initial demo";
-       }
-       
+    yang-version 1;
+    namespace "urn:opendaylight:controller:network";
+    prefix "topos";
+    
+    import ietf-inet-types { prefix "inet"; }
+    
+    revision 2013-05-20 {
+       description "Initial demo";
+    }
 
-       
-       typedef topology-id {
-               type string;
-       }
+    typedef topology-id {
+        type string;
+    }
 
-       typedef node-id {
-               type string;
-       }
+    typedef node-id {
+        type string;
+    }
 
-       typedef link-id {
-               type string;
-       }
+    typedef link-id {
+        type string;
+    }
 
-       typedef tp-id {
-               type string;
-               description "identifier for termination points on a port";
-       }
+    typedef tp-id {
+        type string;
+        description "identifier for termination points on a port";
+    }
 
-       typedef tp-ref {
-               type leafref {
-                       path "/network/topologies/topology/nodes/node/termination-points/termination-point/tp-id";
-               }
-       }
-       typedef topology-ref {
-               type leafref {
-                       path "/network/topologies/topology/topology-id";
-               }
-               description "This type is used for leafs that reference topology identifier instance.";
-               // currently not used
-       }
+    typedef tp-ref {
+        type leafref {
+            path "/network/topologies/topology/nodes/node/termination-points/termination-point/tp-id";
+        }
+    }
+    typedef topology-ref {
+        type leafref {
+            path "/network/topologies/topology/topology-id";
+        }
+        description "This type is used for leafs that reference topology identifier instance.";
+        // currently not used
+    }
 
-       typedef node-ref {
-               type leafref {
-                       path "/network/topologies/topology/nodes/node/node-id";
-               }
-               description "This type is used for leafs that reference a node instance.";
-       }
+    typedef node-ref {
+        type leafref {
+            path "/network/topologies/topology/nodes/node/node-id";
+        }
+        description "This type is used for leafs that reference a node instance.";
+    }
 
-       typedef link-ref {
-               type leafref {
-                       path "/network/topologies/topology/links/link/link-id";
-               }
-               description "This type is used for leafs that reference a link instance.";
-               // currently not used
-       }
-       
-       typedef network-element-ref {
-               type leafref {
-                       path "/network/network-elements/network-element/element-id";
-               }
-       }
+    typedef link-ref {
+        type leafref {
+            path "/network/topologies/topology/links/link/link-id";
+        }
+        description "This type is used for leafs that reference a link instance.";
+        // currently not used
+    }
+    
+    typedef network-element-ref {
+        type leafref {
+            path "/network/network-elements/network-element/element-id";
+        }
+    }
 
+    typedef element-id {
+        type string;
+    }
+    
+    container network {
+        container topologies {
+            list topology {
+                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.
+                ";
+                key "topology-id";
+                leaf topology-id {
+                    type topology-id; 
+                    description "
+                        It is presumed that datastore will contain many topologies. To
+                        distinguish between topologies it is vital to have UNIQUE
+                        topology identifier.
+                    ";
+                }
 
-       typedef element-id {
-               type string;
-       }
-       
-       container network {
-               container topologies {
-                       list topology {
-                               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.
-                               ";
-                               key "topology-id";
-                               leaf topology-id {
-                                       type topology-id; 
-                                       description "
-                                               It is presumed that datastore will contain many topologies. To
-                                               distinguish between topologies it is vital to have UNIQUE
-                                               topology identifier.
-                                       ";
-                               }
+                container types {
+                    description "
+                        The container for definition of topology types.
+                        The augmenting modules should add empty optional leaf 
+                        to this container to signalize topology type.";
+                }
 
-                               container types {
-                                       description "
-                                               The container for definition of topology types.
-                                               The augmenting modules should add empty optional leaf 
-                                               to this container to signalize topology type.
-                                       ";
-                               }
+                container nodes {
+                    list node {
+                        description "The list of network nodes defined for topology.";
 
-                               container nodes {
-                                       list node {
-                                               description "The list of network nodes defined for topology.";
+                        key "node-id";
+                        leaf node-id {
+                            type node-id;
+                            description "The Topology identifier of network-node.";
+                        }
 
-                                               key "node-id";
-                                               leaf node-id {
-                                                       type node-id;
-                                                       description "The Topology identifier of network-node.";
-                                               }
-
-                                               leaf supporting-ne {
-                                                       type network-element-ref;
-                                               }
-                                               
-                                               container termination-points {
-                                                       list termination-point {
-                                                               key "tp-id";
-                                                               leaf tp-id {
-                                                                       type tp-id;
-                                                               }
-                                                       }
-                                               }
-                                       }
-                               }
-               
-                               container links {
-                                       list 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 link-id;
-                                               }
-                                               container source { 
-                                                       leaf source-node {
-                                                               type node-ref;
-                                                               description "Source node identifier.";
-                                                       }
-                                                       leaf source-tp {
-                                                               type tp-ref;
-                                                       }
-                                               }
-                                               container destination { 
-                                                       leaf dest-node {
-                                                               type node-ref;
-                                                               description "Destination node identifier.";
-                                                       }
-                                                       leaf dest-tp {
-                                                               type tp-ref;
-                                                       }
-                                               }
-                                       }
-                               }
-                       }
-               }
-               container network-elements {
-                       config true;
-                       list network-element {
-                               key "element-id";
-                               leaf element-id {
-                                       type element-id;
-                               }
-                       }
-               }
-       }
+                        leaf supporting-ne {
+                            type network-element-ref;
+                        }
+                        
+                        container termination-points {
+                            list termination-point {
+                                key "tp-id";
+                                leaf tp-id {
+                                    type tp-id;
+                                }
+                            }
+                        }
+                    }
+                }
+        
+                container links {
+                    list 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 link-id;
+                        }
+                        container source { 
+                            leaf source-node {
+                                type node-ref;
+                                description "Source node identifier.";
+                            }
+                            leaf source-tp {
+                                type tp-ref;
+                            }
+                        }
+                        container destination { 
+                            leaf dest-node {
+                                type node-ref;
+                                description "Destination node identifier.";
+                            }
+                            leaf dest-tp {
+                                type tp-ref;
+                            }
+                        }
+                    }
+                }
+            }
+        }
+        container network-elements {
+            config true;
+            list network-element {
+                key "element-id";
+                leaf element-id {
+                    type element-id;
+                }
+            }
+        }
+    }
 }
index 1d357bde0ab8851adcf013bc8ef3e1f790fc7068..eec19092fd75f859b8a3efc587efb3df5412fb31 100644 (file)
@@ -12,20 +12,6 @@ module controller-openflow-ipv6 {
        revision 2013-06-07 {
           description "Initial demo";
        }
-
-
-
-       augment "/cn:network/cn:network-elements/cn:network-element/of:flow-tables/of:flow-table/of:flows/of:flow/of:match" {
-
-               leaf nl-src {
-                       type inet:ipv6-prefix;
-               }
-
-               leaf nl-dst {
-                       type inet:ipv6-prefix;
-               }
-           } 
-
 }
 
        
\ No newline at end of file
index 62e937e92ba1049d013c025200d34335aa95bf83..83f69c4dc2ffb669f9380c022650b3246cd84f7f 100644 (file)
@@ -3,16 +3,11 @@ module controller-openflow {
     namespace "urn:opendaylight:controller:openflow";
     prefix "of";
     import controller-network {prefix cn;}
-    
-    
+
     revision 2013-05-20 {
        description "Initial demo";
     }
 
-   
-
-
-
     typedef datapath-id {
         type string {
             length 16;
index d6722be51a359ccf0e72b363100514f4bfdc6512..6e804a199d3a829646cfa951120910543128d9c5 100644 (file)
@@ -15,7 +15,9 @@ import org.opendaylight.controller.yang.model.api.DataSchemaNode;
 import org.opendaylight.controller.yang.model.api.GroupingDefinition;
 
 public abstract class AbstractDataNodeContainerBuilder implements DataNodeContainerBuilder {
-    private final QName qname;
+    protected final int line;
+    protected final QName qname;
+    protected Builder parent;
 
     protected Set<DataSchemaNode> childNodes;
     protected final Set<DataSchemaNodeBuilder> addedChildNodes = new HashSet<DataSchemaNodeBuilder>();
@@ -23,10 +25,26 @@ public abstract class AbstractDataNodeContainerBuilder implements DataNodeContai
     protected Set<GroupingDefinition> groupings;
     protected final Set<GroupingBuilder> addedGroupings = new HashSet<GroupingBuilder>();
 
-    protected AbstractDataNodeContainerBuilder(QName qname) {
+    protected AbstractDataNodeContainerBuilder(final int line, final QName qname) {
+        this.line = line;
         this.qname = qname;
     }
 
+    @Override
+    public int getLine() {
+        return line;
+    }
+
+    @Override
+    public Builder getParent() {
+        return parent;
+    }
+
+    @Override
+    public void setParent(final Builder parent) {
+        this.parent = parent;
+    }
+
     @Override
     public QName getQName() {
         return qname;
@@ -37,6 +55,10 @@ public abstract class AbstractDataNodeContainerBuilder implements DataNodeContai
         return childNodes;
     }
 
+    public void setChildNodes(Set<DataSchemaNode> childNodes) {
+        this.childNodes = childNodes;
+    }
+
     @Override
     public Set<DataSchemaNodeBuilder> getChildNodeBuilders() {
         return addedChildNodes;
@@ -47,15 +69,15 @@ public abstract class AbstractDataNodeContainerBuilder implements DataNodeContai
         addedChildNodes.add(childNode);
     }
 
-    public void setChildNodes(Set<DataSchemaNode> childNodes) {
-        this.childNodes = childNodes;
-    }
-
     @Override
     public Set<GroupingDefinition> getGroupings() {
         return groupings;
     }
 
+    public void setGroupings(final Set<GroupingDefinition> groupings) {
+        this.groupings = groupings;
+    }
+
     public Set<GroupingBuilder> getGroupingBuilders() {
         return addedGroupings;
     }
@@ -65,8 +87,4 @@ public abstract class AbstractDataNodeContainerBuilder implements DataNodeContai
         addedGroupings.add(grouping);
     }
 
-    public void setGroupings(final Set<GroupingDefinition> groupings) {
-        this.groupings = groupings;
-    }
-
 }
index c8e69682741914e9c7c3b5f223bdd2b08149f5fc..1963c6cd36d26ea812f84e266089298b67f4b0e0 100644 (file)
@@ -21,15 +21,16 @@ import org.opendaylight.controller.yang.parser.builder.impl.UnknownSchemaNodeBui
 public abstract class AbstractSchemaNodeBuilder implements SchemaNodeBuilder {\r
     protected final int line;\r
     protected final QName qname;\r
-    protected SchemaPath path;\r
+    protected Builder parent;\r
+    protected SchemaPath schemaPath;\r
     protected String description;\r
     protected String reference;\r
     protected Status status = Status.CURRENT;\r
     protected final List<UnknownSchemaNodeBuilder> addedUnknownNodes = new ArrayList<UnknownSchemaNodeBuilder>();\r
 \r
-    protected AbstractSchemaNodeBuilder(final QName qname, final int line) {\r
-        this.qname = qname;\r
+    protected AbstractSchemaNodeBuilder(final int line, final QName qname) {\r
         this.line = line;\r
+        this.qname = qname;\r
     }\r
 \r
     @Override\r
@@ -41,12 +42,22 @@ public abstract class AbstractSchemaNodeBuilder implements SchemaNodeBuilder {
         return qname;\r
     }\r
 \r
+    @Override\r
+    public Builder getParent() {\r
+        return parent;\r
+    }\r
+\r
+    @Override\r
+    public void setParent(final Builder parent) {\r
+        this.parent = parent;\r
+    }\r
+\r
     public SchemaPath getPath() {\r
-        return path;\r
+        return schemaPath;\r
     }\r
 \r
     public void setPath(SchemaPath schemaPath) {\r
-        this.path = schemaPath;\r
+        this.schemaPath = schemaPath;\r
     }\r
 \r
     public String getDescription() {\r
index 05ef4c5330634fd376cce90059bfeee97535f95e..caf71ecc7b28c892c1bd43a84b9849de4db080fb 100644 (file)
@@ -7,16 +7,44 @@
  */
 package org.opendaylight.controller.yang.parser.builder.api;
 
+import org.opendaylight.controller.yang.common.QName;
 import org.opendaylight.controller.yang.model.api.TypeDefinition;
 
 /**
  * Basic implementation for TypeAwareBuilder builders.
  */
 public abstract class AbstractTypeAwareBuilder implements TypeAwareBuilder {
-
+    protected final int line;
+    protected final QName qname;
+    protected Builder parent;
     protected TypeDefinition<?> type;
     protected TypeDefinitionBuilder typedef;
 
+    public AbstractTypeAwareBuilder(final int line, final QName qname) {
+        this.line = line;
+        this.qname = qname;
+    }
+
+    @Override
+    public int getLine() {
+        return line;
+    }
+
+    @Override
+    public Builder getParent() {
+        return parent;
+    }
+
+    @Override
+    public void setParent(final Builder parent) {
+        this.parent = parent;
+    }
+
+    @Override
+    public QName getQName() {
+        return qname;
+    }
+
     @Override
     public TypeDefinition<?> getType() {
         return type;
index 1d199c2c64147ce6345723605807b296dcadb824..4500b130f16f085dda7d7af54d18d6163e915007 100644 (file)
@@ -14,6 +14,28 @@ import org.opendaylight.controller.yang.parser.builder.impl.UnknownSchemaNodeBui
  */
 public interface Builder {
 
+    /**
+     * Get current line in yang file.
+     *
+     * @return current line in yang file
+     */
+    int getLine();
+
+    /**
+     * Get parent node of this node.
+     *
+     * @return parent node builder or null if this is top level node
+     */
+    Builder getParent();
+
+    /**
+     * Set parent of this node.
+     *
+     * @param parent
+     *            parent node builder
+     */
+    void setParent(Builder parent);
+
     /**
      * Build YANG data model node.
      *
@@ -25,8 +47,6 @@ public interface Builder {
      */
     Object build();
 
-    int getLine();
-
     void addUnknownSchemaNode(UnknownSchemaNodeBuilder unknownNode);
 
 }
index 20d9417f9d5d57768ff13ddf81f2853fe29d89af..2806994c3da9c6c4c8e6bc31640d71b6e79fa697 100644 (file)
@@ -16,7 +16,7 @@ import org.opendaylight.controller.yang.parser.builder.impl.UnknownSchemaNodeBui
 /**
  * Interface for builders of 'grouping' statement.
  */
-public interface GroupingBuilder extends DataNodeContainerBuilder, SchemaNodeBuilder, TypeDefinitionAwareBuilder, GroupingMember {
+public interface GroupingBuilder extends DataNodeContainerBuilder, SchemaNodeBuilder, GroupingMember {
 
     GroupingDefinition build();
 
diff --git a/opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/main/java/org/opendaylight/controller/yang/parser/builder/api/TypeDefinitionAwareBuilder.java b/opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/main/java/org/opendaylight/controller/yang/parser/builder/api/TypeDefinitionAwareBuilder.java
deleted file mode 100644 (file)
index 0156c24..0000000
+++ /dev/null
@@ -1,18 +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.parser.builder.api;
-
-/**
- * Builders of all nodes, which can have 'typedef' statement must implement this interface.
- * [module, submodule, container, list, grouping, rpc, input, output, notification]
- */
-public interface TypeDefinitionAwareBuilder {
-
-       void addTypedef(TypeDefinitionBuilder typedefBuilder);
-
-}
index d5f3c52497bf593880c6c46ee9f4672f1605f8bb..dd8906025da492ed53c481471e0cc86256b49fb8 100644 (file)
@@ -21,47 +21,46 @@ import org.opendaylight.controller.yang.parser.builder.api.AbstractSchemaNodeBui
 import org.opendaylight.controller.yang.parser.builder.api.ConfigNode;
 import org.opendaylight.controller.yang.parser.builder.api.DataSchemaNodeBuilder;
 import org.opendaylight.controller.yang.parser.builder.api.GroupingMember;
+import org.opendaylight.controller.yang.parser.util.Comparators;
 
 public final class AnyXmlBuilder extends AbstractSchemaNodeBuilder implements DataSchemaNodeBuilder, GroupingMember,
         ConfigNode {
     private boolean built;
     private final AnyXmlSchemaNodeImpl instance;
     private final ConstraintsBuilder constraints;
-
     private List<UnknownSchemaNode> unknownNodes;
 
     private Boolean configuration;
     private boolean augmenting;
     private boolean addedByUses;
 
-    public AnyXmlBuilder(final QName qname, final SchemaPath schemaPath, final int line) {
-        super(qname, line);
-        this.path = schemaPath;
+    public AnyXmlBuilder(final int line, final QName qname, final SchemaPath schemaPath) {
+        super(line, qname);
+        this.schemaPath = schemaPath;
         instance = new AnyXmlSchemaNodeImpl(qname);
         constraints = new ConstraintsBuilder(line);
     }
 
     public AnyXmlBuilder(final AnyXmlBuilder builder) {
-        super(builder.qname, builder.line);
+        super(builder.getLine(), builder.getQName());
+        parent = builder.getParent();
         instance = new AnyXmlSchemaNodeImpl(qname);
-        constraints = builder.constraints;
-        path = builder.path;
+        constraints = builder.getConstraints();
+        schemaPath = builder.getPath();
         unknownNodes = builder.unknownNodes;
-        for (UnknownSchemaNodeBuilder un : builder.addedUnknownNodes) {
-            addedUnknownNodes.add(un);
-        }
-        description = builder.description;
-        reference = builder.reference;
-        status = builder.status;
-        configuration = builder.configuration;
-        augmenting = builder.augmenting;
-        addedByUses = builder.addedByUses;
+        addedUnknownNodes.addAll(builder.getUnknownNodes());
+        description = builder.getDescription();
+        reference = builder.getReference();
+        status = builder.getStatus();
+        configuration = builder.isConfiguration();
+        augmenting = builder.isAugmenting();
+        addedByUses = builder.isAddedByUses();
     }
 
     @Override
     public AnyXmlSchemaNode build() {
         if (!built) {
-            instance.setPath(path);
+            instance.setPath(schemaPath);
             instance.setConstraints(constraints.build());
             instance.setDescription(description);
             instance.setReference(reference);
@@ -77,6 +76,7 @@ public final class AnyXmlBuilder extends AbstractSchemaNodeBuilder implements Da
                     unknownNodes.add(b.build());
                 }
             }
+            Collections.sort(unknownNodes, Comparators.SCHEMA_NODE_COMP);
             instance.setUnknownSchemaNodes(unknownNodes);
 
             built = true;
@@ -127,6 +127,48 @@ public final class AnyXmlBuilder extends AbstractSchemaNodeBuilder implements Da
         this.configuration = configuration;
     }
 
+    @Override
+    public int hashCode() {
+        final int prime = 31;
+        int result = 1;
+        result = prime * result + ((schemaPath == null) ? 0 : schemaPath.hashCode());
+        return result;
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (this == obj) {
+            return true;
+        }
+        if (obj == null) {
+            return false;
+        }
+        if (getClass() != obj.getClass()) {
+            return false;
+        }
+        AnyXmlBuilder other = (AnyXmlBuilder) obj;
+        if (schemaPath == null) {
+            if (other.schemaPath != null) {
+                return false;
+            }
+        } else if (!schemaPath.equals(other.schemaPath)) {
+            return false;
+        }
+        if (parent == null) {
+            if (other.parent != null) {
+                return false;
+            }
+        } else if (!parent.equals(other.parent)) {
+            return false;
+        }
+        return true;
+    }
+
+    @Override
+    public String toString() {
+        return "anyxml " + qname.getLocalName();
+    }
+
     private final class AnyXmlSchemaNodeImpl implements AnyXmlSchemaNode {
         private final QName qname;
         private SchemaPath path;
index b18f2558f74e6f559c023693c480708c7d3d6668..b534ba4f6013bb91056e30e1294486ec5b3e5086 100644 (file)
@@ -9,11 +9,12 @@ package org.opendaylight.controller.yang.parser.builder.impl;
 
 import java.util.ArrayList;
 import java.util.Collections;
-import java.util.HashMap;
 import java.util.HashSet;
 import java.util.List;
 import java.util.Map;
 import java.util.Set;
+import java.util.TreeMap;
+import java.util.TreeSet;
 
 import org.opendaylight.controller.yang.common.QName;
 import org.opendaylight.controller.yang.model.api.AugmentationSchema;
@@ -32,6 +33,7 @@ import org.opendaylight.controller.yang.parser.builder.api.DataSchemaNodeBuilder
 import org.opendaylight.controller.yang.parser.builder.api.GroupingBuilder;
 import org.opendaylight.controller.yang.parser.builder.api.TypeDefinitionBuilder;
 import org.opendaylight.controller.yang.parser.builder.api.UsesNodeBuilder;
+import org.opendaylight.controller.yang.parser.util.Comparators;
 import org.opendaylight.controller.yang.parser.util.YangModelBuilderUtil;
 import org.opendaylight.controller.yang.parser.util.YangParseException;
 
@@ -39,7 +41,7 @@ public final class AugmentationSchemaBuilderImpl implements AugmentationSchemaBu
     private boolean built;
     private final AugmentationSchemaImpl instance;
     private final int line;
-    private final Builder parent;
+    private Builder parent;
 
     private String whenCondition;
     private String description;
@@ -56,12 +58,10 @@ public final class AugmentationSchemaBuilderImpl implements AugmentationSchemaBu
     private final List<UnknownSchemaNodeBuilder> addedUnknownNodes = new ArrayList<UnknownSchemaNodeBuilder>();
     private boolean resolved;
 
-    AugmentationSchemaBuilderImpl(final String augmentTargetStr, final int line, final Builder parent) {
+    AugmentationSchemaBuilderImpl(final int line, final String augmentTargetStr) {
         this.augmentTargetStr = augmentTargetStr;
         this.line = line;
-        this.parent = parent;
-        final SchemaPath targetPath = YangModelBuilderUtil
-                .parseAugmentPath(augmentTargetStr);
+        final SchemaPath targetPath = YangModelBuilderUtil.parseAugmentPath(augmentTargetStr);
         dirtyAugmentTarget = targetPath;
         instance = new AugmentationSchemaImpl(targetPath);
     }
@@ -76,6 +76,10 @@ public final class AugmentationSchemaBuilderImpl implements AugmentationSchemaBu
         return parent;
     }
 
+    @Override
+    public void setParent(final Builder parent) {
+        this.parent = parent;
+    }
 
     @Override
     public void addChildNode(DataSchemaNodeBuilder childNode) {
@@ -145,14 +149,15 @@ public final class AugmentationSchemaBuilderImpl implements AugmentationSchemaBu
             instance.setWhenCondition(whenStmt);
 
             // CHILD NODES
-            final Map<QName, DataSchemaNode> childs = new HashMap<QName, DataSchemaNode>();
+            final Map<QName, DataSchemaNode> childs = new TreeMap<QName, DataSchemaNode>(Comparators.QNAME_COMP);
             for (DataSchemaNodeBuilder node : childNodes) {
                 childs.put(node.getQName(), node.build());
             }
             instance.setChildNodes(childs);
 
             // GROUPINGS
-            final Set<GroupingDefinition> groupingDefinitions = new HashSet<GroupingDefinition>();
+            final Set<GroupingDefinition> groupingDefinitions = new TreeSet<GroupingDefinition>(
+                    Comparators.SCHEMA_NODE_COMP);
             for (GroupingBuilder builder : groupings) {
                 groupingDefinitions.add(builder.build());
             }
@@ -170,6 +175,7 @@ public final class AugmentationSchemaBuilderImpl implements AugmentationSchemaBu
             for (UnknownSchemaNodeBuilder b : addedUnknownNodes) {
                 unknownNodes.add(b.build());
             }
+            Collections.sort(unknownNodes, Comparators.SCHEMA_NODE_COMP);
             instance.setUnknownSchemaNodes(unknownNodes);
 
             built = true;
@@ -202,8 +208,7 @@ public final class AugmentationSchemaBuilderImpl implements AugmentationSchemaBu
 
     @Override
     public void addTypedef(TypeDefinitionBuilder type) {
-        throw new YangParseException(line,
-                "Augmentation can not contains typedef statement.");
+        throw new YangParseException(line, "Augmentation can not contains typedef statement.");
     }
 
     @Override
@@ -218,7 +223,7 @@ public final class AugmentationSchemaBuilderImpl implements AugmentationSchemaBu
 
     @Override
     public void setStatus(Status status) {
-        if(status != null) {
+        if (status != null) {
             this.status = status;
         }
     }
@@ -251,13 +256,9 @@ public final class AugmentationSchemaBuilderImpl implements AugmentationSchemaBu
     public int hashCode() {
         final int prime = 17;
         int result = 1;
-        result = prime
-                * result
-                + ((augmentTargetStr == null) ? 0 : augmentTargetStr.hashCode());
-        result = prime * result
-                + ((whenCondition == null) ? 0 : whenCondition.hashCode());
-        result = prime * result
-                + ((childNodes == null) ? 0 : childNodes.hashCode());
+        result = prime * result + ((augmentTargetStr == null) ? 0 : augmentTargetStr.hashCode());
+        result = prime * result + ((whenCondition == null) ? 0 : whenCondition.hashCode());
+        result = prime * result + ((childNodes == null) ? 0 : childNodes.hashCode());
         return result;
     }
 
@@ -297,6 +298,10 @@ public final class AugmentationSchemaBuilderImpl implements AugmentationSchemaBu
         return true;
     }
 
+    public String toString() {
+        return "augment " + augmentTargetStr;
+    }
+
     private final class AugmentationSchemaImpl implements AugmentationSchema {
         private SchemaPath targetPath;
         private RevisionAwareXPath whenCondition;
@@ -332,7 +337,9 @@ public final class AugmentationSchemaBuilderImpl implements AugmentationSchemaBu
 
         @Override
         public Set<DataSchemaNode> getChildNodes() {
-            return new HashSet<DataSchemaNode>(childNodes.values());
+            final Set<DataSchemaNode> result = new TreeSet<DataSchemaNode>(Comparators.SCHEMA_NODE_COMP);
+            result.addAll(childNodes.values());
+            return result;
         }
 
         private void setChildNodes(Map<QName, DataSchemaNode> childNodes) {
@@ -399,12 +406,12 @@ public final class AugmentationSchemaBuilderImpl implements AugmentationSchemaBu
             this.status = status;
         }
 
+        @Override
         public List<UnknownSchemaNode> getUnknownSchemaNodes() {
             return unknownNodes;
         }
 
-        private void setUnknownSchemaNodes(
-                List<UnknownSchemaNode> unknownSchemaNodes) {
+        private void setUnknownSchemaNodes(List<UnknownSchemaNode> unknownSchemaNodes) {
             if (unknownSchemaNodes != null) {
                 this.unknownNodes = unknownSchemaNodes;
             }
@@ -431,12 +438,9 @@ public final class AugmentationSchemaBuilderImpl implements AugmentationSchemaBu
         public int hashCode() {
             final int prime = 17;
             int result = 1;
-            result = prime * result
-                    + ((targetPath == null) ? 0 : targetPath.hashCode());
-            result = prime * result
-                    + ((whenCondition == null) ? 0 : whenCondition.hashCode());
-            result = prime * result
-                    + ((childNodes == null) ? 0 : childNodes.hashCode());
+            result = prime * result + ((targetPath == null) ? 0 : targetPath.hashCode());
+            result = prime * result + ((whenCondition == null) ? 0 : whenCondition.hashCode());
+            result = prime * result + ((childNodes == null) ? 0 : childNodes.hashCode());
             return result;
         }
 
@@ -478,8 +482,7 @@ public final class AugmentationSchemaBuilderImpl implements AugmentationSchemaBu
 
         @Override
         public String toString() {
-            StringBuilder sb = new StringBuilder(
-                    AugmentationSchemaImpl.class.getSimpleName());
+            StringBuilder sb = new StringBuilder(AugmentationSchemaImpl.class.getSimpleName());
             sb.append("[");
             sb.append("targetPath=" + targetPath);
             sb.append(", when=" + whenCondition);
index 0761618b06093bebfa60f1520722034fe3126513..1b4283a46313dbf740c1f2c3b2f1e7594557cda4 100644 (file)
@@ -12,6 +12,7 @@ import java.util.Collections;
 import java.util.HashSet;
 import java.util.List;
 import java.util.Set;
+import java.util.TreeSet;
 
 import org.opendaylight.controller.yang.common.QName;
 import org.opendaylight.controller.yang.model.api.AugmentationSchema;
@@ -27,6 +28,7 @@ import org.opendaylight.controller.yang.parser.builder.api.AugmentationTargetBui
 import org.opendaylight.controller.yang.parser.builder.api.ConfigNode;
 import org.opendaylight.controller.yang.parser.builder.api.DataSchemaNodeBuilder;
 import org.opendaylight.controller.yang.parser.builder.api.GroupingMember;
+import org.opendaylight.controller.yang.parser.util.Comparators;
 import org.opendaylight.controller.yang.parser.util.ParserUtils;
 
 public final class ChoiceBuilder extends AbstractSchemaNodeBuilder implements DataSchemaNodeBuilder,
@@ -47,17 +49,18 @@ public final class ChoiceBuilder extends AbstractSchemaNodeBuilder implements Da
     private final Set<ChoiceCaseBuilder> addedCases = new HashSet<ChoiceCaseBuilder>();
     private String defaultCase;
 
-    public ChoiceBuilder(final QName qname, final int line) {
-        super(qname, line);
+    public ChoiceBuilder(final int line, final QName qname) {
+        super(line, qname);
         instance = new ChoiceNodeImpl(qname);
         constraints = new ConstraintsBuilder(line);
     }
 
     public ChoiceBuilder(ChoiceBuilder b) {
-        super(b.getQName(), b.getLine());
+        super(b.getLine(), b.getQName());
+        parent = b.getParent();
         instance = new ChoiceNodeImpl(qname);
-        constraints = b.constraints;
-        path = b.getPath();
+        constraints = b.getConstraints();
+        schemaPath = b.getPath();
         description = b.getDescription();
         reference = b.getReference();
         status = b.getStatus();
@@ -75,7 +78,7 @@ public final class ChoiceBuilder extends AbstractSchemaNodeBuilder implements Da
     @Override
     public ChoiceNode build() {
         if (!isBuilt) {
-            instance.setPath(path);
+            instance.setPath(schemaPath);
             instance.setDescription(description);
             instance.setReference(reference);
             instance.setStatus(status);
@@ -87,7 +90,7 @@ public final class ChoiceBuilder extends AbstractSchemaNodeBuilder implements Da
 
             // CASES
             if (cases == null) {
-                cases = new HashSet<ChoiceCaseNode>();
+                cases = new TreeSet<ChoiceCaseNode>(Comparators.SCHEMA_NODE_COMP);
                 for (ChoiceCaseBuilder caseBuilder : addedCases) {
                     cases.add(caseBuilder.build());
                 }
@@ -107,6 +110,7 @@ public final class ChoiceBuilder extends AbstractSchemaNodeBuilder implements Da
                 for (UnknownSchemaNodeBuilder b : addedUnknownNodes) {
                     unknownNodes.add(b.build());
                 }
+                Collections.sort(unknownNodes, Comparators.SCHEMA_NODE_COMP);
             }
             instance.setUnknownSchemaNodes(unknownNodes);
 
@@ -127,7 +131,11 @@ public final class ChoiceBuilder extends AbstractSchemaNodeBuilder implements Da
 
     public void addChildNode(DataSchemaNodeBuilder childNode) {
         if (!(childNode instanceof ChoiceCaseBuilder)) {
-            ChoiceCaseBuilder caseBuilder = new ChoiceCaseBuilder(this, childNode.getQName(), childNode.getLine());
+            ChoiceCaseBuilder caseBuilder = new ChoiceCaseBuilder(childNode.getLine(), childNode.getQName());
+            if(childNode.isAugmenting()) {
+                caseBuilder.setAugmenting(true);
+                childNode.setAugmenting(false);
+            }
             caseBuilder.setPath(childNode.getPath());
             SchemaPath newPath = ParserUtils.createSchemaPath(childNode.getPath(), childNode.getQName().getLocalName());
             childNode.setPath(newPath);
@@ -142,6 +150,7 @@ public final class ChoiceBuilder extends AbstractSchemaNodeBuilder implements Da
         this.cases = cases;
     }
 
+    @Override
     public boolean isAugmenting() {
         return augmenting;
     }
@@ -200,6 +209,48 @@ public final class ChoiceBuilder extends AbstractSchemaNodeBuilder implements Da
         this.defaultCase = defaultCase;
     }
 
+    @Override
+    public int hashCode() {
+        final int prime = 31;
+        int result = 1;
+        result = prime * result + ((schemaPath == null) ? 0 : schemaPath.hashCode());
+        return result;
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (this == obj) {
+            return true;
+        }
+        if (obj == null) {
+            return false;
+        }
+        if (getClass() != obj.getClass()) {
+            return false;
+        }
+        ChoiceBuilder other = (ChoiceBuilder) obj;
+        if (schemaPath == null) {
+            if (other.schemaPath != null) {
+                return false;
+            }
+        } else if (!schemaPath.equals(other.schemaPath)) {
+            return false;
+        }
+        if (parent == null) {
+            if (other.parent != null) {
+                return false;
+            }
+        } else if (!parent.equals(other.parent)) {
+            return false;
+        }
+        return true;
+    }
+
+    @Override
+    public String toString() {
+        return "choice " + qname.getLocalName();
+    }
+
     public final class ChoiceNodeImpl implements ChoiceNode {
         private final QName qname;
         private SchemaPath path;
index cfd3866841129178cd242ce9ea7bd97a03e817e8..e6c81ab7aa5399b21ac92040ffaa46b69f47b4cb 100644 (file)
@@ -2,11 +2,11 @@ package org.opendaylight.controller.yang.parser.builder.impl;
 
 import java.util.ArrayList;
 import java.util.Collections;
-import java.util.HashMap;
 import java.util.HashSet;
 import java.util.List;
 import java.util.Map;
 import java.util.Set;
+import java.util.TreeMap;
 
 import org.opendaylight.controller.yang.common.QName;
 import org.opendaylight.controller.yang.model.api.AugmentationSchema;
@@ -25,14 +25,13 @@ import org.opendaylight.controller.yang.parser.builder.api.AugmentationTargetBui
 import org.opendaylight.controller.yang.parser.builder.api.DataSchemaNodeBuilder;
 import org.opendaylight.controller.yang.parser.builder.api.TypeDefinitionBuilder;
 import org.opendaylight.controller.yang.parser.builder.api.UsesNodeBuilder;
+import org.opendaylight.controller.yang.parser.util.Comparators;
 import org.opendaylight.controller.yang.parser.util.YangParseException;
 
 public final class ChoiceCaseBuilder extends AbstractDataNodeContainerBuilder implements DataSchemaNodeBuilder,
         AugmentationTargetBuilder {
     private boolean isBuilt;
     private final ChoiceCaseNodeImpl instance;
-    private final ChoiceBuilder parent;
-    private final int line;
     // SchemaNode args
     private SchemaPath schemaPath;
     private String description;
@@ -47,10 +46,8 @@ public final class ChoiceCaseBuilder extends AbstractDataNodeContainerBuilder im
     // AugmentationTarget args
     private final Set<AugmentationSchemaBuilder> addedAugmentations = new HashSet<AugmentationSchemaBuilder>();
 
-    ChoiceCaseBuilder(final ChoiceBuilder parent, final QName qname, final int line) {
-        super(qname);
-        this.parent = parent;
-        this.line = line;
+    ChoiceCaseBuilder(final int line, final QName qname) {
+        super(line, qname);
         instance = new ChoiceCaseNodeImpl(qname);
         constraints = new ConstraintsBuilder(line);
     }
@@ -66,7 +63,7 @@ public final class ChoiceCaseBuilder extends AbstractDataNodeContainerBuilder im
             instance.setAugmenting(augmenting);
 
             // CHILD NODES
-            final Map<QName, DataSchemaNode> childs = new HashMap<QName, DataSchemaNode>();
+            final Map<QName, DataSchemaNode> childs = new TreeMap<QName, DataSchemaNode>(Comparators.QNAME_COMP);
             for (DataSchemaNodeBuilder node : addedChildNodes) {
                 childs.put(node.getQName(), node.build());
             }
@@ -84,6 +81,7 @@ public final class ChoiceCaseBuilder extends AbstractDataNodeContainerBuilder im
             for (UnknownSchemaNodeBuilder b : addedUnknownNodes) {
                 unknownNodes.add(b.build());
             }
+            Collections.sort(unknownNodes, Comparators.SCHEMA_NODE_COMP);
             instance.setUnknownSchemaNodes(unknownNodes);
 
             // AUGMENTATIONS
@@ -105,15 +103,6 @@ public final class ChoiceCaseBuilder extends AbstractDataNodeContainerBuilder im
         build();
     }
 
-    @Override
-    public int getLine() {
-        return line;
-    }
-
-    public ChoiceBuilder getParent() {
-        return parent;
-    }
-
     public SchemaPath getPath() {
         return schemaPath;
     }
@@ -199,6 +188,48 @@ public final class ChoiceCaseBuilder extends AbstractDataNodeContainerBuilder im
         addedAugmentations.add(augment);
     }
 
+    @Override
+    public int hashCode() {
+        final int prime = 31;
+        int result = 1;
+        result = prime * result + ((schemaPath == null) ? 0 : schemaPath.hashCode());
+        return result;
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (this == obj) {
+            return true;
+        }
+        if (obj == null) {
+            return false;
+        }
+        if (getClass() != obj.getClass()) {
+            return false;
+        }
+        ChoiceCaseBuilder other = (ChoiceCaseBuilder) obj;
+        if (schemaPath == null) {
+            if (other.schemaPath != null) {
+                return false;
+            }
+        } else if (!schemaPath.equals(other.schemaPath)) {
+            return false;
+        }
+        if (parent == null) {
+            if (other.parent != null) {
+                return false;
+            }
+        } else if (!parent.equals(other.parent)) {
+            return false;
+        }
+        return true;
+    }
+
+    @Override
+    public String toString() {
+        return "case " + getQName().getLocalName();
+    }
+
     public final class ChoiceCaseNodeImpl implements ChoiceCaseNode {
         private final QName qname;
         private SchemaPath path;
index ebfe520c3978344570bbc6e83674c214f78a4f84..1351f56b4c97f8f5dd68cb9538032ebf2da5e246 100644 (file)
@@ -21,6 +21,7 @@ import org.opendaylight.controller.yang.parser.util.YangParseException;
 public final class ConstraintsBuilder implements Builder {
     private final ConstraintDefinitionImpl instance;
     private final int line;
+    private Builder parent;
     private final Set<MustDefinition> mustDefinitions;
     private String whenCondition;
     private boolean mandatory;
@@ -54,6 +55,16 @@ public final class ConstraintsBuilder implements Builder {
         return line;
     }
 
+    @Override
+    public Builder getParent() {
+        return parent;
+    }
+
+    @Override
+    public void setParent(final Builder parent) {
+        this.parent = parent;
+    }
+
     @Override
     public void addUnknownSchemaNode(UnknownSchemaNodeBuilder unknownNode) {
         throw new YangParseException(line, "Can not add unknown node to constraints.");
@@ -99,6 +110,7 @@ public final class ConstraintsBuilder implements Builder {
         this.mandatory = mandatory;
     }
 
+
     private final class ConstraintDefinitionImpl implements ConstraintDefinition {
         private RevisionAwareXPath whenCondition;
         private Set<MustDefinition> mustConstraints;
@@ -227,7 +239,6 @@ public final class ConstraintsBuilder implements Builder {
             sb.append("]");
             return sb.toString();
         }
-
     }
 
 }
index a194dea927a0e9097f5c8143f5bdddb7c6c5ad4e..545abead89c473e9a27c4d79600a3536a68048c9 100644 (file)
@@ -9,11 +9,12 @@ package org.opendaylight.controller.yang.parser.builder.impl;
 
 import java.util.ArrayList;
 import java.util.Collections;
-import java.util.HashMap;
 import java.util.HashSet;
 import java.util.List;
 import java.util.Map;
 import java.util.Set;
+import java.util.TreeMap;
+import java.util.TreeSet;
 
 import org.opendaylight.controller.yang.common.QName;
 import org.opendaylight.controller.yang.model.api.AugmentationSchema;
@@ -33,15 +34,14 @@ import org.opendaylight.controller.yang.parser.builder.api.ConfigNode;
 import org.opendaylight.controller.yang.parser.builder.api.DataSchemaNodeBuilder;
 import org.opendaylight.controller.yang.parser.builder.api.GroupingBuilder;
 import org.opendaylight.controller.yang.parser.builder.api.GroupingMember;
-import org.opendaylight.controller.yang.parser.builder.api.TypeDefinitionAwareBuilder;
 import org.opendaylight.controller.yang.parser.builder.api.TypeDefinitionBuilder;
 import org.opendaylight.controller.yang.parser.builder.api.UsesNodeBuilder;
+import org.opendaylight.controller.yang.parser.util.Comparators;
 
 public final class ContainerSchemaNodeBuilder extends AbstractDataNodeContainerBuilder implements
-        TypeDefinitionAwareBuilder, AugmentationTargetBuilder, DataSchemaNodeBuilder, GroupingMember, ConfigNode {
+        AugmentationTargetBuilder, DataSchemaNodeBuilder, GroupingMember, ConfigNode {
     private boolean isBuilt;
     private final ContainerSchemaNodeImpl instance;
-    private final int line;
 
     // SchemaNode args
     private SchemaPath schemaPath;
@@ -66,17 +66,15 @@ public final class ContainerSchemaNodeBuilder extends AbstractDataNodeContainerB
     // ContainerSchemaNode args
     private boolean presence;
 
-    public ContainerSchemaNodeBuilder(final QName qname, final SchemaPath schemaPath, final int line) {
-        super(qname);
+    public ContainerSchemaNodeBuilder(final int line, final QName qname, final SchemaPath schemaPath) {
+        super(line, qname);
         this.schemaPath = schemaPath;
-        this.line = line;
         instance = new ContainerSchemaNodeImpl(qname);
         constraints = new ConstraintsBuilder(line);
     }
 
     public ContainerSchemaNodeBuilder(final ContainerSchemaNodeBuilder b) {
-        super(b.getQName());
-        line = b.getLine();
+        super(b.getLine(), b.getQName());
         instance = new ContainerSchemaNodeImpl(b.getQName());
         constraints = b.getConstraints();
         schemaPath = b.getPath();
@@ -112,14 +110,15 @@ public final class ContainerSchemaNodeBuilder extends AbstractDataNodeContainerB
             instance.setAugmenting(augmenting);
             instance.setAddedByUses(addedByUses);
 
-            // if this builder represents rpc input or output, it can has configuration value set to null
-            if(configuration == null) {
+            // if this builder represents rpc input or output, it can has
+            // configuration value set to null
+            if (configuration == null) {
                 configuration = false;
             }
             instance.setConfiguration(configuration);
 
             // CHILD NODES
-            final Map<QName, DataSchemaNode> childs = new HashMap<QName, DataSchemaNode>();
+            final Map<QName, DataSchemaNode> childs = new TreeMap<QName, DataSchemaNode>(Comparators.QNAME_COMP);
             if (childNodes == null) {
                 for (DataSchemaNodeBuilder node : addedChildNodes) {
                     childs.put(node.getQName(), node.build());
@@ -133,7 +132,7 @@ public final class ContainerSchemaNodeBuilder extends AbstractDataNodeContainerB
 
             // GROUPINGS
             if (groupings == null) {
-                groupings = new HashSet<GroupingDefinition>();
+                groupings = new TreeSet<GroupingDefinition>(Comparators.SCHEMA_NODE_COMP);
                 for (GroupingBuilder builder : addedGroupings) {
                     groupings.add(builder.build());
                 }
@@ -142,7 +141,7 @@ public final class ContainerSchemaNodeBuilder extends AbstractDataNodeContainerB
 
             // TYPEDEFS
             if (typedefs == null) {
-                typedefs = new HashSet<TypeDefinition<?>>();
+                typedefs = new TreeSet<TypeDefinition<?>>(Comparators.SCHEMA_NODE_COMP);
                 for (TypeDefinitionBuilder entry : addedTypedefs) {
                     typedefs.add(entry.build());
                 }
@@ -173,6 +172,7 @@ public final class ContainerSchemaNodeBuilder extends AbstractDataNodeContainerB
                 for (UnknownSchemaNodeBuilder b : addedUnknownNodes) {
                     unknownNodes.add(b.build());
                 }
+                Collections.sort(unknownNodes, Comparators.SCHEMA_NODE_COMP);
             }
             instance.setUnknownSchemaNodes(unknownNodes);
 
@@ -190,11 +190,6 @@ public final class ContainerSchemaNodeBuilder extends AbstractDataNodeContainerB
         build();
     }
 
-    @Override
-    public int getLine() {
-        return line;
-    }
-
     @Override
     public Set<TypeDefinitionBuilder> getTypeDefinitionBuilders() {
         return addedTypedefs;
@@ -332,9 +327,46 @@ public final class ContainerSchemaNodeBuilder extends AbstractDataNodeContainerB
         this.unknownNodes = unknownNodes;
     }
 
+    @Override
+    public int hashCode() {
+        final int prime = 31;
+        int result = 1;
+        result = prime * result + ((schemaPath == null) ? 0 : schemaPath.hashCode());
+        return result;
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (this == obj) {
+            return true;
+        }
+        if (obj == null) {
+            return false;
+        }
+        if (getClass() != obj.getClass()) {
+            return false;
+        }
+        ContainerSchemaNodeBuilder other = (ContainerSchemaNodeBuilder) obj;
+        if (schemaPath == null) {
+            if (other.schemaPath != null) {
+                return false;
+            }
+        } else if (!schemaPath.equals(other.schemaPath)) {
+            return false;
+        }
+        if (parent == null) {
+            if (other.parent != null) {
+                return false;
+            }
+        } else if (!parent.equals(other.parent)) {
+            return false;
+        }
+        return true;
+    }
+
     @Override
     public String toString() {
-        return "container " + getQName().getLocalName();
+        return "container " + qname.getLocalName();
     }
 
     public final class ContainerSchemaNodeImpl implements ContainerSchemaNode {
index 790275cff404a11c551ff96edfbe0623946a448b..9b52d61c88085e822a780f569e97be05003f1ed9 100644 (file)
@@ -16,12 +16,14 @@ import org.opendaylight.controller.yang.model.api.Deviation.Deviate;
 import org.opendaylight.controller.yang.model.api.SchemaPath;
 import org.opendaylight.controller.yang.model.api.UnknownSchemaNode;
 import org.opendaylight.controller.yang.parser.builder.api.Builder;
+import org.opendaylight.controller.yang.parser.util.Comparators;
 import org.opendaylight.controller.yang.parser.util.YangModelBuilderUtil;
 import org.opendaylight.controller.yang.parser.util.YangParseException;
 
 public final class DeviationBuilder implements Builder {
-    private final DeviationImpl instance;
     private final int line;
+    private Builder parent;
+    private final DeviationImpl instance;
     private final List<UnknownSchemaNodeBuilder> addedUnknownNodes = new ArrayList<UnknownSchemaNodeBuilder>();
 
     DeviationBuilder(final String targetPathStr, final int line) {
@@ -38,6 +40,7 @@ public final class DeviationBuilder implements Builder {
         for (UnknownSchemaNodeBuilder b : addedUnknownNodes) {
             unknownNodes.add(b.build());
         }
+        Collections.sort(unknownNodes, Comparators.SCHEMA_NODE_COMP);
         instance.setUnknownSchemaNodes(unknownNodes);
 
         return instance;
@@ -48,6 +51,16 @@ public final class DeviationBuilder implements Builder {
         return line;
     }
 
+    @Override
+    public Builder getParent() {
+        return parent;
+    }
+
+    @Override
+    public void setParent(final Builder parent) {
+        this.parent = parent;
+    }
+
     @Override
     public void addUnknownSchemaNode(UnknownSchemaNodeBuilder unknownNode) {
         addedUnknownNodes.add(unknownNode);
index 65fd1c49d93873f5c022c2625b296ea2e2000304..a0ee47f7b8d13a7fc7540e4480fac53f7c48abeb 100644 (file)
@@ -17,31 +17,32 @@ import org.opendaylight.controller.yang.model.api.SchemaPath;
 import org.opendaylight.controller.yang.model.api.Status;
 import org.opendaylight.controller.yang.model.api.UnknownSchemaNode;
 import org.opendaylight.controller.yang.parser.builder.api.AbstractSchemaNodeBuilder;
+import org.opendaylight.controller.yang.parser.util.Comparators;
 
 public final class ExtensionBuilder extends AbstractSchemaNodeBuilder {
     private boolean isBuilt;
     private final ExtensionDefinitionImpl instance;
-    private final List<UnknownSchemaNodeBuilder> addedExtensions = new ArrayList<UnknownSchemaNodeBuilder>();
 
-    ExtensionBuilder(final QName qname, final int line) {
-        super(qname, line);
+    ExtensionBuilder(final int line, final QName qname) {
+        super(line, qname);
         instance = new ExtensionDefinitionImpl(qname);
     }
 
     @Override
     public ExtensionDefinition build() {
-        if(!isBuilt) {
-            instance.setPath(path);
+        if (!isBuilt) {
+            instance.setPath(schemaPath);
             instance.setDescription(description);
             instance.setReference(reference);
             instance.setStatus(status);
 
             // UNKNOWN NODES
-            final List<UnknownSchemaNode> extensions = new ArrayList<UnknownSchemaNode>();
-            for (UnknownSchemaNodeBuilder e : addedExtensions) {
-                extensions.add(e.build());
+            final List<UnknownSchemaNode> unknownNodes = new ArrayList<UnknownSchemaNode>();
+            for (UnknownSchemaNodeBuilder un : addedUnknownNodes) {
+                unknownNodes.add(un.build());
             }
-            instance.setUnknownSchemaNodes(extensions);
+            Collections.sort(unknownNodes, Comparators.SCHEMA_NODE_COMP);
+            instance.setUnknownSchemaNodes(unknownNodes);
 
             isBuilt = true;
         }
@@ -49,11 +50,6 @@ public final class ExtensionBuilder extends AbstractSchemaNodeBuilder {
         return instance;
     }
 
-
-    public void addExtension(UnknownSchemaNodeBuilder extension) {
-        addedExtensions.add(extension);
-    }
-
     public void setYinElement(boolean yin) {
         instance.setYinElement(yin);
     }
@@ -62,7 +58,6 @@ public final class ExtensionBuilder extends AbstractSchemaNodeBuilder {
         instance.setArgument(argument);
     }
 
-
     private final class ExtensionDefinitionImpl implements ExtensionDefinition {
         private final QName qname;
         private String argument;
@@ -70,8 +65,7 @@ public final class ExtensionBuilder extends AbstractSchemaNodeBuilder {
         private String description;
         private String reference;
         private Status status = Status.CURRENT;
-        private List<UnknownSchemaNode> unknownNodes = Collections
-                .emptyList();
+        private List<UnknownSchemaNode> unknownNodes = Collections.emptyList();
         private boolean yin;
 
         private ExtensionDefinitionImpl(QName qname) {
@@ -126,9 +120,8 @@ public final class ExtensionBuilder extends AbstractSchemaNodeBuilder {
             return unknownNodes;
         }
 
-        private void setUnknownSchemaNodes(
-                List<UnknownSchemaNode> unknownNodes) {
-            if(unknownNodes != null) {
+        private void setUnknownSchemaNodes(List<UnknownSchemaNode> unknownNodes) {
+            if (unknownNodes != null) {
                 this.unknownNodes = unknownNodes;
             }
         }
@@ -156,8 +149,7 @@ public final class ExtensionBuilder extends AbstractSchemaNodeBuilder {
             final int prime = 31;
             int result = 1;
             result = prime * result + ((qname == null) ? 0 : qname.hashCode());
-            result = prime * result
-                    + ((schemaPath == null) ? 0 : schemaPath.hashCode());
+            result = prime * result + ((schemaPath == null) ? 0 : schemaPath.hashCode());
             return result;
         }
 
@@ -192,10 +184,9 @@ public final class ExtensionBuilder extends AbstractSchemaNodeBuilder {
 
         @Override
         public String toString() {
-            StringBuilder sb = new StringBuilder(
-                    ExtensionDefinitionImpl.class.getSimpleName());
+            StringBuilder sb = new StringBuilder(ExtensionDefinitionImpl.class.getSimpleName());
             sb.append("[");
-            sb.append("argument="+ argument);
+            sb.append("argument=" + argument);
             sb.append(", qname=" + qname);
             sb.append(", schemaPath=" + schemaPath);
             sb.append(", extensionSchemaNodes=" + unknownNodes);
index 758478ba8cea169de30586f4b68d9b02d5ffbc98..c5dd60a79042d576b1de82684a9045f4aa802b4e 100644 (file)
@@ -17,20 +17,21 @@ import org.opendaylight.controller.yang.model.api.SchemaPath;
 import org.opendaylight.controller.yang.model.api.Status;
 import org.opendaylight.controller.yang.model.api.UnknownSchemaNode;
 import org.opendaylight.controller.yang.parser.builder.api.AbstractSchemaNodeBuilder;
+import org.opendaylight.controller.yang.parser.util.Comparators;
 
 public final class FeatureBuilder extends AbstractSchemaNodeBuilder {
     private boolean isBuilt;
     private final FeatureDefinitionImpl instance;
 
-    FeatureBuilder(final QName qname, final int line) {
-        super(qname, line);
+    FeatureBuilder(final int line, final QName qname) {
+        super(line, qname);
         instance = new FeatureDefinitionImpl(qname);
     }
 
     @Override
     public FeatureDefinitionImpl build() {
         if (!isBuilt) {
-            instance.setPath(path);
+            instance.setPath(schemaPath);
             instance.setDescription(description);
             instance.setReference(reference);
             instance.setStatus(status);
@@ -40,6 +41,7 @@ public final class FeatureBuilder extends AbstractSchemaNodeBuilder {
             for (UnknownSchemaNodeBuilder b : addedUnknownNodes) {
                 unknownNodes.add(b.build());
             }
+            Collections.sort(unknownNodes, Comparators.SCHEMA_NODE_COMP);
             instance.setUnknownSchemaNodes(unknownNodes);
 
             isBuilt = true;
index 1cfba2517f434a84266576c674cc8ba60f886b83..0f7179e791eeb761cf1b7528e94a96728eff348c 100644 (file)
@@ -14,6 +14,7 @@ import java.util.HashSet;
 import java.util.List;
 import java.util.Map;
 import java.util.Set;
+import java.util.TreeSet;
 
 import org.opendaylight.controller.yang.common.QName;
 import org.opendaylight.controller.yang.model.api.DataSchemaNode;
@@ -23,12 +24,15 @@ import org.opendaylight.controller.yang.model.api.Status;
 import org.opendaylight.controller.yang.model.api.TypeDefinition;
 import org.opendaylight.controller.yang.model.api.UnknownSchemaNode;
 import org.opendaylight.controller.yang.model.api.UsesNode;
+import org.opendaylight.controller.yang.parser.builder.api.Builder;
 import org.opendaylight.controller.yang.parser.builder.api.DataSchemaNodeBuilder;
 import org.opendaylight.controller.yang.parser.builder.api.GroupingBuilder;
 import org.opendaylight.controller.yang.parser.builder.api.TypeDefinitionBuilder;
 import org.opendaylight.controller.yang.parser.builder.api.UsesNodeBuilder;
+import org.opendaylight.controller.yang.parser.util.Comparators;
 
 public final class GroupingBuilderImpl implements GroupingBuilder {
+    private Builder parent;
     private boolean isBuilt;
     private final GroupingDefinitionImpl instance;
     private final int line;
@@ -62,6 +66,7 @@ public final class GroupingBuilderImpl implements GroupingBuilder {
 
     public GroupingBuilderImpl(GroupingBuilder builder) {
         qname = builder.getQName();
+        parent = builder.getParent();
         instance = new GroupingDefinitionImpl(qname);
         line = builder.getLine();
         schemaPath = builder.getPath();
@@ -100,8 +105,8 @@ public final class GroupingBuilderImpl implements GroupingBuilder {
             instance.setChildNodes(childs);
 
             // GROUPINGS
-            if(groupings == null) {
-                groupings = new HashSet<GroupingDefinition>();
+            if (groupings == null) {
+                groupings = new TreeSet<GroupingDefinition>(Comparators.SCHEMA_NODE_COMP);
                 for (GroupingBuilder builder : addedGroupings) {
                     groupings.add(builder.build());
                 }
@@ -109,8 +114,8 @@ public final class GroupingBuilderImpl implements GroupingBuilder {
             instance.setGroupings(groupings);
 
             // TYPEDEFS
-            if(typedefs == null) {
-                typedefs = new HashSet<TypeDefinition<?>>();
+            if (typedefs == null) {
+                typedefs = new TreeSet<TypeDefinition<?>>(Comparators.SCHEMA_NODE_COMP);
                 for (TypeDefinitionBuilder entry : addedTypedefs) {
                     typedefs.add(entry.build());
                 }
@@ -118,7 +123,7 @@ public final class GroupingBuilderImpl implements GroupingBuilder {
             instance.setTypeDefinitions(typedefs);
 
             // USES
-            if(usesNodes == null) {
+            if (usesNodes == null) {
                 usesNodes = new HashSet<UsesNode>();
                 for (UsesNodeBuilder builder : addedUsesNodes) {
                     usesNodes.add(builder.build());
@@ -127,11 +132,12 @@ public final class GroupingBuilderImpl implements GroupingBuilder {
             instance.setUses(usesNodes);
 
             // UNKNOWN NODES
-            if(unknownNodes == null) {
+            if (unknownNodes == null) {
                 unknownNodes = new ArrayList<UnknownSchemaNode>();
                 for (UnknownSchemaNodeBuilder b : addedUnknownNodes) {
                     unknownNodes.add(b.build());
                 }
+                Collections.sort(unknownNodes, Comparators.SCHEMA_NODE_COMP);
             }
             instance.setUnknownSchemaNodes(unknownNodes);
 
@@ -146,6 +152,16 @@ public final class GroupingBuilderImpl implements GroupingBuilder {
         return line;
     }
 
+    @Override
+    public Builder getParent() {
+        return parent;
+    }
+
+    @Override
+    public void setParent(final Builder parent) {
+        this.parent = parent;
+    }
+
     @Override
     public QName getQName() {
         return qname;
@@ -293,7 +309,6 @@ public final class GroupingBuilderImpl implements GroupingBuilder {
         this.unknownNodes = unknownNodes;
     }
 
-
     private final class GroupingDefinitionImpl implements GroupingDefinition {
         private final QName qname;
         private SchemaPath path;
@@ -363,7 +378,9 @@ public final class GroupingBuilderImpl implements GroupingBuilder {
 
         @Override
         public Set<DataSchemaNode> getChildNodes() {
-            return new HashSet<DataSchemaNode>(childNodes.values());
+            final Set<DataSchemaNode> result = new TreeSet<DataSchemaNode>(Comparators.SCHEMA_NODE_COMP);
+            result.addAll(childNodes.values());
+            return result;
         }
 
         private void setChildNodes(Map<QName, DataSchemaNode> childNodes) {
@@ -465,8 +482,7 @@ public final class GroupingBuilderImpl implements GroupingBuilder {
 
         @Override
         public String toString() {
-            StringBuilder sb = new StringBuilder(
-                    GroupingDefinitionImpl.class.getSimpleName());
+            StringBuilder sb = new StringBuilder(GroupingDefinitionImpl.class.getSimpleName());
             sb.append("[");
             sb.append("qname=" + qname);
             sb.append("]");
index 9cce264e60b131679b3ce52460ec8cda373a3a4c..14fca7d250cb4cf9300fcb0d4d4757156762d0ef 100644 (file)
@@ -17,6 +17,7 @@ import org.opendaylight.controller.yang.model.api.SchemaPath;
 import org.opendaylight.controller.yang.model.api.Status;
 import org.opendaylight.controller.yang.model.api.UnknownSchemaNode;
 import org.opendaylight.controller.yang.parser.builder.api.AbstractSchemaNodeBuilder;
+import org.opendaylight.controller.yang.parser.util.Comparators;
 
 public final class IdentitySchemaNodeBuilder extends AbstractSchemaNodeBuilder {
     private boolean isBuilt;
@@ -25,15 +26,15 @@ public final class IdentitySchemaNodeBuilder extends AbstractSchemaNodeBuilder {
     private IdentitySchemaNode baseIdentity;
     private String baseIdentityName;
 
-    IdentitySchemaNodeBuilder(final QName qname, final int line) {
-        super(qname, line);
+    IdentitySchemaNodeBuilder(final int line, final QName qname) {
+        super(line, qname);
         instance = new IdentitySchemaNodeImpl(qname);
     }
 
     @Override
     public IdentitySchemaNode build() {
         if (!isBuilt) {
-            instance.setPath(path);
+            instance.setPath(schemaPath);
             instance.setDescription(description);
             instance.setReference(reference);
             instance.setStatus(status);
@@ -51,6 +52,7 @@ public final class IdentitySchemaNodeBuilder extends AbstractSchemaNodeBuilder {
             for (UnknownSchemaNodeBuilder b : addedUnknownNodes) {
                 unknownNodes.add(b.build());
             }
+            Collections.sort(unknownNodes, Comparators.SCHEMA_NODE_COMP);
             instance.setUnknownSchemaNodes(unknownNodes);
 
             isBuilt = true;
index ea504afae15293c9b5b9ca48fe8439f8fbd1c111..3b505966f6859fbf0d455e94ad4a2a5030296fde 100644 (file)
@@ -32,13 +32,12 @@ import org.opendaylight.controller.yang.parser.util.YangParseException;
 public final class IdentityrefTypeBuilder extends AbstractTypeAwareBuilder implements TypeDefinitionBuilder {
     private static final String NAME = "identityref";
 
-    private final int line;
     private final String baseString;
     private final SchemaPath schemaPath;
     private QName baseQName;
 
     IdentityrefTypeBuilder(final String baseString, final SchemaPath schemaPath, final int line) {
-        this.line = line;
+        super(line, null);
         this.baseString = baseString;
         this.schemaPath = schemaPath;
     }
@@ -56,11 +55,6 @@ public final class IdentityrefTypeBuilder extends AbstractTypeAwareBuilder imple
         this.baseQName = baseQName;
     }
 
-    @Override
-    public int getLine() {
-        return line;
-    }
-
     @Override
     public TypeDefinition<?> getType() {
         return null;
index 9bbe5e9bd05d7225e9836ec2a932986ba0c64488..555a326c92775a0481aed2e592ae6ca75195c154 100644 (file)
@@ -22,14 +22,13 @@ import org.opendaylight.controller.yang.parser.builder.api.AbstractTypeAwareBuil
 import org.opendaylight.controller.yang.parser.builder.api.ConfigNode;
 import org.opendaylight.controller.yang.parser.builder.api.DataSchemaNodeBuilder;
 import org.opendaylight.controller.yang.parser.builder.api.GroupingMember;
+import org.opendaylight.controller.yang.parser.util.Comparators;
 
 public final class LeafListSchemaNodeBuilder extends AbstractTypeAwareBuilder implements DataSchemaNodeBuilder,
         GroupingMember, ConfigNode {
     private boolean isBuilt;
     private final LeafListSchemaNodeImpl instance;
-    private final int line;
     // SchemaNode args
-    private final QName qname;
     private SchemaPath schemaPath;
     private String description;
     private String reference;
@@ -44,17 +43,15 @@ public final class LeafListSchemaNodeBuilder extends AbstractTypeAwareBuilder im
     // LeafListSchemaNode args
     private boolean userOrdered;
 
-    public LeafListSchemaNodeBuilder(final QName qname, final SchemaPath schemaPath, final int line) {
-        this.qname = qname;
+    public LeafListSchemaNodeBuilder(final int line, final QName qname, final SchemaPath schemaPath) {
+        super(line, qname);
         this.schemaPath = schemaPath;
-        this.line = line;
         instance = new LeafListSchemaNodeImpl(qname);
         constraints = new ConstraintsBuilder(line);
     }
 
     public LeafListSchemaNodeBuilder(final LeafListSchemaNodeBuilder b) {
-        qname = b.getQName();
-        line = b.getLine();
+        super(b.getLine(), b.getQName());
         instance = new LeafListSchemaNodeImpl(qname);
 
         type = b.getType();
@@ -98,6 +95,7 @@ public final class LeafListSchemaNodeBuilder extends AbstractTypeAwareBuilder im
                 for (UnknownSchemaNodeBuilder b : addedUnknownNodes) {
                     unknownNodes.add(b.build());
                 }
+                Collections.sort(unknownNodes, Comparators.SCHEMA_NODE_COMP);
             }
             instance.setUnknownSchemaNodes(unknownNodes);
 
@@ -106,16 +104,6 @@ public final class LeafListSchemaNodeBuilder extends AbstractTypeAwareBuilder im
         return instance;
     }
 
-    @Override
-    public int getLine() {
-        return line;
-    }
-
-    @Override
-    public QName getQName() {
-        return qname;
-    }
-
     public SchemaPath getPath() {
         return schemaPath;
     }
@@ -208,6 +196,48 @@ public final class LeafListSchemaNodeBuilder extends AbstractTypeAwareBuilder im
         this.unknownNodes = unknownNodes;
     }
 
+    @Override
+    public int hashCode() {
+        final int prime = 31;
+        int result = 1;
+        result = prime * result + ((schemaPath == null) ? 0 : schemaPath.hashCode());
+        return result;
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (this == obj) {
+            return true;
+        }
+        if (obj == null) {
+            return false;
+        }
+        if (getClass() != obj.getClass()) {
+            return false;
+        }
+        LeafListSchemaNodeBuilder other = (LeafListSchemaNodeBuilder) obj;
+        if (schemaPath == null) {
+            if (other.schemaPath != null) {
+                return false;
+            }
+        } else if (!schemaPath.equals(other.schemaPath)) {
+            return false;
+        }
+        if (parent == null) {
+            if (other.parent != null) {
+                return false;
+            }
+        } else if (!parent.equals(other.parent)) {
+            return false;
+        }
+        return true;
+    }
+
+    @Override
+    public String toString() {
+        return "leaf-list " + qname.getLocalName();
+    }
+
     private final class LeafListSchemaNodeImpl implements LeafListSchemaNode {
         private final QName qname;
         private SchemaPath path;
index 54720b44e1afac2706ad5265cf8d98b9db8ce1a6..071447b9c93f0f58ea7d8a8eb20969d4cbddb505 100644 (file)
@@ -22,15 +22,14 @@ import org.opendaylight.controller.yang.parser.builder.api.AbstractTypeAwareBuil
 import org.opendaylight.controller.yang.parser.builder.api.ConfigNode;
 import org.opendaylight.controller.yang.parser.builder.api.DataSchemaNodeBuilder;
 import org.opendaylight.controller.yang.parser.builder.api.GroupingMember;
+import org.opendaylight.controller.yang.parser.util.Comparators;
 
 public final class LeafSchemaNodeBuilder extends AbstractTypeAwareBuilder implements DataSchemaNodeBuilder,
         GroupingMember, ConfigNode {
     private boolean isBuilt;
     private final LeafSchemaNodeImpl instance;
-    private final int line;
     // SchemaNode args
-    private final QName qname;
-    private SchemaPath path;
+    private SchemaPath schemaPath;
     private String description;
     private String reference;
     private Status status = Status.CURRENT;
@@ -46,19 +45,17 @@ public final class LeafSchemaNodeBuilder extends AbstractTypeAwareBuilder implem
     private String unitsStr;
 
     public LeafSchemaNodeBuilder(final QName qname, final SchemaPath schemaPath, final int line) {
-        this.qname = qname;
-        this.path = schemaPath;
-        this.line = line;
+        super(line, qname);
+        this.schemaPath = schemaPath;
         instance = new LeafSchemaNodeImpl(qname);
         constraints = new ConstraintsBuilder(line);
     }
 
     public LeafSchemaNodeBuilder(final LeafSchemaNodeBuilder b) {
-        qname = b.getQName();
-        line = b.getLine();
+        super(b.getLine(), b.getQName());
         instance = new LeafSchemaNodeImpl(qname);
         constraints = b.getConstraints();
-        path = b.getPath();
+        schemaPath = b.getPath();
 
         type = b.getType();
         typedef = b.getTypedef();
@@ -79,7 +76,7 @@ public final class LeafSchemaNodeBuilder extends AbstractTypeAwareBuilder implem
     @Override
     public LeafSchemaNode build() {
         if (!isBuilt) {
-            instance.setPath(path);
+            instance.setPath(schemaPath);
             instance.setConstraints(constraints.build());
             instance.setDescription(description);
             instance.setReference(reference);
@@ -103,6 +100,7 @@ public final class LeafSchemaNodeBuilder extends AbstractTypeAwareBuilder implem
                 for (UnknownSchemaNodeBuilder b : addedUnknownNodes) {
                     unknownNodes.add(b.build());
                 }
+                Collections.sort(unknownNodes, Comparators.SCHEMA_NODE_COMP);
             }
             instance.setUnknownSchemaNodes(unknownNodes);
 
@@ -111,23 +109,13 @@ public final class LeafSchemaNodeBuilder extends AbstractTypeAwareBuilder implem
         return instance;
     }
 
-    @Override
-    public int getLine() {
-        return line;
-    }
-
-    @Override
-    public QName getQName() {
-        return qname;
-    }
-
     public SchemaPath getPath() {
-        return path;
+        return schemaPath;
     }
 
     @Override
     public void setPath(final SchemaPath path) {
-        this.path = path;
+        this.schemaPath = path;
     }
 
     @Override
@@ -221,6 +209,43 @@ public final class LeafSchemaNodeBuilder extends AbstractTypeAwareBuilder implem
         this.unitsStr = unitsStr;
     }
 
+    @Override
+    public int hashCode() {
+        final int prime = 31;
+        int result = 1;
+        result = prime * result + ((schemaPath == null) ? 0 : schemaPath.hashCode());
+        return result;
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (this == obj) {
+            return true;
+        }
+        if (obj == null) {
+            return false;
+        }
+        if (getClass() != obj.getClass()) {
+            return false;
+        }
+        LeafSchemaNodeBuilder other = (LeafSchemaNodeBuilder) obj;
+        if (schemaPath == null) {
+            if (other.schemaPath != null) {
+                return false;
+            }
+        } else if (!schemaPath.equals(other.schemaPath)) {
+            return false;
+        }
+        if (parent == null) {
+            if (other.parent != null) {
+                return false;
+            }
+        } else if (!parent.equals(other.parent)) {
+            return false;
+        }
+        return true;
+    }
+
     @Override
     public String toString() {
         return "leaf " + qname.getLocalName();
index ce87e3bb99fac9ec4dfa24aa56780d10043ca8f7..a99e6a7406e45bfbe6d7ded27f33c3a2ab2912f9 100644 (file)
@@ -9,11 +9,12 @@ package org.opendaylight.controller.yang.parser.builder.impl;
 
 import java.util.ArrayList;
 import java.util.Collections;
-import java.util.HashMap;
 import java.util.HashSet;
 import java.util.List;
 import java.util.Map;
 import java.util.Set;
+import java.util.TreeMap;
+import java.util.TreeSet;
 
 import org.opendaylight.controller.yang.common.QName;
 import org.opendaylight.controller.yang.model.api.AugmentationSchema;
@@ -33,15 +34,14 @@ import org.opendaylight.controller.yang.parser.builder.api.ConfigNode;
 import org.opendaylight.controller.yang.parser.builder.api.DataSchemaNodeBuilder;
 import org.opendaylight.controller.yang.parser.builder.api.GroupingBuilder;
 import org.opendaylight.controller.yang.parser.builder.api.GroupingMember;
-import org.opendaylight.controller.yang.parser.builder.api.TypeDefinitionAwareBuilder;
 import org.opendaylight.controller.yang.parser.builder.api.TypeDefinitionBuilder;
 import org.opendaylight.controller.yang.parser.builder.api.UsesNodeBuilder;
+import org.opendaylight.controller.yang.parser.util.Comparators;
 
 public final class ListSchemaNodeBuilder extends AbstractDataNodeContainerBuilder implements DataSchemaNodeBuilder,
-        AugmentationTargetBuilder, TypeDefinitionAwareBuilder, GroupingMember, ConfigNode {
+        AugmentationTargetBuilder, GroupingMember, ConfigNode {
     private boolean isBuilt;
     private final ListSchemaNodeImpl instance;
-    private final int line;
     // SchemaNode args
     private SchemaPath schemaPath;
     private String description;
@@ -66,17 +66,15 @@ public final class ListSchemaNodeBuilder extends AbstractDataNodeContainerBuilde
     private List<QName> keyDefinition = Collections.emptyList();
     private boolean userOrdered;
 
-    public ListSchemaNodeBuilder(final QName qname, final SchemaPath schemaPath, final int line) {
-        super(qname);
+    public ListSchemaNodeBuilder(final int line, final QName qname, final SchemaPath schemaPath) {
+        super(line, qname);
         this.schemaPath = schemaPath;
-        this.line = line;
         instance = new ListSchemaNodeImpl(qname);
         constraints = new ConstraintsBuilder(line);
     }
 
     public ListSchemaNodeBuilder(final ListSchemaNodeBuilder b) {
-        super(b.getQName());
-        line = b.getLine();
+        super(b.getLine(), b.getQName());
         instance = new ListSchemaNodeImpl(b.getQName());
         constraints = b.getConstraints();
         schemaPath = b.getPath();
@@ -116,7 +114,7 @@ public final class ListSchemaNodeBuilder extends AbstractDataNodeContainerBuilde
             instance.setUserOrdered(userOrdered);
 
             // CHILD NODES
-            final Map<QName, DataSchemaNode> childs = new HashMap<QName, DataSchemaNode>();
+            final Map<QName, DataSchemaNode> childs = new TreeMap<QName, DataSchemaNode>(Comparators.QNAME_COMP);
             if (childNodes == null) {
                 for (DataSchemaNodeBuilder node : addedChildNodes) {
                     childs.put(node.getQName(), node.build());
@@ -130,7 +128,7 @@ public final class ListSchemaNodeBuilder extends AbstractDataNodeContainerBuilde
 
             // TYPEDEFS
             if (typedefs == null) {
-                typedefs = new HashSet<TypeDefinition<?>>();
+                typedefs = new TreeSet<TypeDefinition<?>>(Comparators.SCHEMA_NODE_COMP);
                 for (TypeDefinitionBuilder entry : addedTypedefs) {
                     typedefs.add(entry.build());
                 }
@@ -148,7 +146,7 @@ public final class ListSchemaNodeBuilder extends AbstractDataNodeContainerBuilde
 
             // GROUPINGS
             if (groupings == null) {
-                groupings = new HashSet<GroupingDefinition>();
+                groupings = new TreeSet<GroupingDefinition>(Comparators.SCHEMA_NODE_COMP);
                 for (GroupingBuilder builder : addedGroupings) {
                     groupings.add(builder.build());
                 }
@@ -170,6 +168,7 @@ public final class ListSchemaNodeBuilder extends AbstractDataNodeContainerBuilde
                 for (UnknownSchemaNodeBuilder b : addedUnknownNodes) {
                     unknownNodes.add(b.build());
                 }
+                Collections.sort(unknownNodes, Comparators.SCHEMA_NODE_COMP);
             }
             instance.setUnknownSchemaNodes(unknownNodes);
 
@@ -187,11 +186,6 @@ public final class ListSchemaNodeBuilder extends AbstractDataNodeContainerBuilde
         build();
     }
 
-    @Override
-    public int getLine() {
-        return line;
-    }
-
     @Override
     public Set<TypeDefinitionBuilder> getTypeDefinitionBuilders() {
         return addedTypedefs;
@@ -334,6 +328,48 @@ public final class ListSchemaNodeBuilder extends AbstractDataNodeContainerBuilde
         this.unknownNodes = unknownNodes;
     }
 
+    @Override
+    public int hashCode() {
+        final int prime = 31;
+        int result = 1;
+        result = prime * result + ((schemaPath == null) ? 0 : schemaPath.hashCode());
+        return result;
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (this == obj) {
+            return true;
+        }
+        if (obj == null) {
+            return false;
+        }
+        if (getClass() != obj.getClass()) {
+            return false;
+        }
+        ListSchemaNodeBuilder other = (ListSchemaNodeBuilder) obj;
+        if (schemaPath == null) {
+            if (other.schemaPath != null) {
+                return false;
+            }
+        } else if (!schemaPath.equals(other.schemaPath)) {
+            return false;
+        }
+        if (parent == null) {
+            if (other.parent != null) {
+                return false;
+            }
+        } else if (!parent.equals(other.parent)) {
+            return false;
+        }
+        return true;
+    }
+
+    @Override
+    public String toString() {
+        return "list " + qname.getLocalName();
+    }
+
     public final class ListSchemaNodeImpl implements ListSchemaNode {
         private final QName qname;
         private SchemaPath path;
index 0a9b6ddf373355736e4da8247c828ef155fc37b8..57e87b33ad855bb345bcd0cf5d1459ac8304ca62 100644 (file)
@@ -13,10 +13,13 @@ import java.util.Collections;
 import java.util.Date;
 import java.util.HashMap;
 import java.util.HashSet;
+import java.util.LinkedHashSet;
 import java.util.LinkedList;
 import java.util.List;
 import java.util.Map;
 import java.util.Set;
+import java.util.TreeMap;
+import java.util.TreeSet;
 
 import org.opendaylight.controller.yang.common.QName;
 import org.opendaylight.controller.yang.model.api.AugmentationSchema;
@@ -41,9 +44,9 @@ import org.opendaylight.controller.yang.parser.builder.api.DataSchemaNodeBuilder
 import org.opendaylight.controller.yang.parser.builder.api.GroupingBuilder;
 import org.opendaylight.controller.yang.parser.builder.api.SchemaNodeBuilder;
 import org.opendaylight.controller.yang.parser.builder.api.TypeAwareBuilder;
-import org.opendaylight.controller.yang.parser.builder.api.TypeDefinitionAwareBuilder;
 import org.opendaylight.controller.yang.parser.builder.api.TypeDefinitionBuilder;
 import org.opendaylight.controller.yang.parser.builder.api.UsesNodeBuilder;
+import org.opendaylight.controller.yang.parser.util.Comparators;
 import org.opendaylight.controller.yang.parser.util.RefineHolder;
 import org.opendaylight.controller.yang.parser.util.YangParseException;
 
@@ -67,17 +70,19 @@ public class ModuleBuilder implements DataNodeContainerBuilder {
      * Holds all child (DataSchemaNode) nodes: anyxml, choice, case, container,
      * list, leaf, leaf-list.
      */
-    private final Map<List<String>, DataSchemaNodeBuilder> childNodes = new HashMap<List<String>, DataSchemaNodeBuilder>();
+    private final Set<DataSchemaNodeBuilder> childNodes = new HashSet<DataSchemaNodeBuilder>();
 
-    private final Map<List<String>, GroupingBuilder> addedGroupings = new HashMap<List<String>, GroupingBuilder>();
+    private final Set<GroupingBuilder> addedGroupings = new HashSet<GroupingBuilder>();
     private final List<AugmentationSchemaBuilder> addedAugments = new ArrayList<AugmentationSchemaBuilder>();
-    private final Map<List<String>, UsesNodeBuilder> addedUsesNodes = new HashMap<List<String>, UsesNodeBuilder>();
-    private final Map<List<String>, RpcDefinitionBuilder> addedRpcs = new HashMap<List<String>, RpcDefinitionBuilder>();
+    private final List<AugmentationSchemaBuilder> allAugments = new ArrayList<AugmentationSchemaBuilder>();
+    private final Set<UsesNodeBuilder> addedUsesNodes = new HashSet<UsesNodeBuilder>();
+    private final List<UsesNodeBuilder> allUsesNodes = new ArrayList<UsesNodeBuilder>();
+    private final Set<RpcDefinitionBuilder> addedRpcs = new HashSet<RpcDefinitionBuilder>();
     private final Set<NotificationBuilder> addedNotifications = new HashSet<NotificationBuilder>();
     private final Set<IdentitySchemaNodeBuilder> addedIdentities = new HashSet<IdentitySchemaNodeBuilder>();
-    private final Map<List<String>, FeatureBuilder> addedFeatures = new HashMap<List<String>, FeatureBuilder>();
+    private final Set<FeatureBuilder> addedFeatures = new HashSet<FeatureBuilder>();
     private final Map<List<String>, DeviationBuilder> addedDeviations = new HashMap<List<String>, DeviationBuilder>();
-    private final Map<List<String>, TypeDefinitionBuilder> addedTypedefs = new HashMap<List<String>, TypeDefinitionBuilder>();
+    private final Set<TypeDefinitionBuilder> addedTypedefs = new HashSet<TypeDefinitionBuilder>();
     private final Map<List<String>, UnionTypeBuilder> addedUnionTypes = new HashMap<List<String>, UnionTypeBuilder>();
     private final List<ExtensionBuilder> addedExtensions = new ArrayList<ExtensionBuilder>();
     private final Map<List<String>, List<UnknownSchemaNodeBuilder>> addedUnknownNodes = new HashMap<List<String>, List<UnknownSchemaNodeBuilder>>();
@@ -102,27 +107,43 @@ public class ModuleBuilder implements DataNodeContainerBuilder {
         instance.setNamespace(namespace);
 
         // TYPEDEFS
-        final Set<TypeDefinition<?>> typedefs = buildModuleTypedefs(addedTypedefs);
+        final Set<TypeDefinition<?>> typedefs = new TreeSet<TypeDefinition<?>>(Comparators.SCHEMA_NODE_COMP);
+        for (TypeDefinitionBuilder tdb : addedTypedefs) {
+            typedefs.add(tdb.build());
+        }
         instance.setTypeDefinitions(typedefs);
 
         // CHILD NODES
-        final Map<QName, DataSchemaNode> children = buildModuleChildNodes(childNodes);
+        final Map<QName, DataSchemaNode> children = new TreeMap<QName, DataSchemaNode>(Comparators.QNAME_COMP);
+        for (DataSchemaNodeBuilder child : childNodes) {
+            children.put(child.getQName(), child.build());
+        }
         instance.setChildNodes(children);
 
         // GROUPINGS
-        final Set<GroupingDefinition> groupings = buildModuleGroupings(addedGroupings);
+        final Set<GroupingDefinition> groupings = new TreeSet<GroupingDefinition>(Comparators.SCHEMA_NODE_COMP);
+        for (GroupingBuilder gb : addedGroupings) {
+            groupings.add(gb.build());
+        }
         instance.setGroupings(groupings);
 
         // USES
-        final Set<UsesNode> usesDefinitions = buildUsesNodes(addedUsesNodes);
+        final Set<UsesNode> usesDefinitions = new HashSet<UsesNode>();
+        for (UsesNodeBuilder unb : addedUsesNodes) {
+            usesDefinitions.add(unb.build());
+        }
         instance.setUses(usesDefinitions);
 
         // FEATURES
-        final Set<FeatureDefinition> features = buildModuleFeatures(addedFeatures);
+        final Set<FeatureDefinition> features = new TreeSet<FeatureDefinition>(Comparators.SCHEMA_NODE_COMP);
+        for (FeatureBuilder fb : addedFeatures) {
+            features.add(fb.build());
+        }
         instance.setFeatures(features);
 
         // NOTIFICATIONS
-        final Set<NotificationDefinition> notifications = new HashSet<NotificationDefinition>();
+        final Set<NotificationDefinition> notifications = new TreeSet<NotificationDefinition>(
+                Comparators.SCHEMA_NODE_COMP);
         for (NotificationBuilder entry : addedNotifications) {
             notifications.add(entry.build());
         }
@@ -136,7 +157,10 @@ public class ModuleBuilder implements DataNodeContainerBuilder {
         instance.setAugmentations(augmentations);
 
         // RPCs
-        final Set<RpcDefinition> rpcs = buildModuleRpcs(addedRpcs);
+        final Set<RpcDefinition> rpcs = new TreeSet<RpcDefinition>(Comparators.SCHEMA_NODE_COMP);
+        for (RpcDefinitionBuilder rpc : addedRpcs) {
+            rpcs.add(rpc.build());
+        }
         instance.setRpcs(rpcs);
 
         // DEVIATIONS
@@ -148,15 +172,16 @@ public class ModuleBuilder implements DataNodeContainerBuilder {
 
         // EXTENSIONS
         final List<ExtensionDefinition> extensions = new ArrayList<ExtensionDefinition>();
-        for (ExtensionBuilder b : addedExtensions) {
-            extensions.add(b.build());
+        for (ExtensionBuilder eb : addedExtensions) {
+            extensions.add(eb.build());
         }
+        Collections.sort(extensions, Comparators.SCHEMA_NODE_COMP);
         instance.setExtensionSchemaNodes(extensions);
 
         // IDENTITIES
-        final Set<IdentitySchemaNode> identities = new HashSet<IdentitySchemaNode>();
-        for (IdentitySchemaNodeBuilder idBuilder : addedIdentities) {
-            identities.add(idBuilder.build());
+        final Set<IdentitySchemaNode> identities = new TreeSet<IdentitySchemaNode>(Comparators.SCHEMA_NODE_COMP);
+        for (IdentitySchemaNodeBuilder id : addedIdentities) {
+            identities.add(id.build());
         }
         instance.setIdentities(identities);
 
@@ -172,6 +197,16 @@ public class ModuleBuilder implements DataNodeContainerBuilder {
         return 0;
     }
 
+    @Override
+    public Builder getParent() {
+        return null;
+    }
+
+    @Override
+    public void setParent(Builder parent) {
+        throw new YangParseException(name, 0, "Can not set parent to module");
+    }
+
     @Override
     public QName getQName() {
         return new QName(namespace, revision, prefix, name);
@@ -184,16 +219,7 @@ public class ModuleBuilder implements DataNodeContainerBuilder {
 
     @Override
     public Set<TypeDefinitionBuilder> getTypeDefinitionBuilders() {
-        final Set<TypeDefinitionBuilder> typeDefinitions = new HashSet<TypeDefinitionBuilder>();
-        for (final Map.Entry<List<String>, TypeDefinitionBuilder> entry : addedTypedefs.entrySet()) {
-            final List<String> key = entry.getKey();
-            final TypeDefinitionBuilder typedefBuilder = entry.getValue();
-            if (key.size() == 2) {
-                typeDefinitions.add(typedefBuilder);
-
-            }
-        }
-        return typeDefinitions;
+        return addedTypedefs;
     }
 
     public void enterNode(final Builder node) {
@@ -220,14 +246,6 @@ public class ModuleBuilder implements DataNodeContainerBuilder {
         }
     }
 
-    public Builder getModuleNode(final List<String> path) {
-        return childNodes.get(path);
-    }
-
-    public GroupingBuilder getGrouping(final List<String> path) {
-        return addedGroupings.get(path);
-    }
-
     @Override
     public Set<GroupingDefinition> getGroupings() {
         return Collections.emptySet();
@@ -235,17 +253,7 @@ public class ModuleBuilder implements DataNodeContainerBuilder {
 
     @Override
     public Set<GroupingBuilder> getGroupingBuilders() {
-        final Set<GroupingBuilder> result = new HashSet<GroupingBuilder>();
-        for (Map.Entry<List<String>, GroupingBuilder> entry : addedGroupings.entrySet()) {
-            if (entry.getKey().size() == 2) {
-                result.add(entry.getValue());
-            }
-        }
-        return result;
-    }
-
-    public Builder getModuleTypedef(final List<String> path) {
-        return addedTypedefs.get(path);
+        return addedGroupings;
     }
 
     @Override
@@ -254,31 +262,23 @@ public class ModuleBuilder implements DataNodeContainerBuilder {
     }
 
     public Set<DataSchemaNodeBuilder> getChildNodeBuilders() {
-        final Set<DataSchemaNodeBuilder> children = new HashSet<DataSchemaNodeBuilder>();
-        for (Map.Entry<List<String>, DataSchemaNodeBuilder> entry : childNodes.entrySet()) {
-            final List<String> path = entry.getKey();
-            final DataSchemaNodeBuilder child = entry.getValue();
-            if (path.size() == 2) {
-                children.add(child);
-            }
-        }
-        return children;
+        return childNodes;
     }
 
     public Map<List<String>, TypeAwareBuilder> getDirtyNodes() {
         return dirtyNodes;
     }
 
-    public List<AugmentationSchemaBuilder> getAugments() {
-        return addedAugments;
+    public List<AugmentationSchemaBuilder> getAllAugments() {
+        return allAugments;
     }
 
     public Set<IdentitySchemaNodeBuilder> getIdentities() {
         return addedIdentities;
     }
 
-    public Map<List<String>, UsesNodeBuilder> getUsesNodes() {
-        return addedUsesNodes;
+    public List<UsesNodeBuilder> getAllUsesNodes() {
+        return allUsesNodes;
     }
 
     public List<UnknownSchemaNodeBuilder> getUnknownNodes() {
@@ -289,26 +289,6 @@ public class ModuleBuilder implements DataNodeContainerBuilder {
         return result;
     }
 
-    public Set<TypeDefinitionBuilder> getModuleTypedefs() {
-        final Set<TypeDefinitionBuilder> typedefs = new HashSet<TypeDefinitionBuilder>();
-        for (Map.Entry<List<String>, TypeDefinitionBuilder> entry : addedTypedefs.entrySet()) {
-            if (entry.getKey().size() == 2) {
-                typedefs.add(entry.getValue());
-            }
-        }
-        return typedefs;
-    }
-
-    public Set<GroupingBuilder> getModuleGroupings() {
-        final Set<GroupingBuilder> groupings = new HashSet<GroupingBuilder>();
-        for (Map.Entry<List<String>, GroupingBuilder> entry : addedGroupings.entrySet()) {
-            if (entry.getKey().size() == 2) {
-                groupings.add(entry.getValue());
-            }
-        }
-        return groupings;
-    }
-
     public String getName() {
         return name;
     }
@@ -381,159 +361,158 @@ public class ModuleBuilder implements DataNodeContainerBuilder {
     }
 
     public ExtensionBuilder addExtension(final QName qname, final int line) {
-        final ExtensionBuilder builder = new ExtensionBuilder(qname, line);
+        final ExtensionBuilder builder = new ExtensionBuilder(line, qname);
         addedExtensions.add(builder);
         return builder;
     }
 
     @Override
     public void addChildNode(DataSchemaNodeBuilder child) {
-        final List<String> pathToChild = new ArrayList<String>();
-        for (QName qname : child.getPath().getPath()) {
-            pathToChild.add(qname.getLocalName());
-        }
-        if (childNodes.containsKey(pathToChild)) {
-            throw new YangParseException(this.name, child.getLine(), "Failed to add child node "
-                    + child.getQName().getLocalName() + ": node already exists in context.");
+        for (DataSchemaNodeBuilder childNode : childNodes) {
+            if (childNode.getQName().getLocalName().equals(child.getQName().getLocalName())) {
+                throw new YangParseException(name, child.getLine(), "Duplicate node found at line "
+                        + childNode.getLine());
+            }
         }
-        childNodes.put(pathToChild, child);
+        childNodes.add(child);
     }
 
-    public ContainerSchemaNodeBuilder addContainerNode(final SchemaPath schemaPath, final QName containerName,
-            final List<String> parentPath, final int line) {
-        final List<String> pathToNode = new ArrayList<String>(parentPath);
-        final ContainerSchemaNodeBuilder containerBuilder = new ContainerSchemaNodeBuilder(containerName, schemaPath, line);
-        updateParent(containerBuilder, line, "container");
+    public ContainerSchemaNodeBuilder addContainerNode(final int line, final QName containerName,
+            final SchemaPath schemaPath) {
+        final ContainerSchemaNodeBuilder builder = new ContainerSchemaNodeBuilder(line, containerName, schemaPath);
 
-        pathToNode.add(containerName.getLocalName());
-        childNodes.put(pathToNode, containerBuilder);
+        Builder parent = getActualNode();
+        builder.setParent(parent);
+        addChildToParent(parent, builder, containerName.getLocalName());
 
-        return containerBuilder;
+        return builder;
     }
 
-    public ListSchemaNodeBuilder addListNode(final SchemaPath schemaPath, final QName listName, final List<String> parentPath, final int line) {
-        final List<String> pathToNode = new ArrayList<String>(parentPath);
-        final ListSchemaNodeBuilder listBuilder = new ListSchemaNodeBuilder(listName, schemaPath, line);
-        updateParent(listBuilder, line, "list");
+    public ListSchemaNodeBuilder addListNode(final int line, final QName listName, final SchemaPath schemaPath) {
+        final ListSchemaNodeBuilder builder = new ListSchemaNodeBuilder(line, listName, schemaPath);
 
-        pathToNode.add(listName.getLocalName());
-        childNodes.put(pathToNode, listBuilder);
+        Builder parent = getActualNode();
+        builder.setParent(parent);
+        addChildToParent(parent, builder, listName.getLocalName());
 
-        return listBuilder;
+        return builder;
     }
 
-    public LeafSchemaNodeBuilder addLeafNode(final SchemaPath schemaPath, final QName leafName, final List<String> parentPath, final int line) {
-        final List<String> pathToNode = new ArrayList<String>(parentPath);
-        final LeafSchemaNodeBuilder leafBuilder = new LeafSchemaNodeBuilder(leafName, schemaPath, line);
-        updateParent(leafBuilder, line, "leaf");
+    public LeafSchemaNodeBuilder addLeafNode(final int line, final QName leafName, final SchemaPath schemaPath) {
+        final LeafSchemaNodeBuilder builder = new LeafSchemaNodeBuilder(leafName, schemaPath, line);
 
-        pathToNode.add(leafName.getLocalName());
-        childNodes.put(pathToNode, leafBuilder);
+        Builder parent = getActualNode();
+        builder.setParent(parent);
+        addChildToParent(parent, builder, leafName.getLocalName());
 
-        return leafBuilder;
+        return builder;
     }
 
-    public LeafListSchemaNodeBuilder addLeafListNode(final SchemaPath schemaPath, final QName qname, final List<String> parentPath, final int line) {
-        final List<String> pathToNode = new ArrayList<String>(parentPath);
-        final LeafListSchemaNodeBuilder leafListBuilder = new LeafListSchemaNodeBuilder(qname, schemaPath, line);
-        updateParent(leafListBuilder, line, "leaf-list");
+    public LeafListSchemaNodeBuilder addLeafListNode(final int line, final QName leafListName,
+            final SchemaPath schemaPath) {
+        final LeafListSchemaNodeBuilder builder = new LeafListSchemaNodeBuilder(line, leafListName, schemaPath);
 
-        pathToNode.add(qname.getLocalName());
-        childNodes.put(pathToNode, leafListBuilder);
+        Builder parent = getActualNode();
+        builder.setParent(parent);
+        addChildToParent(parent, builder, leafListName.getLocalName());
 
-        return leafListBuilder;
+        return builder;
     }
 
     @Override
     public void addGrouping(GroupingBuilder groupingBuilder) {
-        final List<String> pathToGroup = new ArrayList<String>();
-        for (QName qname : groupingBuilder.getPath().getPath()) {
-            pathToGroup.add(qname.getLocalName());
-        }
-        if (addedGroupings.containsKey(pathToGroup)) {
-            throw new YangParseException(this.name, groupingBuilder.getLine(), "Failed to add grouping "
-                    + groupingBuilder.getQName().getLocalName() + ": grouping already exists in context.");
+        for (GroupingBuilder gb : addedGroupings) {
+            if (gb.getQName().getLocalName().equals(groupingBuilder.getQName().getLocalName())) {
+                throw new YangParseException(name, groupingBuilder.getLine(), "Duplicate node found at line "
+                        + gb.getLine());
+            }
         }
-        addedGroupings.put(pathToGroup, groupingBuilder);
+        addedGroupings.add(groupingBuilder);
     }
 
-    public GroupingBuilder addGrouping(final QName qname, final List<String> parentPath, final int line) {
-        final List<String> pathToGroup = new ArrayList<String>(parentPath);
+    public GroupingBuilder addGrouping(final int line, final QName qname) {
         final GroupingBuilder builder = new GroupingBuilderImpl(qname, line);
 
-        if (!(actualPath.isEmpty())) {
-            final Builder parent = actualPath.getFirst();
+        Builder parent = getActualNode();
+        builder.setParent(parent);
+
+        if (parent == null) {
+            for (GroupingBuilder child : addedGroupings) {
+                if (child.getQName().getLocalName().equals(qname.getLocalName())) {
+                    throw new YangParseException(name, line, "Duplicate node found at line " + child.getLine());
+                }
+            }
+            addedGroupings.add(builder);
+        } else {
             if (parent instanceof DataNodeContainerBuilder) {
-                ((DataNodeContainerBuilder) parent).addGrouping(builder);
+                DataNodeContainerBuilder parentNode = (DataNodeContainerBuilder) parent;
+                for (DataSchemaNodeBuilder child : parentNode.getChildNodeBuilders()) {
+                    if (child.getQName().getLocalName().equals(qname.getLocalName())) {
+                        throw new YangParseException(name, line, "Duplicate node found at line " + child.getLine());
+                    }
+                }
+                parentNode.addGrouping(builder);
+            } else if (parent instanceof RpcDefinitionBuilder) {
+                RpcDefinitionBuilder parentNode = (RpcDefinitionBuilder) parent;
+                for (GroupingBuilder child : parentNode.getGroupings()) {
+                    if (child.getQName().getLocalName().equals(qname.getLocalName())) {
+                        throw new YangParseException(name, line, "Duplicate node found at line " + child.getLine());
+                    }
+                }
+                parentNode.addGrouping(builder);
             } else {
                 throw new YangParseException(name, line, "Unresolved parent of grouping " + qname.getLocalName());
             }
         }
 
-        pathToGroup.add(qname.getLocalName());
-        addedGroupings.put(pathToGroup, builder);
-
         return builder;
     }
 
-    public AugmentationSchemaBuilder addAugment(final String name, final List<String> parentPath, final int line) {
-        final List<String> pathToAugment = new ArrayList<String>(parentPath);
-        Builder parent = null;
-        if (!(actualPath.isEmpty())) {
-            parent = actualPath.getFirst();
-        }
-        final AugmentationSchemaBuilder builder = new AugmentationSchemaBuilderImpl(name, line, parent);
+    public AugmentationSchemaBuilder addAugment(final int line, final String augmentTargetStr) {
+        final AugmentationSchemaBuilder builder = new AugmentationSchemaBuilderImpl(line, augmentTargetStr);
 
-        // augment can only be in 'module' or 'uses' statement
-        if (parent != null) {
+        Builder parent = getActualNode();
+        builder.setParent(parent);
+
+        if (parent == null) {
+            addedAugments.add(builder);
+        } else {
+            // augment can only be in 'module' or 'uses' statement
             if (parent instanceof UsesNodeBuilder) {
                 ((UsesNodeBuilder) parent).addAugment(builder);
             } else {
-                throw new YangParseException(this.name, line, "Unresolved parent of augment " + name);
+                throw new YangParseException(name, line, "Augment can be declared only under module or uses.");
             }
         }
-
-        pathToAugment.add(name);
-        addedAugments.add(builder);
+        allAugments.add(builder);
 
         return builder;
     }
 
     @Override
     public void addUsesNode(UsesNodeBuilder usesBuilder) {
-        final List<String> pathToTypedef = new ArrayList<String>();
-        for (QName qname : usesBuilder.getParent().getPath().getPath()) {
-            pathToTypedef.add(qname.getLocalName());
-        }
-        if (addedUsesNodes.containsKey(pathToTypedef)) {
-            throw new YangParseException(this.name, usesBuilder.getLine(), "Failed to add uses node "
-                    + usesBuilder.getGroupingName() + ": uses already exists in context.");
-        }
-        addedUsesNodes.put(pathToTypedef, usesBuilder);
+        addedUsesNodes.add(usesBuilder);
+        allUsesNodes.add(usesBuilder);
     }
 
-    public UsesNodeBuilder addUsesNode(final String groupingPathStr, final List<String> parentPath, final int line) {
-        final List<String> pathToUses = new ArrayList<String>(parentPath);
-        Builder parent = null;
-        if (!actualPath.isEmpty()) {
-            parent = actualPath.getFirst();
-        }
-        if (parent != null && !(parent instanceof DataNodeContainerBuilder)) {
-            throw new YangParseException(name, line, "Unresolved parent of uses " + groupingPathStr);
-        }
-        final UsesNodeBuilder usesBuilder;
+    public UsesNodeBuilder addUsesNode(final int line, final String groupingPathStr) {
+        final UsesNodeBuilder usesBuilder = new UsesNodeBuilderImpl(line, groupingPathStr);
+
+        Builder parent = getActualNode();
+        usesBuilder.setParent(parent);
+
         if (parent == null) {
-            usesBuilder = new UsesNodeBuilderImpl(groupingPathStr, line, this);
+            addedUsesNodes.add(usesBuilder);
         } else {
-            usesBuilder = new UsesNodeBuilderImpl(groupingPathStr, line, (DataNodeContainerBuilder) parent);
+            if (!(parent instanceof DataNodeContainerBuilder)) {
+                throw new YangParseException(name, line, "Unresolved parent of uses '" + groupingPathStr + "'.");
+            }
             if (parent instanceof AugmentationSchemaBuilder) {
                 usesBuilder.setAugmenting(true);
             }
             ((DataNodeContainerBuilder) parent).addUsesNode(usesBuilder);
         }
-
-        pathToUses.add(groupingPathStr);
-        addedUsesNodes.put(pathToUses, usesBuilder);
+        allUsesNodes.add(usesBuilder);
         return usesBuilder;
     }
 
@@ -543,40 +522,44 @@ public class ModuleBuilder implements DataNodeContainerBuilder {
         if (actualPath.isEmpty()) {
             throw new YangParseException(name, refine.getLine(), "refine can be defined only in uses statement");
         } else {
-            final Builder parent = actualPath.getFirst();
+            final Builder parent = getActualNode();
             if (parent instanceof UsesNodeBuilder) {
                 ((UsesNodeBuilder) parent).addRefine(refine);
             } else {
                 throw new YangParseException(name, refine.getLine(), "refine can be defined only in uses statement");
             }
+            refine.setParent(parent);
         }
 
         path.add(refine.getName());
     }
 
-    public RpcDefinitionBuilder addRpc(final QName qname, final List<String> parentPath, final int line) {
-
-        if (!(actualPath.isEmpty())) {
+    public RpcDefinitionBuilder addRpc(final int line, final QName qname) {
+        Builder parent = getActualNode();
+        if (parent != null) {
             throw new YangParseException(name, line, "rpc can be defined only in module or submodule");
         }
 
-        final List<String> pathToRpc = new ArrayList<String>(parentPath);
-        final RpcDefinitionBuilder rpcBuilder = new RpcDefinitionBuilder(qname, line);
-
-        pathToRpc.add(qname.getLocalName());
-        addedRpcs.put(pathToRpc, rpcBuilder);
-
+        final RpcDefinitionBuilder rpcBuilder = new RpcDefinitionBuilder(line, qname);
+        for (RpcDefinitionBuilder rpc : addedRpcs) {
+            if (rpc.getQName().getLocalName().equals(qname.getLocalName())) {
+                throw new YangParseException(name, line, "Duplicate node found at line " + rpc.getLine());
+            }
+        }
+        addedRpcs.add(rpcBuilder);
         return rpcBuilder;
     }
 
     public ContainerSchemaNodeBuilder addRpcInput(final SchemaPath schemaPath, final QName inputQName, final int line) {
-        final Builder parent = actualPath.getFirst();
+        final Builder parent = getActualNode();
         if (!(parent instanceof RpcDefinitionBuilder)) {
             throw new YangParseException(name, line, "input can be defined only in rpc statement");
         }
         final RpcDefinitionBuilder rpc = (RpcDefinitionBuilder) parent;
 
-        final ContainerSchemaNodeBuilder inputBuilder = new ContainerSchemaNodeBuilder(inputQName, schemaPath, line);
+        final ContainerSchemaNodeBuilder inputBuilder = new ContainerSchemaNodeBuilder(line, inputQName, schemaPath);
+        inputBuilder.setParent(rpc);
+
         rpc.setInput(inputBuilder);
         return inputBuilder;
     }
@@ -588,7 +571,9 @@ public class ModuleBuilder implements DataNodeContainerBuilder {
         }
         final RpcDefinitionBuilder rpc = (RpcDefinitionBuilder) parent;
 
-        final ContainerSchemaNodeBuilder outputBuilder = new ContainerSchemaNodeBuilder(outputQName, schemaPath, line);
+        final ContainerSchemaNodeBuilder outputBuilder = new ContainerSchemaNodeBuilder(line, outputQName, schemaPath);
+        outputBuilder.setParent(rpc);
+
         rpc.setOutput(outputBuilder);
         return outputBuilder;
     }
@@ -598,132 +583,132 @@ public class ModuleBuilder implements DataNodeContainerBuilder {
         if (!(actualPath.isEmpty())) {
             throw new YangParseException(name, line, "notification can be defined only in module or submodule");
         }
-        final NotificationBuilder builder = new NotificationBuilder(notificationName, line);
+        for (NotificationBuilder nb : addedNotifications) {
+            if (nb.getQName().equals(notificationName)) {
+                throw new YangParseException(name, line, "Duplicate node found at line " + nb.getLine());
+            }
+        }
 
-        final List<String> notificationPath = new ArrayList<String>(parentPath);
-        notificationPath.add(notificationName.getLocalName());
+        final NotificationBuilder builder = new NotificationBuilder(line, notificationName);
         addedNotifications.add(builder);
 
         return builder;
     }
 
-    public FeatureBuilder addFeature(final QName featureName, final List<String> parentPath, final int line) {
-        if (!(actualPath.isEmpty())) {
+    public FeatureBuilder addFeature(final int line, final QName featureName) {
+        Builder parent = getActualNode();
+        if (parent != null) {
             throw new YangParseException(name, line, "feature can be defined only in module or submodule");
         }
 
-        final List<String> pathToFeature = new ArrayList<String>(parentPath);
-        pathToFeature.add(featureName.getLocalName());
-
-        final FeatureBuilder builder = new FeatureBuilder(featureName, line);
-        addedFeatures.put(pathToFeature, builder);
+        final FeatureBuilder builder = new FeatureBuilder(line, featureName);
+        for (FeatureBuilder fb : addedFeatures) {
+            if (fb.getQName().getLocalName().equals(featureName.getLocalName())) {
+                throw new YangParseException(name, line, "Duplicate node found at line " + fb.getLine());
+            }
+        }
+        addedFeatures.add(builder);
         return builder;
     }
 
-    public ChoiceBuilder addChoice(final QName choiceName, final List<String> parentPath, final int line) {
-        final List<String> pathToChoice = new ArrayList<String>(parentPath);
-        final ChoiceBuilder builder = new ChoiceBuilder(choiceName, line);
+    public ChoiceBuilder addChoice(final int line, final QName choiceName) {
+        final ChoiceBuilder builder = new ChoiceBuilder(line, choiceName);
 
-        if (!(actualPath.isEmpty())) {
-            final Builder parent = actualPath.getFirst();
-            if (parent instanceof DataNodeContainerBuilder) {
-                if (parent instanceof AugmentationSchemaBuilder) {
-                    builder.setAugmenting(true);
-                }
-                ((DataNodeContainerBuilder) parent).addChildNode(builder);
-            } else {
-                throw new YangParseException(name, line, "Unresolved parent of choice " + choiceName.getLocalName());
-            }
-        }
-
-        pathToChoice.add(choiceName.getLocalName());
-        childNodes.put(pathToChoice, builder);
+        Builder parent = getActualNode();
+        builder.setParent(parent);
+        addChildToParent(parent, builder, choiceName.getLocalName());
 
         return builder;
     }
 
-    public ChoiceCaseBuilder addCase(final QName caseName, final List<String> parentPath, final int line) {
+    public ChoiceCaseBuilder addCase(final int line, final QName caseName) {
         Builder parent = getActualNode();
-
-        final List<String> pathToCase = new ArrayList<String>(parentPath);
-        ChoiceCaseBuilder builder = null;
-        if (parent instanceof ChoiceBuilder) {
-            builder = new ChoiceCaseBuilder((ChoiceBuilder) parent, caseName, line);
-        } else {
-            builder = new ChoiceCaseBuilder(null, caseName, line);
+        if (parent == null) {
+            throw new YangParseException(name, line, "'case' parent not found");
         }
 
-        if (actualPath.isEmpty()) {
-            throw new YangParseException(name, line, "'case' parent not found");
+        final ChoiceCaseBuilder builder = new ChoiceCaseBuilder(line, caseName);
+        builder.setParent(parent);
+
+        if (parent instanceof ChoiceBuilder) {
+            ((ChoiceBuilder) parent).addChildNode(builder);
+        } else if (parent instanceof AugmentationSchemaBuilder) {
+            ((AugmentationSchemaBuilder) parent).addChildNode(builder);
         } else {
-            if (parent instanceof ChoiceBuilder) {
-                ((ChoiceBuilder) parent).addChildNode(builder);
-            } else if (parent instanceof AugmentationSchemaBuilder) {
-                builder.setAugmenting(true);
-                ((AugmentationSchemaBuilder) parent).addChildNode(builder);
-            } else {
-                throw new YangParseException(name, line, "Unresolved parent of 'case' " + caseName.getLocalName());
-            }
+            throw new YangParseException(name, line, "Unresolved parent of 'case' " + caseName.getLocalName());
         }
 
-        pathToCase.add(caseName.getLocalName());
-        childNodes.put(pathToCase, builder);
-
         return builder;
     }
 
-    public AnyXmlBuilder addAnyXml(final SchemaPath schemaPath, final QName anyXmlName, final List<String> parentPath, final int line) {
-        final List<String> pathToAnyXml = new ArrayList<String>(parentPath);
-        final AnyXmlBuilder builder = new AnyXmlBuilder(anyXmlName, schemaPath, line);
-        updateParent(builder, line, "anyxml");
+    public AnyXmlBuilder addAnyXml(final int line, final QName anyXmlName, final SchemaPath schemaPath) {
+        final AnyXmlBuilder builder = new AnyXmlBuilder(line, anyXmlName, schemaPath);
 
-        pathToAnyXml.add(anyXmlName.getLocalName());
-        childNodes.put(pathToAnyXml, builder);
+        Builder parent = getActualNode();
+        builder.setParent(parent);
+        addChildToParent(parent, builder, anyXmlName.getLocalName());
 
         return builder;
     }
 
     @Override
     public void addTypedef(TypeDefinitionBuilder typedefBuilder) {
-        final List<String> pathToTypedef = new ArrayList<String>();
-        for (QName qname : typedefBuilder.getPath().getPath()) {
-            pathToTypedef.add(qname.getLocalName());
-        }
-        if (addedTypedefs.containsKey(pathToTypedef)) {
-            throw new YangParseException(this.name, typedefBuilder.getLine(), "Failed to add typedef "
-                    + typedefBuilder.getQName().getLocalName() + ": typedef already exists in context.");
+        for (TypeDefinitionBuilder tdb : addedTypedefs) {
+            if (tdb.getQName().getLocalName().equals(typedefBuilder.getQName().getLocalName())) {
+                throw new YangParseException(name, typedefBuilder.getLine(), "Duplicate node found at line "
+                        + tdb.getLine());
+            }
         }
-        addedTypedefs.put(pathToTypedef, typedefBuilder);
+        addedTypedefs.add(typedefBuilder);
     }
 
-    public TypeDefinitionBuilderImpl addTypedef(final QName typeDefName, final List<String> parentPath, final int line) {
-        final List<String> pathToType = new ArrayList<String>(parentPath);
+    public TypeDefinitionBuilderImpl addTypedef(final int line, final QName typeDefName) {
         final TypeDefinitionBuilderImpl builder = new TypeDefinitionBuilderImpl(typeDefName, line);
 
-        if (!(actualPath.isEmpty())) {
-            final Builder parent = actualPath.getFirst();
-            if (parent instanceof TypeDefinitionAwareBuilder) {
-                ((TypeDefinitionAwareBuilder) parent).addTypedef(builder);
+        Builder parent = getActualNode();
+        builder.setParent(parent);
+
+        if (parent == null) {
+            for (TypeDefinitionBuilder tdb : addedTypedefs) {
+                if (tdb.getQName().getLocalName().equals(builder.getQName().getLocalName())) {
+                    throw new YangParseException(name, builder.getLine(), "Duplicate node found at line "
+                            + tdb.getLine());
+                }
+            }
+            addedTypedefs.add(builder);
+        } else {
+            if (parent instanceof DataNodeContainerBuilder) {
+                DataNodeContainerBuilder parentNode = (DataNodeContainerBuilder) parent;
+                for (DataSchemaNodeBuilder child : parentNode.getChildNodeBuilders()) {
+                    if (child.getQName().getLocalName().equals(typeDefName.getLocalName())) {
+                        throw new YangParseException(name, line, "Duplicate node found at line " + child.getLine());
+                    }
+                }
+                parentNode.addTypedef(builder);
+            } else if (parent instanceof RpcDefinitionBuilder) {
+                RpcDefinitionBuilder rpcParent = (RpcDefinitionBuilder) parent;
+                for (TypeDefinitionBuilder tdb : rpcParent.getTypeDefinitions()) {
+                    if (tdb.getQName().getLocalName().equals(builder.getQName().getLocalName())) {
+                        throw new YangParseException(name, builder.getLine(), "Duplicate node found at line "
+                                + tdb.getLine());
+                    }
+                }
+                rpcParent.addTypedef(builder);
             } else {
                 throw new YangParseException(name, line, "Unresolved parent of typedef " + typeDefName.getLocalName());
             }
         }
 
-        pathToType.add(typeDefName.getLocalName());
-        addedTypedefs.put(pathToType, builder);
         return builder;
     }
 
-    public void setType(final TypeDefinition<?> type, final List<String> parentPath) {
-        if (!(actualPath.isEmpty())) {
-            final Builder parent = actualPath.getFirst();
-            if (parent instanceof TypeAwareBuilder) {
-                ((TypeAwareBuilder) parent).setType(type);
-            } else {
-                throw new YangParseException("Failed to set type '" + type.getQName().getLocalName()
-                        + "'. Unknown parent node: " + parent);
-            }
+    public void setType(final TypeDefinition<?> type) {
+        Builder parent = getActualNode();
+        if (parent == null || !(parent instanceof TypeAwareBuilder)) {
+            throw new YangParseException("Failed to set type '" + type.getQName().getLocalName()
+                    + "'. Unknown parent node: " + parent);
         }
+        ((TypeAwareBuilder) parent).setType(type);
     }
 
     public UnionTypeBuilder addUnionType(final List<String> currentPath, final URI namespace, final Date revision,
@@ -770,7 +755,8 @@ public class ModuleBuilder implements DataNodeContainerBuilder {
     }
 
     public DeviationBuilder addDeviation(final String targetPath, final List<String> parentPath, final int line) {
-        if (!(actualPath.isEmpty())) {
+        Builder parent = getActualNode();
+        if (parent != null) {
             throw new YangParseException(name, line, "deviation can be defined only in module or submodule");
         }
 
@@ -782,39 +768,43 @@ public class ModuleBuilder implements DataNodeContainerBuilder {
     }
 
     public IdentitySchemaNodeBuilder addIdentity(final QName qname, final List<String> parentPath, final int line) {
-        if (!(actualPath.isEmpty())) {
+        Builder parent = getActualNode();
+        if (parent != null) {
             throw new YangParseException(name, line, "identity can be defined only in module or submodule");
         }
+        for (IdentitySchemaNodeBuilder idBuilder : addedIdentities) {
+            if (idBuilder.getQName().equals(qname)) {
+                throw new YangParseException(name, line, "Duplicate node found at line " + idBuilder.getLine());
+            }
+        }
 
-        final List<String> pathToIdentity = new ArrayList<String>(parentPath);
-        final IdentitySchemaNodeBuilder builder = new IdentitySchemaNodeBuilder(qname, line);
-        pathToIdentity.add(qname.getLocalName());
+        final IdentitySchemaNodeBuilder builder = new IdentitySchemaNodeBuilder(line, qname);
         addedIdentities.add(builder);
         return builder;
     }
 
     @Override
-    public void addUnknownSchemaNode(UnknownSchemaNodeBuilder unknownNode) {
+    public void addUnknownSchemaNode(UnknownSchemaNodeBuilder builder) {
         final List<String> unPath = new ArrayList<String>();
-        for (QName qname : unknownNode.getPath().getPath()) {
-            unPath.add(qname.getLocalName());
+        for (QName name : builder.getPath().getPath()) {
+            unPath.add(name.getLocalName());
         }
-
         if (addedUnknownNodes.containsKey(unPath)) {
-            addedUnknownNodes.get(unPath).add(unknownNode);
+            addedUnknownNodes.get(unPath).add(builder);
         } else {
             List<UnknownSchemaNodeBuilder> nodes = new ArrayList<UnknownSchemaNodeBuilder>();
-            nodes.add(unknownNode);
+            nodes.add(builder);
             addedUnknownNodes.put(unPath, nodes);
         }
     }
 
     public UnknownSchemaNodeBuilder addUnknownSchemaNode(final QName qname, final List<String> parentPath,
             final int line) {
-        final UnknownSchemaNodeBuilder builder = new UnknownSchemaNodeBuilder(qname, line);
+        final Builder parent = getActualNode();
+        final UnknownSchemaNodeBuilder builder = new UnknownSchemaNodeBuilder(line, qname);
+        builder.setParent(parent);
 
-        if (!(actualPath.isEmpty())) {
-            final Builder parent = actualPath.getFirst();
+        if (parent != null) {
             if (parent instanceof SchemaNodeBuilder) {
                 ((SchemaNodeBuilder) parent).addUnknownSchemaNode(builder);
             } else if (parent instanceof RefineHolder) {
@@ -1026,7 +1016,7 @@ public class ModuleBuilder implements DataNodeContainerBuilder {
 
         @Override
         public Set<DataSchemaNode> getChildNodes() {
-            return new HashSet<DataSchemaNode>(childNodes.values());
+            return new LinkedHashSet<DataSchemaNode>(childNodes.values());
         }
 
         private void setChildNodes(Map<QName, DataSchemaNode> childNodes) {
@@ -1183,19 +1173,52 @@ public class ModuleBuilder implements DataNodeContainerBuilder {
         }
     }
 
-    private void updateParent(DataSchemaNodeBuilder nodeBuilder, int line, String nodeTypeName) {
-        if (!(actualPath.isEmpty())) {
-            final Builder parent = actualPath.getFirst();
+    private void addChildToParent(final Builder parent, final DataSchemaNodeBuilder child, final String childLocalName) {
+        final int line = child.getLine();
+        if (parent == null) {
+            // if parent == null => node is defined under module
+            // All leafs, leaf-lists, lists, containers, choices, rpcs,
+            // notifications, and anyxmls defined within a parent node or at the
+            // top level of the module or its submodules share the same
+            // identifier namespace.
+            for (DataSchemaNodeBuilder childNode : childNodes) {
+                if (childNode.getQName().getLocalName().equals(childLocalName)) {
+                    throw new YangParseException(name, line, "Duplicate node found at line " + childNode.getLine());
+                }
+            }
+            for (RpcDefinitionBuilder rpc : addedRpcs) {
+                if (rpc.getQName().getLocalName().equals(childLocalName)) {
+                    throw new YangParseException(name, line, "Duplicate node found at line " + rpc.getLine());
+                }
+            }
+            for (NotificationBuilder notification : addedNotifications) {
+                if (notification.getQName().getLocalName().equals(childLocalName)) {
+                    throw new YangParseException(name, line, "Duplicate node found at line " + notification.getLine());
+                }
+            }
+            childNodes.add(child);
+        } else {
+            // no need for checking rpc and notification because they can be
+            // defined only under module or submodule
             if (parent instanceof DataNodeContainerBuilder) {
-                if (parent instanceof AugmentationSchemaBuilder) {
-                    nodeBuilder.setAugmenting(true);
+                DataNodeContainerBuilder parentNode = (DataNodeContainerBuilder) parent;
+                for (DataSchemaNodeBuilder childNode : parentNode.getChildNodeBuilders()) {
+                    if (childNode.getQName().getLocalName().equals(childLocalName)) {
+                        throw new YangParseException(name, line, "Duplicate node found at line " + childNode.getLine());
+                    }
                 }
-                ((DataNodeContainerBuilder) parent).addChildNode(nodeBuilder);
+                parentNode.addChildNode(child);
             } else if (parent instanceof ChoiceBuilder) {
-                ((ChoiceBuilder) parent).addChildNode(nodeBuilder);
+                ChoiceBuilder parentNode = (ChoiceBuilder) parent;
+                for (ChoiceCaseBuilder caseBuilder : parentNode.getCases()) {
+                    if (caseBuilder.getQName().getLocalName().equals(childLocalName)) {
+                        throw new YangParseException(name, line, "Duplicate node found at line "
+                                + caseBuilder.getLine());
+                    }
+                }
+                parentNode.addChildNode(child);
             } else {
-                throw new YangParseException(name, line, "Unresolved parent of " + nodeTypeName + " "
-                        + nodeBuilder.getQName().getLocalName());
+                throw new YangParseException(name, line, "Unresolved parent of node '" + childLocalName + "'.");
             }
         }
     }
@@ -1272,132 +1295,29 @@ public class ModuleBuilder implements DataNodeContainerBuilder {
     }
 
     /**
-     * Traverse through given addedChilds and add only direct module childs.
-     * Direct module child path size is 2 (1. module name, 2. child name).
+     * Traverse through given addedUnknownNodes and add only unknown nodes
+     * defined under module statement.
      *
-     * @param addedChilds
-     * @return map of children, where key is child QName and value is child
-     *         itself
+     * @param addedUnknownNodes
+     *            unknown node builders
+     * @return list of all unknown nodes defined in module in lexicographical
+     *         order
      */
-    private Map<QName, DataSchemaNode> buildModuleChildNodes(Map<List<String>, DataSchemaNodeBuilder> addedChilds) {
-        final Map<QName, DataSchemaNode> childNodes = new HashMap<QName, DataSchemaNode>();
-        for (Map.Entry<List<String>, DataSchemaNodeBuilder> entry : addedChilds.entrySet()) {
-            List<String> path = entry.getKey();
-            DataSchemaNodeBuilder child = entry.getValue();
-            if (path.size() == 2) {
-                DataSchemaNode node = child.build();
-                QName qname = node.getQName();
-                childNodes.put(qname, node);
-            }
-        }
-        return childNodes;
-    }
-
-    /**
-     * Traverse through given addedGroupings and add only direct module
-     * groupings. Direct module grouping path size is 2 (1. module name, 2.
-     * grouping name).
-     *
-     * @param addedGroupings
-     * @return set of built GroupingDefinition objects
-     */
-    private Set<GroupingDefinition> buildModuleGroupings(Map<List<String>, GroupingBuilder> addedGroupings) {
-        final Set<GroupingDefinition> groupings = new HashSet<GroupingDefinition>();
-        for (Map.Entry<List<String>, GroupingBuilder> entry : addedGroupings.entrySet()) {
-            if (entry.getKey().size() == 2) {
-                groupings.add(entry.getValue().build());
-            }
-        }
-        return groupings;
-    }
-
-    /**
-     * Traverse through given addedRpcs and build RpcDefinition objects.
-     *
-     * @param addedRpcs
-     * @return set of built RpcDefinition objects
-     */
-    private Set<RpcDefinition> buildModuleRpcs(Map<List<String>, RpcDefinitionBuilder> addedRpcs) {
-        final Set<RpcDefinition> rpcs = new HashSet<RpcDefinition>();
-        RpcDefinitionBuilder builder;
-        for (Map.Entry<List<String>, RpcDefinitionBuilder> entry : addedRpcs.entrySet()) {
-            builder = entry.getValue();
-            RpcDefinition rpc = builder.build();
-            rpcs.add(rpc);
-        }
-        return rpcs;
-    }
-
-    /**
-     * Traverse through given addedTypedefs and add only direct module typedef
-     * statements. Direct module typedef path size is 2 (1. module name, 2.
-     * typedef name).
-     *
-     * @param addedTypedefs
-     * @return set of built module typedef statements
-     */
-    private Set<TypeDefinition<?>> buildModuleTypedefs(Map<List<String>, TypeDefinitionBuilder> addedTypedefs) {
-        Set<TypeDefinition<?>> typedefs = new HashSet<TypeDefinition<?>>();
-        for (Map.Entry<List<String>, TypeDefinitionBuilder> entry : addedTypedefs.entrySet()) {
-            List<String> key = entry.getKey();
-            TypeDefinitionBuilder typedefBuilder = entry.getValue();
-            if (key.size() == 2) {
-                TypeDefinition<? extends TypeDefinition<?>> node = typedefBuilder.build();
-                typedefs.add(node);
-            }
-        }
-        return typedefs;
-    }
-
-    /**
-     * Traverse through given addedUsesNodes and add only direct module uses
-     * nodes. Direct module uses node path size is 2 (1. module name, 2. uses
-     * name).
-     *
-     * @param addedUsesNodes
-     * @return set of built module uses nodes
-     */
-    private Set<UsesNode> buildUsesNodes(Map<List<String>, UsesNodeBuilder> addedUsesNodes) {
-        final Set<UsesNode> usesNodeDefs = new HashSet<UsesNode>();
-        for (Map.Entry<List<String>, UsesNodeBuilder> entry : addedUsesNodes.entrySet()) {
-            if (entry.getKey().size() == 2) {
-                usesNodeDefs.add(entry.getValue().build());
-            }
-        }
-        return usesNodeDefs;
-    }
-
-    /**
-     * Traverse through given addedFeatures and add only direct module features.
-     * Direct module feature path size is 2 (1. module name, 2. feature name).
-     *
-     * @param addedFeatures
-     * @return set of built module features
-     */
-    private Set<FeatureDefinition> buildModuleFeatures(Map<List<String>, FeatureBuilder> addedFeatures) {
-        Set<FeatureDefinition> features = new HashSet<FeatureDefinition>();
-        for (Map.Entry<List<String>, FeatureBuilder> entry : addedFeatures.entrySet()) {
-            if (entry.getKey().size() == 2) {
-                features.add(entry.getValue().build());
-            }
-        }
-        return features;
-    }
-
     private List<UnknownSchemaNode> buildModuleUnknownNodes(
             final Map<List<String>, List<UnknownSchemaNodeBuilder>> addedUnknownNodes) {
-        final List<UnknownSchemaNode> unknownNodes = new ArrayList<UnknownSchemaNode>();
+        final List<UnknownSchemaNode> result = new ArrayList<UnknownSchemaNode>();
         for (Map.Entry<List<String>, List<UnknownSchemaNodeBuilder>> entry : addedUnknownNodes.entrySet()) {
             final List<String> path = entry.getKey();
             final List<UnknownSchemaNodeBuilder> child = entry.getValue();
-            for (UnknownSchemaNodeBuilder un : child) {
-                if (path.size() == 2) {
-                    final UnknownSchemaNode node = un.build();
-                    unknownNodes.add(node);
+
+            if (path.size() == 2) {
+                for (UnknownSchemaNodeBuilder node : child) {
+                    result.add(node.build());
                 }
             }
         }
-        return unknownNodes;
+        Collections.sort(result, Comparators.SCHEMA_NODE_COMP);
+        return result;
     }
 
 }
index 534ba2c841e5171c579cd3446fdd8625404cf2a8..b9b151989ef00a0526bbf7847e1737a189c8b250 100644 (file)
@@ -9,11 +9,12 @@ package org.opendaylight.controller.yang.parser.builder.impl;
 
 import java.util.ArrayList;
 import java.util.Collections;
-import java.util.HashMap;
 import java.util.HashSet;
 import java.util.List;
 import java.util.Map;
 import java.util.Set;
+import java.util.TreeMap;
+import java.util.TreeSet;
 
 import org.opendaylight.controller.yang.common.QName;
 import org.opendaylight.controller.yang.model.api.AugmentationSchema;
@@ -31,12 +32,12 @@ import org.opendaylight.controller.yang.parser.builder.api.AugmentationTargetBui
 import org.opendaylight.controller.yang.parser.builder.api.DataSchemaNodeBuilder;
 import org.opendaylight.controller.yang.parser.builder.api.GroupingBuilder;
 import org.opendaylight.controller.yang.parser.builder.api.SchemaNodeBuilder;
-import org.opendaylight.controller.yang.parser.builder.api.TypeDefinitionAwareBuilder;
 import org.opendaylight.controller.yang.parser.builder.api.TypeDefinitionBuilder;
 import org.opendaylight.controller.yang.parser.builder.api.UsesNodeBuilder;
+import org.opendaylight.controller.yang.parser.util.Comparators;
 
-public final class NotificationBuilder extends AbstractDataNodeContainerBuilder implements TypeDefinitionAwareBuilder,
-        SchemaNodeBuilder, AugmentationTargetBuilder {
+public final class NotificationBuilder extends AbstractDataNodeContainerBuilder implements SchemaNodeBuilder,
+        AugmentationTargetBuilder {
     private boolean isBuilt;
     private final NotificationDefinitionImpl instance;
     private final int line;
@@ -50,8 +51,8 @@ public final class NotificationBuilder extends AbstractDataNodeContainerBuilder
     private final Set<AugmentationSchemaBuilder> addedAugmentations = new HashSet<AugmentationSchemaBuilder>();
     private final List<UnknownSchemaNodeBuilder> addedUnknownNodes = new ArrayList<UnknownSchemaNodeBuilder>();
 
-    NotificationBuilder(final QName qname, final int line) {
-        super(qname);
+    NotificationBuilder(final int line, final QName qname) {
+        super(line, qname);
         this.line = line;
         instance = new NotificationDefinitionImpl(qname);
     }
@@ -65,21 +66,21 @@ public final class NotificationBuilder extends AbstractDataNodeContainerBuilder
             instance.setStatus(status);
 
             // CHILD NODES
-            final Map<QName, DataSchemaNode> childs = new HashMap<QName, DataSchemaNode>();
+            final Map<QName, DataSchemaNode> childs = new TreeMap<QName, DataSchemaNode>(Comparators.QNAME_COMP);
             for (DataSchemaNodeBuilder node : addedChildNodes) {
                 childs.put(node.getQName(), node.build());
             }
             instance.setChildNodes(childs);
 
             // GROUPINGS
-            final Set<GroupingDefinition> groupingDefs = new HashSet<GroupingDefinition>();
+            final Set<GroupingDefinition> groupingDefs = new TreeSet<GroupingDefinition>(Comparators.SCHEMA_NODE_COMP);
             for (GroupingBuilder builder : addedGroupings) {
                 groupingDefs.add(builder.build());
             }
             instance.setGroupings(groupingDefs);
 
             // TYPEDEFS
-            final Set<TypeDefinition<?>> typedefs = new HashSet<TypeDefinition<?>>();
+            final Set<TypeDefinition<?>> typedefs = new TreeSet<TypeDefinition<?>>(Comparators.SCHEMA_NODE_COMP);
             for (TypeDefinitionBuilder entry : addedTypedefs) {
                 typedefs.add(entry.build());
             }
@@ -106,6 +107,7 @@ public final class NotificationBuilder extends AbstractDataNodeContainerBuilder
             for (UnknownSchemaNodeBuilder b : addedUnknownNodes) {
                 unknownNodes.add(b.build());
             }
+            Collections.sort(unknownNodes, Comparators.SCHEMA_NODE_COMP);
             instance.setUnknownSchemaNodes(unknownNodes);
 
             isBuilt = true;
@@ -120,11 +122,6 @@ public final class NotificationBuilder extends AbstractDataNodeContainerBuilder
         build();
     }
 
-    @Override
-    public int getLine() {
-        return line;
-    }
-
     @Override
     public Set<TypeDefinitionBuilder> getTypeDefinitionBuilders() {
         return addedTypedefs;
index 8cb4a6e56cb46b7d903e8e0d4a3ec9a482b03666..d2b8544bfdf2fdee7a277178d59409aa6c901898 100644 (file)
@@ -12,6 +12,7 @@ import java.util.Collections;
 import java.util.HashSet;
 import java.util.List;
 import java.util.Set;
+import java.util.TreeSet;
 
 import org.opendaylight.controller.yang.common.QName;
 import org.opendaylight.controller.yang.model.api.ContainerSchemaNode;
@@ -23,10 +24,10 @@ import org.opendaylight.controller.yang.model.api.TypeDefinition;
 import org.opendaylight.controller.yang.model.api.UnknownSchemaNode;
 import org.opendaylight.controller.yang.parser.builder.api.AbstractSchemaNodeBuilder;
 import org.opendaylight.controller.yang.parser.builder.api.GroupingBuilder;
-import org.opendaylight.controller.yang.parser.builder.api.TypeDefinitionAwareBuilder;
 import org.opendaylight.controller.yang.parser.builder.api.TypeDefinitionBuilder;
+import org.opendaylight.controller.yang.parser.util.Comparators;
 
-public final class RpcDefinitionBuilder extends AbstractSchemaNodeBuilder implements TypeDefinitionAwareBuilder {
+public final class RpcDefinitionBuilder extends AbstractSchemaNodeBuilder {
     private boolean isBuilt;
     private final RpcDefinitionImpl instance;
     private ContainerSchemaNodeBuilder inputBuilder;
@@ -34,8 +35,8 @@ public final class RpcDefinitionBuilder extends AbstractSchemaNodeBuilder implem
     private final Set<TypeDefinitionBuilder> addedTypedefs = new HashSet<TypeDefinitionBuilder>();
     private final Set<GroupingBuilder> addedGroupings = new HashSet<GroupingBuilder>();
 
-    RpcDefinitionBuilder(final QName qname, final int line) {
-        super(qname, line);
+    RpcDefinitionBuilder(final int line, final QName qname) {
+        super(line, qname);
         this.instance = new RpcDefinitionImpl(qname);
     }
 
@@ -51,17 +52,17 @@ public final class RpcDefinitionBuilder extends AbstractSchemaNodeBuilder implem
             instance.setInput(input);
             instance.setOutput(output);
 
-            instance.setPath(path);
+            instance.setPath(schemaPath);
 
             // TYPEDEFS
-            final Set<TypeDefinition<?>> typedefs = new HashSet<TypeDefinition<?>>();
+            final Set<TypeDefinition<?>> typedefs = new TreeSet<TypeDefinition<?>>(Comparators.SCHEMA_NODE_COMP);
             for (TypeDefinitionBuilder entry : addedTypedefs) {
                 typedefs.add(entry.build());
             }
             instance.setTypeDefinitions(typedefs);
 
             // GROUPINGS
-            final Set<GroupingDefinition> groupings = new HashSet<GroupingDefinition>();
+            final Set<GroupingDefinition> groupings = new TreeSet<GroupingDefinition>(Comparators.SCHEMA_NODE_COMP);
             for (GroupingBuilder entry : addedGroupings) {
                 groupings.add(entry.build());
             }
@@ -72,6 +73,7 @@ public final class RpcDefinitionBuilder extends AbstractSchemaNodeBuilder implem
             for (UnknownSchemaNodeBuilder b : addedUnknownNodes) {
                 unknownNodes.add(b.build());
             }
+            Collections.sort(unknownNodes, Comparators.SCHEMA_NODE_COMP);
             instance.setUnknownSchemaNodes(unknownNodes);
 
             isBuilt = true;
@@ -91,7 +93,6 @@ public final class RpcDefinitionBuilder extends AbstractSchemaNodeBuilder implem
         return addedTypedefs;
     }
 
-    @Override
     public void addTypedef(final TypeDefinitionBuilder type) {
         addedTypedefs.add(type);
     }
@@ -109,7 +110,7 @@ public final class RpcDefinitionBuilder extends AbstractSchemaNodeBuilder implem
         final int prime = 31;
         int result = 1;
         result = prime * result + ((qname == null) ? 0 : qname.hashCode());
-        result = prime * result + ((path == null) ? 0 : path.hashCode());
+        result = prime * result + ((schemaPath == null) ? 0 : schemaPath.hashCode());
         return result;
     }
 
@@ -129,11 +130,11 @@ public final class RpcDefinitionBuilder extends AbstractSchemaNodeBuilder implem
         } else if (!other.qname.equals(this.qname)) {
             return false;
         }
-        if (other.path == null) {
-            if (this.path != null) {
+        if (other.schemaPath == null) {
+            if (this.schemaPath != null) {
                 return false;
             }
-        } else if (!other.path.equals(this.path)) {
+        } else if (!other.schemaPath.equals(this.schemaPath)) {
             return false;
         }
         return true;
index 6ca07bc87fd3e925010819497bcb1c77d39fd0e0..1d1d24b6add76f10a1c15a29a02e6dd7eae9c382 100644 (file)
@@ -23,13 +23,11 @@ import org.opendaylight.controller.yang.model.util.ExtendedType;
 import org.opendaylight.controller.yang.model.util.UnknownType;
 import org.opendaylight.controller.yang.parser.builder.api.AbstractTypeAwareBuilder;
 import org.opendaylight.controller.yang.parser.builder.api.TypeDefinitionBuilder;
+import org.opendaylight.controller.yang.parser.util.Comparators;
 import org.opendaylight.controller.yang.parser.util.YangParseException;
 
 public final class TypeDefinitionBuilderImpl extends AbstractTypeAwareBuilder implements TypeDefinitionBuilder {
-    private final int line;
-    private final QName qname;
     private SchemaPath schemaPath;
-
     private List<UnknownSchemaNode> unknownNodes;
     private final List<UnknownSchemaNodeBuilder> addedUnknownNodes = new ArrayList<UnknownSchemaNodeBuilder>();
     private List<RangeConstraint> ranges = Collections.emptyList();
@@ -45,13 +43,11 @@ public final class TypeDefinitionBuilderImpl extends AbstractTypeAwareBuilder im
     private boolean addedByUses;
 
     public TypeDefinitionBuilderImpl(final QName qname, final int line) {
-        this.qname = qname;
-        this.line = line;
+        super(line, qname);
     }
 
     public TypeDefinitionBuilderImpl(TypeDefinitionBuilder tdb) {
-        qname = tdb.getQName();
-        line = tdb.getLine();
+        super(tdb.getLine(), tdb.getQName());
         schemaPath = tdb.getPath();
 
         type = tdb.getType();
@@ -103,22 +99,13 @@ public final class TypeDefinitionBuilderImpl extends AbstractTypeAwareBuilder im
             for (UnknownSchemaNodeBuilder b : addedUnknownNodes) {
                 unknownNodes.add(b.build());
             }
+            Collections.sort(unknownNodes, Comparators.SCHEMA_NODE_COMP);
         }
         typeBuilder.unknownSchemaNodes(unknownNodes);
         result = typeBuilder.build();
         return result;
     }
 
-    @Override
-    public int getLine() {
-        return line;
-    }
-
-    @Override
-    public QName getQName() {
-        return qname;
-    }
-
     @Override
     public SchemaPath getPath() {
         return schemaPath;
index 433ae962e030ce71493b594a10afea5453a4d886..33a51d6cd322d1201e0caf0452c0d1f79a97655b 100644 (file)
@@ -11,7 +11,6 @@ import java.util.ArrayList;
 import java.util.Collections;
 import java.util.List;
 
-import org.opendaylight.controller.yang.common.QName;
 import org.opendaylight.controller.yang.model.api.SchemaPath;
 import org.opendaylight.controller.yang.model.api.Status;
 import org.opendaylight.controller.yang.model.api.TypeDefinition;
@@ -33,7 +32,6 @@ import org.opendaylight.controller.yang.parser.util.YangParseException;
 public final class UnionTypeBuilder extends AbstractTypeAwareBuilder implements TypeDefinitionBuilder {
     private final static String NAME = "union";
 
-    private final int line;
     private final List<TypeDefinition<?>> types;
     private final List<TypeDefinitionBuilder> typedefs;
     private UnionType instance;
@@ -42,15 +40,11 @@ public final class UnionTypeBuilder extends AbstractTypeAwareBuilder implements
     private SchemaPath path;
 
     public UnionTypeBuilder(final int line) {
-        this.line = line;
+        super(line, null);
         types = new ArrayList<TypeDefinition<?>>();
         typedefs = new ArrayList<TypeDefinitionBuilder>();
     }
 
-    @Override
-    public int getLine() {
-        return line;
-    }
 
     public List<TypeDefinition<?>> getTypes() {
         return types;
@@ -129,12 +123,7 @@ public final class UnionTypeBuilder extends AbstractTypeAwareBuilder implements
 
     @Override
     public void addUnknownSchemaNode(final UnknownSchemaNodeBuilder unknownNode) {
-        // not supported
-    }
-
-    @Override
-    public QName getQName() {
-        return null;
+        // not yet supported
     }
 
     @Override
index 14cf3a9b34a0cda5fcf3024b695dd7c5b540d964..232fa60d6b8805c9ed8130abcbf9200f9f04a393 100644 (file)
@@ -16,6 +16,7 @@ import org.opendaylight.controller.yang.model.api.SchemaPath;
 import org.opendaylight.controller.yang.model.api.Status;
 import org.opendaylight.controller.yang.model.api.UnknownSchemaNode;
 import org.opendaylight.controller.yang.parser.builder.api.AbstractSchemaNodeBuilder;
+import org.opendaylight.controller.yang.parser.util.Comparators;
 
 public final class UnknownSchemaNodeBuilder extends AbstractSchemaNodeBuilder {
     private boolean isBuilt;
@@ -25,15 +26,15 @@ public final class UnknownSchemaNodeBuilder extends AbstractSchemaNodeBuilder {
     private QName nodeType;
     private String nodeParameter;
 
-    public UnknownSchemaNodeBuilder(final QName qname, final int line) {
-        super(qname, line);
+    public UnknownSchemaNodeBuilder(final int line, final QName qname) {
+        super(line, qname);
         instance = new UnknownSchemaNodeImpl(qname);
     }
 
     public UnknownSchemaNodeBuilder(UnknownSchemaNodeBuilder b) {
-        super(b.getQName(), b.getLine());
+        super(b.getLine(), b.getQName());
         instance = new UnknownSchemaNodeImpl(qname);
-        path = b.getPath();
+        schemaPath = b.getPath();
         description = b.getDescription();
         reference = b.getReference();
         status = b.getStatus();
@@ -47,7 +48,7 @@ public final class UnknownSchemaNodeBuilder extends AbstractSchemaNodeBuilder {
     @Override
     public UnknownSchemaNode build() {
         if (!isBuilt) {
-            instance.setPath(path);
+            instance.setPath(schemaPath);
             instance.setNodeType(nodeType);
             instance.setNodeParameter(nodeParameter);
             instance.setDescription(description);
@@ -61,6 +62,7 @@ public final class UnknownSchemaNodeBuilder extends AbstractSchemaNodeBuilder {
                 for (UnknownSchemaNodeBuilder b : addedUnknownNodes) {
                     unknownNodes.add(b.build());
                 }
+                Collections.sort(unknownNodes, Comparators.SCHEMA_NODE_COMP);
             }
             instance.setUnknownSchemaNodes(unknownNodes);
 
index 77a465d5fd3346ab41657c84421f5cd35c1c6e98..ecbc1c54fd0f9a0edaf0367f8008eaade0da99dd 100644 (file)
@@ -21,16 +21,18 @@ import org.opendaylight.controller.yang.model.api.SchemaPath;
 import org.opendaylight.controller.yang.model.api.UnknownSchemaNode;\r
 import org.opendaylight.controller.yang.model.api.UsesNode;\r
 import org.opendaylight.controller.yang.parser.builder.api.AugmentationSchemaBuilder;\r
+import org.opendaylight.controller.yang.parser.builder.api.Builder;\r
 import org.opendaylight.controller.yang.parser.builder.api.DataNodeContainerBuilder;\r
 import org.opendaylight.controller.yang.parser.builder.api.SchemaNodeBuilder;\r
 import org.opendaylight.controller.yang.parser.builder.api.UsesNodeBuilder;\r
 import org.opendaylight.controller.yang.parser.util.RefineHolder;\r
+import org.opendaylight.controller.yang.parser.util.YangParseException;\r
 \r
 public final class UsesNodeBuilderImpl implements UsesNodeBuilder {\r
     private boolean isBuilt;\r
     private UsesNodeImpl instance;\r
     private final int line;\r
-    private final DataNodeContainerBuilder parent;\r
+    private DataNodeContainerBuilder parent;\r
     private final String groupingName;\r
     private SchemaPath groupingPath;\r
     private boolean augmenting;\r
@@ -40,10 +42,9 @@ public final class UsesNodeBuilderImpl implements UsesNodeBuilder {
     private final List<RefineHolder> refines = new ArrayList<RefineHolder>();\r
     private final List<UnknownSchemaNodeBuilder> addedUnknownNodes = new ArrayList<UnknownSchemaNodeBuilder>();\r
 \r
-    public UsesNodeBuilderImpl(final String groupingName, final int line, final DataNodeContainerBuilder parent) {\r
+    public UsesNodeBuilderImpl(final int line, final String groupingName) {\r
         this.groupingName = groupingName;\r
         this.line = line;\r
-        this.parent = parent;\r
     }\r
 \r
     public UsesNodeBuilderImpl(UsesNodeBuilder b) {\r
@@ -102,6 +103,14 @@ public final class UsesNodeBuilderImpl implements UsesNodeBuilder {
         return parent;\r
     }\r
 \r
+    @Override\r
+    public void setParent(Builder parent) {\r
+        if (!(parent instanceof DataNodeContainerBuilder)) {\r
+            throw new YangParseException(line, "Unresolved parent of uses '" + groupingName + "'.");\r
+        }\r
+        this.parent = (DataNodeContainerBuilder) parent;\r
+    }\r
+\r
     @Override\r
     public SchemaPath getGroupingPath() {\r
         return groupingPath;\r
@@ -176,6 +185,47 @@ public final class UsesNodeBuilderImpl implements UsesNodeBuilder {
         addedUnknownNodes.add(unknownNode);\r
     }\r
 \r
+    @Override\r
+    public int hashCode() {\r
+        final int prime = 31;\r
+        int result = 1;\r
+        result = prime * result + ((groupingName == null) ? 0 : groupingName.hashCode());\r
+        return result;\r
+    }\r
+\r
+    @Override\r
+    public boolean equals(Object obj) {\r
+        if (this == obj)\r
+            return true;\r
+        if (obj == null)\r
+            return false;\r
+        if (getClass() != obj.getClass())\r
+            return false;\r
+        UsesNodeBuilderImpl other = (UsesNodeBuilderImpl) obj;\r
+        if (groupingName == null) {\r
+            if (other.groupingName != null)\r
+                return false;\r
+        } else if (!groupingName.equals(other.groupingName))\r
+            return false;\r
+\r
+        if (parent == null) {\r
+            if (other.parent != null)\r
+                return false;\r
+        } else if (!parent.equals(other.parent))\r
+            return false;\r
+        if (refines == null) {\r
+            if (other.refines != null)\r
+                return false;\r
+        } else if (!refines.equals(other.refines))\r
+            return false;\r
+        return true;\r
+    }\r
+\r
+    @Override\r
+    public String toString() {\r
+        return "uses '" + groupingName + "'";\r
+    }\r
+\r
     public final class UsesNodeImpl implements UsesNode {\r
         private final SchemaPath groupingPath;\r
         private Set<AugmentationSchema> augmentations = Collections.emptySet();\r
@@ -296,4 +346,5 @@ public final class UsesNodeBuilderImpl implements UsesNodeBuilder {
             return sb.toString();\r
         }\r
     }\r
+\r
 }\r
index 5dedd3c0270a3776ee7a1400951784619c1cb683..6adc29b2271ce956fed15035084b1a3f9f7f77b0 100644 (file)
@@ -436,8 +436,8 @@ public final class YangParserImpl implements YangModelParser {
         final ModuleBuilder dependentModule = findDependentModuleBuilder(modules, module, unknownTypeQName.getPrefix(),
                 line);
 
-        final TypeDefinitionBuilder targetTypeBuilder = findTypeDefinitionBuilder(nodeToResolve.getPath(),
-                dependentModule, unknownTypeQName.getLocalName(), module.getName(), line);
+        final TypeDefinitionBuilder targetTypeBuilder = findTypeDefinitionBuilder(nodeToResolve, dependentModule,
+                unknownTypeQName.getLocalName(), module.getName(), line);
 
         if (nodeToResolveType instanceof ExtendedType) {
             final ExtendedType extType = (ExtendedType) nodeToResolveType;
@@ -504,7 +504,7 @@ public final class YangParserImpl implements YangModelParser {
             }
 
         } else {
-            final TypeDefinitionBuilder targetTypeBuilder = findTypeDefinitionBuilder(nodeToResolve.getPath(),
+            final TypeDefinitionBuilder targetTypeBuilder = findTypeDefinitionBuilder(nodeToResolve,
                     dependentModuleBuilder, unknownTypeQName.getLocalName(), module.getName(), line);
 
             if (nodeToResolveType instanceof ExtendedType) {
@@ -535,8 +535,8 @@ public final class YangParserImpl implements YangModelParser {
                 final UnknownType ut = (UnknownType) unionType;
                 final ModuleBuilder dependentModule = findDependentModuleBuilder(modules, builder, ut.getQName()
                         .getPrefix(), union.getLine());
-                final TypeDefinitionBuilder resolvedType = findTypeDefinitionBuilder(union.getPath(), dependentModule,
-                        ut.getQName().getLocalName(), builder.getName(), union.getLine());
+                final TypeDefinitionBuilder resolvedType = findTypeDefinitionBuilder(union, dependentModule, ut
+                        .getQName().getLocalName(), builder.getName(), union.getLine());
                 union.setTypedef(resolvedType);
                 toRemove.add(ut);
             } else if (unionType instanceof ExtendedType) {
@@ -546,8 +546,8 @@ public final class YangParserImpl implements YangModelParser {
                     final UnknownType ut = (UnknownType) extTypeBase;
                     final ModuleBuilder dependentModule = findDependentModuleBuilder(modules, builder, ut.getQName()
                             .getPrefix(), union.getLine());
-                    final TypeDefinitionBuilder targetTypeBuilder = findTypeDefinitionBuilder(union.getPath(),
-                            dependentModule, ut.getQName().getLocalName(), builder.getName(), union.getLine());
+                    final TypeDefinitionBuilder targetTypeBuilder = findTypeDefinitionBuilder(union, dependentModule,
+                            ut.getQName().getLocalName(), builder.getName(), union.getLine());
 
                     final TypeDefinitionBuilder newType = extendedTypeWithNewBaseTypeBuilder(targetTypeBuilder,
                             extType, modules, builder, union.getLine());
@@ -581,8 +581,8 @@ public final class YangParserImpl implements YangModelParser {
                     union.setType(type);
                     toRemove.add(ut);
                 } else {
-                    final TypeDefinitionBuilder resolvedType = findTypeDefinitionBuilder(union.getPath(),
-                            dependentModuleBuilder, utQName.getLocalName(), builder.getName(), union.getLine());
+                    final TypeDefinitionBuilder resolvedType = findTypeDefinitionBuilder(union, dependentModuleBuilder,
+                            utQName.getLocalName(), builder.getName(), union.getLine());
                     union.setTypedef(resolvedType);
                     toRemove.add(ut);
                 }
@@ -606,7 +606,7 @@ public final class YangParserImpl implements YangModelParser {
                         union.setTypedef(newType);
                         toRemove.add(extType);
                     } else {
-                        final TypeDefinitionBuilder targetTypeBuilder = findTypeDefinitionBuilder(union.getPath(),
+                        final TypeDefinitionBuilder targetTypeBuilder = findTypeDefinitionBuilder(union,
                                 dependentModuleBuilder, utQName.getLocalName(), builder.getName(), union.getLine());
 
                         final TypeDefinitionBuilder newType = extendedTypeWithNewBaseTypeBuilder(targetTypeBuilder,
@@ -645,7 +645,7 @@ public final class YangParserImpl implements YangModelParser {
             resolveAugment(modules, module);
             // while all augments are not resolved
             final Iterator<ModuleBuilder> allModulesIterator = allModulesSet.iterator();
-            while (!(module.getAugmentsResolved() == module.getAugments().size())) {
+            while (!(module.getAugmentsResolved() == module.getAllAugments().size())) {
                 ModuleBuilder nextModule = null;
                 // try resolve other module augments
                 try {
@@ -670,8 +670,8 @@ public final class YangParserImpl implements YangModelParser {
      *            current module
      */
     private void resolveAugment(final Map<String, TreeMap<Date, ModuleBuilder>> modules, final ModuleBuilder module) {
-        if (module.getAugmentsResolved() < module.getAugments().size()) {
-            for (AugmentationSchemaBuilder augmentBuilder : module.getAugments()) {
+        if (module.getAugmentsResolved() < module.getAllAugments().size()) {
+            for (AugmentationSchemaBuilder augmentBuilder : module.getAllAugments()) {
 
                 if (!augmentBuilder.isResolved()) {
                     final SchemaPath augmentTargetSchemaPath = augmentBuilder.getTargetPath();
@@ -685,7 +685,7 @@ public final class YangParserImpl implements YangModelParser {
 
                     final ModuleBuilder dependentModule = findDependentModuleBuilder(modules, module, prefix,
                             augmentBuilder.getLine());
-                    processAugmentation(augmentBuilder, path, module, qname, dependentModule);
+                    processAugmentation(augmentBuilder, path, module, dependentModule);
                 }
 
             }
@@ -719,7 +719,7 @@ public final class YangParserImpl implements YangModelParser {
             resolveAugmentWithContext(modules, module, context);
             // while all augments are not resolved
             final Iterator<ModuleBuilder> allModulesIterator = allModulesSet.iterator();
-            while (!(module.getAugmentsResolved() == module.getAugments().size())) {
+            while (!(module.getAugmentsResolved() == module.getAllAugments().size())) {
                 ModuleBuilder nextModule = null;
                 // try resolve other module augments
                 try {
@@ -745,9 +745,9 @@ public final class YangParserImpl implements YangModelParser {
      */
     private void resolveAugmentWithContext(final Map<String, TreeMap<Date, ModuleBuilder>> modules,
             final ModuleBuilder module, final SchemaContext context) {
-        if (module.getAugmentsResolved() < module.getAugments().size()) {
+        if (module.getAugmentsResolved() < module.getAllAugments().size()) {
 
-            for (AugmentationSchemaBuilder augmentBuilder : module.getAugments()) {
+            for (AugmentationSchemaBuilder augmentBuilder : module.getAllAugments()) {
                 final int line = augmentBuilder.getLine();
 
                 if (!augmentBuilder.isResolved()) {
@@ -767,7 +767,7 @@ public final class YangParserImpl implements YangModelParser {
                         processAugmentationOnContext(augmentBuilder, path, module, prefix, line, context);
                         continue;
                     } else {
-                        processAugmentation(augmentBuilder, path, module, qname, dependentModuleBuilder);
+                        processAugmentation(augmentBuilder, path, module, dependentModuleBuilder);
                     }
                 }
 
@@ -875,18 +875,17 @@ public final class YangParserImpl implements YangModelParser {
      *            module being resolved
      */
     private void resolveUsesRefine(final Map<String, TreeMap<Date, ModuleBuilder>> modules, final ModuleBuilder module) {
-        final Map<List<String>, UsesNodeBuilder> moduleUses = module.getUsesNodes();
-        for (Map.Entry<List<String>, UsesNodeBuilder> entry : moduleUses.entrySet()) {
+        final List<UsesNodeBuilder> allModuleUses = module.getAllUsesNodes();
+        for (UsesNodeBuilder usesNode : allModuleUses) {
             // refine
-            final UsesNodeBuilder usesNode = entry.getValue();
             final int line = usesNode.getLine();
             final GroupingBuilder targetGrouping = getTargetGroupingFromModules(usesNode, modules, module);
             usesNode.setGroupingPath(targetGrouping.getPath());
             for (RefineHolder refine : usesNode.getRefines()) {
                 final SchemaNodeBuilder nodeToRefine = RefineUtils.getRefineNodeFromGroupingBuilder(targetGrouping,
                         refine, module.getName());
-                if(nodeToRefine instanceof GroupingMember) {
-                    ((GroupingMember)nodeToRefine).setAddedByUses(true);
+                if (nodeToRefine instanceof GroupingMember) {
+                    ((GroupingMember) nodeToRefine).setAddedByUses(true);
                 }
                 RefineUtils.performRefine(nodeToRefine, refine, line);
                 usesNode.addRefineNode(nodeToRefine);
@@ -911,9 +910,8 @@ public final class YangParserImpl implements YangModelParser {
      */
     private void resolveUsesRefineWithContext(final Map<String, TreeMap<Date, ModuleBuilder>> modules,
             final ModuleBuilder module, final SchemaContext context) {
-        final Map<List<String>, UsesNodeBuilder> moduleUses = module.getUsesNodes();
-        for (Map.Entry<List<String>, UsesNodeBuilder> entry : moduleUses.entrySet()) {
-            final UsesNodeBuilder usesNode = entry.getValue();
+        final List<UsesNodeBuilder> moduleUses = module.getAllUsesNodes();
+        for (UsesNodeBuilder usesNode : moduleUses) {
             final int line = usesNode.getLine();
 
             final GroupingBuilder targetGroupingBuilder = getTargetGroupingFromModules(usesNode, modules, module);
@@ -923,8 +921,8 @@ public final class YangParserImpl implements YangModelParser {
                 for (RefineHolder refine : usesNode.getRefines()) {
                     final SchemaNodeBuilder nodeToRefine = RefineUtils.getRefineNodeFromGroupingDefinition(
                             targetGrouping, refine, module.getName());
-                    if(nodeToRefine instanceof GroupingMember) {
-                        ((GroupingMember)nodeToRefine).setAddedByUses(true);
+                    if (nodeToRefine instanceof GroupingMember) {
+                        ((GroupingMember) nodeToRefine).setAddedByUses(true);
                     }
                     RefineUtils.performRefine(nodeToRefine, refine, line);
                     usesNode.addRefineNode(nodeToRefine);
@@ -936,8 +934,8 @@ public final class YangParserImpl implements YangModelParser {
                 for (RefineHolder refine : usesNode.getRefines()) {
                     final SchemaNodeBuilder nodeToRefine = RefineUtils.getRefineNodeFromGroupingBuilder(
                             targetGroupingBuilder, refine, module.getName());
-                    if(nodeToRefine instanceof GroupingMember) {
-                        ((GroupingMember)nodeToRefine).setAddedByUses(true);
+                    if (nodeToRefine instanceof GroupingMember) {
+                        ((GroupingMember) nodeToRefine).setAddedByUses(true);
                     }
                     RefineUtils.performRefine(nodeToRefine, refine, line);
                     usesNode.addRefineNode(nodeToRefine);
@@ -989,36 +987,33 @@ public final class YangParserImpl implements YangModelParser {
             return null;
         }
 
-        List<QName> path = usesBuilder.getParent().getPath().getPath();
         GroupingBuilder result = null;
-        Set<GroupingBuilder> groupings = dependentModule.getModuleGroupings();
+        Set<GroupingBuilder> groupings = dependentModule.getGroupingBuilders();
         result = findGroupingBuilder(groupings, groupingName);
+        if (result != null) {
+            return result;
+        }
 
-        if (result == null) {
-            Builder currentNode = null;
-            final List<String> currentPath = new ArrayList<String>();
-            currentPath.add(dependentModule.getName());
-
-            for (int i = 0; i < path.size(); i++) {
-                QName qname = path.get(i);
-                currentPath.add(qname.getLocalName());
-                currentNode = dependentModule.getModuleNode(currentPath);
-
-                if (currentNode instanceof RpcDefinitionBuilder) {
-                    groupings = ((RpcDefinitionBuilder) currentNode).getGroupings();
-                } else if (currentNode instanceof DataNodeContainerBuilder) {
-                    groupings = ((DataNodeContainerBuilder) currentNode).getGroupingBuilders();
-                } else {
-                    groupings = Collections.emptySet();
-                }
+        Builder parent = usesBuilder.getParent();
 
-                result = findGroupingBuilder(groupings, groupingName);
-                if (result != null) {
-                    break;
-                }
+        while (parent != null) {
+            if (parent instanceof DataNodeContainerBuilder) {
+                groupings = ((DataNodeContainerBuilder) parent).getGroupingBuilders();
+            } else if (parent instanceof RpcDefinitionBuilder) {
+                groupings = ((RpcDefinitionBuilder) parent).getGroupings();
+            }
+            result = findGroupingBuilder(groupings, groupingName);
+            if (result == null) {
+                parent = parent.getParent();
+            } else {
+                break;
             }
         }
 
+        if (result == null) {
+            throw new YangParseException(module.getName(), line, "Referenced grouping '" + groupingName
+                    + "' not found.");
+        }
         return result;
     }
 
@@ -1069,9 +1064,9 @@ public final class YangParserImpl implements YangModelParser {
         for (DataSchemaNodeBuilder child : targetGrouping.getChildNodeBuilders()) {
             // if node is refined, take it from refined nodes and continue
             SchemaNodeBuilder refined = getRefined(child.getQName(), refineNodes);
-            if(refined != null) {
+            if (refined != null) {
                 refined.setPath(createSchemaPath(parentPath, refined.getQName().getLocalName()));
-                parent.addChildNode((DataSchemaNodeBuilder)refined);
+                parent.addChildNode((DataSchemaNodeBuilder) refined);
                 continue;
             }
 
@@ -1130,9 +1125,9 @@ public final class YangParserImpl implements YangModelParser {
         for (DataSchemaNode child : targetGrouping.getChildNodes()) {
             // if node is refined, take it from refined nodes and continue
             SchemaNodeBuilder refined = getRefined(child.getQName(), refineNodes);
-            if(refined != null) {
+            if (refined != null) {
                 refined.setPath(createSchemaPath(parentPath, refined.getQName().getLocalName()));
-                parent.addChildNode((DataSchemaNodeBuilder)refined);
+                parent.addChildNode((DataSchemaNodeBuilder) refined);
                 continue;
             }
 
index 28095b5ef75331bd5c128f82692da619b396272b..f806c94a30909c9a507c9eb3d6a3b4d948a532b5 100644 (file)
@@ -13,7 +13,6 @@ import java.net.URI;
 import java.text.DateFormat;
 import java.text.ParseException;
 import java.text.SimpleDateFormat;
-import java.util.ArrayList;
 import java.util.Date;
 import java.util.List;
 import java.util.Stack;
@@ -52,7 +51,6 @@ import org.opendaylight.controller.antlrv4.code.gen.YangParser.When_stmtContext;
 import org.opendaylight.controller.antlrv4.code.gen.YangParser.Yang_version_stmtContext;
 import org.opendaylight.controller.yang.common.QName;
 import org.opendaylight.controller.yang.model.api.SchemaPath;
-import org.opendaylight.controller.yang.model.api.Status;
 import org.opendaylight.controller.yang.model.api.TypeDefinition;
 import org.opendaylight.controller.yang.model.util.YangTypesConverter;
 import org.opendaylight.controller.yang.parser.builder.api.AugmentationSchemaBuilder;
@@ -94,6 +92,7 @@ public final class YangParserListenerImpl extends YangParserBaseListener {
     @Override
     public void enterModule_stmt(YangParser.Module_stmtContext ctx) {
         moduleName = stringFromNode(ctx);
+        logger.debug("enter module " + moduleName);
         actualPath.push(moduleName);
         moduleBuilder = new ModuleBuilder(moduleName);
 
@@ -118,14 +117,12 @@ public final class YangParserListenerImpl extends YangParserBaseListener {
 
     @Override
     public void exitModule_stmt(YangParser.Module_stmtContext ctx) {
-        final String moduleName = actualPath.pop();
-        logger.debug("Exiting module " + moduleName);
+        exitLog("module", actualPath.pop());
     }
 
     @Override
-    public void enterModule_header_stmts(final Module_header_stmtsContext ctx) {
-        super.enterModule_header_stmts(ctx);
-
+    public void enterModule_header_stmts(Module_header_stmtsContext ctx) {
+        enterLog("module_header", "", ctx.getStart().getLine());
         String yangVersion = null;
         for (int i = 0; i < ctx.getChildCount(); ++i) {
             final ParseTree treeNode = ctx.getChild(i);
@@ -133,11 +130,14 @@ public final class YangParserListenerImpl extends YangParserBaseListener {
                 final String namespaceStr = stringFromNode(treeNode);
                 namespace = URI.create(namespaceStr);
                 moduleBuilder.setNamespace(namespace);
+                setLog("namespace", namespaceStr);
             } else if (treeNode instanceof Prefix_stmtContext) {
                 yangModelPrefix = stringFromNode(treeNode);
                 moduleBuilder.setPrefix(yangModelPrefix);
+                setLog("prefix", yangModelPrefix);
             } else if (treeNode instanceof Yang_version_stmtContext) {
                 yangVersion = stringFromNode(treeNode);
+                setLog("yang-version", yangVersion);
             }
         }
 
@@ -147,34 +147,44 @@ public final class YangParserListenerImpl extends YangParserBaseListener {
         moduleBuilder.setYangVersion(yangVersion);
     }
 
+    @Override
+    public void exitModule_header_stmts(Module_header_stmtsContext ctx) {
+        exitLog("module_header", "");
+    }
+
     @Override
     public void enterMeta_stmts(YangParser.Meta_stmtsContext ctx) {
+        enterLog("meta_stmt", "", ctx.getStart().getLine());
         for (int i = 0; i < ctx.getChildCount(); i++) {
             ParseTree child = ctx.getChild(i);
             if (child instanceof Organization_stmtContext) {
                 final String organization = stringFromNode(child);
                 moduleBuilder.setOrganization(organization);
+                setLog("organization", organization);
             } else if (child instanceof Contact_stmtContext) {
                 final String contact = stringFromNode(child);
                 moduleBuilder.setContact(contact);
+                setLog("contact", contact);
             } else if (child instanceof Description_stmtContext) {
                 final String description = stringFromNode(child);
                 moduleBuilder.setDescription(description);
+                setLog("description", description);
             } else if (child instanceof Reference_stmtContext) {
                 final String reference = stringFromNode(child);
                 moduleBuilder.setReference(reference);
+                setLog("reference", reference);
             }
         }
     }
 
     @Override
-    public void exitSubmodule_header_stmts(YangParser.Submodule_header_stmtsContext ctx) {
-        final String submodule = actualPath.pop();
-        logger.debug("exiting submodule " + submodule);
+    public void exitMeta_stmts(YangParser.Meta_stmtsContext ctx) {
+        exitLog("meta_stmt", "");
     }
 
     @Override
     public void enterRevision_stmts(Revision_stmtsContext ctx) {
+        enterLog("revisions", "", ctx.getStart().getLine());
         if (ctx != null) {
             for (int i = 0; i < ctx.getChildCount(); ++i) {
                 final ParseTree treeNode = ctx.getChild(i);
@@ -185,6 +195,11 @@ public final class YangParserListenerImpl extends YangParserBaseListener {
         }
     }
 
+    @Override
+    public void exitRevision_stmts(Revision_stmtsContext ctx) {
+        exitLog("revisions", "");
+    }
+
     private void updateRevisionForRevisionStatement(final ParseTree treeNode) {
         final String revisionDateStr = stringFromNode(treeNode);
         try {
@@ -192,6 +207,7 @@ public final class YangParserListenerImpl extends YangParserBaseListener {
             if ((revision != null) && (this.revision.compareTo(revision) < 0)) {
                 this.revision = revision;
                 moduleBuilder.setRevision(this.revision);
+                setLog("revision", this.revision.toString());
                 for (int i = 0; i < treeNode.getChildCount(); ++i) {
                     ParseTree child = treeNode.getChild(i);
                     if (child instanceof Reference_stmtContext) {
@@ -207,7 +223,10 @@ public final class YangParserListenerImpl extends YangParserBaseListener {
 
     @Override
     public void enterImport_stmt(Import_stmtContext ctx) {
+        final int line = ctx.getStart().getLine();
         final String importName = stringFromNode(ctx);
+        enterLog("import", importName, line);
+
         String importPrefix = null;
         Date importRevision = null;
 
@@ -221,50 +240,58 @@ public final class YangParserListenerImpl extends YangParserBaseListener {
                 try {
                     importRevision = simpleDateFormat.parse(importRevisionStr);
                 } catch (ParseException e) {
-                    logger.warn("Failed to parse import revision-date: " + importRevisionStr);
+                    logger.warn("Failed to parse import revision-date at line " + line + ": " + importRevisionStr);
                 }
             }
         }
         moduleBuilder.addModuleImport(importName, importRevision, importPrefix);
+        setLog("import", "(" + importName + "; " + importRevision + "; " + importPrefix + ")");
+    }
+
+    @Override
+    public void exitImport_stmt(Import_stmtContext ctx) {
+        exitLog("import", "");
     }
 
     @Override
     public void enterAugment_stmt(YangParser.Augment_stmtContext ctx) {
+        final int line = ctx.getStart().getLine();
         final String augmentPath = stringFromNode(ctx);
-        AugmentationSchemaBuilder builder = moduleBuilder.addAugment(augmentPath, actualPath, ctx.getStart().getLine());
-        moduleBuilder.enterNode(builder);
-        updatePath(augmentPath);
+        enterLog("augment", augmentPath, line);
+
+        AugmentationSchemaBuilder builder = moduleBuilder.addAugment(line, augmentPath);
 
         for (int i = 0; i < ctx.getChildCount(); i++) {
             ParseTree child = ctx.getChild(i);
             if (child instanceof Description_stmtContext) {
-                String desc = stringFromNode(child);
-                builder.setDescription(desc);
+                builder.setDescription(stringFromNode(child));
             } else if (child instanceof Reference_stmtContext) {
-                String ref = stringFromNode(child);
-                builder.setReference(ref);
+                builder.setReference(stringFromNode(child));
             } else if (child instanceof Status_stmtContext) {
-                Status status = parseStatus((Status_stmtContext) child);
-                builder.setStatus(status);
+                builder.setStatus(parseStatus((Status_stmtContext) child));
             } else if (child instanceof When_stmtContext) {
-                String when = stringFromNode(child);
-                builder.addWhenCondition(when);
+                builder.addWhenCondition(stringFromNode(child));
             }
         }
+
+        moduleBuilder.enterNode(builder);
+        actualPath.push(augmentPath);
     }
 
     @Override
     public void exitAugment_stmt(YangParser.Augment_stmtContext ctx) {
-        final String augment = actualPath.pop();
-        logger.debug("exiting augment " + augment);
         moduleBuilder.exitNode();
+        exitLog("augment", actualPath.pop());
     }
 
     @Override
     public void enterExtension_stmt(YangParser.Extension_stmtContext ctx) {
+        final int line = ctx.getStart().getLine();
         final String extName = stringFromNode(ctx);
+        enterLog("extension", extName, line);
+
         QName qname = new QName(namespace, revision, yangModelPrefix, extName);
-        ExtensionBuilder builder = moduleBuilder.addExtension(qname, ctx.getStart().getLine());
+        ExtensionBuilder builder = moduleBuilder.addExtension(qname, line);
         parseSchemaNodeArgs(ctx, builder);
 
         String argument = null;
@@ -279,15 +306,27 @@ public final class YangParserListenerImpl extends YangParserBaseListener {
         }
         builder.setArgument(argument);
         builder.setYinElement(yin);
+
+        moduleBuilder.enterNode(builder);
+        actualPath.push(extName);
+    }
+
+    @Override
+    public void exitExtension_stmt(YangParser.Extension_stmtContext ctx) {
+        moduleBuilder.exitNode();
+        exitLog("extension", actualPath.pop());
     }
 
     @Override
     public void enterTypedef_stmt(YangParser.Typedef_stmtContext ctx) {
+        final int line = ctx.getStart().getLine();
         final String typedefName = stringFromNode(ctx);
+        enterLog("typedef", typedefName, line);
+
         QName typedefQName = new QName(namespace, revision, yangModelPrefix, typedefName);
-        TypeDefinitionBuilder builder = moduleBuilder.addTypedef(typedefQName, actualPath, ctx.getStart().getLine());
+        TypeDefinitionBuilder builder = moduleBuilder.addTypedef(line, typedefQName);
         moduleBuilder.enterNode(builder);
-        updatePath(typedefName);
+        actualPath.push(typedefName);
 
         builder.setPath(createActualSchemaPath(actualPath, namespace, revision, yangModelPrefix));
         parseSchemaNodeArgs(ctx, builder);
@@ -296,15 +335,16 @@ public final class YangParserListenerImpl extends YangParserBaseListener {
 
     @Override
     public void exitTypedef_stmt(YangParser.Typedef_stmtContext ctx) {
-        final String actContainer = actualPath.pop();
-        logger.debug("exiting " + actContainer);
         moduleBuilder.exitNode();
+        exitLog("typedef", actualPath.pop());
     }
 
     @Override
     public void enterType_stmt(YangParser.Type_stmtContext ctx) {
-        final String typeName = stringFromNode(ctx);
         final int line = ctx.getStart().getLine();
+        final String typeName = stringFromNode(ctx);
+        enterLog("type", typeName, line);
+
         final QName typeQName = parseQName(typeName);
 
         TypeDefinition<?> type = null;
@@ -323,22 +363,20 @@ public final class YangParserListenerImpl extends YangParserBaseListener {
                 checkMissingBody(typeName, moduleName, line);
                 // if there are no constraints, just grab default base yang type
                 type = YangTypesConverter.javaTypeForBaseYangType(actualPath, namespace, revision, typeName);
-                moduleBuilder.setType(type, actualPath);
+                moduleBuilder.setType(type);
             } else {
                 if ("union".equals(typeName)) {
-                    List<String> typePath = new ArrayList<String>(actualPath);
-                    typePath.add(typeName);
-                    SchemaPath p = createActualSchemaPath(typePath, namespace, revision, yangModelPrefix);
+                    SchemaPath p = createActualSchemaPath(actualPath, namespace, revision, yangModelPrefix, typeName);
                     UnionTypeBuilder unionBuilder = moduleBuilder.addUnionType(actualPath, namespace, revision, line);
                     moduleBuilder.enterNode(unionBuilder);
                     unionBuilder.setPath(p);
                 } else if ("identityref".equals(typeName)) {
-                    SchemaPath path = createActualSchemaPath(actualPath, namespace, revision, yangModelPrefix);
+                    SchemaPath path = createActualSchemaPath(actualPath, namespace, revision, yangModelPrefix, typeName);
                     moduleBuilder.addIdentityrefType(getIdentityrefBase(typeBody), actualPath, path, line);
                 } else {
                     type = parseTypeWithBody(moduleName, typeName, typeBody, actualPath, namespace, revision,
                             yangModelPrefix, moduleBuilder.getActualNode());
-                    moduleBuilder.setType(type, actualPath);
+                    moduleBuilder.setType(type);
                 }
             }
         } else {
@@ -346,10 +384,10 @@ public final class YangParserListenerImpl extends YangParserBaseListener {
                     moduleBuilder.getActualNode());
             // add parent node of this type statement to dirty nodes
             moduleBuilder.addDirtyNode(actualPath);
-            moduleBuilder.setType(type, actualPath);
+            moduleBuilder.setType(type);
         }
 
-        updatePath(typeName);
+        actualPath.push(typeName);
     }
 
     private QName parseQName(String typeName) {
@@ -371,44 +409,46 @@ public final class YangParserListenerImpl extends YangParserBaseListener {
 
     @Override
     public void exitType_stmt(YangParser.Type_stmtContext ctx) {
-        final String actContainer = actualPath.pop();
-        logger.debug("exiting " + actContainer);
-
         final String typeName = stringFromNode(ctx);
         if ("union".equals(typeName)) {
             moduleBuilder.exitNode();
         }
+        exitLog("type", actualPath.pop());
     }
 
     @Override
     public void enterGrouping_stmt(YangParser.Grouping_stmtContext ctx) {
+        final int line = ctx.getStart().getLine();
         final String groupName = stringFromNode(ctx);
+        enterLog("grouping", groupName, line);
+
         QName groupQName = new QName(namespace, revision, yangModelPrefix, groupName);
-        GroupingBuilder builder = moduleBuilder.addGrouping(groupQName, actualPath, ctx.getStart().getLine());
+        GroupingBuilder builder = moduleBuilder.addGrouping(ctx.getStart().getLine(), groupQName);
         moduleBuilder.enterNode(builder);
-        updatePath(groupName);
+        actualPath.push(groupName);
+
         builder.setPath(createActualSchemaPath(actualPath, namespace, revision, yangModelPrefix));
         parseSchemaNodeArgs(ctx, builder);
     }
 
     @Override
     public void exitGrouping_stmt(YangParser.Grouping_stmtContext ctx) {
-        String actContainer = actualPath.pop();
-        logger.debug("exiting " + actContainer);
         moduleBuilder.exitNode();
+        exitLog("grouping", actualPath.pop());
     }
 
     @Override
     public void enterContainer_stmt(Container_stmtContext ctx) {
         final int line = ctx.getStart().getLine();
         final String containerName = stringFromNode(ctx);
-        QName containerQName = new QName(namespace, revision, yangModelPrefix, containerName);
+        enterLog("container", containerName, line);
 
+        QName containerQName = new QName(namespace, revision, yangModelPrefix, containerName);
         SchemaPath path = createActualSchemaPath(actualPath, namespace, revision, yangModelPrefix, containerName);
 
-        ContainerSchemaNodeBuilder builder = moduleBuilder.addContainerNode(path, containerQName, actualPath, line);
+        ContainerSchemaNodeBuilder builder = moduleBuilder.addContainerNode(line, containerQName, path);
         moduleBuilder.enterNode(builder);
-        updatePath(containerName);
+        actualPath.push(containerName);
 
         parseSchemaNodeArgs(ctx, builder);
         parseConstraints(ctx, builder.getConstraints());
@@ -425,24 +465,26 @@ public final class YangParserListenerImpl extends YangParserBaseListener {
 
     @Override
     public void exitContainer_stmt(Container_stmtContext ctx) {
-        final String actContainer = actualPath.pop();
-        logger.debug("exiting " + actContainer);
         moduleBuilder.exitNode();
+        exitLog("container", actualPath.pop());
     }
 
     @Override
     public void enterLeaf_stmt(Leaf_stmtContext ctx) {
+        final int line = ctx.getStart().getLine();
         final String leafName = stringFromNode(ctx);
+        enterLog("leaf", leafName, line);
+
         QName leafQName = new QName(namespace, revision, yangModelPrefix, leafName);
         SchemaPath schemaPath = createActualSchemaPath(actualPath, namespace, revision, yangModelPrefix, leafName);
 
-        LeafSchemaNodeBuilder builder = moduleBuilder.addLeafNode(schemaPath, leafQName, actualPath, ctx.getStart().getLine());
+        LeafSchemaNodeBuilder builder = moduleBuilder.addLeafNode(line, leafQName, schemaPath);
         moduleBuilder.enterNode(builder);
-        updatePath(leafName);
+        actualPath.push(leafName);
 
         parseSchemaNodeArgs(ctx, builder);
         parseConstraints(ctx, builder.getConstraints());
-        builder.setConfiguration(getConfig(ctx, moduleBuilder.getActualParent(), moduleName, ctx.getStart().getLine()));
+        builder.setConfiguration(getConfig(ctx, moduleBuilder.getActualParent(), moduleName, line));
 
         String defaultStr = null;
         String unitsStr = null;
@@ -460,53 +502,57 @@ public final class YangParserListenerImpl extends YangParserBaseListener {
 
     @Override
     public void exitLeaf_stmt(YangParser.Leaf_stmtContext ctx) {
-        final String actLeaf = actualPath.pop();
-        logger.debug("exiting " + actLeaf);
         moduleBuilder.exitNode();
+        exitLog("leaf", actualPath.pop());
     }
 
     @Override
     public void enterUses_stmt(YangParser.Uses_stmtContext ctx) {
+        final int line = ctx.getStart().getLine();
         final String groupingPathStr = stringFromNode(ctx);
-        UsesNodeBuilder builder = moduleBuilder.addUsesNode(groupingPathStr, actualPath, ctx.getStart().getLine());
+        enterLog("uses", groupingPathStr, line);
+
+        UsesNodeBuilder builder = moduleBuilder.addUsesNode(line, groupingPathStr);
 
         moduleBuilder.enterNode(builder);
-        updatePath(groupingPathStr);
+        actualPath.push(groupingPathStr);
     }
 
     @Override
     public void exitUses_stmt(YangParser.Uses_stmtContext ctx) {
-        final String actContainer = actualPath.pop();
-        logger.debug("exiting " + actContainer);
         moduleBuilder.exitNode();
+        exitLog("uses", actualPath.pop());
     }
 
     @Override
     public void enterRefine_stmt(YangParser.Refine_stmtContext ctx) {
-        String refineString = stringFromNode(ctx);
+        final String refineString = stringFromNode(ctx);
+        enterLog("refine", refineString, ctx.getStart().getLine());
+
         RefineHolder refine = parseRefine(ctx);
         moduleBuilder.addRefine(refine, actualPath);
         moduleBuilder.enterNode(refine);
-        updatePath(refineString);
+        actualPath.push(refineString);
     }
 
     @Override
     public void exitRefine_stmt(YangParser.Refine_stmtContext ctx) {
-        final String actContainer = actualPath.pop();
-        logger.debug("exiting " + actContainer);
         moduleBuilder.exitNode();
+        exitLog("refine", actualPath.pop());
     }
 
     @Override
     public void enterLeaf_list_stmt(Leaf_list_stmtContext ctx) {
+        final int line = ctx.getStart().getLine();
         final String leafListName = stringFromNode(ctx);
+        enterLog("leaf-list", leafListName, line);
+
         QName leafListQName = new QName(namespace, revision, yangModelPrefix, leafListName);
         SchemaPath schemaPath = createActualSchemaPath(actualPath, namespace, revision, yangModelPrefix, leafListName);
 
-        LeafListSchemaNodeBuilder builder = moduleBuilder.addLeafListNode(schemaPath, leafListQName, actualPath, ctx.getStart()
-                .getLine());
+        LeafListSchemaNodeBuilder builder = moduleBuilder.addLeafListNode(line, leafListQName, schemaPath);
         moduleBuilder.enterNode(builder);
-        updatePath(leafListName);
+        actualPath.push(leafListName);
 
         parseSchemaNodeArgs(ctx, builder);
         parseConstraints(ctx, builder.getConstraints());
@@ -525,24 +571,26 @@ public final class YangParserListenerImpl extends YangParserBaseListener {
 
     @Override
     public void exitLeaf_list_stmt(YangParser.Leaf_list_stmtContext ctx) {
-        final String actContainer = actualPath.pop();
-        logger.debug("exiting " + actContainer);
         moduleBuilder.exitNode();
+        exitLog("leaf-list", actualPath.pop());
     }
 
     @Override
     public void enterList_stmt(List_stmtContext ctx) {
+        final int line = ctx.getStart().getLine();
         final String listName = stringFromNode(ctx);
+        enterLog("list", listName, line);
+
         QName listQName = new QName(namespace, revision, yangModelPrefix, listName);
         SchemaPath schemaPath = createActualSchemaPath(actualPath, namespace, revision, yangModelPrefix, listName);
 
-        ListSchemaNodeBuilder builder = moduleBuilder.addListNode(schemaPath, listQName, actualPath, ctx.getStart().getLine());
+        ListSchemaNodeBuilder builder = moduleBuilder.addListNode(line, listQName, schemaPath);
         moduleBuilder.enterNode(builder);
-        updatePath(listName);
+        actualPath.push(listName);
 
         parseSchemaNodeArgs(ctx, builder);
         parseConstraints(ctx, builder.getConstraints());
-        builder.setConfiguration(getConfig(ctx, moduleBuilder.getActualParent(), moduleName, ctx.getStart().getLine()));
+        builder.setConfiguration(getConfig(ctx, moduleBuilder.getActualParent(), moduleName, line));
 
         String keyDefinition = "";
         for (int i = 0; i < ctx.getChildCount(); ++i) {
@@ -561,45 +609,50 @@ public final class YangParserListenerImpl extends YangParserBaseListener {
 
     @Override
     public void exitList_stmt(List_stmtContext ctx) {
-        final String actContainer = actualPath.pop();
-        logger.debug("exiting " + actContainer);
         moduleBuilder.exitNode();
+        exitLog("list", actualPath.pop());
     }
 
     @Override
     public void enterAnyxml_stmt(YangParser.Anyxml_stmtContext ctx) {
+        final int line = ctx.getStart().getLine();
         final String anyXmlName = stringFromNode(ctx);
+        enterLog("anyxml", anyXmlName, line);
+
         QName anyXmlQName = new QName(namespace, revision, yangModelPrefix, anyXmlName);
         SchemaPath schemaPath = createActualSchemaPath(actualPath, namespace, revision, yangModelPrefix, anyXmlName);
 
-        AnyXmlBuilder builder = moduleBuilder.addAnyXml(schemaPath, anyXmlQName, actualPath, ctx.getStart().getLine());
+        AnyXmlBuilder builder = moduleBuilder.addAnyXml(line, anyXmlQName, schemaPath);
         moduleBuilder.enterNode(builder);
-        updatePath(anyXmlName);
+        actualPath.push(anyXmlName);
 
         parseSchemaNodeArgs(ctx, builder);
         parseConstraints(ctx, builder.getConstraints());
-        builder.setConfiguration(getConfig(ctx, moduleBuilder.getActualParent(), moduleName, ctx.getStart().getLine()));
+        builder.setConfiguration(getConfig(ctx, moduleBuilder.getActualParent(), moduleName, line));
     }
 
     @Override
     public void exitAnyxml_stmt(YangParser.Anyxml_stmtContext ctx) {
-        final String actContainer = actualPath.pop();
-        logger.debug("exiting " + actContainer);
         moduleBuilder.exitNode();
+        exitLog("anyxml", actualPath.pop());
     }
 
     @Override
     public void enterChoice_stmt(YangParser.Choice_stmtContext ctx) {
+        final int line = ctx.getStart().getLine();
         final String choiceName = stringFromNode(ctx);
+        enterLog("choice", choiceName, line);
+
         QName choiceQName = new QName(namespace, revision, yangModelPrefix, choiceName);
-        ChoiceBuilder builder = moduleBuilder.addChoice(choiceQName, actualPath, ctx.getStart().getLine());
+
+        ChoiceBuilder builder = moduleBuilder.addChoice(line, choiceQName);
         moduleBuilder.enterNode(builder);
+        actualPath.push(choiceName);
 
-        updatePath(choiceName);
         builder.setPath(createActualSchemaPath(actualPath, namespace, revision, yangModelPrefix));
         parseSchemaNodeArgs(ctx, builder);
         parseConstraints(ctx, builder.getConstraints());
-        builder.setConfiguration(getConfig(ctx, moduleBuilder.getActualParent(), moduleName, ctx.getStart().getLine()));
+        builder.setConfiguration(getConfig(ctx, moduleBuilder.getActualParent(), moduleName, line));
 
         // set 'default' case
         for (int i = 0; i < ctx.getChildCount(); i++) {
@@ -614,19 +667,21 @@ public final class YangParserListenerImpl extends YangParserBaseListener {
 
     @Override
     public void exitChoice_stmt(YangParser.Choice_stmtContext ctx) {
-        final String actContainer = actualPath.pop();
-        logger.debug("exiting " + actContainer);
         moduleBuilder.exitNode();
+        exitLog("choice", actualPath.pop());
     }
 
     @Override
     public void enterCase_stmt(YangParser.Case_stmtContext ctx) {
+        final int line = ctx.getStart().getLine();
         final String caseName = stringFromNode(ctx);
-        QName choiceQName = new QName(namespace, revision, yangModelPrefix, caseName);
-        ChoiceCaseBuilder builder = moduleBuilder.addCase(choiceQName, actualPath, ctx.getStart().getLine());
+        enterLog("case", caseName, line);
+
+        QName caseQName = new QName(namespace, revision, yangModelPrefix, caseName);
+        ChoiceCaseBuilder builder = moduleBuilder.addCase(line, caseQName);
         moduleBuilder.enterNode(builder);
+        actualPath.push(caseName);
 
-        updatePath(caseName);
         builder.setPath(createActualSchemaPath(actualPath, namespace, revision, yangModelPrefix));
         parseSchemaNodeArgs(ctx, builder);
         parseConstraints(ctx, builder.getConstraints());
@@ -634,19 +689,20 @@ public final class YangParserListenerImpl extends YangParserBaseListener {
 
     @Override
     public void exitCase_stmt(YangParser.Case_stmtContext ctx) {
-        final String actContainer = actualPath.pop();
-        logger.debug("exiting " + actContainer);
         moduleBuilder.exitNode();
+        exitLog("case", actualPath.pop());
     }
 
     @Override
     public void enterNotification_stmt(YangParser.Notification_stmtContext ctx) {
+        final int line = ctx.getStart().getLine();
         final String notificationName = stringFromNode(ctx);
+        enterLog("notification", notificationName, line);
+
         QName notificationQName = new QName(namespace, revision, yangModelPrefix, notificationName);
-        NotificationBuilder builder = moduleBuilder.addNotification(notificationQName, actualPath, ctx.getStart()
-                .getLine());
+        NotificationBuilder builder = moduleBuilder.addNotification(notificationQName, actualPath, line);
         moduleBuilder.enterNode(builder);
-        updatePath(notificationName);
+        actualPath.push(notificationName);
 
         builder.setPath(createActualSchemaPath(actualPath, namespace, revision, yangModelPrefix));
         parseSchemaNodeArgs(ctx, builder);
@@ -654,15 +710,17 @@ public final class YangParserListenerImpl extends YangParserBaseListener {
 
     @Override
     public void exitNotification_stmt(YangParser.Notification_stmtContext ctx) {
-        final String actContainer = actualPath.pop();
-        logger.debug("exiting " + actContainer);
         moduleBuilder.exitNode();
+        exitLog("notification", actualPath.pop());
     }
 
-    // Unknown types
+    // Unknown nodes
     @Override
     public void enterIdentifier_stmt(YangParser.Identifier_stmtContext ctx) {
+        final int line = ctx.getStart().getLine();
         final String nodeParameter = stringFromNode(ctx);
+        enterLog("unknown-node", nodeParameter, line);
+
         QName nodeType = null;
 
         final String nodeTypeStr = ctx.getChild(0).getText();
@@ -685,11 +743,10 @@ public final class YangParserListenerImpl extends YangParserBaseListener {
             qname = new QName(namespace, revision, yangModelPrefix, nodeParameter);
         }
 
-        UnknownSchemaNodeBuilder builder = moduleBuilder.addUnknownSchemaNode(qname, actualPath, ctx.getStart()
-                .getLine());
+        UnknownSchemaNodeBuilder builder = moduleBuilder.addUnknownSchemaNode(qname, actualPath, line);
         builder.setNodeType(nodeType);
         builder.setNodeParameter(nodeParameter);
-        updatePath(nodeParameter);
+        actualPath.push(nodeParameter);
         builder.setPath(createActualSchemaPath(actualPath, namespace, revision, yangModelPrefix));
         parseSchemaNodeArgs(ctx, builder);
         moduleBuilder.enterNode(builder);
@@ -697,18 +754,20 @@ public final class YangParserListenerImpl extends YangParserBaseListener {
 
     @Override
     public void exitIdentifier_stmt(YangParser.Identifier_stmtContext ctx) {
-        final String actContainer = actualPath.pop();
-        logger.debug("exiting " + actContainer);
         moduleBuilder.exitNode();
+        exitLog("unknown-node", actualPath.pop());
     }
 
     @Override
     public void enterRpc_stmt(YangParser.Rpc_stmtContext ctx) {
+        final int line = ctx.getStart().getLine();
         final String rpcName = stringFromNode(ctx);
+        enterLog("rpc", rpcName, line);
+
         QName rpcQName = new QName(namespace, revision, yangModelPrefix, rpcName);
-        RpcDefinitionBuilder rpcBuilder = moduleBuilder.addRpc(rpcQName, actualPath, ctx.getStart().getLine());
+        RpcDefinitionBuilder rpcBuilder = moduleBuilder.addRpc(line, rpcQName);
         moduleBuilder.enterNode(rpcBuilder);
-        updatePath(rpcName);
+        actualPath.push(rpcName);
 
         rpcBuilder.setPath(createActualSchemaPath(actualPath, namespace, revision, yangModelPrefix));
         parseSchemaNodeArgs(ctx, rpcBuilder);
@@ -716,20 +775,22 @@ public final class YangParserListenerImpl extends YangParserBaseListener {
 
     @Override
     public void exitRpc_stmt(YangParser.Rpc_stmtContext ctx) {
-        final String actContainer = actualPath.pop();
-        logger.debug("exiting " + actContainer);
         moduleBuilder.exitNode();
+        exitLog("rpc", actualPath.pop());
     }
 
     @Override
     public void enterInput_stmt(YangParser.Input_stmtContext ctx) {
+        final int line = ctx.getStart().getLine();
         final String input = "input";
+        enterLog(input, input, line);
+
         QName rpcQName = new QName(namespace, revision, yangModelPrefix, input);
         SchemaPath path = createActualSchemaPath(actualPath, namespace, revision, yangModelPrefix, input);
 
-        ContainerSchemaNodeBuilder builder = moduleBuilder.addRpcInput(path, rpcQName, ctx.getStart().getLine());
+        ContainerSchemaNodeBuilder builder = moduleBuilder.addRpcInput(path, rpcQName, line);
         moduleBuilder.enterNode(builder);
-        updatePath(input);
+        actualPath.push(input);
 
         parseSchemaNodeArgs(ctx, builder);
         parseConstraints(ctx, builder.getConstraints());
@@ -737,20 +798,22 @@ public final class YangParserListenerImpl extends YangParserBaseListener {
 
     @Override
     public void exitInput_stmt(YangParser.Input_stmtContext ctx) {
-        final String actContainer = actualPath.pop();
-        logger.debug("exiting " + actContainer);
         moduleBuilder.exitNode();
+        exitLog("input", actualPath.pop());
     }
 
     @Override
     public void enterOutput_stmt(YangParser.Output_stmtContext ctx) {
+        final int line = ctx.getStart().getLine();
         final String output = "output";
+        enterLog(output, output, line);
+
         QName rpcQName = new QName(namespace, revision, yangModelPrefix, output);
         SchemaPath path = createActualSchemaPath(actualPath, namespace, revision, yangModelPrefix, output);
 
-        ContainerSchemaNodeBuilder builder = moduleBuilder.addRpcOutput(path, rpcQName, ctx.getStart().getLine());
+        ContainerSchemaNodeBuilder builder = moduleBuilder.addRpcOutput(path, rpcQName, line);
         moduleBuilder.enterNode(builder);
-        updatePath(output);
+        actualPath.push(output);
 
         parseSchemaNodeArgs(ctx, builder);
         parseConstraints(ctx, builder.getConstraints());
@@ -758,18 +821,20 @@ public final class YangParserListenerImpl extends YangParserBaseListener {
 
     @Override
     public void exitOutput_stmt(YangParser.Output_stmtContext ctx) {
-        final String actContainer = actualPath.pop();
-        logger.debug("exiting " + actContainer);
         moduleBuilder.exitNode();
+        exitLog("output", actualPath.pop());
     }
 
     @Override
     public void enterFeature_stmt(YangParser.Feature_stmtContext ctx) {
+        final int line = ctx.getStart().getLine();
         final String featureName = stringFromNode(ctx);
+        enterLog("feature", featureName, line);
+
         QName featureQName = new QName(namespace, revision, yangModelPrefix, featureName);
-        FeatureBuilder featureBuilder = moduleBuilder.addFeature(featureQName, actualPath, ctx.getStart().getLine());
+        FeatureBuilder featureBuilder = moduleBuilder.addFeature(line, featureQName);
         moduleBuilder.enterNode(featureBuilder);
-        updatePath(featureName);
+        actualPath.push(featureName);
 
         featureBuilder.setPath(createActualSchemaPath(actualPath, namespace, revision, yangModelPrefix));
         parseSchemaNodeArgs(ctx, featureBuilder);
@@ -777,19 +842,21 @@ public final class YangParserListenerImpl extends YangParserBaseListener {
 
     @Override
     public void exitFeature_stmt(YangParser.Feature_stmtContext ctx) {
-        final String actContainer = actualPath.pop();
-        logger.debug("exiting " + actContainer);
         moduleBuilder.exitNode();
+        exitLog("feature", actualPath.pop());
     }
 
     @Override
     public void enterDeviation_stmt(YangParser.Deviation_stmtContext ctx) {
+        final int line = ctx.getStart().getLine();
         final String targetPath = stringFromNode(ctx);
+        enterLog("deviation", targetPath, line);
+
         String reference = null;
         String deviate = null;
-        DeviationBuilder builder = moduleBuilder.addDeviation(targetPath, actualPath, ctx.getStart().getLine());
+        DeviationBuilder builder = moduleBuilder.addDeviation(targetPath, actualPath, line);
         moduleBuilder.enterNode(builder);
-        updatePath(targetPath);
+        actualPath.push(targetPath);
 
         for (int i = 0; i < ctx.getChildCount(); i++) {
             ParseTree child = ctx.getChild(i);
@@ -811,19 +878,20 @@ public final class YangParserListenerImpl extends YangParserBaseListener {
 
     @Override
     public void exitDeviation_stmt(YangParser.Deviation_stmtContext ctx) {
-        final String actContainer = actualPath.pop();
-        logger.debug("exiting " + actContainer);
         moduleBuilder.exitNode();
+        exitLog("deviation", actualPath.pop());
     }
 
     @Override
     public void enterIdentity_stmt(YangParser.Identity_stmtContext ctx) {
+        final int line = ctx.getStart().getLine();
         final String identityName = stringFromNode(ctx);
+        enterLog("identity", identityName, line);
+
         final QName identityQName = new QName(namespace, revision, yangModelPrefix, identityName);
-        IdentitySchemaNodeBuilder builder = moduleBuilder.addIdentity(identityQName, actualPath, ctx.getStart()
-                .getLine());
+        IdentitySchemaNodeBuilder builder = moduleBuilder.addIdentity(identityQName, actualPath, line);
         moduleBuilder.enterNode(builder);
-        updatePath(identityName);
+        actualPath.push(identityName);
 
         builder.setPath(createActualSchemaPath(actualPath, namespace, revision, yangModelPrefix));
         parseSchemaNodeArgs(ctx, builder);
@@ -839,17 +907,24 @@ public final class YangParserListenerImpl extends YangParserBaseListener {
 
     @Override
     public void exitIdentity_stmt(YangParser.Identity_stmtContext ctx) {
-        final String actContainer = actualPath.pop();
-        logger.debug("exiting " + actContainer);
         moduleBuilder.exitNode();
+        exitLog("identity", actualPath.pop());
     }
 
     public ModuleBuilder getModuleBuilder() {
         return moduleBuilder;
     }
 
-    private void updatePath(String containerName) {
-        actualPath.push(containerName);
+    private void enterLog(String p1, String p2, int line) {
+        logger.debug("entering " + p1 + " " + p2 + " (" + line + ")");
+    }
+
+    private void exitLog(String p1, String p2) {
+        logger.debug("exiting " + p1 + " " + p2);
+    }
+
+    private void setLog(String p1, String p2) {
+        logger.debug("setting " + p1 + " " + p2);
     }
 
 }
diff --git a/opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/main/java/org/opendaylight/controller/yang/parser/util/Comparators.java b/opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/main/java/org/opendaylight/controller/yang/parser/util/Comparators.java
new file mode 100644 (file)
index 0000000..ea87eec
--- /dev/null
@@ -0,0 +1,37 @@
+/*
+ * 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.parser.util;
+
+import java.util.Comparator;
+
+import org.opendaylight.controller.yang.common.QName;
+import org.opendaylight.controller.yang.model.api.SchemaNode;
+
+public class Comparators {
+
+    public static final QNameComparator QNAME_COMP = new QNameComparator();
+    public static final SchemaNodeComparator SCHEMA_NODE_COMP = new SchemaNodeComparator();
+
+    private Comparators() {
+    }
+
+    private static final class QNameComparator implements Comparator<QName> {
+        @Override
+        public int compare(QName o1, QName o2) {
+            return o1.getLocalName().compareTo(o2.getLocalName());
+        }
+    }
+
+    private static final class SchemaNodeComparator implements Comparator<SchemaNode> {
+        @Override
+        public int compare(SchemaNode o1, SchemaNode o2) {
+            return o1.getQName().getLocalName().compareTo(o2.getQName().getLocalName());
+        }
+    }
+
+}
index 5c42b290a02b88507d54bc1d113ecf8996300984..aea94097148da8899c28cb525c814f5a2424d2c9 100644 (file)
@@ -40,8 +40,7 @@ import com.google.common.collect.Sets;
 public final class ModuleDependencySort {
 
     private static final Date DEFAULT_REVISION = new Date(0);
-    private static final Logger logger = LoggerFactory
-            .getLogger(ModuleDependencySort.class);
+    private static final Logger logger = LoggerFactory.getLogger(ModuleDependencySort.class);
 
     /**
      * Topological sort of module builder dependency graph.
@@ -72,7 +71,7 @@ public final class ModuleDependencySort {
 
             @Override
             public ModuleBuilder apply(Node input) {
-                if(((ModuleNodeImpl) input).getReference() instanceof ModuleBuilder) {
+                if (((ModuleNodeImpl) input).getReference() instanceof ModuleBuilder) {
                     return (ModuleBuilder) ((ModuleNodeImpl) input).getReference();
                 } else {
                     return null;
@@ -113,8 +112,7 @@ public final class ModuleDependencySort {
     }
 
     @VisibleForTesting
-    static Map<String, Map<Date, ModuleNodeImpl>> createModuleGraph(
-            List<?> builders) {
+    static Map<String, Map<Date, ModuleNodeImpl>> createModuleGraph(List<?> builders) {
         Map<String, Map<Date, ModuleNodeImpl>> moduleGraph = Maps.newHashMap();
 
         processModules(moduleGraph, builders);
@@ -126,8 +124,7 @@ public final class ModuleDependencySort {
     /**
      * Extract module:revision from module builders
      */
-    private static void processDependencies(
-            Map<String, Map<Date, ModuleNodeImpl>> moduleGraph, List<?> builders) {
+    private static void processDependencies(Map<String, Map<Date, ModuleNodeImpl>> moduleGraph, List<?> builders) {
         Map<String, Date> imported = Maps.newHashMap();
 
         // Create edges in graph
@@ -154,26 +151,24 @@ public final class ModuleDependencySort {
 
             for (ModuleImport imprt : imports) {
                 String toName = imprt.getModuleName();
-                Date toRevision = imprt.getRevision() == null ? DEFAULT_REVISION
-                        : imprt.getRevision();
+                Date toRevision = imprt.getRevision() == null ? DEFAULT_REVISION : imprt.getRevision();
 
-                ModuleNodeImpl from = moduleGraph.get(fromName).get(
-                        fromRevision);
+                ModuleNodeImpl from = moduleGraph.get(fromName).get(fromRevision);
 
-                ModuleNodeImpl to = getModuleByNameAndRevision(moduleGraph,
-                        fromName, fromRevision, toName, toRevision);
+                ModuleNodeImpl to = getModuleByNameAndRevision(moduleGraph, fromName, fromRevision, toName, toRevision);
 
                 /*
                  * Check imports: If module is imported twice with different
                  * revisions then throw exception
                  */
-                if (imported.get(toName) != null
-                        && !imported.get(toName).equals(toRevision))
-                    ex(String
-                            .format("Module:%s imported twice with different revisions:%s, %s",
-                                    toName,
-                                    formatRevDate(imported.get(toName)),
-                                    formatRevDate(toRevision)));
+                if (imported.get(toName) != null && !imported.get(toName).equals(toRevision)) {
+                    if (!imported.get(toName).equals(DEFAULT_REVISION) && !toRevision.equals(DEFAULT_REVISION)) {
+                        ex(String.format("Module:%s imported twice with different revisions:%s, %s", toName,
+                                formatRevDate(imported.get(toName)), formatRevDate(toRevision)));
+                    }
+
+                }
+
                 imported.put(toName, toRevision);
 
                 from.addEdge(to);
@@ -184,28 +179,23 @@ public final class ModuleDependencySort {
     /**
      * Get imported module by its name and revision from moduleGraph
      */
-    private static ModuleNodeImpl getModuleByNameAndRevision(
-            Map<String, Map<Date, ModuleNodeImpl>> moduleGraph,
+    private static ModuleNodeImpl getModuleByNameAndRevision(Map<String, Map<Date, ModuleNodeImpl>> moduleGraph,
             String fromName, Date fromRevision, String toName, Date toRevision) {
         ModuleNodeImpl to = null;
 
-        if (moduleGraph.get(toName) == null
-                || !moduleGraph.get(toName).containsKey(toRevision)) {
+        if (moduleGraph.get(toName) == null || !moduleGraph.get(toName).containsKey(toRevision)) {
             // If revision is not specified in import, but module exists
             // with different revisions, take first
-            if (moduleGraph.get(toName) != null
-                    && !moduleGraph.get(toName).isEmpty()
+            if (moduleGraph.get(toName) != null && !moduleGraph.get(toName).isEmpty()
                     && toRevision.equals(DEFAULT_REVISION)) {
                 to = moduleGraph.get(toName).values().iterator().next();
                 logger.warn(String
                         .format("Import:%s:%s by module:%s:%s does not specify revision, using:%s:%s for module dependency sort",
-                                toName, formatRevDate(toRevision), fromName,
-                                formatRevDate(fromRevision), to.getName(),
+                                toName, formatRevDate(toRevision), fromName, formatRevDate(fromRevision), to.getName(),
                                 formatRevDate(to.getRevision())));
             } else
-                ex(String.format("Not existing module imported:%s:%s by:%s:%s",
-                        toName, formatRevDate(toRevision), fromName,
-                        formatRevDate(fromRevision)));
+                ex(String.format("Not existing module imported:%s:%s by:%s:%s", toName, formatRevDate(toRevision),
+                        fromName, formatRevDate(fromRevision)));
         } else {
             to = moduleGraph.get(toName).get(toRevision);
         }
@@ -220,8 +210,7 @@ public final class ModuleDependencySort {
      * Extract dependencies from module builders or modules to fill dependency
      * graph
      */
-    private static void processModules(
-            Map<String, Map<Date, ModuleNodeImpl>> moduleGraph, List<?> builders) {
+    private static void processModules(Map<String, Map<Date, ModuleNodeImpl>> moduleGraph, List<?> builders) {
 
         // Process nodes
         for (Object mb : builders) {
@@ -236,11 +225,9 @@ public final class ModuleDependencySort {
                 name = ((ModuleBuilder) mb).getName();
                 rev = ((ModuleBuilder) mb).getRevision();
             } else {
-                throw new IllegalStateException(
-                        String.format(
-                                "Unexpected type of node for sort, expected only:%s, %s, got:%s",
-                                Module.class, ModuleBuilder.class,
-                                mb.getClass()));
+                throw new IllegalStateException(String.format(
+                        "Unexpected type of node for sort, expected only:%s, %s, got:%s", Module.class,
+                        ModuleBuilder.class, mb.getClass()));
             }
 
             if (rev == null)
@@ -250,16 +237,14 @@ public final class ModuleDependencySort {
                 moduleGraph.put(name, Maps.<Date, ModuleNodeImpl> newHashMap());
 
             if (moduleGraph.get(name).get(rev) != null)
-                ex(String.format("Module:%s with revision:%s declared twice",
-                        name, formatRevDate(rev)));
+                ex(String.format("Module:%s with revision:%s declared twice", name, formatRevDate(rev)));
 
             moduleGraph.get(name).put(rev, new ModuleNodeImpl(name, rev, mb));
         }
     }
 
     private static String formatRevDate(Date rev) {
-        return rev == DEFAULT_REVISION ? "default"
-                : YangParserListenerImpl.simpleDateFormat.format(rev);
+        return rev == DEFAULT_REVISION ? "default" : YangParserListenerImpl.simpleDateFormat.format(rev);
     }
 
     @VisibleForTesting
@@ -287,8 +272,7 @@ public final class ModuleDependencySort {
             final int prime = 31;
             int result = 1;
             result = prime * result + ((name == null) ? 0 : name.hashCode());
-            result = prime * result
-                    + ((revision == null) ? 0 : revision.hashCode());
+            result = prime * result + ((revision == null) ? 0 : revision.hashCode());
             return result;
         }
 
@@ -316,8 +300,7 @@ public final class ModuleDependencySort {
 
         @Override
         public String toString() {
-            return "Module [name=" + name + ", revision="
-                    + formatRevDate(revision) + "]";
+            return "Module [name=" + name + ", revision=" + formatRevDate(revision) + "]";
         }
 
         public Object getReference() {
index 554866712f8bdec1db7f75a11f6668943b3dd393..64b06ad68ac4486389374d7c6ec0c5e16e35f245 100644 (file)
@@ -8,7 +8,6 @@
 package org.opendaylight.controller.yang.parser.util;
 
 import java.util.ArrayList;
-import java.util.Collections;
 import java.util.Date;
 import java.util.List;
 import java.util.Map;
@@ -501,6 +500,14 @@ public final class ParserUtils {
             }
         }
 
+        // set correct path for all cases
+        if(childNode instanceof ChoiceBuilder) {
+            ChoiceBuilder choiceBuilder = (ChoiceBuilder) childNode;
+            for (ChoiceCaseBuilder choiceCaseBuilder : choiceBuilder.getCases()) {
+                correctAugmentChildPath(choiceCaseBuilder, childNode.getPath());
+            }
+        }
+
         // if node can contains type, correct path for this type too
         if (childNode instanceof TypeAwareBuilder) {
             TypeAwareBuilder nodeBuilder = (TypeAwareBuilder) childNode;
@@ -756,8 +763,8 @@ public final class ParserUtils {
     }
 
     public static ContainerSchemaNodeBuilder createContainer(ContainerSchemaNode container, int line) {
-        final ContainerSchemaNodeBuilder builder = new ContainerSchemaNodeBuilder(container.getQName(),
-                container.getPath(), line);
+        final ContainerSchemaNodeBuilder builder = new ContainerSchemaNodeBuilder(line, container.getQName(),
+                container.getPath());
         convertDataSchemaNode(container, builder);
         builder.setConfiguration(container.isConfiguration());
         builder.setUnknownNodes(container.getUnknownSchemaNodes());
@@ -771,7 +778,7 @@ public final class ParserUtils {
     }
 
     public static ListSchemaNodeBuilder createList(ListSchemaNode list, int line) {
-        ListSchemaNodeBuilder builder = new ListSchemaNodeBuilder(list.getQName(), list.getPath(), line);
+        ListSchemaNodeBuilder builder = new ListSchemaNodeBuilder(line, list.getQName(), list.getPath());
         convertDataSchemaNode(list, builder);
         builder.setConfiguration(list.isConfiguration());
         builder.setUnknownNodes(list.getUnknownSchemaNodes());
@@ -785,8 +792,8 @@ public final class ParserUtils {
     }
 
     public static LeafListSchemaNodeBuilder createLeafList(LeafListSchemaNode leafList, int line) {
-        final LeafListSchemaNodeBuilder builder = new LeafListSchemaNodeBuilder(leafList.getQName(),
-                leafList.getPath(), line);
+        final LeafListSchemaNodeBuilder builder = new LeafListSchemaNodeBuilder(line, leafList.getQName(),
+                leafList.getPath());
         convertDataSchemaNode(leafList, builder);
         builder.setConfiguration(leafList.isConfiguration());
         builder.setType(leafList.getType());
@@ -796,7 +803,7 @@ public final class ParserUtils {
     }
 
     public static ChoiceBuilder createChoice(ChoiceNode choice, int line) {
-        final ChoiceBuilder builder = new ChoiceBuilder(choice.getQName(), line);
+        final ChoiceBuilder builder = new ChoiceBuilder(line, choice.getQName());
         convertDataSchemaNode(choice, builder);
         builder.setConfiguration(choice.isConfiguration());
         builder.setCases(choice.getCases());
@@ -806,7 +813,7 @@ public final class ParserUtils {
     }
 
     public static AnyXmlBuilder createAnyXml(AnyXmlSchemaNode anyxml, int line) {
-        final AnyXmlBuilder builder = new AnyXmlBuilder(anyxml.getQName(), anyxml.getPath(), line);
+        final AnyXmlBuilder builder = new AnyXmlBuilder(line, anyxml.getQName(), anyxml.getPath());
         convertDataSchemaNode(anyxml, builder);
         builder.setConfiguration(anyxml.isConfiguration());
         builder.setUnknownNodes(anyxml.getUnknownSchemaNodes());
@@ -846,16 +853,16 @@ public final class ParserUtils {
         return builder;
     }
 
-    public static UnknownSchemaNodeBuilder createUnknownSchemaNode(UnknownSchemaNode grouping, int line) {
-        final UnknownSchemaNodeBuilder builder = new UnknownSchemaNodeBuilder(grouping.getQName(), line);
-        builder.setPath(grouping.getPath());
-        builder.setUnknownNodes(grouping.getUnknownSchemaNodes());
-        builder.setDescription(grouping.getDescription());
-        builder.setReference(grouping.getReference());
-        builder.setStatus(grouping.getStatus());
-        builder.setAddedByUses(grouping.isAddedByUses());
-        builder.setNodeType(grouping.getNodeType());
-        builder.setNodeParameter(grouping.getNodeParameter());
+    public static UnknownSchemaNodeBuilder createUnknownSchemaNode(UnknownSchemaNode unknownNode, int line) {
+        final UnknownSchemaNodeBuilder builder = new UnknownSchemaNodeBuilder(line, unknownNode.getQName());
+        builder.setPath(unknownNode.getPath());
+        builder.setUnknownNodes(unknownNode.getUnknownSchemaNodes());
+        builder.setDescription(unknownNode.getDescription());
+        builder.setReference(unknownNode.getReference());
+        builder.setStatus(unknownNode.getStatus());
+        builder.setAddedByUses(unknownNode.isAddedByUses());
+        builder.setNodeType(unknownNode.getNodeType());
+        builder.setNodeParameter(unknownNode.getNodeParameter());
         return builder;
     }
 
@@ -992,11 +999,11 @@ public final class ParserUtils {
     }
 
     public static void processAugmentation(final AugmentationSchemaBuilder augmentBuilder, final List<QName> path,
-            final ModuleBuilder module, final QName qname, final ModuleBuilder dependentModuleBuilder) {
+            final ModuleBuilder module, final ModuleBuilder dependentModuleBuilder) {
         DataSchemaNodeBuilder currentParent = null;
         for (DataSchemaNodeBuilder child : dependentModuleBuilder.getChildNodeBuilders()) {
             final QName childQName = child.getQName();
-            if (childQName.getLocalName().equals(qname.getLocalName())) {
+            if (childQName.getLocalName().equals(path.get(0).getLocalName())) {
                 currentParent = child;
                 break;
             }
@@ -1009,13 +1016,24 @@ public final class ParserUtils {
         for (int i = 1; i < path.size(); i++) {
             final QName currentQName = path.get(i);
             DataSchemaNodeBuilder newParent = null;
-            for (DataSchemaNodeBuilder child : ((DataNodeContainerBuilder) currentParent).getChildNodeBuilders()) {
-                final QName childQName = child.getQName();
-                if (childQName.getLocalName().equals(currentQName.getLocalName())) {
-                    newParent = child;
-                    break;
+            if (currentParent instanceof DataNodeContainerBuilder) {
+                for (DataSchemaNodeBuilder child : ((DataNodeContainerBuilder) currentParent).getChildNodeBuilders()) {
+                    final QName childQName = child.getQName();
+                    if (childQName.getLocalName().equals(currentQName.getLocalName())) {
+                        newParent = child;
+                        break;
+                    }
+                }
+            } else if (currentParent instanceof ChoiceBuilder) {
+                for (ChoiceCaseBuilder caseBuilder : ((ChoiceBuilder) currentParent).getCases()) {
+                    final QName caseQName = caseBuilder.getQName();
+                    if (caseQName.getLocalName().equals(currentQName.getLocalName())) {
+                        newParent = caseBuilder;
+                        break;
+                    }
                 }
             }
+
             if (newParent == null) {
                 break; // node not found, quit search
             } else {
@@ -1190,8 +1208,8 @@ public final class ParserUtils {
                         return constraints;
                     }
                 } else {
-                    TypeDefinitionBuilder tdb = findTypeDefinitionBuilder(nodeToResolve.getPath(),
-                            dependentModuleBuilder, qname.getLocalName(), builder.getName(), nodeToResolve.getLine());
+                    TypeDefinitionBuilder tdb = findTypeDefinitionBuilder(nodeToResolve, dependentModuleBuilder,
+                            qname.getLocalName(), builder.getName(), nodeToResolve.getLine());
                     return findConstraintsFromTypeBuilder(tdb, constraints, modules, dependentModuleBuilder, context);
                 }
             } else if (type instanceof ExtendedType) {
@@ -1205,8 +1223,8 @@ public final class ParserUtils {
                 if (base instanceof UnknownType) {
                     ModuleBuilder dependentModule = findDependentModuleBuilder(modules, builder, base.getQName()
                             .getPrefix(), nodeToResolve.getLine());
-                    TypeDefinitionBuilder tdb = findTypeDefinitionBuilder(nodeToResolve.getPath(), dependentModule,
-                            base.getQName().getLocalName(), builder.getName(), nodeToResolve.getLine());
+                    TypeDefinitionBuilder tdb = findTypeDefinitionBuilder(nodeToResolve, dependentModule, base
+                            .getQName().getLocalName(), builder.getName(), nodeToResolve.getLine());
                     return findConstraintsFromTypeBuilder(tdb, constraints, modules, dependentModule, context);
                 } else {
                     // it has to be base yang type
@@ -1236,43 +1254,36 @@ public final class ParserUtils {
      *            current line in yang model
      * @return
      */
-    public static TypeDefinitionBuilder findTypeDefinitionBuilder(final SchemaPath dirtyNodeSchemaPath,
+    public static TypeDefinitionBuilder findTypeDefinitionBuilder(final TypeAwareBuilder nodeToResolve,
             final ModuleBuilder dependentModule, final String typeName, final String currentModuleName, final int line) {
-        final List<QName> path = dirtyNodeSchemaPath.getPath();
+
         TypeDefinitionBuilder result = null;
 
-        Set<TypeDefinitionBuilder> typedefs = dependentModule.getModuleTypedefs();
+        Set<TypeDefinitionBuilder> typedefs = dependentModule.getTypeDefinitionBuilders();
         result = findTypedefBuilderByName(typedefs, typeName);
+        if (result != null) {
+            return result;
+        }
 
-        if (result == null) {
-            Builder currentNode = null;
-            final List<String> currentPath = new ArrayList<String>();
-            currentPath.add(dependentModule.getName());
-
-            for (int i = 0; i < path.size(); i++) {
-                QName qname = path.get(i);
-                currentPath.add(qname.getLocalName());
-                currentNode = dependentModule.getModuleNode(currentPath);
-
-                if (currentNode instanceof RpcDefinitionBuilder) {
-                    typedefs = ((RpcDefinitionBuilder) currentNode).getTypeDefinitions();
-                } else if (currentNode instanceof DataNodeContainerBuilder) {
-                    typedefs = ((DataNodeContainerBuilder) currentNode).getTypeDefinitionBuilders();
-                } else {
-                    typedefs = Collections.emptySet();
-                }
-
-                result = findTypedefBuilderByName(typedefs, typeName);
-                if (result != null) {
-                    break;
-                }
+        Builder parent = nodeToResolve.getParent();
+        while (parent != null) {
+            if (parent instanceof DataNodeContainerBuilder) {
+                typedefs = ((DataNodeContainerBuilder) parent).getTypeDefinitionBuilders();
+            } else if (parent instanceof RpcDefinitionBuilder) {
+                typedefs = ((RpcDefinitionBuilder) parent).getTypeDefinitions();
+            }
+            result = findTypedefBuilderByName(typedefs, typeName);
+            if (result == null) {
+                parent = parent.getParent();
+            } else {
+                break;
             }
         }
 
-        if (result != null) {
-            return result;
+        if (result == null) {
+            throw new YangParseException(currentModuleName, line, "Referenced type '" + typeName + "' not found.");
         }
-        throw new YangParseException(currentModuleName, line, "Referenced type '" + typeName + "' not found.");
+        return result;
     }
 
 }
index 7d228919010e14b90ecd0969941f522ee9754678..1f5e2945d41b4ed7219ba690cb67dc3e97f76f77 100644 (file)
@@ -16,8 +16,9 @@ import org.opendaylight.controller.yang.parser.builder.api.ConfigNode;
 import org.opendaylight.controller.yang.parser.builder.impl.UnknownSchemaNodeBuilder;
 
 public final class RefineHolder implements Builder, ConfigNode {
-    private final String name;
+    private Builder parent;
     private final int line;
+    private final String name;
     private String defaultStr;
     private String description;
     private String reference;
@@ -29,7 +30,7 @@ public final class RefineHolder implements Builder, ConfigNode {
     private Integer maxElements;
     private final List<UnknownSchemaNodeBuilder> addedUnknownNodes = new ArrayList<UnknownSchemaNodeBuilder>();
 
-    public RefineHolder(final String name, final int line) {
+    public RefineHolder(final int line, final String name) {
         this.name = name;
         this.line = line;
     }
@@ -39,6 +40,16 @@ public final class RefineHolder implements Builder, ConfigNode {
         return line;
     }
 
+    @Override
+    public Builder getParent() {
+        return parent;
+    }
+
+    @Override
+    public void setParent(final Builder parent) {
+        this.parent = parent;
+    }
+
     public String getDefaultStr() {
         return defaultStr;
     }
@@ -130,4 +141,100 @@ public final class RefineHolder implements Builder, ConfigNode {
         return null;
     }
 
+    @Override
+    public int hashCode() {
+        final int prime = 31;
+        int result = 1;
+        result = prime * result + ((addedUnknownNodes == null) ? 0 : addedUnknownNodes.hashCode());
+        result = prime * result + ((config == null) ? 0 : config.hashCode());
+        result = prime * result + ((defaultStr == null) ? 0 : defaultStr.hashCode());
+        result = prime * result + ((description == null) ? 0 : description.hashCode());
+        result = prime * result + ((mandatory == null) ? 0 : mandatory.hashCode());
+        result = prime * result + ((maxElements == null) ? 0 : maxElements.hashCode());
+        result = prime * result + ((minElements == null) ? 0 : minElements.hashCode());
+        result = prime * result + ((must == null) ? 0 : must.hashCode());
+        result = prime * result + ((name == null) ? 0 : name.hashCode());
+        result = prime * result + ((parent == null) ? 0 : parent.hashCode());
+        result = prime * result + ((presence == null) ? 0 : presence.hashCode());
+        result = prime * result + ((reference == null) ? 0 : reference.hashCode());
+        return result;
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (this == obj)
+            return true;
+        if (obj == null)
+            return false;
+        if (getClass() != obj.getClass())
+            return false;
+        RefineHolder other = (RefineHolder) obj;
+        if (addedUnknownNodes == null) {
+            if (other.addedUnknownNodes != null)
+                return false;
+        } else if (!addedUnknownNodes.equals(other.addedUnknownNodes))
+            return false;
+        if (config == null) {
+            if (other.config != null)
+                return false;
+        } else if (!config.equals(other.config))
+            return false;
+        if (defaultStr == null) {
+            if (other.defaultStr != null)
+                return false;
+        } else if (!defaultStr.equals(other.defaultStr))
+            return false;
+        if (description == null) {
+            if (other.description != null)
+                return false;
+        } else if (!description.equals(other.description))
+            return false;
+        if (mandatory == null) {
+            if (other.mandatory != null)
+                return false;
+        } else if (!mandatory.equals(other.mandatory))
+            return false;
+        if (maxElements == null) {
+            if (other.maxElements != null)
+                return false;
+        } else if (!maxElements.equals(other.maxElements))
+            return false;
+        if (minElements == null) {
+            if (other.minElements != null)
+                return false;
+        } else if (!minElements.equals(other.minElements))
+            return false;
+        if (must == null) {
+            if (other.must != null)
+                return false;
+        } else if (!must.equals(other.must))
+            return false;
+        if (name == null) {
+            if (other.name != null)
+                return false;
+        } else if (!name.equals(other.name))
+            return false;
+        if (parent == null) {
+            if (other.parent != null)
+                return false;
+        } else if (!parent.equals(other.parent))
+            return false;
+        if (presence == null) {
+            if (other.presence != null)
+                return false;
+        } else if (!presence.equals(other.presence))
+            return false;
+        if (reference == null) {
+            if (other.reference != null)
+                return false;
+        } else if (!reference.equals(other.reference))
+            return false;
+        return true;
+    }
+
+    @Override
+    public String toString() {
+        return "revine " + name;
+    }
+
 }
index 856f8e2ba711c4d09c7d9447cd38ad453868c588..ada2d2cfd8c427cf4072ac9c2d6227359bbab4ae 100644 (file)
@@ -924,12 +924,12 @@ public final class YangModelBuilderUtil {
                 // If the parent node is a 'case' node, the value is the same as
                 // the 'case' node's parent 'choice' node
                 ChoiceCaseBuilder choiceCase = (ChoiceCaseBuilder) parent;
-                ChoiceBuilder choice = choiceCase.getParent();
+                Builder choice = choiceCase.getParent();
                 Boolean parentConfig = null;
-                if (choice == null) {
-                    parentConfig = true;
+                if(choice instanceof ChoiceBuilder) {
+                    parentConfig = ((ChoiceBuilder)choice).isConfiguration();
                 } else {
-                    parentConfig = choice.isConfiguration();
+                    parentConfig = true;
                 }
                 result = parentConfig;
             } else {
@@ -1460,7 +1460,7 @@ public final class YangModelBuilderUtil {
      */
     public static RefineHolder parseRefine(Refine_stmtContext refineCtx) {
         final String refineTarget = stringFromNode(refineCtx);
-        final RefineHolder refine = new RefineHolder(refineTarget, refineCtx.getStart().getLine());
+        final RefineHolder refine = new RefineHolder(refineCtx.getStart().getLine(), refineTarget);
         for (int j = 0; j < refineCtx.getChildCount(); j++) {
             ParseTree refinePom = refineCtx.getChild(j);
             if (refinePom instanceof Refine_pomContext) {
index 3070c74af8c048cce0b0eb3394ea0e837a2d3bba..fb73bd6e5b7eb6937ce95e9fd70bb4450b8bc955 100644 (file)
@@ -92,7 +92,6 @@ public class YangParserNegativeTest {
         } catch (YangParseException e) {
             assertTrue(e.getMessage().contains("Invalid length constraint: <4, 10>"));
         }
-
     }
 
     @Test
@@ -106,7 +105,61 @@ public class YangParserNegativeTest {
         } catch (YangParseException e) {
             assertTrue(e.getMessage().contains("Invalid range constraint: <5, 20>"));
         }
+    }
+
+    @Test
+    public void testDuplicateContainer() throws IOException {
+        try {
+            try (InputStream stream = new FileInputStream(getClass().getResource(
+                    "/negative-scenario/duplicity/container.yang").getPath())) {
+                TestUtils.loadModule(stream);
+                fail("YangParseException should by thrown");
+            }
+        } catch (YangParseException e) {
+            assertTrue(e.getMessage()
+                    .contains("Error in module 'container' on line 10: Duplicate node found at line 6"));
+        }
+    }
+
+    @Test
+    public void testDuplicateContainerList() throws IOException {
+        try {
+            try (InputStream stream = new FileInputStream(getClass().getResource(
+                    "/negative-scenario/duplicity/container-list.yang").getPath())) {
+                TestUtils.loadModule(stream);
+                fail("YangParseException should by thrown");
+            }
+        } catch (YangParseException e) {
+            assertTrue(e.getMessage().contains(
+                    "Error in module 'container-list' on line 10: Duplicate node found at line 6"));
+        }
+    }
 
+    @Test
+    public void testDuplicateContainerLeaf() throws IOException {
+        try {
+            try (InputStream stream = new FileInputStream(getClass().getResource(
+                    "/negative-scenario/duplicity/container-leaf.yang").getPath())) {
+                TestUtils.loadModule(stream);
+                fail("YangParseException should by thrown");
+            }
+        } catch (YangParseException e) {
+            assertTrue(e.getMessage().contains(
+                    "Error in module 'container-leaf' on line 10: Duplicate node found at line 6"));
+        }
+    }
+
+    @Test
+    public void testDuplicateTypedef() throws IOException {
+        try {
+            try (InputStream stream = new FileInputStream(getClass().getResource(
+                    "/negative-scenario/duplicity/typedef.yang").getPath())) {
+                TestUtils.loadModule(stream);
+                fail("YangParseException should by thrown");
+            }
+        } catch (YangParseException e) {
+            assertTrue(e.getMessage().contains("Error in module 'typedef' on line 10: Duplicate node found at line 6"));
+        }
     }
 
 }
index d331cff18d29b5231498f7cacad2e023aa265341..3eff948d8b65b81df3c776d2f2507d68eaa466bb 100644 (file)
@@ -28,10 +28,12 @@ import org.opendaylight.controller.yang.model.api.ChoiceCaseNode;
 import org.opendaylight.controller.yang.model.api.ChoiceNode;
 import org.opendaylight.controller.yang.model.api.ConstraintDefinition;
 import org.opendaylight.controller.yang.model.api.ContainerSchemaNode;
+import org.opendaylight.controller.yang.model.api.DataSchemaNode;
 import org.opendaylight.controller.yang.model.api.Deviation;
 import org.opendaylight.controller.yang.model.api.Deviation.Deviate;
 import org.opendaylight.controller.yang.model.api.ExtensionDefinition;
 import org.opendaylight.controller.yang.model.api.FeatureDefinition;
+import org.opendaylight.controller.yang.model.api.GroupingDefinition;
 import org.opendaylight.controller.yang.model.api.LeafListSchemaNode;
 import org.opendaylight.controller.yang.model.api.LeafSchemaNode;
 import org.opendaylight.controller.yang.model.api.ListSchemaNode;
@@ -94,6 +96,59 @@ public class YangParserTest {
         assertEquals(" WILL BE DEFINED LATER", test.getReference());
     }
 
+    @Test
+    public void testOrderingTypedef() {
+        Module test = TestUtils.findModule(modules, "types2");
+        Set<TypeDefinition<?>> typedefs = test.getTypeDefinitions();
+        String[] expectedOrder = new String[] { "my-base-int32-type", "my-custom-string", "my-decimal-type",
+                "my-decimal-type-ext", "my-int-type", "my-int-type-ext", "my-int-type2", "my-string-type",
+                "my-string-type-ext", "my-string-type2", "my-type1", "my-union", "my-union-ext", "nested-union1",
+                "nested-union2" };
+        String[] actualOrder = new String[typedefs.size()];
+
+        int i = 0;
+        for (TypeDefinition<?> type : typedefs) {
+            actualOrder[i] = type.getQName().getLocalName();
+            i++;
+        }
+        assertArrayEquals(expectedOrder, actualOrder);
+    }
+
+    @Test
+    public void testOrderingChildNodes() {
+        Module test = TestUtils.findModule(modules, "types2");
+        Set<DataSchemaNode> childNodes = test.getChildNodes();
+        String[] expectedOrder = new String[] { "count", "if-name", "interfaces", "name", "nested-type-leaf", "peer",
+                "system" };
+        String[] actualOrder = new String[childNodes.size()];
+
+        int i = 0;
+        for (DataSchemaNode child : childNodes) {
+            actualOrder[i] = child.getQName().getLocalName();
+            i++;
+        }
+        assertArrayEquals(expectedOrder, actualOrder);
+    }
+
+    @Test
+    public void testOrderingNestedChildNodes() {
+        Module test = TestUtils.findModule(modules, "types2");
+        Set<GroupingDefinition> groupings = test.getGroupings();
+        assertEquals(1, groupings.size());
+        GroupingDefinition target = groupings.iterator().next();
+
+        Set<DataSchemaNode> childNodes = target.getChildNodes();
+        String[] expectedOrder = new String[] { "address", "addresses", "data", "how", "port" };
+        String[] actualOrder = new String[childNodes.size()];
+
+        int i = 0;
+        for (DataSchemaNode child : childNodes) {
+            actualOrder[i] = child.getQName().getLocalName();
+            i++;
+        }
+        assertArrayEquals(expectedOrder, actualOrder);
+    }
+
     @Test
     public void testParseContainer() {
         Module test = TestUtils.findModule(modules, "types2");
@@ -567,10 +622,10 @@ public class YangParserTest {
         assertEquals(5, cases.size());
         ChoiceCaseNode input = null;
         ChoiceCaseNode output = null;
-        for(ChoiceCaseNode caseNode : cases) {
-            if("input".equals(caseNode.getQName().getLocalName())) {
+        for (ChoiceCaseNode caseNode : cases) {
+            if ("input".equals(caseNode.getQName().getLocalName())) {
                 input = caseNode;
-            } else if("output".equals(caseNode.getQName().getLocalName())) {
+            } else if ("output".equals(caseNode.getQName().getLocalName())) {
                 output = caseNode;
             }
         }
index 484e34d4101c20ffbe7fd6ffaf659a4a321c8007..70bf40499632efb4a8b70cebe74e5661a2db5989 100644 (file)
@@ -7,10 +7,10 @@
  */
 package org.opendaylight.controller.yang.parser.util;
 
-import static org.hamcrest.core.AnyOf.*;
-import static org.hamcrest.core.Is.*;
-import static org.junit.Assert.*;
-import static org.junit.matchers.JUnitMatchers.*;
+import static org.hamcrest.core.AnyOf.anyOf;
+import static org.hamcrest.core.Is.is;
+import static org.junit.Assert.assertThat;
+import static org.junit.matchers.JUnitMatchers.containsString;
 import static org.mockito.Mockito.*;
 
 import java.util.Arrays;
@@ -49,8 +49,7 @@ public class ModuleDependencySortTest {
 
         List<ModuleBuilder> l = ModuleDependencySort.sort(builders);
 
-        assertDependencyGraph(ModuleDependencySort.createModuleGraph(Arrays
-                .asList(builders)));
+        assertDependencyGraph(ModuleDependencySort.createModuleGraph(Arrays.asList(builders)));
 
         @SuppressWarnings("unchecked")
         Matcher<String> cOrD = anyOf(is(c.getName()), is(d.getName()));
@@ -90,9 +89,7 @@ public class ModuleDependencySortTest {
         try {
             ModuleDependencySort.sort(builders);
         } catch (YangValidationException e) {
-            assertThat(
-                    e.getMessage(),
-                    containsString("Module:a with revision:default declared twice"));
+            assertThat(e.getMessage(), containsString("Module:a with revision:default declared twice"));
             throw e;
         }
     }
@@ -105,9 +102,7 @@ public class ModuleDependencySortTest {
         try {
             ModuleDependencySort.sort(builders);
         } catch (YangValidationException e) {
-            assertThat(
-                    e.getMessage(),
-                    containsString("Not existing module imported:b:default by:a:default"));
+            assertThat(e.getMessage(), containsString("Not existing module imported:b:default by:a:default"));
             throw e;
         }
     }
@@ -123,8 +118,10 @@ public class ModuleDependencySortTest {
 
     @Test(expected = YangValidationException.class)
     public void testImportTwiceDifferentRevision() throws Exception {
-        Date date = new Date();
-        ModuleBuilder b2 = mockModuleBuilder("b", date);
+        Date date1 = new Date(463846463486L);
+        Date date2 = new Date(364896446683L);
+        b = mockModuleBuilder("b", date1);
+        ModuleBuilder b2 = mockModuleBuilder("b", date2);
 
         mockDependency(a, b);
         mockDependency(c, b2);
@@ -133,11 +130,9 @@ public class ModuleDependencySortTest {
         try {
             ModuleDependencySort.sort(builders);
         } catch (YangValidationException e) {
-            assertThat(
-                    e.getMessage(),
-                    containsString("Module:b imported twice with different revisions:default, "
-                            + YangParserListenerImpl.simpleDateFormat
-                                    .format(date)));
+            assertThat(e.getMessage(), containsString("Module:b imported twice with different revisions:"
+                    + YangParserListenerImpl.simpleDateFormat.format(date1) + ", "
+                    + YangParserListenerImpl.simpleDateFormat.format(date2)));
             throw e;
         }
     }
@@ -161,24 +156,19 @@ public class ModuleDependencySortTest {
             ModuleDependencySort.sort(builders);
         } catch (YangValidationException e) {
             assertThat(e.getMessage(), containsString("Module:a with revision:"
-                    + YangParserListenerImpl.simpleDateFormat.format(rev)
-                    + " declared twice"));
+                    + YangParserListenerImpl.simpleDateFormat.format(rev) + " declared twice"));
             throw e;
         }
     }
 
-    private void assertDependencyGraph(
-            Map<String, Map<Date, ModuleNodeImpl>> moduleGraph) {
-        for (Entry<String, Map<Date, ModuleNodeImpl>> node : moduleGraph
-                .entrySet()) {
+    private void assertDependencyGraph(Map<String, Map<Date, ModuleNodeImpl>> moduleGraph) {
+        for (Entry<String, Map<Date, ModuleNodeImpl>> node : moduleGraph.entrySet()) {
             String name = node.getKey();
 
             // Expects only one module revision
 
-            Set<Edge> inEdges = node.getValue().values().iterator().next()
-                    .getInEdges();
-            Set<Edge> outEdges = node.getValue().values().iterator().next()
-                    .getOutEdges();
+            Set<Edge> inEdges = node.getValue().values().iterator().next().getInEdges();
+            Set<Edge> outEdges = node.getValue().values().iterator().next().getOutEdges();
 
             if (name.equals("a")) {
                 assertEdgeCount(inEdges, 0, outEdges, 1);
@@ -190,8 +180,7 @@ public class ModuleDependencySortTest {
         }
     }
 
-    private void assertEdgeCount(Set<Edge> inEdges, int i, Set<Edge> outEdges,
-            int j) {
+    private void assertEdgeCount(Set<Edge> inEdges, int i, Set<Edge> outEdges, int j) {
         assertThat(inEdges.size(), is(i));
         assertThat(outEdges.size(), is(j));
     }
index bd8f378ee17b392bb8c7d32764ff992880c6511e..47e649112a26f07f973490f4ed26d139f1510d8d 100644 (file)
@@ -135,6 +135,11 @@ module types1 {
         }
         container schemas {
         }
+        choice odl {
+            leaf id {
+                type int8;
+            }
+        }
     }
     
     container mycont {
index 495653c96a744aa95442a9c154aeaba15c31e406..c507da55e521612178a2bde2aa9f01fbb5b21b4c 100644 (file)
@@ -32,14 +32,14 @@ module types3 {
             description "Description for augment holder";
         }
     }
-    
+
     augment "/data:interfaces/data:ifEntry" {
         when "if:ifType='ds2'";
         container augment-holder2 {
             description "Description for augment holder";
         }
     }
-    
+
     augment "/data:interfaces/data:ifEntry/t3:augment-holder/t1:schemas" {
         when "if:leafType='ds1'";
         leaf linkleaf {
@@ -51,7 +51,7 @@ module types3 {
         mnt:mountpoint point {
             mnt:target-ref target;
         }
-        
+
         description "network-description";
         reference "network-reference";
         status obsolete;
@@ -65,7 +65,7 @@ module types3 {
              storage (memory, flash or disk) that can be used to
              store syslog messages.";
     }
-    
+
     extension c-define {
         description
             "Takes as argument a name string.
@@ -73,7 +73,7 @@ module types3 {
              #define.";
         argument "name";
     }
-    
+
     notification event {
         leaf event-class {
             type string;
@@ -83,7 +83,7 @@ module types3 {
             type string;
         }
     }
-    
+
     rpc get-config {
         description
           "Retrieve all or part of a specified configuration.";
diff --git a/opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/test/resources/negative-scenario/duplicity/container-leaf.yang b/opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/test/resources/negative-scenario/duplicity/container-leaf.yang
new file mode 100644 (file)
index 0000000..9679385
--- /dev/null
@@ -0,0 +1,14 @@
+module container-leaf {
+    yang-version 1;
+    namespace "urn:simple.container.demo";
+    prefix "t1";
+
+    container foo {
+        description "foo container";
+    }
+
+    leaf foo {
+        type int8;
+    }
+
+}
diff --git a/opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/test/resources/negative-scenario/duplicity/container-list.yang b/opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/test/resources/negative-scenario/duplicity/container-list.yang
new file mode 100644 (file)
index 0000000..08d90af
--- /dev/null
@@ -0,0 +1,14 @@
+module container-list {
+    yang-version 1;
+    namespace "urn:simple.container.demo";
+    prefix "t1";
+
+    container foo {
+        description "foo container";
+    }
+
+    list foo {
+        description "foo list";
+    }
+
+}
diff --git a/opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/test/resources/negative-scenario/duplicity/container.yang b/opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/test/resources/negative-scenario/duplicity/container.yang
new file mode 100644 (file)
index 0000000..8e347a1
--- /dev/null
@@ -0,0 +1,14 @@
+module container {
+    yang-version 1;
+    namespace "urn:simple.container.demo";
+    prefix "t1";
+
+    container foo {
+        description "foo 1";
+    }
+
+    container foo {
+        description "foo 2";
+    }
+
+}
diff --git a/opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/test/resources/negative-scenario/duplicity/identity.yang b/opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/test/resources/negative-scenario/duplicity/identity.yang
new file mode 100644 (file)
index 0000000..f81e6e5
--- /dev/null
@@ -0,0 +1,14 @@
+module identity {
+    yang-version 1;
+    namespace "urn:simple.container.demo";
+    prefix "t1";
+
+    identity id1;
+
+    identity id2;
+
+    identity id1 {
+        base id2;
+    }
+
+}
diff --git a/opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/test/resources/negative-scenario/duplicity/typedef.yang b/opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/test/resources/negative-scenario/duplicity/typedef.yang
new file mode 100644 (file)
index 0000000..b4ec590
--- /dev/null
@@ -0,0 +1,14 @@
+module typedef {
+    yang-version 1;
+    namespace "urn:simple.container.demo";
+    prefix "t1";
+
+    typedef int-ext {
+        type int32;
+    }
+
+    typedef int-ext {
+        type int16;
+    }
+
+}
index ea60ba91a9b3fc1b3169550746c9ab08938dade3..6e6377e881d61a06fcddafd790da1270aed3ec91 100644 (file)
@@ -1,9 +1,9 @@
 module test0 {
     yang-version 1;
     namespace "urn:simple.container.demo";
-    prefix "t1";
-    
+    prefix "t0";
+
     container interfaces {
-    
     }
+
 }
diff --git a/opendaylight/sal/yang-prototype/yang/yang-binding/src/main/java/org/opendaylight/controller/yang/binding/InstanceIdentifier.java b/opendaylight/sal/yang-prototype/yang/yang-binding/src/main/java/org/opendaylight/controller/yang/binding/InstanceIdentifier.java
new file mode 100644 (file)
index 0000000..7d13655
--- /dev/null
@@ -0,0 +1,12 @@
+package org.opendaylight.controller.yang.binding;
+
+/**
+ * Created with IntelliJ IDEA.
+ * User: lsedlak
+ * Date: 27.6.2013
+ * Time: 11:44
+ * To change this template use File | Settings | File Templates.
+ */
+public class InstanceIdentifier <T extends DataObject> {
+
+}
index 31e0ad682d2b2b9e92473b103bb5d94191257bc1..ae0f72cfe8538b6b294b0a4c5ebaf011a8c84bb4 100644 (file)
@@ -7,6 +7,8 @@
  */\r
 package org.opendaylight.controller.yang.model.api;\r
 \r
+import java.util.List;\r
+\r
 /**\r
  * AugmentationSchema represents augment definition. The "augment" statement\r
  * allows a module or submodule to add to the schema tree defined in an external\r
@@ -45,4 +47,9 @@ public interface AugmentationSchema extends DataNodeContainer {
      */\r
     SchemaPath getTargetPath();\r
 \r
+    /**\r
+     * @return collection of all unknown nodes defined in this augmentation\r
+     */\r
+    public List<UnknownSchemaNode> getUnknownSchemaNodes();\r
+\r
 }\r
index e8c814e20804eadea4ec916ec834a4b3310c7e82..b636a320d4c474cffcc8cb4788a18e6a15195682 100644 (file)
@@ -17,17 +17,23 @@ import org.opendaylight.controller.yang.common.QName;
 public interface DataNodeContainer {\r
 \r
     /**\r
-     * @return Set of all newly defined types within this DataNodeContainer\r
+     * Returns set of all newly defined types within this DataNodeContainer.\r
+     *\r
+     * @return typedef statements in lexicographical order\r
      */\r
     Set<TypeDefinition<?>> getTypeDefinitions();\r
 \r
     /**\r
-     * Set of all child nodes defined within this DataNodeContainer\r
+     * Returns set of all child nodes defined within this DataNodeContainer.\r
+     *\r
+     * @return child nodes in lexicographical order\r
      */\r
     Set<DataSchemaNode> getChildNodes();\r
 \r
     /**\r
-     * Set of all groupings defined within this DataNodeContainer\r
+     * Returns set of all groupings defined within this DataNodeContainer.\r
+     *\r
+     * @return grouping statements in lexicographical order\r
      */\r
     Set<GroupingDefinition> getGroupings();\r
 \r
index a04119b038901f98c7fb871992e5b55f3b8c8c4d..648eacfccf71b4c58676708060763a922839bbb1 100644 (file)
@@ -17,6 +17,13 @@ package org.opendaylight.controller.yang.model.api;
  */\r
 public interface GroupingDefinition extends DataNodeContainer, SchemaNode {\r
 \r
+    /**\r
+     * Returns <code>true</code> if the data node was added by uses statement,\r
+     * otherwise returns <code>false</code>\r
+     *\r
+     * @return <code>true</code> if the data node was added by uses statement,\r
+     *         otherwise returns <code>false</code>\r
+     */\r
     boolean isAddedByUses();\r
 \r
 }\r
index 51dd9f65074d2113314d6a27182d889b8b0adc37..a38d48817b1b1d4b6ecf35d4bc1bf425248ddd29 100644 (file)
@@ -34,20 +34,60 @@ public interface Module extends DataNodeContainer {
 \r
     Set<ModuleImport> getImports();\r
 \r
+    /**\r
+     * Returns feature statements defined in module.\r
+     *\r
+     * @return feature statements in lexicographical order\r
+     */\r
     Set<FeatureDefinition> getFeatures();\r
 \r
+    /**\r
+     * Returns notification statements defined in module.\r
+     *\r
+     * @return notification statements in lexicographical order\r
+     */\r
     Set<NotificationDefinition> getNotifications();\r
 \r
+    /**\r
+     * Returns augment statements defined in module.\r
+     *\r
+     * @return augment statements\r
+     */\r
     Set<AugmentationSchema> getAugmentations();\r
 \r
+    /**\r
+     * Returns rpc statements defined in module.\r
+     *\r
+     * @return rpc statements in lexicographical order\r
+     */\r
     Set<RpcDefinition> getRpcs();\r
 \r
+    /**\r
+     * Returns deviation statements defined in module.\r
+     *\r
+     * @return deviation statements\r
+     */\r
     Set<Deviation> getDeviations();\r
 \r
+    /**\r
+     * Returns identity statements defined in module.\r
+     *\r
+     * @return identity statements in lexicographical order\r
+     */\r
     Set<IdentitySchemaNode> getIdentities();\r
 \r
+    /**\r
+     * Returns extension statements defined in module.\r
+     *\r
+     * @return extension statements in lexicographical order\r
+     */\r
     List<ExtensionDefinition> getExtensionSchemaNodes();\r
 \r
+    /**\r
+     * Returns unknown nodes defined in module.\r
+     *\r
+     * @return unknown nodes in lexicographical order\r
+     */\r
     List<UnknownSchemaNode> getUnknownSchemaNodes();\r
 \r
 }\r
index 0fc8a0e49d2fb02d3438d0824dcd6c012a8b72e5..1920f9859c55e68825677decfe92f4bd9a2a0469 100644 (file)
@@ -31,6 +31,13 @@ public interface UsesNode {
      */\r
     boolean isAugmenting();\r
 \r
+    /**\r
+     * Returns <code>true</code> if the data node was added by uses statement,\r
+     * otherwise returns <code>false</code>\r
+     *\r
+     * @return <code>true</code> if the data node was added by uses statement,\r
+     *         otherwise returns <code>false</code>\r
+     */\r
     boolean isAddedByUses();\r
 \r
     /**\r
index fd288c71276e3669ea30adffb12c5f89248aa9a5..14e440df029f1bb71b901a647d12c2cf548b617e 100644 (file)
@@ -40,6 +40,9 @@
               org.slf4j,
               org.apache.felix.dm
             </Import-Package>
+            <Export-Package>
+              org.opendaylight.controller.sample.simpleforwarding
+            </Export-Package>
             <Bundle-Activator>
               org.opendaylight.controller.samples.simpleforwarding.internal.Activator
             </Bundle-Activator>
index 11056478dbf1742ec48e5cc6bbf9ec3bf01ad56a..7f4c98a6483969fabfd14f6bc54219873ae00cd8 100644 (file)
@@ -50,12 +50,15 @@ import org.opendaylight.controller.sal.routing.IRouting;
 import org.opendaylight.controller.sal.utils.EtherTypes;
 import org.opendaylight.controller.sal.utils.NodeConnectorCreator;
 import org.opendaylight.controller.sal.utils.Status;
+import org.opendaylight.controller.samples.simpleforwarding.HostNodePair;
 import org.opendaylight.controller.switchmanager.IInventoryListener;
 import org.opendaylight.controller.switchmanager.ISwitchManager;
 import org.opendaylight.controller.topologymanager.ITopologyManager;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
+
+
 public class SimpleForwardingImpl implements IfNewHostNotify,
         IListenRoutingUpdates, IInventoryListener {
     private static Logger log = LoggerFactory
index afa4c42d36095072371dafc09c171fd9b6ebb587..7897c398909a48a02cd0221279cf51d054bbaa6c 100644 (file)
@@ -18,7 +18,8 @@ import org.junit.Assert;
 import org.opendaylight.controller.hosttracker.hostAware.HostNodeConnector;
 import org.opendaylight.controller.sal.core.ConstructionException;
 import org.opendaylight.controller.sal.utils.NodeCreator;
-import org.opendaylight.controller.samples.simpleforwarding.internal.HostNodePair;
+import org.opendaylight.controller.samples.simpleforwarding.HostNodePair;
+
 
 public class HostSwitchTest {
     @Test
index 80ed20981961b56e21d397575ea09c2712190cdd..83cb8b1cc9786f42757e1f609dedf724943c0f19 100644 (file)
@@ -150,4 +150,9 @@ public class SpanConfig implements Serializable {
     public boolean matchNode(String nodeId) {
         return this.nodeId.equals(nodeId);
     }
+
+    @Override
+    public String toString() {
+        return ("Span Config [nodeId=" + nodeId + " spanPort=" + spanPort + "]");
+    }
 }
index 87dd99da7f80736c76fc2e31765e84d46667fd35..895f117321a6c61645742e425bcf0ad2d0af6cbd 100644 (file)
@@ -231,6 +231,7 @@ public class SubnetConfig implements Serializable {
         nodePorts.remove(sp);
     }
 
+    @Override
     public String toString() {
         return ("Subnet Config [Description=" + name + " Subnet=" + subnet
                 + " NodeConnectors=" + nodePorts + "]");
index 253096edc34116ed4cc9474624f9711f90efa13a..61b2f0a3a8edf0a00a7a783d088b4751e379859a 100644 (file)
@@ -97,4 +97,10 @@ public class SwitchConfig implements Serializable {
             return false;
         return true;
     }
+
+    @Override
+    public String toString() {
+        return ("Switch Config [Node=" + nodeId + " Description=" + description +
+                " Tier=" + tier + " Mode=" + mode + "]");
+    }
 }
index ab3149610309b08f314b9cee1ca85a6998063a5c..d32f98650b8b549ce8235fd3c14d22c55205ac56 100644 (file)
@@ -52,14 +52,14 @@ import org.opendaylight.controller.sal.core.Tier;
 import org.opendaylight.controller.sal.core.UpdateType;
 import org.opendaylight.controller.sal.inventory.IInventoryService;
 import org.opendaylight.controller.sal.inventory.IListenInventoryUpdates;
-import org.opendaylight.controller.sal.utils.HexEncode;
-import org.opendaylight.controller.sal.utils.StatusCode;
 import org.opendaylight.controller.sal.utils.GlobalConstants;
+import org.opendaylight.controller.sal.utils.HexEncode;
 import org.opendaylight.controller.sal.utils.IObjectReader;
 import org.opendaylight.controller.sal.utils.ObjectReader;
 import org.opendaylight.controller.sal.utils.ObjectWriter;
 import org.opendaylight.controller.sal.utils.ServiceHelper;
 import org.opendaylight.controller.sal.utils.Status;
+import org.opendaylight.controller.sal.utils.StatusCode;
 import org.opendaylight.controller.switchmanager.IInventoryListener;
 import org.opendaylight.controller.switchmanager.ISpanAware;
 import org.opendaylight.controller.switchmanager.ISwitchManager;
@@ -174,7 +174,7 @@ CommandProvider {
 
     public void startUp() {
         // Initialize configuration file names
-        subnetFileName = ROOT + "subnets" + this.getContainerName() + ".conf";
+        subnetFileName = ROOT + "subnets_" + this.getContainerName() + ".conf";
         spanFileName = ROOT + "spanPorts_" + this.getContainerName() + ".conf";
         switchConfigFileName = ROOT + "switchConfig_" + this.getContainerName()
                 + ".conf";
@@ -201,7 +201,6 @@ CommandProvider {
     }
 
     public void shutDown() {
-        destroyCaches(this.getContainerName());
     }
 
     @SuppressWarnings("deprecation")
@@ -499,11 +498,13 @@ CommandProvider {
         }
 
         conf.addNodeConnectors(switchPorts);
+        subnetsConfigList.put(name, conf);
 
         // Update Database
         Subnet sub = subnets.get(conf.getIPnum());
         Set<NodeConnector> sp = conf.getNodeConnectors(switchPorts);
         sub.addNodeConnectors(sp);
+        subnets.put(conf.getIPnum(), sub);
         return new Status(StatusCode.SUCCESS, null);
     }
 
@@ -515,11 +516,13 @@ CommandProvider {
             return new Status(StatusCode.NOTFOUND, "Subnet does not exist");
         }
         conf.removeNodeConnectors(switchPorts);
+        subnetsConfigList.put(name, conf);
 
         // Update Database
         Subnet sub = subnets.get(conf.getIPnum());
         Set<NodeConnector> sp = conf.getNodeConnectors(switchPorts);
         sub.deleteNodeConnectors(sp);
+        subnets.put(conf.getIPnum(), sub);
         return new Status(StatusCode.SUCCESS, null);
     }
 
@@ -554,7 +557,7 @@ CommandProvider {
     @SuppressWarnings("unchecked")
     private void loadSubnetConfiguration() {
         ObjectReader objReader = new ObjectReader();
-        ConcurrentMap<Integer, SubnetConfig> confList = (ConcurrentMap<Integer, SubnetConfig>) objReader
+        ConcurrentMap<String, SubnetConfig> confList = (ConcurrentMap<String, SubnetConfig>) objReader
                 .read(this, subnetFileName);
 
         if (confList == null) {
@@ -598,6 +601,11 @@ CommandProvider {
 
     @Override
     public void updateSwitchConfig(SwitchConfig cfgObject) {
+        // update default container only
+        if (!isDefaultContainer) {
+            return;
+        }
+
         boolean modeChange = false;
 
         SwitchConfig sc = nodeConfigList.get(cfgObject.getNodeId());
@@ -607,28 +615,25 @@ CommandProvider {
 
         nodeConfigList.put(cfgObject.getNodeId(), cfgObject);
         try {
-            // update default container only
-            if (isDefaultContainer) {
-                String nodeId = cfgObject.getNodeId();
-                Node node = Node.fromString(nodeId);
-                Map<String, Property> propMap;
-                if (nodeProps.get(node) != null) {
-                    propMap = nodeProps.get(node);
-                } else {
-                    propMap = new HashMap<String, Property>();
-                }
-                Property desc = new Description(cfgObject.getNodeDescription());
-                propMap.put(desc.getName(), desc);
-                Property tier = new Tier(Integer.parseInt(cfgObject.getTier()));
-                propMap.put(tier.getName(), tier);
-                addNodeProps(node, propMap);
+            String nodeId = cfgObject.getNodeId();
+            Node node = Node.fromString(nodeId);
+            Map<String, Property> propMap;
+            if (nodeProps.get(node) != null) {
+                propMap = nodeProps.get(node);
+            } else {
+                propMap = new HashMap<String, Property>();
+            }
+            Property desc = new Description(cfgObject.getNodeDescription());
+            propMap.put(desc.getName(), desc);
+            Property tier = new Tier(Integer.parseInt(cfgObject.getTier()));
+            propMap.put(tier.getName(), tier);
+            addNodeProps(node, propMap);
 
-                log.info("Set Node {}'s Mode to {}", nodeId,
-                        cfgObject.getMode());
+            log.info("Set Node {}'s Mode to {}", nodeId,
+                    cfgObject.getMode());
 
-                if (modeChange) {
-                    notifyModeChange(node, cfgObject.isProactive());
-                }
+            if (modeChange) {
+                notifyModeChange(node, cfgObject.isProactive());
             }
         } catch (Exception e) {
             log.debug("updateSwitchConfig: {}", e.getMessage());
@@ -1333,17 +1338,26 @@ CommandProvider {
             return;
         }
 
-        nodeProps = this.inventoryService.getNodeProps();
-        Set<Node> nodeSet = nodeProps.keySet();
-        if (nodeSet != null) {
-            for (Node node : nodeSet) {
-                log.debug("getInventories: {} added for container {}",
-                        new Object[] { node, containerName });
-                addNode(node, null);
+        Map<Node, Map<String, Property>> nodeProp = this.inventoryService.getNodeProps();
+        for(Map.Entry<Node, Map<String, Property>> entry : nodeProp.entrySet()) {
+            Node node = entry.getKey();
+            log.debug("getInventories: {} added for container {}",
+                    new Object[] { node, containerName });
+            Map<String, Property> propMap = entry.getValue();
+            Set<Property> props = new HashSet<Property>();
+            for(Property property : propMap.values()) {
+                props.add(property);
             }
+            addNode(node, props);
         }
 
-        nodeConnectorProps = inventoryService.getNodeConnectorProps();
+        Map<NodeConnector, Map<String, Property>> nodeConnectorProp = this.inventoryService.getNodeConnectorProps();
+        for(Map.Entry<NodeConnector, Map<String, Property>> entry : nodeConnectorProp.entrySet()) {
+            Map<String, Property> propMap = entry.getValue();
+            for(Property property : propMap.values()) {
+                addNodeConnectorProp(entry.getKey(), property);
+            }
+        }
     }
 
     private void clearInventories() {
index 863b0a64a04b6e2f32abfaf50bc78adf7965236b..a532560bcde4b3166cf42c7f7bc8e62fc83ef068 100644 (file)
   <div class="modal-header">
    <button type="button" class="close" data-dismiss="modal"
     aria-hidden="true">&times;</button>
+   <button type="button" class="help" aria-hidden="true"
+    >?</button>
    <h3></h3>
   </div>
   <div class="modal-body"></div>
index cb6fbc54fce32f897c65c05512a785be7f018351..b5ab76f323a557278bdb4dd5fe70d7a040678f0b 100644 (file)
 .table-cursor tr:hover {
        cursor: pointer;
 }
+
+// hide
+.modal {
+       .help {
+               display: none;
+       }
+}
\ No newline at end of file