Merge "Adding Inactive Static Hosts"
authorGiovanni Meo <gmeo@cisco.com>
Tue, 30 Jul 2013 15:08:12 +0000 (15:08 +0000)
committerGerrit Code Review <gerrit@opendaylight.org>
Tue, 30 Jul 2013 15:08:12 +0000 (15:08 +0000)
248 files changed:
opendaylight/arphandler/src/main/java/org/opendaylight/controller/arphandler/internal/ArpHandler.java
opendaylight/clustering/services_implementation/src/main/java/org/opendaylight/controller/clustering/services_implementation/internal/Activator.java
opendaylight/clustering/services_implementation/src/main/java/org/opendaylight/controller/clustering/services_implementation/internal/ClusterManager.java
opendaylight/commons/opendaylight/pom.xml
opendaylight/distribution/opendaylight/src/main/resources/configuration/config.ini
opendaylight/forwarding/staticrouting/src/main/java/org/opendaylight/controller/forwarding/staticrouting/internal/StaticRoutingImplementation.java
opendaylight/forwardingrulesmanager/implementation/src/main/java/org/opendaylight/controller/forwardingrulesmanager/internal/ForwardingRulesManager.java
opendaylight/hosttracker/implementation/src/main/java/org/opendaylight/controller/hosttracker/internal/HostTracker.java
opendaylight/hosttracker/implementation/src/main/java/org/opendaylight/controller/hosttracker/internal/HostTrackerCallable.java
opendaylight/northbound/subnets/src/main/java/org/opendaylight/controller/subnets/northbound/SubnetsNorthboundJAXRS.java
opendaylight/protocol_plugins/openflow/src/main/java/org/opendaylight/controller/protocol_plugin/openflow/internal/DiscoveryService.java
opendaylight/protocol_plugins/openflow/src/main/java/org/opendaylight/controller/protocol_plugin/openflow/internal/FlowConverter.java
opendaylight/protocol_plugins/openflow/src/main/java/org/opendaylight/controller/protocol_plugin/openflow/internal/InventoryServiceShim.java
opendaylight/protocol_plugins/openflow/src/main/java/org/opendaylight/controller/protocol_plugin/openflow/internal/OFStatisticsManager.java
opendaylight/protocol_plugins/openflow/src/main/java/org/opendaylight/controller/protocol_plugin/openflow/vendorextension/v6extension/V6Match.java
opendaylight/protocol_plugins/openflow/src/test/java/org/opendaylight/controller/protocol_plugin/openflow/vendorextension/v6extension/V6ExtensionTest.java
opendaylight/sal/api/src/main/java/org/opendaylight/controller/sal/core/ComponentActivatorAbstractBase.java
opendaylight/sal/api/src/main/java/org/opendaylight/controller/sal/match/MatchField.java
opendaylight/sal/api/src/main/java/org/opendaylight/controller/sal/match/MatchType.java
opendaylight/sal/api/src/main/java/org/opendaylight/controller/sal/packet/IPv4.java
opendaylight/sal/api/src/main/java/org/opendaylight/controller/sal/utils/NetUtils.java
opendaylight/sal/api/src/main/java/org/opendaylight/controller/sal/utils/ObjectWriter.java
opendaylight/sal/api/src/test/java/org/opendaylight/controller/sal/packet/IPv4Test.java
opendaylight/sal/api/src/test/java/org/opendaylight/controller/sal/utils/NetUtilsTest.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/main/java/org/opendaylight/controller/sal/binding/yang/types/TypeProviderImpl.java
opendaylight/sal/yang-prototype/code-generator/binding-generator-impl/src/test/java/org/opendaylight/controller/sal/binding/generator/impl/BitAndUnionTOEnclosingTest.java [new file with mode: 0644]
opendaylight/sal/yang-prototype/code-generator/binding-generator-impl/src/test/java/org/opendaylight/controller/sal/binding/generator/impl/ExtendedTypedefTest.java [new file with mode: 0644]
opendaylight/sal/yang-prototype/code-generator/binding-generator-impl/src/test/resources/bit_and_union_in_leaf.yang [new file with mode: 0644]
opendaylight/sal/yang-prototype/code-generator/binding-generator-impl/src/test/resources/typedef_of_typedef.yang [new file with mode: 0644]
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/GeneratorUtil.java
opendaylight/sal/yang-prototype/code-generator/binding-model-api/pom.xml
opendaylight/sal/yang-prototype/code-generator/pom.xml
opendaylight/sal/yang-prototype/code-generator/samples/maven-code-gen-sample/src/main/yang/typedef_of_typedef.yang [new file with mode: 0644]
opendaylight/sal/yang-prototype/code-generator/samples/modeling-sample/src/main/yang/sample.yang [deleted file]
opendaylight/sal/yang-prototype/code-generator/samples/modeling-sample/src/main/yang/toaster.yang [new file with mode: 0644]
opendaylight/sal/yang-prototype/code-generator/src/site/site.xml [new file with mode: 0644]
opendaylight/sal/yang-prototype/concepts-lang/pom.xml
opendaylight/sal/yang-prototype/concepts-lang/src/site/site.xml [new file with mode: 0644]
opendaylight/sal/yang-prototype/model/ietf/ietf-inet-types/pom.xml
opendaylight/sal/yang-prototype/model/ietf/ietf-yang-types/pom.xml
opendaylight/sal/yang-prototype/model/ietf/pom.xml
opendaylight/sal/yang-prototype/model/pom.xml
opendaylight/sal/yang-prototype/model/src/site/site.xml [new file with mode: 0644]
opendaylight/sal/yang-prototype/pom.xml
opendaylight/sal/yang-prototype/src/site/markdown/readme.md [new file with mode: 0644]
opendaylight/sal/yang-prototype/src/site/resources/stylesheet.css [new file with mode: 0644]
opendaylight/sal/yang-prototype/src/site/site.xml [new file with mode: 0644]
opendaylight/sal/yang-prototype/yang/maven-yang-plugin-it/.gitignore [moved from opendaylight/sal/yang-prototype/code-generator/maven-yang-plugin-it/.gitignore with 100% similarity]
opendaylight/sal/yang-prototype/yang/maven-yang-plugin-it/pom.xml [moved from opendaylight/sal/yang-prototype/code-generator/maven-yang-plugin-it/pom.xml with 95% similarity]
opendaylight/sal/yang-prototype/yang/maven-yang-plugin-it/src/test/java/org/opendaylight/controller/yang2sources/plugin/it/YangToSourcesPluginTestIT.java [moved from opendaylight/sal/yang-prototype/code-generator/maven-yang-plugin-it/src/test/java/org/opendaylight/controller/yang2sources/plugin/it/YangToSourcesPluginTestIT.java with 100% similarity]
opendaylight/sal/yang-prototype/yang/maven-yang-plugin-it/src/test/resources/AdditionalConfig/pom.xml [moved from opendaylight/sal/yang-prototype/code-generator/maven-yang-plugin-it/src/test/resources/AdditionalConfig/pom.xml with 100% similarity]
opendaylight/sal/yang-prototype/yang/maven-yang-plugin-it/src/test/resources/Correct/pom.xml [moved from opendaylight/sal/yang-prototype/code-generator/maven-yang-plugin-it/src/test/resources/Correct/pom.xml with 100% similarity]
opendaylight/sal/yang-prototype/yang/maven-yang-plugin-it/src/test/resources/GenerateTest1/pom.xml [moved from opendaylight/sal/yang-prototype/code-generator/maven-yang-plugin-it/src/test/resources/GenerateTest1/pom.xml with 100% similarity]
opendaylight/sal/yang-prototype/yang/maven-yang-plugin-it/src/test/resources/GenerateTest1/src/main/resources/testfile1.yang [moved from opendaylight/sal/yang-prototype/code-generator/maven-yang-plugin-it/src/test/resources/GenerateTest1/src/main/resources/testfile1.yang with 100% similarity]
opendaylight/sal/yang-prototype/yang/maven-yang-plugin-it/src/test/resources/GenerateTest1/src/main/resources/testfile2.yang [moved from opendaylight/sal/yang-prototype/code-generator/maven-yang-plugin-it/src/test/resources/GenerateTest1/src/main/resources/testfile2.yang with 100% similarity]
opendaylight/sal/yang-prototype/yang/maven-yang-plugin-it/src/test/resources/GenerateTest1/src/main/resources/testfile3.yang [moved from opendaylight/sal/yang-prototype/code-generator/maven-yang-plugin-it/src/test/resources/GenerateTest1/src/main/resources/testfile3.yang with 100% similarity]
opendaylight/sal/yang-prototype/yang/maven-yang-plugin-it/src/test/resources/GenerateTest2/pom.xml [moved from opendaylight/sal/yang-prototype/code-generator/maven-yang-plugin-it/src/test/resources/GenerateTest2/pom.xml with 100% similarity]
opendaylight/sal/yang-prototype/yang/maven-yang-plugin-it/src/test/resources/GenerateTest2/yang/private.yang [moved from opendaylight/sal/yang-prototype/code-generator/maven-yang-plugin-it/src/test/resources/GenerateTest2/yang/private.yang with 100% similarity]
opendaylight/sal/yang-prototype/yang/maven-yang-plugin-it/src/test/resources/Generator/pom.xml [moved from opendaylight/sal/yang-prototype/code-generator/maven-yang-plugin-it/src/test/resources/Generator/pom.xml with 100% similarity]
opendaylight/sal/yang-prototype/yang/maven-yang-plugin-it/src/test/resources/MissingYangInDep/pom.xml [moved from opendaylight/sal/yang-prototype/code-generator/maven-yang-plugin-it/src/test/resources/MissingYangInDep/pom.xml with 100% similarity]
opendaylight/sal/yang-prototype/yang/maven-yang-plugin-it/src/test/resources/MissingYangInDep/yang/private.yang [moved from opendaylight/sal/yang-prototype/code-generator/maven-yang-plugin-it/src/test/resources/MissingYangInDep/yang/private.yang with 100% similarity]
opendaylight/sal/yang-prototype/yang/maven-yang-plugin-it/src/test/resources/NoGenerators/pom.xml [moved from opendaylight/sal/yang-prototype/code-generator/maven-yang-plugin-it/src/test/resources/NoGenerators/pom.xml with 100% similarity]
opendaylight/sal/yang-prototype/yang/maven-yang-plugin-it/src/test/resources/NoOutputDir/pom.xml [moved from opendaylight/sal/yang-prototype/code-generator/maven-yang-plugin-it/src/test/resources/NoOutputDir/pom.xml with 100% similarity]
opendaylight/sal/yang-prototype/yang/maven-yang-plugin-it/src/test/resources/NoYangFiles/pom.xml [moved from opendaylight/sal/yang-prototype/code-generator/maven-yang-plugin-it/src/test/resources/NoYangFiles/pom.xml with 100% similarity]
opendaylight/sal/yang-prototype/yang/maven-yang-plugin-it/src/test/resources/UnknownGenerator/pom.xml [moved from opendaylight/sal/yang-prototype/code-generator/maven-yang-plugin-it/src/test/resources/UnknownGenerator/pom.xml with 100% similarity]
opendaylight/sal/yang-prototype/yang/maven-yang-plugin-it/src/test/resources/YangRootNotExist/pom.xml [moved from opendaylight/sal/yang-prototype/code-generator/maven-yang-plugin-it/src/test/resources/YangRootNotExist/pom.xml with 100% similarity]
opendaylight/sal/yang-prototype/yang/maven-yang-plugin-it/src/test/resources/files/testfile1.yang [moved from opendaylight/sal/yang-prototype/code-generator/maven-yang-plugin-it/src/test/resources/files/testfile1.yang with 100% similarity]
opendaylight/sal/yang-prototype/yang/maven-yang-plugin-it/src/test/resources/files/testfile2.yang [moved from opendaylight/sal/yang-prototype/code-generator/maven-yang-plugin-it/src/test/resources/files/testfile2.yang with 100% similarity]
opendaylight/sal/yang-prototype/yang/maven-yang-plugin-it/src/test/resources/files/testfile3.yang [moved from opendaylight/sal/yang-prototype/code-generator/maven-yang-plugin-it/src/test/resources/files/testfile3.yang with 100% similarity]
opendaylight/sal/yang-prototype/yang/maven-yang-plugin/pom.xml [moved from opendaylight/sal/yang-prototype/code-generator/maven-yang-plugin/pom.xml with 98% similarity]
opendaylight/sal/yang-prototype/yang/maven-yang-plugin/src/main/java/org/opendaylight/controller/yang2sources/plugin/ConfigArg.java [moved from opendaylight/sal/yang-prototype/code-generator/maven-yang-plugin/src/main/java/org/opendaylight/controller/yang2sources/plugin/ConfigArg.java with 100% similarity]
opendaylight/sal/yang-prototype/yang/maven-yang-plugin/src/main/java/org/opendaylight/controller/yang2sources/plugin/Util.java [moved from opendaylight/sal/yang-prototype/code-generator/maven-yang-plugin/src/main/java/org/opendaylight/controller/yang2sources/plugin/Util.java with 100% similarity]
opendaylight/sal/yang-prototype/yang/maven-yang-plugin/src/main/java/org/opendaylight/controller/yang2sources/plugin/YangToSourcesMojo.java [moved from opendaylight/sal/yang-prototype/code-generator/maven-yang-plugin/src/main/java/org/opendaylight/controller/yang2sources/plugin/YangToSourcesMojo.java with 100% similarity]
opendaylight/sal/yang-prototype/yang/maven-yang-plugin/src/main/java/org/opendaylight/controller/yang2sources/plugin/YangToSourcesProcessor.java [moved from opendaylight/sal/yang-prototype/code-generator/maven-yang-plugin/src/main/java/org/opendaylight/controller/yang2sources/plugin/YangToSourcesProcessor.java with 100% similarity]
opendaylight/sal/yang-prototype/yang/maven-yang-plugin/src/test/java/org/opendaylight/controller/yang2sources/plugin/GenerateSourcesTest.java [moved from opendaylight/sal/yang-prototype/code-generator/maven-yang-plugin/src/test/java/org/opendaylight/controller/yang2sources/plugin/GenerateSourcesTest.java with 100% similarity]
opendaylight/sal/yang-prototype/yang/maven-yang-plugin/src/test/java/org/opendaylight/controller/yang2sources/plugin/UtilTest.java [moved from opendaylight/sal/yang-prototype/code-generator/maven-yang-plugin/src/test/java/org/opendaylight/controller/yang2sources/plugin/UtilTest.java with 100% similarity]
opendaylight/sal/yang-prototype/yang/maven-yang-plugin/src/test/resources/yang/mock.yang [moved from opendaylight/sal/yang-prototype/code-generator/maven-yang-plugin/src/test/resources/yang/mock.yang with 100% similarity]
opendaylight/sal/yang-prototype/yang/maven-yang/pom.xml [moved from opendaylight/sal/yang-prototype/code-generator/maven-yang/pom.xml with 94% similarity]
opendaylight/sal/yang-prototype/yang/maven-yang/src/main/java/org/opendaylight/controller/yang2sources/spi/CodeGenerator.java [moved from opendaylight/sal/yang-prototype/code-generator/maven-yang/src/main/java/org/opendaylight/controller/yang2sources/spi/CodeGenerator.java with 93% similarity]
opendaylight/sal/yang-prototype/yang/maven-yang/src/test/java/org/opendaylight/controller/yang2sources/spi/CodeGeneratorTestImpl.java [moved from opendaylight/sal/yang-prototype/code-generator/maven-yang/src/test/java/org/opendaylight/controller/yang2sources/spi/CodeGeneratorTestImpl.java with 100% similarity]
opendaylight/sal/yang-prototype/yang/pom.xml
opendaylight/sal/yang-prototype/yang/src/site/site.xml [new file with mode: 0644]
opendaylight/sal/yang-prototype/yang/yang-binding/pom.xml
opendaylight/sal/yang-prototype/yang/yang-common/pom.xml
opendaylight/sal/yang-prototype/yang/yang-data-api/pom.xml
opendaylight/sal/yang-prototype/yang/yang-data-api/src/main/java/org/opendaylight/controller/yang/data/api/CompositeNode.java
opendaylight/sal/yang-prototype/yang/yang-data-api/src/main/java/org/opendaylight/controller/yang/data/api/MutableCompositeNode.java
opendaylight/sal/yang-prototype/yang/yang-data-api/src/main/java/org/opendaylight/controller/yang/data/api/MutableSimpleNode.java
opendaylight/sal/yang-prototype/yang/yang-data-api/src/main/java/org/opendaylight/controller/yang/data/api/SimpleNode.java
opendaylight/sal/yang-prototype/yang/yang-data-impl/pom.xml [changed mode: 0755->0644]
opendaylight/sal/yang-prototype/yang/yang-data-impl/src/main/java/org/opendaylight/controller/yang/data/impl/AbstractNodeTO.java [changed mode: 0755->0644]
opendaylight/sal/yang-prototype/yang/yang-data-impl/src/main/java/org/opendaylight/controller/yang/data/impl/CompositeNodeModificationTOImpl.java
opendaylight/sal/yang-prototype/yang/yang-data-impl/src/main/java/org/opendaylight/controller/yang/data/impl/CompositeNodeTOImpl.java [changed mode: 0755->0644]
opendaylight/sal/yang-prototype/yang/yang-data-impl/src/main/java/org/opendaylight/controller/yang/data/impl/LazyNodeToNodeMap.java [new file with mode: 0644]
opendaylight/sal/yang-prototype/yang/yang-data-impl/src/main/java/org/opendaylight/controller/yang/data/impl/MutableCompositeNodeTOImpl.java [changed mode: 0755->0644]
opendaylight/sal/yang-prototype/yang/yang-data-impl/src/main/java/org/opendaylight/controller/yang/data/impl/MutableSimpleNodeTOImpl.java [changed mode: 0755->0644]
opendaylight/sal/yang-prototype/yang/yang-data-impl/src/main/java/org/opendaylight/controller/yang/data/impl/NodeFactory.java [changed mode: 0755->0644]
opendaylight/sal/yang-prototype/yang/yang-data-impl/src/main/java/org/opendaylight/controller/yang/data/impl/NodeModificationBuilderImpl.java [changed mode: 0755->0644]
opendaylight/sal/yang-prototype/yang/yang-data-impl/src/main/java/org/opendaylight/controller/yang/data/impl/NodeUtils.java [changed mode: 0755->0644]
opendaylight/sal/yang-prototype/yang/yang-data-impl/src/main/java/org/opendaylight/controller/yang/data/impl/SimpleNodeModificationTOImpl.java
opendaylight/sal/yang-prototype/yang/yang-data-impl/src/main/java/org/opendaylight/controller/yang/data/impl/SimpleNodeTOImpl.java [changed mode: 0755->0644]
opendaylight/sal/yang-prototype/yang/yang-data-impl/src/test/java/org/opendaylight/controller/yang/data/impl/IgnoreWhiteCharsDiffListener.java [new file with mode: 0644]
opendaylight/sal/yang-prototype/yang/yang-data-impl/src/test/java/org/opendaylight/controller/yang/data/impl/LazyNodeToNodeMapTest.java [new file with mode: 0755]
opendaylight/sal/yang-prototype/yang/yang-data-impl/src/test/java/org/opendaylight/controller/yang/data/impl/MemoryConsumption.java [new file with mode: 0644]
opendaylight/sal/yang-prototype/yang/yang-data-impl/src/test/java/org/opendaylight/controller/yang/data/impl/MyNodeBuilder.java [new file with mode: 0644]
opendaylight/sal/yang-prototype/yang/yang-data-impl/src/test/java/org/opendaylight/controller/yang/data/impl/NodeFactoryTest.java [changed mode: 0755->0644]
opendaylight/sal/yang-prototype/yang/yang-data-impl/src/test/java/org/opendaylight/controller/yang/data/impl/NodeHelper.java [changed mode: 0755->0644]
opendaylight/sal/yang-prototype/yang/yang-data-impl/src/test/java/org/opendaylight/controller/yang/data/impl/NodeModificationBuilderImplTest.java [changed mode: 0755->0644]
opendaylight/sal/yang-prototype/yang/yang-data-impl/src/test/java/org/opendaylight/controller/yang/data/impl/NodeUtilsTest.java [changed mode: 0755->0644]
opendaylight/sal/yang-prototype/yang/yang-data-impl/src/test/resources/MyXmlGenerator.groovy [new file with mode: 0644]
opendaylight/sal/yang-prototype/yang/yang-data-impl/src/test/resources/config01.xml [changed mode: 0755->0644]
opendaylight/sal/yang-prototype/yang/yang-data-impl/src/test/resources/config02.content [deleted file]
opendaylight/sal/yang-prototype/yang/yang-data-impl/src/test/resources/config02.xml [changed mode: 0755->0644]
opendaylight/sal/yang-prototype/yang/yang-data-impl/src/test/resources/config02g.xml [deleted file]
opendaylight/sal/yang-prototype/yang/yang-data-impl/src/test/resources/controller-network.xsd [changed mode: 0755->0644]
opendaylight/sal/yang-prototype/yang/yang-data-impl/src/test/resources/controller-network.yang [changed mode: 0755->0644]
opendaylight/sal/yang-prototype/yang/yang-data-impl/src/test/resources/generateXml.groovy [deleted file]
opendaylight/sal/yang-prototype/yang/yang-data-impl/src/test/resources/ietf-inet-types@2010-09-24.yang [changed mode: 0755->0644]
opendaylight/sal/yang-prototype/yang/yang-data-impl/src/test/resources/log4j-test.xml [new file with mode: 0755]
opendaylight/sal/yang-prototype/yang/yang-data-impl/src/test/resources/org/opendaylight/controller/yang/data/impl/config02-shadow.xml [new file with mode: 0644]
opendaylight/sal/yang-prototype/yang/yang-data-impl/src/test/resources/org/opendaylight/controller/yang/data/impl/config02.groovy [new file with mode: 0644]
opendaylight/sal/yang-prototype/yang/yang-data-impl/src/test/resources/org/opendaylight/controller/yang/data/impl/config02g-shadow.xml [new file with mode: 0644]
opendaylight/sal/yang-prototype/yang/yang-data-impl/src/test/resources/org/opendaylight/controller/yang/data/impl/mutableNodesConfig.xml [new file with mode: 0644]
opendaylight/sal/yang-prototype/yang/yang-data-util/pom.xml
opendaylight/sal/yang-prototype/yang/yang-data-util/src/main/java/org/opendaylight/controller/yang/data/util/AbstractNode.java
opendaylight/sal/yang-prototype/yang/yang-data-util/src/main/java/org/opendaylight/controller/yang/data/util/Nodes.java
opendaylight/sal/yang-prototype/yang/yang-ext/pom.xml
opendaylight/sal/yang-prototype/yang/yang-model-api/pom.xml
opendaylight/sal/yang-prototype/yang/yang-model-api/src/main/java/org/opendaylight/controller/yang/model/api/type/DecimalTypeDefinition.java
opendaylight/sal/yang-prototype/yang/yang-model-parser-api/pom.xml [moved from opendaylight/sal/yang-prototype/code-generator/yang-model-parser-api/pom.xml with 86% similarity]
opendaylight/sal/yang-prototype/yang/yang-model-parser-api/src/main/java/org/opendaylight/controller/yang/model/parser/api/YangModelParser.java [moved from opendaylight/sal/yang-prototype/code-generator/yang-model-parser-api/src/main/java/org/opendaylight/controller/yang/model/parser/api/YangModelParser.java with 100% similarity]
opendaylight/sal/yang-prototype/yang/yang-model-parser-api/src/main/java/org/opendaylight/controller/yang/model/parser/api/package-info.java [moved from opendaylight/sal/yang-prototype/code-generator/yang-model-parser-api/src/main/java/org/opendaylight/controller/yang/model/parser/api/package-info.java with 100% similarity]
opendaylight/sal/yang-prototype/yang/yang-model-parser-impl/pom.xml [moved from opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/pom.xml with 89% similarity]
opendaylight/sal/yang-prototype/yang/yang-model-parser-impl/src/main/antlr/YangLexer.g4 [moved from opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/main/antlr/YangLexer.g4 with 100% similarity]
opendaylight/sal/yang-prototype/yang/yang-model-parser-impl/src/main/antlr/YangParser.g4 [moved from opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/main/antlr/YangParser.g4 with 100% similarity]
opendaylight/sal/yang-prototype/yang/yang-model-parser-impl/src/main/java/org/opendaylight/controller/yang/parser/builder/api/AbstractBuilder.java [moved from opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/main/java/org/opendaylight/controller/yang/parser/builder/api/AbstractTypeAwareBuilder.java with 61% similarity]
opendaylight/sal/yang-prototype/yang/yang-model-parser-impl/src/main/java/org/opendaylight/controller/yang/parser/builder/api/AbstractDataNodeContainerBuilder.java [moved from opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/main/java/org/opendaylight/controller/yang/parser/builder/api/AbstractDataNodeContainerBuilder.java with 56% similarity]
opendaylight/sal/yang-prototype/yang/yang-model-parser-impl/src/main/java/org/opendaylight/controller/yang/parser/builder/api/AbstractSchemaNodeBuilder.java [moved from opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/main/java/org/opendaylight/controller/yang/parser/builder/api/AbstractSchemaNodeBuilder.java with 63% similarity]
opendaylight/sal/yang-prototype/yang/yang-model-parser-impl/src/main/java/org/opendaylight/controller/yang/parser/builder/api/AbstractTypeAwareBuilder.java [new file with mode: 0644]
opendaylight/sal/yang-prototype/yang/yang-model-parser-impl/src/main/java/org/opendaylight/controller/yang/parser/builder/api/AugmentationSchemaBuilder.java [moved from opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/main/java/org/opendaylight/controller/yang/parser/builder/api/AugmentationSchemaBuilder.java with 100% similarity]
opendaylight/sal/yang-prototype/yang/yang-model-parser-impl/src/main/java/org/opendaylight/controller/yang/parser/builder/api/AugmentationTargetBuilder.java [moved from opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/main/java/org/opendaylight/controller/yang/parser/builder/api/AugmentationTargetBuilder.java with 100% similarity]
opendaylight/sal/yang-prototype/yang/yang-model-parser-impl/src/main/java/org/opendaylight/controller/yang/parser/builder/api/Builder.java [moved from opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/main/java/org/opendaylight/controller/yang/parser/builder/api/Builder.java with 85% similarity]
opendaylight/sal/yang-prototype/yang/yang-model-parser-impl/src/main/java/org/opendaylight/controller/yang/parser/builder/api/DataNodeContainerBuilder.java [moved from opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/main/java/org/opendaylight/controller/yang/parser/builder/api/DataNodeContainerBuilder.java with 100% similarity]
opendaylight/sal/yang-prototype/yang/yang-model-parser-impl/src/main/java/org/opendaylight/controller/yang/parser/builder/api/DataSchemaNodeBuilder.java [moved from opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/main/java/org/opendaylight/controller/yang/parser/builder/api/DataSchemaNodeBuilder.java with 100% similarity]
opendaylight/sal/yang-prototype/yang/yang-model-parser-impl/src/main/java/org/opendaylight/controller/yang/parser/builder/api/GroupingBuilder.java [moved from opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/main/java/org/opendaylight/controller/yang/parser/builder/api/GroupingBuilder.java with 100% similarity]
opendaylight/sal/yang-prototype/yang/yang-model-parser-impl/src/main/java/org/opendaylight/controller/yang/parser/builder/api/GroupingMember.java [moved from opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/main/java/org/opendaylight/controller/yang/parser/builder/api/GroupingMember.java with 100% similarity]
opendaylight/sal/yang-prototype/yang/yang-model-parser-impl/src/main/java/org/opendaylight/controller/yang/parser/builder/api/SchemaNodeBuilder.java [moved from opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/main/java/org/opendaylight/controller/yang/parser/builder/api/SchemaNodeBuilder.java with 100% similarity]
opendaylight/sal/yang-prototype/yang/yang-model-parser-impl/src/main/java/org/opendaylight/controller/yang/parser/builder/api/TypeAwareBuilder.java [moved from opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/main/java/org/opendaylight/controller/yang/parser/builder/api/TypeAwareBuilder.java with 100% similarity]
opendaylight/sal/yang-prototype/yang/yang-model-parser-impl/src/main/java/org/opendaylight/controller/yang/parser/builder/api/TypeDefinitionBuilder.java [moved from opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/main/java/org/opendaylight/controller/yang/parser/builder/api/TypeDefinitionBuilder.java with 100% similarity]
opendaylight/sal/yang-prototype/yang/yang-model-parser-impl/src/main/java/org/opendaylight/controller/yang/parser/builder/api/UsesNodeBuilder.java [moved from opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/main/java/org/opendaylight/controller/yang/parser/builder/api/UsesNodeBuilder.java with 100% similarity]
opendaylight/sal/yang-prototype/yang/yang-model-parser-impl/src/main/java/org/opendaylight/controller/yang/parser/builder/impl/AnyXmlBuilder.java [moved from opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/main/java/org/opendaylight/controller/yang/parser/builder/impl/AnyXmlBuilder.java with 96% similarity]
opendaylight/sal/yang-prototype/yang/yang-model-parser-impl/src/main/java/org/opendaylight/controller/yang/parser/builder/impl/AugmentationSchemaBuilderImpl.java [moved from opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/main/java/org/opendaylight/controller/yang/parser/builder/impl/AugmentationSchemaBuilderImpl.java with 97% similarity]
opendaylight/sal/yang-prototype/yang/yang-model-parser-impl/src/main/java/org/opendaylight/controller/yang/parser/builder/impl/ChoiceBuilder.java [moved from opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/main/java/org/opendaylight/controller/yang/parser/builder/impl/ChoiceBuilder.java with 87% similarity]
opendaylight/sal/yang-prototype/yang/yang-model-parser-impl/src/main/java/org/opendaylight/controller/yang/parser/builder/impl/ChoiceCaseBuilder.java [moved from opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/main/java/org/opendaylight/controller/yang/parser/builder/impl/ChoiceCaseBuilder.java with 97% similarity]
opendaylight/sal/yang-prototype/yang/yang-model-parser-impl/src/main/java/org/opendaylight/controller/yang/parser/builder/impl/ConstraintsBuilder.java [moved from opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/main/java/org/opendaylight/controller/yang/parser/builder/impl/ConstraintsBuilder.java with 92% similarity]
opendaylight/sal/yang-prototype/yang/yang-model-parser-impl/src/main/java/org/opendaylight/controller/yang/parser/builder/impl/ContainerSchemaNodeBuilder.java [moved from opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/main/java/org/opendaylight/controller/yang/parser/builder/impl/ContainerSchemaNodeBuilder.java with 95% similarity]
opendaylight/sal/yang-prototype/yang/yang-model-parser-impl/src/main/java/org/opendaylight/controller/yang/parser/builder/impl/DeviationBuilder.java [moved from opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/main/java/org/opendaylight/controller/yang/parser/builder/impl/DeviationBuilder.java with 77% similarity]
opendaylight/sal/yang-prototype/yang/yang-model-parser-impl/src/main/java/org/opendaylight/controller/yang/parser/builder/impl/ExtensionBuilder.java [moved from opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/main/java/org/opendaylight/controller/yang/parser/builder/impl/ExtensionBuilder.java with 98% similarity]
opendaylight/sal/yang-prototype/yang/yang-model-parser-impl/src/main/java/org/opendaylight/controller/yang/parser/builder/impl/FeatureBuilder.java [moved from opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/main/java/org/opendaylight/controller/yang/parser/builder/impl/FeatureBuilder.java with 97% similarity]
opendaylight/sal/yang-prototype/yang/yang-model-parser-impl/src/main/java/org/opendaylight/controller/yang/parser/builder/impl/GroupingBuilderImpl.java [moved from opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/main/java/org/opendaylight/controller/yang/parser/builder/impl/GroupingBuilderImpl.java with 80% similarity]
opendaylight/sal/yang-prototype/yang/yang-model-parser-impl/src/main/java/org/opendaylight/controller/yang/parser/builder/impl/IdentitySchemaNodeBuilder.java [moved from opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/main/java/org/opendaylight/controller/yang/parser/builder/impl/IdentitySchemaNodeBuilder.java with 97% similarity]
opendaylight/sal/yang-prototype/yang/yang-model-parser-impl/src/main/java/org/opendaylight/controller/yang/parser/builder/impl/IdentityrefTypeBuilder.java [moved from opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/main/java/org/opendaylight/controller/yang/parser/builder/impl/IdentityrefTypeBuilder.java with 77% similarity]
opendaylight/sal/yang-prototype/yang/yang-model-parser-impl/src/main/java/org/opendaylight/controller/yang/parser/builder/impl/LeafListSchemaNodeBuilder.java [moved from opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/main/java/org/opendaylight/controller/yang/parser/builder/impl/LeafListSchemaNodeBuilder.java with 97% similarity]
opendaylight/sal/yang-prototype/yang/yang-model-parser-impl/src/main/java/org/opendaylight/controller/yang/parser/builder/impl/LeafSchemaNodeBuilder.java [moved from opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/main/java/org/opendaylight/controller/yang/parser/builder/impl/LeafSchemaNodeBuilder.java with 97% similarity]
opendaylight/sal/yang-prototype/yang/yang-model-parser-impl/src/main/java/org/opendaylight/controller/yang/parser/builder/impl/ListSchemaNodeBuilder.java [moved from opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/main/java/org/opendaylight/controller/yang/parser/builder/impl/ListSchemaNodeBuilder.java with 96% similarity]
opendaylight/sal/yang-prototype/yang/yang-model-parser-impl/src/main/java/org/opendaylight/controller/yang/parser/builder/impl/ModuleBuilder.java [moved from opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/main/java/org/opendaylight/controller/yang/parser/builder/impl/ModuleBuilder.java with 79% similarity]
opendaylight/sal/yang-prototype/yang/yang-model-parser-impl/src/main/java/org/opendaylight/controller/yang/parser/builder/impl/NotificationBuilder.java [moved from opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/main/java/org/opendaylight/controller/yang/parser/builder/impl/NotificationBuilder.java with 99% similarity]
opendaylight/sal/yang-prototype/yang/yang-model-parser-impl/src/main/java/org/opendaylight/controller/yang/parser/builder/impl/RpcDefinitionBuilder.java [moved from opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/main/java/org/opendaylight/controller/yang/parser/builder/impl/RpcDefinitionBuilder.java with 98% similarity]
opendaylight/sal/yang-prototype/yang/yang-model-parser-impl/src/main/java/org/opendaylight/controller/yang/parser/builder/impl/TypeDefinitionBuilderImpl.java [moved from opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/main/java/org/opendaylight/controller/yang/parser/builder/impl/TypeDefinitionBuilderImpl.java with 97% similarity]
opendaylight/sal/yang-prototype/yang/yang-model-parser-impl/src/main/java/org/opendaylight/controller/yang/parser/builder/impl/UnionTypeBuilder.java [moved from opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/main/java/org/opendaylight/controller/yang/parser/builder/impl/UnionTypeBuilder.java with 83% similarity]
opendaylight/sal/yang-prototype/yang/yang-model-parser-impl/src/main/java/org/opendaylight/controller/yang/parser/builder/impl/UnknownSchemaNodeBuilder.java [moved from opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/main/java/org/opendaylight/controller/yang/parser/builder/impl/UnknownSchemaNodeBuilder.java with 96% similarity]
opendaylight/sal/yang-prototype/yang/yang-model-parser-impl/src/main/java/org/opendaylight/controller/yang/parser/builder/impl/UsesNodeBuilderImpl.java [moved from opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/main/java/org/opendaylight/controller/yang/parser/builder/impl/UsesNodeBuilderImpl.java with 90% similarity]
opendaylight/sal/yang-prototype/yang/yang-model-parser-impl/src/main/java/org/opendaylight/controller/yang/parser/impl/SchemaContextImpl.java [moved from opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/main/java/org/opendaylight/controller/yang/parser/impl/SchemaContextImpl.java with 100% similarity]
opendaylight/sal/yang-prototype/yang/yang-model-parser-impl/src/main/java/org/opendaylight/controller/yang/parser/impl/YangErrorListener.java [moved from opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/main/java/org/opendaylight/controller/yang/parser/impl/YangErrorListener.java with 100% similarity]
opendaylight/sal/yang-prototype/yang/yang-model-parser-impl/src/main/java/org/opendaylight/controller/yang/parser/impl/YangParserImpl.java [moved from opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/main/java/org/opendaylight/controller/yang/parser/impl/YangParserImpl.java with 95% similarity]
opendaylight/sal/yang-prototype/yang/yang-model-parser-impl/src/main/java/org/opendaylight/controller/yang/parser/impl/YangParserListenerImpl.java [moved from opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/main/java/org/opendaylight/controller/yang/parser/impl/YangParserListenerImpl.java with 95% similarity]
opendaylight/sal/yang-prototype/yang/yang-model-parser-impl/src/main/java/org/opendaylight/controller/yang/parser/util/BitImpl.java [moved from opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/main/java/org/opendaylight/controller/yang/parser/util/BitImpl.java with 100% similarity]
opendaylight/sal/yang-prototype/yang/yang-model-parser-impl/src/main/java/org/opendaylight/controller/yang/parser/util/Comparators.java [moved from opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/main/java/org/opendaylight/controller/yang/parser/util/Comparators.java with 100% similarity]
opendaylight/sal/yang-prototype/yang/yang-model-parser-impl/src/main/java/org/opendaylight/controller/yang/parser/util/ModuleDependencySort.java [moved from opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/main/java/org/opendaylight/controller/yang/parser/util/ModuleDependencySort.java with 100% similarity]
opendaylight/sal/yang-prototype/yang/yang-model-parser-impl/src/main/java/org/opendaylight/controller/yang/parser/util/MustDefinitionImpl.java [moved from opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/main/java/org/opendaylight/controller/yang/parser/util/MustDefinitionImpl.java with 100% similarity]
opendaylight/sal/yang-prototype/yang/yang-model-parser-impl/src/main/java/org/opendaylight/controller/yang/parser/util/ParserListenerUtils.java [moved from opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/main/java/org/opendaylight/controller/yang/parser/util/ParserListenerUtils.java with 95% similarity]
opendaylight/sal/yang-prototype/yang/yang-model-parser-impl/src/main/java/org/opendaylight/controller/yang/parser/util/ParserUtils.java [moved from opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/main/java/org/opendaylight/controller/yang/parser/util/ParserUtils.java with 96% similarity]
opendaylight/sal/yang-prototype/yang/yang-model-parser-impl/src/main/java/org/opendaylight/controller/yang/parser/util/RefineHolder.java [moved from opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/main/java/org/opendaylight/controller/yang/parser/util/RefineHolder.java with 85% similarity]
opendaylight/sal/yang-prototype/yang/yang-model-parser-impl/src/main/java/org/opendaylight/controller/yang/parser/util/RefineUtils.java [moved from opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/main/java/org/opendaylight/controller/yang/parser/util/RefineUtils.java with 82% similarity]
opendaylight/sal/yang-prototype/yang/yang-model-parser-impl/src/main/java/org/opendaylight/controller/yang/parser/util/TopologicalSort.java [moved from opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/main/java/org/opendaylight/controller/yang/parser/util/TopologicalSort.java with 100% similarity]
opendaylight/sal/yang-prototype/yang/yang-model-parser-impl/src/main/java/org/opendaylight/controller/yang/parser/util/TypeConstraints.java [moved from opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/main/java/org/opendaylight/controller/yang/parser/util/TypeConstraints.java with 97% similarity]
opendaylight/sal/yang-prototype/yang/yang-model-parser-impl/src/main/java/org/opendaylight/controller/yang/parser/util/UnknownBoundaryNumber.java [moved from opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/main/java/org/opendaylight/controller/yang/parser/util/UnknownBoundaryNumber.java with 100% similarity]
opendaylight/sal/yang-prototype/yang/yang-model-parser-impl/src/main/java/org/opendaylight/controller/yang/parser/util/YangParseException.java [moved from opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/main/java/org/opendaylight/controller/yang/parser/util/YangParseException.java with 70% similarity]
opendaylight/sal/yang-prototype/yang/yang-model-parser-impl/src/main/java/org/opendaylight/controller/yang/parser/util/YangValidationException.java [moved from opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/main/java/org/opendaylight/controller/yang/parser/util/YangValidationException.java with 100% similarity]
opendaylight/sal/yang-prototype/yang/yang-model-parser-impl/src/main/java/org/opendaylight/controller/yang/validator/BasicValidations.java [moved from opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/main/java/org/opendaylight/controller/yang/validator/BasicValidations.java with 100% similarity]
opendaylight/sal/yang-prototype/yang/yang-model-parser-impl/src/main/java/org/opendaylight/controller/yang/validator/ValidationUtil.java [moved from opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/main/java/org/opendaylight/controller/yang/validator/ValidationUtil.java with 100% similarity]
opendaylight/sal/yang-prototype/yang/yang-model-parser-impl/src/main/java/org/opendaylight/controller/yang/validator/YangModelBasicValidationListener.java [moved from opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/main/java/org/opendaylight/controller/yang/validator/YangModelBasicValidationListener.java with 100% similarity]
opendaylight/sal/yang-prototype/yang/yang-model-parser-impl/src/main/java/org/opendaylight/controller/yang/validator/YangModelBasicValidator.java [moved from opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/main/java/org/opendaylight/controller/yang/validator/YangModelBasicValidator.java with 100% similarity]
opendaylight/sal/yang-prototype/yang/yang-model-parser-impl/src/test/java/org/opendaylight/controller/yang/parser/impl/AugmentTest.java [moved from opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/test/java/org/opendaylight/controller/yang/parser/impl/AugmentTest.java with 100% similarity]
opendaylight/sal/yang-prototype/yang/yang-model-parser-impl/src/test/java/org/opendaylight/controller/yang/parser/impl/GroupingTest.java [moved from opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/test/java/org/opendaylight/controller/yang/parser/impl/GroupingTest.java with 69% similarity]
opendaylight/sal/yang-prototype/yang/yang-model-parser-impl/src/test/java/org/opendaylight/controller/yang/parser/impl/TestUtils.java [moved from opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/test/java/org/opendaylight/controller/yang/parser/impl/TestUtils.java with 100% similarity]
opendaylight/sal/yang-prototype/yang/yang-model-parser-impl/src/test/java/org/opendaylight/controller/yang/parser/impl/TypesResolutionTest.java [moved from opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/test/java/org/opendaylight/controller/yang/parser/impl/TypesResolutionTest.java with 98% similarity]
opendaylight/sal/yang-prototype/yang/yang-model-parser-impl/src/test/java/org/opendaylight/controller/yang/parser/impl/YangParserNegativeTest.java [moved from opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/test/java/org/opendaylight/controller/yang/parser/impl/YangParserNegativeTest.java with 68% similarity]
opendaylight/sal/yang-prototype/yang/yang-model-parser-impl/src/test/java/org/opendaylight/controller/yang/parser/impl/YangParserTest.java [moved from opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/test/java/org/opendaylight/controller/yang/parser/impl/YangParserTest.java with 97% similarity]
opendaylight/sal/yang-prototype/yang/yang-model-parser-impl/src/test/java/org/opendaylight/controller/yang/parser/impl/YangParserWithContextTest.java [moved from opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/test/java/org/opendaylight/controller/yang/parser/impl/YangParserWithContextTest.java with 99% similarity]
opendaylight/sal/yang-prototype/yang/yang-model-parser-impl/src/test/java/org/opendaylight/controller/yang/parser/util/ModuleDependencySortTest.java [moved from opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/test/java/org/opendaylight/controller/yang/parser/util/ModuleDependencySortTest.java with 100% similarity]
opendaylight/sal/yang-prototype/yang/yang-model-parser-impl/src/test/java/org/opendaylight/controller/yang/parser/util/TopologicalSortTest.java [moved from opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/test/java/org/opendaylight/controller/yang/parser/util/TopologicalSortTest.java with 100% similarity]
opendaylight/sal/yang-prototype/yang/yang-model-parser-impl/src/test/java/org/opendaylight/controller/yang/validator/YangModelValidationListTest.java [moved from opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/test/java/org/opendaylight/controller/yang/validator/YangModelValidationListTest.java with 100% similarity]
opendaylight/sal/yang-prototype/yang/yang-model-parser-impl/src/test/java/org/opendaylight/controller/yang/validator/YangModelValidationModuleTest.java [moved from opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/test/java/org/opendaylight/controller/yang/validator/YangModelValidationModuleTest.java with 100% similarity]
opendaylight/sal/yang-prototype/yang/yang-model-parser-impl/src/test/java/org/opendaylight/controller/yang/validator/YangModelValidationSubModuleTest.java [moved from opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/test/java/org/opendaylight/controller/yang/validator/YangModelValidationSubModuleTest.java with 100% similarity]
opendaylight/sal/yang-prototype/yang/yang-model-parser-impl/src/test/java/org/opendaylight/controller/yang/validator/YangModelValidationTest.java [moved from opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/test/java/org/opendaylight/controller/yang/validator/YangModelValidationTest.java with 100% similarity]
opendaylight/sal/yang-prototype/yang/yang-model-parser-impl/src/test/resources/context-augment-test/test1.yang [moved from opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/test/resources/context-augment-test/test1.yang with 100% similarity]
opendaylight/sal/yang-prototype/yang/yang-model-parser-impl/src/test/resources/context-augment-test/test2.yang [moved from opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/test/resources/context-augment-test/test2.yang with 100% similarity]
opendaylight/sal/yang-prototype/yang/yang-model-parser-impl/src/test/resources/context-augment-test/test3.yang [moved from opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/test/resources/context-augment-test/test3.yang with 100% similarity]
opendaylight/sal/yang-prototype/yang/yang-model-parser-impl/src/test/resources/context-augment-test/test4.yang [moved from opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/test/resources/context-augment-test/test4.yang with 100% similarity]
opendaylight/sal/yang-prototype/yang/yang-model-parser-impl/src/test/resources/context-test/deviation-test.yang [moved from opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/test/resources/context-test/deviation-test.yang with 100% similarity]
opendaylight/sal/yang-prototype/yang/yang-model-parser-impl/src/test/resources/context-test/test1.yang [moved from opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/test/resources/context-test/test1.yang with 100% similarity]
opendaylight/sal/yang-prototype/yang/yang-model-parser-impl/src/test/resources/context-test/test2.yang [moved from opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/test/resources/context-test/test2.yang with 100% similarity]
opendaylight/sal/yang-prototype/yang/yang-model-parser-impl/src/test/resources/context-test/test3.yang [moved from opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/test/resources/context-test/test3.yang with 100% similarity]
opendaylight/sal/yang-prototype/yang/yang-model-parser-impl/src/test/resources/model/custom.yang [moved from opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/test/resources/model/custom.yang with 100% similarity]
opendaylight/sal/yang-prototype/yang/yang-model-parser-impl/src/test/resources/model/nodes.yang [moved from opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/test/resources/model/nodes.yang with 95% similarity]
opendaylight/sal/yang-prototype/yang/yang-model-parser-impl/src/test/resources/model/types.yang [moved from opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/test/resources/model/types.yang with 79% similarity]
opendaylight/sal/yang-prototype/yang/yang-model-parser-impl/src/test/resources/negative-scenario/duplicity/augment0.yang [new file with mode: 0644]
opendaylight/sal/yang-prototype/yang/yang-model-parser-impl/src/test/resources/negative-scenario/duplicity/augment1.yang [new file with mode: 0644]
opendaylight/sal/yang-prototype/yang/yang-model-parser-impl/src/test/resources/negative-scenario/duplicity/augment2.yang [new file with mode: 0644]
opendaylight/sal/yang-prototype/yang/yang-model-parser-impl/src/test/resources/negative-scenario/duplicity/container-leaf.yang [moved from opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/test/resources/negative-scenario/duplicity/container-leaf.yang with 100% similarity]
opendaylight/sal/yang-prototype/yang/yang-model-parser-impl/src/test/resources/negative-scenario/duplicity/container-list.yang [moved from opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/test/resources/negative-scenario/duplicity/container-list.yang with 100% similarity]
opendaylight/sal/yang-prototype/yang/yang-model-parser-impl/src/test/resources/negative-scenario/duplicity/container.yang [moved from opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/test/resources/negative-scenario/duplicity/container.yang with 100% similarity]
opendaylight/sal/yang-prototype/yang/yang-model-parser-impl/src/test/resources/negative-scenario/duplicity/identity.yang [moved from opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/test/resources/negative-scenario/duplicity/identity.yang with 100% similarity]
opendaylight/sal/yang-prototype/yang/yang-model-parser-impl/src/test/resources/negative-scenario/duplicity/typedef.yang [moved from opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/test/resources/negative-scenario/duplicity/typedef.yang with 100% similarity]
opendaylight/sal/yang-prototype/yang/yang-model-parser-impl/src/test/resources/negative-scenario/testfile0.yang [moved from opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/test/resources/negative-scenario/testfile0.yang with 100% similarity]
opendaylight/sal/yang-prototype/yang/yang-model-parser-impl/src/test/resources/negative-scenario/testfile1.yang [moved from opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/test/resources/negative-scenario/testfile1.yang with 100% similarity]
opendaylight/sal/yang-prototype/yang/yang-model-parser-impl/src/test/resources/negative-scenario/testfile2.yang [moved from opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/test/resources/negative-scenario/testfile2.yang with 100% similarity]
opendaylight/sal/yang-prototype/yang/yang-model-parser-impl/src/test/resources/negative-scenario/testfile3.yang [moved from opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/test/resources/negative-scenario/testfile3.yang with 100% similarity]
opendaylight/sal/yang-prototype/yang/yang-model-parser-impl/src/test/resources/negative-scenario/testfile4.yang [moved from opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/test/resources/negative-scenario/testfile4.yang with 100% similarity]
opendaylight/sal/yang-prototype/yang/yang-model-parser-impl/src/test/resources/negative-scenario/testfile5.yang [moved from opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/test/resources/negative-scenario/testfile5.yang with 100% similarity]
opendaylight/sal/yang-prototype/yang/yang-model-parser-impl/src/test/resources/negative-scenario/testfile6.yang [moved from opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/test/resources/negative-scenario/testfile6.yang with 100% similarity]
opendaylight/sal/yang-prototype/yang/yang-model-parser-impl/src/test/resources/types/custom-types-test@2012-4-4.yang [moved from opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/test/resources/types/custom-types-test@2012-4-4.yang with 72% similarity]
opendaylight/sal/yang-prototype/yang/yang-model-parser-impl/src/test/resources/types/iana-afn-safi@2012-06-04.yang [moved from opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/test/resources/types/iana-afn-safi@2012-06-04.yang with 100% similarity]
opendaylight/sal/yang-prototype/yang/yang-model-parser-impl/src/test/resources/types/iana-if-type@2012-06-05.yang [moved from opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/test/resources/types/iana-if-type@2012-06-05.yang with 100% similarity]
opendaylight/sal/yang-prototype/yang/yang-model-parser-impl/src/test/resources/types/iana-timezones@2012-07-09.yang [moved from opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/test/resources/types/iana-timezones@2012-07-09.yang with 100% similarity]
opendaylight/sal/yang-prototype/yang/yang-model-parser-impl/src/test/resources/types/ietf-inet-types@2010-09-24.yang [moved from opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/test/resources/types/ietf-inet-types@2010-09-24.yang with 100% similarity]
opendaylight/sal/yang-prototype/yang/yang-model-parser-impl/src/test/resources/types/ietf-yang-types@2010-09-24.yang [moved from opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/test/resources/types/ietf-yang-types@2010-09-24.yang with 100% similarity]
opendaylight/sal/yang-prototype/yang/yang-model-util/pom.xml
opendaylight/sal/yang-prototype/yang/yang-model-util/src/main/java/org/opendaylight/controller/yang/model/util/AbstractUnsignedInteger.java
opendaylight/sal/yang-prototype/yang/yang-model-util/src/main/java/org/opendaylight/controller/yang/model/util/BitsType.java
opendaylight/samples/simpleforwarding/pom.xml
opendaylight/switchmanager/implementation/src/main/java/org/opendaylight/controller/switchmanager/internal/SwitchManagerImpl.java
opendaylight/topologymanager/src/main/java/org/opendaylight/controller/topologymanager/TopologyUserLinkConfig.java
opendaylight/topologymanager/src/main/java/org/opendaylight/controller/topologymanager/internal/Activator.java
opendaylight/topologymanager/src/main/java/org/opendaylight/controller/topologymanager/internal/TopologyManagerImpl.java

index 6e625a0eb7ff963b02c13b7c89b36f0045f4807f..811c7aca8370525d13bcabd2ef46d898bcc4a88f 100644 (file)
@@ -21,9 +21,7 @@ import java.util.Set;
 import java.util.Timer;
 import java.util.TimerTask;
 import java.util.concurrent.ConcurrentHashMap;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
+import java.util.concurrent.ConcurrentMap;
 
 import org.opendaylight.controller.hosttracker.IfHostListener;
 import org.opendaylight.controller.hosttracker.IfIptoHost;
@@ -47,6 +45,8 @@ import org.opendaylight.controller.sal.utils.NetUtils;
 import org.opendaylight.controller.switchmanager.ISwitchManager;
 import org.opendaylight.controller.switchmanager.Subnet;
 import org.opendaylight.controller.topologymanager.ITopologyManager;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 
 public class ArpHandler implements IHostFinder, IListenDataPacket {
     private static final Logger logger = LoggerFactory
@@ -57,8 +57,8 @@ public class ArpHandler implements IHostFinder, IListenDataPacket {
     private IDataPacketService dataPacketService = null;
     private Set<IfHostListener> hostListener = Collections
             .synchronizedSet(new HashSet<IfHostListener>());
-    private ConcurrentHashMap<InetAddress, Set<HostNodeConnector>> arpRequestors;
-    private ConcurrentHashMap<InetAddress, Short> countDownTimers;
+    private ConcurrentMap<InetAddress, Set<HostNodeConnector>> arpRequestors;
+    private ConcurrentMap<InetAddress, Short> countDownTimers;
     private Timer periodicTimer;
 
     void setHostListener(IfHostListener s) {
index cb96ad5c8ece76fab65b518f9ddea8eb4b67c374..5a39e9ec4f6d3c1501d04a74869e41b7c2c8b36b 100644 (file)
@@ -10,6 +10,7 @@
 package org.opendaylight.controller.clustering.services_implementation.internal;
 
 import org.opendaylight.controller.sal.core.ComponentActivatorAbstractBase;
+import org.opendaylight.controller.sal.core.IContainerAware;
 
 import org.opendaylight.controller.clustering.services.ICacheUpdateAware;
 import org.opendaylight.controller.clustering.services.IClusterContainerServices;
@@ -30,6 +31,7 @@ public class Activator extends ComponentActivatorAbstractBase {
      * ComponentActivatorAbstractBase.
      *
      */
+    @Override
     public void init() {
     }
 
@@ -38,6 +40,7 @@ public class Activator extends ComponentActivatorAbstractBase {
      * cleanup done by ComponentActivatorAbstractBase
      *
      */
+    @Override
     public void destroy() {
     }
 
@@ -50,6 +53,7 @@ public class Activator extends ComponentActivatorAbstractBase {
      * instantiated in order to get an fully working implementation
      * Object
      */
+    @Override
     public Object[] getGlobalImplementations() {
         Object[] res = { ClusterManager.class, ClusterGlobalManager.class };
         return res;
@@ -64,6 +68,7 @@ public class Activator extends ComponentActivatorAbstractBase {
      * instantiated in order to get an fully working implementation
      * Object
      */
+    @Override
     public Object[] getImplementations() {
         Object[] res = { ClusterContainerManager.class };
         return res;
@@ -82,6 +87,7 @@ public class Activator extends ComponentActivatorAbstractBase {
      * also optional 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(ClusterContainerManager.class)) {
             c.setInterface(new String[] { IClusterContainerServices.class.getName() },
@@ -118,10 +124,11 @@ public class Activator extends ComponentActivatorAbstractBase {
      * needed as long as the same routine can configure multiple
      * implementations
      */
+    @Override
     public void configureGlobalInstance(Component c, Object imp) {
         if (imp.equals(ClusterManager.class)) {
             // export the service for Apps and Plugins
-            c.setInterface(new String[] { IClusterServices.class.getName() }, null);
+            c.setInterface(new String[] { IClusterServices.class.getName(), IContainerAware.class.getName() }, null);
         }
 
         if (imp.equals(ClusterGlobalManager.class)) {
index 0b2610797fe507f210bf09af989fa4ee643c21ab..c3fd30ae9b65629c8e83bb7f789229b0b6bc5870 100644 (file)
@@ -9,8 +9,6 @@
 
 package org.opendaylight.controller.clustering.services_implementation.internal;
 
-import java.io.PrintWriter;
-import java.io.StringWriter;
 import java.net.InetAddress;
 import java.net.NetworkInterface;
 import java.net.SocketException;
@@ -54,10 +52,11 @@ import org.opendaylight.controller.clustering.services.IClusterServices;
 import org.opendaylight.controller.clustering.services.IGetUpdates;
 import org.opendaylight.controller.clustering.services.IListenRoleChange;
 import org.opendaylight.controller.clustering.services.ListenRoleChangeAddException;
+import org.opendaylight.controller.sal.core.IContainerAware;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-public class ClusterManager implements IClusterServices {
+public class ClusterManager implements IClusterServices, IContainerAware {
     protected static final Logger logger = LoggerFactory
             .getLogger(ClusterManager.class);
     private DefaultCacheManager cm;
@@ -99,10 +98,10 @@ public class ClusterManager implements IClusterServices {
             try {
                 Enumeration<NetworkInterface> e = NetworkInterface.getNetworkInterfaces();
                 while (e.hasMoreElements()) {
-                    NetworkInterface n = (NetworkInterface) e.nextElement();
+                    NetworkInterface n = e.nextElement();
                     Enumeration<InetAddress> ee = n.getInetAddresses();
                     while (ee.hasMoreElements()) {
-                        InetAddress i = (InetAddress) ee.nextElement();
+                        InetAddress i = ee.nextElement();
                         myAddresses.add(i);
                     }
                 }
@@ -562,25 +561,29 @@ public class ClusterManager implements IClusterServices {
         return null;
     }
 
+    @Override
     public List<InetAddress> getClusteredControllers() {
         EmbeddedCacheManager manager = this.cm;
         if (manager == null) {
             return null;
         }
         List<Address> controllers = manager.getMembers();
-        if ((controllers == null) || controllers.size() == 0)
+        if ((controllers == null) || controllers.size() == 0) {
             return null;
+        }
 
         List<InetAddress> clusteredControllers = new ArrayList<InetAddress>();
         for (Address a : controllers) {
             InetAddress inetAddress = addressToInetAddress(a);
             if (inetAddress != null
-                    && !inetAddress.getHostAddress().equals(loopbackAddress))
+                    && !inetAddress.getHostAddress().equals(loopbackAddress)) {
                 clusteredControllers.add(inetAddress);
+            }
         }
         return clusteredControllers;
     }
 
+    @Override
     public InetAddress getMyAddress() {
         EmbeddedCacheManager manager = this.cm;
         if (manager == null) {
@@ -660,4 +663,21 @@ public class ClusterManager implements IClusterServices {
             }
         }
     }
+
+    private void removeContainerCaches(String containerName) {
+        logger.info("Destroying caches for container {}", containerName);
+        for (String cacheName : this.getCacheList(containerName)) {
+            this.destroyCache(containerName, cacheName);
+        }
+    }
+
+    @Override
+    public void containerCreate(String arg0) {
+        // no op
+    }
+
+    @Override
+    public void containerDestroy(String container) {
+        removeContainerCaches(container);
+    }
 }
index 98e1d1ab909e945c30f75d3db67bfdb43d4bb654..33218808a84773e0a6b884eee204a1193763c8c3 100644 (file)
@@ -40,6 +40,7 @@
     <virgo.version>3.6.0.RELEASE</virgo.version>
     <geminiweb.version>2.2.0.RELEASE</geminiweb.version>
     <checkstyle.version>2.10</checkstyle.version>
+    <testvm.argLine>-Xmx1024m -XX:MaxPermSize=256m</testvm.argLine>
   </properties>
 
   <pluginRepositories>
         <groupId>org.apache.maven.plugins</groupId>
         <artifactId>maven-failsafe-plugin</artifactId>
         <version>${failsafe.version}</version>
+        <configuration>
+          <argLine>${testvm.argLine}</argLine>
+        </configuration>
         <executions>
           <execution>
             <goals>
         <groupId>org.apache.maven.plugins</groupId>
         <artifactId>maven-surefire-plugin</artifactId>
         <version>${surefire.version}</version>
+        <configuration>
+          <argLine>${testvm.argLine}</argLine>
+        </configuration>
       </plugin>
     </plugins>
     <pluginManagement>
index 460145ee8729d949dd6b0ef664be74d7947dd3ac..b99b4bfdcaf40aefc2aae1daa0c340f97e96d218 100644 (file)
@@ -50,6 +50,8 @@ org.eclipse.gemini.web.tomcat.config.path=configuration/tomcat-server.xml
 # of.messageResponseTimer=2000
 # The switch liveness timeout value (default 60500 msec)
 # of.switchLivenessTimeout=60500
+# The size of the queue holding pending statistics requests (default 64). For large networks of n switches, it is recommended to set the queue size to n
+# of.statsQueueSize = 64
 # The flow statistics polling interval in second (default 10 sec)
 # of.flowStatsPollInterval=10
 # The port statistics polling interval in second (default 5 sec)
@@ -57,15 +59,17 @@ org.eclipse.gemini.web.tomcat.config.path=configuration/tomcat-server.xml
 # The description statistics polling interval in second (default 60 sec)
 # of.descStatsPollInterval=60
 # The table statistics polling interval in second (default 10 sec)
-#  of.tableStatsPollInterval=10
+# of.tableStatsPollInterval=10
 # The maximum number of asynchronous messages can be sent before sending a Barrier Request (default 100)
 # of.barrierMessagePriorCount=100
 # The interval which determines how often the discovery packets should be sent (default 300 sec)
 # of.discoveryInterval=300
-# The timeout value in waiting for returned discovery packet (default 60 sec)
-# of.discoveryTimeout=60
-# The number of retries after the initial discovery packet is not received within the timeout period (default 2)
-# of.discoveryRetry=2
+# The timeout multiple of discovery interval
+# of.discoveryTimeoutMultiple=2
+# For newly added ports, allow one more retry if the elapsed time exceeds this threshold (default 30 sec)
+# of.discoveryThreshold=30
+# The maximum number of ports handled in one discovery batch (default 1024)
+# of.discoveryBatchMaxPorts=1024
 
 # TLS configuration
 # To enable TLS, set secureChannelEnabled=true and specify the location of controller Java KeyStore and TrustStore files.
index 8819be39885d950e9f6aafc7ed4ad737247a2037..bccdea416208ef27d30294b9f7ddcebf83a77ba2 100644 (file)
@@ -24,8 +24,11 @@ import java.util.Map;
 import java.util.Set;
 import java.util.Timer;
 import java.util.TimerTask;
+import java.util.concurrent.Callable;
 import java.util.concurrent.ConcurrentHashMap;
 import java.util.concurrent.ConcurrentMap;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
 import java.util.concurrent.Future;
 import java.util.regex.Matcher;
 import java.util.regex.Pattern;
@@ -44,20 +47,17 @@ import org.opendaylight.controller.forwarding.staticrouting.StaticRouteConfig;
 import org.opendaylight.controller.hosttracker.IfIptoHost;
 import org.opendaylight.controller.hosttracker.IfNewHostNotify;
 import org.opendaylight.controller.hosttracker.hostAware.HostNodeConnector;
-import org.opendaylight.controller.sal.utils.StatusCode;
 import org.opendaylight.controller.sal.utils.GlobalConstants;
 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.Status;
+import org.opendaylight.controller.sal.utils.StatusCode;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
 /**
  * Static Routing feature provides the bridge between SDN and Non-SDN networks.
- *
- *
- *
  */
 public class StaticRoutingImplementation implements IfNewHostNotify,
         IForwardingStaticRouting, IObjectReader, IConfigurationContainerAware,
@@ -75,6 +75,7 @@ public class StaticRoutingImplementation implements IfNewHostNotify,
     private IClusterContainerServices clusterContainerService = null;
     private Set<IStaticRoutingAware> staticRoutingAware = Collections
             .synchronizedSet(new HashSet<IStaticRoutingAware>());
+    private ExecutorService executor;
 
     void setStaticRoutingAware(IStaticRoutingAware s) {
         if (this.staticRoutingAware != null) {
@@ -206,22 +207,6 @@ public class StaticRoutingImplementation implements IfNewHostNotify,
         }
     }
 
-    @SuppressWarnings("deprecation")
-        private void destroyCaches() {
-        if (this.clusterContainerService == null) {
-            log
-                    .info("un-initialized clusterContainerService, can't destroy cache");
-            return;
-        }
-
-        clusterContainerService.destroyCache("forwarding.staticrouting.routes");
-        clusterContainerService
-                .destroyCache("forwarding.staticrouting.configs");
-        clusterContainerService
-                .destroyCache("forwarding.staticrouting.configSaveEvent");
-
-    }
-
     @Override
     public void entryCreated(Long key, String cacheName, boolean local) {
     }
@@ -251,43 +236,53 @@ public class StaticRoutingImplementation implements IfNewHostNotify,
         }
     }
 
-    private class NotifyStaticRouteThread extends Thread {
+    private class NotifyStaticRouteWorker implements Callable<Object> {
         private StaticRoute staticRoute;
         private boolean added;
 
-        public NotifyStaticRouteThread(StaticRoute s, boolean update) {
+        public NotifyStaticRouteWorker(StaticRoute s, boolean update) {
             this.staticRoute = s;
             this.added = update;
         }
 
-        public void run() {
+        @Override
+        public Object call() throws Exception {
             if (!added
                     || (staticRoute.getType() == StaticRoute.NextHopType.SWITCHPORT)) {
                 notifyStaticRouteUpdate(staticRoute, added);
             } else {
-                HostNodeConnector host = hostTracker.hostQuery(staticRoute
-                        .getNextHopAddress());
+                InetAddress nh = staticRoute.getNextHopAddress();
+                HostNodeConnector host = hostTracker.hostQuery(nh);
                 if (host == null) {
-                    Future<HostNodeConnector> future = hostTracker
-                            .discoverHost(staticRoute.getNextHopAddress());
+                    log.debug("Next hop {}  is not present, try to discover it", nh.getHostAddress());
+                    Future<HostNodeConnector> future = hostTracker.discoverHost(nh);
                     if (future != null) {
                         try {
                             host = future.get();
                         } catch (Exception e) {
-                            log.error("",e);
+                            log.error("", e);
                         }
                     }
                 }
                 if (host != null) {
+                    log.debug("Next hop {} is found", nh.getHostAddress());
                     staticRoute.setHost(host);
                     notifyStaticRouteUpdate(staticRoute, added);
+                } else {
+                    log.debug("Next hop {}  is still not present, try again later", nh.getHostAddress());
                 }
             }
+            return null;
         }
     }
 
     private void checkAndUpdateListeners(StaticRoute staticRoute, boolean added) {
-        new NotifyStaticRouteThread(staticRoute, added).start();
+        NotifyStaticRouteWorker worker = new NotifyStaticRouteWorker(staticRoute, added);
+        try {
+            executor.submit(worker);
+        } catch (Exception e) {
+            log.error("got Exception ", e);
+        }
     }
 
     private void notifyHostUpdate(HostNodeConnector host, boolean added) {
@@ -456,7 +451,7 @@ public class StaticRoutingImplementation implements IfNewHostNotify,
         //staticRoutes = new ConcurrentHashMap<String, StaticRoute>();
         allocateCaches();
         retrieveCaches();
-
+        this.executor = Executors.newFixedThreadPool(1);
         if (staticRouteConfigs.isEmpty())
             loadConfiguration();
 
@@ -488,7 +483,6 @@ public class StaticRoutingImplementation implements IfNewHostNotify,
         log.debug("Destroy all the Static Routing Rules given we are "
                 + "shutting down");
 
-        destroyCaches();
         gatewayProbeTimer.cancel();
 
         // Clear the listener so to be ready in next life
@@ -511,10 +505,12 @@ public class StaticRoutingImplementation implements IfNewHostNotify,
      *
      */
     void stop() {
+        executor.shutdown();
     }
 
     @Override
     public Status saveConfiguration() {
         return this.saveConfig();
     }
+
 }
index eea28364ac9cc4e5db00c76a67dee5e9873a918c..2eaafb698917d74225866068b385ec8a3f74aeba 100644 (file)
@@ -897,10 +897,11 @@ public class ForwardingRulesManager implements IForwardingRulesManager, PortGrou
             log.warn(logMsg, groupName);
             return new Status(StatusCode.NOTACCEPTABLE, msg);
         }
-        int toBeRemoved = groupFlows.get(groupName).size();
+        int toBeRemoved = 0;
         String error = "";
         if (groupFlows.containsKey(groupName)) {
             List<FlowEntryInstall> list = new ArrayList<FlowEntryInstall>(groupFlows.get(groupName));
+            toBeRemoved = list.size();
             for (FlowEntryInstall entry : list) {
                 Status status = this.removeEntry(entry.getOriginal(), false);
                 if (status.isSuccess()) {
index 8468c5b284aee7230d2264974f33e3d428f07127..5aa8f10706cae4e774455895fc30642a1fa8049d 100644 (file)
@@ -97,7 +97,7 @@ public class HostTracker implements IfIptoHost, IfHostListener, ISwitchManagerAw
     private Timer timer;
     private Timer arp_refresh_timer;
     private String containerName = null;
-
+    private ExecutorService executor;
     private static class ARPPending {
         protected InetAddress hostIP;
         protected short sent_count;
@@ -158,7 +158,7 @@ public class HostTracker implements IfIptoHost, IfHostListener, ISwitchManagerAw
 
         timer = new Timer();
         timer.schedule(new OutStandingARPHandler(), 4000, 4000);
-
+        executor = Executors.newFixedThreadPool(2);
         /* ARP Refresh Timer to go off every 5 seconds to implement ARP aging */
         arp_refresh_timer = new Timer();
         arp_refresh_timer.schedule(new ARPRefreshHandler(), 5000, 5000);
@@ -212,17 +212,6 @@ public class HostTracker implements IfIptoHost, IfHostListener, ISwitchManagerAw
         inactiveStaticHosts = new ConcurrentHashMap<NodeConnector, HostNodeConnector>();
     }
 
-    @SuppressWarnings("deprecation")
-    private void destroyCache() {
-        if (this.clusterContainerService == null) {
-            logger.error("un-initialized clusterMger, can't destroy cache");
-            return;
-        }
-        logger.debug("Destroying Cache for HostTracker");
-        this.clusterContainerService.destroyCache("hostTrackerAH");
-        this.clusterContainerService.destroyCache("hostTrackerIH");
-        nonClusterObjectCreate();
-    }
 
     public void shutDown() {
     }
@@ -307,7 +296,6 @@ public class HostTracker implements IfIptoHost, IfHostListener, ISwitchManagerAw
 
     @Override
     public Future<HostNodeConnector> discoverHost(InetAddress networkAddress) {
-        ExecutorService executor = Executors.newFixedThreadPool(1);
         if (executor == null) {
             logger.error("discoverHost: Null executor");
             return null;
@@ -1343,7 +1331,6 @@ public class HostTracker implements IfIptoHost, IfHostListener, ISwitchManagerAw
      *
      */
     void destroy() {
-        destroyCache();
     }
 
     /**
@@ -1361,6 +1348,7 @@ public class HostTracker implements IfIptoHost, IfHostListener, ISwitchManagerAw
      *
      */
     void stop() {
+        executor.shutdown();
     }
 
     @Override
index 06311a5206268ae79fe8ebe32970a395423cf162..303308270d77d36eb803b42feca3096bbfeed0fb 100644 (file)
@@ -42,7 +42,7 @@ public class HostTrackerCallable implements Callable<HostNodeConnector> {
         if (h != null)
             return h;
         hostTracker.setCallableOnPendingARP(trackedHost, this);
-        latch.await();
+        Thread.sleep(2000); // wait 2sec to see if the host responds
         return hostTracker.hostQuery(trackedHost);
     }
 
index 6869fd5fbea37595c33eec0d2f04c950db5e754a..e3c2189bf91550bd7c8d35526ec0d75413a88a6a 100644 (file)
@@ -9,6 +9,7 @@ package org.opendaylight.controller.subnets.northbound;
 
 import java.util.ArrayList;
 import java.util.HashSet;
+import java.util.List;
 import java.util.Set;
 
 import javax.ws.rs.Consumes;
@@ -31,7 +32,6 @@ import org.codehaus.enunciate.jaxrs.TypeHint;
 import org.opendaylight.controller.northbound.commons.RestMessages;
 import org.opendaylight.controller.northbound.commons.exception.InternalServerErrorException;
 import org.opendaylight.controller.northbound.commons.exception.ResourceNotFoundException;
-import org.opendaylight.controller.northbound.commons.exception.ServiceUnavailableException;
 import org.opendaylight.controller.northbound.commons.exception.UnauthorizedException;
 import org.opendaylight.controller.northbound.commons.utils.NorthboundUtils;
 import org.opendaylight.controller.sal.authorization.Privilege;
@@ -44,8 +44,7 @@ import org.slf4j.LoggerFactory;
 
 @Path("/")
 public class SubnetsNorthboundJAXRS {
-    protected static final Logger logger = LoggerFactory
-            .getLogger(SubnetsNorthboundJAXRS.class);
+    protected static final Logger logger = LoggerFactory.getLogger(SubnetsNorthboundJAXRS.class);
 
     private String username;
 
@@ -71,20 +70,15 @@ public class SubnetsNorthboundJAXRS {
     @Produces({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML })
     @StatusCodes({ @ResponseCode(code = 404, condition = "The containerName passed was not found") })
     @TypeHint(SubnetConfigs.class)
-    public SubnetConfigs listSubnets(
-            @PathParam("containerName") String containerName) {
-        if (!NorthboundUtils.isAuthorized(
-                getUserName(), containerName, Privilege.READ, this)) {
-            throw new UnauthorizedException(
-                    "User is not authorized to perform this operation on container "
-                            + containerName);
+    public SubnetConfigs listSubnets(@PathParam("containerName") String containerName) {
+        if (!NorthboundUtils.isAuthorized(getUserName(), containerName, Privilege.READ, this)) {
+            throw new UnauthorizedException("User is not authorized to perform this operation on container "
+                    + containerName);
         }
         ISwitchManager switchManager = null;
-        switchManager = (ISwitchManager) ServiceHelper.getInstance(
-                ISwitchManager.class, containerName, this);
+        switchManager = (ISwitchManager) ServiceHelper.getInstance(ISwitchManager.class, containerName, this);
         if (switchManager == null) {
-            throw new ResourceNotFoundException(
-                    RestMessages.NOCONTAINER.toString());
+            throw new ResourceNotFoundException(RestMessages.NOCONTAINER.toString());
         }
         return new SubnetConfigs(switchManager.getSubnetsConfigList());
     }
@@ -103,30 +97,25 @@ public class SubnetsNorthboundJAXRS {
     @GET
     @Produces({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML })
     @StatusCodes({
-            @ResponseCode(code = 404, condition = "The containerName passed was not found"),
-            @ResponseCode(code = 404, condition = "Subnet does not exist") })
-    @TypeHint(SubnetConfig.class)
+        @ResponseCode(code = 404, condition = "The containerName passed was not found"),
+        @ResponseCode(code = 404, condition = "Subnet does not exist") })
+        @TypeHint(SubnetConfig.class)
     public SubnetConfig listSubnet(
-            @PathParam("containerName") String containerName,
-            @PathParam("subnetName") String subnetName) {
+        @PathParam("containerName") String containerName,
+        @PathParam("subnetName") String subnetName) {
 
-        if (!NorthboundUtils.isAuthorized(
-                getUserName(), containerName, Privilege.READ, this)) {
-            throw new UnauthorizedException(
-                    "User is not authorized to perform this operation on container "
-                            + containerName);
+        if (!NorthboundUtils.isAuthorized(getUserName(), containerName, Privilege.READ, this)) {
+            throw new UnauthorizedException("User is not authorized to perform this operation on container "
+                    + containerName);
         }
         ISwitchManager switchManager = null;
-        switchManager = (ISwitchManager) ServiceHelper.getInstance(
-                ISwitchManager.class, containerName, this);
+        switchManager = (ISwitchManager) ServiceHelper.getInstance(ISwitchManager.class, containerName, this);
         if (switchManager == null) {
-            throw new ResourceNotFoundException(
-                    RestMessages.NOCONTAINER.toString());
+            throw new ResourceNotFoundException(RestMessages.NOCONTAINER.toString());
         }
         SubnetConfig res = switchManager.getSubnetConfig(subnetName);
         if (res == null) {
-            throw new ResourceNotFoundException(
-                    RestMessages.NOSUBNET.toString());
+            throw new ResourceNotFoundException(RestMessages.NOSUBNET.toString());
         } else {
             return res;
         }
@@ -147,37 +136,30 @@ public class SubnetsNorthboundJAXRS {
     @Path("/{containerName}/{subnetName}")
     @POST
     @StatusCodes({
-            @ResponseCode(code = 404, condition = "Invalid Data passed"),
-            @ResponseCode(code = 201, condition = "Subnet added"),
-            @ResponseCode(code = 500, condition = "Addition of subnet failed") })
-    public Response addSubnet(@PathParam("containerName") String containerName,
-            @PathParam("subnetName") String subnetName,
-            @QueryParam("subnet") String subnet) {
-
-        if (!NorthboundUtils.isAuthorized(
-                getUserName(), containerName, Privilege.WRITE, this)) {
-            throw new UnauthorizedException(
-                    "User is not authorized to perform this operation on container "
-                            + containerName);
+        @ResponseCode(code = 404, condition = "Invalid Data passed"),
+        @ResponseCode(code = 201, condition = "Subnet added"),
+        @ResponseCode(code = 500, condition = "Addition of subnet failed") })
+    public Response addSubnet(
+        @PathParam("containerName") String containerName,
+        @PathParam("subnetName") String subnetName, @QueryParam("subnet") String subnet) {
+
+        if (!NorthboundUtils.isAuthorized(getUserName(), containerName, Privilege.WRITE, this)) {
+            throw new UnauthorizedException("User is not authorized to perform this operation on container "
+                    + containerName);
         }
         if (subnetName == null) {
-            throw new ResourceNotFoundException(
-                    RestMessages.INVALIDDATA.toString());
+            throw new ResourceNotFoundException(RestMessages.INVALIDDATA.toString());
         }
         if (subnet == null) {
-            throw new ResourceNotFoundException(
-                    RestMessages.INVALIDDATA.toString());
+            throw new ResourceNotFoundException(RestMessages.INVALIDDATA.toString());
         }
         ISwitchManager switchManager = null;
-        switchManager = (ISwitchManager) ServiceHelper.getInstance(
-                ISwitchManager.class, containerName, this);
+        switchManager = (ISwitchManager) ServiceHelper.getInstance(ISwitchManager.class, containerName, this);
         if (switchManager == null) {
-            throw new ResourceNotFoundException(
-                    RestMessages.NOCONTAINER.toString());
+            throw new ResourceNotFoundException(RestMessages.NOCONTAINER.toString());
         }
 
-        SubnetConfig cfgObject = new SubnetConfig(subnetName, subnet,
-                new ArrayList<String>(0));
+        SubnetConfig cfgObject = new SubnetConfig(subnetName, subnet, new ArrayList<String>(0));
         Status status = switchManager.addSubnet(cfgObject);
         if (status.isSuccess()) {
             return Response.status(Response.Status.CREATED).build();
@@ -197,29 +179,24 @@ public class SubnetsNorthboundJAXRS {
     @Path("/{containerName}/{subnetName}")
     @DELETE
     @StatusCodes({
-            @ResponseCode(code = 404, condition = "The containerName passed was not found"),
-            @ResponseCode(code = 500, condition = "Removal of subnet failed") })
+        @ResponseCode(code = 404, condition = "The containerName passed was not found"),
+        @ResponseCode(code = 500, condition = "Removal of subnet failed") })
     public Response removeSubnet(
-            @PathParam("containerName") String containerName,
-            @PathParam("subnetName") String subnetName) {
+        @PathParam("containerName") String containerName,
+        @PathParam("subnetName") String subnetName) {
         if (subnetName == null) {
-            throw new ResourceNotFoundException(
-                    RestMessages.INVALIDDATA.toString());
+            throw new ResourceNotFoundException(RestMessages.INVALIDDATA.toString());
         }
 
-        if (!NorthboundUtils.isAuthorized(
-                getUserName(), containerName, Privilege.WRITE, this)) {
-            throw new UnauthorizedException(
-                    "User is not authorized to perform this operation on container "
-                            + containerName);
+        if (!NorthboundUtils.isAuthorized(getUserName(), containerName, Privilege.WRITE, this)) {
+            throw new UnauthorizedException("User is not authorized to perform this operation on container "
+                    + containerName);
         }
 
         ISwitchManager switchManager = null;
-        switchManager = (ISwitchManager) ServiceHelper.getInstance(
-                ISwitchManager.class, containerName, this);
+        switchManager = (ISwitchManager) ServiceHelper.getInstance(ISwitchManager.class, containerName, this);
         if (switchManager == null) {
-            throw new ResourceNotFoundException(
-                    RestMessages.NOCONTAINER.toString());
+            throw new ResourceNotFoundException(RestMessages.NOCONTAINER.toString());
         }
         Status status = switchManager.removeSubnet(subnetName);
         if (status.isSuccess()) {
@@ -244,22 +221,21 @@ public class SubnetsNorthboundJAXRS {
     @POST
     @Consumes({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML })
     @StatusCodes({
-            @ResponseCode(code = 202, condition = "Operation successful"),
-            @ResponseCode(code = 400, condition = "Invalid request, i.e., requested changing the subnet name"),
-            @ResponseCode(code = 404, condition = "The containerName or subnetName is not found"),
-            @ResponseCode(code = 500, condition = "Internal server error")})
+        @ResponseCode(code = 202, condition = "Operation successful"),
+        @ResponseCode(code = 400, condition = "Invalid request, i.e., requested changing the subnet name"),
+        @ResponseCode(code = 404, condition = "The containerName or subnetName is not found"),
+        @ResponseCode(code = 500, condition = "Internal server error") })
     public Response modifySubnet(@PathParam("containerName") String containerName,
-                                 @PathParam("subnetName") String name,
-                                 @TypeHint(SubnetConfig.class) JAXBElement<SubnetConfig> subnetConfigData) {
+        @PathParam("subnetName") String name,
+        @TypeHint(SubnetConfig.class) JAXBElement<SubnetConfig> subnetConfigData) {
 
-        if (!NorthboundUtils.isAuthorized(getUserName(), containerName,
-                                          Privilege.WRITE, this)) {
-            throw new UnauthorizedException(
-                "User is not authorized to perform this operation on container " + containerName);
+        if (!NorthboundUtils.isAuthorized(getUserName(), containerName, Privilege.WRITE, this)) {
+            throw new UnauthorizedException("User is not authorized to perform this operation on container "
+                    + containerName);
         }
 
-        ISwitchManager switchManager = (ISwitchManager) ServiceHelper.getInstance(ISwitchManager.class,
-                                                                                  containerName, this);
+        ISwitchManager switchManager = (ISwitchManager) ServiceHelper.getInstance(ISwitchManager.class, containerName,
+                this);
         if (switchManager == null) {
             throw new ResourceNotFoundException(RestMessages.NOCONTAINER.toString());
         }
@@ -271,96 +247,171 @@ public class SubnetsNorthboundJAXRS {
 
         // make sure that the name matches an existing subnet and we're not
         // changing the name or subnet IP/mask
-        if (existingConf == null){
+        if (existingConf == null) {
             // don't have a subnet by that name
             return Response.status(Response.Status.NOT_FOUND).build();
 
-        }else if( !existingConf.getName().equals(subnetConf.getName())
-            || !existingConf.getSubnet().equals(subnetConf.getSubnet())) {
+        } else if (!existingConf.getName().equals(subnetConf.getName())
+                || !existingConf.getSubnet().equals(subnetConf.getSubnet())) {
             // can't change the name of a subnet
             return Response.status(Response.Status.BAD_REQUEST).build();
 
-        }else{
+        } else {
             // create a set for fast lookups
             Set<String> newPorts = new HashSet<String>(subnetConf.getNodePorts());
 
             // go through the current ports and (1) remove ports that aren't
             // there anymore and (2) remove ports that are still there from the
             // set of ports to add
-            for(String s : existingConf.getNodePorts()){
-                if(newPorts.contains(s)){
+            for (String s : existingConf.getNodePorts()) {
+                if (newPorts.contains(s)) {
                     newPorts.remove(s);
-                }else{
+                } else {
                     Status st = switchManager.removePortsFromSubnet(name, s);
                     successful = successful && st.isSuccess();
                 }
             }
 
             // add any remaining ports
-            for(String s : newPorts){
+            for (String s : newPorts) {
                 Status st = switchManager.addPortsToSubnet(name, s);
                 successful = successful && st.isSuccess();
             }
         }
 
-        if(successful){
+        if (successful) {
             return Response.status(Response.Status.ACCEPTED).build();
-        }else{
+        } else {
             return Response.status(Response.Status.INTERNAL_SERVER_ERROR).build();
         }
     }
 
-    /*
-     *
-     * Add or remove switch ports to a subnet POST subnets/green/sw
+    /**
      *
-     * @param model
+     * Add ports to a subnet
      *
      * @param containerName
-     *
+     *            Name of the Container
      * @param name
+     *            Name of the SubnetConfig to be modified
+     * @param subnetConfigData
+     *            the {@link SubnetConfig} structure in JSON passed as a POST
+     *            parameter
+     * @return If the operation is successful or not
+     */
+    @Path("/{containerName}/{subnetName}/add")
+    @POST
+    @Consumes({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML })
+    @StatusCodes({
+        @ResponseCode(code = 202, condition = "Operation successful"),
+        @ResponseCode(code = 400, condition = "Invalid request"),
+        @ResponseCode(code = 404, condition = "The containerName or subnetName is not found"),
+        @ResponseCode(code = 500, condition = "Internal server error") })
+    public Response addNodePorts(
+            @PathParam("containerName") String containerName,
+            @PathParam("subnetName") String name,
+            @TypeHint(SubnetConfig.class) JAXBElement<SubnetConfig> subnetConfigData) {
+
+        SubnetConfig subnetConf = subnetConfigData.getValue();
+        return addOrDeletePorts(containerName, name, subnetConf, "add");
+    }
+
+    /**
      *
-     * @param subnet: the subnet name name
-     *
-     * @param switchports: datapath ID/port list =>
-     * xx:xx:xx:xx:xx:xx:xx:xx/a,b,c-m,r-t,y
-     *
-     * @return
-     *
-     * @RequestMapping(value = "/{containerName}/{name}", method =
-     * RequestMethod.POST)
-     *
-     * public View addSwitchports(Map<String, Object> model,
-     *
-     * @PathVariable(value = "containerName") String containerName,
-     *
-     * @PathVariable(value = "name") String name,
-     *
-     * @RequestParam(value = "nodeports") String nodePorts,
-     *
-     * @RequestParam(value = "action") String action) {
-     *
-     * checkDefaultDisabled(containerName); ISwitchManager switchManager = null;
-     * try { BundleContext bCtx = FrameworkUtil.getBundle(this.getClass())
-     * .getBundleContext();
-     *
-     * ServiceReference[] services = bCtx.getServiceReferences(
-     * ISwitchManager.class.getName(), "(containerName=" + containerName + ")");
-     *
-     * if (services != null) { switchManager = (ISwitchManager)
-     * bCtx.getService(services[0]); logger.debug("Switch manager reference is:"
-     * + switchManager); } } catch (Exception e) {
-     * logger.error("Switch Manager reference is NULL"); }
-     *
-     * checkContainerExists(switchManager);
-     *
-     * String ret; if (action.equals("add")) { ret =
-     * switchManager.addPortsToSubnet(name, nodePorts); } else if
-     * (action.equals("remove")) { ret =
-     * switchManager.removePortsFromSubnet(name, nodePorts); } else { throw new
-     * UnsupportedMediaTypeException(RestMessages.UNKNOWNACTION .toString() +
-     * ": " + action); }
+     * Delete ports from a subnet
      *
-     * return returnViewOrThrowConflicEx(model, ret); }
+     * @param containerName
+     *            Name of the Container
+     * @param name
+     *            Name of the SubnetConfig to be modified
+     * @param subnetConfigData
+     *            the {@link SubnetConfig} structure in JSON passed as a POST
+     *            parameter
+     * @return If the operation is successful or not
      */
+    @Path("/{containerName}/{subnetName}/delete")
+    @POST
+    @Consumes({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML })
+    @StatusCodes({
+        @ResponseCode(code = 202, condition = "Operation successful"),
+        @ResponseCode(code = 400, condition = "Invalid request"),
+        @ResponseCode(code = 404, condition = "The containerName or subnetName is not found"),
+        @ResponseCode(code = 500, condition = "Internal server error") })
+    public Response deleteNodePorts(
+            @PathParam("containerName") String containerName,
+            @PathParam("subnetName") String name,
+            @TypeHint(SubnetConfig.class) JAXBElement<SubnetConfig> subnetConfigData) {
+
+        SubnetConfig subnetConf = subnetConfigData.getValue();
+        return addOrDeletePorts(containerName, name, subnetConf, "delete");
+    }
+
+    /**
+    *
+    * Add/Delete ports to/from a subnet
+    *
+    * @param containerName
+    *            Name of the Container
+    * @param name
+    *            Name of the SubnetConfig to be modified
+    * @param subnetConfig
+    *            the {@link SubnetConfig} structure
+    * @param action
+    *            add or delete
+    * @return If the operation is successful or not
+    */
+    private Response addOrDeletePorts(String containerName, String name, SubnetConfig subnetConf, String action) {
+
+        if (!NorthboundUtils.isAuthorized(getUserName(), containerName, Privilege.WRITE, this)) {
+            throw new UnauthorizedException("User is not authorized to perform this operation on container "
+                    + containerName);
+        }
+
+        ISwitchManager switchManager = (ISwitchManager) ServiceHelper.getInstance(ISwitchManager.class, containerName,
+                this);
+        if (switchManager == null) {
+            throw new ResourceNotFoundException(RestMessages.NOCONTAINER.toString());
+        }
+
+        SubnetConfig existingConf = switchManager.getSubnetConfig(name);
+
+        // make sure that the name matches an existing subnet and we're not
+        // changing the name or subnet IP/mask
+        if (existingConf == null) {
+            // don't have a subnet by that name
+            return Response.status(Response.Status.NOT_FOUND).build();
+        } else if (!existingConf.getName().equals(subnetConf.getName())
+                || !existingConf.getSubnet().equals(subnetConf.getSubnet())) {
+            // can't change the name of a subnet
+            return Response.status(Response.Status.BAD_REQUEST).build();
+        } else {
+            Status st;
+            boolean successful = true;
+            List<String> ports = subnetConf.getNodePorts();
+
+            if (action.equals("add")) {
+                // add new ports
+                ports.removeAll(existingConf.getNodePorts());
+                for (String port : ports) {
+                    st = switchManager.addPortsToSubnet(name, port);
+                    successful = successful && st.isSuccess();
+                }
+            } else if (action.equals("delete")) {
+                // delete existing ports
+                ports.retainAll(existingConf.getNodePorts());
+                for (String port : ports) {
+                    st = switchManager.removePortsFromSubnet(name, port);
+                    successful = successful && st.isSuccess();
+                }
+            } else {
+                return Response.status(Response.Status.BAD_REQUEST).build();
+            }
+
+            if (successful) {
+                return Response.status(Response.Status.ACCEPTED).build();
+            } else {
+                return Response.status(Response.Status.INTERNAL_SERVER_ERROR).build();
+            }
+        }
+    }
 }
index 3f3c8bde2e2aef4751c735f84e6259da1b10c730..ee712030e95573a807239dc6283f4291bb5f01d0 100644 (file)
@@ -11,6 +11,7 @@ package org.opendaylight.controller.protocol_plugin.openflow.internal;
 import java.nio.charset.Charset;
 import java.util.ArrayList;
 import java.util.Collection;
+import java.util.Collections;
 import java.util.HashSet;
 import java.util.List;
 import java.util.Map;
@@ -70,20 +71,23 @@ public class DiscoveryService implements IInventoryShimExternalListener, IDataPa
     private IDiscoveryListener discoveryListener = null;
     private IInventoryProvider inventoryProvider = null;
     private IDataPacketMux iDataPacketMux = null;
-    // Newly added ports go into this list and will be served first
+    // High priority list containing newly added ports which will be served first
     private List<NodeConnector> readyListHi = null;
-    // Come here after served at least once
+    // List containing all the ports which will be served periodically
     private List<NodeConnector> readyListLo = null;
     // Staging area during quiet period
-    private List<NodeConnector> waitingList = null;
+    private List<NodeConnector> stagingList = null;
     // Wait for next discovery packet. The map contains the time elapsed since
     // the last received LLDP frame on each node connector
-    private ConcurrentMap<NodeConnector, Integer> pendingMap = null;
-    // openflow edges keyed by head connector
+    private ConcurrentMap<NodeConnector, Integer> holdTime = null;
+    // Allow one more retry for newly added ports. This map contains the time
+    // period elapsed since last discovery pkt transmission on the port.
+    private ConcurrentMap<NodeConnector, Integer> elapsedTime = null;
+    // OpenFlow edges keyed by head connector
     private ConcurrentMap<NodeConnector, Edge> edgeMap = null;
-    // Aging entries keyed by head edge connector
+    // The map contains aging entry keyed by head connector of Production edge
     private ConcurrentMap<NodeConnector, Integer> agingMap = null;
-    // Production edges keyed by head edge connector
+    // Production edges keyed by head connector
     private ConcurrentMap<NodeConnector, Edge> prodMap = null;
 
     private Timer discoveryTimer;
@@ -91,21 +95,20 @@ public class DiscoveryService implements IInventoryShimExternalListener, IDataPa
     private final static long discoveryTimerTick = 2L * 1000; // per tick in msec
     private int discoveryTimerTickCount = 0; // main tick counter
     // Max # of ports handled in one batch
-    private int discoveryBatchMaxPorts = 500;
+    private int discoveryBatchMaxPorts;
     // Periodically restart batching process
-    private int discoveryBatchRestartTicks = getDiscoveryInterval();
-    private int discoveryBatchPausePeriod = 5;
+    private int discoveryBatchRestartTicks;
+    private int discoveryBatchPausePeriod = 2;
     // Pause after this point
-    private int discoveryBatchPauseTicks = discoveryBatchRestartTicks - discoveryBatchPausePeriod;
-    // Number of retries after initial timeout
-    private int discoveryRetry = getDiscoveryRetry();
-    private int discoveryTimeoutTicks = getDiscoveryTimeout();
-    private int discoveryAgeoutTicks = getDiscoveryAgeout();
+    private int discoveryBatchPauseTicks;
+    private int discoveryTimeoutTicks;
+    private int discoveryThresholdTicks;
+    private int discoveryAgeoutTicks;
     // multiple of discoveryBatchRestartTicks
     private int discoveryConsistencyCheckMultiple = 2;
     // CC tick counter
-    private int discoveryConsistencyCheckTickCount = discoveryBatchPauseTicks;
-    // # of times CC getscalled
+    private int discoveryConsistencyCheckTickCount;
+    // # of times CC gets called
     private int discoveryConsistencyCheckCallingTimes = 0;
     // # of cases CC corrected
     private int discoveryConsistencyCheckCorrected = 0;
@@ -162,9 +165,9 @@ public class DiscoveryService implements IInventoryShimExternalListener, IDataPa
     }
 
     public enum DiscoveryPeriod {
-        INTERVAL(300),
-        TIMEOUT (60),
-        AGEOUT  (120);
+        INTERVAL        (300),
+        AGEOUT          (120),
+        THRESHOLD       (30);
 
         private int time;   // sec
         private int tick;   // tick
@@ -187,9 +190,18 @@ public class DiscoveryService implements IInventoryShimExternalListener, IDataPa
             return tick;
         }
 
+        public void setTick(int tick) {
+            this.time = tick2Time(tick);
+            this.tick = tick;
+        }
+
         private int time2Tick(int time) {
             return (int) (time / (discoveryTimerTick / 1000));
         }
+
+        private int tick2Time(int tick) {
+            return (int) (tick * (discoveryTimerTick / 1000));
+        }
     }
 
     private RawPacket createDiscoveryPacket(NodeConnector nodeConnector) {
@@ -409,7 +421,6 @@ public class DiscoveryService implements IInventoryShimExternalListener, IDataPa
             logger.error("Caught exception ", e);
         }
         addEdge(edge, props);
-        pendingMap.put(dstNodeConnector, 0);
 
         logger.trace("Received discovery packet for Edge {}", edge);
 
@@ -472,11 +483,11 @@ public class DiscoveryService implements IInventoryShimExternalListener, IDataPa
             return true;
         }
 
-        if (pendingMap.keySet().contains(nodeConnector)) {
+        if (holdTime.keySet().contains(nodeConnector)) {
             return true;
         }
 
-        if (waitingList.contains(nodeConnector)) {
+        if (stagingList.contains(nodeConnector)) {
             return true;
         }
 
@@ -494,6 +505,9 @@ public class DiscoveryService implements IInventoryShimExternalListener, IDataPa
 
             workingSet.add(nodeConnector);
             removeSet.add(nodeConnector);
+
+            // Put it in the map and start the timer. It may need retry.
+            elapsedTime.put(nodeConnector, 0);
         }
         readyListHi.removeAll(removeSet);
 
@@ -557,7 +571,16 @@ public class DiscoveryService implements IInventoryShimExternalListener, IDataPa
         }
         for (NodeConnector nodeConnector : c) {
             if (node.equals(nodeConnector.getNode())) {
-                removeSet.add(nodeConnector);
+                Edge edge1 = edgeMap.get(nodeConnector);
+                if (edge1 != null) {
+                    removeSet.add(nodeConnector);
+
+                    // check reverse direction
+                    Edge edge2 = edgeMap.get(edge1.getTailNodeConnector());
+                    if ((edge2 != null) && node.equals(edge2.getTailNodeConnector().getNode())) {
+                        removeSet.add(edge2.getHeadNodeConnector());
+                    }
+                }
             }
         }
         return removeSet;
@@ -572,12 +595,12 @@ public class DiscoveryService implements IInventoryShimExternalListener, IDataPa
         removeSet = getRemoveSet(readyListLo, node);
         readyListLo.removeAll(removeSet);
 
-        removeSet = getRemoveSet(waitingList, node);
-        waitingList.removeAll(removeSet);
+        removeSet = getRemoveSet(stagingList, node);
+        stagingList.removeAll(removeSet);
 
-        removeSet = getRemoveSet(pendingMap.keySet(), node);
+        removeSet = getRemoveSet(holdTime.keySet(), node);
         for (NodeConnector nodeConnector : removeSet) {
-            pendingMap.remove(nodeConnector);
+            holdTime.remove(nodeConnector);
         }
 
         removeSet = getRemoveSet(edgeMap.keySet(), node);
@@ -594,28 +617,25 @@ public class DiscoveryService implements IInventoryShimExternalListener, IDataPa
     private void removeDiscovery(NodeConnector nodeConnector) {
         readyListHi.remove(nodeConnector);
         readyListLo.remove(nodeConnector);
-        waitingList.remove(nodeConnector);
-        pendingMap.remove(nodeConnector);
+        stagingList.remove(nodeConnector);
+        holdTime.remove(nodeConnector);
         removeEdge(nodeConnector, false);
         removeProdEdge(nodeConnector);
     }
 
     private void checkTimeout() {
         Set<NodeConnector> removeSet = new HashSet<NodeConnector>();
-        Set<NodeConnector> retrySet = new HashSet<NodeConnector>();
         int ticks;
 
-        Set<NodeConnector> pendingSet = pendingMap.keySet();
-        if (pendingSet != null) {
-            for (NodeConnector nodeConnector : pendingSet) {
-                ticks = pendingMap.get(nodeConnector);
-                pendingMap.put(nodeConnector, ++ticks);
-                if (ticks > getDiscoveryFinalTimeoutInterval()) {
+        Set<NodeConnector> monitorSet = holdTime.keySet();
+        if (monitorSet != null) {
+            for (NodeConnector nodeConnector : monitorSet) {
+                ticks = holdTime.get(nodeConnector);
+                holdTime.put(nodeConnector, ++ticks);
+                if (ticks >= discoveryTimeoutTicks) {
                     // timeout the edge
                     removeSet.add(nodeConnector);
                     logger.trace("Discovery timeout {}", nodeConnector);
-                } else if (ticks % discoveryTimeoutTicks == 0) {
-                    retrySet.add(nodeConnector);
                 }
             }
         }
@@ -624,8 +644,22 @@ public class DiscoveryService implements IInventoryShimExternalListener, IDataPa
             removeEdge(nodeConnector);
         }
 
-        for (NodeConnector nodeConnector : retrySet) {
-            transmitQ.add(nodeConnector);
+        Set<NodeConnector> retrySet = new HashSet<NodeConnector>();
+        Set<NodeConnector> ncSet = elapsedTime.keySet();
+        if ((ncSet != null) && (ncSet.size() > 0)) {
+            for (NodeConnector nodeConnector : ncSet) {
+                ticks = elapsedTime.get(nodeConnector);
+                elapsedTime.put(nodeConnector, ++ticks);
+                if (ticks >= discoveryThresholdTicks) {
+                    retrySet.add(nodeConnector);
+                }
+            }
+
+            for (NodeConnector nodeConnector : retrySet) {
+                // Allow one more retry
+                readyListLo.add(nodeConnector);
+                elapsedTime.remove(nodeConnector);
+            }
         }
     }
 
@@ -659,15 +693,19 @@ public class DiscoveryService implements IInventoryShimExternalListener, IDataPa
         if (++discoveryTimerTickCount <= discoveryBatchPauseTicks) {
             for (NodeConnector nodeConnector : getWorkingSet()) {
                 transmitQ.add(nodeConnector);
+                // Move to staging area after it's served
+                if (!stagingList.contains(nodeConnector)) {
+                    stagingList.add(nodeConnector);
+                }
             }
         } else if (discoveryTimerTickCount >= discoveryBatchRestartTicks) {
             discoveryTimerTickCount = 0;
-            for (NodeConnector nodeConnector : waitingList) {
+            for (NodeConnector nodeConnector : stagingList) {
                 if (!readyListLo.contains(nodeConnector)) {
                     readyListLo.add(nodeConnector);
                 }
             }
-            waitingList.removeAll(readyListLo);
+            stagingList.removeAll(readyListLo);
         }
     }
 
@@ -696,7 +734,7 @@ public class DiscoveryService implements IInventoryShimExternalListener, IDataPa
             }
 
             if (!isTracked(nodeConnector)) {
-                waitingList.add(nodeConnector);
+                stagingList.add(nodeConnector);
                 discoveryConsistencyCheckCorrected++;
                 logger.debug("ConsistencyChecker: add back untracked {}", nodeConnector);
                 continue;
@@ -709,14 +747,14 @@ public class DiscoveryService implements IInventoryShimExternalListener, IDataPa
 
         // remove stale entries
         removeSet.clear();
-        for (NodeConnector nodeConnector : waitingList) {
+        for (NodeConnector nodeConnector : stagingList) {
             if (!isEnabled(nodeConnector)) {
                 removeSet.add(nodeConnector);
                 discoveryConsistencyCheckCorrected++;
                 logger.debug("ConsistencyChecker: remove disabled {}", nodeConnector);
             }
         }
-        waitingList.removeAll(removeSet);
+        stagingList.removeAll(removeSet);
 
         // Get a snapshot of all the existing switches
         Map<Long, ISwitch> switches = this.controller.getSwitches();
@@ -725,7 +763,7 @@ public class DiscoveryService implements IInventoryShimExternalListener, IDataPa
                 Node node = NodeCreator.createOFNode(sw.getId());
                 NodeConnector nodeConnector = NodeConnectorCreator.createOFNodeConnector(port.getPortNumber(), node);
                 if (!isTracked(nodeConnector)) {
-                    waitingList.add(nodeConnector);
+                    stagingList.add(nodeConnector);
                     discoveryConsistencyCheckCorrected++;
                     logger.debug("ConsistencyChecker: add back untracked {}", nodeConnector);
                 }
@@ -739,12 +777,13 @@ public class DiscoveryService implements IInventoryShimExternalListener, IDataPa
         }
 
         NodeConnector src = edge.getTailNodeConnector();
+        NodeConnector dst = edge.getHeadNodeConnector();
         if (!src.getType().equals(NodeConnector.NodeConnectorIDType.PRODUCTION)) {
-            pendingMap.remove(src);
+            holdTime.put(dst, 0);
         } else {
-            NodeConnector dst = edge.getHeadNodeConnector();
             agingMap.put(dst, 0);
         }
+        elapsedTime.remove(src);
 
         // notify
         updateEdge(edge, UpdateType.ADDED, props);
@@ -812,18 +851,18 @@ public class DiscoveryService implements IInventoryShimExternalListener, IDataPa
      * Remove OpenFlow edge
      */
     private void removeEdge(NodeConnector nodeConnector, boolean stillEnabled) {
-        pendingMap.remove(nodeConnector);
+        holdTime.remove(nodeConnector);
         readyListLo.remove(nodeConnector);
         readyListHi.remove(nodeConnector);
 
         if (stillEnabled) {
             // keep discovering
-            if (!waitingList.contains(nodeConnector)) {
-                waitingList.add(nodeConnector);
+            if (!stagingList.contains(nodeConnector)) {
+                stagingList.add(nodeConnector);
             }
         } else {
             // stop it
-            waitingList.remove(nodeConnector);
+            stagingList.remove(nodeConnector);
         }
 
         Edge edge = null;
@@ -873,8 +912,8 @@ public class DiscoveryService implements IInventoryShimExternalListener, IDataPa
     private void moveToReadyListHi(NodeConnector nodeConnector) {
         if (readyListLo.contains(nodeConnector)) {
             readyListLo.remove(nodeConnector);
-        } else if (waitingList.contains(nodeConnector)) {
-            waitingList.remove(nodeConnector);
+        } else if (stagingList.contains(nodeConnector)) {
+            stagingList.remove(nodeConnector);
         }
         readyListHi.add(nodeConnector);
     }
@@ -888,18 +927,15 @@ public class DiscoveryService implements IInventoryShimExternalListener, IDataPa
         return discoveryConsistencyCheckMultiple * discoveryBatchRestartTicks;
     }
 
-    private int getDiscoveryFinalTimeoutInterval() {
-        return (discoveryRetry + 1) * discoveryTimeoutTicks;
-    }
-
     @Override
     public String getHelp() {
         StringBuffer help = new StringBuffer();
         help.append("---Topology Discovery---\n");
         help.append("\t prlh                            - Print readyListHi entries\n");
         help.append("\t prll                            - Print readyListLo entries\n");
-        help.append("\t pwl                             - Print waitingList entries\n");
-        help.append("\t ppl                             - Print pendingList entries\n");
+        help.append("\t psl                             - Print stagingList entries\n");
+        help.append("\t pht                             - Print hold time\n");
+        help.append("\t pet                             - Print elapsed time\n");
         help.append("\t ptick                           - Print tick time in msec\n");
         help.append("\t pcc                             - Print CC info\n");
         help.append("\t psize                           - Print sizes of all the lists\n");
@@ -910,8 +946,6 @@ public class DiscoveryService implements IInventoryShimExternalListener, IDataPa
         help.append("\t sports [ports]                  - Set/show max ports per batch\n");
         help.append("\t spause [ticks]                  - Set/show pause period\n");
         help.append("\t sdi [ticks]                     - Set/show discovery interval in ticks\n");
-        help.append("\t stm [ticks]                     - Set/show per timeout ticks\n");
-        help.append("\t sretry [count]                  - Set/show num of retries\n");
         help.append("\t addsw <swid>                    - Add a switch\n");
         help.append("\t remsw <swid>                    - Remove a switch\n");
         help.append("\t page                            - Print aging info\n");
@@ -927,42 +961,69 @@ public class DiscoveryService implements IInventoryShimExternalListener, IDataPa
         return help.toString();
     }
 
+    private List<NodeConnector> sortList(Collection<NodeConnector> ncs) {
+        List<String> ncStrArray = new ArrayList<String>();
+        for (NodeConnector nc : ncs) {
+            ncStrArray.add(nc.toString());
+        }
+        Collections.sort(ncStrArray);
+
+        List<NodeConnector> sortedNodeConnectors = new ArrayList<NodeConnector>();
+        for (String ncStr : ncStrArray) {
+            sortedNodeConnectors.add(NodeConnector.fromString(ncStr));
+        }
+
+        return sortedNodeConnectors;
+    }
+
     public void _prlh(CommandInterpreter ci) {
-        ci.println("ReadyListHi\n");
-        for (NodeConnector nodeConnector : readyListHi) {
+        ci.println("readyListHi\n");
+        for (NodeConnector nodeConnector : sortList(readyListHi)) {
             if (nodeConnector == null) {
                 continue;
             }
             ci.println(nodeConnector);
         }
+        ci.println("Total number of Node Connectors: " + readyListHi.size());
     }
 
     public void _prll(CommandInterpreter ci) {
-        ci.println("ReadyListLo\n");
-        for (NodeConnector nodeConnector : readyListLo) {
+        ci.println("readyListLo\n");
+        for (NodeConnector nodeConnector : sortList(readyListLo)) {
             if (nodeConnector == null) {
                 continue;
             }
             ci.println(nodeConnector);
         }
+        ci.println("Total number of Node Connectors: " + readyListLo.size());
     }
 
-    public void _pwl(CommandInterpreter ci) {
-        ci.println("WaitingList\n");
-        for (NodeConnector nodeConnector : waitingList) {
+    public void _psl(CommandInterpreter ci) {
+        ci.println("stagingList\n");
+        for (NodeConnector nodeConnector : sortList(stagingList)) {
             if (nodeConnector == null) {
                 continue;
             }
             ci.println(nodeConnector);
         }
+        ci.println("Total number of Node Connectors: " + stagingList.size());
     }
 
-    public void _ppl(CommandInterpreter ci) {
-        ci.println("pendingMap\n");
-        ci.println("          NodeConnector            Last rx LLDP (s)");
-        for (ConcurrentMap.Entry<NodeConnector, Integer> entry: pendingMap.entrySet()) {
-            ci.println(entry.getKey() + "\t\t" + entry.getValue());
+    public void _pht(CommandInterpreter ci) {
+        ci.println("          NodeConnector            Last rx LLDP (sec)");
+        for (ConcurrentMap.Entry<NodeConnector, Integer> entry: holdTime.entrySet()) {
+            ci.println(entry.getKey() + "\t\t" + entry.getValue() * (discoveryTimerTick / 1000));
         }
+        ci.println("\nSize: " + holdTime.size() + "\tTimeout: " + discoveryTimeoutTicks * (discoveryTimerTick / 1000)
+                + " sec");
+    }
+
+    public void _pet(CommandInterpreter ci) {
+        ci.println("          NodeConnector            Elapsed Time (sec)");
+        for (ConcurrentMap.Entry<NodeConnector, Integer> entry: elapsedTime.entrySet()) {
+            ci.println(entry.getKey() + "\t\t" + entry.getValue() * (discoveryTimerTick / 1000));
+        }
+        ci.println("\nSize: " + elapsedTime.size() + "\tThreshold: " + DiscoveryPeriod.THRESHOLD.getTime() + " sec");
     }
 
     public void _ptick(CommandInterpreter ci) {
@@ -982,16 +1043,14 @@ public class DiscoveryService implements IInventoryShimExternalListener, IDataPa
     }
 
     public void _ptm(CommandInterpreter ci) {
-        ci.println("Final timeout ticks " + getDiscoveryFinalTimeoutInterval());
-        ci.println("Per timeout ticks " + discoveryTimeoutTicks);
-        ci.println("Number of retries after initial timeout " + discoveryRetry);
+        ci.println("Timeout " + discoveryTimeoutTicks + " ticks, " + discoveryTimerTick / 1000 + " sec per tick.");
     }
 
     public void _psize(CommandInterpreter ci) {
         ci.println("readyListLo size " + readyListLo.size() + "\n" + "readyListHi size " + readyListHi.size() + "\n"
-                + "waitingList size " + waitingList.size() + "\n" + "pendingMap size " + pendingMap.size() + "\n"
+                + "stagingList size " + stagingList.size() + "\n" + "holdTime size " + holdTime.size() + "\n"
                 + "edgeMap size " + edgeMap.size() + "\n" + "prodMap size " + prodMap.size() + "\n" + "agingMap size "
-                + agingMap.size());
+                + agingMap.size() + "\n" + "elapsedTime size " + elapsedTime.size());
     }
 
     public void _page(CommandInterpreter ci) {
@@ -1136,14 +1195,15 @@ public class DiscoveryService implements IInventoryShimExternalListener, IDataPa
     public void _spause(CommandInterpreter ci) {
         String val = ci.nextArgument();
         String out = "Please enter pause period less than " + discoveryBatchRestartTicks + ". Current pause period is "
-                + discoveryBatchPausePeriod + " pause tick is " + discoveryBatchPauseTicks + ".";
+                + discoveryBatchPausePeriod + " ticks, pause at " + discoveryBatchPauseTicks + " ticks, "
+                + discoveryTimerTick / 1000 + " sec per tick.";
 
         if (val != null) {
             try {
                 int pause = Integer.parseInt(val);
                 if (pause < discoveryBatchRestartTicks) {
                     discoveryBatchPausePeriod = pause;
-                    discoveryBatchPauseTicks = discoveryBatchRestartTicks - discoveryBatchPausePeriod;
+                    discoveryBatchPauseTicks = getDiscoveryPauseInterval();
                     return;
                 }
             } catch (Exception e) {
@@ -1155,17 +1215,17 @@ public class DiscoveryService implements IInventoryShimExternalListener, IDataPa
 
     public void _sdi(CommandInterpreter ci) {
         String val = ci.nextArgument();
-        String out = "Please enter discovery interval greater than " + discoveryBatchPausePeriod
-                + ". Current value is " + discoveryBatchRestartTicks + ".";
+        String out = "Please enter discovery interval in ticks. Current value is " + discoveryBatchRestartTicks + " ticks, "
+                + discoveryTimerTick / 1000 + " sec per tick.";
 
         if (val != null) {
             try {
-                int restart = Integer.parseInt(val);
-                if (restart > discoveryBatchPausePeriod) {
-                    discoveryBatchRestartTicks = restart;
-                    discoveryBatchPauseTicks = discoveryBatchRestartTicks - discoveryBatchPausePeriod;
-                    return;
-                }
+                int ticks = Integer.parseInt(val);
+                DiscoveryPeriod.INTERVAL.setTick(ticks);
+                discoveryBatchRestartTicks = getDiscoveryInterval();
+                discoveryBatchPauseTicks = getDiscoveryPauseInterval();
+                discoveryTimeoutTicks = getDiscoveryTimeout();
+                return;
             } catch (Exception e) {
             }
         }
@@ -1186,38 +1246,6 @@ public class DiscoveryService implements IInventoryShimExternalListener, IDataPa
         return;
     }
 
-    public void _sretry(CommandInterpreter ci) {
-        String val = ci.nextArgument();
-        if (val == null) {
-            ci.println("Please enter number of retries. Current value is " + discoveryRetry);
-            return;
-        }
-        try {
-            discoveryRetry = Integer.parseInt(val);
-        } catch (Exception e) {
-            ci.println("Please enter a valid number");
-        }
-        return;
-    }
-
-    public void _stm(CommandInterpreter ci) {
-        String val = ci.nextArgument();
-        String out = "Please enter timeout tick value less than " + discoveryBatchRestartTicks + ". Current value is "
-                + discoveryTimeoutTicks;
-        if (val != null) {
-            try {
-                int timeout = Integer.parseInt(val);
-                if (timeout < discoveryBatchRestartTicks) {
-                    discoveryTimeoutTicks = timeout;
-                    return;
-                }
-            } catch (Exception e) {
-            }
-        }
-
-        ci.println(out);
-    }
-
     public void _addsw(CommandInterpreter ci) {
         String val = ci.nextArgument();
         Long sid;
@@ -1403,13 +1431,22 @@ public class DiscoveryService implements IInventoryShimExternalListener, IDataPa
 
         readyListHi = new CopyOnWriteArrayList<NodeConnector>();
         readyListLo = new CopyOnWriteArrayList<NodeConnector>();
-        waitingList = new CopyOnWriteArrayList<NodeConnector>();
-        pendingMap = new ConcurrentHashMap<NodeConnector, Integer>();
+        stagingList = new CopyOnWriteArrayList<NodeConnector>();
+        holdTime = new ConcurrentHashMap<NodeConnector, Integer>();
+        elapsedTime = new ConcurrentHashMap<NodeConnector, Integer>();
         edgeMap = new ConcurrentHashMap<NodeConnector, Edge>();
         agingMap = new ConcurrentHashMap<NodeConnector, Integer>();
         prodMap = new ConcurrentHashMap<NodeConnector, Edge>();
         discoverySnoopingDisableList = new CopyOnWriteArrayList<NodeConnector>();
 
+        discoveryBatchRestartTicks = getDiscoveryInterval();
+        discoveryBatchPauseTicks = getDiscoveryPauseInterval();
+        discoveryTimeoutTicks = getDiscoveryTimeout();
+        discoveryThresholdTicks = getDiscoveryThreshold();
+        discoveryAgeoutTicks = getDiscoveryAgeout();
+        discoveryConsistencyCheckTickCount = discoveryBatchPauseTicks;
+        discoveryBatchMaxPorts = getDiscoveryBatchMaxPorts();
+
         discoveryTimer = new Timer("DiscoveryService");
         discoveryTimerTask = new DiscoveryTimerTask();
 
@@ -1430,8 +1467,8 @@ public class DiscoveryService implements IInventoryShimExternalListener, IDataPa
         transmitQ = null;
         readyListHi = null;
         readyListLo = null;
-        waitingList = null;
-        pendingMap = null;
+        stagingList = null;
+        holdTime = null;
         edgeMap = null;
         agingMap = null;
         prodMap = null;
@@ -1534,14 +1571,31 @@ public class DiscoveryService implements IInventoryShimExternalListener, IDataPa
     }
 
     /**
-     * This method returns the timeout value in waiting for response of a
-     * discovery query.
+     * This method returns the timeout value in receiving subsequent discovery packets on a port.
      *
      * @return The discovery timeout in ticks
      */
     private int getDiscoveryTimeout() {
-        String timeout = System.getProperty("of.discoveryTimeout");
-        return getDiscoveryTicks(DiscoveryPeriod.TIMEOUT, timeout);
+        String val = System.getProperty("of.discoveryTimeoutMultiple");
+        int multiple = 2;
+
+        if (val != null) {
+            try {
+                multiple = Integer.parseInt(val);
+            } catch (Exception e) {
+            }
+        }
+        return getDiscoveryInterval() * multiple + 3;
+    }
+
+    /**
+     * This method returns the user configurable threshold value
+     *
+     * @return The discovery threshold value in ticks
+     */
+    private int getDiscoveryThreshold() {
+        String val = System.getProperty("of.discoveryThreshold");
+        return getDiscoveryTicks(DiscoveryPeriod.THRESHOLD, val);
     }
 
     /**
@@ -1554,22 +1608,34 @@ public class DiscoveryService implements IInventoryShimExternalListener, IDataPa
     }
 
     /**
-     * This method returns the number of retries after the initial discovery
-     * packet is not received within the timeout period. Default is 2 times.
+     * This method returns the pause interval
      *
-     * @return The number of discovery retries
+     * @return The pause interval in ticks
      */
-    private int getDiscoveryRetry() {
-        String retry = System.getProperty("of.discoveryRetry");
-        int rv = 2;
+    private int getDiscoveryPauseInterval() {
+        if (discoveryBatchRestartTicks > discoveryBatchPausePeriod) {
+            return discoveryBatchRestartTicks - discoveryBatchPausePeriod;
+        } else {
+            return discoveryBatchRestartTicks - 1;
+        }
+    }
 
-        if (retry != null) {
+    /**
+     * This method returns the user configurable maximum number of ports handled
+     * in one discovery batch.
+     *
+     * @return The maximum number of ports
+     */
+    private int getDiscoveryBatchMaxPorts() {
+        String val = System.getProperty("of.discoveryBatchMaxPorts");
+        int ports = 1024;
+
+        if (val != null) {
             try {
-                rv = Integer.parseInt(retry);
+                ports = Integer.parseInt(val);
             } catch (Exception e) {
             }
         }
-
-        return rv;
+        return ports;
     }
 }
index 8d3a1be20339b866b4165ad305f20aef2629d371..756a6895dc06e19ef0fbcbd85314c3fb0abdc645 100644 (file)
@@ -51,6 +51,7 @@ import org.openflow.protocol.OFPacketOut;
 import org.openflow.protocol.OFPort;
 import org.openflow.protocol.OFVendor;
 import org.openflow.protocol.action.OFAction;
+import org.openflow.protocol.action.OFActionDataLayer;
 import org.openflow.protocol.action.OFActionDataLayerDestination;
 import org.openflow.protocol.action.OFActionDataLayerSource;
 import org.openflow.protocol.action.OFActionNetworkLayerAddress;
@@ -196,35 +197,23 @@ public class FlowConverter {
                 }
             }
             if (match.isPresent(MatchType.NW_SRC)) {
-                InetAddress address = (InetAddress) match.getField(
-                        MatchType.NW_SRC).getValue();
-                InetAddress mask = (InetAddress) match.getField(
-                        MatchType.NW_SRC).getMask();
+                InetAddress address = (InetAddress) match.getField(MatchType.NW_SRC).getValue();
+                InetAddress mask = (InetAddress) match.getField(MatchType.NW_SRC).getMask();
                 if (!isIPv6) {
-                    ofMatch.setNetworkSource(NetUtils.byteArray4ToInt(address
-                            .getAddress()));
-                    int maskLength = NetUtils
-                            .getSubnetMaskLength((mask == null) ? null : mask
-                                    .getAddress());
-                    wildcards = (wildcards & ~OFMatch.OFPFW_NW_SRC_MASK)
-                            | (maskLength << OFMatch.OFPFW_NW_SRC_SHIFT);
+                    ofMatch.setNetworkSource(NetUtils.byteArray4ToInt(address.getAddress()));
+                    int maskLength = (mask == null) ? 32 : NetUtils.getSubnetMaskLength(mask);
+                    wildcards = (wildcards & ~OFMatch.OFPFW_NW_SRC_MASK) | ((32 - maskLength) << OFMatch.OFPFW_NW_SRC_SHIFT);
                 } else {
                     ((V6Match) ofMatch).setNetworkSource(address, mask);
                 }
             }
             if (match.isPresent(MatchType.NW_DST)) {
-                InetAddress address = (InetAddress) match.getField(
-                        MatchType.NW_DST).getValue();
-                InetAddress mask = (InetAddress) match.getField(
-                        MatchType.NW_DST).getMask();
+                InetAddress address = (InetAddress) match.getField(MatchType.NW_DST).getValue();
+                InetAddress mask = (InetAddress) match.getField(MatchType.NW_DST).getMask();
                 if (!isIPv6) {
-                    ofMatch.setNetworkDestination(NetUtils
-                            .byteArray4ToInt(address.getAddress()));
-                    int maskLength = NetUtils
-                            .getSubnetMaskLength((mask == null) ? null : mask
-                                    .getAddress());
-                    wildcards = (wildcards & ~OFMatch.OFPFW_NW_DST_MASK)
-                            | (maskLength << OFMatch.OFPFW_NW_DST_SHIFT);
+                    ofMatch.setNetworkDestination(NetUtils.byteArray4ToInt(address.getAddress()));
+                    int maskLength = (mask == null) ? 32 : NetUtils.getSubnetMaskLength(mask);
+                    wildcards = (wildcards & ~OFMatch.OFPFW_NW_DST_MASK) | ((32 - maskLength) << OFMatch.OFPFW_NW_DST_SHIFT);
                 } else {
                     ((V6Match) ofMatch).setNetworkDestination(address, mask);
                 }
@@ -354,7 +343,7 @@ public class FlowConverter {
                     OFActionDataLayerSource ofAction = new OFActionDataLayerSource();
                     ofAction.setDataLayerAddress(a.getDlAddress());
                     actionsList.add(ofAction);
-                    actionsLength += OFActionDataLayerSource.MINIMUM_LENGTH;
+                    actionsLength += OFActionDataLayer.MINIMUM_LENGTH;
                     continue;
                 }
                 if (action.getType() == ActionType.SET_DL_DST) {
@@ -362,7 +351,7 @@ public class FlowConverter {
                     OFActionDataLayerDestination ofAction = new OFActionDataLayerDestination();
                     ofAction.setDataLayerAddress(a.getDlAddress());
                     actionsList.add(ofAction);
-                    actionsLength += OFActionDataLayerDestination.MINIMUM_LENGTH;
+                    actionsLength += OFActionDataLayer.MINIMUM_LENGTH;
                     continue;
                 }
                 if (action.getType() == ActionType.SET_NW_SRC) {
@@ -502,7 +491,7 @@ public class FlowConverter {
             if (ofMatch != null) {
                 if (!isIPv6) {
                     // Compute OF1.0 Match
-                    if (ofMatch.getInputPort() != 0) {
+                    if (ofMatch.getInputPort() != 0 && ofMatch.getInputPort() != OFPort.OFPP_LOCAL.getValue()) {
                         salMatch.setField(new MatchField(MatchType.IN_PORT,
                                 NodeConnectorCreator.createNodeConnector(
                                         ofMatch.getInputPort(), node)));
@@ -569,7 +558,7 @@ public class FlowConverter {
                 } else {
                     // Compute OF1.0 + IPv6 extensions Match
                     V6Match v6Match = (V6Match) ofMatch;
-                    if (v6Match.getInputPort() != 0) {
+                    if (v6Match.getInputPort() != 0 && v6Match.getInputPort() != OFPort.OFPP_LOCAL.getValue()) {
                         // Mask on input port is not defined
                         salMatch.setField(new MatchField(MatchType.IN_PORT,
                                 NodeConnectorCreator.createOFNodeConnector(
@@ -601,15 +590,30 @@ public class FlowConverter {
                         salMatch.setField(MatchType.DL_VLAN_PR, v6Match
                                 .getDataLayerVirtualLanPriorityCodePoint());
                     }
+                    // V6Match may carry IPv4 address
                     if (v6Match.getNetworkSrc() != null) {
                         salMatch.setField(MatchType.NW_SRC,
                                 v6Match.getNetworkSrc(),
                                 v6Match.getNetworkSourceMask());
+                    } else if (v6Match.getNetworkSource() != 0) {
+                        salMatch.setField(MatchType.NW_SRC, NetUtils
+                                .getInetAddress(v6Match.getNetworkSource()),
+                                NetUtils.getInetNetworkMask(
+                                        v6Match.getNetworkSourceMaskLen(),
+                                        false));
                     }
+                    // V6Match may carry IPv4 address
                     if (v6Match.getNetworkDest() != null) {
                         salMatch.setField(MatchType.NW_DST,
                                 v6Match.getNetworkDest(),
                                 v6Match.getNetworkDestinationMask());
+                    } else if (v6Match.getNetworkDestination() != 0) {
+                        salMatch.setField(MatchType.NW_DST,
+                                NetUtils.getInetAddress(v6Match
+                                        .getNetworkDestination()),
+                                NetUtils.getInetNetworkMask(
+                                        v6Match.getNetworkDestinationMaskLen(),
+                                        false));
                     }
                     if (v6Match.getNetworkTypeOfService() != 0) {
                         int dscp = NetUtils.getUnsignedByte(v6Match
index 024549de596a7813eb191a18f35cae2c23babfc7..f0b8735f83f960b0626fff87c20304ce40a03cb9 100644 (file)
@@ -8,6 +8,7 @@
 
 package org.opendaylight.controller.protocol_plugin.openflow.internal;
 
+import java.util.ArrayList;
 import java.util.Date;
 import java.util.HashSet;
 import java.util.List;
@@ -16,6 +17,7 @@ import java.util.Set;
 import java.util.concurrent.ConcurrentHashMap;
 import java.util.concurrent.ConcurrentMap;
 import java.util.concurrent.CopyOnWriteArrayList;
+import java.util.concurrent.CopyOnWriteArraySet;
 
 import org.opendaylight.controller.protocol_plugin.openflow.IInventoryShimExternalListener;
 import org.opendaylight.controller.protocol_plugin.openflow.IInventoryShimInternalListener;
@@ -27,13 +29,11 @@ import org.opendaylight.controller.protocol_plugin.openflow.core.ISwitchStateLis
 import org.opendaylight.controller.sal.core.Actions;
 import org.opendaylight.controller.sal.core.Buffers;
 import org.opendaylight.controller.sal.core.Capabilities;
-import org.opendaylight.controller.sal.core.ConstructionException;
 import org.opendaylight.controller.sal.core.ContainerFlow;
 import org.opendaylight.controller.sal.core.Description;
 import org.opendaylight.controller.sal.core.IContainerListener;
 import org.opendaylight.controller.sal.core.MacAddress;
 import org.opendaylight.controller.sal.core.Node;
-import org.opendaylight.controller.sal.core.Node.NodeIDType;
 import org.opendaylight.controller.sal.core.NodeConnector;
 import org.opendaylight.controller.sal.core.Property;
 import org.opendaylight.controller.sal.core.Tables;
@@ -64,7 +64,10 @@ public class InventoryServiceShim implements IContainerListener,
     private IController controller = null;
     private final ConcurrentMap<String, IInventoryShimInternalListener> inventoryShimInternalListeners = new ConcurrentHashMap<String, IInventoryShimInternalListener>();
     private final List<IInventoryShimExternalListener> inventoryShimExternalListeners = new CopyOnWriteArrayList<IInventoryShimExternalListener>();
-    private final ConcurrentMap<NodeConnector, List<String>> containerMap = new ConcurrentHashMap<NodeConnector, List<String>>();
+    private final ConcurrentMap<NodeConnector, Set<String>> nodeConnectorContainerMap = new ConcurrentHashMap<NodeConnector, Set<String>>();
+    private final ConcurrentMap<Node, Set<String>> nodeContainerMap = new ConcurrentHashMap<Node, Set<String>>();
+    private final ConcurrentMap<NodeConnector, Set<Property>> nodeConnectorProps = new ConcurrentHashMap<NodeConnector, Set<Property>>();
+    private final ConcurrentMap<Node, Set<Property>> nodeProps = new ConcurrentHashMap<Node, Set<Property>>();
 
     void setController(IController s) {
         this.controller = s;
@@ -162,7 +165,8 @@ public class InventoryServiceShim implements IContainerListener,
         this.controller.removeSwitchStateListener(this);
 
         this.inventoryShimInternalListeners.clear();
-        this.containerMap.clear();
+        this.nodeConnectorContainerMap.clear();
+        this.nodeContainerMap.clear();
         this.controller = null;
     }
 
@@ -178,21 +182,24 @@ public class InventoryServiceShim implements IContainerListener,
         Node node = NodeCreator.createOFNode(sw.getId());
         NodeConnector nodeConnector = PortConverter.toNodeConnector(
             m.getDesc().getPortNumber(), node);
+        // get node connector properties
+        Set<Property> props = InventoryServiceHelper.OFPortToProps(m.getDesc());
 
         UpdateType type = null;
         if (m.getReason() == (byte) OFPortReason.OFPPR_ADD.ordinal()) {
             type = UpdateType.ADDED;
+            nodeConnectorProps.put(nodeConnector, props);
         } else if (m.getReason() == (byte) OFPortReason.OFPPR_DELETE.ordinal()) {
             type = UpdateType.REMOVED;
+            nodeConnectorProps.remove(nodeConnector);
         } else if (m.getReason() == (byte) OFPortReason.OFPPR_MODIFY.ordinal()) {
             type = UpdateType.CHANGED;
+            nodeConnectorProps.put(nodeConnector, props);
         }
 
         logger.trace("handlePortStatusMessage {} type {}", nodeConnector, type);
 
         if (type != null) {
-            // get node connector properties
-            Set<Property> props = InventoryServiceHelper.OFPortToProps(m.getDesc());
             notifyInventoryShimListener(nodeConnector, type, props);
         }
     }
@@ -207,6 +214,12 @@ public class InventoryServiceShim implements IContainerListener,
         Map<NodeConnector, Set<Property>> ncProps = InventoryServiceHelper
                 .OFSwitchToProps(sw);
         for (Map.Entry<NodeConnector, Set<Property>> entry : ncProps.entrySet()) {
+            Set<Property> props = new HashSet<Property>();
+            Set<Property> prop = entry.getValue();
+            if (prop != null) {
+                props.addAll(prop);
+            }
+            nodeConnectorProps.put(entry.getKey(), props);
             notifyInventoryShimListener(entry.getKey(), UpdateType.ADDED,
                     entry.getValue());
         }
@@ -242,48 +255,71 @@ public class InventoryServiceShim implements IContainerListener,
     }
 
     @Override
-    public void nodeConnectorUpdated(String containerName, NodeConnector p,
-            UpdateType t) {
-        logger.debug("nodeConnectorUpdated: {} type {} for container {}",
-                new Object[] { p, t, containerName });
-        if (this.containerMap == null) {
-            logger.error("containerMap is NULL");
-            return;
+    public void nodeConnectorUpdated(String containerName, NodeConnector nc, UpdateType t) {
+        logger.debug("nodeConnectorUpdated: {} type {} for container {}", new Object[] { nc, t, containerName });
+        Node node = nc.getNode();
+        Set<String> ncContainers = this.nodeConnectorContainerMap.get(nc);
+        Set<String> nodeContainers = this.nodeContainerMap.get(node);
+        if (ncContainers == null) {
+            ncContainers = new CopyOnWriteArraySet<String>();
         }
-        List<String> containers = this.containerMap.get(p);
-        if (containers == null) {
-            containers = new CopyOnWriteArrayList<String>();
+        if (nodeContainers == null) {
+            nodeContainers = new CopyOnWriteArraySet<String>();
         }
-        boolean updateMap = false;
+        boolean notifyNodeUpdate = false;
+
         switch (t) {
         case ADDED:
-            if (!containers.contains(containerName)) {
-                containers.add(containerName);
-                updateMap = true;
+            if (ncContainers.add(containerName)) {
+                this.nodeConnectorContainerMap.put(nc, ncContainers);
+            }
+            if (nodeContainers.add(containerName)) {
+                this.nodeContainerMap.put(node, nodeContainers);
+                notifyNodeUpdate = true;
             }
             break;
         case REMOVED:
-            if (containers.contains(containerName)) {
-                containers.remove(containerName);
-                updateMap = true;
+            if (ncContainers.remove(containerName)) {
+                if (ncContainers.isEmpty()) {
+                    // Do cleanup to reduce memory footprint if no
+                    // elements to be tracked
+                    this.nodeConnectorContainerMap.remove(nc);
+                } else {
+                    this.nodeConnectorContainerMap.put(nc, ncContainers);
+                }
+            }
+            boolean nodeContainerUpdate = true;
+            for (NodeConnector ncContainer : nodeConnectorContainerMap.keySet()) {
+                if ((ncContainer.getNode().equals(node)) && (nodeConnectorContainerMap.get(ncContainer).contains(containerName))) {
+                    nodeContainerUpdate = false;
+                    break;
+                }
+            }
+            if (nodeContainerUpdate) {
+                nodeContainers.remove(containerName);
+                notifyNodeUpdate = true;
+                if (nodeContainers.isEmpty()) {
+                    this.nodeContainerMap.remove(node);
+                } else {
+                    this.nodeContainerMap.put(node, nodeContainers);
+                }
             }
             break;
         case CHANGED:
             break;
         }
-        if (updateMap) {
-            if (containers.isEmpty()) {
-                // Do cleanup to reduce memory footprint if no
-                // elements to be tracked
-                this.containerMap.remove(p);
-            } else {
-                this.containerMap.put(p, containers);
-            }
-        }
 
+        Set<Property> nodeProp = nodeProps.get(node);
+        if (nodeProp == null) {
+            return;
+        }
+        Set<Property> ncProp = nodeConnectorProps.get(nc);
         // notify InventoryService
-        notifyInventoryShimInternalListener(containerName, p, t, null);
-        notifyInventoryShimInternalListener(containerName, p.getNode(), t, null);
+        notifyInventoryShimInternalListener(containerName, nc, t, ncProp);
+
+        if (notifyNodeUpdate) {
+            notifyInventoryShimInternalListener(containerName, node, t, nodeProp);
+        }
     }
 
     private void notifyInventoryShimExternalListener(Node node,
@@ -316,21 +352,13 @@ public class InventoryServiceShim implements IContainerListener,
     /*
      * Notify all internal and external listeners
      */
-    private void notifyInventoryShimListener(NodeConnector nodeConnector,
-            UpdateType type, Set<Property> props) {
-        // Always notify default InventoryService. Store properties in default
-        // one.
-        notifyInventoryShimInternalListener(GlobalConstants.DEFAULT.toString(),
-                nodeConnector, type, props);
-
-        // Now notify other containers
-        List<String> containers = containerMap.get(nodeConnector);
-        if (containers != null) {
-            for (String container : containers) {
-                // no property stored in container components.
-                notifyInventoryShimInternalListener(container, nodeConnector,
-                        type, null);
-            }
+    private void notifyInventoryShimListener(NodeConnector nodeConnector, UpdateType type, Set<Property> props) {
+        // notify other containers
+        Set<String> containers = (nodeConnectorContainerMap.get(nodeConnector) == null) ? new HashSet<String>()
+                : new HashSet<String>(nodeConnectorContainerMap.get(nodeConnector));
+        containers.add(GlobalConstants.DEFAULT.toString());
+        for (String container : containers) {
+            notifyInventoryShimInternalListener(container, nodeConnector, type, props);
         }
 
         // Notify DiscoveryService
@@ -340,34 +368,13 @@ public class InventoryServiceShim implements IContainerListener,
     /*
      * Notify all internal and external listeners
      */
-    private void notifyInventoryShimListener(Node node, UpdateType type,
-            Set<Property> props) {
-        switch (type) {
-        case ADDED:
-            // Notify only the default Inventory Service
-            IInventoryShimInternalListener inventoryShimDefaultListener = inventoryShimInternalListeners
-                    .get(GlobalConstants.DEFAULT.toString());
-            if (inventoryShimDefaultListener != null) {
-                inventoryShimDefaultListener.updateNode(node, type, props);
-            }
-            break;
-        case REMOVED:
-            // Notify all Inventory Service containers
-            for (IInventoryShimInternalListener inventoryShimInternalListener : inventoryShimInternalListeners
-                    .values()) {
-                inventoryShimInternalListener.updateNode(node, type, null);
-            }
-            break;
-        case CHANGED:
-            // Notify only the default Inventory Service
-            inventoryShimDefaultListener = inventoryShimInternalListeners
-                    .get(GlobalConstants.DEFAULT.toString());
-            if (inventoryShimDefaultListener != null) {
-                inventoryShimDefaultListener.updateNode(node, type, props);
-            }
-            break;
-        default:
-            break;
+    private void notifyInventoryShimListener(Node node, UpdateType type, Set<Property> props) {
+        // Now notify other containers
+        Set<String> containers = (nodeContainerMap.get(node) == null) ? new HashSet<String>() : new HashSet<String>(
+                nodeContainerMap.get(node));
+        containers.add(GlobalConstants.DEFAULT.toString());
+        for (String container : containers) {
+            notifyInventoryShimInternalListener(container, node, type, props);
         }
 
         // Notify external listener
@@ -421,21 +428,19 @@ public class InventoryServiceShim implements IContainerListener,
             props.add(b);
         }
 
+        nodeProps.put(node, props);
         // Notify all internal and external listeners
         notifyInventoryShimListener(node, type, props);
     }
 
     private void removeNode(ISwitch sw) {
-        Node node;
-        try {
-            node = new Node(NodeIDType.OPENFLOW, sw.getId());
-        } catch (ConstructionException e) {
-            logger.error("{}", e.getMessage());
+        Node node = NodeCreator.createOFNode(sw.getId());
+        if(node == null) {
             return;
         }
-
+        removeNodeConnectorProps(node);
+        nodeProps.remove(node);
         UpdateType type = UpdateType.REMOVED;
-
         // Notify all internal and external listeners
         notifyInventoryShimListener(node, type, null);
     }
@@ -448,6 +453,18 @@ public class InventoryServiceShim implements IContainerListener,
         }
     }
 
+    private void removeNodeConnectorProps(Node node) {
+        List<NodeConnector> ncList = new ArrayList<NodeConnector>();
+        for (NodeConnector nc : nodeConnectorProps.keySet()) {
+            if (nc.getNode().equals(node)) {
+                ncList.add(nc);
+            }
+        }
+        for (NodeConnector nc : ncList) {
+            nodeConnectorProps.remove(nc);
+        }
+    }
+
     @Override
     public void descriptionStatisticsRefreshed(Long switchId, List<OFStatistics> descriptionStats) {
         Node node = NodeCreator.createOFNode(switchId);
index 3c02c1762875eceb1ba226f8b333584af9b852bf..bae49d511a2f853f61d428f0751ea7b231539831 100644 (file)
@@ -155,6 +155,20 @@ IInventoryShimExternalListener, CommandProvider {
         }
     }
 
+    private short getStatsQueueSize() {
+        String statsQueueSizeStr = System.getProperty("of.statsQueueSize");
+        short statsQueueSize = INITIAL_SIZE;
+        if (statsQueueSizeStr != null) {
+            try {
+                statsQueueSize = Short.parseShort(statsQueueSizeStr);
+                if (statsQueueSize <= 0) {
+                    statsQueueSize = INITIAL_SIZE;
+                }
+            } catch (Exception e) {
+            }
+        }
+        return statsQueueSize;
+    }
     /**
      * Function called by the dependency manager when all the required
      * dependencies are satisfied
@@ -166,8 +180,8 @@ IInventoryShimExternalListener, CommandProvider {
         portStatistics = new ConcurrentHashMap<Long, List<OFStatistics>>();
         tableStatistics = new ConcurrentHashMap<Long, List<OFStatistics>>();
         dummyList = new ArrayList<OFStatistics>(1);
+        pendingStatsRequests = new LinkedBlockingQueue<StatsRequest>(getStatsQueueSize());
         statisticsTimerTicks = new ConcurrentHashMap<Long, StatisticsTicks>(INITIAL_SIZE);
-        pendingStatsRequests = new LinkedBlockingQueue<StatsRequest>(INITIAL_SIZE);
         switchPortStatsUpdated = new LinkedBlockingQueue<Long>(INITIAL_SIZE);
         switchSupportsVendorExtStats = new ConcurrentHashMap<Long, Boolean>(INITIAL_SIZE);
         txRates = new HashMap<Long, Map<Short, TxRates>>(INITIAL_SIZE);
index c7439edc2e7b7b62bc3e7a0b13cc4ccb214dc894..6c26af2dc710e91eb8bcc6e11d9b4fef2bac8f14 100644 (file)
@@ -39,8 +39,8 @@ import org.slf4j.LoggerFactory;
 public class V6Match extends OFMatch implements Cloneable {
     private static final Logger logger = LoggerFactory.getLogger(V6Match.class);
     private static final long serialVersionUID = 1L;
-    protected InetAddress nwSrc;
-    protected InetAddress nwDst;
+    protected Inet6Address nwSrc;
+    protected Inet6Address nwDst;
     protected short inputPortMask;
     protected byte[] dataLayerSourceMask;
     protected byte[] dataLayerDestinationMask;
@@ -49,8 +49,6 @@ public class V6Match extends OFMatch implements Cloneable {
     protected short dataLayerTypeMask;
     protected byte networkTypeOfServiceMask;
     protected byte networkProtocolMask;
-    protected InetAddress networkSourceMask;
-    protected InetAddress networkDestinationMask;
     protected short transportSourceMask;
     protected short transportDestinationMask;
     protected short srcIPv6SubnetMaskbits;
@@ -135,8 +133,6 @@ public class V6Match extends OFMatch implements Cloneable {
         this.dataLayerTypeMask = 0;
         this.dataLayerVirtualLanMask = 0;
         this.dataLayerVirtualLanPriorityCodePointMask = 0;
-        this.networkDestinationMask = null;
-        this.networkSourceMask = null;
         this.networkTypeOfServiceMask = 0;
         this.networkProtocolMask = 0;
         this.transportSourceMask = 0;
@@ -163,33 +159,19 @@ public class V6Match extends OFMatch implements Cloneable {
         this.match_len = 0;
         this.pad_size = 0;
 
-        this.networkSourceMask = null;
         if (match.getNetworkSource() != 0) {
-            InetAddress address = null;
-            try {
-                address = InetAddress.getByAddress(ByteBuffer.allocate(4)
-                        .putInt(match.getNetworkSource()).array());
-            } catch (UnknownHostException e) {
-                logger.error("",e);
-            }
-            this.setNetworkSource(address, null);
+            InetAddress address = NetUtils.getInetAddress(match.getNetworkSource());
+            InetAddress mask = NetUtils.getInetNetworkMask(match.getNetworkSourceMaskLen(), false);
+            this.setNetworkDestination(address, mask);
         } else {
-            this.nwSrc = null;
             this.nwSrcState = MatchFieldState.MATCH_ABSENT;
         }
 
-        this.networkDestinationMask = null;
         if (match.getNetworkDestination() != 0) {
-            InetAddress address = null;
-            try {
-                address = InetAddress.getByAddress(ByteBuffer.allocate(4)
-                        .putInt(match.getNetworkDestination()).array());
-            } catch (UnknownHostException e) {
-                logger.error("",e);
-            }
-            this.setNetworkDestination(address, null);
+            InetAddress address = NetUtils.getInetAddress(match.getNetworkDestination());
+            InetAddress mask = NetUtils.getInetNetworkMask(match.getNetworkDestinationMaskLen(), false);
+            this.setNetworkDestination(address, mask);
         } else {
-            this.nwDst = null;
             this.nwDstState = MatchFieldState.MATCH_ABSENT;
         }
 
@@ -475,20 +457,23 @@ public class V6Match extends OFMatch implements Cloneable {
     @Override
     public void fromString(String match) throws IllegalArgumentException {
         if (match.equals("") || match.equalsIgnoreCase("any")
-                || match.equalsIgnoreCase("all") || match.equals("[]"))
+                || match.equalsIgnoreCase("all") || match.equals("[]")) {
             match = "OFMatch[]";
+        }
         String[] tokens = match.split("[\\[,\\]]");
         String[] values;
         int initArg = 0;
-        if (tokens[0].equals("OFMatch"))
+        if (tokens[0].equals("OFMatch")) {
             initArg = 1;
+        }
         this.wildcards = OFPFW_ALL;
         int i;
         for (i = initArg; i < tokens.length; i++) {
             values = tokens[i].split("=");
-            if (values.length != 2)
+            if (values.length != 2) {
                 throw new IllegalArgumentException("Token " + tokens[i]
                         + " does not have form 'key=value' parsing " + match);
+            }
             values[0] = values[0].toLowerCase(); // try to make this case insens
             if (values[0].equals(STR_IN_PORT) || values[0].equals("input_port")) {
                 this.inputPort = U16.t(Integer.valueOf(values[1]));
@@ -508,11 +493,12 @@ public class V6Match extends OFMatch implements Cloneable {
                 this.wildcards &= ~OFPFW_DL_SRC;
             } else if (values[0].equals(STR_DL_TYPE)
                     || values[0].equals("eth_type")) {
-                if (values[1].startsWith("0x"))
+                if (values[1].startsWith("0x")) {
                     this.dataLayerType = U16.t(Integer.valueOf(values[1]
                             .replaceFirst("0x", ""), 16));
-                else
+                } else {
                     this.dataLayerType = U16.t(Integer.valueOf(values[1]));
+                }
                 ethTypeState = MatchFieldState.MATCH_FIELD_ONLY;
                 match_len += 6;
             } else if (values[0].equals(STR_DL_VLAN)) {
@@ -526,36 +512,34 @@ public class V6Match extends OFMatch implements Cloneable {
             } else if (values[0].equals(STR_NW_DST)
                     || values[0].equals("ip_dst")) {
                 try {
+                    InetAddress address = null;
+                    InetAddress mask = null;
                     if (values[1].contains("/")) {
-                        String ipv6addr_wmask[] = values[1].split("/");
-                        this.nwDst = InetAddress.getByName(ipv6addr_wmask[0]);
-                        this.dstIPv6SubnetMaskbits = Short
-                                .valueOf(ipv6addr_wmask[1]);
-                        nwDstState = MatchFieldState.MATCH_FIELD_WITH_MASK;
-                        match_len += 36;
+                        String addressString[] = values[1].split("/");
+                        address = InetAddress.getByName(addressString[0]);
+                        int masklen = Integer.valueOf(addressString[1]);
+                        mask = NetUtils.getInetNetworkMask(masklen, address instanceof Inet6Address);
                     } else {
-                        this.nwDst = InetAddress.getByName(values[1]);
-                        nwDstState = MatchFieldState.MATCH_FIELD_ONLY;
-                        match_len += 20;
+                        address = InetAddress.getByName(values[1]);
                     }
+                    this.setNetworkDestination(address, mask);
                 } catch (UnknownHostException e) {
                     logger.error("",e);
                 }
             } else if (values[0].equals(STR_NW_SRC)
                     || values[0].equals("ip_src")) {
                 try {
+                    InetAddress address = null;
+                    InetAddress mask = null;
                     if (values[1].contains("/")) {
-                        String ipv6addr_wmask[] = values[1].split("/");
-                        this.nwSrc = InetAddress.getByName(ipv6addr_wmask[0]);
-                        this.srcIPv6SubnetMaskbits = Short
-                                .valueOf(ipv6addr_wmask[1]);
-                        nwSrcState = MatchFieldState.MATCH_FIELD_WITH_MASK;
-                        match_len += 36;
+                        String addressString[] = values[1].split("/");
+                        address = InetAddress.getByName(addressString[0]);
+                        int masklen = Integer.valueOf(addressString[1]);
+                        mask = NetUtils.getInetNetworkMask(masklen, address instanceof Inet6Address);
                     } else {
-                        this.nwSrc = InetAddress.getByName(values[1]);
-                        nwSrcState = MatchFieldState.MATCH_FIELD_ONLY;
-                        match_len += 20;
+                        address = InetAddress.getByName(values[1]);
                     }
+                    this.setNetworkSource(address, mask);
                 } catch (UnknownHostException e) {
                     logger.error("",e);
                 }
@@ -580,9 +564,10 @@ public class V6Match extends OFMatch implements Cloneable {
                 this.transportSource = U16.t(Integer.valueOf(values[1]));
                 tpSrcState = MatchFieldState.MATCH_FIELD_ONLY;
                 match_len += 6;
-            } else
+            } else {
                 throw new IllegalArgumentException("unknown token " + tokens[i]
                         + " parsing " + match);
+            }
         }
 
         /*
@@ -675,11 +660,12 @@ public class V6Match extends OFMatch implements Cloneable {
     }
 
     private void readInPort(ByteBuffer data, int nxmLen, boolean hasMask) {
-        if ((nxmLen != 2) || (data.remaining() < 2) || (hasMask))
+        if ((nxmLen != 2) || (data.remaining() < 2) || (hasMask)) {
             /*
              * mask is not allowed for inport port
              */
             return;
+        }
         super.setInputPort(data.getShort());
         this.inputPortState = MatchFieldState.MATCH_FIELD_ONLY;
         this.wildcards ^= (1 << 0); // Sync with 0F 1.0 Match
@@ -689,9 +675,9 @@ public class V6Match extends OFMatch implements Cloneable {
     private void readDataLinkDestination(ByteBuffer data, int nxmLen,
             boolean hasMask) {
         if (hasMask) {
-            if ((nxmLen != 2 * 6) || (data.remaining() < 2 * 6))
+            if ((nxmLen != 2 * 6) || (data.remaining() < 2 * 6)) {
                 return;
-            else {
+            else {
                 byte[] bytes = new byte[6];
                 data.get(bytes);
                 super.setDataLayerDestination(bytes);
@@ -701,9 +687,9 @@ public class V6Match extends OFMatch implements Cloneable {
                 this.match_len += 16;
             }
         } else {
-            if ((nxmLen != 6) || (data.remaining() < 6))
+            if ((nxmLen != 6) || (data.remaining() < 6)) {
                 return;
-            else {
+            else {
                 byte[] bytes = new byte[6];
                 data.get(bytes);
                 super.setDataLayerDestination(bytes);
@@ -718,8 +704,9 @@ public class V6Match extends OFMatch implements Cloneable {
         /*
          * mask is not allowed in data link source
          */
-        if ((nxmLen != 6) || (data.remaining() < 6) || (hasMask))
+        if ((nxmLen != 6) || (data.remaining() < 6) || (hasMask)) {
             return;
+        }
         byte[] bytes = new byte[6];
         data.get(bytes);
         super.setDataLayerSource(bytes);
@@ -732,8 +719,9 @@ public class V6Match extends OFMatch implements Cloneable {
         /*
          * mask is not allowed in ethertype
          */
-        if ((nxmLen != 2) || (data.remaining() < 2) || (hasMask))
+        if ((nxmLen != 2) || (data.remaining() < 2) || (hasMask)) {
             return;
+        }
         super.setDataLayerType(data.getShort());
         this.ethTypeState = MatchFieldState.MATCH_FIELD_ONLY;
         this.wildcards ^= (1 << 4); // Sync with 0F 1.0 Match
@@ -743,9 +731,9 @@ public class V6Match extends OFMatch implements Cloneable {
     private void readVlanTci(ByteBuffer data, int nxmLen, boolean hasMask) {
         short vlan_mask = 0xfff;
         if (hasMask) {
-            if ((nxmLen != 2 * 2) || (data.remaining() < 2 * 2))
+            if ((nxmLen != 2 * 2) || (data.remaining() < 2 * 2)) {
                 return;
-            else {
+            else {
                 short vlan = data.getShort();
                 vlan &= vlan_mask;
                 super.setDataLayerVirtualLan(vlan);
@@ -755,9 +743,9 @@ public class V6Match extends OFMatch implements Cloneable {
                 this.wildcards ^= (1 << 20);
             }
         } else {
-            if ((nxmLen != 2) || (data.remaining() < 2))
+            if ((nxmLen != 2) || (data.remaining() < 2)) {
                 return;
-            else {
+            else {
                 short vlan = data.getShort();
                 vlan &= vlan_mask;
                 super.setDataLayerVirtualLan(vlan);
@@ -773,8 +761,9 @@ public class V6Match extends OFMatch implements Cloneable {
         /*
          * mask is not allowed in IP TOS
          */
-        if ((nxmLen != 1) || (data.remaining() < 1) || (hasMask))
+        if ((nxmLen != 1) || (data.remaining() < 1) || (hasMask)) {
             return;
+        }
         super.setNetworkTypeOfService(data.get());
         this.nwTosState = MatchFieldState.MATCH_FIELD_ONLY;
         this.match_len += 5;
@@ -785,8 +774,9 @@ public class V6Match extends OFMatch implements Cloneable {
         /*
          * mask is not allowed in IP protocol
          */
-        if ((nxmLen != 1) || (data.remaining() < 1) || (hasMask))
+        if ((nxmLen != 1) || (data.remaining() < 1) || (hasMask)) {
             return;
+        }
         super.setNetworkProtocol(data.get());
         this.nwProtoState = MatchFieldState.MATCH_FIELD_ONLY;
         this.match_len += 5;
@@ -795,41 +785,31 @@ public class V6Match extends OFMatch implements Cloneable {
 
     private void readIpv4Src(ByteBuffer data, int nxmLen, boolean hasMask) {
         if (hasMask) {
-            if ((nxmLen != 2 * 4) || (data.remaining() < 2 * 4))
+            if ((nxmLen != 2 * 4) || (data.remaining() < 2 * 4)) {
                 return;
-            else {
+            else {
                 byte[] sbytes = new byte[4];
                 data.get(sbytes);
-                try {
-                    this.nwSrc = InetAddress.getByAddress(sbytes);
-                } catch (UnknownHostException e) {
-                    return;
-                }
+                // For compatibility, let's set the IPv4 in the parent OFMatch
+                int address = NetUtils.byteArray4ToInt(sbytes);
+                super.setNetworkSource(address);
                 byte[] mbytes = new byte[4];
                 data.get(mbytes);
-                try {
-                    this.networkSourceMask = InetAddress.getByAddress(mbytes);
-                } catch (UnknownHostException e) {
-                    return;
-                }
                 this.nwSrcState = MatchFieldState.MATCH_FIELD_WITH_MASK;
                 this.match_len += 12;
                 int prefixlen = getNetworkMaskPrefixLength(mbytes);
                 this.wildcards ^= (((1 << 6) - 1) << 8); // Sync with 0F 1.0 Match
                 this.wildcards |= ((32 - prefixlen) << 8); // Sync with 0F 1.0 Match
-
             }
         } else {
-            if ((nxmLen != 4) || (data.remaining() < 4))
+            if ((nxmLen != 4) || (data.remaining() < 4)) {
                 return;
-            else {
+            else {
                 byte[] sbytes = new byte[4];
                 data.get(sbytes);
-                try {
-                    this.nwSrc = InetAddress.getByAddress(sbytes);
-                } catch (UnknownHostException e) {
-                    return;
-                }
+                // For compatibility, let's also set the IPv4 in the parent OFMatch
+                int address = NetUtils.byteArray4ToInt(sbytes);
+                super.setNetworkSource(address);
                 this.nwSrcState = MatchFieldState.MATCH_FIELD_ONLY;
                 this.match_len += 8;
                 this.wildcards ^= (((1 << 6) - 1) << 8); // Sync with 0F 1.0 Match
@@ -839,24 +819,16 @@ public class V6Match extends OFMatch implements Cloneable {
 
     private void readIpv4Dst(ByteBuffer data, int nxmLen, boolean hasMask) {
         if (hasMask) {
-            if ((nxmLen != 2 * 4) || (data.remaining() < 2 * 4))
+            if ((nxmLen != 2 * 4) || (data.remaining() < 2 * 4)) {
                 return;
-            else {
+            else {
                 byte[] dbytes = new byte[4];
                 data.get(dbytes);
-                try {
-                    this.nwDst = InetAddress.getByAddress(dbytes);
-                } catch (UnknownHostException e) {
-                    return;
-                }
+                // For compatibility, let's also set the IPv4 in the parent OFMatch
+                int address = NetUtils.byteArray4ToInt(dbytes);
+                super.setNetworkDestination(address);
                 byte[] mbytes = new byte[4];
                 data.get(mbytes);
-                try {
-                    this.networkDestinationMask = InetAddress
-                            .getByAddress(mbytes);
-                } catch (UnknownHostException e) {
-                    return;
-                }
                 this.nwDstState = MatchFieldState.MATCH_FIELD_WITH_MASK;
                 this.match_len += 12;
                 int prefixlen = getNetworkMaskPrefixLength(mbytes);
@@ -864,16 +836,13 @@ public class V6Match extends OFMatch implements Cloneable {
                 this.wildcards |= ((32 - prefixlen) << 14); // Sync with 0F 1.0 Match
             }
         } else {
-            if ((nxmLen != 4) || (data.remaining() < 4))
+            if ((nxmLen != 4) || (data.remaining() < 4)) {
                 return;
-            else {
+            else {
                 byte[] dbytes = new byte[4];
                 data.get(dbytes);
-                try {
-                    this.nwDst = InetAddress.getByAddress(dbytes);
-                } catch (UnknownHostException e) {
-                    return;
-                }
+                int address = NetUtils.byteArray4ToInt(dbytes);
+                super.setNetworkDestination(address);
                 this.nwDstState = MatchFieldState.MATCH_FIELD_ONLY;
                 this.wildcards ^= (((1 << 6) - 1) << 14); // Sync with 0F 1.0 Match
                 this.match_len += 8;
@@ -885,8 +854,9 @@ public class V6Match extends OFMatch implements Cloneable {
         /*
          * mask is not allowed in TCP SRC
          */
-        if ((nxmLen != 2) || (data.remaining() < 2) || (hasMask))
+        if ((nxmLen != 2) || (data.remaining() < 2) || (hasMask)) {
             return;
+        }
         super.setTransportSource(data.getShort());
         this.tpSrcState = MatchFieldState.MATCH_FIELD_ONLY;
         this.match_len += 6;
@@ -897,8 +867,9 @@ public class V6Match extends OFMatch implements Cloneable {
         /*
          * mask is not allowed in TCP DST
          */
-        if ((nxmLen != 2) || (data.remaining() < 2) || (hasMask))
+        if ((nxmLen != 2) || (data.remaining() < 2) || (hasMask)) {
             return;
+        }
         super.setTransportDestination(data.getShort());
         this.tpDstState = MatchFieldState.MATCH_FIELD_ONLY;
         this.match_len += 6;
@@ -909,8 +880,9 @@ public class V6Match extends OFMatch implements Cloneable {
         /*
          * mask is not allowed in UDP SRC
          */
-        if ((nxmLen != 2) || (data.remaining() < 2) || (hasMask))
+        if ((nxmLen != 2) || (data.remaining() < 2) || (hasMask)) {
             return;
+        }
         super.setTransportSource(data.getShort());
         this.tpSrcState = MatchFieldState.MATCH_FIELD_ONLY;
         this.match_len += 6;
@@ -921,8 +893,9 @@ public class V6Match extends OFMatch implements Cloneable {
         /*
          * mask is not allowed in UDP DST
          */
-        if ((nxmLen != 2) || (data.remaining() < 2) || (hasMask))
+        if ((nxmLen != 2) || (data.remaining() < 2) || (hasMask)) {
             return;
+        }
         super.setTransportDestination(data.getShort());
         this.tpDstState = MatchFieldState.MATCH_FIELD_ONLY;
         this.match_len += 6;
@@ -931,34 +904,30 @@ public class V6Match extends OFMatch implements Cloneable {
 
     private void readIpv6Src(ByteBuffer data, int nxmLen, boolean hasMask) {
         if (hasMask) {
-            if ((nxmLen != 2 * 16) || (data.remaining() < 2 * 16))
+            if ((nxmLen != 2 * 16) || (data.remaining() < 2 * 16)) {
                 return;
-            else {
+            else {
                 byte[] sbytes = new byte[16];
                 data.get(sbytes);
                 try {
-                    this.nwSrc = InetAddress.getByAddress(sbytes);
+                    this.nwSrc = (Inet6Address) InetAddress.getByAddress(sbytes);
                 } catch (UnknownHostException e) {
                     return;
                 }
                 byte[] mbytes = new byte[16];
                 data.get(mbytes);
-                try {
-                    this.networkSourceMask = InetAddress.getByAddress(mbytes);
-                } catch (UnknownHostException e) {
-                    return;
-                }
+                this.srcIPv6SubnetMaskbits = (short)NetUtils.getSubnetMaskLength(mbytes);
                 this.nwSrcState = MatchFieldState.MATCH_FIELD_WITH_MASK;
                 this.match_len += 36;
             }
         } else {
-            if ((nxmLen != 16) || (data.remaining() < 16))
+            if ((nxmLen != 16) || (data.remaining() < 16)) {
                 return;
-            else {
+            else {
                 byte[] sbytes = new byte[16];
                 data.get(sbytes);
                 try {
-                    this.nwSrc = InetAddress.getByAddress(sbytes);
+                    this.nwSrc = (Inet6Address) InetAddress.getByAddress(sbytes);
                 } catch (UnknownHostException e) {
                     return;
                 }
@@ -970,35 +939,30 @@ public class V6Match extends OFMatch implements Cloneable {
 
     private void readIpv6Dst(ByteBuffer data, int nxmLen, boolean hasMask) {
         if (hasMask) {
-            if ((nxmLen != 2 * 16) || (data.remaining() < 2 * 16))
+            if ((nxmLen != 2 * 16) || (data.remaining() < 2 * 16)) {
                 return;
-            else {
+            else {
                 byte[] dbytes = new byte[16];
                 data.get(dbytes);
                 try {
-                    this.nwDst = InetAddress.getByAddress(dbytes);
+                    this.nwDst = (Inet6Address) InetAddress.getByAddress(dbytes);
                 } catch (UnknownHostException e) {
                     return;
                 }
                 byte[] mbytes = new byte[16];
                 data.get(mbytes);
-                try {
-                    this.networkDestinationMask = InetAddress
-                            .getByAddress(mbytes);
-                } catch (UnknownHostException e) {
-                    return;
-                }
+                this.dstIPv6SubnetMaskbits = (short)NetUtils.getSubnetMaskLength(mbytes);
                 this.nwDstState = MatchFieldState.MATCH_FIELD_WITH_MASK;
                 this.match_len += 36;
             }
         } else {
-            if ((nxmLen != 16) || (data.remaining() < 16))
+            if ((nxmLen != 16) || (data.remaining() < 16)) {
                 return;
-            else {
+            else {
                 byte[] dbytes = new byte[16];
                 data.get(dbytes);
                 try {
-                    this.nwDst = InetAddress.getByAddress(dbytes);
+                    this.nwDst = (Inet6Address) InetAddress.getByAddress(dbytes);
                 } catch (UnknownHostException e) {
                     return;
                 }
@@ -1021,8 +985,6 @@ public class V6Match extends OFMatch implements Cloneable {
                 + ", dataLayerTypeMask=" + dataLayerTypeMask
                 + ", networkTypeOfServiceMask=" + networkTypeOfServiceMask
                 + ", networkProtocolMask=" + networkProtocolMask
-                + ", networkSourceMask=" + networkSourceMask
-                + ", networkDestinationMask=" + networkDestinationMask
                 + ", transportSourceMask=" + transportSourceMask
                 + ", transportDestinationMask=" + transportDestinationMask
                 + ", srcIPv6SubnetMaskbits=" + srcIPv6SubnetMaskbits
@@ -1151,10 +1113,10 @@ public class V6Match extends OFMatch implements Cloneable {
         V6Match ret = (V6Match) super.clone();
         try {
             if (this.nwSrc != null) {
-                ret.nwSrc = InetAddress.getByAddress(this.nwSrc.getAddress());
+                ret.nwSrc = (Inet6Address) InetAddress.getByAddress(this.nwSrc.getAddress());
             }
             if (this.nwDst != null) {
-                ret.nwDst = InetAddress.getByAddress(this.nwDst.getAddress());
+                ret.nwDst = (Inet6Address) InetAddress.getByAddress(this.nwDst.getAddress());
             }
             return ret;
         } catch (UnknownHostException e) {
@@ -1168,37 +1130,17 @@ public class V6Match extends OFMatch implements Cloneable {
      * @return
      */
 
-    public InetAddress getNetworkDest() {
+    public Inet6Address getNetworkDest() {
         return this.nwDst;
     }
 
-    /**
-     * Get nw_src
-     *
-     * @return
-     */
-
-    public void setNetworkSrc(InetAddress address) {
-        nwSrc = address;
-    }
-
-    /**
-     * Set nw_dst
-     *
-     * @return
-     */
-
-    public void setNetworkDest(InetAddress address) {
-        nwDst = address;
-    }
-
     /**
      * Set nw_src
      *
      * @return
      */
 
-    public InetAddress getNetworkSrc() {
+    public Inet6Address getNetworkSrc() {
         return this.nwSrc;
     }
 
@@ -1303,35 +1245,63 @@ public class V6Match extends OFMatch implements Cloneable {
         this.match_len += 5;
     }
 
-    public InetAddress getNetworkSourceMask() {
-        return networkSourceMask;
+    public Inet6Address getNetworkSourceMask() {
+        return (this.nwSrcState == MatchFieldState.MATCH_FIELD_WITH_MASK) ? (Inet6Address) NetUtils.getInetNetworkMask(
+                this.srcIPv6SubnetMaskbits, true) : null;
     }
 
     public void setNetworkSource(InetAddress address, InetAddress mask) {
-        this.nwSrc = address;
-        if (mask == null) {
-            this.nwSrcState = MatchFieldState.MATCH_FIELD_ONLY;
-            this.match_len += (address instanceof Inet6Address) ? 20 : 8;
+        if (address instanceof Inet6Address) {
+            this.nwSrc = (Inet6Address) address;
+            if (mask == null) {
+                this.nwSrcState = MatchFieldState.MATCH_FIELD_ONLY;
+                this.match_len += (address instanceof Inet6Address) ? 20 : 8;
+            } else {
+                this.srcIPv6SubnetMaskbits = (short)NetUtils.getSubnetMaskLength(mask);
+                this.nwSrcState = MatchFieldState.MATCH_FIELD_WITH_MASK;
+                this.match_len += (address instanceof Inet6Address) ? 36 : 12;
+            }
         } else {
-            this.networkSourceMask = mask;
-            this.nwSrcState = MatchFieldState.MATCH_FIELD_WITH_MASK;
-            this.match_len += (address instanceof Inet6Address) ? 36 : 12;
+            super.setNetworkSource(NetUtils.byteArray4ToInt(address.getAddress()));
+            this.wildcards ^= (((1 << 6) - 1) << 8);
+            if (mask == null) {
+                this.nwSrcState = MatchFieldState.MATCH_FIELD_ONLY;
+                this.match_len += 8;
+            } else {
+                this.nwSrcState = MatchFieldState.MATCH_FIELD_WITH_MASK;
+                this.match_len += 12;
+                this.wildcards |= ((32 - NetUtils.getSubnetMaskLength(mask)) << 8);
+            }
         }
     }
 
-    public InetAddress getNetworkDestinationMask() {
-        return networkDestinationMask;
+    public Inet6Address getNetworkDestinationMask() {
+        return (this.nwDstState == MatchFieldState.MATCH_FIELD_WITH_MASK) ? (Inet6Address) NetUtils.getInetNetworkMask(
+                this.dstIPv6SubnetMaskbits, true) : null;
     }
 
     public void setNetworkDestination(InetAddress address, InetAddress mask) {
-        this.nwDst = address;
-        if (mask == null) {
-            this.nwDstState = MatchFieldState.MATCH_FIELD_ONLY;
-            this.match_len += (address instanceof Inet6Address) ? 20 : 8;
+        if (address instanceof Inet6Address) {
+            this.nwDst = (Inet6Address) address;
+            if (mask == null) {
+                this.nwDstState = MatchFieldState.MATCH_FIELD_ONLY;
+                this.match_len += (address instanceof Inet6Address) ? 20 : 8;
+            } else {
+                this.dstIPv6SubnetMaskbits = (short)NetUtils.getSubnetMaskLength(mask);
+                this.nwDstState = MatchFieldState.MATCH_FIELD_WITH_MASK;
+                this.match_len += (address instanceof Inet6Address) ? 36 : 12;
+            }
         } else {
-            this.networkDestinationMask = mask;
-            this.nwDstState = MatchFieldState.MATCH_FIELD_WITH_MASK;
-            this.match_len += (address instanceof Inet6Address) ? 36 : 12;
+            this.setNetworkDestination(NetUtils.byteArray4ToInt(address.getAddress()));
+            this.wildcards ^= (((1 << 6) - 1) << 14);
+            if (mask == null) {
+                this.nwDstState = MatchFieldState.MATCH_FIELD_ONLY;
+                this.match_len += 8;
+            } else {
+                this.nwDstState = MatchFieldState.MATCH_FIELD_WITH_MASK;
+                this.match_len += 12;
+                this.wildcards |= ((32 - NetUtils.getSubnetMaskLength(mask)) << 14);
+            }
         }
     }
 
@@ -1387,9 +1357,7 @@ public class V6Match extends OFMatch implements Cloneable {
         result = prime * result + inputPortMask;
         result = prime * result + ((inputPortState == null) ? 0 : inputPortState.hashCode());
         result = prime * result + match_len;
-        result = prime * result + ((networkDestinationMask == null) ? 0 : networkDestinationMask.hashCode());
         result = prime * result + networkProtocolMask;
-        result = prime * result + ((networkSourceMask == null) ? 0 : networkSourceMask.hashCode());
         result = prime * result + networkTypeOfServiceMask;
         result = prime * result + ((nwDst == null) ? 0 : nwDst.hashCode());
         result = prime * result + ((nwDstState == null) ? 0 : nwDstState.hashCode());
@@ -1408,83 +1376,105 @@ public class V6Match extends OFMatch implements Cloneable {
 
     @Override
     public boolean equals(Object obj) {
-        if (this == obj)
+        if (this == obj) {
             return true;
-        if (!super.equals(obj))
+        }
+        if (!super.equals(obj)) {
             return false;
-        if (getClass() != obj.getClass())
+        }
+        if (getClass() != obj.getClass()) {
             return false;
+        }
         V6Match other = (V6Match) obj;
-        if (!Arrays.equals(dataLayerDestinationMask, other.dataLayerDestinationMask))
+        if (!Arrays.equals(dataLayerDestinationMask, other.dataLayerDestinationMask)) {
             return false;
-        if (!Arrays.equals(dataLayerSourceMask, other.dataLayerSourceMask))
-            return false;
-        if (dataLayerTypeMask != other.dataLayerTypeMask)
-            return false;
-        if (dataLayerVirtualLanMask != other.dataLayerVirtualLanMask)
+        }
+        if (!Arrays.equals(dataLayerSourceMask, other.dataLayerSourceMask)) {
             return false;
-        if (dataLayerVirtualLanPriorityCodePointMask != other.dataLayerVirtualLanPriorityCodePointMask)
+        }
+        if (dataLayerTypeMask != other.dataLayerTypeMask) {
             return false;
-        if (dlDestState != other.dlDestState)
+        }
+        if (dataLayerVirtualLanMask != other.dataLayerVirtualLanMask) {
             return false;
-        if (dlSourceState != other.dlSourceState)
+        }
+        if (dataLayerVirtualLanPriorityCodePointMask != other.dataLayerVirtualLanPriorityCodePointMask) {
             return false;
-        if (dlVlanState != other.dlVlanState)
+        }
+        if (dlDestState != other.dlDestState) {
             return false;
-        if (dstIPv6SubnetMaskbits != other.dstIPv6SubnetMaskbits)
+        }
+        if (dlSourceState != other.dlSourceState) {
             return false;
-        if (ethTypeState != other.ethTypeState)
+        }
+        if (dlVlanState != other.dlVlanState) {
             return false;
-        if (inputPortMask != other.inputPortMask)
+        }
+        if (dstIPv6SubnetMaskbits != other.dstIPv6SubnetMaskbits) {
             return false;
-        if (inputPortState != other.inputPortState)
+        }
+        if (ethTypeState != other.ethTypeState) {
             return false;
-        if (match_len != other.match_len)
+        }
+        if (inputPortMask != other.inputPortMask) {
             return false;
-        if (networkDestinationMask == null) {
-            if (other.networkDestinationMask != null)
-                return false;
-        } else if (!networkDestinationMask.equals(other.networkDestinationMask))
+        }
+        if (inputPortState != other.inputPortState) {
             return false;
-        if (networkProtocolMask != other.networkProtocolMask)
+        }
+        if (match_len != other.match_len) {
             return false;
-        if (networkSourceMask == null) {
-            if (other.networkSourceMask != null)
-                return false;
-        } else if (!networkSourceMask.equals(other.networkSourceMask))
+        }
+        if (networkProtocolMask != other.networkProtocolMask) {
             return false;
-        if (networkTypeOfServiceMask != other.networkTypeOfServiceMask)
+        }
+        if (networkTypeOfServiceMask != other.networkTypeOfServiceMask) {
             return false;
+        }
         if (nwDst == null) {
-            if (other.nwDst != null)
+            if (other.nwDst != null) {
                 return false;
-        } else if (!nwDst.equals(other.nwDst))
+            }
+        } else if (!nwDst.equals(other.nwDst)) {
             return false;
-        if (nwDstState != other.nwDstState)
+        }
+        if (nwDstState != other.nwDstState) {
             return false;
-        if (nwProtoState != other.nwProtoState)
+        }
+        if (nwProtoState != other.nwProtoState) {
             return false;
+        }
         if (nwSrc == null) {
-            if (other.nwSrc != null)
+            if (other.nwSrc != null) {
                 return false;
-        } else if (!nwSrc.equals(other.nwSrc))
+            }
+        } else if (!nwSrc.equals(other.nwSrc)) {
             return false;
-        if (nwSrcState != other.nwSrcState)
+        }
+        if (nwSrcState != other.nwSrcState) {
             return false;
-        if (nwTosState != other.nwTosState)
+        }
+        if (nwTosState != other.nwTosState) {
             return false;
-        if (pad_size != other.pad_size)
+        }
+        if (pad_size != other.pad_size) {
             return false;
-        if (srcIPv6SubnetMaskbits != other.srcIPv6SubnetMaskbits)
+        }
+        if (srcIPv6SubnetMaskbits != other.srcIPv6SubnetMaskbits) {
             return false;
-        if (tpDstState != other.tpDstState)
+        }
+        if (tpDstState != other.tpDstState) {
             return false;
-        if (tpSrcState != other.tpSrcState)
+        }
+        if (tpSrcState != other.tpSrcState) {
             return false;
-        if (transportDestinationMask != other.transportDestinationMask)
+        }
+        if (transportDestinationMask != other.transportDestinationMask) {
             return false;
-        if (transportSourceMask != other.transportSourceMask)
+        }
+        if (transportSourceMask != other.transportSourceMask) {
             return false;
+        }
         return true;
     }
 }
index 75f6a83a327fb9daf9bad619091c083cad8cc1ab..6afaf5f67531ace92c1cebf282bc5d2d632c6773 100644 (file)
@@ -89,9 +89,10 @@ public class V6ExtensionTest {
                 match3.getDataLayerSource()));
         Assert.assertTrue(Arrays.equals(match.getDataLayerDestination(),
                 match3.getDataLayerDestination()));
-        Assert.assertTrue(match.getNetworkSrc().equals(match3.getNetworkSrc()));
-        Assert.assertTrue(match.getNetworkDest()
-                .equals(match3.getNetworkDest()));
+        Assert.assertNull(match.getNetworkSrc());
+        Assert.assertNull(match3.getNetworkSrc());
+        Assert.assertNull(match.getNetworkDest());
+        Assert.assertNull(match3.getNetworkDest());
         Assert.assertTrue(match.getDataLayerVirtualLan() == match3
                 .getDataLayerVirtualLan());
         Assert.assertTrue(match.getDataLayerVirtualLanPriorityCodePoint() == match3
index 66882af5d3098d95b97fb7eee530ce57d834974c..de77837c34a1472249b7fe69cd9ac64d10ba129a 100644 (file)
@@ -152,6 +152,11 @@ abstract public class ComponentActivatorAbstractBase implements
 
         @Override
         public void stopped(Component component) {
+            // do nothing
+        }
+
+        @Override
+        public void stopping(Component component) {
             if (component == null) {
                 return;
             }
@@ -160,11 +165,6 @@ abstract public class ComponentActivatorAbstractBase implements
                     { Component.class }, {} }, new Object[][] { { component },
                     {} });
         }
-
-        @Override
-        public void stopping(Component component) {
-            // do nothing
-        }
     }
 
     /**
index 4f3cbbd54b81967285e0dd2924bb1e57df2bb1f9..3b8a2952164eafb0cf463208d06cc29a182e2d6f 100644 (file)
@@ -9,7 +9,6 @@
 package org.opendaylight.controller.sal.match;
 
 import java.io.Serializable;
-
 import javax.xml.bind.annotation.XmlAccessType;
 import javax.xml.bind.annotation.XmlAccessorType;
 import javax.xml.bind.annotation.XmlElement;
@@ -208,6 +207,6 @@ public class MatchField implements Cloneable, Serializable {
         if (type != other.type) {
             return false;
         }
-        return (type.equalValues(this.value, other.value) && type.equalMasks(this.mask, other.mask));
+        return type.equals(this.value, other.value, this.mask, other.mask);
     }
 }
index bb5e0079b7134ed909dccf0280b95c786e1b0ebd..85e505671ef177627c84bff640f2a7596d66b441 100644 (file)
@@ -8,7 +8,7 @@
 
 package org.opendaylight.controller.sal.match;
 
-import java.net.Inet6Address;
+import java.net.Inet4Address;
 import java.net.InetAddress;
 import java.util.Arrays;
 
@@ -242,8 +242,12 @@ public enum MatchType {
             break;
         case NW_SRC:
         case NW_DST:
-            result = prime * result + ((v == null)? 0 : v.hashCode());
-            result = prime * result + ((m == null)? NetUtils.gethighestIP(v instanceof Inet6Address).hashCode() : m.hashCode());
+            // Hash code has to take into account only prefix address
+            InetAddress ip = (InetAddress) v;
+            int maskLen = (m == null) ? ((ip instanceof Inet4Address) ? 32 : 128) : NetUtils
+                    .getSubnetMaskLength((InetAddress) m);
+            InetAddress prefix = NetUtils.getSubnetPrefix(ip, maskLen);
+            result = prime * result + ((v == null)? 0 : prefix.hashCode());
             break;
         default:
             result = prime * result + ((v == null)? 0 : v.hashCode());
@@ -278,14 +282,10 @@ public enum MatchType {
              * For network address mask, network node may return full mask for
              * flows the controller generated with a null mask object
              */
-            byte maskBytes[] = null;
-            if (a == null) {
-                maskBytes = ((InetAddress) b).getAddress();
-            } else if (b == null) {
-                maskBytes = ((InetAddress) a).getAddress();
-            }
-            if (maskBytes != null) {
-                return (NetUtils.getSubnetMaskLength(maskBytes) == 0);
+            if (a == null || b == null) {
+                InetAddress mask = (a == null) ? (InetAddress) b : (InetAddress) a;
+                int maxLength = (mask instanceof Inet4Address) ? 32 : 128;
+                return (NetUtils.getSubnetMaskLength(mask) == maxLength);
             }
         default:
             if (a == null) {
@@ -294,4 +294,23 @@ public enum MatchType {
             return a.equals(b);
         }
     }
+
+    public boolean equals(Object value1, Object value2, Object mask1, Object mask2) {
+        switch (this) {
+        case NW_SRC:
+        case NW_DST:
+            // Equality to be checked against prefix addresses
+            InetAddress thisIP = (InetAddress) value1;
+            int thisMaskLen = (mask1 == null) ? ((thisIP instanceof Inet4Address) ? 32 : 128) : NetUtils
+                    .getSubnetMaskLength((InetAddress) mask1);
+            InetAddress otherIP = (InetAddress) value2;
+            int otherMaskLen = (mask2 == null) ? ((otherIP instanceof Inet4Address) ? 32 : 128) : NetUtils
+                    .getSubnetMaskLength((InetAddress) mask2);
+
+            return NetUtils.getSubnetPrefix(thisIP, thisMaskLen)
+                    .equals(NetUtils.getSubnetPrefix(otherIP, otherMaskLen));
+        default:
+            return (this.equalValues(value1, value2) && this.equalMasks(mask1, mask2));
+        }
+    }
 }
index 1e2f4277c1f4035b873c61502a43bdc1e6d6fe4c..a0ea67a91ac63aab6305209792d119f6e88d6d08 100644 (file)
@@ -47,6 +47,10 @@ public class IPv4 extends Packet {
     private static final String DIP = "DestinationIPAddress";
     private static final String OPTIONS = "Options";
 
+    private static final int UNIT_SIZE_SHIFT = 2;
+    private static final int UNIT_SIZE = (1 << UNIT_SIZE_SHIFT);
+    private static final int MIN_HEADER_SIZE = 20;
+
     public static final Map<Byte, Class<? extends Packet>> protocolClassMap;
     static {
         protocolClassMap = new HashMap<Byte, Class<? extends Packet>>();
@@ -145,12 +149,7 @@ public class IPv4 extends Packet {
     public int getHeaderSize() {
         int headerLen = this.getHeaderLen();
         if (headerLen == 0) {
-            headerLen = 20;
-        }
-
-        byte[] options = hdrFieldsMap.get(OPTIONS);
-        if (options != null) {
-            headerLen += options.length;
+            headerLen = MIN_HEADER_SIZE;
         }
 
         return headerLen * NetUtils.NumBitsInAByte;
@@ -260,6 +259,10 @@ public class IPv4 extends Packet {
     public void setHeaderField(String headerField, byte[] readValue) {
         if (headerField.equals(PROTOCOL)) {
             payloadClass = protocolClassMap.get(readValue[0]);
+        } else if (headerField.equals(OPTIONS) &&
+                   (readValue == null || readValue.length == 0)) {
+            hdrFieldsMap.remove(headerField);
+            return;
         }
         hdrFieldsMap.put(headerField, readValue);
     }
@@ -434,8 +437,23 @@ public class IPv4 extends Packet {
      * @return IPv4
      */
     public IPv4 setOptions(byte[] options) {
-        fieldValues.put(OPTIONS, options);
-        byte newIHL = (byte) (5 + options.length);
+        byte newIHL = (byte)(MIN_HEADER_SIZE >>> UNIT_SIZE_SHIFT);
+        if (options == null || options.length == 0) {
+            fieldValues.remove(OPTIONS);
+        } else {
+            int len = options.length;
+            int rlen = (len + (UNIT_SIZE - 1)) & ~(UNIT_SIZE - 1);
+            if (rlen > len) {
+                // Padding is required.
+                byte[] newopt = new byte[rlen];
+                System.arraycopy(options, 0, newopt, 0, len);
+                options = newopt;
+                len = rlen;
+            }
+            fieldValues.put(OPTIONS, options);
+            newIHL += (len >>> UNIT_SIZE_SHIFT);
+        }
+
         setHeaderLength(newIHL);
 
         return this;
@@ -477,15 +495,13 @@ public class IPv4 extends Packet {
     @Override
     /**
      * Gets the number of bits for the fieldname specified
-     * If the fieldname has variable length like "Options", then this value is computed using the
-     * options length and the header length
+     * If the fieldname has variable length like "Options", then this value is computed using the header length
      * @param fieldname - String
      * @return number of bits for fieldname - int
      */
     public int getfieldnumBits(String fieldName) {
         if (fieldName.equals(OPTIONS)) {
-            byte[] options = getOptions();
-            return ((options == null) ? 0 : (options.length - getHeaderLen()));
+            return (getHeaderLen() - MIN_HEADER_SIZE) * NetUtils.NumBitsInAByte;
         }
         return hdrFieldCoordMap.get(fieldName).getRight();
     }
index 4b42cb7669d5dca28b343774a9c07d841b3c1645..6a3a42fbb9ba52b5414937027d53788ed5058c9e 100644 (file)
@@ -8,6 +8,7 @@
 
 package org.opendaylight.controller.sal.utils;
 
+import java.net.Inet4Address;
 import java.net.Inet6Address;
 import java.net.InetAddress;
 import java.net.UnknownHostException;
@@ -41,7 +42,7 @@ public abstract class NetUtils {
     /**
      * Constant holding the broadcast MAC address
      */
-    public static byte[] BroadcastMACAddr = {-1, -1, -1, -1, -1, -1};
+    private static final byte[] BroadcastMACAddr = {-1, -1, -1, -1, -1, -1};
 
     /**
      * Converts a 4 bytes array into an integer number
@@ -144,46 +145,44 @@ public abstract class NetUtils {
     }
 
     /**
-     * Returns the number of contiguous bits belonging to the subnet, that have
-     * to be masked out Example: A prefix network byte mask of ff.ff.ff.00 will
-     * give a subnet mask length of 8, while ff.00.00.00 will return a subnet
-     * mask length of 24. If the passed prefixMask object is null, 0 is returned
+     * Returns the prefix size in bits of the specified subnet mask. Example:
+     * For the subnet mask ff.ff.ff.e0 it returns 25 while for ff.00.00.00 it
+     * returns 8. If the passed subnetMask array is null, 0 is returned.
      *
-     * @param prefixMask
-     *            the prefix mask as byte array
-     * @return the length of the prefix network mask
+     * @param subnetMask
+     *            the subnet mask as byte array
+     * @return the prefix length as number of bits
      */
-    public static int getSubnetMaskLength(byte[] prefixMask) {
+    public static int getSubnetMaskLength(byte[] subnetMask) {
         int maskLength = 0;
-        if (prefixMask != null) {
-            // Create bit mask
-            int intMask = 0;
-            int numBytes = prefixMask.length;
-            for (int i = 0; i < numBytes; i++) {
-                intMask |= (prefixMask[i] & 0xff) << (8 * (numBytes - 1 - i));
+        if (subnetMask != null && (subnetMask.length == 4 || subnetMask.length == 16)) {
+            int index = 0;
+            while (index < subnetMask.length && subnetMask[index] == (byte) 0xFF) {
+                maskLength += NetUtils.NumBitsInAByte;
+                index++;
             }
-
-            int bit = 1;
-            while (((intMask & bit) == 0) && (maskLength <= (numBytes * 8))) {
-                maskLength += 1;
-                bit = bit << 1;
+            if (index != subnetMask.length) {
+                int bits = NetUtils.NumBitsInAByte - 1;
+                while (bits >= 0 && (subnetMask[index] & 1 << bits)  != 0) {
+                    bits--;
+                    maskLength++;
+                }
             }
         }
         return maskLength;
     }
 
     /**
-     * Returns the number of contiguous bits belonging to the subnet, that have
-     * to be masked out Example: A prefix network byte mask of ff.ff.ff.00 will
-     * give a subnet mask length of 8, while ff.00.00.00 will return a subnet
-     * mask length of 24 If the passed prefixMask object is null, 0 is returned
+     * Returns the prefix size in bits of the specified subnet mask. Example:
+     * For the subnet mask 255.255.255.128 it returns 25 while for 255.0.0.0 it
+     * returns 8. If the passed subnetMask object is null, 0 is returned
      *
-     * @param prefixMask
-     *            the prefix mask as InetAddress
-     * @return the length of the prefix network mask
+     * @param subnetMask
+     *            the subnet mask as InetAddress
+     * @return the prefix length as number of bits
      */
-    public static int getSubnetMaskLength(InetAddress prefixMask) {
-        return (prefixMask == null) ? 0 : NetUtils.getSubnetMaskLength(prefixMask.getAddress());
+    public static int getSubnetMaskLength(InetAddress subnetMask) {
+        return subnetMask == null ? 0 : NetUtils.getSubnetMaskLength(subnetMask.getAddress());
     }
 
     /**
@@ -247,20 +246,18 @@ public abstract class NetUtils {
             return false;
         }
 
-        int testMaskLen = (testMask != null) ? NetUtils.getSubnetMaskLength(testMask.getAddress()) : 0;
-        int filterMaskLen = (filterMask != null) ? NetUtils.getSubnetMaskLength(filterMask.getAddress()) : 0;
-
-        int testPrefixLen = (testAddress instanceof Inet6Address) ? (128 - testMaskLen) : (32 - testMaskLen);
-        int filterPrefixLen = (filterAddress instanceof Inet6Address) ? (128 - filterMaskLen) : (32 - filterMaskLen);
+        int testMaskLen = (testMask == null) ? ((testAddress instanceof Inet4Address) ? 32 : 128) : NetUtils
+                .getSubnetMaskLength(testMask);
+        int filterMaskLen = NetUtils.getSubnetMaskLength(filterMask);
 
         // Mask length check. Test mask has to be more specific than filter one
-        if (testPrefixLen < filterPrefixLen) {
+        if (testMaskLen < filterMaskLen) {
             return true;
         }
 
         // Subnet Prefix on filter mask length must be the same
-        InetAddress prefix1 = getSubnetPrefix(testAddress, filterPrefixLen);
-        InetAddress prefix2 = getSubnetPrefix(filterAddress, filterPrefixLen);
+        InetAddress prefix1 = getSubnetPrefix(testAddress, filterMaskLen);
+        InetAddress prefix2 = getSubnetPrefix(filterAddress, filterMaskLen);
         return (!prefix1.equals(prefix2));
     }
 
index 730a9b0368f6b853b250d758f7ca95a7be940a82..8e1dcd69f999fec5f2619c1f8e65d0fc511212f4 100644 (file)
@@ -61,6 +61,6 @@ public class ObjectWriter {
                 }
             }
         }
-        return new Status(StatusCode.SUCCESS, null);
+        return new Status(StatusCode.SUCCESS);
     }
 }
index 429272f22769dc2ef36a17510cfe09910189a607..5afcd8be7dc4f47d79270dd00b6c3c8870c07631 100644 (file)
@@ -224,6 +224,126 @@ public class IPv4Test {
         Assert.assertTrue(destinationAddress[3] == 110);
     }
 
+    @Test
+    public void testOptions() throws Exception {
+        IPv4 ip = new IPv4();
+        Assert.assertEquals(20, ip.getHeaderLen());
+        Assert.assertEquals(160, ip.getHeaderSize());
+        Assert.assertEquals(0, ip.getfieldnumBits("Options"));
+
+        byte[][] options = {
+            new byte[] {
+                (byte)0x01,
+            },
+            new byte[] {
+                (byte)0x01, (byte)0x02,
+            },
+            new byte[] {
+                (byte)0x01, (byte)0x02, (byte)0x03,
+            },
+            new byte[] {
+                (byte)0x01, (byte)0x02, (byte)0x03, (byte)0x04,
+            },
+            null,
+            new byte[] {
+                (byte)0x01, (byte)0x02, (byte)0x03, (byte)0x04,
+                (byte)0x05,
+            },
+            new byte[] {
+                (byte)0x01, (byte)0x02, (byte)0x03, (byte)0x04,
+                (byte)0x05, (byte)0x06,
+            },
+            new byte[] {
+                (byte)0x01, (byte)0x02, (byte)0x03, (byte)0x04,
+                (byte)0x05, (byte)0x06, (byte)0x07,
+            },
+            new byte[] {
+                (byte)0x01, (byte)0x02, (byte)0x03, (byte)0x04,
+                (byte)0x05, (byte)0x06, (byte)0x07, (byte)0x08,
+            },
+            new byte[0],
+        };
+
+        byte[][] expected = {
+            new byte[] {
+                (byte)0x01, (byte)0x00, (byte)0x00, (byte)0x00,
+            },
+            new byte[] {
+                (byte)0x01, (byte)0x02, (byte)0x00, (byte)0x00,
+            },
+            new byte[] {
+                (byte)0x01, (byte)0x02, (byte)0x03, (byte)0x00,
+            },
+            new byte[] {
+                (byte)0x01, (byte)0x02, (byte)0x03, (byte)0x04,
+            },
+            null,
+            new byte[] {
+                (byte)0x01, (byte)0x02, (byte)0x03, (byte)0x04,
+                (byte)0x05, (byte)0x00, (byte)0x00, (byte)0x00,
+            },
+            new byte[] {
+                (byte)0x01, (byte)0x02, (byte)0x03, (byte)0x04,
+                (byte)0x05, (byte)0x06, (byte)0x00, (byte)0x00,
+            },
+            new byte[] {
+                (byte)0x01, (byte)0x02, (byte)0x03, (byte)0x04,
+                (byte)0x05, (byte)0x06, (byte)0x07, (byte)0x00,
+            },
+            new byte[] {
+                (byte)0x01, (byte)0x02, (byte)0x03, (byte)0x04,
+                (byte)0x05, (byte)0x06, (byte)0x07, (byte)0x08,
+            },
+            null,
+        };
+
+        byte[] echo = {
+            (byte)0x11, (byte)0x22, (byte)0x33, (byte)0x44,
+            (byte)0x55, (byte)0x66, (byte)0x77, (byte)0x88,
+            (byte)0x99, (byte)0xaa,
+        };
+        ICMP icmp = new ICMP();
+        icmp.setType((byte)8);
+        icmp.setCode((byte)0);
+        icmp.setIdentifier((short)0xabcd);
+        icmp.setSequenceNumber((short)7777);
+        icmp.setRawPayload(echo);
+
+        ip.setSourceAddress(InetAddress.getByName("192.168.10.20"));
+        ip.setDestinationAddress(InetAddress.getByName("192.168.30.40"));
+        ip.setProtocol(IPProtocols.ICMP.byteValue());
+
+        for (int i = 0; i < options.length; i++) {
+            byte[] opts = options[i];
+            byte[] exp = expected[i];
+
+            // Set IPv4 options.
+            int hlen = 20;
+            int optlen;
+            if (exp != null) {
+                optlen = exp.length;
+                hlen += optlen;
+            } else {
+                optlen = 0;
+            }
+            ip.setOptions(opts);
+            Assert.assertTrue(Arrays.equals(exp, ip.getOptions()));
+            Assert.assertEquals(hlen, ip.getHeaderLen());
+            Assert.assertEquals(hlen * 8, ip.getHeaderSize());
+            Assert.assertEquals(optlen * 8, ip.getfieldnumBits("Options"));
+
+            // Serialize/Deserialize test.
+            ip.setPayload(icmp);
+
+            byte[] raw = ip.serialize();
+            IPv4 newip = new IPv4();
+            newip.deserialize(raw, 0, raw.length * 8);
+            Assert.assertEquals(ip, newip);
+            Assert.assertEquals(icmp, newip.getPayload());
+            Assert.assertTrue(Arrays.equals(exp, newip.getOptions()));
+        }
+    }
+
     @Test
     public void testChecksum() {
         byte header[] = { (byte) 0x45, 00, 00, (byte) 0x3c, (byte) 0x1c,
index 599f97448a4ce4e4d504542f9ae7df6347442789..0c7e5bb2e5b4fce7a6ec89e96d08d1903dbe4e34 100644 (file)
@@ -200,16 +200,46 @@ public class NetUtilsTest {
     public void testGetSubnetLen() {
 
         byte address[] = { (byte) 128, (byte) 0, (byte) 0, 0 };
-        Assert.assertTrue(NetUtils.getSubnetMaskLength(address) == 31);
+        Assert.assertTrue(NetUtils.getSubnetMaskLength(address) == 1);
 
         byte address1[] = { (byte) 255, 0, 0, 0 };
-        Assert.assertTrue(NetUtils.getSubnetMaskLength(address1) == 24);
+        Assert.assertTrue(NetUtils.getSubnetMaskLength(address1) == 8);
 
         byte address2[] = { (byte) 255, (byte) 255, (byte) 248, 0 };
-        Assert.assertTrue(NetUtils.getSubnetMaskLength(address2) == 11);
+        Assert.assertTrue(NetUtils.getSubnetMaskLength(address2) == 21);
 
         byte address4[] = { (byte) 255, (byte) 255, (byte) 255, (byte) 254 };
-        Assert.assertTrue(NetUtils.getSubnetMaskLength(address4) == 1);
+        Assert.assertTrue(NetUtils.getSubnetMaskLength(address4) == 31);
+
+        byte address5[] = { (byte) 255, (byte) 255, (byte) 255, (byte) 255, (byte) 255, (byte) 255, (byte) 255,
+                (byte) 255, (byte) 255, (byte) 255, (byte) 255, (byte) 255, (byte) 255, (byte) 255, (byte) 255,
+                (byte) 255 };
+        Assert.assertTrue(NetUtils.getSubnetMaskLength(address5) == 128);
+
+        byte address6[] = { (byte) 255, (byte) 255, (byte) 255, (byte) 255, (byte) 255, (byte) 255, (byte) 255,
+                (byte) 255, (byte) 255, (byte) 255, (byte) 255, (byte) 255, (byte) 255, (byte) 255, (byte) 255,
+                (byte) 254 };
+        Assert.assertTrue(NetUtils.getSubnetMaskLength(address6) == 127);
+
+        byte address7[] = { (byte) 255, (byte) 255, (byte) 255, (byte) 255, (byte) 255, (byte) 255, (byte) 255,
+                (byte) 255, (byte) 0, (byte) 0, (byte) 0, (byte) 0, (byte) 0, (byte) 0, (byte) 0, (byte) 0 };
+        Assert.assertTrue(NetUtils.getSubnetMaskLength(address7) == 64);
+
+        byte address8[] = { (byte) 255, (byte) 255, (byte) 255, (byte) 255, (byte) 255, (byte) 255, (byte) 255,
+                (byte) 254, (byte) 0, (byte) 0, (byte) 0, (byte) 0, (byte) 0, (byte) 0, (byte) 0, (byte) 0 };
+        Assert.assertTrue(NetUtils.getSubnetMaskLength(address8) == 63);
+
+        byte address9[] = { (byte) 255, (byte) 255, (byte) 255, (byte) 255, (byte) 255, (byte) 255, (byte) 128,
+                (byte) 0, (byte) 0, (byte) 0, (byte) 0, (byte) 0, (byte) 0, (byte) 0, (byte) 0, (byte) 0 };
+        Assert.assertTrue(NetUtils.getSubnetMaskLength(address9) == 49);
+
+        byte address10[] = { (byte) 128, (byte) 0, (byte) 0, (byte) 0, (byte) 0, (byte) 0, (byte) 0, (byte) 0,
+                (byte) 0, (byte) 0, (byte) 0, (byte) 0, (byte) 0, (byte) 0, (byte) 0, (byte) 0 };
+        Assert.assertTrue(NetUtils.getSubnetMaskLength(address10) == 1);
+
+        byte address11[] = { (byte) 0, (byte) 0, (byte) 0, (byte) 0, (byte) 0, (byte) 0, (byte) 0, (byte) 0, (byte) 0,
+                (byte) 0, (byte) 0, (byte) 0, (byte) 0, (byte) 0, (byte) 0, (byte) 0 };
+        Assert.assertTrue(NetUtils.getSubnetMaskLength(address11) == 0);
     }
 
     @Test
index bcaf3a062a754e4ea5303723a4159a3226c75bdb..6700b470faee489b0789dfde840b4a1e65c47448 100644 (file)
@@ -11,7 +11,6 @@ import static org.opendaylight.controller.binding.generator.util.BindingGenerato
 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 java.util.ArrayList;
@@ -21,9 +20,7 @@ import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
 import java.util.Set;
-import java.util.concurrent.Future;
 
-import org.opendaylight.controller.binding.generator.util.BindingGeneratorUtil;
 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;
@@ -856,11 +853,11 @@ public final class BindingGeneratorImpl implements BindingGenerator {
                     if (genTOBuilder != null) {
                         returnType = new ReferencedTypeImpl(genTOBuilder.getPackageName(), genTOBuilder.getName());
                     }
-                } else if(typeDef instanceof BitsTypeDefinition) {
+                } else if (typeDef instanceof BitsTypeDefinition) {
                     GeneratedTOBuilder genTOBuilder = addEnclosedTOToTypeBuilder(typeDef, typeBuilder, leafName);
                     if (genTOBuilder != null) {
                         returnType = new ReferencedTypeImpl(genTOBuilder.getPackageName(), genTOBuilder.getName());
-                    }                    
+                    }
                 } else {
                     returnType = typeProvider.javaTypeForSchemaDefinitionType(typeDef);
                 }
@@ -1184,23 +1181,23 @@ public final class BindingGeneratorImpl implements BindingGenerator {
         return genTOBuilder;
     }
 
-    
-    private GeneratedTOBuilder addEnclosedTOToTypeBuilder( TypeDefinition<?> typeDef, GeneratedTypeBuilder typeBuilder, String leafName) { 
+    private GeneratedTOBuilder addEnclosedTOToTypeBuilder(TypeDefinition<?> typeDef, GeneratedTypeBuilder typeBuilder,
+            String leafName) {
         String className = parseToClassName(leafName);
         GeneratedTOBuilder genTOBuilder = null;
         if (typeDef instanceof UnionType) {
             genTOBuilder = ((TypeProviderImpl) typeProvider).addUnionGeneratedTypeDefinition(
-                    typeBuilder.getPackageName(), typeDef, className);
+                    typeBuilder.getFullyQualifiedName(), typeDef, className);
         } else if (typeDef instanceof BitsTypeDefinition) {
             genTOBuilder = ((TypeProviderImpl) typeProvider).bitsTypedefToTransferObject(
-                    typeBuilder.getPackageName(), typeDef, className);
+                    typeBuilder.getFullyQualifiedName(), typeDef, className);
         }
         if (genTOBuilder != null) {
             typeBuilder.addEnclosingTransferObject(genTOBuilder);
             return genTOBuilder;
         }
         return null;
-        
+
     }
-    
+
 }
index 4824fa75fd000be4910397bc7bd02f3e3775d6ad..b6d8de62e6d170d6e7e4a44f7cfe6944e2bfed7c 100644 (file)
@@ -27,13 +27,16 @@ import org.opendaylight.controller.yang.model.api.type.*;
 import org.opendaylight.controller.yang.model.api.type.BitsTypeDefinition.Bit;
 import org.opendaylight.controller.yang.model.api.type.EnumTypeDefinition.EnumPair;
 import org.opendaylight.controller.yang.model.util.ExtendedType;
+
 import org.opendaylight.controller.yang.model.util.StringType;
+import org.opendaylight.controller.yang.model.util.UnionType;
 
 import java.util.ArrayList;
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
 import java.util.Set;
+import java.util.TreeMap;
 
 import static org.opendaylight.controller.binding.generator.util.BindingGeneratorUtil.*;
 import static org.opendaylight.controller.yang.model.util.SchemaContextUtil.*;
@@ -361,18 +364,15 @@ public final class TypeProviderImpl implements TypeProvider {
             final String basePackageName = moduleNamespaceToPackageName(module);
 
             final Set<TypeDefinition<?>> typeDefinitions = module.getTypeDefinitions();
+            final List<TypeDefinition<?>> listTypeDefinitions = sortTypeDefinitionAccordingDepth(typeDefinitions);
 
             final Map<String, Type> typeMap = new HashMap<>();
             genTypeDefsContextMap.put(moduleName, typeMap);
 
-            if ((typeDefinitions != null) && (basePackageName != null)) {
-                for (final TypeDefinition<?> typedef : typeDefinitions) {
+            if ((listTypeDefinitions != null) && (basePackageName != null)) {
+                for (final TypeDefinition<?> typedef : listTypeDefinitions) {
                     typedefToGeneratedType(basePackageName, moduleName, typedef);
                 }
-                final List<ExtendedType> extUnions = UnionDependencySort.sort(typeDefinitions);
-                for (final ExtendedType extUnionType : extUnions) {
-                    addUnionGeneratedTypeDefinition(basePackageName, extUnionType, null);
-                }
             }
         }
     }
@@ -382,23 +382,31 @@ public final class TypeProviderImpl implements TypeProvider {
         if ((basePackageName != null) && (moduleName != null) && (typedef != null) && (typedef.getQName() != null)) {
 
             final String typedefName = typedef.getQName().getLocalName();
-            final TypeDefinition<?> baseTypeDefinition = baseTypeDefForExtendedType(typedef);
-            if (!(baseTypeDefinition instanceof LeafrefTypeDefinition)
-                    && !(baseTypeDefinition instanceof IdentityrefTypeDefinition)) {
-                Type returnType;
-                if (baseTypeDefinition instanceof EnumTypeDefinition) {
-                    final EnumTypeDefinition enumTypeDef = (EnumTypeDefinition) baseTypeDefinition;
+            final TypeDefinition<?> innerTypeDefinition = typedef.getBaseType();
+            if (!(innerTypeDefinition instanceof LeafrefTypeDefinition)
+                    && !(innerTypeDefinition instanceof IdentityrefTypeDefinition)) {
+                Type returnType = null;
+                if (innerTypeDefinition instanceof ExtendedType) {
+                    ExtendedType extendedTypeDef = (ExtendedType) innerTypeDefinition;
+                    returnType = resolveExtendedTypeFromTypeDef(extendedTypeDef, basePackageName, typedefName,
+                            moduleName);
+                } else if (innerTypeDefinition instanceof UnionTypeDefinition) {
+                    final GeneratedTOBuilder genTOBuilder = addUnionGeneratedTypeDefinition(basePackageName, typedef,
+                            typedefName);
+                    returnType = genTOBuilder.toInstance();
+                } else if (innerTypeDefinition instanceof EnumTypeDefinition) {
+                    final EnumTypeDefinition enumTypeDef = (EnumTypeDefinition) innerTypeDefinition;
                     returnType = resolveEnumFromTypeDefinition(enumTypeDef, typedefName);
 
-                } else if (baseTypeDefinition instanceof BitsTypeDefinition) {
-                    final BitsTypeDefinition bitsTypeDefinition = (BitsTypeDefinition) baseTypeDefinition;
-                    GeneratedTOBuilder genTOBuilder = bitsTypedefToTransferObject(basePackageName, bitsTypeDefinition,
-                            typedefName);
+                } else if (innerTypeDefinition instanceof BitsTypeDefinition) {
+                    final BitsTypeDefinition bitsTypeDefinition = (BitsTypeDefinition) innerTypeDefinition;
+                    final GeneratedTOBuilder genTOBuilder = bitsTypedefToTransferObject(basePackageName,
+                            bitsTypeDefinition, typedefName);
                     returnType = genTOBuilder.toInstance();
 
                 } else {
                     final Type javaType = BaseYangTypes.BASE_YANG_TYPES_PROVIDER
-                            .javaTypeForSchemaDefinitionType(baseTypeDefinition);
+                            .javaTypeForSchemaDefinitionType(innerTypeDefinition);
 
                     returnType = wrapJavaTypeIntoTO(basePackageName, typedef, javaType);
                 }
@@ -428,12 +436,12 @@ public final class TypeProviderImpl implements TypeProvider {
             genTOBuilder.addEqualsIdentity(genPropBuilder);
             genTOBuilder.addHashIdentity(genPropBuilder);
             genTOBuilder.addToStringProperty(genPropBuilder);
-
-            if (typedef instanceof ExtendedType) {
-                final List<String> regExps = resolveRegExpressionsFromTypedef((ExtendedType) typedef);
-                addStringRegExAsConstant(genTOBuilder, regExps);
+            if (javaType == BaseYangTypes.STRING_TYPE) {
+                if (typedef instanceof ExtendedType) {
+                    final List<String> regExps = resolveRegExpressionsFromTypedef((ExtendedType) typedef);
+                    addStringRegExAsConstant(genTOBuilder, regExps);
+                }
             }
-
             return genTOBuilder.toInstance();
         }
         return null;
@@ -479,9 +487,10 @@ public final class TypeProviderImpl implements TypeProvider {
                     final Module unionTypeModule = findParentModuleForTypeDefinition(schemaContext, unionType);
                     if (unionTypeModule != null && unionTypeModule.getName() != null) {
                         final Map<String, Type> innerGenTOs = genTypeDefsContextMap.get(unionTypeModule.getName());
-
-                        final GeneratedTransferObject genTransferObject = (GeneratedTransferObject) innerGenTOs
-                                .get(typeName);
+                        Type genTransferObject = null;
+                        if (innerGenTOs != null) {
+                            genTransferObject = innerGenTOs.get(typeName);
+                        }
                         if (genTransferObject != null) {
                             updateUnionTypeAsProperty(unionGenTransObject, genTransferObject,
                                     genTransferObject.getName());
@@ -620,4 +629,103 @@ public final class TypeProviderImpl implements TypeProvider {
         }
     }
 
+    private GeneratedTransferObject resolveExtendedTypeFromTypeDef(final ExtendedType extendedType,
+            final String basePackageName, final String typedefName, final String moduleName) {
+
+        if (extendedType == null) {
+            throw new IllegalArgumentException("Extended type cannot be NULL!");
+        }
+        if (basePackageName == null) {
+            throw new IllegalArgumentException("String with base package name cannot be NULL!");
+        }
+        if (typedefName == null) {
+            throw new IllegalArgumentException("String with type definition name cannot be NULL!");
+        }
+
+        final String typeDefName = parseToClassName(typedefName);
+        final String lowTypeDef = extendedType.getQName().getLocalName();
+        final GeneratedTOBuilder genTOBuilder = new GeneratedTOBuilderImpl(basePackageName, typeDefName);
+
+        final Map<String, Type> typeMap = genTypeDefsContextMap.get(moduleName);
+        if (typeMap != null) {
+            Type type = typeMap.get(lowTypeDef);
+            if (type instanceof GeneratedTransferObject) {
+                genTOBuilder.setExtendsType((GeneratedTransferObject) type);
+            }
+        }
+
+        return genTOBuilder.toInstance();
+    }
+
+    /**
+     * The method find out for each type definition how many immersion (depth)
+     * is necessary to get to the base type. Every type definition is inserted
+     * to the map which key is depth and value is list of type definitions with
+     * equal depth. In next step are lists from this map concatenated to one
+     * list in ascending order according to their depth. All type definitions
+     * are in the list behind all type definitions on which depends.
+     * 
+     * @param unsortedTypeDefinitions
+     *            represents list of type definitions
+     * @return list of type definitions sorted according their each other
+     *         dependencies (type definitions which are depend on other type
+     *         definitions are in list behind them).
+     */
+    private List<TypeDefinition<?>> sortTypeDefinitionAccordingDepth(
+            final Set<TypeDefinition<?>> unsortedTypeDefinitions) {
+        List<TypeDefinition<?>> sortedTypeDefinition = new ArrayList<>();
+
+        Map<Integer, List<TypeDefinition<?>>> typeDefinitionsDepths = new TreeMap<>();
+        for (TypeDefinition<?> unsortedTypeDefinition : unsortedTypeDefinitions) {
+            final int depth = getTypeDefinitionDepth(unsortedTypeDefinition);
+            List<TypeDefinition<?>> typeDefinitionsConcreteDepth = typeDefinitionsDepths.get(depth);
+            if (typeDefinitionsConcreteDepth == null) {
+                typeDefinitionsConcreteDepth = new ArrayList<TypeDefinition<?>>();
+                typeDefinitionsDepths.put(depth, typeDefinitionsConcreteDepth);
+            }
+            typeDefinitionsConcreteDepth.add(unsortedTypeDefinition);
+        }
+
+        Set<Integer> depths = typeDefinitionsDepths.keySet(); // keys are in
+                                                              // ascending order
+        for (Integer depth : depths) {
+            sortedTypeDefinition.addAll(typeDefinitionsDepths.get(depth));
+        }
+
+        return sortedTypeDefinition;
+    }
+
+    /**
+     * The method return how many immersion is necessary to get from type
+     * definition to base type.
+     * 
+     * @param typeDefinition
+     *            is type definition for which is depth looked for.
+     * @return how many immersion is necessary to get from type definition to
+     *         base type
+     */
+    private int getTypeDefinitionDepth(final TypeDefinition<?> typeDefinition) {
+        if (typeDefinition == null) {
+            throw new IllegalArgumentException("Type definition can't be null");
+        }
+        int depth = 1;
+        TypeDefinition<?> baseType = typeDefinition.getBaseType();
+
+        if (baseType instanceof ExtendedType) {
+            depth = depth + getTypeDefinitionDepth(typeDefinition.getBaseType());
+        } else if (baseType instanceof UnionType) {
+            List<TypeDefinition<?>> childTypeDefinitions = ((UnionType) baseType).getTypes();
+            int maxChildDepth = 0;
+            int childDepth = 1;
+            for (TypeDefinition<?> childTypeDefinition : childTypeDefinitions) {
+                childDepth = childDepth + getTypeDefinitionDepth(childTypeDefinition.getBaseType());
+                if (childDepth > maxChildDepth) {
+                    maxChildDepth = childDepth;
+                }
+            }
+            return maxChildDepth;
+        }
+        return depth;
+    }
+
 }
diff --git a/opendaylight/sal/yang-prototype/code-generator/binding-generator-impl/src/test/java/org/opendaylight/controller/sal/binding/generator/impl/BitAndUnionTOEnclosingTest.java b/opendaylight/sal/yang-prototype/code-generator/binding-generator-impl/src/test/java/org/opendaylight/controller/sal/binding/generator/impl/BitAndUnionTOEnclosingTest.java
new file mode 100644 (file)
index 0000000..3ca4f3e
--- /dev/null
@@ -0,0 +1,133 @@
+/*
+ * 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 static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+
+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.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.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;
+
+public class BitAndUnionTOEnclosingTest {
+
+    private final static List<File> testModels = new ArrayList<File>();
+
+    @BeforeClass
+    public static void loadTestResources() {
+        final File listModelFile = new File(ExtendedTypedefTest.class.getResource("/bit_and_union_in_leaf.yang")
+                .getPath());
+        testModels.add(listModelFile);
+    }
+
+    @Test
+    public void bitAndUnionEnclosingTest() {
+        final YangModelParser parser = new YangParserImpl();
+        final Set<Module> modules = parser.parseYangModels(testModels);
+        final SchemaContext context = parser.resolveSchemaContext(modules);
+
+        assertNotNull(context);
+        final BindingGenerator bindingGen = new BindingGeneratorImpl();
+        final List<Type> genTypes = bindingGen.generateTypes(context);
+
+        GeneratedType parentContainer = null;
+
+        for (Type type : genTypes) {
+            if ((type instanceof GeneratedType) && !(type instanceof GeneratedTransferObject)) {
+                GeneratedType genTO = (GeneratedType) type;
+                if (genTO.getName().equals("ParentContainer")) {
+                    parentContainer = genTO;
+                    break;
+                }
+            }
+        }
+
+        assertNotNull("Parent container object wasn't found.", parentContainer);
+
+        GeneratedTransferObject bitLeaf = null;
+        GeneratedTransferObject unionLeaf = null;
+        List<GeneratedType> enclosedTypes = parentContainer.getEnclosedTypes();
+        for (GeneratedType genType : enclosedTypes) {
+            if (genType instanceof GeneratedTransferObject) {
+                if (genType.getName().equals("BitLeaf")) {
+                    bitLeaf = (GeneratedTransferObject) genType;
+                } else if (genType.getName().equals("UnionLeaf")) {
+                    unionLeaf = (GeneratedTransferObject) genType;
+                }
+            }
+        }
+
+        assertNotNull("BitLeaf TO builder wasn't found.", bitLeaf);
+        assertNotNull("UnionLeaf TO builder wasn't found.", unionLeaf);
+
+        assertEquals("BitLeaf has incorrect package name.",
+                "org.opendaylight.yang.gen.v1.urn.bit.union.in.leaf.rev2013626.ParentContainer",
+                bitLeaf.getPackageName());
+        assertEquals("UnionLeaf has incorrect package name.",
+                "org.opendaylight.yang.gen.v1.urn.bit.union.in.leaf.rev2013626.ParentContainer",
+                bitLeaf.getPackageName());
+
+        List<GeneratedProperty> propertiesBitLeaf = bitLeaf.getProperties();
+        GeneratedProperty firstBitProperty = null;
+        GeneratedProperty secondBitProperty = null;
+        GeneratedProperty thirdBitProperty = null;
+        for (GeneratedProperty genProperty : propertiesBitLeaf) {
+            if (genProperty.getName().equals("firstBit")) {
+                firstBitProperty = genProperty;
+            } else if (genProperty.getName().equals("secondBit")) {
+                secondBitProperty = genProperty;
+            } else if (genProperty.getName().equals("thirdBit")) {
+                thirdBitProperty = genProperty;
+            }
+        }
+
+        assertNotNull("firstBit property wasn't found", firstBitProperty);
+        assertNotNull("secondBit property wasn't found", secondBitProperty);
+        assertNotNull("thirdBit property wasn't found", thirdBitProperty);
+
+        assertEquals("firstBit property has incorrect type", "Boolean", firstBitProperty.getReturnType().getName());
+        assertEquals("secondBit property has incorrect type", "Boolean", secondBitProperty.getReturnType().getName());
+        assertEquals("thirdBit property has incorrect type", "Boolean", thirdBitProperty.getReturnType().getName());
+
+        GeneratedProperty uint32Property = null;
+        GeneratedProperty stringProperty = null;
+        GeneratedProperty uint8Property = null;
+        List<GeneratedProperty> propertiesUnionLeaf = unionLeaf.getProperties();
+        for (GeneratedProperty genProperty : propertiesUnionLeaf) {
+            if (genProperty.getName().equals("int32")) {
+                uint32Property = genProperty;
+            } else if (genProperty.getName().equals("string")) {
+                stringProperty = genProperty;
+            } else if (genProperty.getName().equals("uint8")) {
+                uint8Property = genProperty;
+            }
+        }
+
+        assertNotNull("uint32 property wasn't found", uint32Property);
+        assertNotNull("string property wasn't found", stringProperty);
+        assertNotNull("uint8 property wasn't found", uint8Property);
+
+        assertEquals("uint32 property has incorrect type", "Integer", uint32Property.getReturnType().getName());
+        assertEquals("string property has incorrect type", "String", stringProperty.getReturnType().getName());
+        assertEquals("uint8 property has incorrect type", "Short", uint8Property.getReturnType().getName());
+
+    }
+}
diff --git a/opendaylight/sal/yang-prototype/code-generator/binding-generator-impl/src/test/java/org/opendaylight/controller/sal/binding/generator/impl/ExtendedTypedefTest.java b/opendaylight/sal/yang-prototype/code-generator/binding-generator-impl/src/test/java/org/opendaylight/controller/sal/binding/generator/impl/ExtendedTypedefTest.java
new file mode 100644 (file)
index 0000000..bbbf469
--- /dev/null
@@ -0,0 +1,137 @@
+package org.opendaylight.controller.sal.binding.generator.impl;
+
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertFalse;
+
+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.generator.impl.BindingGeneratorImpl;
+import org.opendaylight.controller.sal.binding.model.api.Constant;
+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.ParameterizedType;
+import org.opendaylight.controller.sal.binding.model.api.Type;
+import org.opendaylight.controller.sal.binding.yang.types.BaseYangTypes;
+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;
+
+public class ExtendedTypedefTest {
+
+    private final static List<File> testModels = new ArrayList<File>();
+
+    @BeforeClass
+    public static void loadTestResources() {
+        final File listModelFile = new File(ExtendedTypedefTest.class.getResource("/typedef_of_typedef.yang").getPath());
+        testModels.add(listModelFile);
+    }
+
+    @Test    
+    public void constantGenerationTest() {
+        final YangModelParser parser = new YangParserImpl();
+        final Set<Module> modules = parser.parseYangModels(testModels);
+        final SchemaContext context = parser.resolveSchemaContext(modules);
+
+        assertNotNull(context);
+        final BindingGenerator bindingGen = new BindingGeneratorImpl();
+        final List<Type> genTypes = bindingGen.generateTypes(context);
+
+        GeneratedTransferObject simpleTypedef4 = null;
+        GeneratedTransferObject extendedTypedefUnion = null;
+        GeneratedTransferObject unionTypedef = null;
+        for (final Type type : genTypes) {
+            if (type instanceof GeneratedTransferObject) {
+                if (type.getName().equals("SimpleTypedef4")) {
+                    simpleTypedef4 = (GeneratedTransferObject) type;
+                } else if (type.getName().equals("ExtendedTypedefUnion")) {
+                    extendedTypedefUnion = (GeneratedTransferObject) type;
+                } else if (type.getName().equals("UnionTypedef")) {
+                    unionTypedef = (GeneratedTransferObject) type;
+                }
+            }
+        }
+
+        // simple-typedef4
+        assertNotNull("SimpleTypedef4 not found", simpleTypedef4);
+        assertNotNull("ExtendedTypedefUnion not found", extendedTypedefUnion);
+        assertNotNull("UnionTypedef", unionTypedef);
+
+        List<GeneratedProperty> properties = simpleTypedef4.getProperties();
+        assertTrue("SimpleTypedef4 shouldn't have properties.", properties.isEmpty());
+
+        GeneratedTransferObject extendTO = simpleTypedef4.getExtends();
+        assertNotNull("SimpleTypedef4 should have extend.", extendTO);
+        assertEquals("Incorrect extension for SimpleTypedef4.", "SimpleTypedef3", extendTO.getName());
+        properties = extendTO.getProperties();
+        assertTrue("SimpleTypedef3 shouldn't have properties.", properties.isEmpty());
+
+        extendTO = extendTO.getExtends();
+        assertNotNull("SimpleTypedef3 should have extend.", extendTO);
+        assertEquals("Incorrect extension for SimpleTypedef3.", "SimpleTypedef2", extendTO.getName());
+        properties = extendTO.getProperties();
+        assertTrue("SimpleTypedef2 shouldn't have properties.", properties.isEmpty());
+
+        extendTO = extendTO.getExtends();
+        assertNotNull("SimpleTypedef2 should have extend.", extendTO);
+        assertEquals("SimpleTypedef2 should be extended with SimpleTypedef1.", "SimpleTypedef1", extendTO.getName());
+        properties = extendTO.getProperties();
+        assertEquals("Incorrect number of properties in class SimpleTypedef1.", 1, properties.size());
+
+        assertEquals("Incorrect property's name", "simpleTypedef1", properties.get(0).getName());
+        assertEquals("Property's incorrect type", BaseYangTypes.UINT8_TYPE, properties.get(0).getReturnType());
+
+        extendTO = extendTO.getExtends();
+        assertNull("SimpleTypedef1 shouldn't have extend.", extendTO);
+
+        // extended-typedef-union
+        assertNotNull("ExtendedTypedefUnion object not found", extendedTypedefUnion);
+        properties = extendedTypedefUnion.getProperties();
+        assertTrue("ExtendedTypedefUnion shouldn't have any property", properties.isEmpty());
+
+        extendTO = extendedTypedefUnion.getExtends();
+        assertEquals("Incorrect extension fo ExtendedTypedefUnion.", "UnionTypedef", extendTO.getName());
+        assertNull("UnionTypedef shouldn't be extended", extendTO.getExtends());
+        assertEquals("Incorrect number of properties for UnionTypedef.", 4, extendTO.getProperties().size());
+
+        GeneratedProperty simpleTypedef4Property = null;
+        GeneratedProperty simpleTypedef1Property = null;
+        GeneratedProperty byteTypeProperty = null;
+        GeneratedProperty typedefEnumFruitProperty = null;
+        for (GeneratedProperty genProperty : extendTO.getProperties()) {
+            if (genProperty.getName().equals("simpleTypedef1")) {
+                simpleTypedef1Property = genProperty;
+            } else if (genProperty.getName().equals("simpleTypedef4")) {
+                simpleTypedef4Property = genProperty;
+            } else if (genProperty.getName().equals("byteType")) {
+                byteTypeProperty = genProperty;
+            } else if (genProperty.getName().equals("typedefEnumFruit")) {
+                typedefEnumFruitProperty = genProperty;
+            }
+        }
+
+        assertNotNull("simpleTypedef4 property not found in UnionTypedef", simpleTypedef4Property);
+        assertNotNull("simpleTypedef1 property not found in UnionTypedef", simpleTypedef1Property);
+        assertNotNull("byteType property not found in UnionTypedef", byteTypeProperty);
+        assertNotNull("typedefEnumFruit property not found in UnionTypedef", typedefEnumFruitProperty);
+
+        assertEquals("Incorrect type for property simpleTypedef4.", "SimpleTypedef4", simpleTypedef4Property
+                .getReturnType().getName());
+        assertEquals("Incorrect type for property simpleTypedef1.", "SimpleTypedef1", simpleTypedef1Property
+                .getReturnType().getName());
+        assertEquals("Incorrect type for property byteType.", "ByteType", byteTypeProperty
+                .getReturnType().getName());
+        assertEquals("Incorrect type for property typedefEnumFruit.", "TypedefEnumFruit", typedefEnumFruitProperty
+                .getReturnType().getName());
+    }
+
+}
diff --git a/opendaylight/sal/yang-prototype/code-generator/binding-generator-impl/src/test/resources/bit_and_union_in_leaf.yang b/opendaylight/sal/yang-prototype/code-generator/binding-generator-impl/src/test/resources/bit_and_union_in_leaf.yang
new file mode 100644 (file)
index 0000000..e254dd2
--- /dev/null
@@ -0,0 +1,55 @@
+module bit-and-union-in-leaf {
+    
+    namespace "urn:bit:union:in:leaf";
+    prefix "sbd";
+
+    organization "OPEN DAYLIGHT";
+    contact "http://www.opendaylight.org/";
+
+    revision 2013-06-26 {
+        
+    }
+    
+    typedef union-typedef {
+        type union {
+            type string {
+                pattern "[a-g]";
+            };
+            type int16;
+        }
+    }
+    
+    typedef union-typedef2 {
+        type union {
+            type string; 
+            type int16;
+        }
+    }    
+    
+    container parent-container {
+        leaf bit-leaf {
+            type bits {
+                bit first-bit;
+                bit second-bit;
+                bit third-bit;
+            }
+        }
+        
+        leaf union-leaf {
+            type union {
+                type int32;
+                type string {
+                    pattern "[a-z]";
+                };
+                type string {
+                    pattern "[0-9]*"
+                };
+                type string {
+                    pattern "[a-d]*";
+                    pattern "[0-5]*";
+                };
+                type uint8;
+            }
+        }
+    }
+}
\ No newline at end of file
diff --git a/opendaylight/sal/yang-prototype/code-generator/binding-generator-impl/src/test/resources/typedef_of_typedef.yang b/opendaylight/sal/yang-prototype/code-generator/binding-generator-impl/src/test/resources/typedef_of_typedef.yang
new file mode 100644 (file)
index 0000000..fc0bab9
--- /dev/null
@@ -0,0 +1,79 @@
+module typedef_typedef {
+    
+    namespace "urn:typedef:typedef";
+    prefix "sbd";
+
+    organization "OPEN DAYLIGHT";
+    contact "http://www.opendaylight.org/";
+
+    revision 2013-07-09 {
+        
+    }
+
+   typedef byte-type {
+        type bits {
+            bit first-bit {
+                position 10;
+            }
+            bit second-bit {
+                position 20;
+            }
+         }
+    }    
+    
+    
+  typedef typedef-enum-fruit {
+    type enumeration {
+      enum "apple" {
+        value 1;
+        description "gold";
+      }
+      enum "pear" {
+        value 2;
+      }
+    }
+  }    
+    
+    typedef simple-typedef1 {
+        type uint8;
+    }
+    
+    typedef simple-typedef2 {
+        type simple-typedef1;
+    }
+    
+    typedef simple-typedef3 {
+        type simple-typedef2;
+    }
+    
+    typedef simple-typedef4 {
+        type simple-typedef3;
+    }
+    
+    typedef simple-typedef1-1 {
+        type uint16;
+    }
+
+    
+    typedef union-typedef {
+        type union {
+            type simple-typedef1;
+            type simple-typedef4;
+            type byte-type;
+            type typedef-enum-fruit;
+        }
+    }
+    
+    typedef extended-typedef-union {
+        type union-typedef;
+    }
+    
+    
+    typedef extended-typedef-simple {
+        type simple-typedef1;
+    }
+    
+    typedef extended-typedef-enum {
+        type typedef-enum-fruit;
+    }
+}
\ No newline at end of file
index 717988af3efef6afaba36b5ef34bad37218b75ce..31b94a65cad703d8b78ca79c8fbaf94f62ea7f70 100644 (file)
@@ -67,11 +67,14 @@ public final class ClassCodeGenerator implements CodeGenerator {
             }
 
             writer.write(NL);
+            final boolean oneConstructor;
             if (genTO.isUnionType()) {
-                writer.write(GeneratorUtil.createConstructors(genTO, indent + TAB, imports, genTO.isAbstract()));
+                oneConstructor = false;
             } else {
-                writer.write(GeneratorUtil.createConstructor(genTO, indent + TAB, imports, genTO.isAbstract()) + NL);
+                oneConstructor = true;
             }
+            writer.write(GeneratorUtil.createConstructor(genTO, indent + TAB, imports, genTO.isAbstract(),
+                    oneConstructor));
             writer.write(NL);
 
             for (GeneratedProperty field : fields) {
index dfae4a2ceaad57c3de7555e7867913416aa78535..0e2da819371cf7b962ba0eba39fa980e1e66bdbd 100644 (file)
@@ -17,9 +17,9 @@ 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.Enumeration.Pair;
 import org.opendaylight.controller.sal.binding.model.api.MethodSignature.Parameter;
-import org.opendaylight.controller.binding.generator.util.Types;
 
 public final class GeneratorUtil {
 
@@ -232,90 +232,244 @@ public final class GeneratorUtil {
         return builder.toString();
     }
 
-    public static String createConstructor(GeneratedTransferObject genTransferObject, final String indent,
-            final Map<String, String> availableImports, boolean isIdentity) {
-        StringBuilder builder = new StringBuilder();
+    public static String createConstructor(final GeneratedTransferObject genTransferObject, final String indent,
+            final Map<String, String> availableImports, final boolean isIdentity, final boolean oneConstructor) {
+        if (genTransferObject == null) {
+            throw new IllegalArgumentException("Generated transfer object can't be null");
+        }
+        if (indent == null) {
+            throw new IllegalArgumentException("String with indent can't be null");
+        }
+        if (availableImports == null) {
+            throw new IllegalArgumentException("Map of available imports can't be null");
+        }
+        GeneratedTransferObject genTOTopParent = getTopParrentTransportObject(genTransferObject);
+        final List<GeneratedProperty> ctorProperties = resolveReadOnlyPropertiesFromTO(genTransferObject
+                .getProperties());
+        final List<GeneratedProperty> ctorPropertiesAllParents = getPropertiesOfAllParents(genTransferObject
+                .getExtends());
 
         final String currentPkg = genTransferObject.getPackageName();
-        final List<GeneratedProperty> properties = genTransferObject.getProperties();
-        final List<GeneratedProperty> ctorParams = new ArrayList<GeneratedProperty>();
-        if (properties != null) {
-            for (final GeneratedProperty property : properties) {
-                if (property.isReadOnly()) {
-                    ctorParams.add(property);
-                }
+        final String className = genTransferObject.getName();
+
+        String constructorPart = "";
+        if (oneConstructor) {
+            if (genTOTopParent != genTransferObject && genTOTopParent.isUnionType()) {
+                constructorPart = createConstructorForEveryParentProperty(indent, isIdentity, ctorProperties,
+                        ctorPropertiesAllParents, availableImports, currentPkg, className);
+
+            } else {
+                constructorPart = createOneConstructor(indent, isIdentity, ctorProperties, ctorPropertiesAllParents,
+                        availableImports, currentPkg, className);
             }
+
+        } else { // union won't be extended
+            constructorPart = createConstructorForEveryProperty(indent, isIdentity, ctorProperties,
+                    ctorPropertiesAllParents, availableImports, currentPkg, className);
         }
 
-        builder.append(createConstructorDeclarationToLeftParenthesis(genTransferObject, indent, isIdentity));
+        return constructorPart;
+    }
 
-        final String parameterSeparator = COMMA + GAP;
-        for (final GeneratedProperty ctorParam : ctorParams) {
-            builder.append(createMethodParamDeclaration(ctorParam, availableImports, currentPkg));
-            builder.append(parameterSeparator);
+    private static String createOneConstructor(final String indent, boolean isIdentity,
+            final List<GeneratedProperty> properties, final List<GeneratedProperty> propertiesAllParents,
+            final Map<String, String> availableImports, final String currentPkg, final String className) {
+        if (indent == null) {
+            throw new IllegalArgumentException("String with indent can't be null");
         }
-        if (!ctorParams.isEmpty()) {
-            builder = builder.delete(builder.length() - parameterSeparator.length(), builder.length());
+        if (properties == null) {
+            throw new IllegalArgumentException("List of generated properties can't be null");
         }
-        builder.append(createConstructorDeclarationFromRightParenthesis());
-        builder.append(createConstructorSuperCalling(indent));
-
-        for (final GeneratedProperty ctorParam : ctorParams) {
-            builder.append(createClassAttributeInitialization(indent, ctorParam));
+        if (propertiesAllParents == null) {
+            throw new IllegalArgumentException(
+                    "List of generated properties of all parent transport objects can't be null");
+        }
+        if (availableImports == null) {
+            throw new IllegalArgumentException("Map of available imports can't be null");
         }
+        if (currentPkg == null) {
+            throw new IllegalArgumentException("String with current package can't be null");
+        }
+        if (className == null) {
+            throw new IllegalArgumentException("String with class name can't be null");
+        }
+
+        final StringBuilder builder = new StringBuilder();
 
+        List<GeneratedProperty> propertiesAll = new ArrayList<GeneratedProperty>(properties);
+        propertiesAll.addAll(propertiesAllParents);
+
+        builder.append(createConstructorDeclarationToLeftParenthesis(className, indent, isIdentity));
+        builder.append(createMethodPropertiesDeclaration(propertiesAll, availableImports, currentPkg, COMMA + GAP));
+        builder.append(createConstructorDeclarationFromRightParenthesis());
+        builder.append(createConstructorSuper(propertiesAllParents, indent));
+        builder.append(createClassPropertiesInitialization(propertiesAll, indent));
         builder.append(createConstructorClosingPart(indent));
         return builder.toString();
     }
 
-    public static String createConstructors(GeneratedTransferObject genTransferObject, final String indent,
-            final Map<String, String> availableImports, boolean isIdentity) {
+    private static String createConstructorForEveryParentProperty(final String indent, final boolean isIdentity,
+            final List<GeneratedProperty> properties, final List<GeneratedProperty> propertiesAllParents,
+            final Map<String, String> availableImports, final String currentPkg, final String className) {
+        if (indent == null) {
+            throw new IllegalArgumentException("String with indent can't be null");
+        }
+        if (properties == null) {
+            throw new IllegalArgumentException("List of generated properties can't be null");
+        }
+        if (propertiesAllParents == null) {
+            throw new IllegalArgumentException(
+                    "List of generated properties of all parent transport objects can't be null");
+        }
+        if (availableImports == null) {
+            throw new IllegalArgumentException("Map of available imports can't be null");
+        }
+        if (currentPkg == null) {
+            throw new IllegalArgumentException("String with current package can't be null");
+        }
+        if (className == null) {
+            throw new IllegalArgumentException("String with class name can't be null");
+        }
         final StringBuilder builder = new StringBuilder();
+        GeneratedProperty parentProperty;
+        Iterator<GeneratedProperty> parentPropertyIterator = propertiesAllParents.iterator();
 
-        final String currentPkg = genTransferObject.getPackageName();
-        final List<GeneratedProperty> properties = genTransferObject.getProperties();
-        final List<GeneratedProperty> ctorParams = new ArrayList<GeneratedProperty>();
-        if (properties != null) {
-            for (final GeneratedProperty property : properties) {
-                if (property.isReadOnly()) {
-                    ctorParams.add(property);
-                }
+        do {
+            parentProperty = null;
+            if (parentPropertyIterator.hasNext()) {
+                parentProperty = parentPropertyIterator.next();
+            }
+
+            List<GeneratedProperty> propertiesAndParentProperties = new ArrayList<GeneratedProperty>();
+            if (parentProperty != null) {
+                propertiesAndParentProperties.add(parentProperty);
             }
+            propertiesAndParentProperties.addAll(properties);
+
+            builder.append(createConstructorDeclarationToLeftParenthesis(className, indent, isIdentity));
+            builder.append(createMethodPropertiesDeclaration(propertiesAndParentProperties, availableImports,
+                    currentPkg, COMMA + GAP));
+            builder.append(createConstructorDeclarationFromRightParenthesis());
+            builder.append(createConstructorSuper(parentProperty, indent));
+            builder.append(createClassPropertiesInitialization(properties, indent));
+            builder.append(createConstructorClosingPart(indent));
+        } while (parentPropertyIterator.hasNext());
+
+        return builder.toString();
+    }
+
+    private static String createConstructorForEveryProperty(final String indent, final boolean isIdentity,
+            final List<GeneratedProperty> properties, final List<GeneratedProperty> propertiesAllParents,
+            final Map<String, String> availableImports, final String currentPkg, final String className) {
+        if (indent == null) {
+            throw new IllegalArgumentException("String with indent can't be null");
+        }
+        if (properties == null) {
+            throw new IllegalArgumentException("List of generated properties can't be null");
+        }
+        if (propertiesAllParents == null) {
+            throw new IllegalArgumentException(
+                    "List of generated properties of all parent transport objects can't be null");
+        }
+        if (availableImports == null) {
+            throw new IllegalArgumentException("Map of available imports can't be null");
+        }
+        if (currentPkg == null) {
+            throw new IllegalArgumentException("String with current package can't be null");
+        }
+        if (className == null) {
+            throw new IllegalArgumentException("String with class name can't be null");
         }
 
-        GeneratedProperty ctorParam;
-        Iterator<GeneratedProperty> iteratorCtorParams = ctorParams.iterator();
+        final StringBuilder builder = new StringBuilder();
+
+        GeneratedProperty property;
+        Iterator<GeneratedProperty> propertyIterator = properties.iterator();
 
         do {
-            ctorParam = null;
-            if (iteratorCtorParams.hasNext()) {
-                ctorParam = iteratorCtorParams.next();
+            property = null;
+            if (propertyIterator.hasNext()) {
+                property = propertyIterator.next();
             }
-            builder.append(createConstructorDeclarationToLeftParenthesis(genTransferObject, indent, isIdentity));
 
-            if (ctorParam != null) {
-                builder.append(createMethodParamDeclaration(ctorParam, availableImports, currentPkg));
+            List<GeneratedProperty> propertyAndTopParentProperties = new ArrayList<GeneratedProperty>();
+            if (property != null) {
+                propertyAndTopParentProperties.add(property);
             }
+            propertyAndTopParentProperties.addAll(propertiesAllParents);
+
+            builder.append(createConstructorDeclarationToLeftParenthesis(className, indent, isIdentity));
+            builder.append(createMethodPropertiesDeclaration(propertyAndTopParentProperties, availableImports,
+                    currentPkg, COMMA + GAP));
             builder.append(createConstructorDeclarationFromRightParenthesis());
-            builder.append(createConstructorSuperCalling(indent));
+            builder.append(createConstructorSuper(propertiesAllParents, indent));
+            builder.append(createClassPropertyInitialization(property, indent));
+            builder.append(createConstructorClosingPart(indent));
+        } while (propertyIterator.hasNext());
 
-            if (ctorParam != null) {
-                builder.append(createClassAttributeInitialization(indent, ctorParam));
+        return builder.toString();
+    }
+
+    /**
+     * The method selects from input list of properties only those which have
+     * read only attribute set to true.
+     * 
+     * @param properties
+     *            contains list of properties of generated transfer object
+     * @return subset of <code>properties</code> which have read only attribute
+     *         set to true
+     */
+    private static List<GeneratedProperty> resolveReadOnlyPropertiesFromTO(List<GeneratedProperty> properties) {
+        List<GeneratedProperty> readOnlyProperties = new ArrayList<GeneratedProperty>();
+        if (properties != null) {
+            for (final GeneratedProperty property : properties) {
+                if (property.isReadOnly()) {
+                    readOnlyProperties.add(property);
+                }
             }
+        }
+        return readOnlyProperties;
+    }
 
-            builder.append(createConstructorClosingPart(indent));
-        } while (iteratorCtorParams.hasNext());
+    private static String createMethodPropertiesDeclaration(final List<GeneratedProperty> parameters,
+            final Map<String, String> availableImports, final String currentPkg, final String parameterSeparator) {
+        StringBuilder builder = new StringBuilder();
+        if (parameters == null) {
+            throw new IllegalArgumentException("List of generated properties can't be null");
+        }
+        if (availableImports == null) {
+            throw new IllegalArgumentException("Map of available imports can't be null");
+        }
+        if (currentPkg == null) {
+            throw new IllegalArgumentException("String with current package can't be null");
+        }
+        if (parameterSeparator == null) {
+            throw new IllegalArgumentException("String with separator of parameters can't be null");
+        }
 
+        for (final GeneratedProperty parameter : parameters) {
+            builder.append(createMethodPropertyDeclaration(parameter, availableImports, currentPkg));
+            builder.append(parameterSeparator);
+        }
+        if (!parameters.isEmpty()) {
+            builder = builder.delete(builder.length() - parameterSeparator.length(), builder.length());
+        }
         return builder.toString();
     }
 
-    private static String createConstructorDeclarationToLeftParenthesis(GeneratedTransferObject genTransferObject,
-            final String indent, boolean isIdentity) {
+    private static String createConstructorDeclarationToLeftParenthesis(final String className, final String indent,
+            final boolean isIdentity) {
+        if (className == null) {
+            throw new IllegalArgumentException("String with class name can't be null");
+        }
+        if (indent == null) {
+            throw new IllegalArgumentException("String with indent can't be null");
+        }
         final StringBuilder builder = new StringBuilder();
         builder.append(indent);
         builder.append(isIdentity ? PROTECTED : PUBLIC);
         builder.append(GAP);
-        builder.append(genTransferObject.getName());
+        builder.append(className);
         builder.append(LB);
         return builder.toString();
     }
@@ -326,13 +480,48 @@ public final class GeneratorUtil {
         return builder.toString();
     }
 
-    private static String createConstructorSuperCalling(String indent) {
-        final StringBuilder builder = new StringBuilder();
-        builder.append(indent + TAB + "super();" + NL);
+    private static String createConstructorSuper(final List<GeneratedProperty> propertiesAllParents, final String indent) {
+        if (indent == null) {
+            throw new IllegalArgumentException("String with indent can't be null");
+        }
+        if (propertiesAllParents == null) {
+            throw new IllegalArgumentException("List of all parent's properties can't be null");
+        }
+        StringBuilder builder = new StringBuilder();
+        builder.append(indent + TAB + "super(");
+        String propertySeparator = COMMA + GAP;
+        for (GeneratedProperty superProperty : propertiesAllParents) {
+            builder.append(superProperty.getName());
+            builder.append(propertySeparator);
+        }
+        if (!propertiesAllParents.isEmpty()) {
+            builder = builder.delete(builder.length() - propertySeparator.length(), builder.length());
+        }
+
+        builder.append(");" + NL);
         return builder.toString();
     }
 
-    private static String createConstructorClosingPart(String indent) {
+    private static String createConstructorSuper(final GeneratedProperty parentProperty, final String indent) {
+        if (indent == null) {
+            throw new IllegalArgumentException("String with indent can't be null");
+        }
+        if (parentProperty == null) {
+            throw new IllegalArgumentException("Parent property can't be null");
+        }
+        StringBuilder builder = new StringBuilder();
+        if (parentProperty != null) {
+            builder.append(indent + TAB + "super(");
+            builder.append(parentProperty.getName());
+            builder.append(");" + NL);
+        }
+        return builder.toString();
+    }
+
+    private static String createConstructorClosingPart(final String indent) {
+        if (indent == null) {
+            throw new IllegalArgumentException("String with indent can't be null");
+        }
         final StringBuilder builder = new StringBuilder();
         builder.append(indent);
         builder.append(RCB);
@@ -340,25 +529,55 @@ public final class GeneratorUtil {
         return builder.toString();
     }
 
-    private static String createClassAttributeInitialization(String indent, GeneratedProperty methodParameter) {
+    private static String createClassPropertiesInitialization(final List<GeneratedProperty> properties,
+            final String indent) {
+        if (indent == null) {
+            throw new IllegalArgumentException("String with indent can't be null");
+        }
+        if (properties == null) {
+            throw new IllegalArgumentException("List of generated class properties can't be null");
+        }
+        final StringBuilder builder = new StringBuilder();
+        for (final GeneratedProperty property : properties) {
+            createClassPropertyInitialization(property, indent);
+        }
+        return builder.toString();
+    }
+
+    private static String createClassPropertyInitialization(final GeneratedProperty property, final String indent) {
+        if (indent == null) {
+            throw new IllegalArgumentException("String with indent can't be null");
+        }
+        if (property == null) {
+            throw new IllegalArgumentException("List of generated class properties can't be null");
+        }
         final StringBuilder builder = new StringBuilder();
         builder.append(indent);
         builder.append(TAB);
         builder.append("this.");
-        builder.append(methodParameter.getName());
+        builder.append(property.getName());
         builder.append(" = ");
-        builder.append(methodParameter.getName());
+        builder.append(property.getName());
         builder.append(SC);
         builder.append(NL);
         return builder.toString();
     }
 
-    private static String createMethodParamDeclaration(GeneratedProperty methodParameter,
-            final Map<String, String> availableImports, String currentPkg) {
+    private static String createMethodPropertyDeclaration(final GeneratedProperty property,
+            final Map<String, String> availableImports, final String currentPkg) {
+        if (property == null) {
+            throw new IllegalArgumentException("Generated property can't be null");
+        }
+        if (availableImports == null) {
+            throw new IllegalArgumentException("Map of available imports can't be null");
+        }
+        if (currentPkg == null) {
+            throw new IllegalArgumentException("String with current package can't be null");
+        }
         final StringBuilder builder = new StringBuilder();
-        builder.append(getExplicitType(methodParameter.getReturnType(), availableImports, currentPkg));
+        builder.append(getExplicitType(property.getReturnType(), availableImports, currentPkg));
         builder.append(GAP);
-        builder.append(methodParameter.getName());
+        builder.append(property.getName());
         return builder.toString();
     }
 
@@ -784,6 +1003,51 @@ public final class GeneratorUtil {
         return false;
     }
 
+    /**
+     * The method returns reference to highest (top parent) Generated Transfer
+     * Object.
+     * 
+     * @param childTransportObject
+     *            is generated transfer object which can be extended by other
+     *            generated transfer object
+     * @return in first case that <code>childTransportObject</code> isn't
+     *         extended then <code>childTransportObject</code> is returned. In
+     *         second case the method is recursive called until first case.
+     */
+    private static GeneratedTransferObject getTopParrentTransportObject(GeneratedTransferObject childTransportObject) {
+        if (childTransportObject == null) {
+            throw new IllegalArgumentException("Parameter childTransportObject can't be null.");
+        }
+        if (childTransportObject.getExtends() == null) {
+            return childTransportObject;
+        } else {
+            return getTopParrentTransportObject(childTransportObject.getExtends());
+        }
+    }
+
+    /**
+     * The method returns the list of the properties of all extending generated
+     * transfer object from <code>genTO</code> to highest parent generated
+     * transfer object
+     * 
+     * @param genTO
+     * @return the list of all properties from actual to highest parent
+     *         generated transfer object. In case when extension exists the
+     *         method is recursive called.
+     */
+    private static List<GeneratedProperty> getPropertiesOfAllParents(GeneratedTransferObject genTO) {
+        List<GeneratedProperty> propertiesOfAllParents = new ArrayList<GeneratedProperty>();
+        if (genTO != null) {
+            final List<GeneratedProperty> allPropertiesOfTO = genTO.getProperties();
+            List<GeneratedProperty> readOnlyPropertiesOfTO = resolveReadOnlyPropertiesFromTO(allPropertiesOfTO);
+            propertiesOfAllParents.addAll(readOnlyPropertiesOfTO);
+            if (genTO.getExtends() != null) {
+                propertiesOfAllParents.addAll(getPropertiesOfAllParents(genTO.getExtends()));
+            }
+        }
+        return propertiesOfAllParents;
+    }
+
     public static String createStaticInicializationBlock(GeneratedTransferObject genTransferObject, String indent) {
 
         final StringBuilder builder = new StringBuilder();
index f9f4c8398bbdda2215112294ebf9cfac8b64d1c5..972b60c0f752c6b123d7a442728d82c2a780a2bb 100644 (file)
@@ -1,9 +1,15 @@
-<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">\r
-  <modelVersion>4.0.0</modelVersion>\r
-  <parent>\r
-    <groupId>org.opendaylight.controller</groupId>\r
-    <artifactId>binding-generator</artifactId>\r
-    <version>0.5.4-SNAPSHOT</version>\r
-  </parent>\r
-  <artifactId>binding-model-api</artifactId>\r
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"\r
+    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">\r
+\r
+    <parent>\r
+        <groupId>org.opendaylight.controller</groupId>\r
+        <artifactId>binding-generator</artifactId>\r
+        <version>0.5.4-SNAPSHOT</version>\r
+    </parent>\r
+\r
+    <modelVersion>4.0.0</modelVersion>\r
+    <artifactId>binding-model-api</artifactId>\r
+    <name>${project.artifactId}</name>\r
+    <description>${project.artifactId}</description>\r
+\r
 </project>\r
index 8776bd98ab02c93af7d68722ccfa34e3fda17782..3776cf8bc70d37cc7d8ad53cab0c3fcc3c25c749 100644 (file)
@@ -1,18 +1,18 @@
-<project xmlns="http://maven.apache.org/POM/4.0.0"
-         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
-         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
-    <modelVersion>4.0.0</modelVersion>
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
 
     <parent>
         <groupId>org.opendaylight.controller</groupId>
         <artifactId>yang-prototype</artifactId>
         <version>0.5-SNAPSHOT</version>
     </parent>
-    <version>0.5.4-SNAPSHOT</version>
 
+    <modelVersion>4.0.0</modelVersion>
+    <version>0.5.4-SNAPSHOT</version>
     <artifactId>binding-generator</artifactId>
     <packaging>pom</packaging>
-    <name>binding-generator</name>
+    <name>${project.artifactId}</name>
+    <description>${project.artifactId}</description>
 
     <properties>
         <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
                     <target>1.7</target>
                 </configuration>
             </plugin>
-            <plugin>
-                <groupId>org.apache.maven.plugins</groupId>
-                <artifactId>maven-javadoc-plugin</artifactId>
-                <version>2.8.1</version>
-                <configuration>
-                    <stylesheet>maven</stylesheet>
-                </configuration>
-                <executions>
-                    <execution>
-                        <goals>
-                            <goal>aggregate</goal>
-                        </goals>
-                        <phase>site</phase>
-                    </execution>
-                </executions>
-            </plugin>
         </plugins>
     </build>
+
 </project>
diff --git a/opendaylight/sal/yang-prototype/code-generator/samples/maven-code-gen-sample/src/main/yang/typedef_of_typedef.yang b/opendaylight/sal/yang-prototype/code-generator/samples/maven-code-gen-sample/src/main/yang/typedef_of_typedef.yang
new file mode 100644 (file)
index 0000000..3aa6770
--- /dev/null
@@ -0,0 +1,79 @@
+module typedef_typedef {
+    
+    namespace "urn:typedef:typedef";
+    prefix "sbd";
+
+    organization "OPEN DAYLIGHT";
+    contact "http://www.opendaylight.org/";
+
+    revision 2013-07-09 {
+        
+    }
+
+   typedef byte-type {
+        type bits {
+            bit first-bit {
+                position 10;
+            }
+            bit second-bit {
+                position 20;
+            }
+         }
+    }    
+    
+    
+  typedef typedef-enum-fruit {
+    type enumeration {
+      enum "apple" {
+        value 1;
+        description "gold";
+      }
+      enum "pear" {
+        value 2;
+      }
+    }
+  }    
+    
+    typedef simple-typedef1 {
+       type uint8;
+    }
+    
+    typedef simple-typedef2 {
+        type simple-typedef1;
+    }
+    
+    typedef simple-typedef3 {
+        type simple-typedef2;
+    }
+    
+    typedef simple-typedef4 {
+        type simple-typedef3;
+    }
+    
+    typedef simple-typedef1-1 {
+        type uint16;
+    }    
+
+    
+    typedef union-typedef {
+        type union {
+            type simple-typedef1;
+            type simple-typedef4;
+            type byte-type;
+            type typedef-enum-fruit;
+        }
+    }    
+    
+    typedef extended-typedef-union {
+        type union-typedef;
+    }
+    
+    
+    typedef extended-typedef-simple {
+        type simple-typedef1;
+    }
+    
+    typedef extended-typedef-enum {
+        type typedef-enum-fruit;
+    }
+}
\ No newline at end of file
diff --git a/opendaylight/sal/yang-prototype/code-generator/samples/modeling-sample/src/main/yang/sample.yang b/opendaylight/sal/yang-prototype/code-generator/samples/modeling-sample/src/main/yang/sample.yang
deleted file mode 100644 (file)
index 3ecdc0a..0000000
+++ /dev/null
@@ -1,62 +0,0 @@
-module sample {
-    yang-version 1;
-    namespace "sample";
-    prefix "s";
-
-    revision 2013-06-13 {
-       description "Initial demo";
-    }
-    
-
-
-    // Simple Type definition
-    
-    typedef foo-name {
-        type string;
-    }
-    
-    // Storage / data structure
-    
-    container topologies {
-        list topology {
-            leaf foo-name {
-                type string;
-            }
-        }
-    }
-    
-    
-    // Notification / Event
-    
-    notification packet-in {
-        leaf node {
-            type string;
-        }
-        leaf port {
-            type uint16;
-        }
-        leaf content {
-            type binary;
-        }
-    }
-    
-    // RPC
-    
-    rpc packet-out {
-        input {
-            leaf node {
-                type string;
-            }
-            leaf port {
-                type uint16;
-            }
-            leaf content {
-                type binary;
-            }
-        }
-        output {
-            
-        }
-    }    
-
-}
\ No newline at end of file
diff --git a/opendaylight/sal/yang-prototype/code-generator/samples/modeling-sample/src/main/yang/toaster.yang b/opendaylight/sal/yang-prototype/code-generator/samples/modeling-sample/src/main/yang/toaster.yang
new file mode 100644 (file)
index 0000000..fc9b665
--- /dev/null
@@ -0,0 +1,187 @@
+module toaster {
+
+    yang-version 1;
+
+    namespace
+      "http://netconfcentral.org/ns/toaster";
+
+    prefix toast;
+
+    organization "Netconf Central";
+
+    contact
+      "Andy Bierman <andy@netconfcentral.org>";
+
+    description
+      "YANG version of the TOASTER-MIB.";
+
+    revision "2009-11-20" {
+      description
+        "Toaster module in progress.";
+    }
+
+
+    identity toast-type {
+      description
+          "Base for all bread types supported by the toaster.
+           New bread types not listed here nay be added in the 
+           future.";
+    }
+
+    identity white-bread {
+      base toast:toast-type;
+      description "White bread.";
+    }
+
+    identity wheat-bread {
+      base toast-type;
+      description "Wheat bread.";
+    }
+
+    identity wonder-bread {
+      base toast-type;
+      description "Wonder bread.";
+    }
+
+    identity frozen-waffle {
+      base toast-type;
+      description "Frozen waffle.";
+    }
+
+    identity frozen-bagel {
+      base toast-type;
+      description "Frozen bagel.";
+    }
+
+    identity hash-brown {
+      base toast-type;
+      description "Hash browned potatos.";
+    }
+
+    typedef DisplayString {
+      type string;
+      description
+        "YANG version of the SMIv2 DisplayString TEXTUAL-CONVENTION.";
+      reference
+        "RFC 2579, section 2.";
+
+    }
+
+    container toaster {
+      presence
+        "Indicates the toaster service is available";
+      description
+        "Top-level container for all toaster database objects.";
+      leaf toasterManufacturer {
+        type DisplayString;
+        config false;
+        mandatory true;
+        description
+          "The name of the toaster's manufacturer. For instance, 
+                Microsoft Toaster.";
+      }
+
+      leaf toasterModelNumber {
+        type DisplayString;
+        config false;
+        mandatory true;
+        description
+          "The name of the toaster's model. For instance,
+               Radiant Automatic.";
+      }
+
+      leaf toasterStatus {
+        type enumeration {
+          enum "up" {
+            value 1;
+            description
+              "The toaster knob position is up.
+                      No toast is being made now.";
+          }
+          enum "down" {
+            value 2;
+            description
+              "The toaster knob position is down.
+                      Toast is being made now.";
+          }
+        }
+        config false;
+        mandatory true;
+        description
+          "This variable indicates the current state of 
+               the toaster.";
+      }
+    }  // container toaster
+
+    rpc make-toast {
+      description
+        "Make some toast.
+           The toastDone notification will be sent when 
+           the toast is finished.
+           An 'in-use' error will be returned if toast
+           is already being made.
+           A 'resource-denied' error will be returned 
+           if the toaster service is disabled.";
+      input {
+        leaf toasterDoneness {
+          type uint32 {
+            range "1 .. 10";
+          }
+          default '5';
+          description
+            "This variable controls how well-done is the 
+                   ensuing toast. It should be on a scale of 1 to 10.
+                   Toast made at 10 generally is considered unfit 
+                   for human consumption; toast made at 1 is warmed 
+                   lightly.";
+        }
+
+        leaf toasterToastType {
+          type identityref {
+            base toast:toast-type;
+          }
+          default 'wheat-bread';
+          description
+            "This variable informs the toaster of the type of 
+                   material that is being toasted. The toaster 
+                   uses this information, combined with 
+                   toasterDoneness, to compute for how 
+                   long the material must be toasted to achieve 
+                   the required doneness.";
+        }
+      }
+    }  // rpc make-toast
+
+    rpc cancel-toast {
+      description
+        "Stop making toast, if any is being made.
+           A 'resource-denied' error will be returned 
+           if the toaster service is disabled.";
+    }  // rpc cancel-toast
+
+    notification toastDone {
+      description
+        "Indicates that the toast in progress has completed.";
+      leaf toastStatus {
+        type enumeration {
+          enum "done" {
+            value 0;
+            description "The toast is done.";
+          }
+          enum "cancelled" {
+            value 1;
+            description
+              "The toast was cancelled.";
+          }
+          enum "error" {
+            value 2;
+            description
+              "The toaster service was disabled or
+                     the toaster is broken.";
+          }
+        }
+        description
+          "Indicates the final toast status";
+      }
+    }  // notification toastDone
+  }  // module toaster
diff --git a/opendaylight/sal/yang-prototype/code-generator/src/site/site.xml b/opendaylight/sal/yang-prototype/code-generator/src/site/site.xml
new file mode 100644 (file)
index 0000000..80ff3a4
--- /dev/null
@@ -0,0 +1,16 @@
+<project name="${project.name}">
+
+    <skin>
+        <groupId>org.apache.maven.skins</groupId>
+        <artifactId>maven-fluido-skin</artifactId>
+        <version>1.3.0</version>
+    </skin>
+
+    <body>
+        <menu ref="parent"/>
+        <menu ref="modules"/>
+        <menu ref="reports"/>
+    </body>
+
+</project>
+
index 68fe50d23891abdeb26a1c6d783c6c3afa26eae0..e6ed882aaaba1d51138f8b6b08bc1ba9c58e37d6 100644 (file)
@@ -1,11 +1,16 @@
 <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
-         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
-    <modelVersion>4.0.0</modelVersion>
+    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+
     <parent>
         <artifactId>yang-prototype</artifactId>
         <groupId>org.opendaylight.controller</groupId>
         <version>0.5-SNAPSHOT</version>
     </parent>
+
+    <modelVersion>4.0.0</modelVersion>
     <artifactId>concepts-lang</artifactId>
     <packaging>jar</packaging>
-</project>
\ No newline at end of file
+    <name>${project.artifactId}</name>
+    <description>${project.artifactId}</description>
+
+</project>
diff --git a/opendaylight/sal/yang-prototype/concepts-lang/src/site/site.xml b/opendaylight/sal/yang-prototype/concepts-lang/src/site/site.xml
new file mode 100644 (file)
index 0000000..80ff3a4
--- /dev/null
@@ -0,0 +1,16 @@
+<project name="${project.name}">
+
+    <skin>
+        <groupId>org.apache.maven.skins</groupId>
+        <artifactId>maven-fluido-skin</artifactId>
+        <version>1.3.0</version>
+    </skin>
+
+    <body>
+        <menu ref="parent"/>
+        <menu ref="modules"/>
+        <menu ref="reports"/>
+    </body>
+
+</project>
+
index e9fa751143260a23387a991e14e3beaf886178dd..06d1189aa0434bc2fb0670d574b2ef4530889618 100644 (file)
@@ -1,11 +1,16 @@
 <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
     xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
-    <modelVersion>4.0.0</modelVersion>
+
     <parent>
         <artifactId>model-ietf</artifactId>
         <groupId>org.opendaylight.controller</groupId>
         <version>0.5-SNAPSHOT</version>
     </parent>
+
+    <modelVersion>4.0.0</modelVersion>
     <artifactId>ietf-inet-types</artifactId>
     <version>2010.09.24-SNAPSHOT</version>
-</project>
\ No newline at end of file
+    <name>${project.artifactId}</name>
+    <description>${project.artifactId}</description>
+
+</project>
index 4831cf1bc8b12b0698a09865f19b3fa0200d83e3..1ad4e4a78e9196a4088a4f0e50b3922bb6c883ff 100644 (file)
@@ -1,11 +1,16 @@
 <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
     xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
-    <modelVersion>4.0.0</modelVersion>
+
     <parent>
         <artifactId>model-ietf</artifactId>
         <groupId>org.opendaylight.controller</groupId>
         <version>0.5-SNAPSHOT</version>
     </parent>
+
+    <modelVersion>4.0.0</modelVersion>
     <artifactId>ietf-yang-types</artifactId>
     <version>2010.09.24-SNAPSHOT</version>
-</project>
\ No newline at end of file
+    <name>${project.artifactId}</name>
+    <description>${project.artifactId}</description>
+
+</project>
index aadde168571b3f9a3b7b41e2576311436fa3e054..a5b87b03eac2ee87402afad912d44a25a8c0bc7d 100644 (file)
@@ -1,15 +1,21 @@
 <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
     xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
-    <modelVersion>4.0.0</modelVersion>
+
     <parent>
         <artifactId>model-parent</artifactId>
         <groupId>org.opendaylight.controller</groupId>
         <version>0.5-SNAPSHOT</version>
     </parent>
+
+    <modelVersion>4.0.0</modelVersion>
     <artifactId>model-ietf</artifactId>
     <packaging>pom</packaging>
+    <name>${project.artifactId}</name>
+    <description>${project.artifactId}</description>
+
     <modules>
-       <module>ietf-inet-types</module>
-       <module>ietf-yang-types</module>
+        <module>ietf-inet-types</module>
+        <module>ietf-yang-types</module>
     </modules>
-</project>
\ No newline at end of file
+
+</project>
index 44f59bc36b915184a068859befae502189a0885d..2c14ea6d61d5280d85abf57c9e22018d210e3869 100644 (file)
@@ -1,18 +1,23 @@
 <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
-         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
-    <modelVersion>4.0.0</modelVersion>
+    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+
     <parent>
         <artifactId>yang-prototype</artifactId>
         <groupId>org.opendaylight.controller</groupId>
         <version>0.5-SNAPSHOT</version>
     </parent>
+
+    <modelVersion>4.0.0</modelVersion>
     <artifactId>model-parent</artifactId>
     <packaging>pom</packaging>
+    <name>${project.artifactId}</name>
+    <description>${project.artifactId}</description>
+
     <modules>
         <module>ietf</module>
         <module>model-topology</module>
         <module>model-openflow</module>
-        <!--module>model-topology-bgp</module-->
+        <!-- <module>model-topology-bgp</module> -->
     </modules>
 
     <build>
@@ -72,7 +77,8 @@
         </plugins>
         <pluginManagement>
             <plugins>
-                <!--This plugin's configuration is used to store Eclipse m2e settings only. It has no influence on the Maven build itself.-->
+                <!--This plugin's configuration is used to store Eclipse 
+                    m2e settings only. It has no influence on the Maven build itself. -->
                 <plugin>
                     <groupId>org.eclipse.m2e</groupId>
                     <artifactId>lifecycle-mapping</artifactId>
             </plugins>
         </pluginManagement>
     </build>
+
     <dependencies>
         <dependency>
             <groupId>org.opendaylight.controller</groupId>
             <version>0.5.4-SNAPSHOT</version>
         </dependency>
     </dependencies>
+
 </project>
diff --git a/opendaylight/sal/yang-prototype/model/src/site/site.xml b/opendaylight/sal/yang-prototype/model/src/site/site.xml
new file mode 100644 (file)
index 0000000..80ff3a4
--- /dev/null
@@ -0,0 +1,16 @@
+<project name="${project.name}">
+
+    <skin>
+        <groupId>org.apache.maven.skins</groupId>
+        <artifactId>maven-fluido-skin</artifactId>
+        <version>1.3.0</version>
+    </skin>
+
+    <body>
+        <menu ref="parent"/>
+        <menu ref="modules"/>
+        <menu ref="reports"/>
+    </body>
+
+</project>
+
index 741e2177ff9376cb8a1b80c555ec826ea751a6ab..2f2df0a04d676dd0ab947b8cc94bbe1b431704a6 100644 (file)
@@ -1,10 +1,63 @@
 <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
     xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+
     <modelVersion>4.0.0</modelVersion>
     <groupId>org.opendaylight.controller</groupId>
     <artifactId>yang-prototype</artifactId>
     <version>0.5-SNAPSHOT</version>
     <packaging>pom</packaging>
+    <name>${project.artifactId}</name>
+    <description>
+        YANG Tools is a infrastructure project aiming to develop necessary tooling and libraries providing support of
+        NETCONF and YANG for Java (JVM-language based) projects and applications, such as Model Driven SAL for 
+        Controller (which uses YANG as it's modeling language) and Netconf / OFConfig plugins. 
+    </description>
+
+    <developers>
+        <developer>
+            <id>ttkacik</id>
+            <name>Tony Tkacik</name>
+            <email>ttkacik@cisco.com</email>
+            <organization>OpenDaylight</organization>
+        </developer>
+        <developer>
+            <id>rovarga</id>
+            <name>Robert Varga</name>
+            <email>rovarga@cisco.com</email>
+            <organization>OpenDaylight</organization>
+        </developer>
+        <developer>
+            <id>lsedlak</id>
+            <name>Lukas Sedlak</name>
+            <email>lsedlak@cisco.com</email>
+            <organization>OpenDaylight</organization>
+        </developer>
+        <developer>
+            <id>mvitez</id>
+            <name>Martin Vitez</name>
+            <email>mvitez@cisco.com</email>
+            <organization>OpenDaylight</organization>
+        </developer>
+        <developer>
+            <id>jmedved</id>
+            <name>Jan Medved</name>
+            <email>jmedved@cisco.com</email>
+            <organization>OpenDaylight</organization>
+        </developer>
+        <developer>
+            <id>jgloncak</id>
+            <name>Jozef Gloncak</name>
+            <email>jgloncak@cisco.com</email>
+            <organization>OpenDaylight</organization>
+        </developer>
+        <developer>
+            <id>mirehak</id>
+            <name>Michal Rehak</name>
+            <email>mirehak@cisco.com</email>
+            <organization>OpenDaylight</organization>
+        </developer>
+    </developers>
+
     <modules>
         <module>concepts-lang</module>
         <module>yang</module>
@@ -17,6 +70,7 @@
         <nexusproxy>http://nexus.opendaylight.org/content</nexusproxy>
         <sitedeploy>dav:http://nexus.opendaylight.org/content/sites/site</sitedeploy>
         <siteplugin>3.2</siteplugin>
+        <defaultStylesheet>${project.basedir}/src/site/resources/stylesheet.css</defaultStylesheet>
         <projectinfo>2.6</projectinfo>
         <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
         <compiler.version>2.3.2</compiler.version>
             <name>ops4j-releases</name>
             <url>${nexusproxy}/repositories/ops4j-releases/</url>
         </repository>
-        <!-- Third Packages hosted in local maven because not available in other 
-            places -->
+        <!-- Third Packages hosted in local maven because not available in 
+            other places -->
         <repository>
             <id>thirdparty</id>
             <name>thirdparty</name>
             <id>opendaylight-snapshot</id>
             <url>${nexusproxy}/repositories/opendaylight.snapshot/</url>
         </snapshotRepository>
-        <!-- Site deployment -->
-        <!-- site>
-            <id>website</id>
-            <url>${sitedeploy}</url>
-        </site -->
+        <site>
+            <id>${project.artifactId}-site</id>
+            <url>./</url>
+        </site>
     </distributionManagement>
 
-
     <dependencyManagement>
         <dependencies>
             <dependency>
             </dependency>
         </dependencies>
     </dependencyManagement>
+
     <build>
         <plugins>
             <plugin>
                     <target>1.7</target>
                 </configuration>
             </plugin>
+            <plugin>
+                <artifactId>maven-source-plugin</artifactId>
+                <executions>
+                    <execution>
+                        <id>attach-sources</id>
+                        <phase>deploy</phase>
+                        <goals>
+                            <goal>jar-no-fork</goal>
+                        </goals>
+                    </execution>
+                </executions>
+            </plugin>
+            <plugin>
+                <!-- explicitly define maven-deploy-plugin after other to 
+                    force exec order -->
+                <artifactId>maven-deploy-plugin</artifactId>
+                <executions>
+                    <execution>
+                        <id>deploy</id>
+                        <phase>deploy</phase>
+                        <goals>
+                            <goal>deploy</goal>
+                        </goals>
+                    </execution>
+                </executions>
+            </plugin>
+
             <plugin>
                 <groupId>org.apache.maven.plugins</groupId>
                 <artifactId>maven-javadoc-plugin</artifactId>
-                <version>2.8.1</version>
                 <configuration>
-                    <stylesheet>maven</stylesheet>
+                    <stylesheetfile>${defaultStylesheet}</stylesheetfile>
+                    <excludePackageNames>
+                        *.opendaylight.controller.antlrv4.code.gen
+                    </excludePackageNames>
                 </configuration>
                 <executions>
                     <execution>
+                        <id>aggregate</id>
                         <goals>
                             <goal>aggregate</goal>
                         </goals>
                         <phase>site</phase>
-                    </execution> 
-                    <execution> 
-                          <id>attach-javadocs</id>
-                          <phase>deploy</phase>
-                          <goals><goal>jar</goal></goals> 
-                    </execution> 
-                </executions> 
-            </plugin>
-            <plugin>
-            <artifactId>maven-source-plugin</artifactId>
-                <executions>
+                    </execution>
                     <execution>
-                        <id>attach-sources</id>
+                        <id>attach-javadocs</id>
                         <phase>deploy</phase>
-                        <goals><goal>jar-no-fork</goal></goals> 
+                        <goals>
+                            <goal>jar</goal>
+                        </goals>
                     </execution>
-                 </executions>
+                </executions>
+            </plugin>
+
+            <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-site-plugin</artifactId>
+                <inherited>false</inherited>
+                <dependencies>
+                    <dependency>
+                        <groupId>org.apache.maven.doxia</groupId>
+                        <artifactId>doxia-module-markdown</artifactId>
+                        <version>1.3</version>
+                    </dependency>
+                </dependencies>
+                <configuration>
+                    <siteDirectory>${project.basedir}/src/site</siteDirectory>
+                    <inputEncoding>UTF-8</inputEncoding>
+                    <outputEncoding>UTF-8</outputEncoding>
+                </configuration>
             </plugin>
-            <plugin> 
-                <!-- explicitly define maven-deploy-plugin after other to force exec order -->
-                <artifactId>maven-deploy-plugin</artifactId> 
-                <executions> 
-                    <execution> 
-                        <id>deploy</id>
-                        <phase>deploy</phase>
-                        <goals><goal>deploy</goal></goals> 
-                    </execution> 
-                </executions> 
-            </plugin> 
         </plugins>
+
+        <pluginManagement>
+            <plugins>
+                <plugin>
+                    <groupId>org.apache.maven.plugins</groupId>
+                    <artifactId>maven-source-plugin</artifactId>
+                    <version>2.2.1</version>
+                </plugin>
+                <plugin>
+                    <groupId>org.apache.maven.plugins</groupId>
+                    <artifactId>maven-deploy-plugin</artifactId>
+                    <version>2.7</version>
+                </plugin>
+                <plugin>
+                    <groupId>org.apache.maven.plugins</groupId>
+                    <artifactId>maven-surefire-plugin</artifactId>
+                    <version>2.15</version>
+                </plugin>
+                <plugin>
+                    <groupId>org.apache.maven.plugins</groupId>
+                    <artifactId>maven-site-plugin</artifactId>
+                    <dependencies>
+                        <dependency>
+                            <groupId>org.apache.maven.doxia</groupId>
+                            <artifactId>doxia-module-markdown</artifactId>
+                            <version>1.3</version>
+                        </dependency>
+                    </dependencies>
+                    <configuration>
+                        <siteDirectory>${project.parent.basedir}/src/site</siteDirectory>
+                        <inputEncoding>UTF-8</inputEncoding>
+                        <outputEncoding>UTF-8</outputEncoding>
+                    </configuration>
+                </plugin>
+                <plugin>
+                    <groupId>org.apache.maven.plugins</groupId>
+                    <artifactId>maven-javadoc-plugin</artifactId>
+                    <version>2.9.1</version>
+                    <configuration>
+                        <stylesheetfile>${defaultStylesheet}</stylesheetfile>
+                    </configuration>
+                    <executions>
+                        <execution>
+                            <id>aggregate</id>
+                            <goals>
+                                <goal>aggregate</goal>
+                            </goals>
+                            <phase>site</phase>
+                        </execution>
+                        <execution>
+                            <id>attach-javadocs</id>
+                            <phase>deploy</phase>
+                            <goals>
+                                <goal>jar</goal>
+                            </goals>
+                        </execution>
+                    </executions>
+                </plugin>
+            </plugins>
+        </pluginManagement>
+
     </build>
+
     <reporting>
         <plugins>
+            <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-javadoc-plugin</artifactId>
+                <version>2.9.1</version>
+                <reportSets>
+                    <reportSet>
+                        <reports>
+                            <report>javadoc</report>
+                        </reports>
+                    </reportSet>
+                </reportSets>
+            </plugin>
             <plugin>
                 <groupId>org.codehaus.mojo</groupId>
                 <artifactId>findbugs-maven-plugin</artifactId>
             </plugin>
         </plugins>
     </reporting>
+
     <profiles>
         <profile>
             <id>viewbuild</id>
diff --git a/opendaylight/sal/yang-prototype/src/site/markdown/readme.md b/opendaylight/sal/yang-prototype/src/site/markdown/readme.md
new file mode 100644 (file)
index 0000000..1faff04
--- /dev/null
@@ -0,0 +1,24 @@
+YANG tools
+====================
+
+Project documentation
+---------------------
+
+### Description
+
+YANG Tools is a infrastructure project aiming to develop necessary tooling and libraries providing support of NETCONF and YANG for Java (JVM-language based) projects and applications, such as Model Driven SAL for Controller (which uses YANG as it's modeling language) and Netconf / OFConfig plugins. 
+
+### Scope
+
+The scope of YANG Tools includes:
+
+* Parser of YANG files
+* Java meta-model for YANG
+* Java binding for YANG
+* Maven plugin for processing YANG files
+* Infrastructure for code generators based on YANG
+* Validation of instance data (XML) based on YANG to RelaxNG mapping - RFC6110
+* Proof-of-concept, research and support for new YANG extensions, which are meant to be reused by other projects.
+* IDE related tools to assist in writing, using and developing YANG models
+* Libraries and supporting functionality for YANG API (REST APIs defined by the YANG model).
diff --git a/opendaylight/sal/yang-prototype/src/site/resources/stylesheet.css b/opendaylight/sal/yang-prototype/src/site/resources/stylesheet.css
new file mode 100644 (file)
index 0000000..1936586
--- /dev/null
@@ -0,0 +1,522 @@
+/* Javadoc style sheet */
+/*
+Overall document style
+*/
+body {
+    background-color:#ffffff;
+    color:#353833;
+    font-family:Arial, Helvetica, sans-serif;
+    font-size:76%;
+    margin:0;
+}
+a:link, a:visited {
+    text-decoration:none;
+    color:#4c6b87;
+}
+a:hover, a:focus {
+    text-decoration:none;
+    color:#bb7a2a;
+}
+a:active {
+    text-decoration:none;
+    color:#4c6b87;
+}
+a[name] {
+    color:#353833;
+}
+a[name]:hover {
+    text-decoration:none;
+    color:#353833;
+}
+pre {
+    font-size:1.3em;
+}
+h1 {
+    font-size:1.8em;
+}
+h2 {
+    font-size:1.5em;
+}
+h3 {
+    font-size:1.4em;
+}
+h4 {
+    font-size:1.3em;
+}
+h5 {
+    font-size:1.2em;
+}
+h6 {
+    font-size:1.1em;
+}
+ul {
+    list-style-type:disc;
+}
+code, tt {
+    font-size:1.2em;
+}
+dt code {
+    font-size:1.2em;
+}
+table tr td dt code {
+    font-size:1.2em;
+    vertical-align:top;
+}
+sup {
+    font-size:.6em;
+}
+/*
+Document title and Copyright styles
+*/
+.clear {
+    clear:both;
+    height:0px;
+    overflow:hidden;
+}
+.aboutLanguage {
+    float:right;
+    padding:0px 21px;
+    font-size:.8em;
+    z-index:200;
+    margin-top:-7px;
+}
+.legalCopy {
+    margin-left:.5em;
+}
+.bar a, .bar a:link, .bar a:visited, .bar a:active {
+    color:#FFFFFF;
+    text-decoration:none;
+}
+.bar a:hover, .bar a:focus {
+    color:#bb7a2a;
+}
+.tab {
+    background-color:#0066FF;
+    background-image:url(resources/titlebar.gif);
+    background-position:left top;
+    background-repeat:no-repeat;
+    color:#ffffff;
+    padding:8px;
+    width:5em;
+    font-weight:bold;
+}
+/*
+Navigation bar styles
+*/
+.bar {
+    background-image:url(resources/background.gif);
+    background-repeat:repeat-x;
+    color:#FFFFFF;
+    padding:.8em .5em .4em .8em;
+    height:auto;/*height:1.8em;*/
+    font-size:1em;
+    margin:0;
+}
+.topNav {
+    background-image:url(resources/background.gif);
+    background-repeat:repeat-x;
+    color:#FFFFFF;
+    float:left;
+    padding:0;
+    width:100%;
+    clear:right;
+    height:2.8em;
+    padding-top:10px;
+    overflow:hidden;
+}
+.bottomNav {
+    margin-top:10px;
+    background-image:url(resources/background.gif);
+    background-repeat:repeat-x;
+    color:#FFFFFF;
+    float:left;
+    padding:0;
+    width:100%;
+    clear:right;
+    height:2.8em;
+    padding-top:10px;
+    overflow:hidden;
+}
+.subNav {
+    background-color:#dee3e9;
+    border-bottom:1px solid #9eadc0;
+    float:left;
+    width:100%;
+    overflow:hidden;
+}
+.subNav div {
+    clear:left;
+    float:left;
+    padding:0 0 5px 6px;
+}
+ul.navList, ul.subNavList {
+    float:left;
+    margin:0 25px 0 0;
+    padding:0;
+}
+ul.navList li{
+    list-style:none;
+    float:left;
+    padding:3px 6px;
+}
+ul.subNavList li{
+    list-style:none;
+    float:left;
+    font-size:90%;
+}
+.topNav a:link, .topNav a:active, .topNav a:visited, .bottomNav a:link, .bottomNav a:active, .bottomNav a:visited {
+    color:#FFFFFF;
+    text-decoration:none;
+}
+.topNav a:hover, .bottomNav a:hover {
+    text-decoration:none;
+    color:#bb7a2a;
+}
+.navBarCell1Rev {
+    background-image:url(resources/tab.gif);
+    background-color:#a88834;
+    color:#FFFFFF;
+    margin: auto 5px;
+    border:1px solid #c9aa44;
+}
+/*
+Page header and footer styles
+*/
+.header, .footer {
+    clear:both;
+    margin:0 20px;
+    padding:5px 0 0 0;
+}
+.indexHeader {
+    margin:10px;
+    position:relative;
+}
+.indexHeader span{
+    margin-right:15px;
+}
+.indexHeader h1 {
+    font-size:1.3em;
+}
+.title {
+    color:#2c4557;
+    margin:10px 0;
+}
+.subTitle {
+    margin:5px 0 0 0;
+}
+.header ul {
+    margin:0 0 25px 0;
+    padding:0;
+}
+.footer ul {
+    margin:20px 0 5px 0;
+}
+.header ul li, .footer ul li {
+    list-style:none;
+    font-size:1.2em;
+}
+/*
+Heading styles
+*/
+div.details ul.blockList ul.blockList ul.blockList li.blockList h4, div.details ul.blockList ul.blockList ul.blockListLast li.blockList h4 {
+    background-color:#dee3e9;
+    border-top:1px solid #9eadc0;
+    border-bottom:1px solid #9eadc0;
+    margin:0 0 6px -8px;
+    padding:2px 5px;
+}
+ul.blockList ul.blockList ul.blockList li.blockList h3 {
+    background-color:#dee3e9;
+    border-top:1px solid #9eadc0;
+    border-bottom:1px solid #9eadc0;
+    margin:0 0 6px -8px;
+    padding:2px 5px;
+}
+ul.blockList ul.blockList li.blockList h3 {
+    padding:0;
+    margin:15px 0;
+}
+ul.blockList li.blockList h2 {
+    padding:0px 0 20px 0;
+}
+/*
+Page layout container styles
+*/
+.contentContainer, .sourceContainer, .classUseContainer, .serializedFormContainer, .constantValuesContainer {
+    clear:both;
+    padding:10px 20px;
+    position:relative;
+}
+.indexContainer {
+    margin:10px;
+    position:relative;
+    font-size:1.0em;
+}
+.indexContainer h2 {
+    font-size:1.1em;
+    padding:0 0 3px 0;
+}
+.indexContainer ul {
+    margin:0;
+    padding:0;
+}
+.indexContainer ul li {
+    list-style:none;
+}
+.contentContainer .description dl dt, .contentContainer .details dl dt, .serializedFormContainer dl dt {
+    font-size:1.1em;
+    font-weight:bold;
+    margin:10px 0 0 0;
+    color:#4E4E4E;
+}
+.contentContainer .description dl dd, .contentContainer .details dl dd, .serializedFormContainer dl dd {
+    margin:10px 0 10px 20px;
+}
+.serializedFormContainer dl.nameValue dt {
+    margin-left:1px;
+    font-size:1.1em;
+    display:inline;
+    font-weight:bold;
+}
+.serializedFormContainer dl.nameValue dd {
+    margin:0 0 0 1px;
+    font-size:1.1em;
+    display:inline;
+}
+/*
+List styles
+*/
+ul.horizontal li {
+    display:inline;
+    font-size:0.9em;
+}
+ul.inheritance {
+    margin:0;
+    padding:0;
+}
+ul.inheritance li {
+    display:inline;
+    list-style:none;
+}
+ul.inheritance li ul.inheritance {
+    margin-left:15px;
+    padding-left:15px;
+    padding-top:1px;
+}
+ul.blockList, ul.blockListLast {
+    margin:10px 0 10px 0;
+    padding:0;
+}
+ul.blockList li.blockList, ul.blockListLast li.blockList {
+    list-style:none;
+    margin-bottom:25px;
+}
+ul.blockList ul.blockList li.blockList, ul.blockList ul.blockListLast li.blockList {
+    padding:0px 20px 5px 10px;
+    border:1px solid #9eadc0;
+    background-color:#f9f9f9;
+}
+ul.blockList ul.blockList ul.blockList li.blockList, ul.blockList ul.blockList ul.blockListLast li.blockList {
+    padding:0 0 5px 8px;
+    background-color:#ffffff;
+    border:1px solid #9eadc0;
+    border-top:none;
+}
+ul.blockList ul.blockList ul.blockList ul.blockList li.blockList {
+    margin-left:0;
+    padding-left:0;
+    padding-bottom:15px;
+    border:none;
+    border-bottom:1px solid #9eadc0;
+}
+ul.blockList ul.blockList ul.blockList ul.blockList li.blockListLast {
+    list-style:none;
+    border-bottom:none;
+    padding-bottom:0;
+}
+table tr td dl, table tr td dl dt, table tr td dl dd {
+    margin-top:0;
+    margin-bottom:1px;
+}
+/*
+Table styles
+*/
+.contentContainer table, .classUseContainer table, .constantValuesContainer table {
+    border-bottom:1px solid #9eadc0;
+    width:100%;
+}
+.contentContainer ul li table, .classUseContainer ul li table, .constantValuesContainer ul li table {
+    width:100%;
+}
+.contentContainer .description table, .contentContainer .details table {
+    border-bottom:none;
+}
+.contentContainer ul li table th.colOne, .contentContainer ul li table th.colFirst, .contentContainer ul li table th.colLast, .classUseContainer ul li table th, .constantValuesContainer ul li table th, .contentContainer ul li table td.colOne, .contentContainer ul li table td.colFirst, .contentContainer ul li table td.colLast, .classUseContainer ul li table td, .constantValuesContainer ul li table td{
+    vertical-align:top;
+    padding-right:20px;
+}
+.contentContainer ul li table th.colLast, .classUseContainer ul li table th.colLast,.constantValuesContainer ul li table th.colLast,
+.contentContainer ul li table td.colLast, .classUseContainer ul li table td.colLast,.constantValuesContainer ul li table td.colLast,
+.contentContainer ul li table th.colOne, .classUseContainer ul li table th.colOne,
+.contentContainer ul li table td.colOne, .classUseContainer ul li table td.colOne {
+    padding-right:3px;
+}
+.overviewSummary caption, .packageSummary caption, .contentContainer ul.blockList li.blockList caption, .summary caption, .classUseContainer caption, .constantValuesContainer caption {
+    position:relative;
+    text-align:left;
+    background-repeat:no-repeat;
+    color:#FFFFFF;
+    font-weight:bold;
+    clear:none;
+    overflow:hidden;
+    padding:0px;
+    margin:0px;
+    white-space:pre;
+}
+caption a:link, caption a:hover, caption a:active, caption a:visited {
+    color:#FFFFFF;
+}
+.overviewSummary caption span, .packageSummary caption span, .contentContainer ul.blockList li.blockList caption span, .summary caption span, .classUseContainer caption span, .constantValuesContainer caption span {
+    white-space:nowrap;
+    padding-top:8px;
+    padding-left:8px;
+    display:block;
+    float:left;
+    background-image:url(resources/titlebar.gif);
+    height:18px;
+}
+.contentContainer ul.blockList li.blockList caption span.activeTableTab span {
+    white-space:nowrap;
+    padding-top:8px;
+    padding-left:8px;
+    display:block;
+    float:left;
+    background-image:url(resources/activetitlebar.gif);
+    height:18px;
+}
+.contentContainer ul.blockList li.blockList caption span.tableTab span {
+    white-space:nowrap;
+    padding-top:8px;
+    padding-left:8px;
+    display:block;
+    float:left;
+    background-image:url(resources/titlebar.gif);
+    height:18px;
+}
+.contentContainer ul.blockList li.blockList caption span.tableTab, .contentContainer ul.blockList li.blockList caption span.activeTableTab {
+    padding-top:0px;
+    padding-left:0px;
+    background-image:none;
+    float:none;
+    display:inline;
+}
+.overviewSummary .tabEnd, .packageSummary .tabEnd, .contentContainer ul.blockList li.blockList .tabEnd, .summary .tabEnd, .classUseContainer .tabEnd, .constantValuesContainer .tabEnd {
+    width:10px;
+    background-image:url(resources/titlebar_end.gif);
+    background-repeat:no-repeat;
+    background-position:top right;
+    position:relative;
+    float:left;
+}
+.contentContainer ul.blockList li.blockList .activeTableTab .tabEnd {
+    width:10px;
+    margin-right:5px;
+    background-image:url(resources/activetitlebar_end.gif);
+    background-repeat:no-repeat;
+    background-position:top right;
+    position:relative;
+    float:left;
+}
+.contentContainer ul.blockList li.blockList .tableTab .tabEnd {
+    width:10px;
+    margin-right:5px;
+    background-image:url(resources/titlebar_end.gif);
+    background-repeat:no-repeat;
+    background-position:top right;
+    position:relative;
+    float:left;
+}
+ul.blockList ul.blockList li.blockList table {
+    margin:0 0 12px 0px;
+    width:100%;
+}
+.tableSubHeadingColor {
+    background-color: #EEEEFF;
+}
+.altColor {
+    background-color:#eeeeef;
+}
+.rowColor {
+    background-color:#ffffff;
+}
+.overviewSummary td, .packageSummary td, .contentContainer ul.blockList li.blockList td, .summary td, .classUseContainer td, .constantValuesContainer td {
+    text-align:left;
+    padding:3px 3px 3px 7px;
+}
+th.colFirst, th.colLast, th.colOne, .constantValuesContainer th {
+    background:#dee3e9;
+    border-top:1px solid #9eadc0;
+    border-bottom:1px solid #9eadc0;
+    text-align:left;
+    padding:3px 3px 3px 7px;
+}
+td.colOne a:link, td.colOne a:active, td.colOne a:visited, td.colOne a:hover, td.colFirst a:link, td.colFirst a:active, td.colFirst a:visited, td.colFirst a:hover, td.colLast a:link, td.colLast a:active, td.colLast a:visited, td.colLast a:hover, .constantValuesContainer td a:link, .constantValuesContainer td a:active, .constantValuesContainer td a:visited, .constantValuesContainer td a:hover {
+    font-weight:bold;
+}
+td.colFirst, th.colFirst {
+    border-left:1px solid #9eadc0;
+    white-space:nowrap;
+}
+td.colLast, th.colLast {
+    border-right:1px solid #9eadc0;
+}
+td.colOne, th.colOne {
+    border-right:1px solid #9eadc0;
+    border-left:1px solid #9eadc0;
+}
+table.overviewSummary  {
+    padding:0px;
+    margin-left:0px;
+}
+table.overviewSummary td.colFirst, table.overviewSummary th.colFirst,
+table.overviewSummary td.colOne, table.overviewSummary th.colOne {
+    width:25%;
+    vertical-align:middle;
+}
+table.packageSummary td.colFirst, table.overviewSummary th.colFirst {
+    width:25%;
+    vertical-align:middle;
+}
+/*
+Content styles
+*/
+.description pre {
+    margin-top:0;
+}
+.deprecatedContent {
+    margin:0;
+    padding:10px 0;
+}
+.docSummary {
+    padding:0;
+}
+/*
+Formatting effect styles
+*/
+.sourceLineNo {
+    color:green;
+    padding:0 30px 0 0;
+}
+h1.hidden {
+    visibility:hidden;
+    overflow:hidden;
+    font-size:.9em;
+}
+.block {
+    display:block;
+    margin:3px 0 0 0;
+}
+.strong {
+    font-weight:bold;
+}
+
diff --git a/opendaylight/sal/yang-prototype/src/site/site.xml b/opendaylight/sal/yang-prototype/src/site/site.xml
new file mode 100644 (file)
index 0000000..6957e2e
--- /dev/null
@@ -0,0 +1,18 @@
+<project name="${project.name}">
+
+    <skin>
+        <groupId>org.apache.maven.skins</groupId>
+        <artifactId>maven-fluido-skin</artifactId>
+        <version>1.3.0</version>
+    </skin>
+
+    <body>
+        <menu ref="parent"/>
+        <menu ref="modules"/>
+        <menu ref="reports"/>
+        <menu name="Overview">
+            <item name="Readme" href="readme.html" />
+        </menu>
+    </body>
+
+</project>
similarity index 95%
rename from opendaylight/sal/yang-prototype/code-generator/maven-yang-plugin-it/pom.xml
rename to opendaylight/sal/yang-prototype/yang/maven-yang-plugin-it/pom.xml
index 0fb693380ad65a785cad3fd35a7ed04c52c0fe54..bec1acb110256e9f66c534317a7cde9d80418a2d 100644 (file)
@@ -5,7 +5,6 @@
         <artifactId>yang</artifactId>
         <groupId>org.opendaylight.controller</groupId>
         <version>0.5.4-SNAPSHOT</version>
-        <relativePath>../../yang/pom.xml</relativePath>
     </parent>
     <artifactId>yang-maven-plugin-it</artifactId>
 
similarity index 98%
rename from opendaylight/sal/yang-prototype/code-generator/maven-yang-plugin/pom.xml
rename to opendaylight/sal/yang-prototype/yang/maven-yang-plugin/pom.xml
index 8fa00dd665a6785d3b834d1aeb14ee140e105fc2..444fa1fc3f05e94a97e812166d2dd08f91f1f13a 100644 (file)
@@ -5,7 +5,6 @@
         <artifactId>yang</artifactId>
         <groupId>org.opendaylight.controller</groupId>
         <version>0.5.4-SNAPSHOT</version>
-        <relativePath>../../yang/pom.xml</relativePath>
     </parent>
 
     <artifactId>yang-maven-plugin</artifactId>
similarity index 94%
rename from opendaylight/sal/yang-prototype/code-generator/maven-yang/pom.xml
rename to opendaylight/sal/yang-prototype/yang/maven-yang/pom.xml
index a8a45519ac814264b46917efbad1ad5c10d699e3..6754c8c3c4c05c4eadc120ccf2ca6331c9e6c80e 100644 (file)
@@ -1,13 +1,17 @@
 <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
     xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
-    <modelVersion>4.0.0</modelVersion>
+
     <parent>
         <artifactId>yang</artifactId>
         <groupId>org.opendaylight.controller</groupId>
         <version>0.5.4-SNAPSHOT</version>
-        <relativePath>../../yang/pom.xml</relativePath>
     </parent>
+
+    <modelVersion>4.0.0</modelVersion>
     <artifactId>yang-maven-plugin-spi</artifactId>
+    <name>${project.artifactId}</name>
+    <description>${project.artifactId}</description>
+
     <dependencies>
         <dependency>
             <groupId>org.opendaylight.controller</groupId>
@@ -43,4 +47,5 @@
             </plugin>
         </plugins>
     </build>
+
 </project>
@@ -34,13 +34,11 @@ public interface CodeGenerator {
      *            user
      * @param currentModules
      *            yang modules parsed from yangFilesRootDir
-     * @param log
-     *            maven logger
      * @return collection of files that were generated from schema context
      * @throws IOException
      */
-    Collection<File> generateSources(SchemaContext context, File outputBaseDir,
-            Set<Module> currentModules) throws IOException;
+    Collection<File> generateSources(SchemaContext context, File outputBaseDir, Set<Module> currentModules)
+            throws IOException;
 
     /**
      * Utilize maven logging if necessary
@@ -69,7 +67,7 @@ public interface CodeGenerator {
      * Provided maven project object. Any additional information about current
      * maven project can be accessed from it.
      *
-     * @param resourceBaseDir
+     * @param project
      */
     void setMavenProject(MavenProject project);
 }
index fc506049946eab15cb02fd307ddac6e72712423f..5c3617c98856ad86247025d58d490c7b94aa1064 100644 (file)
         <module>yang-common</module>
         <module>yang-data-api</module>
         <module>yang-data-util</module>
-               <module>yang-data-impl</module>
+        <module>yang-data-impl</module>
         <module>yang-model-api</module>
         <module>yang-model-util</module>
         <module>yang-binding</module>
         <module>yang-ext</module>
-        <module>../code-generator/yang-model-parser-api</module>
-        <module>../code-generator/yang-model-parser-impl</module>
-        <module>../code-generator/maven-yang</module>
-        <module>../code-generator/maven-yang-plugin</module>
-        <module>../code-generator/maven-yang-plugin-it</module>
+        <module>yang-model-parser-api</module>
+        <module>yang-model-parser-impl</module>
+        <module>maven-yang</module>
+        <module>maven-yang-plugin</module>
+        <module>maven-yang-plugin-it</module>
     </modules>
 
     <dependencyManagement>
             <plugin>
                 <groupId>org.apache.maven.plugins</groupId>
                 <artifactId>maven-javadoc-plugin</artifactId>
-                <version>2.8.1</version>
                 <configuration>
                     <stylesheet>maven</stylesheet>
                 </configuration>
             </plugin>
         </plugins>
     </build>
+
     <reporting>
         <plugins>
             <plugin>
             </plugin>
         </plugins>
     </reporting>
+
 </project>
diff --git a/opendaylight/sal/yang-prototype/yang/src/site/site.xml b/opendaylight/sal/yang-prototype/yang/src/site/site.xml
new file mode 100644 (file)
index 0000000..80ff3a4
--- /dev/null
@@ -0,0 +1,16 @@
+<project name="${project.name}">
+
+    <skin>
+        <groupId>org.apache.maven.skins</groupId>
+        <artifactId>maven-fluido-skin</artifactId>
+        <version>1.3.0</version>
+    </skin>
+
+    <body>
+        <menu ref="parent"/>
+        <menu ref="modules"/>
+        <menu ref="reports"/>
+    </body>
+
+</project>
+
index 79add782544be821f3fc57edb55cf1e6eaf6cb9d..70b7a5a311d217bd0119d9da85f3975c1ce800d2 100644 (file)
@@ -1,9 +1,15 @@
-<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">\r
-  <modelVersion>4.0.0</modelVersion>\r
-  <parent>\r
-    <groupId>org.opendaylight.controller</groupId>\r
-    <artifactId>yang</artifactId>\r
-    <version>0.5.4-SNAPSHOT</version>\r
-  </parent>\r
-  <artifactId>yang-binding</artifactId>\r
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"\r
+    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">\r
+\r
+    <parent>\r
+        <groupId>org.opendaylight.controller</groupId>\r
+        <artifactId>yang</artifactId>\r
+        <version>0.5.4-SNAPSHOT</version>\r
+    </parent>\r
+\r
+    <modelVersion>4.0.0</modelVersion>\r
+    <artifactId>yang-binding</artifactId>\r
+    <name>${project.artifactId}</name>\r
+    <description>Java binding for YANG</description>\r
+\r
 </project>\r
index a94013b288957a9cbd3ba907a41d0792013f9340..445e310a2a624546f235834ecc1491a047ea44ef 100644 (file)
@@ -1,16 +1,23 @@
-<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">\r
-  <modelVersion>4.0.0</modelVersion>\r
-  <parent>\r
-    <groupId>org.opendaylight.controller</groupId>\r
-    <artifactId>yang</artifactId>\r
-    <version>0.5.4-SNAPSHOT</version>\r
-  </parent>\r
-  <artifactId>yang-common</artifactId>\r
-  <dependencies>\r
-      <dependency>\r
-          <groupId>org.slf4j</groupId>\r
-          <artifactId>slf4j-api</artifactId>\r
-          <version>${slf4j.version}</version>\r
-      </dependency>\r
-  </dependencies>\r
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"\r
+    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">\r
+\r
+    <parent>\r
+        <groupId>org.opendaylight.controller</groupId>\r
+        <artifactId>yang</artifactId>\r
+        <version>0.5.4-SNAPSHOT</version>\r
+    </parent>\r
+\r
+    <modelVersion>4.0.0</modelVersion>\r
+    <artifactId>yang-common</artifactId>\r
+    <name>${project.artifactId}</name>\r
+    <description>${project.artifactId}</description>\r
+\r
+    <dependencies>\r
+        <dependency>\r
+            <groupId>org.slf4j</groupId>\r
+            <artifactId>slf4j-api</artifactId>\r
+        </dependency>\r
+    </dependencies>\r
+\r
 </project>\r
+\r
index 28f25946ba6dee9a4bd07688e20cf7a07de9112a..145daf9561a0554f81087e34e8ab65e3e6b96a1b 100644 (file)
@@ -1,12 +1,16 @@
 <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"\r
     xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">\r
-    <modelVersion>4.0.0</modelVersion>\r
+\r
     <parent>\r
         <groupId>org.opendaylight.controller</groupId>\r
         <artifactId>yang</artifactId>\r
         <version>0.5.4-SNAPSHOT</version>\r
     </parent>\r
+\r
+    <modelVersion>4.0.0</modelVersion>\r
     <artifactId>yang-data-api</artifactId>\r
+    <name>${project.artifactId}</name>\r
+    <description>${project.artifactId}</description>\r
 \r
     <dependencies>\r
         <dependency>\r
@@ -14,4 +18,5 @@
             <artifactId>yang-common</artifactId>\r
         </dependency>\r
     </dependencies>\r
-</project>
\ No newline at end of file
+\r
+</project>\r
index dfc790e0bddb7f140562ea794ec33e49dfbe2d15..e8ef4067641ac65f37c663a304bcc8dca7027eb5 100644 (file)
@@ -29,7 +29,7 @@ import org.opendaylight.controller.yang.common.QName;
  * \r
  * \r
  */\r
-public interface CompositeNode extends Node<List<Node<?>>> {\r
+public interface CompositeNode extends Node<List<Node<?>>>, NodeModification {\r
 \r
     List<Node<?>> getChildren();\r
 \r
@@ -45,4 +45,8 @@ public interface CompositeNode extends Node<List<Node<?>>> {
 \r
     SimpleNode<?> getFirstSimpleByName(QName leaf);\r
 \r
+    /**\r
+     * @return cast self to mutable, if possible \r
+     */\r
+    MutableCompositeNode asMutable();\r
 }\r
index b1baf309c5de1ead51f67a94cc5779e65e7e0114..4f11adbc174c9b2220c1464b41fbf6a997373cfa 100755 (executable)
@@ -20,4 +20,9 @@ public interface MutableCompositeNode extends MutableNode<List<Node<?>>>, Compos
      * update internal map\r
      */\r
     public void init();\r
+    \r
+    /**\r
+     * @return original node, if available\r
+     */\r
+    CompositeNode getOriginal();\r
 }\r
index 9519fac7922c197e42d774cc130ed42bf5efbad3..ad25f8f380d3eed5ee115d79ce1713bd6b0dc89d 100755 (executable)
@@ -15,6 +15,9 @@ package org.opendaylight.controller.yang.data.api;
  */\r
 public interface MutableSimpleNode<T> extends MutableNode<T>, SimpleNode<T> {\r
     \r
-   // nothing\r
+    /**\r
+     * @return original node, if available\r
+     */\r
+    SimpleNode<T> getOriginal();\r
     \r
 }\r
index 717c7224ee824484f0302ae75546d9bbee6d6aed..3f75da5203c84fe39e0bf07c6fb68e97ee47ef48 100644 (file)
@@ -21,6 +21,10 @@ package org.opendaylight.controller.yang.data.api;
  * \r
  * @param <T>\r
  */\r
-public interface SimpleNode<T> extends Node<T> {\r
+public interface SimpleNode<T> extends Node<T>, NodeModification {\r
 \r
+    /**\r
+     * @return cast self to mutable, if possible \r
+     */\r
+    MutableSimpleNode<T> asMutable();\r
 }\r
old mode 100755 (executable)
new mode 100644 (file)
index 41fd113..ca5bd5c
@@ -1,32 +1,33 @@
-<project xmlns="http://maven.apache.org/POM/4.0.0"\r
-    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"\r
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"\r
     xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">\r
-    <modelVersion>4.0.0</modelVersion>\r
+\r
     <parent>\r
         <groupId>org.opendaylight.controller</groupId>\r
         <artifactId>yang</artifactId>\r
         <version>0.5.4-SNAPSHOT</version>\r
     </parent>\r
+\r
+    <modelVersion>4.0.0</modelVersion>\r
     <artifactId>yang-data-impl</artifactId>\r
+    <name>${project.artifactId}</name>\r
+    <description>${project.artifactId}</description>\r
 \r
     <properties>\r
-        <groovy.version>2.1.5</groovy.version>\r
+        <groovy.version>2.1.6</groovy.version>\r
     </properties>\r
-\r
     <build>\r
         <plugins>\r
             <plugin>\r
                 <groupId>org.apache.maven.plugins</groupId>\r
                 <artifactId>maven-surefire-plugin</artifactId>\r
                 <configuration>\r
-                    <argLine>-Dlog4j.configuration=log4j-test.xml</argLine>\r
+                    <argLine>-Dlog4j.configuration=log4j-test.xml -Xmx1500m</argLine>\r
                     <redirectTestOutputToFile>true</redirectTestOutputToFile>\r
                 </configuration>\r
             </plugin>\r
         </plugins>\r
     </build>\r
 \r
-\r
     <dependencies>\r
         <dependency>\r
             <groupId>org.opendaylight.controller</groupId>\r
         <dependency>\r
             <groupId>org.opendaylight.controller</groupId>\r
             <artifactId>yang-model-parser-impl</artifactId>\r
+            <exclusions>\r
+                <exclusion>\r
+                    <groupId>org.slf4j</groupId>\r
+                    <artifactId>slf4j-simple</artifactId>\r
+                </exclusion>\r
+            </exclusions>\r
         </dependency>\r
         <dependency>\r
             <groupId>com.google.guava</groupId>\r
             <artifactId>guava</artifactId>\r
             <version>14.0.1</version>\r
         </dependency>\r
+        \r
         <dependency>\r
             <groupId>junit</groupId>\r
             <artifactId>junit</artifactId>\r
             <version>${groovy.version}</version>\r
             <scope>test</scope>\r
         </dependency>\r
+        <dependency>\r
+            <groupId>xmlunit</groupId>\r
+            <artifactId>xmlunit</artifactId>\r
+            <version>1.4</version>\r
+            <scope>test</scope>\r
+        </dependency>\r
     </dependencies>\r
+\r
 </project>\r
old mode 100755 (executable)
new mode 100644 (file)
index cc4dfee..3385700
@@ -9,7 +9,9 @@ package org.opendaylight.controller.yang.data.impl;
 \r
 import org.opendaylight.controller.yang.common.QName;\r
 import org.opendaylight.controller.yang.data.api.CompositeNode;\r
+import org.opendaylight.controller.yang.data.api.ModifyAction;\r
 import org.opendaylight.controller.yang.data.api.Node;\r
+import org.opendaylight.controller.yang.data.api.NodeModification;\r
 \r
 /**\r
  * @author michal.rehak\r
@@ -17,12 +19,13 @@ import org.opendaylight.controller.yang.data.api.Node;
  *            type of node value\r
  * \r
  */\r
-public abstract class AbstractNodeTO<T> implements Node<T> {\r
+public abstract class AbstractNodeTO<T> implements Node<T>, NodeModification {\r
 \r
     private QName qName;\r
     private CompositeNode parent;\r
     private T value;\r
-\r
+    private ModifyAction modifyAction;\r
+    \r
     /**\r
      * @param qname\r
      * @param parent\r
@@ -33,6 +36,19 @@ public abstract class AbstractNodeTO<T> implements Node<T> {
         this.parent = parent;\r
         this.value = value;\r
     }\r
+    \r
+    /**\r
+     * @param qname\r
+     * @param parent\r
+     * @param value\r
+     * @param modifyAction \r
+     */\r
+    public AbstractNodeTO(QName qname, CompositeNode parent, T value, ModifyAction modifyAction) {\r
+        this.qName = qname;\r
+        this.parent = parent;\r
+        this.value = value;\r
+        this.modifyAction = modifyAction;\r
+    }\r
 \r
     @Override\r
     public QName getNodeType() {\r
@@ -42,7 +58,7 @@ public abstract class AbstractNodeTO<T> implements Node<T> {
     /**\r
      * @return the qName\r
      */\r
-    protected QName getQName() {\r
+    public QName getQName() {\r
         return qName;\r
     }\r
 \r
@@ -69,4 +85,76 @@ public abstract class AbstractNodeTO<T> implements Node<T> {
     public T getValue() {\r
         return value;\r
     }\r
+\r
+    /**\r
+     * @return modification action\r
+     * @see org.opendaylight.controller.yang.data.impl.NodeModificationSupport#getModificationAction()\r
+     */\r
+    @Override\r
+    public ModifyAction getModificationAction() {\r
+        return modifyAction;\r
+    }\r
+\r
+    /**\r
+     * @param modifyAction\r
+     *            the modifyAction to set\r
+     */\r
+    protected void setModificationAction(ModifyAction modifyAction) {\r
+        this.modifyAction = modifyAction;\r
+    }\r
+    \r
+    @Override\r
+    public String toString() {\r
+        StringBuffer out = new StringBuffer();\r
+        out.append(String.format("Node[%s], qName[%s], modify[%s]", \r
+                getClass().getSimpleName(), getQName().getLocalName(),\r
+                getModificationAction() == null ? "n/a" : getModificationAction()));\r
+        return out.toString();\r
+    }\r
+\r
+    /* */\r
+    @Override\r
+    public int hashCode() {\r
+        final int prime = 31;\r
+        int result = 1;\r
+        result = prime * result\r
+                + ((modifyAction == null) ? 0 : modifyAction.hashCode());\r
+//        result = prime * result + ((parent == null) ? 0 : parent.hashCode());\r
+        result = prime * result + ((qName == null) ? 0 : qName.hashCode());\r
+        result = prime * result + ((value == null) ? 0 : value.hashCode());\r
+        return result % 2;\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
+        @SuppressWarnings("unchecked")\r
+        AbstractNodeTO<T> other = (AbstractNodeTO<T>) obj;\r
+        if (modifyAction != other.modifyAction)\r
+            return false;\r
+        if (parent == null) {\r
+            if (other.parent != null)\r
+                return false;\r
+        } else if (other.parent == null) {\r
+            return false;\r
+        } \r
+        if (qName == null) {\r
+            if (other.qName != null)\r
+                return false;\r
+        } else if (!qName.equals(other.qName))\r
+            return false;\r
+        if (value == null) {\r
+            if (other.value != null)\r
+                return false;\r
+        } else if (!value.equals(other.value))\r
+            return false;\r
+        return true;\r
+    }\r
+    /* */\r
+    \r
 }\r
index 7981df2f204f110bf87f2c484aca83d36dd08bc3..44c8c852f5a49d4361b5d2552f6bf1ce32a8588c 100755 (executable)
@@ -1,5 +1,9 @@
-/**\r
- * \r
+/*\r
+ * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.\r
+ *\r
+ * This program and the accompanying materials are made available under the\r
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,\r
+ * and is available at http://www.eclipse.org/legal/epl-v10.html\r
  */\r
 package org.opendaylight.controller.yang.data.impl;\r
 \r
@@ -9,16 +13,12 @@ import org.opendaylight.controller.yang.common.QName;
 import org.opendaylight.controller.yang.data.api.CompositeNode;\r
 import org.opendaylight.controller.yang.data.api.ModifyAction;\r
 import org.opendaylight.controller.yang.data.api.Node;\r
-import org.opendaylight.controller.yang.data.api.NodeModification;\r
 \r
 /**\r
  * @author michal.rehak\r
  * \r
  */\r
-public class CompositeNodeModificationTOImpl extends CompositeNodeTOImpl\r
-        implements NodeModification {\r
-\r
-    private ModifyAction modifyAction;\r
+public class CompositeNodeModificationTOImpl extends CompositeNodeTOImpl {\r
 \r
     /**\r
      * @param qname\r
@@ -29,24 +29,6 @@ public class CompositeNodeModificationTOImpl extends CompositeNodeTOImpl
     public CompositeNodeModificationTOImpl(QName qname, CompositeNode parent,\r
             List<Node<?>> value, ModifyAction modifyAction) {\r
         super(qname, parent, value);\r
-        this.modifyAction = modifyAction;\r
-    }\r
-\r
-    /**\r
-     * @return modification action\r
-     * @see org.opendaylight.controller.yang.data.impl.NodeModificationSupport#getModificationAction()\r
-     */\r
-    @Override\r
-    public ModifyAction getModificationAction() {\r
-        return modifyAction;\r
+        super.setModificationAction(modifyAction);\r
     }\r
-\r
-    /**\r
-     * @param modifyAction\r
-     *            the modifyAction to set\r
-     */\r
-    protected void setModificationAction(ModifyAction modifyAction) {\r
-        this.modifyAction = modifyAction;\r
-    }\r
-\r
 }\r
old mode 100755 (executable)
new mode 100644 (file)
index f94163a..605b99c
@@ -13,6 +13,8 @@ import java.util.Map;
 \r
 import org.opendaylight.controller.yang.common.QName;\r
 import org.opendaylight.controller.yang.data.api.CompositeNode;\r
+import org.opendaylight.controller.yang.data.api.ModifyAction;\r
+import org.opendaylight.controller.yang.data.api.MutableCompositeNode;\r
 import org.opendaylight.controller.yang.data.api.Node;\r
 import org.opendaylight.controller.yang.data.api.SimpleNode;\r
 \r
@@ -36,6 +38,19 @@ public class CompositeNodeTOImpl extends AbstractNodeTO<List<Node<?>>>
         if (value != null) {\r
             nodeMap = NodeUtils.buildNodeMap(getValue());\r
         }\r
+        init();\r
+    }\r
+\r
+    /**\r
+     * @param qname\r
+     * @param parent use null to create top composite node (without parent)\r
+     * @param value\r
+     * @param modifyAction \r
+     */\r
+    public CompositeNodeTOImpl(QName qname, CompositeNode parent,\r
+            List<Node<?>> value, ModifyAction modifyAction) {\r
+        super(qname, parent, value, modifyAction);\r
+        init();\r
     }\r
     \r
 \r
@@ -105,16 +120,34 @@ public class CompositeNodeTOImpl extends AbstractNodeTO<List<Node<?>>>
 \r
     @Override\r
     public List<CompositeNode> getCompositesByName(String children) {\r
-        return getCompositesByName(localQName(children));\r
+        return getCompositesByName(new QName(getNodeType(), children));\r
     }\r
     \r
     @Override\r
     public List<SimpleNode<?>> getSimpleNodesByName(String children) {\r
-        return getSimpleNodesByName(localQName(children));\r
+        return getSimpleNodesByName(new QName(getNodeType(), children));\r
     }\r
 \r
-    private QName localQName(String str) {\r
-        return new QName(getNodeType(), str);\r
+    /**\r
+     * @param value\r
+     */\r
+    protected void init() {\r
+        if (getValue() != null) {\r
+            nodeMap = NodeUtils.buildNodeMap(getValue());\r
+        }\r
+    }\r
+    \r
+    @Override\r
+    public MutableCompositeNode asMutable() {\r
+        throw new IllegalAccessError("cast to mutable is not supported - "+getClass().getSimpleName());\r
     }\r
+    \r
+    @Override\r
+    public String toString() {\r
+        return super.toString() + ", children.size = " \r
+                + (getChildren() != null ? getChildren().size() : "n/a");\r
+    }\r
+    \r
+    \r
 \r
 }\r
diff --git a/opendaylight/sal/yang-prototype/yang/yang-data-impl/src/main/java/org/opendaylight/controller/yang/data/impl/LazyNodeToNodeMap.java b/opendaylight/sal/yang-prototype/yang/yang-data-impl/src/main/java/org/opendaylight/controller/yang/data/impl/LazyNodeToNodeMap.java
new file mode 100644 (file)
index 0000000..81dd86e
--- /dev/null
@@ -0,0 +1,156 @@
+/*\r
+ * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.\r
+ *\r
+ * This program and the accompanying materials are made available under the\r
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,\r
+ * and is available at http://www.eclipse.org/legal/epl-v10.html\r
+ */\r
+package org.opendaylight.controller.yang.data.impl;\r
+\r
+import java.util.ArrayList;\r
+import java.util.HashMap;\r
+import java.util.Map;\r
+import java.util.Set;\r
+import java.util.Stack;\r
+\r
+import org.opendaylight.controller.yang.data.api.CompositeNode;\r
+import org.opendaylight.controller.yang.data.api.MutableCompositeNode;\r
+import org.opendaylight.controller.yang.data.api.MutableNode;\r
+import org.opendaylight.controller.yang.data.api.MutableSimpleNode;\r
+import org.opendaylight.controller.yang.data.api.Node;\r
+import org.opendaylight.controller.yang.data.api.NodeModification;\r
+import org.opendaylight.controller.yang.data.api.SimpleNode;\r
+\r
+/**\r
+ * @author michal.rehak\r
+ *\r
+ */\r
+public class LazyNodeToNodeMap {\r
+    \r
+    private Map<Node<?>, Node<?>> node2node = new HashMap<>();\r
+    private CompositeNode originalRoot;\r
+    private MutableCompositeNode mutableRoot;\r
+    \r
+    /**\r
+     * @param originalNode\r
+     * @return mutable twin\r
+     */\r
+    public Node<?> getMutableEquivalent(Node<?> originalNode) {\r
+        Node<?> mutableNode = node2node.get(originalNode);\r
+        if (mutableNode == null) {\r
+            addPathMembers(originalNode);\r
+            mutableNode = node2node.get(originalNode);\r
+        }\r
+        \r
+        return mutableNode;\r
+    }\r
+    \r
+    /**\r
+     * @param originalNode\r
+     */\r
+    private void addPathMembers(Node<?> originalNode) {\r
+        Stack<Node<?>> jobQueue = new Stack<>(); \r
+        jobQueue.push(originalNode);\r
+        while (!jobQueue.isEmpty()) {\r
+            Node<?> node2add = jobQueue.pop();\r
+            boolean fixChildrenRefOnly = false;\r
+            if (node2node.containsKey(node2add)) {\r
+                if (node2add instanceof SimpleNode<?>) {\r
+                    continue;\r
+                }\r
+                fixChildrenRefOnly = true;\r
+            }\r
+            \r
+            CompositeNode nextParent = node2add.getParent();\r
+            MutableNode<?> mutableEquivalent = null;\r
+            \r
+            if (node2add instanceof SimpleNode<?>) {\r
+                SimpleNode<?> node2addSimple = (SimpleNode<?>) node2add;\r
+                MutableSimpleNode<?> nodeMutant = NodeFactory.createMutableSimpleNode(\r
+                        node2add.getNodeType(), null, node2addSimple.getValue(), \r
+                        node2addSimple.getModificationAction(), node2addSimple);\r
+                mutableEquivalent = nodeMutant;\r
+            } else if (node2add instanceof CompositeNode) {\r
+                MutableCompositeNode nodeMutant = null;\r
+                if (fixChildrenRefOnly) {\r
+                    nodeMutant = (MutableCompositeNode) node2node.get(node2add);\r
+                } else {\r
+                    CompositeNode node2addComposite = (CompositeNode) node2add;\r
+                    nodeMutant = NodeFactory.createMutableCompositeNode(node2add.getNodeType(), \r
+                        null, null, \r
+                        ((NodeModification) node2add).getModificationAction(), node2addComposite);\r
+                }\r
+                \r
+                mutableEquivalent = nodeMutant;\r
+\r
+                // tidy up children\r
+                if (nodeMutant.getChildren() == null) {\r
+                    nodeMutant.setValue(new ArrayList<Node<?>>());\r
+                }\r
+                for (Node<?> originalChildNode : ((CompositeNode) node2add).getChildren()) {\r
+                    MutableNode<?> mutableChild = (MutableNode<?>) node2node.get(originalChildNode);\r
+                    fixChildrenRef(nodeMutant, mutableChild);\r
+                }\r
+                \r
+                if (nodeMutant.getChildren() != null && !nodeMutant.getChildren().isEmpty()) {\r
+                    nodeMutant.init();\r
+                }\r
+\r
+                // store tree root, if occured\r
+                if (nextParent == null) {\r
+                    if (originalRoot == null) {\r
+                        originalRoot = (CompositeNode) node2add;\r
+                        mutableRoot = nodeMutant;\r
+                    } else {\r
+                        if (!originalRoot.equals(node2add)) {\r
+                            throw new IllegalStateException("Different tree root node obtained - " +\r
+                                       "perhaps nodes of different trees are getting mixed up.");\r
+                        }\r
+                    }\r
+                }\r
+            }\r
+            \r
+            // feed jobQueue\r
+            node2node.put(node2add, mutableEquivalent);\r
+            if (nextParent != null) {\r
+                jobQueue.push(nextParent);\r
+            } \r
+        }\r
+    }\r
+\r
+    /**\r
+     * @param nodeMutant\r
+     * @param mutableChild\r
+     */\r
+    private static void fixChildrenRef(MutableCompositeNode nodeMutant,\r
+            MutableNode<?> mutableChild) {\r
+        if (mutableChild != null) {\r
+            if (!nodeMutant.getChildren().contains(mutableChild)) {\r
+                nodeMutant.getChildren().add(mutableChild);\r
+            }\r
+            CompositeNode parentOfChild = mutableChild.getParent();\r
+            if (parentOfChild == null) {\r
+                mutableChild.setParent(nodeMutant);\r
+            } else {\r
+                if (!parentOfChild.equals(nodeMutant)) {\r
+                    throw new IllegalStateException("Different parent node obtained - " +\r
+                            "perhaps nodes of different trees are getting mixed up.");\r
+                }\r
+            }\r
+        }\r
+    }\r
+\r
+    /**\r
+     * @return the mutableRoot\r
+     */\r
+    public MutableCompositeNode getMutableRoot() {\r
+        return mutableRoot;\r
+    }\r
+    \r
+    /**\r
+     * @return set of original nodes, registered in map as keys \r
+     */\r
+    public Set<Node<?>> getKeyNodes() {\r
+        return node2node.keySet();\r
+    }\r
+}\r
old mode 100755 (executable)
new mode 100644 (file)
index 997b502..c29ecc4
@@ -20,10 +20,11 @@ import org.opendaylight.controller.yang.data.api.Node;
  * @author michal.rehak\r
  * \r
  */\r
-public class MutableCompositeNodeTOImpl extends CompositeNodeModificationTOImpl\r
+public class MutableCompositeNodeTOImpl extends CompositeNodeTOImpl\r
         implements MutableCompositeNode {\r
 \r
     private Map<QName, List<Node<?>>> nodeMap;\r
+    private CompositeNode original;\r
 \r
     /**\r
      * @param qname\r
@@ -41,7 +42,9 @@ public class MutableCompositeNodeTOImpl extends CompositeNodeModificationTOImpl
      */\r
     @Override\r
     public void init() {\r
-        nodeMap = NodeUtils.buildNodeMap(getChildren());\r
+        if (!getChildren().isEmpty()) {\r
+            nodeMap = NodeUtils.buildNodeMap(getChildren());\r
+        }\r
     }\r
 \r
     @Override\r
@@ -58,4 +61,21 @@ public class MutableCompositeNodeTOImpl extends CompositeNodeModificationTOImpl
     protected Map<QName, List<Node<?>>> getNodeMap() {\r
         return nodeMap;\r
     }\r
+    \r
+    @Override\r
+    public MutableCompositeNode asMutable() {\r
+        return this;\r
+    }\r
+    \r
+    @Override\r
+    public CompositeNode getOriginal() {\r
+        return original;\r
+    }\r
+    \r
+    /**\r
+     * @param original the original to set\r
+     */\r
+    public void setOriginal(CompositeNode original) {\r
+        this.original = original;\r
+    }\r
 }\r
old mode 100755 (executable)
new mode 100644 (file)
index 17cbb8d..a3b73b1
@@ -11,15 +11,18 @@ import org.opendaylight.controller.yang.common.QName;
 import org.opendaylight.controller.yang.data.api.CompositeNode;\r
 import org.opendaylight.controller.yang.data.api.ModifyAction;\r
 import org.opendaylight.controller.yang.data.api.MutableSimpleNode;\r
+import org.opendaylight.controller.yang.data.api.SimpleNode;\r
 \r
 /**\r
  * @author michal.rehak\r
  * @param <T> type of simple node value\r
  * \r
  */\r
-public class MutableSimpleNodeTOImpl<T> extends SimpleNodeModificationTOImpl<T> \r
+public class MutableSimpleNodeTOImpl<T> extends SimpleNodeTOImpl<T> \r
         implements MutableSimpleNode<T> {\r
 \r
+    private SimpleNode<T> original;\r
+\r
     /**\r
      * @param qname\r
      * @param parent\r
@@ -40,4 +43,21 @@ public class MutableSimpleNodeTOImpl<T> extends SimpleNodeModificationTOImpl<T>
     public void setModifyAction(ModifyAction action) {\r
         super.setModificationAction(action);\r
     }\r
+    \r
+    @Override\r
+    public MutableSimpleNode<T> asMutable() {\r
+        return this;\r
+    }\r
+    \r
+    @Override\r
+    public SimpleNode<T> getOriginal() {\r
+        return original;\r
+    }\r
+    \r
+    /**\r
+     * @param original the original to set\r
+     */\r
+    public void setOriginal(SimpleNode<T> original) {\r
+        this.original = original;\r
+    }\r
 }\r
old mode 100755 (executable)
new mode 100644 (file)
index 8b3b7d4..8e6e774
@@ -10,6 +10,7 @@ package org.opendaylight.controller.yang.data.impl;
 import java.util.AbstractMap.SimpleEntry;\r
 import java.util.ArrayList;\r
 import java.util.Arrays;\r
+import java.util.HashMap;\r
 import java.util.List;\r
 import java.util.Map;\r
 import java.util.Stack;\r
@@ -20,6 +21,7 @@ import org.opendaylight.controller.yang.data.api.ModifyAction;
 import org.opendaylight.controller.yang.data.api.MutableCompositeNode;\r
 import org.opendaylight.controller.yang.data.api.MutableSimpleNode;\r
 import org.opendaylight.controller.yang.data.api.Node;\r
+import org.opendaylight.controller.yang.data.api.NodeModification;\r
 import org.opendaylight.controller.yang.data.api.SimpleNode;\r
 \r
 /**\r
@@ -34,47 +36,56 @@ public abstract class NodeFactory {
      * @param value\r
      * @return simple node modification, based on given qname, value and parent\r
      */\r
-    public static <T> SimpleNode<T> createSimpleNode(QName qName,\r
+    public static <T> SimpleNode<T> createImmutableSimpleNode(QName qName,\r
             CompositeNode parent, T value) {\r
-        SimpleNodeTOImpl<T> simpleNodeTOImpl = new SimpleNodeTOImpl<T>(qName, parent, value);\r
-        return simpleNodeTOImpl;\r
+        return createImmutableSimpleNode(qName, parent, value, null);\r
     }\r
     \r
     /**\r
      * @param qName\r
      * @param parent\r
      * @param value\r
+     * @param modifyAction \r
+     * @param original originating node, if available\r
      * @return simple node modification, based on given qname, value and parent\r
      */\r
     public static <T> MutableSimpleNode<T> createMutableSimpleNode(QName qName,\r
-            CompositeNode parent, T value) {\r
+            CompositeNode parent, Object value, ModifyAction modifyAction, SimpleNode<T> original) {\r
+        @SuppressWarnings("unchecked")\r
         MutableSimpleNodeTOImpl<T> simpleNodeTOImpl = \r
-                new MutableSimpleNodeTOImpl<T>(qName, parent, value, null);\r
+                new MutableSimpleNodeTOImpl<T>(qName, parent, (T) value, modifyAction);\r
+        simpleNodeTOImpl.setOriginal(original);\r
         return simpleNodeTOImpl;\r
     }\r
-\r
+    \r
     /**\r
      * @param qName\r
      * @param parent\r
      * @param value\r
      * @return composite node modification, based on given qname, value (children), parent and modifyAction\r
      */\r
-    public static CompositeNode createCompositeNode(QName qName,\r
+    public static CompositeNode createImmutableCompositeNode(QName qName,\r
             CompositeNode parent, List<Node<?>> value) {\r
-        CompositeNode compositeNodeTOImpl = new CompositeNodeTOImpl(qName, parent, value);\r
-        return compositeNodeTOImpl;\r
+        return createImmutableCompositeNode(qName, parent, value, null);\r
     }\r
     \r
     /**\r
      * @param qName\r
      * @param parent\r
-     * @param value\r
-     * @return composite node modification, based on given qname, value (children), parent and modifyAction\r
+     * @param valueArg \r
+     * @param modifyAction \r
+     * @param original originating node, if available\r
+     * @return composite node modification, based on given qName, value (children), parent and modifyAction\r
      */\r
     public static MutableCompositeNode createMutableCompositeNode(QName qName,\r
-            CompositeNode parent, List<Node<?>> value) {\r
+            CompositeNode parent, List<Node<?>> valueArg, ModifyAction modifyAction, CompositeNode original) {\r
+        List<Node<?>> value = valueArg;\r
+        if (value == null) {\r
+            value = new ArrayList<>();\r
+        }\r
         MutableCompositeNodeTOImpl compositeNodeTOImpl = \r
-                new MutableCompositeNodeTOImpl(qName, parent, value, null);\r
+                new MutableCompositeNodeTOImpl(qName, parent, value, modifyAction);\r
+        compositeNodeTOImpl.setOriginal(original);\r
         return compositeNodeTOImpl;\r
     }\r
     \r
@@ -86,10 +97,10 @@ public abstract class NodeFactory {
      * @param modifyAction\r
      * @return simple node modification, based on given qname, value, parent and modifyAction\r
      */\r
-    public static <T> SimpleNodeModificationTOImpl<T> createSimpleNodeModification(QName qName,\r
+    public static <T> SimpleNode<T> createImmutableSimpleNode(QName qName,\r
             CompositeNode parent, T value, ModifyAction modifyAction) {\r
-        SimpleNodeModificationTOImpl<T> simpleNodeModTOImpl = \r
-                new SimpleNodeModificationTOImpl<T>(qName, parent, value, modifyAction);\r
+        SimpleNodeTOImpl<T> simpleNodeModTOImpl = \r
+                new SimpleNodeTOImpl<T>(qName, parent, value, modifyAction);\r
         return simpleNodeModTOImpl;\r
     }\r
 \r
@@ -100,10 +111,10 @@ public abstract class NodeFactory {
      * @param modifyAction \r
      * @return composite node modification, based on given qname, value (children), parent and modifyAction\r
      */\r
-    public static CompositeNodeModificationTOImpl createCompositeNodeModification(QName qName,\r
+    public static CompositeNode createImmutableCompositeNode(QName qName,\r
             CompositeNode parent, List<Node<?>> value, ModifyAction modifyAction) {\r
-        CompositeNodeModificationTOImpl compositeNodeModTOImpl = \r
-                new CompositeNodeModificationTOImpl(qName, parent, value, modifyAction);\r
+        CompositeNodeTOImpl compositeNodeModTOImpl = \r
+                new CompositeNodeTOImpl(qName, parent, value, modifyAction);\r
         return compositeNodeModTOImpl;\r
     }\r
 \r
@@ -113,7 +124,7 @@ public abstract class NodeFactory {
      * has no reference to this copy \r
      */\r
     public static <T> SimpleNode<T> copyNode(SimpleNode<T> node) {\r
-        SimpleNode<T> twinNode = createSimpleNode(\r
+        SimpleNode<T> twinNode = createImmutableSimpleNode(\r
                     node.getNodeType(), node.getParent(), node.getValue());\r
         return twinNode;\r
     }\r
@@ -123,12 +134,13 @@ public abstract class NodeFactory {
      * @return copy of given node, parent and value are the same, but parent \r
      * has no reference to this copy \r
      */\r
-    public static <T> SimpleNode<T> copyNodeAsMutable(SimpleNode<T> node) {\r
-        SimpleNode<T> twinNode = createMutableSimpleNode(\r
-                    node.getNodeType(), node.getParent(), node.getValue());\r
+    public static <T> MutableSimpleNode<T> copyNodeAsMutable(SimpleNode<T> node) {\r
+        MutableSimpleNode<T> twinNode = createMutableSimpleNode(\r
+                    node.getNodeType(), node.getParent(), node.getValue(), \r
+                    node.getModificationAction(), null);\r
         return twinNode;\r
     }\r
-\r
+    \r
     /**\r
      * @param node\r
      * @param children \r
@@ -136,8 +148,8 @@ public abstract class NodeFactory {
      * have no reference to this copy\r
      */\r
     public static CompositeNode copyNode(CompositeNode node, Node<?>... children) {\r
-        CompositeNode twinNode = createCompositeNode(\r
-                node.getNodeType(), node.getParent(), Arrays.asList(children));\r
+        CompositeNode twinNode = createImmutableCompositeNode(\r
+                node.getNodeType(), node.getParent(), Arrays.asList(children), node.getModificationAction());\r
         return twinNode;\r
     }\r
     \r
@@ -152,53 +164,98 @@ public abstract class NodeFactory {
     \r
     /**\r
      * @param node root of original tree\r
-     * @param originalToMutable (optional) empty map, where binding between original and copy \r
+     * @param originalToCopyArg (optional) empty map, where binding between original and copy \r
      * will be stored\r
-     * @return copy of given node, parent and children are the same, but parent and children \r
-     * have no reference to this copy\r
+     * @return copy of given node and all subnodes recursively\r
      */\r
-    public static MutableCompositeNode copyDeepNode(CompositeNode node, \r
-            Map<Node<?>, Node<?>> originalToMutable) {\r
-              \r
-       MutableCompositeNode mutableRoot = \r
-               createMutableCompositeNode(node.getNodeType(), null, null);\r
-       Stack<SimpleEntry<CompositeNode, MutableCompositeNode>> jobQueue = new Stack<>();\r
-       jobQueue.push(new SimpleEntry<CompositeNode, MutableCompositeNode>(node, mutableRoot));\r
-       if (originalToMutable != null) {\r
-           originalToMutable.put(node, mutableRoot);\r
-       }\r
-       \r
-       while (!jobQueue.isEmpty()) {\r
-           SimpleEntry<CompositeNode, MutableCompositeNode> job = jobQueue.pop();\r
-           CompositeNode originalNode = job.getKey();\r
-           MutableCompositeNode mutableNode = job.getValue();\r
-           mutableNode.setValue(new ArrayList<Node<?>>());\r
-           \r
-           for (Node<?> child : originalNode.getChildren()) {\r
-               Node<?> mutableAscendant = null;\r
-               if (child instanceof CompositeNode) {\r
-                   MutableCompositeNode newMutable = \r
-                           createMutableCompositeNode(child.getNodeType(), mutableNode, null);\r
-                   jobQueue.push(new SimpleEntry<CompositeNode, MutableCompositeNode>(\r
-                           (CompositeNode) child, newMutable));\r
-                   mutableAscendant = newMutable;\r
-               } else if (child instanceof SimpleNode<?>) {\r
-                   mutableAscendant = \r
-                           createMutableSimpleNode(child.getNodeType(), mutableNode, child.getValue());\r
-               } else {\r
-                   throw new IllegalStateException("Node class deep copy not supported: "\r
-                           +child.getClass().getName());\r
-               }\r
-               \r
-               mutableNode.getChildren().add(mutableAscendant);\r
-               if (originalToMutable != null) {\r
-                   originalToMutable.put(child, mutableAscendant);\r
-               }\r
-           }\r
-           mutableNode.init();\r
-       }\r
+    public static MutableCompositeNode copyDeepAsMutable(CompositeNode node, \r
+            Map<Node<?>, Node<?>> originalToCopyArg) {\r
+        \r
+        Map<Node<?>, Node<?>> originalToCopy = originalToCopyArg;\r
+        if (originalToCopy == null) {\r
+            originalToCopy = new HashMap<>();\r
+        }\r
+\r
+        MutableCompositeNode mutableRoot = createMutableCompositeNode(node.getNodeType(), null, null, \r
+                node.getModificationAction(), null);\r
+        Stack<SimpleEntry<CompositeNode, MutableCompositeNode>> jobQueue = new Stack<>();\r
+        jobQueue.push(new SimpleEntry<CompositeNode, MutableCompositeNode>(node, mutableRoot));\r
+        originalToCopy.put(node, mutableRoot);\r
+\r
+        while (!jobQueue.isEmpty()) {\r
+            SimpleEntry<CompositeNode, MutableCompositeNode> job = jobQueue.pop();\r
+            CompositeNode originalNode = job.getKey();\r
+            MutableCompositeNode mutableNode = job.getValue();\r
+            mutableNode.setValue(new ArrayList<Node<?>>());\r
+\r
+            for (Node<?> child : originalNode.getChildren()) {\r
+                Node<?> mutableAscendant = null;\r
+                if (child instanceof CompositeNode) {\r
+                    MutableCompositeNode newMutable = \r
+                            createMutableCompositeNode(child.getNodeType(), mutableNode, null, \r
+                                    ((NodeModification) child).getModificationAction(), null);\r
+                    jobQueue.push(new SimpleEntry<CompositeNode, MutableCompositeNode>(\r
+                            (CompositeNode) child, newMutable));\r
+                    mutableAscendant = newMutable;\r
+                } else if (child instanceof SimpleNode<?>) {\r
+                    mutableAscendant = \r
+                            createMutableSimpleNode(child.getNodeType(), mutableNode, \r
+                                    child.getValue(), \r
+                                    ((NodeModification) child).getModificationAction(), null);\r
+                } else {\r
+                    throw new IllegalStateException("Node class deep copy not supported: "\r
+                            +child.getClass().getName());\r
+                }\r
+\r
+                mutableNode.getChildren().add(mutableAscendant);\r
+                originalToCopy.put(child, mutableAscendant);\r
+            }\r
+            mutableNode.init();\r
+        }\r
+\r
+        return mutableRoot;\r
+    }\r
+    \r
+    /**\r
+     * @param node root of original tree\r
+     * @param originalToCopyArg (optional) empty map, where binding between original and copy \r
+     * will be stored\r
+     * @return copy of given node and all subnodes recursively\r
+     */\r
+    public static CompositeNode copyDeepAsImmutable(CompositeNode node, \r
+            Map<Node<?>, Node<?>> originalToCopyArg) {\r
+        Stack<CompositeNode> jobQueue = new Stack<>();\r
+        jobQueue.push(node);\r
+        \r
+        Map<Node<?>, Node<?>> originalToCopy = originalToCopyArg;\r
+        if (originalToCopy == null) {\r
+            originalToCopy = new HashMap<>();\r
+        }\r
+        \r
+        while (!jobQueue.isEmpty()) {\r
+            CompositeNode jobNode = jobQueue.peek();\r
+            if (!originalToCopy.isEmpty() \r
+                    && originalToCopy.keySet().containsAll(jobNode.getChildren())) {\r
+                jobQueue.pop();\r
+                List<Node<?>> newChildren = NodeUtils.collectMapValues(jobNode.getChildren(), originalToCopy);\r
+                CompositeNode nodeCopy = createImmutableCompositeNode(jobNode.getNodeType(), null, \r
+                        newChildren, jobNode.getModificationAction());\r
+                NodeUtils.fixChildrenRelation(nodeCopy);\r
+                originalToCopy.put(jobNode, nodeCopy);\r
+            } else {\r
+                for (Node<?> child : jobNode.getChildren()) {\r
+                    if (child instanceof SimpleNode<?>) {\r
+                        originalToCopy.put(child, createImmutableSimpleNode(\r
+                                child.getNodeType(), null, child.getValue(), \r
+                                ((NodeModification) child).getModificationAction()));\r
+                    } else if (child instanceof CompositeNode) {\r
+                        jobQueue.push((CompositeNode) child);\r
+                    }\r
+                }\r
+            }\r
+        }\r
        \r
-       return mutableRoot;\r
+        return (CompositeNode) originalToCopy.get(node);\r
     }\r
     \r
 }\r
old mode 100755 (executable)
new mode 100644 (file)
index cd71731..2ab2dd8
@@ -1,14 +1,16 @@
-/**\r
- * \r
+/*\r
+ * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.\r
+ *\r
+ * This program and the accompanying materials are made available under the\r
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,\r
+ * and is available at http://www.eclipse.org/legal/epl-v10.html\r
  */\r
 package org.opendaylight.controller.yang.data.impl;\r
 \r
-import java.util.HashMap;\r
 import java.util.HashSet;\r
 import java.util.List;\r
 import java.util.Map;\r
 import java.util.Set;\r
-import java.util.Stack;\r
 \r
 import org.opendaylight.controller.yang.common.QName;\r
 import org.opendaylight.controller.yang.data.api.CompositeNode;\r
@@ -30,9 +32,7 @@ public class NodeModificationBuilderImpl implements NodeModificationBuilder {
     private SchemaContext context;\r
     \r
     private Set<MutableNode<?>> changeLog;\r
-    private Map<Node<?>, Node<?>> originalToMutable;\r
-\r
-    private MutableCompositeNode mutableRoot;\r
+    private LazyNodeToNodeMap originalToMutable;\r
 \r
     /**\r
      * @param originalTreeRootNode \r
@@ -40,24 +40,10 @@ public class NodeModificationBuilderImpl implements NodeModificationBuilder {
      */\r
     public NodeModificationBuilderImpl(CompositeNode originalTreeRootNode, SchemaContext context) {\r
         this.context = context;\r
-        originalToMutable = new HashMap<>();\r
-        mutableRoot = NodeFactory.copyDeepNode(originalTreeRootNode, originalToMutable);\r
+        originalToMutable = new LazyNodeToNodeMap();\r
         changeLog = new HashSet<>();\r
     }\r
 \r
-    /**\r
-     * add given node to it's parent's list of children\r
-     * @param newNode\r
-     */\r
-    private static void fixParentRelation(Node<?> newNode) {\r
-        if (newNode.getParent() != null) {\r
-            List<Node<?>> siblings = newNode.getParent().getChildren();\r
-            if (!siblings.contains(newNode)) {\r
-                siblings.add(newNode);\r
-            }\r
-        }\r
-    }\r
-\r
     /**\r
      * @param modNode\r
      * @param action \r
@@ -69,13 +55,13 @@ public class NodeModificationBuilderImpl implements NodeModificationBuilder {
 \r
     @Override\r
     public void addNode(MutableSimpleNode<?> newNode) {\r
-        fixParentRelation(newNode);\r
+        NodeUtils.fixParentRelation(newNode);\r
         addModificationToLog(newNode, ModifyAction.CREATE);\r
     }\r
     \r
     @Override\r
     public void addNode(MutableCompositeNode newNode) {\r
-        fixParentRelation(newNode);\r
+        NodeUtils.fixParentRelation(newNode);\r
         addModificationToLog(newNode, ModifyAction.CREATE);\r
     }\r
     \r
@@ -126,9 +112,8 @@ public class NodeModificationBuilderImpl implements NodeModificationBuilder {
             wanted.addAll(collectSelfAndAllParents(mutant));\r
         }\r
         \r
-        // TODO:: walk wanted and add relevant keys\r
+        // walk wanted and add relevant keys\r
         Map<String, ListSchemaNode>  mapOfLists = NodeUtils.buildMapOfListNodes(context);\r
-        Set<Node<?>> wantedKeys = new HashSet<>();\r
         for (Node<?> outlaw : wanted) {\r
             if (outlaw instanceof CompositeNode) {\r
                 String path = NodeUtils.buildPath(outlaw);\r
@@ -137,54 +122,27 @@ public class NodeModificationBuilderImpl implements NodeModificationBuilder {
                     if (listSchema.getQName().equals(outlaw.getNodeType())) {\r
                         // try to add key subnode to wanted list\r
                         List<QName> supportedKeys = listSchema.getKeyDefinition();\r
-                        for (Node<?> outlawChildren : ((CompositeNode) outlaw).getChildren()) {\r
-                            if (supportedKeys.contains(outlawChildren.getNodeType())) {\r
-                                wantedKeys.add(outlawChildren);\r
+                        CompositeNode outlawOriginal = ((MutableCompositeNode) outlaw).getOriginal();\r
+                        for (Node<?> outlawOriginalChild : outlawOriginal.getChildren()) {\r
+                            if (supportedKeys.contains(outlawOriginalChild.getNodeType())) {\r
+                                originalToMutable.getMutableEquivalent(outlawOriginalChild);\r
                             }\r
                         }\r
                     }\r
                 }\r
             }\r
         }\r
-        wanted.addAll(wantedKeys);\r
-        \r
-        // remove all unwanted nodes from tree\r
-        removeUnrelevantNodes(mutableRoot, wanted);\r
         \r
-        return mutableRoot;\r
-    }\r
-\r
-    /**\r
-     * @param mutableRoot2\r
-     * @param wanted\r
-     */\r
-    private static void removeUnrelevantNodes(MutableCompositeNode mutRoot,\r
-            Set<Node<?>> wanted) {\r
-        Stack<MutableNode<?>> jobQueue = new Stack<>();\r
-        jobQueue.push(mutRoot);\r
-        while (!jobQueue.isEmpty()) {\r
-            MutableNode<?> mutNode = jobQueue.pop();\r
-            if (!wanted.contains(mutNode)) {\r
-                if (mutNode.getParent() != null) {\r
-                    mutNode.getParent().getChildren().remove(mutNode);\r
-                }\r
-            } else {\r
-                if (mutNode instanceof MutableCompositeNode) {\r
-                    for (Node<?> mutChild : ((MutableCompositeNode) mutNode).getChildren()) {\r
-                        jobQueue.push((MutableNode<?>) mutChild);\r
-                    }\r
-                }\r
-            }\r
-        }\r
+        return originalToMutable.getMutableRoot();\r
     }\r
 \r
     /**\r
-     * @param focusedAncestor\r
+     * @param focusedDescendant\r
      * @return set of parents and focusedAncestor itself\r
      */\r
-    private static Set<Node<?>> collectSelfAndAllParents(Node<?> focusedAncestor) {\r
+    private static Set<Node<?>> collectSelfAndAllParents(Node<?> focusedDescendant) {\r
         Set<Node<?>> family = new HashSet<>();\r
-        Node<?> tmpNode = focusedAncestor;\r
+        Node<?> tmpNode = focusedDescendant;\r
         while (tmpNode != null) {\r
             family.add(tmpNode);\r
             tmpNode = tmpNode.getParent();\r
@@ -198,7 +156,7 @@ public class NodeModificationBuilderImpl implements NodeModificationBuilder {
      */\r
     @Override\r
     public Node<?> getMutableEquivalent(Node<?> originalNode) {\r
-        return originalToMutable.get(originalNode);\r
+        return originalToMutable.getMutableEquivalent(originalNode);\r
     }\r
 \r
 }\r
old mode 100755 (executable)
new mode 100644 (file)
index b3a7640..513cf06
@@ -36,10 +36,10 @@ import org.opendaylight.controller.yang.model.api.ListSchemaNode;
 import org.opendaylight.controller.yang.model.api.SchemaContext;\r
 import org.slf4j.Logger;\r
 import org.slf4j.LoggerFactory;\r
-import org.w3c.dom.Document;\r
 import org.w3c.dom.Element;\r
 \r
 import com.google.common.base.Joiner;\r
+import com.google.common.collect.Lists;\r
 \r
 \r
 /**\r
@@ -48,11 +48,12 @@ import com.google.common.base.Joiner;
  */\r
 public abstract class NodeUtils {\r
     \r
+    private static final Logger LOG = LoggerFactory.getLogger(NodeUtils.class);\r
+    \r
     /**\r
      * \r
      */\r
     private static final String USER_KEY_NODE = "node";\r
-    private static final Logger LOG = LoggerFactory.getLogger(NodeUtils.class);\r
     \r
     /**\r
      * @param node\r
@@ -75,9 +76,9 @@ public abstract class NodeUtils {
      * @return dom tree, containing same node structure, yang nodes are associated \r
      * to dom nodes as user data\r
      */\r
-    public static Document buildShadowDomTree(CompositeNode treeRootNode) {\r
+    public static org.w3c.dom.Document buildShadowDomTree(CompositeNode treeRootNode) {
         DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();\r
-        Document doc = null;\r
+        org.w3c.dom.Document doc = null;\r
         try {\r
             DocumentBuilder bob = dbf.newDocumentBuilder();\r
             doc = bob.newDocument();\r
@@ -86,6 +87,7 @@ public abstract class NodeUtils {
             return null;\r
         }\r
         \r
+        \r
         Stack<SimpleEntry<org.w3c.dom.Node, Node<?>>> jobQueue = new Stack<>();\r
         jobQueue.push(new SimpleEntry<org.w3c.dom.Node, Node<?>>(doc, treeRootNode));\r
         \r
@@ -93,12 +95,14 @@ public abstract class NodeUtils {
             SimpleEntry<org.w3c.dom.Node, Node<?>> job = jobQueue.pop();\r
             org.w3c.dom.Node jointPlace = job.getKey();\r
             Node<?> item = job.getValue();\r
-            Element itemEl = doc.createElement(item.getNodeType().getLocalName());\r
+            QName nodeType = item.getNodeType();\r
+            Element itemEl = doc.createElementNS(nodeType.getNamespace().toString(), \r
+                    item.getNodeType().getLocalName());\r
             itemEl.setUserData(USER_KEY_NODE, item, null);\r
             if (item instanceof SimpleNode<?>) {\r
                 Object value = ((SimpleNode<?>) item).getValue();\r
                 itemEl.setTextContent(String.valueOf(value));\r
-                itemEl.setAttribute("type", value.getClass().getSimpleName());\r
+                //itemEl.setAttribute("type", value.getClass().getSimpleName());\r
             }\r
             if (item instanceof NodeModification) {\r
                 ModifyAction modificationAction = ((NodeModification) item).getModificationAction();\r
@@ -126,7 +130,7 @@ public abstract class NodeUtils {
      * @throws XPathExpressionException\r
      */\r
     @SuppressWarnings("unchecked")\r
-    public static <T> T findNodeByXpath(Document doc, String xpathEx) \r
+    public static <T> T findNodeByXpath(org.w3c.dom.Document doc, String xpathEx) \r
             throws XPathExpressionException {\r
         T userNode = null;\r
         XPathFactory xPathfactory = XPathFactory.newInstance();\r
@@ -190,8 +194,7 @@ public abstract class NodeUtils {
         \r
         return mapOfLists;\r
     }\r
-\r
-\r
+    \r
     /**\r
      * @param path\r
      * @return\r
@@ -203,4 +206,56 @@ public abstract class NodeUtils {
         }\r
         return Joiner.on(".").join(pathSeed);\r
     }\r
+\r
+    /**\r
+     * add given node to it's parent's list of children\r
+     * @param newNode\r
+     */\r
+    public static void fixParentRelation(Node<?> newNode) {\r
+        if (newNode.getParent() != null) {\r
+            List<Node<?>> siblings = newNode.getParent().getChildren();\r
+            if (!siblings.contains(newNode)) {\r
+                siblings.add(newNode);\r
+            }\r
+        }\r
+    }\r
+    \r
+    /**\r
+     * crawl all children of given node and assign it as their parent\r
+     * @param parentNode\r
+     */\r
+    public static void fixChildrenRelation(CompositeNode parentNode) {\r
+        if (parentNode.getChildren() != null) {\r
+            for (Node<?> child : parentNode.getChildren()) {\r
+                if (child instanceof AbstractNodeTO<?>) {\r
+                    ((AbstractNodeTO<?>) child).setParent(parentNode);\r
+                }\r
+            }\r
+        }\r
+    }\r
+\r
+\r
+    /**\r
+     * @param keys\r
+     * @param dataMap\r
+     * @return list of values of map, found by given keys \r
+     */\r
+    public static <T, K> List<K> collectMapValues(List<T> keys,\r
+            Map<T, K> dataMap) {\r
+        List<K> valueSubList = new ArrayList<>();\r
+        for (T key : keys) {\r
+            valueSubList.add(dataMap.get(key));\r
+        }\r
+        \r
+        return valueSubList;\r
+    }\r
+    \r
+    /**\r
+     * @param nodes\r
+     * @return list of children in list of appropriate type\r
+     */\r
+    public static List<Node<?>> buildChildrenList(Node<?>...nodes) {\r
+        return Lists.newArrayList(nodes);\r
+    }\r
+\r
 }\r
index 726863737716f891d4d0cec613426c93e01d6955..eaee3730a7979a91a3ba6bcba1409917aee2c188 100755 (executable)
@@ -1,22 +1,22 @@
-/**\r
- * \r
+/*\r
+ * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.\r
+ *\r
+ * This program and the accompanying materials are made available under the\r
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,\r
+ * and is available at http://www.eclipse.org/legal/epl-v10.html\r
  */\r
 package org.opendaylight.controller.yang.data.impl;\r
 \r
 import org.opendaylight.controller.yang.common.QName;\r
 import org.opendaylight.controller.yang.data.api.CompositeNode;\r
 import org.opendaylight.controller.yang.data.api.ModifyAction;\r
-import org.opendaylight.controller.yang.data.api.NodeModification;\r
 \r
 /**\r
  * @author michal.rehak\r
  * @param <T> type of node value\r
  * \r
  */\r
-public class SimpleNodeModificationTOImpl<T> extends SimpleNodeTOImpl<T>\r
-        implements NodeModification {\r
-\r
-    private ModifyAction modifyAction;\r
+public class SimpleNodeModificationTOImpl<T> extends SimpleNodeTOImpl<T> {\r
 \r
     /**\r
      * @param qname\r
@@ -27,23 +27,6 @@ public class SimpleNodeModificationTOImpl<T> extends SimpleNodeTOImpl<T>
     public SimpleNodeModificationTOImpl(QName qname, CompositeNode parent,\r
             T value, ModifyAction modifyAction) {\r
         super(qname, parent, value);\r
-        this.modifyAction = modifyAction;\r
-    }\r
-\r
-    /**\r
-     * @return modification action\r
-     * @see org.opendaylight.controller.yang.data.impl.NodeModificationSupport#getModificationAction()\r
-     */\r
-    @Override\r
-    public ModifyAction getModificationAction() {\r
-        return modifyAction;\r
-    }\r
-\r
-    /**\r
-     * @param modifyAction\r
-     *            the modifyAction to set\r
-     */\r
-    protected void setModificationAction(ModifyAction modifyAction) {\r
-        this.modifyAction = modifyAction;\r
+        setModificationAction(modifyAction);\r
     }\r
 }\r
old mode 100755 (executable)
new mode 100644 (file)
index 5cfc03a..466cea5
@@ -9,6 +9,8 @@ package org.opendaylight.controller.yang.data.impl;
 \r
 import org.opendaylight.controller.yang.common.QName;\r
 import org.opendaylight.controller.yang.data.api.CompositeNode;\r
+import org.opendaylight.controller.yang.data.api.ModifyAction;\r
+import org.opendaylight.controller.yang.data.api.MutableSimpleNode;\r
 import org.opendaylight.controller.yang.data.api.SimpleNode;\r
 \r
 /**\r
@@ -27,5 +29,25 @@ public class SimpleNodeTOImpl<T> extends AbstractNodeTO<T> implements
     public SimpleNodeTOImpl(QName qname, CompositeNode parent, T value) {\r
         super(qname, parent, value);\r
     }\r
+    \r
+    /**\r
+     * @param qname\r
+     * @param parent\r
+     * @param value\r
+     * @param modifyAction \r
+     */\r
+    public SimpleNodeTOImpl(QName qname, CompositeNode parent, T value, ModifyAction modifyAction) {\r
+        super(qname, parent, value, modifyAction);\r
+    }\r
 \r
+    \r
+    @Override\r
+    public MutableSimpleNode<T> asMutable() {\r
+        throw new IllegalAccessError("cast to mutable is not supported - "+getClass().getSimpleName());\r
+    }\r
+    \r
+    @Override\r
+    public String toString() {\r
+        return super.toString() + ", value = "+getValue();\r
+    }\r
 }\r
diff --git a/opendaylight/sal/yang-prototype/yang/yang-data-impl/src/test/java/org/opendaylight/controller/yang/data/impl/IgnoreWhiteCharsDiffListener.java b/opendaylight/sal/yang-prototype/yang/yang-data-impl/src/test/java/org/opendaylight/controller/yang/data/impl/IgnoreWhiteCharsDiffListener.java
new file mode 100644 (file)
index 0000000..bf6b292
--- /dev/null
@@ -0,0 +1,44 @@
+/**
+ * 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.data.impl;
+
+import org.custommonkey.xmlunit.Difference;
+import org.custommonkey.xmlunit.DifferenceConstants;
+import org.custommonkey.xmlunit.DifferenceListener;
+
+/**
+ * Implementatin of {@link DifferenceListener} ignoring white characters around text elements
+ * @author mirehak
+ *
+ */
+public class IgnoreWhiteCharsDiffListener implements DifferenceListener {
+    
+    @Override
+    public void skippedComparison(org.w3c.dom.Node control,
+            org.w3c.dom.Node test) {
+        // do nothing                
+    }
+
+    @Override
+    public int differenceFound(Difference diff) {
+        
+        if (diff.getId() == DifferenceConstants.TEXT_VALUE.getId()) {
+            
+            String control = diff.getControlNodeDetail().getValue();
+            if (control != null) {
+                control = control.trim();
+                if (diff.getTestNodeDetail().getValue() != null
+                    && control.equals(diff.getTestNodeDetail().getValue().trim())) {
+                    return
+                        DifferenceListener.RETURN_IGNORE_DIFFERENCE_NODES_SIMILAR;
+                }
+            }
+        }
+        return RETURN_ACCEPT_DIFFERENCE;
+    }
+}
diff --git a/opendaylight/sal/yang-prototype/yang/yang-data-impl/src/test/java/org/opendaylight/controller/yang/data/impl/LazyNodeToNodeMapTest.java b/opendaylight/sal/yang-prototype/yang/yang-data-impl/src/test/java/org/opendaylight/controller/yang/data/impl/LazyNodeToNodeMapTest.java
new file mode 100755 (executable)
index 0000000..c4dc672
--- /dev/null
@@ -0,0 +1,80 @@
+/*\r
+ * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.\r
+ *\r
+ * This program and the accompanying materials are made available under the\r
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,\r
+ * and is available at http://www.eclipse.org/legal/epl-v10.html\r
+ */\r
+package org.opendaylight.controller.yang.data.impl;\r
+\r
+import java.net.URI;\r
+import java.util.Date;\r
+\r
+import org.junit.Assert;\r
+import org.junit.Before;\r
+import org.junit.Test;\r
+import org.opendaylight.controller.yang.common.QName;\r
+import org.opendaylight.controller.yang.data.api.CompositeNode;\r
+import org.opendaylight.controller.yang.data.api.MutableCompositeNode;\r
+import org.opendaylight.controller.yang.data.api.Node;\r
+\r
+/**\r
+ * @author michal.rehak\r
+ *\r
+ */\r
+public class LazyNodeToNodeMapTest {\r
+    \r
+    private LazyNodeToNodeMap lazyN2N;\r
+    private CompositeNode tree;\r
+\r
+    /**\r
+     * prepare test values\r
+     * @throws Exception \r
+     */\r
+    @Before\r
+    public void setUp() throws Exception {\r
+        lazyN2N = new LazyNodeToNodeMap();\r
+        \r
+        QName qName = new QName(\r
+                new URI("urn:ietf:params:xml:ns:netconf:base:1.0"), \r
+                new Date(42), "yang-data-impl-mutableTest");\r
+        \r
+        tree = NodeHelper.buildTestConfigTree(qName);\r
+    }\r
+\r
+    /**\r
+     * Test method for {@link org.opendaylight.controller.yang.data.impl.LazyNodeToNodeMap#getMutableEquivalent(org.opendaylight.controller.yang.data.api.Node)}.\r
+     */\r
+    @Test\r
+    public void testGetMutableEquivalent() {\r
+        MutableCompositeNode mutableTree = (MutableCompositeNode) lazyN2N.getMutableEquivalent(tree);\r
+        \r
+        Assert.assertNull(mutableTree.getParent());\r
+        Assert.assertEquals(tree.getNodeType(), mutableTree.getNodeType());\r
+        Assert.assertEquals(1, lazyN2N.getKeyNodes().size());\r
+        \r
+        Node<?> subNode = tree.getCompositesByName("topologies").iterator().next();\r
+        Node<?> subMutant = lazyN2N.getMutableEquivalent(subNode);\r
+        \r
+        Assert.assertNotNull(subMutant.getParent());\r
+        Assert.assertEquals(subNode.getNodeType(), subMutant.getNodeType());\r
+        Assert.assertEquals(2, lazyN2N.getKeyNodes().size());\r
+        \r
+        Assert.assertEquals(mutableTree, subMutant.getParent());\r
+        Assert.assertEquals(mutableTree.getChildren().size(), 1);\r
+        Assert.assertEquals(mutableTree.getChildren().iterator().next(), subMutant);\r
+    }\r
+\r
+    /**\r
+     * Test method for {@link org.opendaylight.controller.yang.data.impl.LazyNodeToNodeMap#getMutableRoot()}.\r
+     */\r
+    @Test\r
+    public void testGetMutableRoot() {\r
+        Node<?> subNode = tree.getCompositesByName("topologies").iterator().next();\r
+        Node<?> subMutant = lazyN2N.getMutableEquivalent(subNode);\r
+        \r
+        Assert.assertNotNull(subMutant.getParent());\r
+        Assert.assertEquals(subMutant.getParent(), lazyN2N.getMutableRoot());\r
+    }\r
+\r
+}\r
diff --git a/opendaylight/sal/yang-prototype/yang/yang-data-impl/src/test/java/org/opendaylight/controller/yang/data/impl/MemoryConsumption.java b/opendaylight/sal/yang-prototype/yang/yang-data-impl/src/test/java/org/opendaylight/controller/yang/data/impl/MemoryConsumption.java
new file mode 100644 (file)
index 0000000..e53307d
--- /dev/null
@@ -0,0 +1,53 @@
+/**
+ * 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.data.impl;
+
+/**
+ * Provides memory consumption and elapsed time between 2 points 
+ * @author mirehak
+ */
+public class MemoryConsumption {
+    
+    private long memBegin;
+    private long tsBegin;
+
+    /**
+     * record memory and timestamp
+     */
+    public void startObserving() {
+        Runtime runtime = Runtime.getRuntime();
+        // Run the garbage collector
+        runtime.gc();
+        memBegin = getActualMemoryConsumption();
+        tsBegin = System.currentTimeMillis();
+    }
+    
+    
+    /**
+     * @return memory usage and time elapsed message
+     */
+    public String finishObserving() {
+        long memEnd = getActualMemoryConsumption();
+        long tsEnd = System.currentTimeMillis();
+        return String.format("Used memory: %10d B; Elapsed time: %5d ms", (memEnd - memBegin), (tsEnd - tsBegin));
+    }
+    
+    
+    /**
+     * @return actual memory usage
+     */
+    public static long getActualMemoryConsumption() {
+        Runtime runtime = Runtime.getRuntime();
+        // Calculate the used memory
+        long memory = runtime.totalMemory() - runtime.freeMemory();
+        return memory;
+    }
+    
+    
+}
diff --git a/opendaylight/sal/yang-prototype/yang/yang-data-impl/src/test/java/org/opendaylight/controller/yang/data/impl/MyNodeBuilder.java b/opendaylight/sal/yang-prototype/yang/yang-data-impl/src/test/java/org/opendaylight/controller/yang/data/impl/MyNodeBuilder.java
new file mode 100644 (file)
index 0000000..26cee74
--- /dev/null
@@ -0,0 +1,190 @@
+/*\r
+ * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.\r
+ *\r
+ * This program and the accompanying materials are made available under the\r
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,\r
+ * and is available at http://www.eclipse.org/legal/epl-v10.html\r
+ */\r
+package org.opendaylight.controller.yang.data.impl;\r
+\r
+import groovy.util.BuilderSupport;\r
+\r
+import java.net.URI;\r
+import java.net.URISyntaxException;\r
+import java.util.Date;\r
+import java.util.Map;\r
+import java.util.Map.Entry;\r
+\r
+import org.opendaylight.controller.yang.common.QName;\r
+import org.opendaylight.controller.yang.data.api.CompositeNode;\r
+import org.opendaylight.controller.yang.data.api.ModifyAction;\r
+import org.opendaylight.controller.yang.data.api.MutableCompositeNode;\r
+import org.opendaylight.controller.yang.data.api.Node;\r
+import org.opendaylight.controller.yang.data.api.SimpleNode;\r
+import org.slf4j.Logger;\r
+import org.slf4j.LoggerFactory;\r
+\r
+/**\r
+ * @author michal.rehak\r
+ *\r
+ */\r
+public class MyNodeBuilder extends BuilderSupport {\r
+    \r
+    private static final Logger LOG = LoggerFactory\r
+            .getLogger(MyNodeBuilder.class);\r
+\r
+    private URI qnNamespace;\r
+    private String qnPrefix;\r
+    private Date qnRevision;\r
+    \r
+    private CompositeNode rootNode;\r
+\r
+       /**\r
+        * @param baseQName\r
+        */\r
+       private MyNodeBuilder(QName baseQName) {\r
+               qnNamespace = baseQName.getNamespace();\r
+               qnPrefix = baseQName.getPrefix();\r
+               qnRevision = baseQName.getRevision();\r
+    }\r
+\r
+       /**\r
+        * @return initialized singleton instance\r
+        */\r
+       public static MyNodeBuilder newInstance() {\r
+       QName qName = null;\r
+       try {\r
+                       qName = new QName(\r
+                       new URI("urn:opendaylight:controller:network"), \r
+                       new Date(42), "yang-data-impl-groovyTest_", null);\r
+        } catch (URISyntaxException e) {\r
+               LOG.error(e.getMessage(), e);\r
+        }\r
+        return new MyNodeBuilder(qName);\r
+    }\r
+\r
+    @Override\r
+    protected void setParent(Object parent, Object child) {\r
+       // do nothing\r
+        if (child instanceof AbstractNodeTO<?>) {\r
+            ((AbstractNodeTO<?>) child).setParent((CompositeNode) parent);\r
+        } else {\r
+            LOG.error("PARENTING FAILED: "+parent + " -> " + child);\r
+        }\r
+    }\r
+\r
+    @Override\r
+    protected Object createNode(Object name) {\r
+        MutableCompositeNode newNode = NodeFactory.createMutableCompositeNode(\r
+                createQName(name), getCurrentNode(), null, null, null);\r
+        NodeUtils.fixParentRelation(newNode);\r
+        return newNode;\r
+    }\r
+\r
+    @Override\r
+    protected Object createNode(Object name, @SuppressWarnings("rawtypes") Map attributes) {\r
+        ModifyAction modifyAction = processAttributes(attributes);\r
+        MutableCompositeNode newNode = NodeFactory.createMutableCompositeNode(\r
+                createQName(name), getCurrentNode(), null, modifyAction, null);\r
+        NodeUtils.fixParentRelation(newNode);\r
+        return newNode;\r
+    }\r
+\r
+\r
+    @Override\r
+    protected Object createNode(Object name, @SuppressWarnings("rawtypes") Map attributes, Object value) {\r
+        ModifyAction modifyAction = processAttributes(attributes);\r
+        SimpleNode<Object> newNode = NodeFactory.createImmutableSimpleNode(\r
+                createQName(name), (CompositeNode) getCurrent(), value, modifyAction);\r
+        NodeUtils.fixParentRelation(newNode);\r
+        return newNode;\r
+    }\r
+    \r
+    /**\r
+     * @param attributes\r
+     * @return \r
+     */\r
+    private ModifyAction processAttributes(@SuppressWarnings("rawtypes") Map attributes) {\r
+        LOG.debug("attributes:" + attributes);\r
+        ModifyAction modAction = null;\r
+        \r
+        @SuppressWarnings("unchecked")\r
+        Map<String, String> attributesSane = attributes;\r
+        for (Entry<String, String> attr : attributesSane.entrySet()) {\r
+            switch (attr.getKey()) {\r
+            case "xmlns":\r
+                try {\r
+                    qnNamespace = new URI(attr.getValue());\r
+                } catch (URISyntaxException e) {\r
+                    LOG.error(e.getMessage(), e);\r
+                }\r
+                break;\r
+            case "modifyAction":\r
+                modAction = ModifyAction.valueOf(attr.getValue());\r
+                break;\r
+                \r
+            default:\r
+                throw new IllegalArgumentException("Attribute not supported: "+attr.getKey());\r
+            }\r
+        }\r
+        return modAction;\r
+    }\r
+\r
+    @Override\r
+    protected Object createNode(Object name, Object value) {\r
+        SimpleNode<Object> newNode = NodeFactory.createImmutableSimpleNode(createQName(name), (CompositeNode) getCurrent(), value);\r
+        NodeUtils.fixParentRelation(newNode);\r
+        return newNode;\r
+    }\r
+\r
+    private QName createQName(Object localName) {\r
+       LOG.debug("qname for: "+localName);\r
+           return new QName(qnNamespace, qnRevision, qnPrefix, (String) localName);\r
+    }\r
+\r
+       protected CompositeNode getCurrentNode() {\r
+           if (getCurrent() != null) {\r
+               if (getCurrent() instanceof CompositeNode) {\r
+                   return (CompositeNode) getCurrent();\r
+                   \r
+               } else {\r
+                   throw new IllegalAccessError("current node is not of type CompositeNode, but: "\r
+                       +getCurrent().getClass().getSimpleName());\r
+               }\r
+           }\r
+           \r
+           return null;\r
+    }\r
+       \r
+       @Override\r
+       protected Object postNodeCompletion(Object parent, Object node) {\r
+           Node<?> nodeRevisited = (Node<?>) node;\r
+           LOG.debug("postNodeCompletion at: \n  "+ nodeRevisited+"\n  "+parent);\r
+           if (nodeRevisited instanceof MutableCompositeNode) {\r
+               MutableCompositeNode mutant = (MutableCompositeNode) nodeRevisited;\r
+               if (mutant.getValue().isEmpty()) {\r
+                   LOG.error("why is it having empty value? -- " + mutant);\r
+               }\r
+               nodeRevisited = NodeFactory.createImmutableCompositeNode(\r
+                       mutant.getNodeType(), mutant.getParent(), mutant.getValue(), mutant.getModificationAction());\r
+               NodeUtils.fixChildrenRelation((CompositeNode) nodeRevisited);\r
+\r
+               if (parent == null) {\r
+                   rootNode = (CompositeNode) nodeRevisited;\r
+               } else {\r
+                   NodeUtils.fixParentRelation(nodeRevisited);\r
+                   nodeRevisited.getParent().getChildren().remove(mutant);\r
+               }\r
+           }\r
+           \r
+           \r
+           return nodeRevisited;\r
+       }\r
+       \r
+       /**\r
+        * @return tree root\r
+        */\r
+       public CompositeNode getRootNode() {\r
+        return rootNode;\r
+    }\r
+}
\ No newline at end of file
old mode 100755 (executable)
new mode 100644 (file)
index 3d97cc8..cafbfa3
@@ -7,8 +7,6 @@
  */\r
 package org.opendaylight.controller.yang.data.impl;\r
 \r
-import java.io.ByteArrayOutputStream;\r
-import java.io.PrintStream;\r
 import java.net.URI;\r
 import java.util.ArrayList;\r
 import java.util.Date;\r
@@ -17,6 +15,7 @@ import java.util.List;
 import java.util.Map;\r
 \r
 import org.junit.Assert;\r
+import org.junit.Before;\r
 import org.junit.Test;\r
 import org.opendaylight.controller.yang.common.QName;\r
 import org.opendaylight.controller.yang.data.api.CompositeNode;\r
@@ -24,6 +23,7 @@ import org.opendaylight.controller.yang.data.api.ModifyAction;
 import org.opendaylight.controller.yang.data.api.MutableCompositeNode;\r
 import org.opendaylight.controller.yang.data.api.Node;\r
 import org.opendaylight.controller.yang.data.api.NodeModification;\r
+import org.opendaylight.controller.yang.data.api.SimpleNode;\r
 import org.w3c.dom.Document;\r
 \r
 /**\r
@@ -31,6 +31,27 @@ import org.w3c.dom.Document;
  * \r
  */\r
 public class NodeFactoryTest {\r
+    \r
+    private QName qName;\r
+    private CompositeNode network;\r
+\r
+    private String ns;\r
+    private Document networkShadow;\r
+\r
+\r
+    /**\r
+     * @throws Exception\r
+     */\r
+    @Before\r
+    public void setUp() throws Exception {\r
+        ns = "urn:ietf:params:xml:ns:netconf:base:1.0";\r
+        qName = new QName(\r
+                new URI(ns), \r
+                new Date(42), null);\r
+        network = NodeHelper.buildTestConfigTree(qName);\r
+        networkShadow = NodeUtils.buildShadowDomTree(network);\r
+        NodeHelper.compareXmlTree(networkShadow, "./config02-shadow.xml", getClass());\r
+    }\r
 \r
     /**\r
      * Test method for methods creating immutable nodes in\r
@@ -39,29 +60,19 @@ public class NodeFactoryTest {
      */\r
     @Test\r
     public void testImmutableNodes() throws Exception {\r
-        QName qName = new QName(\r
-                new URI("urn:opendaylight:controller:network"), \r
-                new Date(42), "yang-data-impl-immutableTest_", null);\r
-        \r
-        CompositeNode network = NodeHelper.buildTestConfigTree(qName);\r
-        \r
-        \r
-        Assert.assertEquals(1, network.getChildren().size());\r
-        Document domTree = NodeUtils.buildShadowDomTree(network);\r
-        NodeHelper.dumpDoc(domTree, System.out);\r
-        \r
-        CompositeNode tpList = NodeUtils.findNodeByXpath(domTree, \r
-                "//node[node-id/text()='nodeId_19']/termination-points");\r
+        Assert.assertEquals(2, network.getChildren().size());\r
+        CompositeNode tpList = NodeUtils.findNodeByXpath(networkShadow, \r
+                NodeHelper.AddNamespaceToPattern(\r
+                        "//{0}node[{0}node-id/text()='nodeId_19']/{0}termination-points", ns));\r
         \r
         \r
         Assert.assertEquals(2, tpList.getCompositesByName("termination-point").size());\r
-//        Assert.assertEquals(1, topologies.getCompositesByName("topology").size());\r
-//        Assert.assertEquals(2, destination.getChildren().size());\r
     }\r
 \r
     /**\r
-     * Test method for methods creating immutable nodes in\r
-     * {@link org.opendaylight.controller.yang.data.impl.NodeFactory}.\r
+     * Test method for methods creating immutable and mutable nodes:\r
+     * {@link NodeFactory#createMutableCompositeNode(QName, CompositeNode, List, ModifyAction, CompositeNode)},\r
+     * {@link NodeFactory#createMutableSimpleNode(QName, CompositeNode, Object, ModifyAction, SimpleNode)}\r
      * @throws Exception \r
      */\r
     @Test\r
@@ -79,69 +90,75 @@ public class NodeFactoryTest {
         //   </top>\r
         // </config>\r
         \r
-        QName qName = new QName(\r
-                new URI("urn:ietf:params:xml:ns:netconf:base:1.0"), \r
-                new Date(42), "yang-data-impl-mutableTest");\r
         \r
         List<Node<?>> value = new ArrayList<Node<?>>(); \r
-        value.add(NodeFactory.createSimpleNode(new QName(qName, "name"), null, "Ethernet0/0"));\r
-        value.add(NodeFactory.createSimpleNode(new QName(qName, "mtu"), null, 1500));\r
+        value.add(NodeFactory.createImmutableSimpleNode(new QName(qName, "name"), null, "Ethernet0/0"));\r
+        value.add(NodeFactory.createImmutableSimpleNode(new QName(qName, "mtu"), null, 1500));\r
         \r
-        CompositeNodeModificationTOImpl ifNode = NodeFactory.createCompositeNodeModification(\r
-                new QName(qName, "interface"), null, value, ModifyAction.DELETE);\r
+        MutableCompositeNode ifNode = NodeFactory.createMutableCompositeNode(\r
+                new QName(qName, "interface"), null, value, ModifyAction.DELETE, null);\r
+        ifNode.init();\r
         NodeHelper.assignParentToChildren(ifNode);\r
         \r
         value = new ArrayList<Node<?>>(); \r
-        value.add(NodeFactory.createSimpleNode(new QName(qName, "name"), null, "Ethernet1/0"));\r
-        value.add(NodeFactory.createSimpleNode(new QName(qName, "mtu"), null, 1501));\r
+        value.add(NodeFactory.createImmutableSimpleNode(new QName(qName, "name"), null, "Ethernet1/0"));\r
+        value.add(NodeFactory.createMutableSimpleNode(new QName(qName, "mtu"), null, 1501, ModifyAction.REMOVE, null));\r
         \r
-        CompositeNode ifNode2 = NodeFactory.createCompositeNode(new QName(qName, "interface"), null, value);\r
+        CompositeNode ifNode2 = NodeFactory.createImmutableCompositeNode(new QName(qName, "interface"), null, value);\r
         NodeHelper.assignParentToChildren(ifNode2);\r
 \r
         value = new ArrayList<Node<?>>(); \r
         value.add(ifNode);\r
         value.add(ifNode2);\r
         \r
-        CompositeNode topNode = NodeFactory.createCompositeNode(new QName(qName, "top"), null, value);\r
+        CompositeNode topNode = NodeFactory.createImmutableCompositeNode(new QName(qName, "top"), null, value);\r
         NodeHelper.assignParentToChildren(topNode);\r
         value = new ArrayList<Node<?>>(); \r
         value.add(topNode);\r
         \r
-        CompositeNode root = NodeFactory.createCompositeNode(new QName(qName, "config"), null, value);\r
-        \r
+        CompositeNode root = NodeFactory.createImmutableCompositeNode(new QName(qName, "config"), null, value);\r
+        Document shadowConfig = NodeUtils.buildShadowDomTree(root);\r
+        NodeHelper.compareXmlTree(shadowConfig, "./mutableNodesConfig.xml", getClass());\r
         \r
         Assert.assertEquals(1, root.getChildren().size());\r
         Assert.assertEquals(1, ifNode.getSimpleNodesByName("name").size());\r
         Assert.assertEquals(1, ifNode.getSimpleNodesByName("mtu").size());\r
         Assert.assertEquals(2, topNode.getCompositesByName("interface").size());\r
-        NodeModification interfaceMod = (NodeModification) \r
-                topNode.getCompositesByName("interface").get(0);\r
+        NodeModification interfaceMod = topNode.getCompositesByName("interface").get(0);\r
         Assert.assertEquals(ModifyAction.DELETE, interfaceMod.getModificationAction());\r
     }\r
 \r
     /**\r
-     * test modifications builder\r
+     * test of {@link NodeFactory#copyDeepAsMutable(CompositeNode, Map)}\r
      * @throws Exception \r
      */\r
     @Test\r
-    public void testCopyDeepNode() throws Exception {\r
-        QName qName = new QName(\r
-                new URI("urn:opendaylight:controller:network"), \r
-                new Date(42), "yang-data-impl-immutableTest_", null);\r
-        \r
-        CompositeNode network = NodeHelper.buildTestConfigTree(qName);\r
+    public void testCopyDeepAsMutable() throws Exception {\r
         Map<Node<?>, Node<?>> mutableToOrig = new HashMap<>();\r
-        MutableCompositeNode mutableNetwork = NodeFactory.copyDeepNode(network, mutableToOrig );\r
+        CompositeNode mutableNetwork = NodeFactory.copyDeepAsMutable(network, mutableToOrig);\r
 \r
-        Document networkShadow = NodeUtils.buildShadowDomTree(network);\r
-        ByteArrayOutputStream expected = new ByteArrayOutputStream();\r
-        NodeHelper.dumpDoc(networkShadow, new PrintStream(expected));\r
-        \r
         Document mutableNetworkShadow = NodeUtils.buildShadowDomTree(mutableNetwork);\r
-        ByteArrayOutputStream actual = new ByteArrayOutputStream();\r
-        NodeHelper.dumpDoc(mutableNetworkShadow, new PrintStream(actual));\r
         \r
-        Assert.assertEquals(new String(expected.toByteArray()), new String(actual.toByteArray()));\r
+        NodeHelper.compareXmlTree(mutableNetworkShadow, "./config02-shadow.xml", getClass());\r
+        \r
+        CompositeNode immutableNetwork = NodeFactory.copyDeepAsImmutable(mutableNetwork, null);\r
+        Assert.assertEquals(network, immutableNetwork);\r
+    }\r
+    \r
+    \r
+    /**\r
+     * test of {@link NodeFactory#copyDeepAsImmutable(CompositeNode, Map)}\r
+     * @throws Exception \r
+     */\r
+    @Test\r
+    public void testCopyDeepAsImmutable() throws Exception {\r
+        Map<Node<?>, Node<?>> mutableToOrig = new HashMap<>();\r
+        CompositeNode immutableNetwork = NodeFactory.copyDeepAsImmutable(network, mutableToOrig);\r
+        \r
+        Document mutableNetworkShadow = NodeUtils.buildShadowDomTree(immutableNetwork);\r
+        NodeHelper.compareXmlTree(mutableNetworkShadow, "./config02-shadow.xml", getClass());\r
+        \r
+        Assert.assertEquals(network, immutableNetwork);\r
     }\r
 \r
 }\r
old mode 100755 (executable)
new mode 100644 (file)
index 3b7c0d0..a7e7d2f
@@ -7,9 +7,20 @@
  */\r
 package org.opendaylight.controller.yang.data.impl;\r
 \r
+import groovy.lang.Binding;\r
+import groovy.lang.GroovyShell;\r
+import groovy.lang.Script;\r
+\r
+import java.io.ByteArrayInputStream;\r
+import java.io.ByteArrayOutputStream;\r
+import java.io.IOException;\r
 import java.io.InputStream;\r
+import java.io.InputStreamReader;\r
 import java.io.PrintStream;\r
+import java.io.Reader;\r
 import java.io.StringWriter;\r
+import java.lang.reflect.Method;\r
+import java.text.MessageFormat;\r
 import java.util.ArrayList;\r
 import java.util.List;\r
 import java.util.Set;\r
@@ -20,6 +31,8 @@ import javax.xml.transform.TransformerFactory;
 import javax.xml.transform.dom.DOMSource;\r
 import javax.xml.transform.stream.StreamResult;\r
 \r
+import org.custommonkey.xmlunit.Diff;\r
+import org.junit.Assert;\r
 import org.opendaylight.controller.yang.common.QName;\r
 import org.opendaylight.controller.yang.data.api.CompositeNode;\r
 import org.opendaylight.controller.yang.data.api.Node;\r
@@ -27,7 +40,10 @@ import org.opendaylight.controller.yang.model.api.Module;
 import org.opendaylight.controller.yang.model.api.SchemaContext;\r
 import org.opendaylight.controller.yang.model.parser.api.YangModelParser;\r
 import org.opendaylight.controller.yang.parser.impl.YangParserImpl;\r
+import org.slf4j.Logger;\r
+import org.slf4j.LoggerFactory;\r
 import org.w3c.dom.Document;\r
+import org.xml.sax.SAXException;\r
 \r
 /**\r
  * @author michal.rehak\r
@@ -35,6 +51,8 @@ import org.w3c.dom.Document;
  */\r
 public abstract class NodeHelper {\r
     \r
+    private static final Logger LOG = LoggerFactory.getLogger(NodeHelper.class);\r
+    \r
     /** xml source of example network configuration */\r
     public static final String NETWORK_XML = \r
       "<network xmlns=\"urn:opendaylight:controller:network\">\n" +\r
@@ -127,145 +145,145 @@ public abstract class NodeHelper {
       String xmlString = result.getWriter().toString();\r
       out.println(xmlString);\r
     }\r
-\r
+    \r
     /**\r
      * @param qName\r
      * @return example tree, see {@link #NETWORK_XML}\r
      */\r
     public static CompositeNode buildTestConfigTree(QName qName) {\r
         List<Node<?>> value = new ArrayList<Node<?>>(); \r
-        value.add(NodeFactory.createSimpleNode(new QName(qName, "element-id"), null, "ntElementId_09"));\r
-        CompositeNode ntElementNode1 = NodeFactory.createCompositeNode(new QName(qName, "network-element"), null, value);\r
+        value.add(NodeFactory.createImmutableSimpleNode(new QName(qName, "element-id"), null, "ntElementId_09"));\r
+        CompositeNode ntElementNode1 = NodeFactory.createImmutableCompositeNode(new QName(qName, "network-element"), null, value);\r
         assignParentToChildren(ntElementNode1);\r
         \r
         value = new ArrayList<Node<?>>(); \r
-        value.add(NodeFactory.createSimpleNode(new QName(qName, "element-id"), null, "ntElementId_10"));\r
-        CompositeNode ntElementNode2 = NodeFactory.createCompositeNode(new QName(qName, "network-element"), null, value);\r
+        value.add(NodeFactory.createImmutableSimpleNode(new QName(qName, "element-id"), null, "ntElementId_10"));\r
+        CompositeNode ntElementNode2 = NodeFactory.createImmutableCompositeNode(new QName(qName, "network-element"), null, value);\r
         assignParentToChildren(ntElementNode2);\r
         \r
         value = new ArrayList<Node<?>>();\r
         value.add(ntElementNode1);\r
         value.add(ntElementNode2);\r
-        CompositeNode ntElementsNode = NodeFactory.createCompositeNode(\r
+        CompositeNode ntElementsNode = NodeFactory.createImmutableCompositeNode(\r
                 new QName(qName, "network-elements"), null, value);\r
         assignParentToChildren(ntElementsNode);\r
         \r
         value = new ArrayList<Node<?>>(); \r
-        value.add(NodeFactory.createSimpleNode(new QName(qName, "dest-node"), null, "nodeId_07"));\r
-        value.add(NodeFactory.createSimpleNode(new QName(qName, "dest-tp"), null, "tpId_08"));\r
-        CompositeNode destination = NodeFactory.createCompositeNode(\r
+        value.add(NodeFactory.createImmutableSimpleNode(new QName(qName, "dest-node"), null, "nodeId_07"));\r
+        value.add(NodeFactory.createImmutableSimpleNode(new QName(qName, "dest-tp"), null, "tpId_08"));\r
+        CompositeNode destination = NodeFactory.createImmutableCompositeNode(\r
                 new QName(qName, "destination"), null, value);\r
         assignParentToChildren(destination);\r
         \r
         value = new ArrayList<Node<?>>(); \r
-        value.add(NodeFactory.createSimpleNode(new QName(qName, "source-node"), null, "nodeId_05"));\r
-        value.add(NodeFactory.createSimpleNode(new QName(qName, "source-tp"), null, "tpId_06"));\r
-        CompositeNode source = NodeFactory.createCompositeNode(\r
+        value.add(NodeFactory.createImmutableSimpleNode(new QName(qName, "source-node"), null, "nodeId_05"));\r
+        value.add(NodeFactory.createImmutableSimpleNode(new QName(qName, "source-tp"), null, "tpId_06"));\r
+        CompositeNode source = NodeFactory.createImmutableCompositeNode(\r
                 new QName(qName, "source"), null, value);\r
         assignParentToChildren(source);\r
         \r
         value = new ArrayList<Node<?>>(); \r
-        value.add(NodeFactory.createSimpleNode(new QName(qName, "link-id"), null, "linkId_04"));\r
+        value.add(NodeFactory.createImmutableSimpleNode(new QName(qName, "link-id"), null, "linkId_04"));\r
         value.add(source);\r
         value.add(destination);\r
-        CompositeNode link1 = NodeFactory.createCompositeNode(\r
+        CompositeNode link1 = NodeFactory.createImmutableCompositeNode(\r
                 new QName(qName, "link"), null, value);\r
         assignParentToChildren(link1);\r
         \r
         value = new ArrayList<Node<?>>(); \r
-        value.add(NodeFactory.createSimpleNode(new QName(qName, "dest-node"), null, "nodeId_14"));\r
-        value.add(NodeFactory.createSimpleNode(new QName(qName, "dest-tp"), null, "tpId_15"));\r
-        destination = NodeFactory.createCompositeNode(\r
+        value.add(NodeFactory.createImmutableSimpleNode(new QName(qName, "dest-node"), null, "nodeId_14"));\r
+        value.add(NodeFactory.createImmutableSimpleNode(new QName(qName, "dest-tp"), null, "tpId_15"));\r
+        destination = NodeFactory.createImmutableCompositeNode(\r
                 new QName(qName, "destination"), null, value);\r
         assignParentToChildren(destination);\r
         \r
         value = new ArrayList<Node<?>>(); \r
-        value.add(NodeFactory.createSimpleNode(new QName(qName, "source-node"), null, "nodeId_12"));\r
-        value.add(NodeFactory.createSimpleNode(new QName(qName, "source-tp"), null, "tpId_13"));\r
-        source = NodeFactory.createCompositeNode(\r
+        value.add(NodeFactory.createImmutableSimpleNode(new QName(qName, "source-node"), null, "nodeId_12"));\r
+        value.add(NodeFactory.createImmutableSimpleNode(new QName(qName, "source-tp"), null, "tpId_13"));\r
+        source = NodeFactory.createImmutableCompositeNode(\r
                 new QName(qName, "source"), null, value);\r
         assignParentToChildren(source);\r
         \r
         value = new ArrayList<Node<?>>(); \r
-        value.add(NodeFactory.createSimpleNode(new QName(qName, "link-id"), null, "linkId_11"));\r
+        value.add(NodeFactory.createImmutableSimpleNode(new QName(qName, "link-id"), null, "linkId_11"));\r
         value.add(source);\r
         value.add(destination);\r
-        CompositeNode link2 = NodeFactory.createCompositeNode(\r
+        CompositeNode link2 = NodeFactory.createImmutableCompositeNode(\r
                 new QName(qName, "link"), null, value);\r
         assignParentToChildren(link2);\r
         \r
         value = new ArrayList<Node<?>>(); \r
         value.add(link1);\r
         value.add(link2);\r
-        CompositeNode links = NodeFactory.createCompositeNode(\r
+        CompositeNode links = NodeFactory.createImmutableCompositeNode(\r
                 new QName(qName, "links"), null, value);\r
         assignParentToChildren(links);\r
         \r
         \r
         value = new ArrayList<Node<?>>(); \r
-        value.add(NodeFactory.createSimpleNode(new QName(qName, "tp-id"), null, "tpId_03"));\r
-        CompositeNode terminationPointNode1 = NodeFactory.createCompositeNode(\r
+        value.add(NodeFactory.createImmutableSimpleNode(new QName(qName, "tp-id"), null, "tpId_03"));\r
+        CompositeNode terminationPointNode1 = NodeFactory.createImmutableCompositeNode(\r
                 new QName(qName, "termination-point"), null, value);\r
         assignParentToChildren(terminationPointNode1);\r
         \r
         value = new ArrayList<Node<?>>(); \r
         value.add(terminationPointNode1);\r
-        CompositeNode terminationPointsNode = NodeFactory.createCompositeNode(\r
+        CompositeNode terminationPointsNode = NodeFactory.createImmutableCompositeNode(\r
                 new QName(qName, "termination-points"), null, value);\r
         assignParentToChildren(terminationPointsNode);\r
         \r
         value = new ArrayList<Node<?>>(); \r
-        value.add(NodeFactory.createSimpleNode(new QName(qName, "node-id"), null, "nodeId_02"));\r
-        value.add(NodeFactory.createSimpleNode(new QName(qName, "supporting-ne"), null, "networkId_02"));\r
+        value.add(NodeFactory.createImmutableSimpleNode(new QName(qName, "node-id"), null, "nodeId_02"));\r
+        value.add(NodeFactory.createImmutableSimpleNode(new QName(qName, "supporting-ne"), null, "networkId_02"));\r
         value.add(terminationPointsNode);\r
-        CompositeNode node1Node = NodeFactory.createCompositeNode(\r
+        CompositeNode node1Node = NodeFactory.createImmutableCompositeNode(\r
                 new QName(qName, "node"), null, value);\r
         assignParentToChildren(node1Node);\r
         \r
         value = new ArrayList<Node<?>>(); \r
-        value.add(NodeFactory.createSimpleNode(new QName(qName, "tp-id"), null, "tpId_18"));\r
-        terminationPointNode1 = NodeFactory.createCompositeNode(\r
+        value.add(NodeFactory.createImmutableSimpleNode(new QName(qName, "tp-id"), null, "tpId_18"));\r
+        terminationPointNode1 = NodeFactory.createImmutableCompositeNode(\r
                 new QName(qName, "termination-point"), null, value);\r
         assignParentToChildren(terminationPointNode1);\r
         \r
         value = new ArrayList<Node<?>>(); \r
         value.add(terminationPointNode1);\r
-        terminationPointsNode = NodeFactory.createCompositeNode(\r
+        terminationPointsNode = NodeFactory.createImmutableCompositeNode(\r
                 new QName(qName, "termination-points"), null, value);\r
         assignParentToChildren(terminationPointsNode);\r
         \r
         value = new ArrayList<Node<?>>(); \r
-        value.add(NodeFactory.createSimpleNode(new QName(qName, "node-id"), null, "nodeId_16"));\r
-        value.add(NodeFactory.createSimpleNode(new QName(qName, "supporting-ne"), null, "networkId_17"));\r
+        value.add(NodeFactory.createImmutableSimpleNode(new QName(qName, "node-id"), null, "nodeId_16"));\r
+        value.add(NodeFactory.createImmutableSimpleNode(new QName(qName, "supporting-ne"), null, "networkId_17"));\r
         value.add(terminationPointsNode);\r
-        CompositeNode node2Node = NodeFactory.createCompositeNode(\r
+        CompositeNode node2Node = NodeFactory.createImmutableCompositeNode(\r
                 new QName(qName, "node"), null, value);\r
         assignParentToChildren(node2Node);\r
         \r
         value = new ArrayList<Node<?>>(); \r
-        value.add(NodeFactory.createSimpleNode(new QName(qName, "tp-id"), null, "tpId_18"));\r
-        terminationPointNode1 = NodeFactory.createCompositeNode(\r
+        value.add(NodeFactory.createImmutableSimpleNode(new QName(qName, "tp-id"), null, "tpId_18"));\r
+        terminationPointNode1 = NodeFactory.createImmutableCompositeNode(\r
                 new QName(qName, "termination-point"), null, value);\r
         assignParentToChildren(terminationPointNode1);\r
         \r
         value = new ArrayList<Node<?>>(); \r
-        value.add(NodeFactory.createSimpleNode(new QName(qName, "tp-id"), null, "tpId_19"));\r
-        CompositeNode terminationPointNode2 = NodeFactory.createCompositeNode(\r
+        value.add(NodeFactory.createImmutableSimpleNode(new QName(qName, "tp-id"), null, "tpId_19"));\r
+        CompositeNode terminationPointNode2 = NodeFactory.createImmutableCompositeNode(\r
                 new QName(qName, "termination-point"), null, value);\r
         assignParentToChildren(terminationPointNode2);\r
         \r
         value = new ArrayList<Node<?>>(); \r
         value.add(terminationPointNode1);\r
         value.add(terminationPointNode2);\r
-        terminationPointsNode = NodeFactory.createCompositeNode(\r
+        terminationPointsNode = NodeFactory.createImmutableCompositeNode(\r
                 new QName(qName, "termination-points"), null, value);\r
         assignParentToChildren(terminationPointsNode);\r
         \r
         value = new ArrayList<Node<?>>(); \r
-        value.add(NodeFactory.createSimpleNode(new QName(qName, "node-id"), null, "nodeId_19"));\r
-        value.add(NodeFactory.createSimpleNode(new QName(qName, "supporting-ne"), null, "networkId_20"));\r
+        value.add(NodeFactory.createImmutableSimpleNode(new QName(qName, "node-id"), null, "nodeId_19"));\r
+        value.add(NodeFactory.createImmutableSimpleNode(new QName(qName, "supporting-ne"), null, "networkId_20"));\r
         value.add(terminationPointsNode);\r
-        CompositeNode node3Node = NodeFactory.createCompositeNode(\r
+        CompositeNode node3Node = NodeFactory.createImmutableCompositeNode(\r
                 new QName(qName, "node"), null, value);\r
         assignParentToChildren(node3Node);\r
         \r
@@ -273,27 +291,28 @@ public abstract class NodeHelper {
         value.add(node1Node);\r
         value.add(node2Node);\r
         value.add(node3Node);\r
-        CompositeNode nodesNode = NodeFactory.createCompositeNode(\r
+        CompositeNode nodesNode = NodeFactory.createImmutableCompositeNode(\r
                 new QName(qName, "nodes"), null, value);\r
         assignParentToChildren(nodesNode);\r
         \r
         value = new ArrayList<Node<?>>();\r
         value.add(links);\r
         value.add(nodesNode);\r
-        value.add(NodeFactory.createSimpleNode(new QName(qName, "topology-id"), null, "topId_01"));\r
-        CompositeNode topology = NodeFactory.createCompositeNode(\r
+        value.add(NodeFactory.createImmutableSimpleNode(new QName(qName, "topology-id"), null, "topId_01"));\r
+        CompositeNode topology = NodeFactory.createImmutableCompositeNode(\r
                 new QName(qName, "topology"), null, value);\r
         assignParentToChildren(topology);\r
         \r
         value = new ArrayList<Node<?>>();\r
         value.add(topology);\r
-        CompositeNode topologies = NodeFactory.createCompositeNode(\r
+        CompositeNode topologies = NodeFactory.createImmutableCompositeNode(\r
                 new QName(qName, "topologies"), null, value);\r
         assignParentToChildren(topologies);\r
         \r
         value = new ArrayList<Node<?>>();\r
         value.add(topologies);\r
-        CompositeNode network = NodeFactory.createCompositeNode(\r
+        value.add(ntElementsNode);\r
+        CompositeNode network = NodeFactory.createImmutableCompositeNode(\r
                 new QName(qName, "network"), null, value);\r
         assignParentToChildren(network);\r
         \r
@@ -323,5 +342,70 @@ public abstract class NodeHelper {
                 .parseYangModelsFromStreams(yangInputStreams);\r
         return yParser.resolveSchemaContext(modules);\r
     }\r
+    \r
+    /**\r
+     * @param scriptName \r
+     * @return tree root\r
+     * @throws Exception\r
+     */\r
+    public static CompositeNode loadConfigByGroovy(String scriptName) throws Exception {\r
+       InputStream configStream = NodeHelper.class.getResourceAsStream(scriptName);\r
+       Binding binding = new Binding();\r
+       GroovyShell gShell = new GroovyShell(binding);\r
+       LOG.debug("groovy: starting script parse..  " + scriptName);\r
+               Script configScript = gShell.parse(new InputStreamReader(configStream));\r
+               LOG.debug("groovy: starting script..  " + scriptName);\r
+               configScript.run();\r
+               LOG.debug("groovy: digging result");\r
+       Object xmlGen = binding.getVariable("xmlGen");\r
+       LOG.debug("xmlGen = " + xmlGen);\r
+       Method getter = xmlGen.getClass().getDeclaredMethod("getBuilder", new Class[0]);\r
+       MyNodeBuilder builder = (MyNodeBuilder) getter.invoke(xmlGen, new Object[0]);\r
+       \r
+       return builder.getRootNode();\r
+    }\r
+    \r
+    /**\r
+     * @param pattern , e.g.: <pre>"//{0}:network/{1}:xx[text() = 'sss']"</pre>\r
+     * @param nsArg , e.g.: <pre>{"uri:ns1", "uri:ns2"}</pre>\r
+     * @return pattern with namespaces: <pre>//uri:ns1:network/uri:ns2:xx[text() = ''sss'']"</pre>\r
+     */\r
+    public static String AddNamespaceToPattern(String pattern, Object... nsArg) {\r
+        Object[] ns = nsArg;\r
+        String patternNs = pattern.replaceAll("'", "''");\r
+        if (ns == null) {\r
+            ns = new Object[]{""};\r
+        } else {\r
+            // add ':' into pattern after placeholders\r
+            patternNs = patternNs.replaceAll("(\\{[0-9]+\\})", "$1:");\r
+        }\r
+        \r
+        return MessageFormat.format(patternNs, ns);\r
+    }\r
+\r
+    /**\r
+     * @param tree\r
+     * @param xmlFile \r
+     * @param clazz \r
+     * @throws Exception\r
+     * @throws SAXException\r
+     * @throws IOException\r
+     */\r
+    public static void compareXmlTree(Document tree, String xmlFile, Class<?> clazz) throws Exception,\r
+            SAXException, IOException {\r
+        ByteArrayOutputStream actualRaw = new ByteArrayOutputStream();\r
+        dumpDoc(tree, new PrintStream(actualRaw));\r
+        Reader actualReader = new InputStreamReader(new ByteArrayInputStream(actualRaw.toByteArray()));\r
+        \r
+        Reader expectedReader = new InputStreamReader(clazz.getResourceAsStream(xmlFile));\r
+        Diff myDiff = new Diff(expectedReader, actualReader);\r
+        myDiff.overrideDifferenceListener(new IgnoreWhiteCharsDiffListener());\r
+        \r
+        boolean similar = myDiff.similar();\r
+        if (! similar) {\r
+            System.out.println(new String(actualRaw.toByteArray()));\r
+        }\r
+        Assert.assertEquals(myDiff.toString(), true, similar);\r
+    }\r
 \r
 }\r
old mode 100755 (executable)
new mode 100644 (file)
index 2df397a..5f4e482
@@ -18,8 +18,11 @@ import org.opendaylight.controller.yang.common.QName;
 import org.opendaylight.controller.yang.data.api.CompositeNode;\r
 import org.opendaylight.controller.yang.data.api.MutableCompositeNode;\r
 import org.opendaylight.controller.yang.data.api.MutableSimpleNode;\r
+import org.opendaylight.controller.yang.data.api.Node;\r
 import org.opendaylight.controller.yang.data.api.SimpleNode;\r
 import org.opendaylight.controller.yang.model.api.SchemaContext;\r
+import org.slf4j.Logger;\r
+import org.slf4j.LoggerFactory;\r
 import org.w3c.dom.Document;\r
 \r
 /**\r
@@ -27,12 +30,28 @@ import org.w3c.dom.Document;
  * \r
  */\r
 public class NodeModificationBuilderImplTest {\r
+    \r
+    private static final Logger LOG = LoggerFactory\r
+            .getLogger(NodeModificationBuilderImplTest.class);\r
 \r
     private SchemaContext schemaCtx;\r
     private QName qName;\r
     private CompositeNode network;\r
     private NodeModificationBuilderImpl nodeModificationBuilder;\r
 \r
+    private String ns;\r
+\r
+    /**\r
+     * @throws Exception\r
+     */\r
+    private void dumpResult() throws Exception {\r
+        CompositeNode diffTree = nodeModificationBuilder.buildDiffTree();\r
+        CompositeNode diffTreeImmutable = NodeFactory.copyDeepAsImmutable(diffTree, null);\r
+        \r
+        Document diffShadow = NodeUtils.buildShadowDomTree(diffTreeImmutable);\r
+        NodeHelper.dumpDoc(diffShadow, System.out);\r
+    }\r
+\r
     /**\r
      * prepare schemaContext\r
      * @throws Exception \r
@@ -41,14 +60,130 @@ public class NodeModificationBuilderImplTest {
     public void setUp() throws Exception {\r
         schemaCtx = NodeHelper.loadSchemaContext();\r
 \r
+        ns = "urn:opendaylight:controller:network";\r
         qName = new QName(\r
-                new URI("urn:opendaylight:controller:network"), \r
+                new URI(ns), \r
                 new Date(1369000800000L), "topos");\r
         network = NodeHelper.buildTestConfigTree(qName);\r
         \r
         nodeModificationBuilder = new NodeModificationBuilderImpl(network, schemaCtx);\r
     }\r
 \r
+    /**\r
+     * Test method for\r
+     * {@link org.opendaylight.controller.yang.data.impl.NodeModificationBuilderImpl#getMutableEquivalent(org.opendaylight.controller.yang.data.api.Node)}\r
+     * .\r
+     */\r
+    @Test\r
+    public void testGetMutableEquivalent() {\r
+        MutableCompositeNode rootMutable = (MutableCompositeNode) \r
+                nodeModificationBuilder.getMutableEquivalent(network);\r
+        \r
+        CompositeNode topologies = network.getCompositesByName("topologies").iterator().next();\r
+        Node<?> mutableEquivalent = nodeModificationBuilder.getMutableEquivalent(topologies);\r
+        CompositeNode topologiesMutable = rootMutable.getCompositesByName("topologies").iterator().next();\r
+        \r
+        Assert.assertSame(topologiesMutable, mutableEquivalent);\r
+    }\r
+\r
+    /**\r
+     * Test method for\r
+     * {@link org.opendaylight.controller.yang.data.impl.NodeModificationBuilderImpl#buildDiffTree()}\r
+     * .\r
+     * @throws Exception \r
+     */\r
+    @Test\r
+    public void testBuildDiffTreeAddSimple() throws Exception {\r
+        LOG.debug("testBuildDiffTreeAddSimple");\r
+        Document networkShadow = NodeUtils.buildShadowDomTree(network);\r
+        CompositeNode needle = NodeUtils.findNodeByXpath(networkShadow, \r
+                NodeHelper.AddNamespaceToPattern(\r
+                "//{0}node[{0}node-id='nodeId_19']//{0}termination-point[2]", ns));\r
+        \r
+        MutableCompositeNode mutableParent = (MutableCompositeNode) \r
+                nodeModificationBuilder.getMutableEquivalent(needle);\r
+        \r
+        MutableSimpleNode<String> newMutable = NodeFactory.createMutableSimpleNode(\r
+                new QName(needle.getNodeType(), "anySubNode"), mutableParent, "42", null, null);\r
+        \r
+        nodeModificationBuilder.addNode(newMutable);\r
+        dumpResult();\r
+    }\r
+    \r
+    /**\r
+     * Test method for\r
+     * {@link org.opendaylight.controller.yang.data.impl.NodeModificationBuilderImpl#buildDiffTree()}\r
+     * .\r
+     * @throws Exception \r
+     */\r
+    @Test\r
+    public void testBuildDiffTreeAddComposite() throws Exception {\r
+        LOG.debug("testBuildDiffTreeAddComposite");\r
+        Document networkShadow = NodeUtils.buildShadowDomTree(network);\r
+        CompositeNode needle = NodeUtils.findNodeByXpath(networkShadow, \r
+                NodeHelper.AddNamespaceToPattern(\r
+                "//{0}node[{0}node-id='nodeId_19']//{0}termination-point[2]", ns));\r
+        \r
+        MutableCompositeNode mutableParent = (MutableCompositeNode) \r
+                nodeModificationBuilder.getMutableEquivalent(needle);\r
+        \r
+        MutableSimpleNode<String> newMutable = NodeFactory.createMutableSimpleNode(\r
+                new QName(needle.getNodeType(), "anySubNode"), null, "42", null, null);\r
+        \r
+        MutableCompositeNode newMutableCom = NodeFactory.createMutableCompositeNode(\r
+                new QName(needle.getNodeType(), "anySubNode"), mutableParent, \r
+                NodeUtils.buildChildrenList(newMutable), null, null);\r
+        NodeUtils.fixChildrenRelation(newMutableCom);\r
+        newMutableCom.init();\r
+        \r
+        nodeModificationBuilder.addNode(newMutableCom);\r
+        dumpResult();\r
+    }\r
+\r
+    /**\r
+     * Test method for\r
+     * {@link org.opendaylight.controller.yang.data.impl.NodeModificationBuilderImpl#buildDiffTree()}\r
+     * .\r
+     * @throws Exception \r
+     */\r
+    @Test\r
+    public void testBuildDiffTreeDeleteComposite() throws Exception {\r
+        LOG.debug("testBuildDiffTreeDeleteComposite");\r
+        Document networkShadow = NodeUtils.buildShadowDomTree(network);\r
+        SimpleNode<?> needle = NodeUtils.findNodeByXpath(networkShadow, \r
+                NodeHelper.AddNamespaceToPattern(\r
+                "//{0}node[{0}node-id='nodeId_19']//{0}termination-point[2]/{0}tp-id", ns));\r
+\r
+        @SuppressWarnings("unchecked")\r
+        MutableSimpleNode<String> mutableNeedle = (MutableSimpleNode<String>) \r
+                nodeModificationBuilder.getMutableEquivalent(needle);\r
+        \r
+        nodeModificationBuilder.deleteNode(mutableNeedle.getParent().asMutable());\r
+        dumpResult();\r
+    }\r
+\r
+    /**\r
+     * Test method for\r
+     * {@link org.opendaylight.controller.yang.data.impl.NodeModificationBuilderImpl#buildDiffTree()}\r
+     * .\r
+     * @throws Exception \r
+     */\r
+    @Test\r
+    public void testBuildDiffTreeDeleteSimple() throws Exception {\r
+        LOG.debug("testBuildDiffTreeDeleteSimple");\r
+        Document networkShadow = NodeUtils.buildShadowDomTree(network);\r
+        SimpleNode<?> needle = NodeUtils.findNodeByXpath(networkShadow, \r
+                NodeHelper.AddNamespaceToPattern(\r
+                "//{0}node[{0}node-id='nodeId_19']//{0}termination-point[2]/{0}tp-id", ns));\r
+        \r
+        @SuppressWarnings("unchecked")\r
+        MutableSimpleNode<String> mutableNeedle = (MutableSimpleNode<String>) \r
+                nodeModificationBuilder.getMutableEquivalent(needle);\r
+        \r
+        nodeModificationBuilder.deleteNode(mutableNeedle);\r
+        dumpResult();\r
+    }\r
+\r
     /**\r
      * Test method for\r
      * {@link org.opendaylight.controller.yang.data.impl.NodeModificationBuilderImpl#buildDiffTree()}\r
@@ -56,37 +191,111 @@ public class NodeModificationBuilderImplTest {
      * @throws Exception \r
      */\r
     @Test\r
-    public void testBuildDiffTree() throws Exception {\r
+    public void testBuildDiffTreeMerge() throws Exception {\r
+        LOG.debug("testBuildDiffTreeMerge");\r
         Document networkShadow = NodeUtils.buildShadowDomTree(network);\r
-        SimpleNode<String> needle = NodeUtils.findNodeByXpath(networkShadow, \r
-                "//node[node-id='nodeId_19']//termination-point[2]/tp-id");\r
+        SimpleNode<?> needle = NodeUtils.findNodeByXpath(networkShadow, \r
+                NodeHelper.AddNamespaceToPattern(\r
+                "//{0}node[{0}node-id='nodeId_19']//{0}termination-point[2]/{0}tp-id", ns));\r
         \r
         @SuppressWarnings("unchecked")\r
         MutableSimpleNode<String> mutableNeedle = (MutableSimpleNode<String>) \r
                 nodeModificationBuilder.getMutableEquivalent(needle);\r
         \r
         mutableNeedle.setValue("tpId_18x");\r
-        nodeModificationBuilder.replaceNode(mutableNeedle);\r
-        CompositeNode diffTree = nodeModificationBuilder.buildDiffTree();\r
+        nodeModificationBuilder.mergeNode(mutableNeedle.getParent().asMutable());\r
+        dumpResult();\r
+    }\r
+\r
+    /**\r
+     * Test method for\r
+     * {@link org.opendaylight.controller.yang.data.impl.NodeModificationBuilderImpl#buildDiffTree()}\r
+     * .\r
+     * @throws Exception \r
+     */\r
+    @Test\r
+    public void testBuildDiffTreeRemoveComposite() throws Exception {\r
+        LOG.debug("testBuildDiffTreeRemoveComposite");\r
+        Document networkShadow = NodeUtils.buildShadowDomTree(network);\r
+        SimpleNode<?> needle = NodeUtils.findNodeByXpath(networkShadow, \r
+                NodeHelper.AddNamespaceToPattern(\r
+                "//{0}node[{0}node-id='nodeId_19']//{0}termination-point[2]/{0}tp-id", ns));\r
         \r
-        Document diffShadow = NodeUtils.buildShadowDomTree(diffTree);\r
-        NodeHelper.dumpDoc(diffShadow, System.out);\r
+        @SuppressWarnings("unchecked")\r
+        MutableSimpleNode<String> mutableNeedle = (MutableSimpleNode<String>) \r
+                nodeModificationBuilder.getMutableEquivalent(needle);\r
+        \r
+        nodeModificationBuilder.removeNode(mutableNeedle.getParent().asMutable());\r
+        dumpResult();\r
     }\r
 \r
     /**\r
      * Test method for\r
-     * {@link org.opendaylight.controller.yang.data.impl.NodeModificationBuilderImpl#getMutableEquivalent(org.opendaylight.controller.yang.data.api.Node)}\r
+     * {@link org.opendaylight.controller.yang.data.impl.NodeModificationBuilderImpl#buildDiffTree()}\r
      * .\r
+     * @throws Exception \r
      */\r
     @Test\r
-    public void testGetMutableEquivalent() {\r
-        MutableCompositeNode rootMutable = (MutableCompositeNode) \r
-                nodeModificationBuilder.getMutableEquivalent(network);\r
+    public void testBuildDiffTreeRemoveSimple() throws Exception {\r
+        LOG.debug("testBuildDiffTreeRemoveSimple");\r
+        Document networkShadow = NodeUtils.buildShadowDomTree(network);\r
+        SimpleNode<?> needle = NodeUtils.findNodeByXpath(networkShadow, \r
+                NodeHelper.AddNamespaceToPattern(\r
+                "//{0}node[{0}node-id='nodeId_19']//{0}termination-point[2]/{0}tp-id", ns));\r
         \r
-        CompositeNode topologies = network.getCompositesByName("topologies").iterator().next();\r
-        CompositeNode topologiesMutable = rootMutable.getCompositesByName("topologies").iterator().next();\r
+        @SuppressWarnings("unchecked")\r
+        MutableSimpleNode<String> mutableNeedle = (MutableSimpleNode<String>) \r
+                nodeModificationBuilder.getMutableEquivalent(needle);\r
+        \r
+        nodeModificationBuilder.removeNode(mutableNeedle);\r
+        dumpResult();\r
+    }\r
+\r
+    /**\r
+     * Test method for\r
+     * {@link org.opendaylight.controller.yang.data.impl.NodeModificationBuilderImpl#buildDiffTree()}\r
+     * .\r
+     * @throws Exception \r
+     */\r
+    @Test\r
+    public void testBuildDiffTreeReplaceComposite() throws Exception {\r
+        LOG.debug("testBuildDiffTreeReplaceComposite");\r
+        Document networkShadow = NodeUtils.buildShadowDomTree(network);\r
+        SimpleNode<?> needle = NodeUtils.findNodeByXpath(networkShadow, \r
+                NodeHelper.AddNamespaceToPattern(\r
+                "//{0}node[{0}node-id='nodeId_19']//{0}termination-point[2]/{0}tp-id", ns));\r
+        \r
+        @SuppressWarnings("unchecked")\r
+        MutableSimpleNode<String> mutableNeedle = (MutableSimpleNode<String>) \r
+                nodeModificationBuilder.getMutableEquivalent(needle);\r
+        \r
+        mutableNeedle.setValue("tpId_18x");\r
+        nodeModificationBuilder.replaceNode(mutableNeedle.getParent().asMutable());\r
+        dumpResult();\r
+    }\r
+\r
+    /**\r
+     * Test method for\r
+     * {@link org.opendaylight.controller.yang.data.impl.NodeModificationBuilderImpl#buildDiffTree()}\r
+     * .\r
+     * @throws Exception \r
+     */\r
+    @Test\r
+    public void testBuildDiffTreeReplaceSimple() throws Exception {\r
+        LOG.debug("testBuildDiffTreeReplaceSimple");\r
+        Document networkShadow = NodeUtils.buildShadowDomTree(network);\r
+        SimpleNode<?> needle = NodeUtils.findNodeByXpath(networkShadow, \r
+                NodeHelper.AddNamespaceToPattern(\r
+                "//{0}node[{0}node-id='nodeId_19']//{0}termination-point[2]/{0}tp-id", ns));\r
         \r
-        Assert.assertSame(topologiesMutable, nodeModificationBuilder.getMutableEquivalent(topologies));\r
+        @SuppressWarnings("unchecked")\r
+        MutableSimpleNode<String> mutableNeedle = (MutableSimpleNode<String>) \r
+                nodeModificationBuilder.getMutableEquivalent(needle);\r
+        \r
+        mutableNeedle.setValue("tpId_18x");\r
+        nodeModificationBuilder.replaceNode(mutableNeedle);\r
+        dumpResult();\r
     }\r
 \r
+\r
 }\r
old mode 100755 (executable)
new mode 100644 (file)
index 487c10c..16d736a
@@ -7,12 +7,12 @@
  */\r
 package org.opendaylight.controller.yang.data.impl;\r
 \r
-import java.io.ByteArrayOutputStream;\r
-import java.io.PrintStream;\r
+import java.io.IOException;\r
 import java.net.URI;\r
 import java.util.Date;\r
 import java.util.List;\r
 import java.util.Map;\r
+import java.util.Stack;\r
 \r
 import org.junit.Assert;\r
 import org.junit.Before;\r
@@ -23,6 +23,8 @@ import org.opendaylight.controller.yang.data.api.Node;
 import org.opendaylight.controller.yang.data.api.SimpleNode;\r
 import org.opendaylight.controller.yang.model.api.ListSchemaNode;\r
 import org.opendaylight.controller.yang.model.api.SchemaContext;\r
+import org.slf4j.Logger;\r
+import org.slf4j.LoggerFactory;\r
 import org.w3c.dom.Document;\r
 \r
 /**\r
@@ -31,16 +33,23 @@ import org.w3c.dom.Document;
  */\r
 public class NodeUtilsTest {\r
     \r
+    private static final Logger LOG = LoggerFactory\r
+            .getLogger(NodeUtilsTest.class);\r
+    \r
     private QName qName;\r
     private CompositeNode network;\r
 \r
+    private String ns;\r
+\r
+\r
     /**\r
      * @throws Exception\r
      */\r
     @Before\r
     public void setUp() throws Exception {\r
+        ns = "urn:ietf:params:xml:ns:netconf:base:1.0";\r
         qName = new QName(\r
-                new URI("urn:ietf:params:xml:ns:netconf:base:1.0"), \r
+                new URI(ns), \r
                 new Date(42), "yang-data-impl-mutableTest");\r
         network = NodeHelper.buildTestConfigTree(qName);\r
     }\r
@@ -65,11 +74,13 @@ public class NodeUtilsTest {
      */\r
     @Test\r
     public void testBuildShadowDomTree() throws Exception {\r
+        MemoryConsumption mc = new MemoryConsumption();\r
+        mc.startObserving();\r
+        \r
         Document networkShadow = NodeUtils.buildShadowDomTree(network);\r
-        ByteArrayOutputStream actual = new ByteArrayOutputStream();\r
-        NodeHelper.dumpDoc(networkShadow, new PrintStream(actual));\r
         \r
-        Assert.assertEquals(2760, new String(actual.toByteArray()).length());\r
+        LOG.debug("After dom built: "+mc.finishObserving());\r
+        NodeHelper.compareXmlTree(networkShadow, "./config02-shadow.xml", getClass());\r
     }\r
 \r
     /**\r
@@ -79,12 +90,19 @@ public class NodeUtilsTest {
     @Test\r
     public void testFindNodeByXpath() throws Exception {\r
         Document networkShadow = NodeUtils.buildShadowDomTree(network);\r
+        MemoryConsumption mc = new MemoryConsumption();\r
+        mc.startObserving();\r
+        \r
         SimpleNode<String> needle = NodeUtils.findNodeByXpath(networkShadow, \r
-                "//node[node-id='nodeId_19']//termination-point[2]/tp-id");\r
+                NodeHelper.AddNamespaceToPattern(\r
+                        "//{0}node[{0}node-id='nodeId_19']//{0}termination-point[2]/{0}tp-id", ns));\r
+        \r
+        LOG.debug("After xpath executed: "+mc.finishObserving());\r
+        \r
         Assert.assertNotNull(needle);\r
         Assert.assertEquals("tpId_18", needle.getValue());\r
     }\r
-\r
+    \r
     /**\r
      * Test method for {@link org.opendaylight.controller.yang.data.impl.NodeUtils#buildNodeMap(java.util.List)}.\r
      */\r
@@ -107,4 +125,41 @@ public class NodeUtilsTest {
         Assert.assertEquals(5, mapOfLists.size());\r
     }\r
 \r
+    /**\r
+     * Test method for {@link org.opendaylight.controller.yang.data.impl.NodeUtils#buildMapOfListNodes(org.opendaylight.controller.yang.model.api.SchemaContext)}.\r
+     * @throws Exception \r
+     * @throws IOException \r
+     */\r
+    @Test\r
+    public void testLoadConfigByGroovy() throws IOException, Exception {\r
+       CompositeNode treeRoot = NodeHelper.loadConfigByGroovy("./config02.groovy");\r
+       Document shadowTree = NodeUtils.buildShadowDomTree(treeRoot);\r
+       try {\r
+            checkFamilyBinding(treeRoot);\r
+        } catch (Exception e) {\r
+            LOG.error(e.getMessage());\r
+            throw e;\r
+        }\r
+       \r
+       NodeHelper.compareXmlTree(shadowTree, "./config02g-shadow.xml", getClass());\r
+    }\r
+\r
+    private static void checkFamilyBinding(CompositeNode treeRoot) throws Exception {\r
+        Stack<CompositeNode> jobQueue = new Stack<>();\r
+        jobQueue.push(treeRoot);\r
+        \r
+        while (!jobQueue.isEmpty()) {\r
+            CompositeNode job = jobQueue.pop();\r
+            for (Node<?> child : job.getChildren()) {\r
+                if (child instanceof CompositeNode) {\r
+                    jobQueue.push((CompositeNode) child);\r
+                }\r
+                \r
+                if (job != child.getParent()) {\r
+                    throw new Exception("binding mismatch occured: \nPARENT["+job+"]\n CHILD[" + child+"]\n  +->  "+child.getParent());\r
+                }\r
+            }\r
+        }\r
+    }\r
+    \r
 }\r
diff --git a/opendaylight/sal/yang-prototype/yang/yang-data-impl/src/test/resources/MyXmlGenerator.groovy b/opendaylight/sal/yang-prototype/yang/yang-data-impl/src/test/resources/MyXmlGenerator.groovy
new file mode 100644 (file)
index 0000000..f22da0c
--- /dev/null
@@ -0,0 +1,120 @@
+/*
+ * 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
+ */
+import groovy.xml.MarkupBuilder
+import org.opendaylight.controller.yang.data.impl.MyNodeBuilder
+
+/**
+ * wrapper class - applies hardcoded builder on given data closure
+ */
+class MyXmlGenerator {
+
+    def myBuilder
+    
+    MyXmlGenerator() {
+        myBuilder = MyNodeBuilder.newInstance();
+    }
+
+    MyNodeBuilder getBuilder() { 
+      return myBuilder;
+    }
+        
+    void buildTree(data) {
+        data.setDelegate(myBuilder)
+        data()
+    }
+    
+    /**
+     * tests builder execution
+     */
+    static void main(args) {
+        println 'hello'
+        def data = {
+          network(xmlns: 'urn:opendaylight:controller:network') {
+            topologies {
+              topology {
+                'topology-id'('topId_01')
+                
+                nodes {
+                  node {
+                    'node-id'('nodeId_02')
+                    'supporting-ne'('networkId_03')
+                    'termination-points' {
+                      'termination-point' {
+                        'tp-id'('tpId_04')
+                      }
+                    }
+                  }
+                  node {
+                    'node-id'('nodeId_05')
+                    'supporting-ne'('networkId_06')
+                    'termination-points' {
+                      'termination-point' {
+                        'tp-id'('tpId_07')
+                      }
+                    }
+                  }
+                  node {
+                    'node-id'('nodeId_08')
+                    'supporting-ne'('networkId_09')
+                    'termination-points' {
+                      'termination-point' {
+                        'tp-id'('tpId_10')
+                      }
+                      'termination-point' {
+                        'tp-id'('tpId_11')
+                      }
+                    }
+                  }
+                }
+                links {
+                  link {
+                    'link-id'('linkId_12')
+                    source {
+                      'source-node'('nodeId_13')
+                      'source-tp'('tpId_13')
+                    }
+                    destination {
+                      'dest-node'('nodeId_14')
+                      'dest-tp'('tpId_14')
+                    }
+                  }
+                  link {
+                    'link-id'('linkId_15')
+                    source {
+                      'source-node'('nodeId_16')
+                      'source-tp'('tpId_16')
+                    }
+                    destination {
+                      'dest-node'('nodeId_17')
+                      'dest-tp'('tpId_17')
+                    }
+                  }
+                }
+              }
+            }
+            'network-elements' {
+              'network-element' {
+                'element-id'('ntElementId_18')
+              }
+              'network-element' {
+                'element-id'('ntElementId_19')
+              }
+            }
+          }
+
+        }
+
+        def xmlGen = new MyXmlGenerator()
+        xmlGen.buildTree(data)
+        println xmlGen.getBuilder().getRootNode()
+    }
+
+}
+
+
+
diff --git a/opendaylight/sal/yang-prototype/yang/yang-data-impl/src/test/resources/config02.content b/opendaylight/sal/yang-prototype/yang/yang-data-impl/src/test/resources/config02.content
deleted file mode 100755 (executable)
index e9c05c9..0000000
+++ /dev/null
@@ -1,73 +0,0 @@
-xmlDoc.network(xmlns: 'urn:opendaylight:controller:network') {\r
-    topologies {\r
-      topology {\r
-        'topology-id'('topId_'+cnt.get())\r
-        \r
-        types()\r
-        nodes {\r
-          node {\r
-            'node-id'('nodeId_'+cnt.get())\r
-            'supporting-ne'('networkId_'+cnt.get())\r
-            'termination-points' {\r
-              'termination-point' {\r
-                'tp-id'('tpId_'+cnt.get())\r
-              }\r
-            }\r
-          }\r
-          node {\r
-            'node-id'('nodeId_'+cnt.get())\r
-            'supporting-ne'('networkId_'+cnt.get())\r
-            'termination-points' {\r
-              'termination-point' {\r
-                'tp-id'('tpId_'+cnt.get())\r
-              }\r
-            }\r
-          }\r
-          node {\r
-            'node-id'('nodeId_'+cnt.get())\r
-            'supporting-ne'('networkId_'+cnt.get())\r
-            'termination-points' {\r
-              'termination-point' {\r
-                'tp-id'('tpId_'+cnt.get())\r
-              }\r
-              'termination-point' {\r
-                'tp-id'('tpId_'+cnt.get())\r
-              }\r
-            }\r
-          }\r
-        }\r
-        links {\r
-          link {\r
-            'link-id'('linkId_'+cnt.get())\r
-            source {\r
-              'source-node'('nodeId_'+cnt.get())\r
-              'source-tp'('tpId_'+cnt.get(false))\r
-            }\r
-            destination {\r
-              'dest-node'('nodeId_'+cnt.get())\r
-              'dest-tp'('tpId_'+cnt.get(false))\r
-            }\r
-          }\r
-          link {\r
-            'link-id'('linkId_'+cnt.get())\r
-            source {\r
-              'source-node'('nodeId_'+cnt.get())\r
-              'source-tp'('tpId_'+cnt.get(false))\r
-            }\r
-            destination {\r
-              'dest-node'('nodeId_'+cnt.get())\r
-              'dest-tp'('tpId_'+cnt.get(false))\r
-            }\r
-          }\r
-        }\r
-      }\r
-    }\r
-    'network-elements' {\r
-      'network-element' {\r
-        'element-id'('ntElementId_'+cnt.get())\r
-      }\r
-      'network-element' {\r
-        'element-id'('ntElementId_'+cnt.get())\r
-      }\r
-    }\r
-  }
\ No newline at end of file
diff --git a/opendaylight/sal/yang-prototype/yang/yang-data-impl/src/test/resources/config02g.xml b/opendaylight/sal/yang-prototype/yang/yang-data-impl/src/test/resources/config02g.xml
deleted file mode 100644 (file)
index d1ac68c..0000000
+++ /dev/null
@@ -1,73 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<network xmlns="urn:opendaylight:controller:network">
-  <topologies>
-    <topology>
-      <topology-id>topId_01</topology-id>
-      <types />
-      <nodes>
-        <node>
-          <node-id>nodeId_02</node-id>
-          <supporting-ne>networkId_03</supporting-ne>
-          <termination-points>
-            <termination-point>
-              <tp-id>tpId_04</tp-id>
-            </termination-point>
-          </termination-points>
-        </node>
-        <node>
-          <node-id>nodeId_05</node-id>
-          <supporting-ne>networkId_06</supporting-ne>
-          <termination-points>
-            <termination-point>
-              <tp-id>tpId_07</tp-id>
-            </termination-point>
-          </termination-points>
-        </node>
-        <node>
-          <node-id>nodeId_08</node-id>
-          <supporting-ne>networkId_09</supporting-ne>
-          <termination-points>
-            <termination-point>
-              <tp-id>tpId_10</tp-id>
-            </termination-point>
-            <termination-point>
-              <tp-id>tpId_11</tp-id>
-            </termination-point>
-          </termination-points>
-        </node>
-      </nodes>
-      <links>
-        <link>
-          <link-id>linkId_12</link-id>
-          <source>
-            <source-node>nodeId_13</source-node>
-            <source-tp>tpId_13</source-tp>
-          </source>
-          <destination>
-            <dest-node>nodeId_14</dest-node>
-            <dest-tp>tpId_14</dest-tp>
-          </destination>
-        </link>
-        <link>
-          <link-id>linkId_15</link-id>
-          <source>
-            <source-node>nodeId_16</source-node>
-            <source-tp>tpId_16</source-tp>
-          </source>
-          <destination>
-            <dest-node>nodeId_17</dest-node>
-            <dest-tp>tpId_17</dest-tp>
-          </destination>
-        </link>
-      </links>
-    </topology>
-  </topologies>
-  <network-elements>
-    <network-element>
-      <element-id>ntElementId_18</element-id>
-    </network-element>
-    <network-element>
-      <element-id>ntElementId_19</element-id>
-    </network-element>
-  </network-elements>
-</network>\r
diff --git a/opendaylight/sal/yang-prototype/yang/yang-data-impl/src/test/resources/generateXml.groovy b/opendaylight/sal/yang-prototype/yang/yang-data-impl/src/test/resources/generateXml.groovy
deleted file mode 100755 (executable)
index a778137..0000000
+++ /dev/null
@@ -1,110 +0,0 @@
-//import groovy.xml.StreamingMarkupBuilder
-import groovy.xml.MarkupBuilder
-import groovy.xml.XmlUtil
-
-class Counter {
-    def counter = 0
-    def get() {
-        return get(true)
-    }
-    def get(isInc) {
-        if (isInc) {
-            counter++
-        }
-        return String.format('%02d', counter)
-    }
-}
-
-
-cnt = new Counter()
-def writer = new StringWriter()
-xmlDoc = new MarkupBuilder(writer)
-xmlDoc.setDoubleQuotes(true)
-xmlDoc.getMkp().xmlDeclaration(version:'1.0', encoding: 'UTF-8')
-
-//def data = {
-//  mkp.xmlDeclaration()
-//  network(xmlns: 'urn:opendaylight:controller:network') {
-dataFile = new File(args[0])
-evaluate(dataFile)
-// xmlDoc.network(xmlns: 'urn:opendaylight:controller:network') {
-    // topologies {
-      // topology {
-        // 'topology-id'('topId_'+cnt.get())
-        // types()
-        // nodes {
-          // node {
-            // 'node-id'('nodeId_'+cnt.get())
-            // 'supporting-ne'('networkId_'+cnt.get())
-            // 'termination-points' {
-              // 'termination-point' {
-                // 'tp-id'('tpId_'+cnt.get())
-              // }
-            // }
-          // }
-          // node {
-            // 'node-id'('nodeId_'+cnt.get())
-            // 'supporting-ne'('networkId_'+cnt.get())
-            // 'termination-points' {
-              // 'termination-point' {
-                // 'tp-id'('tpId_'+cnt.get())
-              // }
-            // }
-          // }
-          // node {
-            // 'node-id'('nodeId_'+cnt.get())
-            // 'supporting-ne'('networkId_'+cnt.get())
-            // 'termination-points' {
-              // 'termination-point' {
-                // 'tp-id'('tpId_'+cnt.get())
-              // }
-              // 'termination-point' {
-                // 'tp-id'('tpId_'+cnt.get())
-              // }
-            // }
-          // }
-        // }
-        // links {
-          // link {
-            // 'link-id'('linkId_'+cnt.get())
-            // source {
-              // 'source-node'('nodeId_'+cnt.get())
-              // 'source-tp'('tpId_'+cnt.get(false))
-            // }
-            // destination {
-              // 'dest-node'('nodeId_'+cnt.get())
-              // 'dest-tp'('tpId_'+cnt.get(false))
-            // }
-          // }
-          // link {
-            // 'link-id'('linkId_'+cnt.get())
-            // source {
-              // 'source-node'('nodeId_'+cnt.get())
-              // 'source-tp'('tpId_'+cnt.get(false))
-            // }
-            // destination {
-              // 'dest-node'('nodeId_'+cnt.get())
-              // 'dest-tp'('tpId_'+cnt.get(false))
-            // }
-          // }
-        // }
-      // }
-    // }
-    // 'network-elements' {
-      // 'network-element' {
-        // 'element-id'('ntElementId_'+cnt.get())
-      // }
-      // 'network-element' {
-        // 'element-id'('ntElementId_'+cnt.get())
-      // }
-    // }
-  // }
-
-//}
-
-
-// def xmlDoc = new StreamingMarkupBuilder()
-// xmlDoc.encoding = 'UTF'
-//println XmlUtil.serialize(xmlDoc.bind(data))
-
-println writer
diff --git a/opendaylight/sal/yang-prototype/yang/yang-data-impl/src/test/resources/log4j-test.xml b/opendaylight/sal/yang-prototype/yang/yang-data-impl/src/test/resources/log4j-test.xml
new file mode 100755 (executable)
index 0000000..189236a
--- /dev/null
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>\r
+<!DOCTYPE log4j:configuration SYSTEM "log4j.dtd">\r
+<log4j:configuration xmlns:log4j="http://jakarta.apache.org/log4j/">\r
+\r
+    <appender name="console" class="org.apache.log4j.ConsoleAppender">\r
+       <layout class="org.apache.log4j.PatternLayout">\r
+          <param name="ConversionPattern" value="%-6p %d{HH:mm:ss.SSS} [%t] %42.42c %x - %m%n"/>\r
+       </layout>\r
+    </appender>        \r
+\r
+    <logger name="org.opendaylight.controller.yang.data.impl" additivity="false">\r
+           <level value="DEBUG" />\r
+           <appender-ref ref="console"/>\r
+       </logger>\r
+    <logger name="org.opendaylight.controller.yang.data.impl.MyNodeBuilder" additivity="false">\r
+        <level value="INFO" />\r
+        <appender-ref ref="console"/>\r
+    </logger>   \r
+       \r
+       <root>\r
+        <priority value="INFO"/>\r
+        <appender-ref ref="console" />\r
+    </root>\r
+</log4j:configuration>
\ No newline at end of file
diff --git a/opendaylight/sal/yang-prototype/yang/yang-data-impl/src/test/resources/org/opendaylight/controller/yang/data/impl/config02-shadow.xml b/opendaylight/sal/yang-prototype/yang/yang-data-impl/src/test/resources/org/opendaylight/controller/yang/data/impl/config02-shadow.xml
new file mode 100644 (file)
index 0000000..aaaf22d
--- /dev/null
@@ -0,0 +1,73 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<network xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
+    <topologies>
+        <topology>
+            <topology-id>topId_01</topology-id>
+            <nodes>
+                <node>
+                    <node-id>nodeId_19</node-id>
+                    <supporting-ne>networkId_20</supporting-ne>
+                    <termination-points>
+                        <termination-point>
+                            <tp-id>tpId_19</tp-id>
+                        </termination-point>
+                        <termination-point>
+                            <tp-id>tpId_18</tp-id>
+                        </termination-point>
+                    </termination-points>
+                </node>
+                <node>
+                    <node-id>nodeId_16</node-id>
+                    <supporting-ne>networkId_17</supporting-ne>
+                    <termination-points>
+                        <termination-point>
+                            <tp-id>tpId_18</tp-id>
+                        </termination-point>
+                    </termination-points>
+                </node>
+                <node>
+                    <node-id>nodeId_02</node-id>
+                    <supporting-ne>networkId_02</supporting-ne>
+                    <termination-points>
+                        <termination-point>
+                            <tp-id>tpId_03</tp-id>
+                        </termination-point>
+                    </termination-points>
+                </node>
+            </nodes>
+            <links>
+                <link>
+                    <destination>
+                        <dest-tp>tpId_15</dest-tp>
+                        <dest-node>nodeId_14</dest-node>
+                    </destination>
+                    <source>
+                        <source-tp>tpId_13</source-tp>
+                        <source-node>nodeId_12</source-node>
+                    </source>
+                    <link-id>linkId_11</link-id>
+                </link>
+                <link>
+                    <destination>
+                        <dest-tp>tpId_08</dest-tp>
+                        <dest-node>nodeId_07</dest-node>
+                    </destination>
+                    <source>
+                        <source-tp>tpId_06</source-tp>
+                        <source-node>nodeId_05</source-node>
+                    </source>
+                    <link-id>linkId_04</link-id>
+                </link>
+            </links>
+        </topology>
+    </topologies>
+    <network-elements>
+        <network-element>
+            <element-id>ntElementId_10</element-id>
+        </network-element>
+        <network-element>
+            <element-id>ntElementId_09</element-id>
+        </network-element>
+    </network-elements>
+</network>
diff --git a/opendaylight/sal/yang-prototype/yang/yang-data-impl/src/test/resources/org/opendaylight/controller/yang/data/impl/config02.groovy b/opendaylight/sal/yang-prototype/yang/yang-data-impl/src/test/resources/org/opendaylight/controller/yang/data/impl/config02.groovy
new file mode 100644 (file)
index 0000000..cfd8ab0
--- /dev/null
@@ -0,0 +1,89 @@
+/*\r
+ * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.\r
+ *\r
+ * This program and the accompanying materials are made available under the\r
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,\r
+ * and is available at http://www.eclipse.org/legal/epl-v10.html\r
+ */\r
+def data = {\r
+ network(xmlns: 'urn:opendaylight:controller:network') {\r
+    topologies {\r
+      topology {\r
+        'topology-id'('topId_01')\r
+        \r
+        //types()\r
+        nodes {\r
+          node {\r
+            'node-id'('nodeId_02')\r
+            'supporting-ne'('networkId_03')\r
+            'termination-points' {\r
+              'termination-point' {\r
+                'tp-id'('tpId_04')\r
+              }\r
+            }\r
+          }\r
+          node {\r
+            'node-id'('nodeId_05')\r
+            'supporting-ne'('networkId_06')\r
+            'termination-points' {\r
+              'termination-point' {\r
+                'tp-id'('tpId_07')\r
+              }\r
+            }\r
+          }\r
+          node {\r
+            'node-id'('nodeId_08')\r
+            'supporting-ne'('networkId_09')\r
+            'termination-points' {\r
+              'termination-point' {\r
+                'tp-id'('tpId_10')\r
+              }\r
+              'termination-point' {\r
+                'tp-id'('tpId_11')\r
+              }\r
+            }\r
+          }\r
+        }\r
+        links {\r
+          link {\r
+            'link-id'('linkId_12')\r
+            source {\r
+              'source-node'('nodeId_13')\r
+              'source-tp'('tpId_13')\r
+            }\r
+            destination {\r
+              'dest-node'('nodeId_14')\r
+              'dest-tp'('tpId_14')\r
+            }\r
+          }\r
+          link {\r
+            'link-id'('linkId_15')\r
+            source {\r
+              'source-node'('nodeId_16')\r
+              'source-tp'('tpId_16')\r
+            }\r
+            destination {\r
+              'dest-node'('nodeId_17')\r
+              'dest-tp'('tpId_17')\r
+            }\r
+          }\r
+        }\r
+      }\r
+    }\r
+    'network-elements' {\r
+      'network-element' {\r
+        'element-id'('ntElementId_18')\r
+      }\r
+      'network-element' {\r
+        'element-id'('ntElementId_19')\r
+      }\r
+    }\r
+  }\r
+}\r
+\r
+System.err.println('data inited')\r
+\r
+import MyXmlGenerator\r
+\r
+xmlGen = new MyXmlGenerator()\r
+xmlGen.buildTree(data)\r
diff --git a/opendaylight/sal/yang-prototype/yang/yang-data-impl/src/test/resources/org/opendaylight/controller/yang/data/impl/config02g-shadow.xml b/opendaylight/sal/yang-prototype/yang/yang-data-impl/src/test/resources/org/opendaylight/controller/yang/data/impl/config02g-shadow.xml
new file mode 100644 (file)
index 0000000..9db9342
--- /dev/null
@@ -0,0 +1,72 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<network xmlns="urn:opendaylight:controller:network">
+    <topologies>
+        <topology>
+            <links>
+                <link>
+                    <destination>
+                        <dest-tp>tpId_17</dest-tp>
+                        <dest-node>nodeId_17</dest-node>
+                    </destination>
+                    <source>
+                        <source-tp>tpId_16</source-tp>
+                        <source-node>nodeId_16</source-node>
+                    </source>
+                    <link-id>linkId_15</link-id>
+                </link>
+                <link>
+                    <destination>
+                        <dest-tp>tpId_14</dest-tp>
+                        <dest-node>nodeId_14</dest-node>
+                    </destination>
+                    <source>
+                        <source-tp>tpId_13</source-tp>
+                        <source-node>nodeId_13</source-node>
+                    </source>
+                    <link-id>linkId_12</link-id>
+                </link>
+            </links>
+            <nodes>
+                <node>
+                    <termination-points>
+                        <termination-point>
+                            <tp-id>tpId_11</tp-id>
+                        </termination-point>
+                        <termination-point>
+                            <tp-id>tpId_10</tp-id>
+                        </termination-point>
+                    </termination-points>
+                    <supporting-ne>networkId_09</supporting-ne>
+                    <node-id>nodeId_08</node-id>
+                </node>
+                <node>
+                    <termination-points>
+                        <termination-point>
+                            <tp-id>tpId_07</tp-id>
+                        </termination-point>
+                    </termination-points>
+                    <supporting-ne>networkId_06</supporting-ne>
+                    <node-id>nodeId_05</node-id>
+                </node>
+                <node>
+                    <termination-points>
+                        <termination-point>
+                            <tp-id>tpId_04</tp-id>
+                        </termination-point>
+                    </termination-points>
+                    <supporting-ne>networkId_03</supporting-ne>
+                    <node-id>nodeId_02</node-id>
+                </node>
+            </nodes>
+            <topology-id>topId_01</topology-id>
+        </topology>
+    </topologies>
+    <network-elements>
+        <network-element>
+            <element-id>ntElementId_19</element-id>
+        </network-element>
+        <network-element>
+            <element-id>ntElementId_18</element-id>
+        </network-element>
+    </network-elements>
+</network>
\ No newline at end of file
diff --git a/opendaylight/sal/yang-prototype/yang/yang-data-impl/src/test/resources/org/opendaylight/controller/yang/data/impl/mutableNodesConfig.xml b/opendaylight/sal/yang-prototype/yang/yang-data-impl/src/test/resources/org/opendaylight/controller/yang/data/impl/mutableNodesConfig.xml
new file mode 100644 (file)
index 0000000..851022b
--- /dev/null
@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<config xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
+    <top>
+        <interface>
+            <mtu modifyAction="REMOVE">1501</mtu>
+            <name>Ethernet1/0</name>
+        </interface>
+        <interface modifyAction="DELETE">
+            <mtu>1500</mtu>
+            <name>Ethernet0/0</name>
+        </interface>
+    </top>
+</config>
\ No newline at end of file
index 722a379aa31a4ecaad4dab9928ba40397b830f56..bbd6cd63828a37057c8f731d7f92543dc8537e29 100644 (file)
@@ -1,16 +1,22 @@
 <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"\r
     xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">\r
-    <modelVersion>4.0.0</modelVersion>\r
+\r
     <parent>\r
         <groupId>org.opendaylight.controller</groupId>\r
         <artifactId>yang</artifactId>\r
         <version>0.5.4-SNAPSHOT</version>\r
     </parent>\r
+\r
+    <modelVersion>4.0.0</modelVersion>\r
     <artifactId>yang-data-util</artifactId>\r
+    <name>${project.artifactId}</name>\r
+    <description>${project.artifactId}</description>\r
+\r
     <dependencies>\r
         <dependency>\r
             <groupId>org.opendaylight.controller</groupId>\r
             <artifactId>yang-data-api</artifactId>\r
         </dependency>\r
     </dependencies>\r
-</project>
\ No newline at end of file
+\r
+</project>\r
index 250cd9d2a6e02cd8a0224aabf52fd93e969ea119..e6297f55b2ecef2db772bb2f40d59eae0d82289b 100644 (file)
@@ -9,6 +9,7 @@ package org.opendaylight.controller.yang.data.util;
 
 import org.opendaylight.controller.yang.common.QName;
 import org.opendaylight.controller.yang.data.api.CompositeNode;
+import org.opendaylight.controller.yang.data.api.ModifyAction;
 import org.opendaylight.controller.yang.data.api.Node;
 
 public abstract class AbstractNode<T> implements Node<T> {
@@ -28,4 +29,14 @@ public abstract class AbstractNode<T> implements Node<T> {
     public CompositeNode getParent() {
         return parent;
     }
+    
+    /* (non-Javadoc)
+     */
+    /**
+     * @see org.opendaylight.controller.yang.data.api.NodeModification#getModificationAction()
+     */
+    public ModifyAction getModificationAction() {
+        // TODO Auto-generated method stub
+        return null;
+    }
 }
index 57feff1514526c91dbd2f4a93f5bb2a27e4a9d15..fca835f4585200eb1c5b0f53f0b233f77c3dc4ce 100644 (file)
@@ -14,6 +14,9 @@ import java.util.Map;
 
 import org.opendaylight.controller.yang.common.QName;
 import org.opendaylight.controller.yang.data.api.CompositeNode;
+import org.opendaylight.controller.yang.data.api.ModifyAction;
+import org.opendaylight.controller.yang.data.api.MutableCompositeNode;
+import org.opendaylight.controller.yang.data.api.MutableSimpleNode;
 import org.opendaylight.controller.yang.data.api.Node;
 import org.opendaylight.controller.yang.data.api.SimpleNode;
 
@@ -71,6 +74,16 @@ public class Nodes {
 
             return nodeMap;
         }
+
+        /* (non-Javadoc)
+         * @see org.opendaylight.controller.yang.data.api.CompositeNode#asMutable()
+         */
+        @Override
+        public MutableCompositeNode asMutable() {
+            // TODO Auto-generated method stub
+            return null;
+        }
+
     }
 
     private static class SimpleNodeTO<T> extends AbstractNode<T> implements
@@ -89,6 +102,15 @@ public class Nodes {
             return value;
         }
 
+        /* (non-Javadoc)
+         * @see org.opendaylight.controller.yang.data.api.SimpleNode#asMutable()
+         */
+        @Override
+        public MutableSimpleNode<T> asMutable() {
+            // TODO Auto-generated method stub
+            return null;
+        }
+
     }
 
 }
index 85ecb91b332db2151f8acf3370a216eaae2aebc2..d1d543abb5626fe4ec7d462da0076871b351f3dc 100644 (file)
@@ -1,13 +1,17 @@
 <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
     xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
-    <modelVersion>4.0.0</modelVersion>
+
     <parent>
         <groupId>org.opendaylight.controller</groupId>
         <artifactId>yang</artifactId>
         <version>0.5.4-SNAPSHOT</version>
     </parent>
+
+    <modelVersion>4.0.0</modelVersion>
     <artifactId>yang-ext</artifactId>
     <version>2013.09.07-SNAPSHOT</version>
+    <name>${project.artifactId}</name>
+    <description>${project.artifactId}</description>
 
     <build>
         <plugins>
index 8c4cb351967dcc96fe6c9ded26ac130d5950f0a2..14e7d20350da5ab65c06612c74b5600612408961 100644 (file)
@@ -1,16 +1,22 @@
 <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"\r
     xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">\r
-    <modelVersion>4.0.0</modelVersion>\r
+\r
     <parent>\r
         <groupId>org.opendaylight.controller</groupId>\r
         <artifactId>yang</artifactId>\r
         <version>0.5.4-SNAPSHOT</version>\r
     </parent>\r
+\r
+    <modelVersion>4.0.0</modelVersion>\r
     <artifactId>yang-model-api</artifactId>\r
+    <name>${project.artifactId}</name>\r
+    <description>${project.artifactId}</description>\r
+\r
     <dependencies>\r
         <dependency>\r
             <groupId>org.opendaylight.controller</groupId>\r
             <artifactId>yang-common</artifactId>\r
         </dependency>\r
     </dependencies>\r
+\r
 </project>\r
index 74a420a3f885f9b88ea7df04f2803e353893948d..068d4a977c74f883f601007b2643cdf0cb068cfb 100644 (file)
@@ -11,21 +11,20 @@ import java.util.List;
 
 import org.opendaylight.controller.yang.model.api.TypeDefinition;
 
-public interface DecimalTypeDefinition extends
-        TypeDefinition<DecimalTypeDefinition> {
+public interface DecimalTypeDefinition extends TypeDefinition<DecimalTypeDefinition> {
 
     List<RangeConstraint> getRangeStatements();
 
     /**
      * Returns integer between 1 and 18 inclusively. <br>
      * <br>
-     * 
+     *
      * The "fraction-digits" statement controls the size of the minimum
      * difference between values of a decimal64 type, by restricting the value
      * space to numbers that are expressible as "i x 10^-n" where n is the
      * fraction-digits argument.
-     * 
-     * @return
+     *
+     * @return number of fraction digits
      */
     Integer getFractionDigits();
 }
similarity index 86%
rename from opendaylight/sal/yang-prototype/code-generator/yang-model-parser-api/pom.xml
rename to opendaylight/sal/yang-prototype/yang/yang-model-parser-api/pom.xml
index c796f34f55d6dac73f154721038deb3e86b51b2b..5bd261cdbdd7e8e4ba445b4b97e9f6876ff597cf 100644 (file)
@@ -1,16 +1,21 @@
 <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
-  <modelVersion>4.0.0</modelVersion>
+  
   <parent>
     <groupId>org.opendaylight.controller</groupId>
     <artifactId>yang</artifactId>
     <version>0.5.4-SNAPSHOT</version>
-    <relativePath>../../yang/pom.xml</relativePath>
   </parent>
+  
+  <modelVersion>4.0.0</modelVersion>
   <artifactId>yang-model-parser-api</artifactId>
+  <name>${project.artifactId}</name>
+  <description>YANG parser API</description>
+  
   <dependencies>
       <dependency>
           <groupId>org.opendaylight.controller</groupId>
           <artifactId>yang-model-api</artifactId>
       </dependency>
   </dependencies>
+  
 </project>
similarity index 89%
rename from opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/pom.xml
rename to opendaylight/sal/yang-prototype/yang/yang-model-parser-impl/pom.xml
index f0ba0d298168da109f1ef7ff5455ab1310a64c24..b40cd3c0b55bf8a18cf61cafba743ae5806ec7da 100644 (file)
@@ -5,11 +5,12 @@
         <groupId>org.opendaylight.controller</groupId>\r
         <artifactId>yang</artifactId>\r
         <version>0.5.4-SNAPSHOT</version>\r
-        <relativePath>../../yang/pom.xml</relativePath>\r
     </parent>\r
 \r
     <modelVersion>4.0.0</modelVersion>\r
     <artifactId>yang-model-parser-impl</artifactId>\r
+    <name>${project.artifactId}</name>\r
+    <description>YANG parser</description>\r
 \r
     <dependencies>\r
         <dependency>\r
                     </execution>\r
                 </executions>\r
             </plugin>\r
+            <plugin>\r
+                <groupId>org.apache.maven.plugins</groupId>\r
+                <artifactId>maven-javadoc-plugin</artifactId>\r
+                <configuration>\r
+                    <excludePackageNames>\r
+                        *.opendaylight.controller.antlrv4.code.gen\r
+                    </excludePackageNames>\r
+                </configuration>\r
+            </plugin>\r
         </plugins>\r
         <pluginManagement>\r
             <plugins>\r
@@ -10,68 +10,48 @@ package org.opendaylight.controller.yang.parser.builder.api;
 import java.util.ArrayList;
 import java.util.List;
 
-import org.opendaylight.controller.yang.common.QName;
-import org.opendaylight.controller.yang.model.api.TypeDefinition;
 import org.opendaylight.controller.yang.model.api.UnknownSchemaNode;
 import org.opendaylight.controller.yang.parser.builder.impl.UnknownSchemaNodeBuilder;
 
 /**
- * Basic implementation for TypeAwareBuilder builders.
+ * Basic implementation of Builder.
  */
-public abstract class AbstractTypeAwareBuilder implements TypeAwareBuilder {
+public abstract class AbstractBuilder implements Builder {
+    protected String moduleName;
     protected final int line;
-    protected final QName qname;
     protected Builder parent;
-    protected TypeDefinition<?> type;
-    protected TypeDefinitionBuilder typedef;
+
     protected List<UnknownSchemaNode> unknownNodes;
     protected final List<UnknownSchemaNodeBuilder> addedUnknownNodes = new ArrayList<UnknownSchemaNodeBuilder>();
 
-    public AbstractTypeAwareBuilder(final int line, final QName qname) {
+    protected AbstractBuilder(final String moduleName, final int line) {
+        this.moduleName = moduleName;
         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;
+    public String getModuleName() {
+        return moduleName;
     }
 
     @Override
-    public TypeDefinition<?> getType() {
-        return type;
+    public void setModuleName(final String moduleName) {
+        this.moduleName = moduleName;
     }
 
     @Override
-    public TypeDefinitionBuilder getTypedef() {
-        return typedef;
+    public int getLine() {
+        return line;
     }
 
     @Override
-    public void setType(TypeDefinition<?> type) {
-        this.type = type;
-        this.typedef = null;
+    public Builder getParent() {
+        return parent;
     }
 
     @Override
-    public void setTypedef(TypeDefinitionBuilder typedef) {
-        this.typedef = typedef;
-        this.type = null;
+    public void setParent(final Builder parent) {
+        this.parent = parent;
     }
 
     @Override
@@ -7,26 +7,20 @@
  */
 package org.opendaylight.controller.yang.parser.builder.api;
 
-import java.util.ArrayList;
 import java.util.Collections;
 import java.util.HashSet;
-import java.util.List;
 import java.util.Set;
 
 import org.opendaylight.controller.yang.common.QName;
 import org.opendaylight.controller.yang.model.api.DataSchemaNode;
 import org.opendaylight.controller.yang.model.api.GroupingDefinition;
-import org.opendaylight.controller.yang.model.api.UnknownSchemaNode;
-import org.opendaylight.controller.yang.parser.builder.impl.UnknownSchemaNodeBuilder;
 import org.opendaylight.controller.yang.parser.util.YangParseException;
 
 /**
  * Basic implementation of DataNodeContainerBuilder.
  */
-public abstract class AbstractDataNodeContainerBuilder implements DataNodeContainerBuilder {
-    protected final int line;
+public abstract class AbstractDataNodeContainerBuilder extends AbstractBuilder implements DataNodeContainerBuilder {
     protected final QName qname;
-    protected Builder parent;
 
     protected Set<DataSchemaNode> childNodes;
     protected final Set<DataSchemaNodeBuilder> addedChildNodes = new HashSet<DataSchemaNodeBuilder>();
@@ -34,29 +28,11 @@ public abstract class AbstractDataNodeContainerBuilder implements DataNodeContai
     protected Set<GroupingDefinition> groupings;
     protected final Set<GroupingBuilder> addedGroupings = new HashSet<GroupingBuilder>();
 
-    protected List<UnknownSchemaNode> unknownNodes;
-    protected final List<UnknownSchemaNodeBuilder> addedUnknownNodes = new ArrayList<UnknownSchemaNodeBuilder>();
-
-    protected AbstractDataNodeContainerBuilder(final int line, final QName qname) {
-        this.line = line;
+    protected AbstractDataNodeContainerBuilder(final String moduleName, final int line, final QName qname) {
+        super(moduleName, 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;
@@ -91,9 +67,12 @@ public abstract class AbstractDataNodeContainerBuilder implements DataNodeContai
 
     @Override
     public void addChildNode(DataSchemaNodeBuilder child) {
-        for (DataSchemaNodeBuilder childNode : addedChildNodes) {
-            if (childNode.getQName().getLocalName().equals(child.getQName().getLocalName())) {
-                throw new YangParseException(child.getLine(), "Duplicate node found at line " + childNode.getLine());
+        String childName = child.getQName().getLocalName();
+        for (DataSchemaNodeBuilder addedChildNode : addedChildNodes) {
+            if (addedChildNode.getQName().getLocalName().equals(childName)) {
+                throw new YangParseException(child.getModuleName(), child.getLine(), "Can not add '" + child + "' to '"
+                        + this + "' in module '" + moduleName + "': node with same name already declared at line "
+                        + addedChildNode.getLine());
             }
         }
         addedChildNodes.add(child);
@@ -116,27 +95,16 @@ public abstract class AbstractDataNodeContainerBuilder implements DataNodeContai
     }
 
     @Override
-    public void addGrouping(GroupingBuilder groupingBuilder) {
-        for (GroupingBuilder gb : addedGroupings) {
-            if (gb.getQName().getLocalName().equals(groupingBuilder.getQName().getLocalName())) {
-                throw new YangParseException(groupingBuilder.getLine(), "Duplicate node found at line " + gb.getLine());
+    public void addGrouping(GroupingBuilder grouping) {
+        String groupingName = grouping.getQName().getLocalName();
+        for (GroupingBuilder addedGrouping : addedGroupings) {
+            if (addedGrouping.getQName().getLocalName().equals(groupingName)) {
+                throw new YangParseException(grouping.getModuleName(), grouping.getLine(), "Can not add '" + grouping
+                        + "': grouping with same name already declared in module '" + moduleName + "' at line "
+                        + addedGrouping.getLine());
             }
         }
-        addedGroupings.add(groupingBuilder);
-    }
-
-    @Override
-    public List<UnknownSchemaNodeBuilder> getUnknownNodeBuilders() {
-        return addedUnknownNodes;
-    }
-
-    @Override
-    public void addUnknownNodeBuilder(UnknownSchemaNodeBuilder unknownNode) {
-        addedUnknownNodes.add(unknownNode);
-    }
-
-    public void setUnknownNodes(List<UnknownSchemaNode> unknownNodes) {
-        this.unknownNodes = unknownNodes;
+        addedGroupings.add(grouping);
     }
 
 }
@@ -7,53 +7,33 @@
  */\r
 package org.opendaylight.controller.yang.parser.builder.api;\r
 \r
-import java.util.ArrayList;\r
 import java.util.List;\r
 \r
 import org.opendaylight.controller.yang.common.QName;\r
 import org.opendaylight.controller.yang.model.api.SchemaPath;\r
 import org.opendaylight.controller.yang.model.api.Status;\r
 import org.opendaylight.controller.yang.model.api.UnknownSchemaNode;\r
-import org.opendaylight.controller.yang.parser.builder.impl.UnknownSchemaNodeBuilder;\r
 \r
 /**\r
  * Basic implementation of SchemaNodeBuilder.\r
  */\r
-public abstract class AbstractSchemaNodeBuilder implements SchemaNodeBuilder {\r
-    protected final int line;\r
+public abstract class AbstractSchemaNodeBuilder extends AbstractBuilder implements SchemaNodeBuilder {\r
     protected final QName qname;\r
-    protected Builder parent;\r
     protected SchemaPath schemaPath;\r
     protected String description;\r
     protected String reference;\r
     protected Status status = Status.CURRENT;\r
     protected List<UnknownSchemaNode> unknownNodes;\r
-    protected final List<UnknownSchemaNodeBuilder> addedUnknownNodes = new ArrayList<UnknownSchemaNodeBuilder>();\r
 \r
-    protected AbstractSchemaNodeBuilder(final int line, final QName qname) {\r
-        this.line = line;\r
+    protected AbstractSchemaNodeBuilder(final String moduleName, final int line, final QName qname) {\r
+        super(moduleName, line);\r
         this.qname = qname;\r
     }\r
 \r
-    @Override\r
-    public int getLine() {\r
-        return line;\r
-    }\r
-\r
     public QName getQName() {\r
         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
     @Override\r
     public SchemaPath getPath() {\r
         return schemaPath;\r
@@ -96,16 +76,6 @@ public abstract class AbstractSchemaNodeBuilder implements SchemaNodeBuilder {
         }\r
     }\r
 \r
-    @Override\r
-    public List<UnknownSchemaNodeBuilder> getUnknownNodeBuilders() {\r
-        return addedUnknownNodes;\r
-    }\r
-\r
-    @Override\r
-    public void addUnknownNodeBuilder(UnknownSchemaNodeBuilder unknownNode) {\r
-        addedUnknownNodes.add(unknownNode);\r
-    }\r
-\r
     public void setUnknownNodes(List<UnknownSchemaNode> unknownNodes) {\r
         this.unknownNodes = unknownNodes;\r
     }\r
diff --git a/opendaylight/sal/yang-prototype/yang/yang-model-parser-impl/src/main/java/org/opendaylight/controller/yang/parser/builder/api/AbstractTypeAwareBuilder.java b/opendaylight/sal/yang-prototype/yang/yang-model-parser-impl/src/main/java/org/opendaylight/controller/yang/parser/builder/api/AbstractTypeAwareBuilder.java
new file mode 100644 (file)
index 0000000..23ded94
--- /dev/null
@@ -0,0 +1,53 @@
+/*
+ * 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;
+
+import org.opendaylight.controller.yang.common.QName;
+import org.opendaylight.controller.yang.model.api.TypeDefinition;
+
+/**
+ * Basic implementation for TypeAwareBuilder builders.
+ */
+public abstract class AbstractTypeAwareBuilder extends AbstractBuilder implements TypeAwareBuilder {
+    protected final QName qname;
+    protected TypeDefinition<?> type;
+    protected TypeDefinitionBuilder typedef;
+
+    public AbstractTypeAwareBuilder(final String moduleName, final int line, final QName qname) {
+        super(moduleName, line);
+        this.qname = qname;
+    }
+
+    @Override
+    public QName getQName() {
+        return qname;
+    }
+
+    @Override
+    public TypeDefinition<?> getType() {
+        return type;
+    }
+
+    @Override
+    public TypeDefinitionBuilder getTypedef() {
+        return typedef;
+    }
+
+    @Override
+    public void setType(TypeDefinition<?> type) {
+        this.type = type;
+        this.typedef = null;
+    }
+
+    @Override
+    public void setTypedef(TypeDefinitionBuilder typedef) {
+        this.typedef = typedef;
+        this.type = null;
+    }
+
+}
@@ -16,6 +16,20 @@ import org.opendaylight.controller.yang.parser.builder.impl.UnknownSchemaNodeBui
  */
 public interface Builder {
 
+    /**
+     * Get name of module in which this node is declared.
+     *
+     * @return module name
+     */
+    String getModuleName();
+
+    /**
+     * Set name of module in which this node is declared.
+     *
+     * @param moduleName
+     */
+    void setModuleName(String moduleName);
+
     /**
      * Get current line in yang file.
      *
@@ -31,15 +31,15 @@ public final class AnyXmlBuilder extends AbstractSchemaNodeBuilder implements Da
     private boolean augmenting;
     private boolean addedByUses;
 
-    public AnyXmlBuilder(final int line, final QName qname, final SchemaPath schemaPath) {
-        super(line, qname);
+    public AnyXmlBuilder(final String moduleName, final int line, final QName qname, final SchemaPath schemaPath) {
+        super(moduleName, line, qname);
         this.schemaPath = schemaPath;
         instance = new AnyXmlSchemaNodeImpl(qname);
-        constraints = new ConstraintsBuilder(line);
+        constraints = new ConstraintsBuilder(moduleName, line);
     }
 
     public AnyXmlBuilder(final AnyXmlBuilder builder) {
-        super(builder.getLine(), builder.getQName());
+        super(builder.getModuleName(), builder.getLine(), builder.getQName());
         parent = builder.getParent();
         instance = new AnyXmlSchemaNodeImpl(qname);
         constraints = builder.getConstraints();
@@ -54,8 +54,8 @@ public final class AugmentationSchemaBuilderImpl extends AbstractDataNodeContain
     private final Set<UsesNodeBuilder> usesNodes = new HashSet<UsesNodeBuilder>();
     private boolean resolved;
 
-    AugmentationSchemaBuilderImpl(final int line, final String augmentTargetStr) {
-        super(line, null);
+    AugmentationSchemaBuilderImpl(final String moduleName, final int line, final String augmentTargetStr) {
+        super(moduleName, line, null);
         this.augmentTargetStr = augmentTargetStr;
         final SchemaPath targetPath = ParserListenerUtils.parseAugmentPath(augmentTargetStr);
         dirtyAugmentTarget = targetPath;
@@ -74,7 +74,7 @@ public final class AugmentationSchemaBuilderImpl extends AbstractDataNodeContain
 
     @Override
     public void addGrouping(GroupingBuilder grouping) {
-        throw new YangParseException(line, "augment can not contains grouping statement");
+        throw new YangParseException(moduleName, line, "augment can not contains grouping statement");
     }
 
     @Override
@@ -158,7 +158,7 @@ public final class AugmentationSchemaBuilderImpl extends AbstractDataNodeContain
 
     @Override
     public void addTypedef(TypeDefinitionBuilder type) {
-        throw new YangParseException(line, "Augmentation can not contains typedef statement.");
+        throw new YangParseException(moduleName, line, "Augmentation can not contains typedef statement.");
     }
 
     @Override
@@ -29,6 +29,7 @@ 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;
+import org.opendaylight.controller.yang.parser.util.YangParseException;
 
 public final class ChoiceBuilder extends AbstractSchemaNodeBuilder implements DataSchemaNodeBuilder,
         AugmentationTargetBuilder, GroupingMember {
@@ -46,14 +47,14 @@ public final class ChoiceBuilder extends AbstractSchemaNodeBuilder implements Da
     private final Set<ChoiceCaseBuilder> addedCases = new HashSet<ChoiceCaseBuilder>();
     private String defaultCase;
 
-    public ChoiceBuilder(final int line, final QName qname) {
-        super(line, qname);
+    public ChoiceBuilder(final String moduleName, final int line, final QName qname) {
+        super(moduleName, line, qname);
         instance = new ChoiceNodeImpl(qname);
-        constraints = new ConstraintsBuilder(line);
+        constraints = new ConstraintsBuilder(moduleName, line);
     }
 
     public ChoiceBuilder(ChoiceBuilder b) {
-        super(b.getLine(), b.getQName());
+        super(b.getModuleName(), b.getLine(), b.getQName());
         parent = b.getParent();
         instance = new ChoiceNodeImpl(qname);
         constraints = b.getConstraints();
@@ -126,20 +127,43 @@ public final class ChoiceBuilder extends AbstractSchemaNodeBuilder implements Da
         return addedCases;
     }
 
-    public void addChildNode(DataSchemaNodeBuilder childNode) {
-        if (!(childNode instanceof ChoiceCaseBuilder)) {
-            ChoiceCaseBuilder caseBuilder = new ChoiceCaseBuilder(childNode.getLine(), childNode.getQName());
-            if (childNode.isAugmenting()) {
+    /**
+     * Add case node to this choice.
+     *
+     * If node is not declared with 'case' keyword, create new case builder and
+     * make this node child of newly created case.
+     *
+     * @param caseNode
+     *            case node
+     */
+    public void addCase(DataSchemaNodeBuilder caseNode) {
+        QName caseQName = caseNode.getQName();
+        String caseName = caseQName.getLocalName();
+        for (ChoiceCaseBuilder addedCase : addedCases) {
+            if (addedCase.getQName().getLocalName().equals(caseName)) {
+                throw new YangParseException(caseNode.getModuleName(), caseNode.getLine(), "Can not add '" + caseNode
+                        + "' to node '" + qname.getLocalName() + "' in module '" + moduleName
+                        + "': case with same name already declared at line " + addedCase.getLine());
+            }
+        }
+
+        if (caseNode instanceof ChoiceCaseBuilder) {
+            addedCases.add((ChoiceCaseBuilder) caseNode);
+        } else {
+            ChoiceCaseBuilder caseBuilder = new ChoiceCaseBuilder(caseNode.getModuleName(), caseNode.getLine(),
+                    caseQName);
+            if (caseNode.isAugmenting()) {
+                // if node is added by augmentation, set case builder augmenting
+                // as true and node augmenting as false
                 caseBuilder.setAugmenting(true);
-                childNode.setAugmenting(false);
+                caseNode.setAugmenting(false);
             }
-            caseBuilder.setPath(childNode.getPath());
-            SchemaPath newPath = ParserUtils.createSchemaPath(childNode.getPath(), childNode.getQName().getLocalName());
-            childNode.setPath(newPath);
-            caseBuilder.addChildNode(childNode);
+            caseBuilder.setPath(caseNode.getPath());
+            SchemaPath newPath = ParserUtils.createSchemaPath(caseNode.getPath(), caseQName.getLocalName(),
+                    caseQName.getNamespace(), caseQName.getRevision(), caseQName.getPrefix());
+            caseNode.setPath(newPath);
+            caseBuilder.addChildNode(caseNode);
             addedCases.add(caseBuilder);
-        } else {
-            addedCases.add((ChoiceCaseBuilder) childNode);
         }
     }
 
@@ -45,10 +45,10 @@ public final class ChoiceCaseBuilder extends AbstractDataNodeContainerBuilder im
     // AugmentationTarget args
     private final Set<AugmentationSchemaBuilder> addedAugmentations = new HashSet<AugmentationSchemaBuilder>();
 
-    ChoiceCaseBuilder(final int line, final QName qname) {
-        super(line, qname);
+    ChoiceCaseBuilder(final String moduleName, final int line, final QName qname) {
+        super(moduleName, line, qname);
         instance = new ChoiceCaseNodeImpl(qname);
-        constraints = new ConstraintsBuilder(line);
+        constraints = new ConstraintsBuilder(moduleName, line);
     }
 
     @Override
@@ -165,7 +165,7 @@ public final class ChoiceCaseBuilder extends AbstractDataNodeContainerBuilder im
 
     @Override
     public void addTypedef(TypeDefinitionBuilder typedefBuilder) {
-        throw new YangParseException(line, "Can not add type definition to choice case.");
+        throw new YangParseException(moduleName, line, "Can not add type definition to choice case.");
     }
 
     @Override
@@ -175,7 +175,7 @@ public final class ChoiceCaseBuilder extends AbstractDataNodeContainerBuilder im
 
     @Override
     public void setConfiguration(final Boolean configuration) {
-        throw new YangParseException(line, "Can not add config statement to choice case.");
+        throw new YangParseException(moduleName, line, "Can not add config statement to choice case.");
     }
 
     @Override
@@ -16,21 +16,19 @@ import org.opendaylight.controller.yang.model.api.ConstraintDefinition;
 import org.opendaylight.controller.yang.model.api.MustDefinition;
 import org.opendaylight.controller.yang.model.api.RevisionAwareXPath;
 import org.opendaylight.controller.yang.model.util.RevisionAwareXPathImpl;
-import org.opendaylight.controller.yang.parser.builder.api.Builder;
+import org.opendaylight.controller.yang.parser.builder.api.AbstractBuilder;
 import org.opendaylight.controller.yang.parser.util.YangParseException;
 
-public final class ConstraintsBuilder implements Builder {
+public final class ConstraintsBuilder extends AbstractBuilder {
     private final ConstraintDefinitionImpl instance;
-    private final int line;
-    private Builder parent;
     private final Set<MustDefinition> mustDefinitions;
     private String whenCondition;
     private boolean mandatory;
     private Integer min;
     private Integer max;
 
-    ConstraintsBuilder(final int line) {
-        this.line = line;
+    ConstraintsBuilder(final String moduleName, final int line) {
+        super(moduleName, line);
         instance = new ConstraintDefinitionImpl();
         mustDefinitions = new HashSet<MustDefinition>();
     }
@@ -51,24 +49,9 @@ public final class ConstraintsBuilder implements Builder {
         return instance;
     }
 
-    @Override
-    public int getLine() {
-        return line;
-    }
-
-    @Override
-    public Builder getParent() {
-        return parent;
-    }
-
-    @Override
-    public void setParent(final Builder parent) {
-        this.parent = parent;
-    }
-
     @Override
     public void addUnknownNodeBuilder(UnknownSchemaNodeBuilder unknownNode) {
-        throw new YangParseException(line, "Can not add unknown node to constraints.");
+        throw new YangParseException(moduleName, line, "Can not add unknown node to constraints.");
     }
 
     @Override
@@ -116,7 +99,6 @@ public final class ConstraintsBuilder implements Builder {
         this.mandatory = mandatory;
     }
 
-
     private final class ConstraintDefinitionImpl implements ConstraintDefinition {
         private RevisionAwareXPath whenCondition;
         private Set<MustDefinition> mustConstraints;
@@ -36,6 +36,7 @@ import org.opendaylight.controller.yang.parser.builder.api.GroupingMember;
 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 ContainerSchemaNodeBuilder extends AbstractDataNodeContainerBuilder implements
         AugmentationTargetBuilder, DataSchemaNodeBuilder, GroupingMember {
@@ -63,15 +64,16 @@ public final class ContainerSchemaNodeBuilder extends AbstractDataNodeContainerB
     // ContainerSchemaNode args
     private boolean presence;
 
-    public ContainerSchemaNodeBuilder(final int line, final QName qname, final SchemaPath schemaPath) {
-        super(line, qname);
+    public ContainerSchemaNodeBuilder(final String moduleName, final int line, final QName qname,
+            final SchemaPath schemaPath) {
+        super(moduleName, line, qname);
         this.schemaPath = schemaPath;
         instance = new ContainerSchemaNodeImpl(qname);
-        constraints = new ConstraintsBuilder(line);
+        constraints = new ConstraintsBuilder(moduleName, line);
     }
 
     public ContainerSchemaNodeBuilder(final ContainerSchemaNodeBuilder b) {
-        super(b.getLine(), b.getQName());
+        super(b.getModuleName(), b.getLine(), b.getQName());
         instance = new ContainerSchemaNodeImpl(b.getQName());
         constraints = b.getConstraints();
         schemaPath = b.getPath();
@@ -116,7 +118,7 @@ public final class ContainerSchemaNodeBuilder extends AbstractDataNodeContainerB
 
             // CHILD NODES
             final Map<QName, DataSchemaNode> childs = new TreeMap<QName, DataSchemaNode>(Comparators.QNAME_COMP);
-            if (childNodes == null) {
+            if (childNodes == null || childNodes.isEmpty()) {
                 for (DataSchemaNodeBuilder node : addedChildNodes) {
                     childs.put(node.getQName(), node.build());
                 }
@@ -194,6 +196,11 @@ public final class ContainerSchemaNodeBuilder extends AbstractDataNodeContainerB
 
     @Override
     public void addTypedef(final TypeDefinitionBuilder type) {
+        String typeName = type.getQName().getLocalName();
+        for (TypeDefinitionBuilder addedTypedef : addedTypedefs) {
+            throw new YangParseException(moduleName, type.getLine(), "Can not add typedef '" + typeName
+                    + "': typedef with same name already declared at line " + addedTypedef.getLine());
+        }
         addedTypedefs.add(type);
     }
 
@@ -15,15 +15,13 @@ import org.opendaylight.controller.yang.model.api.Deviation;
 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.builder.api.AbstractBuilder;
 import org.opendaylight.controller.yang.parser.util.Comparators;
 import org.opendaylight.controller.yang.parser.util.ParserListenerUtils;
 import org.opendaylight.controller.yang.parser.util.YangParseException;
 
-public final class DeviationBuilder implements Builder {
-    private final int line;
+public final class DeviationBuilder extends AbstractBuilder {
     private final String targetPathStr;
-    private Builder parent;
     private boolean isBuilt;
     private final DeviationImpl instance;
 
@@ -31,11 +29,12 @@ public final class DeviationBuilder implements Builder {
     private String reference;
     private final List<UnknownSchemaNodeBuilder> addedUnknownNodes = new ArrayList<UnknownSchemaNodeBuilder>();
 
-    DeviationBuilder(final int line, final String targetPathStr) {
-        if(!targetPathStr.startsWith("/")) {
-            throw new YangParseException(line, "Deviation argument string must be an absolute schema node identifier.");
+    DeviationBuilder(final String moduleName, final int line, final String targetPathStr) {
+        super(moduleName, line);
+        if (!targetPathStr.startsWith("/")) {
+            throw new YangParseException(moduleName, line,
+                    "Deviation argument string must be an absolute schema node identifier.");
         }
-        this.line = line;
         this.targetPathStr = targetPathStr;
         this.targetPath = ParserListenerUtils.parseAugmentPath(targetPathStr);
         instance = new DeviationImpl();
@@ -43,11 +42,11 @@ public final class DeviationBuilder implements Builder {
 
     @Override
     public Deviation build() {
-        if(targetPath == null) {
-            throw new YangParseException(line, "Unresolved deviation target");
+        if (targetPath == null) {
+            throw new YangParseException(moduleName, line, "Unresolved deviation target");
         }
 
-        if(!isBuilt) {
+        if (!isBuilt) {
             instance.setTargetPath(targetPath);
             instance.setReference(reference);
 
@@ -65,31 +64,6 @@ public final class DeviationBuilder implements Builder {
         return instance;
     }
 
-    @Override
-    public int getLine() {
-        return line;
-    }
-
-    @Override
-    public Builder getParent() {
-        return parent;
-    }
-
-    @Override
-    public void setParent(final Builder parent) {
-        this.parent = parent;
-    }
-
-    @Override
-    public List<UnknownSchemaNodeBuilder> getUnknownNodeBuilders() {
-        return addedUnknownNodes;
-    }
-
-    @Override
-    public void addUnknownNodeBuilder(UnknownSchemaNodeBuilder unknownNode) {
-        addedUnknownNodes.add(unknownNode);
-    }
-
     public SchemaPath getTargetPath() {
         return targetPath;
     }
@@ -108,8 +82,7 @@ public final class DeviationBuilder implements Builder {
         } else if ("delete".equals(deviate)) {
             instance.setDeviate(Deviate.DELETE);
         } else {
-            throw new YangParseException(line,
-                    "Unsupported type of 'deviate' statement: " + deviate);
+            throw new YangParseException(moduleName, line, "Unsupported type of 'deviate' statement: " + deviate);
         }
     }
 
@@ -173,12 +146,9 @@ public final class DeviationBuilder implements Builder {
         public int hashCode() {
             final int prime = 31;
             int result = 1;
-            result = prime * result
-                    + ((targetPath == null) ? 0 : targetPath.hashCode());
-            result = prime * result
-                    + ((deviate == null) ? 0 : deviate.hashCode());
-            result = prime * result
-                    + ((reference == null) ? 0 : reference.hashCode());
+            result = prime * result + ((targetPath == null) ? 0 : targetPath.hashCode());
+            result = prime * result + ((deviate == null) ? 0 : deviate.hashCode());
+            result = prime * result + ((reference == null) ? 0 : reference.hashCode());
             return result;
         }
 
@@ -220,8 +190,7 @@ public final class DeviationBuilder implements Builder {
 
         @Override
         public String toString() {
-            StringBuilder sb = new StringBuilder(
-                    DeviationImpl.class.getSimpleName());
+            StringBuilder sb = new StringBuilder(DeviationImpl.class.getSimpleName());
             sb.append("[");
             sb.append("targetPath=" + targetPath);
             sb.append(", deviate=" + deviate);
@@ -23,8 +23,8 @@ public final class ExtensionBuilder extends AbstractSchemaNodeBuilder {
     private boolean isBuilt;
     private final ExtensionDefinitionImpl instance;
 
-    ExtensionBuilder(final int line, final QName qname) {
-        super(line, qname);
+    ExtensionBuilder(final String moduleName, final int line, final QName qname) {
+        super(moduleName, line, qname);
         instance = new ExtensionDefinitionImpl(qname);
     }
 
@@ -23,8 +23,8 @@ public final class FeatureBuilder extends AbstractSchemaNodeBuilder {
     private boolean isBuilt;
     private final FeatureDefinitionImpl instance;
 
-    FeatureBuilder(final int line, final QName qname) {
-        super(line, qname);
+    FeatureBuilder(final String moduleName, final int line, final QName qname) {
+        super(moduleName, line, qname);
         instance = new FeatureDefinitionImpl(qname);
     }
 
@@ -9,11 +9,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 java.util.TreeSet;
 
 import org.opendaylight.controller.yang.common.QName;
@@ -24,51 +24,38 @@ 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.AbstractDataNodeContainerBuilder;
 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.YangParseException;
 
-public final class GroupingBuilderImpl implements GroupingBuilder {
-    private Builder parent;
+public final class GroupingBuilderImpl extends AbstractDataNodeContainerBuilder implements GroupingBuilder {
     private boolean isBuilt;
     private final GroupingDefinitionImpl instance;
-    private final int line;
-    private final QName qname;
     private SchemaPath schemaPath;
     private String description;
     private String reference;
     private Status status = Status.CURRENT;
     private boolean addedByUses;
 
-    private Set<DataSchemaNode> childNodes;
-    private final Set<DataSchemaNodeBuilder> addedChildNodes = new HashSet<DataSchemaNodeBuilder>();
-
-    private Set<GroupingDefinition> groupings;
-    private final Set<GroupingBuilder> addedGroupings = new HashSet<GroupingBuilder>();
-
     private Set<TypeDefinition<?>> typedefs;
     private final Set<TypeDefinitionBuilder> addedTypedefs = new HashSet<TypeDefinitionBuilder>();
 
     private Set<UsesNode> usesNodes;
     private final Set<UsesNodeBuilder> addedUsesNodes = new HashSet<UsesNodeBuilder>();
 
-    private List<UnknownSchemaNode> unknownNodes;
-    private final List<UnknownSchemaNodeBuilder> addedUnknownNodes = new ArrayList<UnknownSchemaNodeBuilder>();
-
-    public GroupingBuilderImpl(final QName qname, final int line) {
-        this.qname = qname;
+    public GroupingBuilderImpl(final String moduleName, final int line, final QName qname) {
+        super(moduleName, line, qname);
         instance = new GroupingDefinitionImpl(qname);
-        this.line = line;
     }
 
     public GroupingBuilderImpl(GroupingBuilder builder) {
-        qname = builder.getQName();
+        super(builder.getModuleName(), builder.getLine(), builder.getQName());
         parent = builder.getParent();
         instance = new GroupingDefinitionImpl(qname);
-        line = builder.getLine();
         schemaPath = builder.getPath();
         description = builder.getDescription();
         reference = builder.getReference();
@@ -92,8 +79,8 @@ public final class GroupingBuilderImpl implements GroupingBuilder {
             instance.setAddedByUses(addedByUses);
 
             // CHILD NODES
-            final Map<QName, DataSchemaNode> childs = new HashMap<QName, DataSchemaNode>();
-            if (childNodes == null) {
+            final Map<QName, DataSchemaNode> childs = new TreeMap<QName, DataSchemaNode>(Comparators.QNAME_COMP);
+            if (childNodes == null || childNodes.isEmpty()) {
                 for (DataSchemaNodeBuilder node : addedChildNodes) {
                     childs.put(node.getQName(), node.build());
                 }
@@ -147,25 +134,6 @@ public final class GroupingBuilderImpl implements GroupingBuilder {
         return instance;
     }
 
-    @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 Set<TypeDefinitionBuilder> getTypeDefinitionBuilders() {
@@ -174,6 +142,11 @@ public final class GroupingBuilderImpl implements GroupingBuilder {
 
     @Override
     public void addTypedef(final TypeDefinitionBuilder type) {
+        String typeName = type.getQName().getLocalName();
+        for (TypeDefinitionBuilder addedTypedef : addedTypedefs) {
+            throw new YangParseException(moduleName, type.getLine(), "Can not add typedef '" + typeName
+                    + "': typedef with same name already declared at line " + addedTypedef.getLine());
+        }
         addedTypedefs.add(type);
     }
 
@@ -231,54 +204,6 @@ public final class GroupingBuilderImpl implements GroupingBuilder {
         this.addedByUses = addedByUses;
     }
 
-    @Override
-    public Set<DataSchemaNode> getChildNodes() {
-        return childNodes;
-    }
-
-    @Override
-    public void addChildNode(final DataSchemaNodeBuilder childNode) {
-        addedChildNodes.add(childNode);
-    }
-
-    @Override
-    public Set<DataSchemaNodeBuilder> getChildNodeBuilders() {
-        return addedChildNodes;
-    }
-
-    @Override
-    public DataSchemaNodeBuilder getDataChildByName(final String name) {
-        for(DataSchemaNodeBuilder child : addedChildNodes) {
-            if(child.getQName().getLocalName().equals(name)) {
-                return child;
-            }
-        }
-        return null;
-    }
-
-    public void setChildNodes(final Set<DataSchemaNode> childNodes) {
-        this.childNodes = childNodes;
-    }
-
-    @Override
-    public Set<GroupingDefinition> getGroupings() {
-        return Collections.emptySet();
-    }
-
-    @Override
-    public Set<GroupingBuilder> getGroupingBuilders() {
-        return addedGroupings;
-    }
-
-    @Override
-    public void addGrouping(final GroupingBuilder grouping) {
-        addedGroupings.add(grouping);
-    }
-
-    public void setGroupings(final Set<GroupingDefinition> groupings) {
-        this.groupings = groupings;
-    }
-
     @Override
     public Set<UsesNodeBuilder> getUses() {
         return addedUsesNodes;
@@ -293,20 +218,6 @@ public final class GroupingBuilderImpl implements GroupingBuilder {
         this.usesNodes = usesNodes;
     }
 
-    @Override
-    public List<UnknownSchemaNodeBuilder> getUnknownNodeBuilders() {
-        return addedUnknownNodes;
-    }
-
-    @Override
-    public void addUnknownNodeBuilder(final UnknownSchemaNodeBuilder unknownNode) {
-        addedUnknownNodes.add(unknownNode);
-    }
-
-    public void setUnknownNodes(List<UnknownSchemaNode> unknownNodes) {
-        this.unknownNodes = unknownNodes;
-    }
-
     @Override
     public String toString() {
         return "grouping " + qname.getLocalName();
@@ -26,8 +26,8 @@ public final class IdentitySchemaNodeBuilder extends AbstractSchemaNodeBuilder {
     private IdentitySchemaNode baseIdentity;
     private String baseIdentityName;
 
-    IdentitySchemaNodeBuilder(final int line, final QName qname) {
-        super(line, qname);
+    IdentitySchemaNodeBuilder(final String moduleName, final int line, final QName qname) {
+        super(moduleName, line, qname);
         instance = new IdentitySchemaNodeImpl(qname);
     }
 
@@ -36,8 +36,8 @@ public final class IdentityrefTypeBuilder extends AbstractTypeAwareBuilder imple
     private final SchemaPath schemaPath;
     private QName baseQName;
 
-    IdentityrefTypeBuilder(final String baseString, final SchemaPath schemaPath, final int line) {
-        super(line, null);
+    IdentityrefTypeBuilder(final String moduleName, final int line, final String baseString, final SchemaPath schemaPath) {
+        super(moduleName, line, null);
         this.baseString = baseString;
         this.schemaPath = schemaPath;
     }
@@ -67,32 +67,32 @@ public final class IdentityrefTypeBuilder extends AbstractTypeAwareBuilder imple
 
     @Override
     public void setType(final TypeDefinition<?> type) {
-        throw new YangParseException(line, "Can not set type to " + NAME);
+        throw new YangParseException(moduleName, line, "Can not set type to " + NAME);
     }
 
     @Override
     public void setTypedef(final TypeDefinitionBuilder tdb) {
-        throw new YangParseException(line, "Can not set type to " + NAME);
+        throw new YangParseException(moduleName, line, "Can not set type to " + NAME);
     }
 
     @Override
     public void setPath(final SchemaPath schemaPath) {
-        throw new YangParseException(line, "Can not set path to " + NAME);
+        throw new YangParseException(moduleName, line, "Can not set path to " + NAME);
     }
 
     @Override
     public void setDescription(final String description) {
-        throw new YangParseException(line, "Can not set description to " + NAME);
+        throw new YangParseException(moduleName, line, "Can not set description to " + NAME);
     }
 
     @Override
     public void setReference(final String reference) {
-        throw new YangParseException(line, "Can not set reference to " + NAME);
+        throw new YangParseException(moduleName, line, "Can not set reference to " + NAME);
     }
 
     @Override
     public void setStatus(final Status status) {
-        throw new YangParseException(line, "Can not set status to " + NAME);
+        throw new YangParseException(moduleName, line, "Can not set status to " + NAME);
     }
 
     @Override
@@ -102,7 +102,7 @@ public final class IdentityrefTypeBuilder extends AbstractTypeAwareBuilder imple
 
     @Override
     public void setAddedByUses(final boolean addedByUses) {
-        throw new YangParseException(line, "Identityref type can not be added by uses.");
+        throw new YangParseException(moduleName, line, "Identityref type can not be added by uses.");
     }
 
     @Override
@@ -112,7 +112,7 @@ public final class IdentityrefTypeBuilder extends AbstractTypeAwareBuilder imple
 
     @Override
     public void addUnknownNodeBuilder(final UnknownSchemaNodeBuilder unknownNode) {
-        throw new YangParseException(line, "Can not add unknown node to " + NAME);
+        throw new YangParseException(moduleName, line, "Can not add unknown node to " + NAME);
     }
 
     @Override
@@ -147,7 +147,7 @@ public final class IdentityrefTypeBuilder extends AbstractTypeAwareBuilder imple
 
     @Override
     public void setRanges(List<RangeConstraint> ranges) {
-        throw new YangParseException(line, "Can not set ranges to " + NAME);
+        throw new YangParseException(moduleName, line, "Can not set ranges to " + NAME);
     }
 
     @Override
@@ -157,7 +157,7 @@ public final class IdentityrefTypeBuilder extends AbstractTypeAwareBuilder imple
 
     @Override
     public void setLengths(List<LengthConstraint> lengths) {
-        throw new YangParseException(line, "Can not set lengths to " + NAME);
+        throw new YangParseException(moduleName, line, "Can not set lengths to " + NAME);
     }
 
     @Override
@@ -167,7 +167,7 @@ public final class IdentityrefTypeBuilder extends AbstractTypeAwareBuilder imple
 
     @Override
     public void setPatterns(List<PatternConstraint> patterns) {
-        throw new YangParseException(line, "Can not set patterns to " + NAME);
+        throw new YangParseException(moduleName, line, "Can not set patterns to " + NAME);
     }
 
     @Override
@@ -177,7 +177,7 @@ public final class IdentityrefTypeBuilder extends AbstractTypeAwareBuilder imple
 
     @Override
     public void setFractionDigits(Integer fractionDigits) {
-        throw new YangParseException(line, "Can not set fraction digits to " + NAME);
+        throw new YangParseException(moduleName, line, "Can not set fraction digits to " + NAME);
     }
 
     @Override
@@ -192,7 +192,7 @@ public final class IdentityrefTypeBuilder extends AbstractTypeAwareBuilder imple
 
     @Override
     public void setDefaultValue(Object defaultValue) {
-        throw new YangParseException(line, "Can not set default value to " + NAME);
+        throw new YangParseException(moduleName, line, "Can not set default value to " + NAME);
     }
 
     @Override
@@ -202,7 +202,7 @@ public final class IdentityrefTypeBuilder extends AbstractTypeAwareBuilder imple
 
     @Override
     public void setUnits(String units) {
-        throw new YangParseException(line, "Can not set units to " + NAME);
+        throw new YangParseException(moduleName, line, "Can not set units to " + NAME);
     }
 
     @Override
@@ -40,15 +40,16 @@ public final class LeafListSchemaNodeBuilder extends AbstractTypeAwareBuilder im
     // LeafListSchemaNode args
     private boolean userOrdered;
 
-    public LeafListSchemaNodeBuilder(final int line, final QName qname, final SchemaPath schemaPath) {
-        super(line, qname);
+    public LeafListSchemaNodeBuilder(final String moduleName, final int line, final QName qname,
+            final SchemaPath schemaPath) {
+        super(moduleName, line, qname);
         this.schemaPath = schemaPath;
         instance = new LeafListSchemaNodeImpl(qname);
-        constraints = new ConstraintsBuilder(line);
+        constraints = new ConstraintsBuilder(moduleName, line);
     }
 
     public LeafListSchemaNodeBuilder(final LeafListSchemaNodeBuilder b) {
-        super(b.getLine(), b.getQName());
+        super(b.getModuleName(), b.getLine(), b.getQName());
         instance = new LeafListSchemaNodeImpl(qname);
 
         type = b.getType();
@@ -41,15 +41,15 @@ public final class LeafSchemaNodeBuilder extends AbstractTypeAwareBuilder implem
     private String defaultStr;
     private String unitsStr;
 
-    public LeafSchemaNodeBuilder(final QName qname, final SchemaPath schemaPath, final int line) {
-        super(line, qname);
+    public LeafSchemaNodeBuilder(final String moduleName, final int line, final QName qname, final SchemaPath schemaPath) {
+        super(moduleName, line, qname);
         this.schemaPath = schemaPath;
         instance = new LeafSchemaNodeImpl(qname);
-        constraints = new ConstraintsBuilder(line);
+        constraints = new ConstraintsBuilder(moduleName, line);
     }
 
     public LeafSchemaNodeBuilder(final LeafSchemaNodeBuilder b) {
-        super(b.getLine(), b.getQName());
+        super(b.getModuleName(), b.getLine(), b.getQName());
         instance = new LeafSchemaNodeImpl(qname);
         constraints = b.getConstraints();
         schemaPath = b.getPath();
@@ -36,6 +36,7 @@ import org.opendaylight.controller.yang.parser.builder.api.GroupingMember;
 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 ListSchemaNodeBuilder extends AbstractDataNodeContainerBuilder implements DataSchemaNodeBuilder,
         AugmentationTargetBuilder, GroupingMember {
@@ -63,15 +64,15 @@ public final class ListSchemaNodeBuilder extends AbstractDataNodeContainerBuilde
     private List<QName> keyDefinition = Collections.emptyList();
     private boolean userOrdered;
 
-    public ListSchemaNodeBuilder(final int line, final QName qname, final SchemaPath schemaPath) {
-        super(line, qname);
+    public ListSchemaNodeBuilder(final String moduleName, final int line, final QName qname, final SchemaPath schemaPath) {
+        super(moduleName, line, qname);
         this.schemaPath = schemaPath;
         instance = new ListSchemaNodeImpl(qname);
-        constraints = new ConstraintsBuilder(line);
+        constraints = new ConstraintsBuilder(moduleName, line);
     }
 
     public ListSchemaNodeBuilder(final ListSchemaNodeBuilder b) {
-        super(b.getLine(), b.getQName());
+        super(b.getModuleName(), b.getLine(), b.getQName());
         instance = new ListSchemaNodeImpl(b.getQName());
         constraints = b.getConstraints();
         schemaPath = b.getPath();
@@ -112,7 +113,7 @@ public final class ListSchemaNodeBuilder extends AbstractDataNodeContainerBuilde
 
             // CHILD NODES
             final Map<QName, DataSchemaNode> childs = new TreeMap<QName, DataSchemaNode>(Comparators.QNAME_COMP);
-            if (childNodes == null) {
+            if (childNodes == null || childNodes.isEmpty()) {
                 for (DataSchemaNodeBuilder node : addedChildNodes) {
                     childs.put(node.getQName(), node.build());
                 }
@@ -190,6 +191,11 @@ public final class ListSchemaNodeBuilder extends AbstractDataNodeContainerBuilde
 
     @Override
     public void addTypedef(final TypeDefinitionBuilder type) {
+        String typeName = type.getQName().getLocalName();
+        for (TypeDefinitionBuilder addedTypedef : addedTypedefs) {
+            throw new YangParseException(moduleName, type.getLine(), "Can not add typedef '" + typeName
+                    + "': typedef with same name already declared at line " + addedTypedef.getLine());
+        }
         addedTypedefs.add(type);
     }
 
@@ -82,9 +82,10 @@ public class ModuleBuilder extends AbstractDataNodeContainerBuilder {
     private final List<UnknownSchemaNodeBuilder> allUnknownNodes = new ArrayList<UnknownSchemaNodeBuilder>();
 
     public ModuleBuilder(final String name) {
-        super(0, null);
+        super(name, 0, null);
         this.name = name;
         instance = new ModuleImpl(name);
+        actualPath.push(this);
     }
 
     /**
@@ -320,85 +321,94 @@ public class ModuleBuilder extends AbstractDataNodeContainerBuilder {
     }
 
     public ExtensionBuilder addExtension(final QName qname, final int line) {
-        final ExtensionBuilder builder = new ExtensionBuilder(line, qname);
+        final String extName = qname.getLocalName();
+        for (ExtensionBuilder addedExtension : addedExtensions) {
+            if (addedExtension.getQName().getLocalName().equals(extName)) {
+                throw new YangParseException(moduleName, line, "Can not add extension '" + extName
+                        + "': extension with same name already declared at line " + addedExtension.getLine());
+            }
+        }
+        final ExtensionBuilder builder = new ExtensionBuilder(name, line, qname);
         addedExtensions.add(builder);
         return builder;
     }
 
-    public ContainerSchemaNodeBuilder addContainerNode(final int line, final QName containerName,
-            final SchemaPath schemaPath) {
-        final ContainerSchemaNodeBuilder builder = new ContainerSchemaNodeBuilder(line, containerName, schemaPath);
+    public ContainerSchemaNodeBuilder addContainerNode(final int line, final QName qname, final SchemaPath schemaPath) {
+        final ContainerSchemaNodeBuilder builder = new ContainerSchemaNodeBuilder(name, line, qname, schemaPath);
 
         Builder parent = getActualNode();
         builder.setParent(parent);
-        addChildToParent(parent, builder, containerName.getLocalName());
+        addChildToParent(parent, builder, qname.getLocalName());
 
         return builder;
     }
 
-    public ListSchemaNodeBuilder addListNode(final int line, final QName listName, final SchemaPath schemaPath) {
-        final ListSchemaNodeBuilder builder = new ListSchemaNodeBuilder(line, listName, schemaPath);
+    public ListSchemaNodeBuilder addListNode(final int line, final QName qname, final SchemaPath schemaPath) {
+        final ListSchemaNodeBuilder builder = new ListSchemaNodeBuilder(name, line, qname, schemaPath);
 
         Builder parent = getActualNode();
         builder.setParent(parent);
-        addChildToParent(parent, builder, listName.getLocalName());
+        addChildToParent(parent, builder, qname.getLocalName());
 
         return builder;
     }
 
-    public LeafSchemaNodeBuilder addLeafNode(final int line, final QName leafName, final SchemaPath schemaPath) {
-        final LeafSchemaNodeBuilder builder = new LeafSchemaNodeBuilder(leafName, schemaPath, line);
+    public LeafSchemaNodeBuilder addLeafNode(final int line, final QName qname, final SchemaPath schemaPath) {
+        final LeafSchemaNodeBuilder builder = new LeafSchemaNodeBuilder(name, line, qname, schemaPath);
 
         Builder parent = getActualNode();
         builder.setParent(parent);
-        addChildToParent(parent, builder, leafName.getLocalName());
+        addChildToParent(parent, builder, qname.getLocalName());
 
         return builder;
     }
 
-    public LeafListSchemaNodeBuilder addLeafListNode(final int line, final QName leafListName,
-            final SchemaPath schemaPath) {
-        final LeafListSchemaNodeBuilder builder = new LeafListSchemaNodeBuilder(line, leafListName, schemaPath);
+    public LeafListSchemaNodeBuilder addLeafListNode(final int line, final QName qname, final SchemaPath schemaPath) {
+        final LeafListSchemaNodeBuilder builder = new LeafListSchemaNodeBuilder(name, line, qname, schemaPath);
 
         Builder parent = getActualNode();
         builder.setParent(parent);
-        addChildToParent(parent, builder, leafListName.getLocalName());
+        addChildToParent(parent, builder, qname.getLocalName());
 
         return builder;
     }
 
     public GroupingBuilder addGrouping(final int line, final QName qname) {
-        final GroupingBuilder builder = new GroupingBuilderImpl(qname, line);
+        final GroupingBuilder builder = new GroupingBuilderImpl(name, line, qname);
 
         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());
+        String groupingName = qname.getLocalName();
+        if (parent.equals(this)) {
+            for (GroupingBuilder addedGrouping : addedGroupings) {
+                if (addedGrouping.getQName().getLocalName().equals(groupingName)) {
+                    throw new YangParseException(name, line, "grouping with same name '" + groupingName
+                            + "' already declared at line " + addedGrouping.getLine());
                 }
             }
             addedGroupings.add(builder);
         } else {
             if (parent instanceof DataNodeContainerBuilder) {
                 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());
+                for (GroupingBuilder addedGrouping : parentNode.getGroupingBuilders()) {
+                    if (addedGrouping.getQName().getLocalName().equals(groupingName)) {
+                        throw new YangParseException(name, line, "grouping with same name '" + groupingName
+                                + "' already declared at line " + addedGrouping.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());
+                    if (child.getQName().getLocalName().equals(groupingName)) {
+                        throw new YangParseException(name, line, "grouping with same name '" + groupingName
+                                + "' already declared at line " + child.getLine());
                     }
                 }
                 parentNode.addGrouping(builder);
             } else {
-                throw new YangParseException(name, line, "Unresolved parent of grouping " + qname.getLocalName());
+                throw new YangParseException(name, line, "Unresolved parent of grouping " + groupingName);
             }
         }
 
@@ -406,19 +416,20 @@ public class ModuleBuilder extends AbstractDataNodeContainerBuilder {
     }
 
     public AugmentationSchemaBuilder addAugment(final int line, final String augmentTargetStr) {
-        final AugmentationSchemaBuilder builder = new AugmentationSchemaBuilderImpl(line, augmentTargetStr);
+        final AugmentationSchemaBuilder builder = new AugmentationSchemaBuilderImpl(name, line, augmentTargetStr);
 
         Builder parent = getActualNode();
         builder.setParent(parent);
 
-        if (parent == null) {
+        if (parent.equals(this)) {
+            // augment can be declared only under 'module' ...
             addedAugments.add(builder);
         } else {
-            // augment can only be in 'module' or 'uses' statement
+            // ... or 'uses' statement
             if (parent instanceof UsesNodeBuilder) {
                 ((UsesNodeBuilder) parent).addAugment(builder);
             } else {
-                throw new YangParseException(name, line, "Augment can be declared only under module or uses.");
+                throw new YangParseException(name, line, "Augment can be declared only under module or uses statement.");
             }
         }
         allAugments.add(builder);
@@ -433,12 +444,12 @@ public class ModuleBuilder extends AbstractDataNodeContainerBuilder {
     }
 
     public UsesNodeBuilder addUsesNode(final int line, final String groupingPathStr) {
-        final UsesNodeBuilder usesBuilder = new UsesNodeBuilderImpl(line, groupingPathStr);
+        final UsesNodeBuilder usesBuilder = new UsesNodeBuilderImpl(name, line, groupingPathStr);
 
         Builder parent = getActualNode();
         usesBuilder.setParent(parent);
 
-        if (parent == null) {
+        if (parent.equals(this)) {
             addedUsesNodes.add(usesBuilder);
         } else {
             if (!(parent instanceof DataNodeContainerBuilder)) {
@@ -453,172 +464,199 @@ public class ModuleBuilder extends AbstractDataNodeContainerBuilder {
         return usesBuilder;
     }
 
-    public void addRefine(final RefineHolder refine, final List<String> parentPath) {
-        final List<String> path = new ArrayList<String>(parentPath);
-
-        if (actualPath.isEmpty()) {
+    public void addRefine(final RefineHolder refine) {
+        final Builder parent = getActualNode();
+        if (!(parent instanceof UsesNodeBuilder)) {
             throw new YangParseException(name, refine.getLine(), "refine can be defined only in uses statement");
-        } else {
-            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());
+        ((UsesNodeBuilder) parent).addRefine(refine);
+        refine.setParent(parent);
     }
 
     public RpcDefinitionBuilder addRpc(final int line, final QName qname) {
         Builder parent = getActualNode();
-        if (parent != null) {
+        if (!(parent.equals(this))) {
             throw new YangParseException(name, line, "rpc can be defined only in module or submodule");
         }
 
-        final RpcDefinitionBuilder rpcBuilder = new RpcDefinitionBuilder(line, qname);
+        final RpcDefinitionBuilder rpcBuilder = new RpcDefinitionBuilder(name, line, qname);
+
+        String rpcName = qname.getLocalName();
         for (RpcDefinitionBuilder rpc : addedRpcs) {
-            if (rpc.getQName().getLocalName().equals(qname.getLocalName())) {
-                throw new YangParseException(name, line, "Duplicate node found at line " + rpc.getLine());
+            if (rpc.getQName().getLocalName().equals(rpcName)) {
+                throw new YangParseException(name, line, "rpc with same name '" + rpcName
+                        + "' already declared at line " + rpc.getLine());
+            }
+        }
+        for (DataSchemaNodeBuilder addedChild : addedChildNodes) {
+            if (addedChild.getQName().getLocalName().equals(rpcName)) {
+                throw new YangParseException(name, line, "Can not add rpc: node with same name '" + rpcName
+                        + "' already declared at line " + addedChild.getLine());
+            }
+        }
+        for (NotificationBuilder addedNotification : addedNotifications) {
+            if (addedNotification.getQName().getLocalName().equals(rpcName)) {
+                throw new YangParseException(name, line, "Can not add rpc: notification with same name '" + rpcName
+                        + "' already declared at line " + addedNotification.getLine());
             }
         }
         addedRpcs.add(rpcBuilder);
         return rpcBuilder;
     }
 
-    public ContainerSchemaNodeBuilder addRpcInput(final SchemaPath schemaPath, final QName inputQName, final int line) {
+    public ContainerSchemaNodeBuilder addRpcInput(final int line, final QName qname, final SchemaPath schemaPath) {
         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(line, inputQName, schemaPath);
+        final ContainerSchemaNodeBuilder inputBuilder = new ContainerSchemaNodeBuilder(name, line, qname, schemaPath);
         inputBuilder.setParent(rpc);
 
         rpc.setInput(inputBuilder);
         return inputBuilder;
     }
 
-    public ContainerSchemaNodeBuilder addRpcOutput(final SchemaPath schemaPath, final QName outputQName, final int line) {
-        final Builder parent = actualPath.getFirst();
+    public ContainerSchemaNodeBuilder addRpcOutput(final SchemaPath schemaPath, final QName qname, final int line) {
+        final Builder parent = getActualNode();
         if (!(parent instanceof RpcDefinitionBuilder)) {
             throw new YangParseException(name, line, "output can be defined only in rpc statement");
         }
         final RpcDefinitionBuilder rpc = (RpcDefinitionBuilder) parent;
 
-        final ContainerSchemaNodeBuilder outputBuilder = new ContainerSchemaNodeBuilder(line, outputQName, schemaPath);
+        final ContainerSchemaNodeBuilder outputBuilder = new ContainerSchemaNodeBuilder(name, line, qname, schemaPath);
         outputBuilder.setParent(rpc);
 
         rpc.setOutput(outputBuilder);
         return outputBuilder;
     }
 
-    public NotificationBuilder addNotification(final QName notificationName, final List<String> parentPath,
-            final int line) {
-        if (!(actualPath.isEmpty())) {
+    public NotificationBuilder addNotification(final int line, final QName qname) {
+        final Builder parent = getActualNode();
+        if (!(parent.equals(this))) {
             throw new YangParseException(name, line, "notification can be defined only in module or submodule");
         }
+
+        String notificationName = qname.getLocalName();
         for (NotificationBuilder nb : addedNotifications) {
-            if (nb.getQName().equals(notificationName)) {
-                throw new YangParseException(name, line, "Duplicate node found at line " + nb.getLine());
+            if (nb.getQName().equals(qname)) {
+                throw new YangParseException(name, line, "notification with same name '" + notificationName
+                        + "' already declared at line " + nb.getLine());
+            }
+        }
+        for (RpcDefinitionBuilder rpc : addedRpcs) {
+            if (rpc.getQName().getLocalName().equals(notificationName)) {
+                throw new YangParseException(name, line, "Can not add notification: rpc with same name '"
+                        + notificationName + "' already declared at line " + rpc.getLine());
+            }
+        }
+        for (DataSchemaNodeBuilder addedChild : addedChildNodes) {
+            if (addedChild.getQName().getLocalName().equals(notificationName)) {
+                throw new YangParseException(name, line, "Can not add notification: node with same name '"
+                        + notificationName + "' already declared at line " + addedChild.getLine());
             }
         }
 
-        final NotificationBuilder builder = new NotificationBuilder(line, notificationName);
+        final NotificationBuilder builder = new NotificationBuilder(name, line, qname);
         addedNotifications.add(builder);
 
         return builder;
     }
 
-    public FeatureBuilder addFeature(final int line, final QName featureName) {
+    public FeatureBuilder addFeature(final int line, final QName qname) {
         Builder parent = getActualNode();
-        if (parent != null) {
+        if (!(parent.equals(this))) {
             throw new YangParseException(name, line, "feature can be defined only in module or submodule");
         }
 
-        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());
+        final FeatureBuilder builder = new FeatureBuilder(name, line, qname);
+
+        String featureName = qname.getLocalName();
+        for (FeatureBuilder addedFeature : addedFeatures) {
+            if (addedFeature.getQName().getLocalName().equals(featureName)) {
+                throw new YangParseException(name, line, "feature with same name '" + featureName
+                        + "' already declared at line " + addedFeature.getLine());
             }
         }
         addedFeatures.add(builder);
         return builder;
     }
 
-    public ChoiceBuilder addChoice(final int line, final QName choiceName) {
-        final ChoiceBuilder builder = new ChoiceBuilder(line, choiceName);
+    public ChoiceBuilder addChoice(final int line, final QName qname) {
+        final ChoiceBuilder builder = new ChoiceBuilder(name, line, qname);
 
         Builder parent = getActualNode();
         builder.setParent(parent);
-        addChildToParent(parent, builder, choiceName.getLocalName());
+        addChildToParent(parent, builder, qname.getLocalName());
 
         return builder;
     }
 
-    public ChoiceCaseBuilder addCase(final int line, final QName caseName) {
+    public ChoiceCaseBuilder addCase(final int line, final QName qname) {
         Builder parent = getActualNode();
-        if (parent == null) {
+        if (parent == null || parent.equals(this)) {
             throw new YangParseException(name, line, "'case' parent not found");
         }
 
-        final ChoiceCaseBuilder builder = new ChoiceCaseBuilder(line, caseName);
+        final ChoiceCaseBuilder builder = new ChoiceCaseBuilder(name, line, qname);
         builder.setParent(parent);
 
         if (parent instanceof ChoiceBuilder) {
-            ((ChoiceBuilder) parent).addChildNode(builder);
+            ((ChoiceBuilder) parent).addCase(builder);
         } else if (parent instanceof AugmentationSchemaBuilder) {
             ((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' " + qname.getLocalName());
         }
 
         return builder;
     }
 
-    public AnyXmlBuilder addAnyXml(final int line, final QName anyXmlName, final SchemaPath schemaPath) {
-        final AnyXmlBuilder builder = new AnyXmlBuilder(line, anyXmlName, schemaPath);
+    public AnyXmlBuilder addAnyXml(final int line, final QName qname, final SchemaPath schemaPath) {
+        final AnyXmlBuilder builder = new AnyXmlBuilder(name, line, qname, schemaPath);
 
         Builder parent = getActualNode();
         builder.setParent(parent);
-        addChildToParent(parent, builder, anyXmlName.getLocalName());
+        addChildToParent(parent, builder, qname.getLocalName());
 
         return builder;
     }
 
     @Override
     public void addTypedef(TypeDefinitionBuilder typedefBuilder) {
+        String nodeName = typedefBuilder.getQName().getLocalName();
         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());
+            if (tdb.getQName().getLocalName().equals(nodeName)) {
+                throw new YangParseException(name, typedefBuilder.getLine(), "typedef with same name '" + nodeName
+                        + "' already declared at line " + tdb.getLine());
             }
         }
         addedTypedefs.add(typedefBuilder);
     }
 
-    public TypeDefinitionBuilderImpl addTypedef(final int line, final QName typeDefName) {
-        final TypeDefinitionBuilderImpl builder = new TypeDefinitionBuilderImpl(typeDefName, line);
+    public TypeDefinitionBuilderImpl addTypedef(final int line, final QName qname) {
+        final TypeDefinitionBuilderImpl builder = new TypeDefinitionBuilderImpl(name, line, qname);
 
         Builder parent = getActualNode();
         builder.setParent(parent);
 
-        if (parent == null) {
+        String typedefName = qname.getLocalName();
+        if (parent.equals(this)) {
             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());
+                if (tdb.getQName().getLocalName().equals(typedefName)) {
+                    throw new YangParseException(name, line, "typedef with same name '" + typedefName
+                            + "' already declared 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());
+                for (TypeDefinitionBuilder child : parentNode.getTypeDefinitionBuilders()) {
+                    if (child.getQName().getLocalName().equals(typedefName)) {
+                        throw new YangParseException(name, line, "typedef with same name '" + typedefName
+                                + "' already declared at line " + child.getLine());
                     }
                 }
                 parentNode.addTypedef(builder);
@@ -626,13 +664,13 @@ public class ModuleBuilder extends AbstractDataNodeContainerBuilder {
                 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());
+                        throw new YangParseException(name, line, "typedef with same name '" + typedefName
+                                + "' already declared at line " + tdb.getLine());
                     }
                 }
                 rpcParent.addTypedef(builder);
             } else {
-                throw new YangParseException(name, line, "Unresolved parent of typedef " + typeDefName.getLocalName());
+                throw new YangParseException(name, line, "Unresolved parent of typedef " + typedefName);
             }
         }
 
@@ -651,9 +689,9 @@ public class ModuleBuilder extends AbstractDataNodeContainerBuilder {
     public UnionTypeBuilder addUnionType(final int line, final URI namespace, final Date revision) {
         final Builder parent = getActualNode();
         if (parent == null) {
-            throw new YangParseException(line, "Error while parsing union type");
+            throw new YangParseException(name, line, "Unresolved parent of union type");
         } else {
-            final UnionTypeBuilder union = new UnionTypeBuilder(line);
+            final UnionTypeBuilder union = new UnionTypeBuilder(name, line);
             if (parent instanceof TypeAwareBuilder) {
                 ((TypeAwareBuilder) parent).setTypedef(union);
                 return union;
@@ -664,11 +702,11 @@ public class ModuleBuilder extends AbstractDataNodeContainerBuilder {
     }
 
     public void addIdentityrefType(final int line, final SchemaPath schemaPath, final String baseString) {
-        final IdentityrefTypeBuilder identityref = new IdentityrefTypeBuilder(baseString, schemaPath, line);
+        final IdentityrefTypeBuilder identityref = new IdentityrefTypeBuilder(name, line, baseString, schemaPath);
 
         final Builder parent = getActualNode();
         if (parent == null) {
-            throw new YangParseException(line, "Error while parsing identityref type.");
+            throw new YangParseException(name, line, "Unresolved parent of identityref type.");
         } else {
             if (parent instanceof TypeAwareBuilder) {
                 final TypeAwareBuilder typeParent = (TypeAwareBuilder) parent;
@@ -682,27 +720,29 @@ public class ModuleBuilder extends AbstractDataNodeContainerBuilder {
 
     public DeviationBuilder addDeviation(final int line, final String targetPath) {
         Builder parent = getActualNode();
-        if (parent != null) {
+        if (!(parent.equals(this))) {
             throw new YangParseException(name, line, "deviation can be defined only in module or submodule");
         }
 
-        final DeviationBuilder builder = new DeviationBuilder(line, targetPath);
+        final DeviationBuilder builder = new DeviationBuilder(name, line, targetPath);
         addedDeviations.add(builder);
         return builder;
     }
 
     public IdentitySchemaNodeBuilder addIdentity(final QName qname, final List<String> parentPath, final int line) {
         Builder parent = getActualNode();
-        if (parent != null) {
+        if (!(parent.equals(this))) {
             throw new YangParseException(name, line, "identity can be defined only in module or submodule");
         }
+        String identityName = qname.getLocalName();
         for (IdentitySchemaNodeBuilder idBuilder : addedIdentities) {
             if (idBuilder.getQName().equals(qname)) {
-                throw new YangParseException(name, line, "Duplicate node found at line " + idBuilder.getLine());
+                throw new YangParseException(name, line, "identity with same name '" + identityName
+                        + "' already declared at line " + idBuilder.getLine());
             }
         }
 
-        final IdentitySchemaNodeBuilder builder = new IdentitySchemaNodeBuilder(line, qname);
+        final IdentitySchemaNodeBuilder builder = new IdentitySchemaNodeBuilder(name, line, qname);
         addedIdentities.add(builder);
         return builder;
     }
@@ -715,11 +755,11 @@ public class ModuleBuilder extends AbstractDataNodeContainerBuilder {
 
     public UnknownSchemaNodeBuilder addUnknownSchemaNode(final int line, final QName qname) {
         final Builder parent = getActualNode();
-        final UnknownSchemaNodeBuilder builder = new UnknownSchemaNodeBuilder(line, qname);
+        final UnknownSchemaNodeBuilder builder = new UnknownSchemaNodeBuilder(name, line, qname);
         builder.setParent(parent);
         allUnknownNodes.add(builder);
 
-        if (parent == null) {
+        if (parent.equals(this)) {
             addedUnknownNodes.add(builder);
         } else {
             if (parent instanceof SchemaNodeBuilder) {
@@ -1083,27 +1123,39 @@ public class ModuleBuilder extends AbstractDataNodeContainerBuilder {
         }
     }
 
-    private void addChildToParent(final Builder parent, final DataSchemaNodeBuilder child, final String childLocalName) {
+    /**
+     * Add child to parent. Method checks for duplicates and add given child
+     * node to parent. If node with same name is found, throws exception. If
+     * parent is null, child node will be added directly to module.
+     *
+     * @param parent
+     * @param child
+     * @param childName
+     */
+    private void addChildToParent(final Builder parent, final DataSchemaNodeBuilder child, final String childName) {
         final int line = child.getLine();
-        if (parent == null) {
+        if (parent.equals(this)) {
             // 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 : addedChildNodes) {
-                if (childNode.getQName().getLocalName().equals(childLocalName)) {
-                    throw new YangParseException(name, line, "Duplicate node found at line " + childNode.getLine());
+                if (childNode.getQName().getLocalName().equals(childName)) {
+                    throw new YangParseException(name, line, "Can not add '" + child
+                            + "': node with same name already declared 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());
+                if (rpc.getQName().getLocalName().equals(childName)) {
+                    throw new YangParseException(name, line, "Can not add '" + child
+                            + "': rpc with same name already declared 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());
+                if (notification.getQName().getLocalName().equals(childName)) {
+                    throw new YangParseException(name, line, "Can not add '" + child
+                            + "': notification with same name already declared at line " + notification.getLine());
                 }
             }
             addedChildNodes.add(child);
@@ -1113,22 +1165,23 @@ public class ModuleBuilder extends AbstractDataNodeContainerBuilder {
             if (parent instanceof DataNodeContainerBuilder) {
                 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());
+                    if (childNode.getQName().getLocalName().equals(childName)) {
+                        throw new YangParseException(name, line, "Can not add '" + child + "': node with same name '"
+                                + childName + "' already declared at line " + childNode.getLine());
                     }
                 }
                 parentNode.addChildNode(child);
             } else if (parent instanceof ChoiceBuilder) {
                 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());
+                    if (caseBuilder.getQName().getLocalName().equals(childName)) {
+                        throw new YangParseException(name, line, "Can not add '" + child + "': case with same name '"
+                                + childName + "' already declared at line " + caseBuilder.getLine());
                     }
                 }
-                parentNode.addChildNode(child);
+                parentNode.addCase(child);
             } else {
-                throw new YangParseException(name, line, "Unresolved parent of node '" + childLocalName + "'.");
+                throw new YangParseException(name, line, "Unresolved parent of node '" + childName + "'.");
             }
         }
     }
@@ -49,8 +49,8 @@ public final class NotificationBuilder extends AbstractDataNodeContainerBuilder
     private Set<AugmentationSchema> augmentations;
     private final Set<AugmentationSchemaBuilder> addedAugmentations = new HashSet<AugmentationSchemaBuilder>();
 
-    NotificationBuilder(final int line, final QName qname) {
-        super(line, qname);
+    NotificationBuilder(final String moduleName, final int line, final QName qname) {
+        super(moduleName, line, qname);
         instance = new NotificationDefinitionImpl(qname);
     }
 
@@ -35,8 +35,8 @@ public final class RpcDefinitionBuilder extends AbstractSchemaNodeBuilder {
     private final Set<TypeDefinitionBuilder> addedTypedefs = new HashSet<TypeDefinitionBuilder>();
     private final Set<GroupingBuilder> addedGroupings = new HashSet<GroupingBuilder>();
 
-    RpcDefinitionBuilder(final int line, final QName qname) {
-        super(line, qname);
+    RpcDefinitionBuilder(final String moduleName, final int line, final QName qname) {
+        super(moduleName, line, qname);
         this.instance = new RpcDefinitionImpl(qname);
     }
 
@@ -40,12 +40,12 @@ public final class TypeDefinitionBuilderImpl extends AbstractTypeAwareBuilder im
     private Object defaultValue;
     private boolean addedByUses;
 
-    public TypeDefinitionBuilderImpl(final QName qname, final int line) {
-        super(line, qname);
+    public TypeDefinitionBuilderImpl(final String moduleName, final int line, final QName qname) {
+        super(moduleName, line, qname);
     }
 
     public TypeDefinitionBuilderImpl(TypeDefinitionBuilder tdb) {
-        super(tdb.getLine(), tdb.getQName());
+        super(tdb.getModuleName(), tdb.getLine(), tdb.getQName());
         schemaPath = tdb.getPath();
 
         type = tdb.getType();
@@ -39,13 +39,12 @@ public final class UnionTypeBuilder extends AbstractTypeAwareBuilder implements
 
     private SchemaPath path;
 
-    public UnionTypeBuilder(final int line) {
-        super(line, null);
+    public UnionTypeBuilder(final String moduleName, final int line) {
+        super(moduleName, line, null);
         types = new ArrayList<TypeDefinition<?>>();
         typedefs = new ArrayList<TypeDefinitionBuilder>();
     }
 
-
     public List<TypeDefinition<?>> getTypes() {
         return types;
     }
@@ -93,17 +92,17 @@ public final class UnionTypeBuilder extends AbstractTypeAwareBuilder implements
 
     @Override
     public void setDescription(final String description) {
-        throw new YangParseException(line, "Can not set description to " + NAME);
+        throw new YangParseException(moduleName, line, "Can not set description to " + NAME);
     }
 
     @Override
     public void setReference(final String reference) {
-        throw new YangParseException(line, "Can not set reference to " + NAME);
+        throw new YangParseException(moduleName, line, "Can not set reference to " + NAME);
     }
 
     @Override
     public void setStatus(final Status status) {
-        throw new YangParseException(line, "Can not set status to " + NAME);
+        throw new YangParseException(moduleName, line, "Can not set status to " + NAME);
     }
 
     @Override
@@ -113,7 +112,7 @@ public final class UnionTypeBuilder extends AbstractTypeAwareBuilder implements
 
     @Override
     public void setAddedByUses(final boolean addedByUses) {
-        throw new YangParseException(line, "Union type can not be added by uses.");
+        throw new YangParseException(moduleName, line, "Union type can not be added by uses.");
     }
 
     @Override
@@ -153,7 +152,7 @@ public final class UnionTypeBuilder extends AbstractTypeAwareBuilder implements
 
     @Override
     public void setRanges(List<RangeConstraint> ranges) {
-        throw new YangParseException(line, "Can not set ranges to " + NAME);
+        throw new YangParseException(moduleName, line, "Can not set ranges to " + NAME);
     }
 
     @Override
@@ -163,7 +162,7 @@ public final class UnionTypeBuilder extends AbstractTypeAwareBuilder implements
 
     @Override
     public void setLengths(List<LengthConstraint> lengths) {
-        throw new YangParseException(line, "Can not set lengths to " + NAME);
+        throw new YangParseException(moduleName, line, "Can not set lengths to " + NAME);
     }
 
     @Override
@@ -173,7 +172,7 @@ public final class UnionTypeBuilder extends AbstractTypeAwareBuilder implements
 
     @Override
     public void setPatterns(List<PatternConstraint> patterns) {
-        throw new YangParseException(line, "Can not set patterns to " + NAME);
+        throw new YangParseException(moduleName, line, "Can not set patterns to " + NAME);
     }
 
     @Override
@@ -183,7 +182,7 @@ public final class UnionTypeBuilder extends AbstractTypeAwareBuilder implements
 
     @Override
     public void setFractionDigits(Integer fractionDigits) {
-        throw new YangParseException(line, "Can not set fraction digits to " + NAME);
+        throw new YangParseException(moduleName, line, "Can not set fraction digits to " + NAME);
     }
 
     @Override
@@ -198,7 +197,7 @@ public final class UnionTypeBuilder extends AbstractTypeAwareBuilder implements
 
     @Override
     public void setDefaultValue(Object defaultValue) {
-        throw new YangParseException(line, "Can not set default value to " + NAME);
+        throw new YangParseException(moduleName, line, "Can not set default value to " + NAME);
     }
 
     @Override
@@ -208,7 +207,7 @@ public final class UnionTypeBuilder extends AbstractTypeAwareBuilder implements
 
     @Override
     public void setUnits(String units) {
-        throw new YangParseException(line, "Can not set units to " + NAME);
+        throw new YangParseException(moduleName, line, "Can not set units to " + NAME);
     }
 
     @Override
@@ -25,13 +25,13 @@ public final class UnknownSchemaNodeBuilder extends AbstractSchemaNodeBuilder {
     private QName nodeType;
     private String nodeParameter;
 
-    public UnknownSchemaNodeBuilder(final int line, final QName qname) {
-        super(line, qname);
+    public UnknownSchemaNodeBuilder(final String moduleName, final int line, final QName qname) {
+        super(moduleName, line, qname);
         instance = new UnknownSchemaNodeImpl(qname);
     }
 
     public UnknownSchemaNodeBuilder(UnknownSchemaNodeBuilder b) {
-        super(b.getLine(), b.getQName());
+        super(b.getModuleName(), b.getLine(), b.getQName());
         instance = new UnknownSchemaNodeImpl(qname);
         schemaPath = b.getPath();
         description = b.getDescription();
@@ -20,6 +20,7 @@ import org.opendaylight.controller.yang.model.api.SchemaNode;
 import org.opendaylight.controller.yang.model.api.SchemaPath;\r
 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.AbstractBuilder;\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
@@ -28,10 +29,9 @@ import org.opendaylight.controller.yang.parser.builder.api.UsesNodeBuilder;
 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
+public final class UsesNodeBuilderImpl extends AbstractBuilder implements UsesNodeBuilder {\r
     private boolean isBuilt;\r
     private UsesNodeImpl instance;\r
-    private final int line;\r
     private DataNodeContainerBuilder parent;\r
     private final String groupingName;\r
     private SchemaPath groupingPath;\r
@@ -40,16 +40,15 @@ public final class UsesNodeBuilderImpl implements UsesNodeBuilder {
     private final Set<AugmentationSchemaBuilder> addedAugments = new HashSet<AugmentationSchemaBuilder>();\r
     private final List<SchemaNodeBuilder> refineBuilders = new ArrayList<SchemaNodeBuilder>();\r
     private final List<RefineHolder> refines = new ArrayList<RefineHolder>();\r
-    private final List<UnknownSchemaNodeBuilder> addedUnknownNodes = new ArrayList<UnknownSchemaNodeBuilder>();\r
 \r
-    public UsesNodeBuilderImpl(final int line, final String groupingName) {\r
+    public UsesNodeBuilderImpl(final String moduleName, final int line, final String groupingName) {\r
+        super(moduleName, line);\r
         this.groupingName = groupingName;\r
-        this.line = line;\r
     }\r
 \r
     public UsesNodeBuilderImpl(UsesNodeBuilder b) {\r
+        super(b.getModuleName(), b.getLine());\r
         groupingName = b.getGroupingName();\r
-        line = b.getLine();\r
         parent = b.getParent();\r
         groupingPath = b.getGroupingPath();\r
         augmenting = b.isAugmenting();\r
@@ -93,11 +92,6 @@ public final class UsesNodeBuilderImpl implements UsesNodeBuilder {
         return instance;\r
     }\r
 \r
-    @Override\r
-    public int getLine() {\r
-        return line;\r
-    }\r
-\r
     @Override\r
     public DataNodeContainerBuilder getParent() {\r
         return parent;\r
@@ -106,7 +100,7 @@ public final class UsesNodeBuilderImpl implements UsesNodeBuilder {
     @Override\r
     public void setParent(Builder parent) {\r
         if (!(parent instanceof DataNodeContainerBuilder)) {\r
-            throw new YangParseException(line, "Unresolved parent of uses '" + groupingName + "'.");\r
+            throw new YangParseException(moduleName, line, "Unresolved parent of uses '" + groupingName + "'.");\r
         }\r
         this.parent = (DataNodeContainerBuilder) parent;\r
     }\r
@@ -176,16 +170,6 @@ public final class UsesNodeBuilderImpl implements UsesNodeBuilder {
         refines.add(refine);\r
     }\r
 \r
-    @Override\r
-    public List<UnknownSchemaNodeBuilder> getUnknownNodeBuilders() {\r
-        return addedUnknownNodes;\r
-    }\r
-\r
-    @Override\r
-    public void addUnknownNodeBuilder(UnknownSchemaNodeBuilder unknownNode) {\r
-        addedUnknownNodes.add(unknownNode);\r
-    }\r
-\r
     @Override\r
     public int hashCode() {\r
         final int prime = 31;\r
@@ -14,6 +14,7 @@ import java.io.FileInputStream;
 import java.io.FileNotFoundException;
 import java.io.IOException;
 import java.io.InputStream;
+import java.net.URI;
 import java.util.ArrayList;
 import java.util.Collections;
 import java.util.Date;
@@ -893,7 +894,7 @@ public final class YangParserImpl implements YangModelParser {
             }
 
             // child nodes
-            processUsesNode(usesNode, targetGrouping);
+            processUsesNode(module, usesNode, targetGrouping);
         }
     }
 
@@ -921,7 +922,7 @@ public final class YangParserImpl implements YangModelParser {
                 usesNode.setGroupingPath(targetGrouping.getPath());
                 for (RefineHolder refine : usesNode.getRefines()) {
                     final SchemaNodeBuilder nodeToRefine = RefineUtils.getRefineNodeFromGroupingDefinition(
-                            targetGrouping, refine, module.getName());
+                            targetGrouping, refine);
                     if (nodeToRefine instanceof GroupingMember) {
                         ((GroupingMember) nodeToRefine).setAddedByUses(true);
                     }
@@ -942,7 +943,7 @@ public final class YangParserImpl implements YangModelParser {
                     usesNode.addRefineNode(nodeToRefine);
                 }
 
-                processUsesNode(usesNode, targetGroupingBuilder);
+                processUsesNode(module, usesNode, targetGroupingBuilder);
             }
         }
     }
@@ -1053,21 +1054,37 @@ public final class YangParserImpl implements YangModelParser {
     }
 
     /**
-     * Add nodes defined in target grouping to current context.
+     * Add nodes defined in target grouping to current context. Refinement has
+     * to be already performed.
      *
+     * @param module current module
      * @param usesNode
      * @param targetGrouping
      */
-    private void processUsesNode(final UsesNodeBuilder usesNode, final GroupingBuilder targetGrouping) {
+    private void processUsesNode(final ModuleBuilder module, final UsesNodeBuilder usesNode, final GroupingBuilder targetGrouping) {
         List<SchemaNodeBuilder> refineNodes = usesNode.getRefineNodes();
         DataNodeContainerBuilder parent = usesNode.getParent();
+        URI namespace = null;
+        Date revision = null;
+        String prefix = null;
+        if (parent instanceof ModuleBuilder || parent instanceof AugmentationSchemaBuilder) {
+            namespace = module.getNamespace();
+            revision = module.getRevision();
+            prefix = module.getPrefix();
+        } else {
+            QName parentQName = parent.getQName();
+            namespace = parentQName.getNamespace();
+            revision = parentQName.getRevision();
+            prefix = parentQName.getPrefix();
+        }
         SchemaPath parentPath = parent.getPath();
         for (DataSchemaNodeBuilder child : targetGrouping.getChildNodeBuilders()) {
             if (child != null) {
                 // if node is refined, take it from refined nodes and continue
                 SchemaNodeBuilder refined = getRefined(child.getQName(), refineNodes);
                 if (refined != null) {
-                    refined.setPath(createSchemaPath(parentPath, refined.getQName().getLocalName()));
+                    refined.setPath(createSchemaPath(parentPath, refined.getQName().getLocalName(), namespace,
+                            revision, prefix));
                     parent.addChildNode((DataSchemaNodeBuilder) refined);
                     continue;
                 }
@@ -1088,7 +1105,7 @@ public final class YangParserImpl implements YangModelParser {
                 }
 
                 if (newChild == null) {
-                    throw new YangParseException(usesNode.getLine(),
+                    throw new YangParseException(usesNode.getModuleName(), usesNode.getLine(),
                             "Unknown member of target grouping while resolving uses node.");
                 }
 
@@ -1096,20 +1113,22 @@ public final class YangParserImpl implements YangModelParser {
                     ((GroupingMember) newChild).setAddedByUses(true);
                 }
 
-                newChild.setPath(createSchemaPath(parentPath, newChild.getQName().getLocalName()));
+                newChild.setPath(createSchemaPath(parentPath, newChild.getQName().getLocalName(), namespace, revision,
+                        prefix));
                 parent.addChildNode(newChild);
             }
         }
         for (GroupingBuilder g : targetGrouping.getGroupingBuilders()) {
             GroupingBuilder newGrouping = new GroupingBuilderImpl(g);
             newGrouping.setAddedByUses(true);
-            newGrouping.setPath(createSchemaPath(parentPath, newGrouping.getQName().getLocalName()));
+            newGrouping.setPath(createSchemaPath(parentPath, newGrouping.getQName().getLocalName(), namespace,
+                    revision, prefix));
             parent.addGrouping(newGrouping);
         }
         for (TypeDefinitionBuilder td : targetGrouping.getTypeDefinitionBuilders()) {
             TypeDefinitionBuilder newType = new TypeDefinitionBuilderImpl(td);
             newType.setAddedByUses(true);
-            newType.setPath(createSchemaPath(parentPath, newType.getQName().getLocalName()));
+            newType.setPath(createSchemaPath(parentPath, newType.getQName().getLocalName(), namespace, revision, prefix));
             parent.addTypedef(newType);
         }
         for (UsesNodeBuilder un : targetGrouping.getUses()) {
@@ -1121,63 +1140,81 @@ public final class YangParserImpl implements YangModelParser {
         for (UnknownSchemaNodeBuilder un : targetGrouping.getUnknownNodeBuilders()) {
             UnknownSchemaNodeBuilder newUn = new UnknownSchemaNodeBuilder(un);
             newUn.setAddedByUses(true);
-            newUn.setPath(createSchemaPath(parentPath, un.getQName().getLocalName()));
+            newUn.setPath(createSchemaPath(parentPath, un.getQName().getLocalName(), namespace, revision, prefix));
             parent.addUnknownNodeBuilder(newUn);
         }
     }
 
     private void processUsesNode(final UsesNodeBuilder usesNode, final GroupingDefinition targetGrouping) {
+        final String moduleName = usesNode.getModuleName();
         final int line = usesNode.getLine();
         List<SchemaNodeBuilder> refineNodes = usesNode.getRefineNodes();
         DataNodeContainerBuilder parent = usesNode.getParent();
+        URI namespace = null;
+        Date revision = null;
+        String prefix = null;
+        if (parent instanceof ModuleBuilder) {
+            ModuleBuilder module = (ModuleBuilder) parent;
+            namespace = module.getNamespace();
+            revision = module.getRevision();
+            prefix = module.getPrefix();
+        } else {
+            QName parentQName = parent.getQName();
+            namespace = parentQName.getNamespace();
+            revision = parentQName.getRevision();
+            prefix = parentQName.getPrefix();
+        }
         SchemaPath parentPath = parent.getPath();
         for (DataSchemaNode child : targetGrouping.getChildNodes()) {
             if (child != null) {
                 // if node is refined, take it from refined nodes and continue
                 SchemaNodeBuilder refined = getRefined(child.getQName(), refineNodes);
                 if (refined != null) {
-                    refined.setPath(createSchemaPath(parentPath, refined.getQName().getLocalName()));
+                    refined.setPath(createSchemaPath(parentPath, refined.getQName().getLocalName(), namespace,
+                            revision, prefix));
                     parent.addChildNode((DataSchemaNodeBuilder) refined);
                     continue;
                 }
 
                 DataSchemaNodeBuilder newChild = null;
                 if (child instanceof AnyXmlSchemaNode) {
-                    newChild = createAnyXml((AnyXmlSchemaNode) child, line);
+                    newChild = createAnyXml((AnyXmlSchemaNode) child, moduleName, line);
                 } else if (child instanceof ChoiceNode) {
-                    newChild = createChoice((ChoiceNode) child, line);
+                    newChild = createChoice((ChoiceNode) child, moduleName, line);
                 } else if (child instanceof ContainerSchemaNode) {
-                    newChild = createContainer((ContainerSchemaNode) child, line);
+                    newChild = createContainer((ContainerSchemaNode) child, moduleName, line);
                 } else if (child instanceof LeafListSchemaNode) {
-                    newChild = createLeafList((LeafListSchemaNode) child, line);
+                    newChild = createLeafList((LeafListSchemaNode) child, moduleName, line);
                 } else if (child instanceof LeafSchemaNode) {
-                    newChild = createLeafBuilder((LeafSchemaNode) child, line);
+                    newChild = createLeafBuilder((LeafSchemaNode) child, moduleName, line);
                 } else if (child instanceof ListSchemaNode) {
-                    newChild = createList((ListSchemaNode) child, line);
+                    newChild = createList((ListSchemaNode) child, moduleName, line);
                 }
 
                 if (newChild == null) {
-                    throw new YangParseException(usesNode.getLine(),
+                    throw new YangParseException(moduleName, line,
                             "Unknown member of target grouping while resolving uses node.");
                 }
 
                 if (newChild instanceof GroupingMember) {
                     ((GroupingMember) newChild).setAddedByUses(true);
                 }
-                newChild.setPath(createSchemaPath(parentPath, newChild.getQName().getLocalName()));
+                newChild.setPath(createSchemaPath(parentPath, newChild.getQName().getLocalName(), namespace, revision,
+                        prefix));
                 parent.addChildNode(newChild);
             }
         }
         for (GroupingDefinition g : targetGrouping.getGroupings()) {
-            GroupingBuilder newGrouping = createGrouping(g, line);
+            GroupingBuilder newGrouping = createGrouping(g, moduleName, line);
             newGrouping.setAddedByUses(true);
-            newGrouping.setPath(createSchemaPath(parentPath, newGrouping.getQName().getLocalName()));
+            newGrouping.setPath(createSchemaPath(parentPath, newGrouping.getQName().getLocalName(), namespace,
+                    revision, prefix));
             parent.addGrouping(newGrouping);
         }
         for (TypeDefinition<?> td : targetGrouping.getTypeDefinitions()) {
-            TypeDefinitionBuilder newType = createTypedef((ExtendedType) td, line);
+            TypeDefinitionBuilder newType = createTypedef((ExtendedType) td, moduleName, line);
             newType.setAddedByUses(true);
-            newType.setPath(createSchemaPath(parentPath, newType.getQName().getLocalName()));
+            newType.setPath(createSchemaPath(parentPath, newType.getQName().getLocalName(), namespace, revision, prefix));
             parent.addTypedef(newType);
         }
         for (UsesNode un : targetGrouping.getUses()) {
@@ -1189,9 +1226,9 @@ public final class YangParserImpl implements YangModelParser {
             }
         }
         for (UnknownSchemaNode un : targetGrouping.getUnknownSchemaNodes()) {
-            UnknownSchemaNodeBuilder newNode = createUnknownSchemaNode(un, line);
+            UnknownSchemaNodeBuilder newNode = createUnknownSchemaNode(un, moduleName, line);
             newNode.setAddedByUses(true);
-            newNode.setPath(createSchemaPath(parentPath, un.getQName().getLocalName()));
+            newNode.setPath(createSchemaPath(parentPath, un.getQName().getLocalName(), namespace, revision, prefix));
             parent.addUnknownNodeBuilder(newNode);
         }
     }
@@ -373,13 +373,13 @@ public final class YangParserListenerImpl extends YangParserBaseListener {
                     SchemaPath path = createActualSchemaPath(actualPath, namespace, revision, yangModelPrefix, typeName);
                     moduleBuilder.addIdentityrefType(line, path, getIdentityrefBase(typeBody));
                 } else {
-                    type = parseTypeWithBody(moduleName, typeName, typeBody, actualPath, namespace, revision,
-                            yangModelPrefix, moduleBuilder.getActualNode());
+                    type = parseTypeWithBody(typeName, typeBody, actualPath, namespace, revision, yangModelPrefix,
+                            moduleBuilder.getActualNode());
                     moduleBuilder.setType(type);
                 }
             }
         } else {
-            type = parseUnknownTypeWithBody(moduleName, typeQName, typeBody, actualPath, namespace, revision, yangModelPrefix,
+            type = parseUnknownTypeWithBody(typeQName, typeBody, actualPath, namespace, revision, yangModelPrefix,
                     moduleBuilder.getActualNode());
             // add parent node of this type statement to dirty nodes
             moduleBuilder.markActualNodeDirty();
@@ -523,13 +523,42 @@ public final class YangParserListenerImpl extends YangParserBaseListener {
         exitLog("uses", actualPath.pop());
     }
 
+    @Override public void enterUses_augment_stmt(YangParser.Uses_augment_stmtContext ctx) {
+        final int line = ctx.getStart().getLine();
+        final String augmentPath = stringFromNode(ctx);
+        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) {
+                builder.setDescription(stringFromNode(child));
+            } else if (child instanceof Reference_stmtContext) {
+                builder.setReference(stringFromNode(child));
+            } else if (child instanceof Status_stmtContext) {
+                builder.setStatus(parseStatus((Status_stmtContext) child));
+            } else if (child instanceof When_stmtContext) {
+                builder.addWhenCondition(stringFromNode(child));
+            }
+        }
+
+        moduleBuilder.enterNode(builder);
+        actualPath.push(augmentPath);
+    }
+
+    @Override public void exitUses_augment_stmt(YangParser.Uses_augment_stmtContext ctx) {
+        moduleBuilder.exitNode();
+        exitLog("augment", actualPath.pop());
+    }
+
     @Override
     public void enterRefine_stmt(YangParser.Refine_stmtContext ctx) {
         final String refineString = stringFromNode(ctx);
         enterLog("refine", refineString, ctx.getStart().getLine());
 
-        RefineHolder refine = parseRefine(ctx);
-        moduleBuilder.addRefine(refine, actualPath);
+        RefineHolder refine = parseRefine(ctx, moduleName);
+        moduleBuilder.addRefine(refine);
         moduleBuilder.enterNode(refine);
         actualPath.push(refineString);
     }
@@ -699,7 +728,7 @@ public final class YangParserListenerImpl extends YangParserBaseListener {
         enterLog("notification", notificationName, line);
 
         QName notificationQName = new QName(namespace, revision, yangModelPrefix, notificationName);
-        NotificationBuilder builder = moduleBuilder.addNotification(notificationQName, actualPath, line);
+        NotificationBuilder builder = moduleBuilder.addNotification(line, notificationQName);
         moduleBuilder.enterNode(builder);
         actualPath.push(notificationName);
 
@@ -787,7 +816,7 @@ public final class YangParserListenerImpl extends YangParserBaseListener {
         QName rpcQName = new QName(namespace, revision, yangModelPrefix, input);
         SchemaPath path = createActualSchemaPath(actualPath, namespace, revision, yangModelPrefix, input);
 
-        ContainerSchemaNodeBuilder builder = moduleBuilder.addRpcInput(path, rpcQName, line);
+        ContainerSchemaNodeBuilder builder = moduleBuilder.addRpcInput(line, rpcQName, path);
         moduleBuilder.enterNode(builder);
         actualPath.push(input);
 
@@ -326,13 +326,14 @@ public final class ParserListenerUtils {
      *            type body context to parse
      * @param path
      *            actual position in YANG model
+     * @param moduleName current module name
      * @param namespace
      * @param revision
      * @param prefix
      * @return List of EnumPair object parsed from given context
      */
     private static List<EnumTypeDefinition.EnumPair> getEnumConstants(final Type_body_stmtsContext ctx,
-            final List<String> path, final URI namespace, final Date revision, final String prefix) {
+            final List<String> path, final String moduleName, final URI namespace, final Date revision, final String prefix) {
         List<EnumTypeDefinition.EnumPair> enumConstants = new ArrayList<EnumTypeDefinition.EnumPair>();
 
         for (int i = 0; i < ctx.getChildCount(); i++) {
@@ -342,7 +343,7 @@ public final class ParserListenerUtils {
                 for (int j = 0; j < enumSpecChild.getChildCount(); j++) {
                     ParseTree enumChild = enumSpecChild.getChild(j);
                     if (enumChild instanceof Enum_stmtContext) {
-                        EnumPair enumPair = createEnumPair((Enum_stmtContext) enumChild, highestValue, path, namespace,
+                        EnumPair enumPair = createEnumPair((Enum_stmtContext) enumChild, highestValue, path, moduleName, namespace,
                                 revision, prefix);
                         if (enumPair.getValue() > highestValue) {
                             highestValue = enumPair.getValue();
@@ -364,13 +365,16 @@ public final class ParserListenerUtils {
      *            current highest value in enumeration
      * @param path
      *            actual position in YANG model
+     * @param moduleName
+     *            current module name
      * @param namespace
      * @param revision
      * @param prefix
      * @return EnumPair object parsed from given context
      */
     private static EnumTypeDefinition.EnumPair createEnumPair(final Enum_stmtContext ctx, final int highestValue,
-            final List<String> path, final URI namespace, final Date revision, final String prefix) {
+            final List<String> path, final String moduleName, final URI namespace, final Date revision,
+            final String prefix) {
         final String name = stringFromNode(ctx);
         final QName qname = new QName(namespace, revision, prefix, name);
         Integer value = null;
@@ -400,7 +404,7 @@ public final class ParserListenerUtils {
             value = highestValue + 1;
         }
         if (value < -2147483648 || value > 2147483647) {
-            throw new YangParseException(ctx.getStart().getLine(), "Error on enum '" + name
+            throw new YangParseException(moduleName, ctx.getStart().getLine(), "Error on enum '" + name
                     + "': the enum value MUST be in the range from -2147483648 to 2147483647, but was: " + value);
         }
 
@@ -543,7 +547,7 @@ public final class ParserListenerUtils {
      *            type body context to parse
      * @return List of RangeConstraint created from this context
      */
-    private static List<RangeConstraint> getRangeConstraints(final Type_body_stmtsContext ctx) {
+    private static List<RangeConstraint> getRangeConstraints(final Type_body_stmtsContext ctx, final String moduleName) {
         List<RangeConstraint> rangeConstraints = Collections.emptyList();
         outer: for (int i = 0; i < ctx.getChildCount(); i++) {
             ParseTree numRestrChild = ctx.getChild(i);
@@ -551,7 +555,7 @@ public final class ParserListenerUtils {
                 for (int j = 0; j < numRestrChild.getChildCount(); j++) {
                     ParseTree rangeChild = numRestrChild.getChild(j);
                     if (rangeChild instanceof Range_stmtContext) {
-                        rangeConstraints = parseRangeConstraints((Range_stmtContext) rangeChild);
+                        rangeConstraints = parseRangeConstraints((Range_stmtContext) rangeChild, moduleName);
                         break outer;
                     }
                 }
@@ -567,7 +571,7 @@ public final class ParserListenerUtils {
      *            range context to parse
      * @return List of RangeConstraints parsed from this context
      */
-    private static List<RangeConstraint> parseRangeConstraints(final Range_stmtContext ctx) {
+    private static List<RangeConstraint> parseRangeConstraints(final Range_stmtContext ctx, final String moduleName) {
         final int line = ctx.getStart().getLine();
         List<RangeConstraint> rangeConstraints = new ArrayList<RangeConstraint>();
         String description = null;
@@ -590,10 +594,10 @@ public final class ParserListenerUtils {
             Number min;
             Number max;
             if (splittedRangeDef.length == 1) {
-                min = max = parseNumberConstraintValue(splittedRangeDef[0], line);
+                min = max = parseNumberConstraintValue(splittedRangeDef[0], moduleName, line);
             } else {
-                min = parseNumberConstraintValue(splittedRangeDef[0], line);
-                max = parseNumberConstraintValue(splittedRangeDef[1], line);
+                min = parseNumberConstraintValue(splittedRangeDef[0], moduleName, line);
+                max = parseNumberConstraintValue(splittedRangeDef[1], moduleName, line);
             }
             RangeConstraint range = BaseConstraints.rangeConstraint(min, max, description, reference);
             rangeConstraints.add(range);
@@ -609,7 +613,7 @@ public final class ParserListenerUtils {
      *            type body context to parse
      * @return List of LengthConstraint created from this context
      */
-    private static List<LengthConstraint> getLengthConstraints(final Type_body_stmtsContext ctx) {
+    private static List<LengthConstraint> getLengthConstraints(final Type_body_stmtsContext ctx, final String moduleName) {
         List<LengthConstraint> lengthConstraints = Collections.emptyList();
         outer: for (int i = 0; i < ctx.getChildCount(); i++) {
             ParseTree stringRestrChild = ctx.getChild(i);
@@ -617,7 +621,7 @@ public final class ParserListenerUtils {
                 for (int j = 0; j < stringRestrChild.getChildCount(); j++) {
                     ParseTree lengthChild = stringRestrChild.getChild(j);
                     if (lengthChild instanceof Length_stmtContext) {
-                        lengthConstraints = parseLengthConstraints((Length_stmtContext) lengthChild);
+                        lengthConstraints = parseLengthConstraints((Length_stmtContext) lengthChild, moduleName);
                         break outer;
                     }
                 }
@@ -633,7 +637,7 @@ public final class ParserListenerUtils {
      *            length context to parse
      * @return List of LengthConstraints parsed from this context
      */
-    private static List<LengthConstraint> parseLengthConstraints(final Length_stmtContext ctx) {
+    private static List<LengthConstraint> parseLengthConstraints(final Length_stmtContext ctx, final String moduleName) {
         final int line = ctx.getStart().getLine();
         List<LengthConstraint> lengthConstraints = new ArrayList<LengthConstraint>();
         String description = null;
@@ -656,10 +660,10 @@ public final class ParserListenerUtils {
             Number min;
             Number max;
             if (splittedRangeDef.length == 1) {
-                min = max = parseNumberConstraintValue(splittedRangeDef[0], line);
+                min = max = parseNumberConstraintValue(splittedRangeDef[0], moduleName, line);
             } else {
-                min = parseNumberConstraintValue(splittedRangeDef[0], line);
-                max = parseNumberConstraintValue(splittedRangeDef[1], line);
+                min = parseNumberConstraintValue(splittedRangeDef[0], moduleName, line);
+                max = parseNumberConstraintValue(splittedRangeDef[1], moduleName, line);
             }
             LengthConstraint range = BaseConstraints.lengthConstraint(min, max, description, reference);
             lengthConstraints.add(range);
@@ -674,7 +678,7 @@ public final class ParserListenerUtils {
      * @return wrapper object of primitive java type or UnknownBoundaryNumber if
      *         type is one of special YANG values 'min' or 'max'
      */
-    private static Number parseNumberConstraintValue(final String value, final int line) {
+    private static Number parseNumberConstraintValue(final String value, final String moduleName, final int line) {
         Number result = null;
         if ("min".equals(value) || "max".equals(value)) {
             result = new UnknownBoundaryNumber(value);
@@ -682,7 +686,7 @@ public final class ParserListenerUtils {
             try {
                 result = Long.valueOf(value);
             } catch (NumberFormatException e) {
-                throw new YangParseException(line, "Unable to parse range value '" + value + "'.", e);
+                throw new YangParseException(moduleName, line, "Unable to parse range value '" + value + "'.", e);
             }
         }
         return result;
@@ -812,13 +816,14 @@ public final class ParserListenerUtils {
      *            type body context to parse
      * @param actualPath
      *            current position in YANG model
+     * @param moduleName current module name
      * @param namespace
      * @param revision
      * @param prefix
      * @return List of Bit objects created from this context
      */
     private static List<BitsTypeDefinition.Bit> getBits(Type_body_stmtsContext ctx, List<String> actualPath,
-            URI namespace, Date revision, String prefix) {
+            String moduleName, URI namespace, Date revision, String prefix) {
         final List<BitsTypeDefinition.Bit> bits = new ArrayList<BitsTypeDefinition.Bit>();
         for (int j = 0; j < ctx.getChildCount(); j++) {
             ParseTree bitsSpecChild = ctx.getChild(j);
@@ -827,7 +832,7 @@ public final class ParserListenerUtils {
                 for (int k = 0; k < bitsSpecChild.getChildCount(); k++) {
                     ParseTree bitChild = bitsSpecChild.getChild(k);
                     if (bitChild instanceof Bit_stmtContext) {
-                        Bit bit = parseBit((Bit_stmtContext) bitChild, highestPosition, actualPath, namespace,
+                        Bit bit = parseBit((Bit_stmtContext) bitChild, highestPosition, actualPath, moduleName, namespace,
                                 revision, prefix);
                         if (bit.getPosition() > highestPosition) {
                             highestPosition = bit.getPosition();
@@ -849,13 +854,14 @@ public final class ParserListenerUtils {
      *            current highest position in bits type
      * @param actualPath
      *            current position in YANG model
+     * @param moduleName current module name
      * @param namespace
      * @param revision
      * @param prefix
      * @return Bit object parsed from this context
      */
     private static BitsTypeDefinition.Bit parseBit(final Bit_stmtContext ctx, long highestPosition,
-            List<String> actualPath, final URI namespace, final Date revision, final String prefix) {
+            List<String> actualPath, final String moduleName, final URI namespace, final Date revision, final String prefix) {
         String name = stringFromNode(ctx);
         final QName qname = new QName(namespace, revision, prefix, name);
         Long position = null;
@@ -888,7 +894,7 @@ public final class ParserListenerUtils {
             position = highestPosition + 1;
         }
         if (position < 0 || position > 4294967295L) {
-            throw new YangParseException(ctx.getStart().getLine(), "Error on bit '" + name
+            throw new YangParseException(moduleName, ctx.getStart().getLine(), "Error on bit '" + name
                     + "': the position value MUST be in the range 0 to 4294967295");
         }
 
@@ -946,7 +952,7 @@ public final class ParserListenerUtils {
         for (int i = 0; i < ctx.getChildCount(); i++) {
             ParseTree child = ctx.getChild(i);
             if (child instanceof Config_stmtContext) {
-                config = parseConfig((Config_stmtContext) child);
+                config = parseConfig((Config_stmtContext) child, moduleName);
                 break;
             }
         }
@@ -994,10 +1000,11 @@ public final class ParserListenerUtils {
      * Parse config statement.
      *
      * @param ctx
-     *            config context to parse.
+     *            config context to parse
+     * @param moduleName current module name
      * @return true if given context contains string 'true', false otherwise
      */
-    private static Boolean parseConfig(final Config_stmtContext ctx) {
+    private static Boolean parseConfig(final Config_stmtContext ctx, final String moduleName) {
         Boolean result = null;
         if (ctx != null) {
             for (int i = 0; i < ctx.getChildCount(); ++i) {
@@ -1011,7 +1018,7 @@ public final class ParserListenerUtils {
                         result = false;
                         break;
                     } else {
-                        throw new YangParseException(ctx.getStart().getLine(),
+                        throw new YangParseException(moduleName, ctx.getStart().getLine(),
                                 "Failed to parse 'config' statement value: '" + value + "'.");
                     }
                 }
@@ -1023,8 +1030,6 @@ public final class ParserListenerUtils {
     /**
      * Parse type body and create UnknownType definition.
      *
-     * @param moduleName
-     *            name of current module
      * @param typedefQName
      *            qname of current type
      * @param ctx
@@ -1036,16 +1041,17 @@ public final class ParserListenerUtils {
      * @param parent
      * @return UnknownType object with constraints from parsed type body
      */
-    public static TypeDefinition<?> parseUnknownTypeWithBody(final String moduleName, final QName typedefQName,
+    public static TypeDefinition<?> parseUnknownTypeWithBody(final QName typedefQName,
             final Type_body_stmtsContext ctx, final List<String> actualPath, final URI namespace, final Date revision,
             final String prefix, final Builder parent) {
+        String moduleName = parent.getModuleName();
         String typeName = typedefQName.getLocalName();
 
         UnknownType.Builder unknownType = new UnknownType.Builder(typedefQName);
 
         if (ctx != null) {
-            List<RangeConstraint> rangeStatements = getRangeConstraints(ctx);
-            List<LengthConstraint> lengthStatements = getLengthConstraints(ctx);
+            List<RangeConstraint> rangeStatements = getRangeConstraints(ctx, moduleName);
+            List<LengthConstraint> lengthStatements = getLengthConstraints(ctx, moduleName);
             List<PatternConstraint> patternStatements = getPatternConstraint(ctx);
             Integer fractionDigits = getFractionDigits(ctx, moduleName);
 
@@ -1080,8 +1086,6 @@ public final class ParserListenerUtils {
     /**
      * Create TypeDefinition object based on given type name and type body.
      *
-     * @param moduleName
-     *            current module name
      * @param typeName
      *            name of type
      * @param typeBody
@@ -1098,16 +1102,17 @@ public final class ParserListenerUtils {
      *            parent builder
      * @return TypeDefinition object based on parsed values.
      */
-    public static TypeDefinition<?> parseTypeWithBody(final String moduleName, final String typeName,
+    public static TypeDefinition<?> parseTypeWithBody(final String typeName,
             final Type_body_stmtsContext typeBody, final List<String> actualPath, final URI namespace,
             final Date revision, final String prefix, final Builder parent) {
+        final String moduleName = parent.getModuleName();
         final int line = typeBody.getStart().getLine();
         TypeDefinition<?> baseType = null;
 
         Integer fractionDigits = getFractionDigits(typeBody, moduleName);
-        List<LengthConstraint> lengthStatements = getLengthConstraints(typeBody);
+        List<LengthConstraint> lengthStatements = getLengthConstraints(typeBody, moduleName);
         List<PatternConstraint> patternStatements = getPatternConstraint(typeBody);
-        List<RangeConstraint> rangeStatements = getRangeConstraints(typeBody);
+        List<RangeConstraint> rangeStatements = getRangeConstraints(typeBody, moduleName);
 
         TypeConstraints constraints = new TypeConstraints(moduleName, line);
         constraints.addFractionDigits(fractionDigits);
@@ -1159,7 +1164,7 @@ public final class ParserListenerUtils {
             constraints.addRanges(uintType.getRangeStatements());
             baseType = uintType;
         } else if ("enumeration".equals(typeName)) {
-            List<EnumTypeDefinition.EnumPair> enumConstants = getEnumConstants(typeBody, actualPath, namespace,
+            List<EnumTypeDefinition.EnumPair> enumConstants = getEnumConstants(typeBody, actualPath, moduleName, namespace,
                     revision, prefix);
             return new EnumerationType(baseTypePathFinal, enumConstants);
         } else if ("string".equals(typeName)) {
@@ -1167,7 +1172,7 @@ public final class ParserListenerUtils {
             constraints.addLengths(stringType.getLengthStatements());
             baseType = stringType;
         } else if ("bits".equals(typeName)) {
-            return new BitsType(baseTypePathFinal, getBits(typeBody, actualPath, namespace, revision, prefix));
+            return new BitsType(baseTypePathFinal, getBits(typeBody, actualPath, moduleName, namespace, revision, prefix));
         } else if ("leafref".equals(typeName)) {
             final String path = parseLeafrefPath(typeBody);
             final boolean absolute = path.startsWith("/");
@@ -1382,10 +1387,10 @@ public final class ParserListenerUtils {
         for (int i = 0; i < ctx.getChildCount(); ++i) {
             final ParseTree childNode = ctx.getChild(i);
             if (childNode instanceof Max_elements_stmtContext) {
-                Integer max = parseMaxElements((Max_elements_stmtContext) childNode);
+                Integer max = parseMaxElements((Max_elements_stmtContext) childNode, constraints.getModuleName());
                 constraints.setMaxElements(max);
             } else if (childNode instanceof Min_elements_stmtContext) {
-                Integer min = parseMinElements((Min_elements_stmtContext) childNode);
+                Integer min = parseMinElements((Min_elements_stmtContext) childNode, constraints.getModuleName());
                 constraints.setMinElements(min);
             } else if (childNode instanceof Must_stmtContext) {
                 MustDefinition must = parseMust((Must_stmtContext) childNode);
@@ -1404,7 +1409,7 @@ public final class ParserListenerUtils {
         }
     }
 
-    private static Integer parseMinElements(Min_elements_stmtContext ctx) {
+    private static Integer parseMinElements(Min_elements_stmtContext ctx, String moduleName) {
         Integer result = null;
         try {
             for (int i = 0; i < ctx.getChildCount(); i++) {
@@ -1418,11 +1423,11 @@ public final class ParserListenerUtils {
             }
             return result;
         } catch (Exception e) {
-            throw new YangParseException(ctx.getStart().getLine(), "Failed to parse min-elements.", e);
+            throw new YangParseException(moduleName, ctx.getStart().getLine(), "Failed to parse min-elements.", e);
         }
     }
 
-    private static Integer parseMaxElements(Max_elements_stmtContext ctx) {
+    private static Integer parseMaxElements(Max_elements_stmtContext ctx, String moduleName) {
         Integer result = null;
         try {
             for (int i = 0; i < ctx.getChildCount(); i++) {
@@ -1436,7 +1441,7 @@ public final class ParserListenerUtils {
             }
             return result;
         } catch (Exception e) {
-            throw new YangParseException(ctx.getStart().getLine(), "Failed to parse max-elements.", e);
+            throw new YangParseException(moduleName, ctx.getStart().getLine(), "Failed to parse max-elements.", e);
         }
     }
 
@@ -1506,9 +1511,9 @@ public final class ParserListenerUtils {
      *            refine statement
      * @return RefineHolder object representing this refine statement
      */
-    public static RefineHolder parseRefine(Refine_stmtContext refineCtx) {
+    public static RefineHolder parseRefine(Refine_stmtContext refineCtx, String moduleName) {
         final String refineTarget = stringFromNode(refineCtx);
-        final RefineHolder refine = new RefineHolder(refineCtx.getStart().getLine(), refineTarget);
+        final RefineHolder refine = new RefineHolder(moduleName, refineCtx.getStart().getLine(), refineTarget);
         for (int i = 0; i < refineCtx.getChildCount(); i++) {
             ParseTree refinePom = refineCtx.getChild(i);
             if (refinePom instanceof Refine_pomContext) {
@@ -1545,7 +1550,7 @@ public final class ParserListenerUtils {
                 String reference = stringFromNode(refineArg);
                 refine.setReference(reference);
             } else if (refineArg instanceof Config_stmtContext) {
-                Boolean config = parseConfig((Config_stmtContext) refineArg);
+                Boolean config = parseConfig((Config_stmtContext) refineArg, refine.getModuleName());
                 refine.setConfiguration(config);
             }
         }
@@ -1594,10 +1599,10 @@ public final class ParserListenerUtils {
                 MustDefinition must = parseMust((Must_stmtContext) refineArg);
                 refine.setMust(must);
             } else if (refineArg instanceof Max_elements_stmtContext) {
-                Integer max = parseMaxElements((Max_elements_stmtContext) refineArg);
+                Integer max = parseMaxElements((Max_elements_stmtContext) refineArg, refine.getModuleName());
                 refine.setMaxElements(max);
             } else if (refineArg instanceof Min_elements_stmtContext) {
-                Integer min = parseMinElements((Min_elements_stmtContext) refineArg);
+                Integer min = parseMinElements((Min_elements_stmtContext) refineArg, refine.getModuleName());
                 refine.setMinElements(min);
             }
         }
@@ -1611,10 +1616,10 @@ public final class ParserListenerUtils {
                 MustDefinition must = parseMust((Must_stmtContext) refineArg);
                 refine.setMust(must);
             } else if (refineArg instanceof Max_elements_stmtContext) {
-                Integer max = parseMaxElements((Max_elements_stmtContext) refineArg);
+                Integer max = parseMaxElements((Max_elements_stmtContext) refineArg, refine.getModuleName());
                 refine.setMaxElements(max);
             } else if (refineArg instanceof Min_elements_stmtContext) {
-                Integer min = parseMinElements((Min_elements_stmtContext) refineArg);
+                Integer min = parseMinElements((Min_elements_stmtContext) refineArg, refine.getModuleName());
                 refine.setMinElements(min);
             }
         }
@@ -7,6 +7,7 @@
  */
 package org.opendaylight.controller.yang.parser.util;
 
+import java.net.URI;
 import java.util.ArrayList;
 import java.util.Date;
 import java.util.List;
@@ -93,6 +94,7 @@ import org.opendaylight.controller.yang.parser.builder.impl.ConstraintsBuilder;
 import org.opendaylight.controller.yang.parser.builder.impl.ContainerSchemaNodeBuilder;
 import org.opendaylight.controller.yang.parser.builder.impl.ContainerSchemaNodeBuilder.ContainerSchemaNodeImpl;
 import org.opendaylight.controller.yang.parser.builder.impl.GroupingBuilderImpl;
+import org.opendaylight.controller.yang.parser.builder.impl.IdentityrefTypeBuilder;
 import org.opendaylight.controller.yang.parser.builder.impl.LeafListSchemaNodeBuilder;
 import org.opendaylight.controller.yang.parser.builder.impl.LeafSchemaNodeBuilder;
 import org.opendaylight.controller.yang.parser.builder.impl.ListSchemaNodeBuilder;
@@ -121,12 +123,15 @@ public final class ParserUtils {
      * @param name
      * @return
      */
-    public static SchemaPath createSchemaPath(SchemaPath schemaPath, String name) {
-        List<QName> path = new ArrayList<QName>(schemaPath.getPath());
-        QName last = path.get(path.size() - 1);
-        QName newQName = new QName(last.getNamespace(), last.getRevision(), last.getPrefix(), name);
+    public static SchemaPath createSchemaPath(SchemaPath schemaPath, String name, URI namespace, Date revision, String prefix) {
+        List<QName> path = new ArrayList<QName>();
+        if(schemaPath != null) {
+            path.addAll(schemaPath.getPath());
+        }
+        QName newQName = new QName(namespace, revision, prefix, name);
         path.add(newQName);
-        return new SchemaPath(path, schemaPath.isAbsolute());
+        boolean abs = schemaPath == null ? true : schemaPath.isAbsolute();
+        return new SchemaPath(path, abs);
     }
 
     /**
@@ -482,7 +487,7 @@ public final class ParserUtils {
                 }
             }
             correctAugmentChildPath(builder, target.getPath());
-            target.addChildNode(builder);
+            target.addCase(builder);
         }
     }
 
@@ -750,8 +755,9 @@ public final class ParserUtils {
      *            line in module
      * @return builder object from leaf
      */
-    public static LeafSchemaNodeBuilder createLeafBuilder(LeafSchemaNode leaf, int line) {
-        final LeafSchemaNodeBuilder builder = new LeafSchemaNodeBuilder(leaf.getQName(), leaf.getPath(), line);
+    public static LeafSchemaNodeBuilder createLeafBuilder(LeafSchemaNode leaf, String moduleName, int line) {
+        final LeafSchemaNodeBuilder builder = new LeafSchemaNodeBuilder(moduleName, line, leaf.getQName(),
+                leaf.getPath());
         convertDataSchemaNode(leaf, builder);
         builder.setConfiguration(leaf.isConfiguration());
         final TypeDefinition<?> type = leaf.getType();
@@ -763,9 +769,9 @@ public final class ParserUtils {
         return builder;
     }
 
-    public static ContainerSchemaNodeBuilder createContainer(ContainerSchemaNode container, int line) {
-        final ContainerSchemaNodeBuilder builder = new ContainerSchemaNodeBuilder(line, container.getQName(),
-                container.getPath());
+    public static ContainerSchemaNodeBuilder createContainer(ContainerSchemaNode container, String moduleName, int line) {
+        final ContainerSchemaNodeBuilder builder = new ContainerSchemaNodeBuilder(moduleName, line,
+                container.getQName(), container.getPath());
         convertDataSchemaNode(container, builder);
         builder.setConfiguration(container.isConfiguration());
         builder.setUnknownNodes(container.getUnknownSchemaNodes());
@@ -778,8 +784,8 @@ public final class ParserUtils {
         return builder;
     }
 
-    public static ListSchemaNodeBuilder createList(ListSchemaNode list, int line) {
-        ListSchemaNodeBuilder builder = new ListSchemaNodeBuilder(line, list.getQName(), list.getPath());
+    public static ListSchemaNodeBuilder createList(ListSchemaNode list, String moduleName, int line) {
+        ListSchemaNodeBuilder builder = new ListSchemaNodeBuilder(moduleName, line, list.getQName(), list.getPath());
         convertDataSchemaNode(list, builder);
         builder.setConfiguration(list.isConfiguration());
         builder.setUnknownNodes(list.getUnknownSchemaNodes());
@@ -792,8 +798,8 @@ public final class ParserUtils {
         return builder;
     }
 
-    public static LeafListSchemaNodeBuilder createLeafList(LeafListSchemaNode leafList, int line) {
-        final LeafListSchemaNodeBuilder builder = new LeafListSchemaNodeBuilder(line, leafList.getQName(),
+    public static LeafListSchemaNodeBuilder createLeafList(LeafListSchemaNode leafList, String moduleName, int line) {
+        final LeafListSchemaNodeBuilder builder = new LeafListSchemaNodeBuilder(moduleName, line, leafList.getQName(),
                 leafList.getPath());
         convertDataSchemaNode(leafList, builder);
         builder.setConfiguration(leafList.isConfiguration());
@@ -803,8 +809,8 @@ public final class ParserUtils {
         return builder;
     }
 
-    public static ChoiceBuilder createChoice(ChoiceNode choice, int line) {
-        final ChoiceBuilder builder = new ChoiceBuilder(line, choice.getQName());
+    public static ChoiceBuilder createChoice(ChoiceNode choice, String moduleName, int line) {
+        final ChoiceBuilder builder = new ChoiceBuilder(moduleName, line, choice.getQName());
         convertDataSchemaNode(choice, builder);
         builder.setConfiguration(choice.isConfiguration());
         builder.setCases(choice.getCases());
@@ -813,16 +819,16 @@ public final class ParserUtils {
         return builder;
     }
 
-    public static AnyXmlBuilder createAnyXml(AnyXmlSchemaNode anyxml, int line) {
-        final AnyXmlBuilder builder = new AnyXmlBuilder(line, anyxml.getQName(), anyxml.getPath());
+    public static AnyXmlBuilder createAnyXml(AnyXmlSchemaNode anyxml, String moduleName, int line) {
+        final AnyXmlBuilder builder = new AnyXmlBuilder(moduleName, line, anyxml.getQName(), anyxml.getPath());
         convertDataSchemaNode(anyxml, builder);
         builder.setConfiguration(anyxml.isConfiguration());
         builder.setUnknownNodes(anyxml.getUnknownSchemaNodes());
         return builder;
     }
 
-    public static GroupingBuilder createGrouping(GroupingDefinition grouping, int line) {
-        final GroupingBuilderImpl builder = new GroupingBuilderImpl(grouping.getQName(), line);
+    public static GroupingBuilder createGrouping(GroupingDefinition grouping, String moduleName, int line) {
+        final GroupingBuilderImpl builder = new GroupingBuilderImpl(moduleName, line, grouping.getQName());
         builder.setPath(grouping.getPath());
         builder.setChildNodes(grouping.getChildNodes());
         builder.setGroupings(grouping.getGroupings());
@@ -835,8 +841,8 @@ public final class ParserUtils {
         return builder;
     }
 
-    public static TypeDefinitionBuilder createTypedef(ExtendedType typedef, int line) {
-        final TypeDefinitionBuilderImpl builder = new TypeDefinitionBuilderImpl(typedef.getQName(), line);
+    public static TypeDefinitionBuilder createTypedef(ExtendedType typedef, String moduleName, int line) {
+        final TypeDefinitionBuilderImpl builder = new TypeDefinitionBuilderImpl(moduleName, line, typedef.getQName());
         builder.setPath(typedef.getPath());
         builder.setDefaultValue(typedef.getDefaultValue());
         builder.setUnits(typedef.getUnits());
@@ -854,8 +860,9 @@ public final class ParserUtils {
         return builder;
     }
 
-    public static UnknownSchemaNodeBuilder createUnknownSchemaNode(UnknownSchemaNode unknownNode, int line) {
-        final UnknownSchemaNodeBuilder builder = new UnknownSchemaNodeBuilder(line, unknownNode.getQName());
+    public static UnknownSchemaNodeBuilder createUnknownSchemaNode(UnknownSchemaNode unknownNode, String moduleName,
+            int line) {
+        final UnknownSchemaNodeBuilder builder = new UnknownSchemaNodeBuilder(moduleName, line, unknownNode.getQName());
         builder.setPath(unknownNode.getPath());
         builder.setUnknownNodes(unknownNode.getUnknownSchemaNodes());
         builder.setDescription(unknownNode.getDescription());
@@ -995,7 +1002,7 @@ public final class ParserUtils {
             module.augmentResolved();
         } else {
             throw new YangParseException(module.getName(), line, "Target of type " + node.getClass()
-                    + " can not be augmented.");
+                    + " cannot be augmented.");
         }
     }
 
@@ -1084,7 +1091,8 @@ public final class ParserUtils {
         tc.addRanges(oldExtendedType.getRanges());
 
         final TypeConstraints constraints = findConstraintsFromTypeBuilder(newBaseType, tc, modules, module, null);
-        final TypeDefinitionBuilderImpl newType = new TypeDefinitionBuilderImpl(oldExtendedType.getQName(), line);
+        final TypeDefinitionBuilderImpl newType = new TypeDefinitionBuilderImpl(module.getModuleName(), line,
+                oldExtendedType.getQName());
         newType.setTypedef(newBaseType);
         newType.setPath(oldExtendedType.getPath());
         newType.setDescription(oldExtendedType.getDescription());
@@ -1120,7 +1128,8 @@ public final class ParserUtils {
         final TypeConstraints tc = new TypeConstraints(module.getName(), line);
 
         final TypeConstraints constraints = findConstraintsFromTypeDefinition(newBaseType, tc);
-        final TypeDefinitionBuilderImpl newType = new TypeDefinitionBuilderImpl(oldExtendedType.getQName(), line);
+        final TypeDefinitionBuilderImpl newType = new TypeDefinitionBuilderImpl(module.getModuleName(), line,
+                oldExtendedType.getQName());
         newType.setType(newBaseType);
         newType.setPath(oldExtendedType.getPath());
         newType.setDescription(oldExtendedType.getDescription());
@@ -1169,8 +1178,8 @@ public final class ParserUtils {
             final TypeConstraints constraints, final Map<String, TreeMap<Date, ModuleBuilder>> modules,
             final ModuleBuilder builder, final SchemaContext context) {
 
-        // union type cannot be restricted
-        if (nodeToResolve instanceof UnionTypeBuilder) {
+        // union and identityref types cannot be restricted
+        if (nodeToResolve instanceof UnionTypeBuilder || nodeToResolve instanceof IdentityrefTypeBuilder) {
             return constraints;
         }
 
@@ -7,16 +7,10 @@
  */
 package org.opendaylight.controller.yang.parser.util;
 
-import java.util.ArrayList;
-import java.util.List;
-
 import org.opendaylight.controller.yang.model.api.MustDefinition;
-import org.opendaylight.controller.yang.parser.builder.api.Builder;
-import org.opendaylight.controller.yang.parser.builder.impl.UnknownSchemaNodeBuilder;
+import org.opendaylight.controller.yang.parser.builder.api.AbstractBuilder;
 
-public final class RefineHolder implements Builder {
-    private Builder parent;
-    private final int line;
+public final class RefineHolder extends AbstractBuilder {
     private final String name;
     private String defaultStr;
     private String description;
@@ -27,26 +21,10 @@ public final class RefineHolder implements Builder {
     private MustDefinition must;
     private Integer minElements;
     private Integer maxElements;
-    private final List<UnknownSchemaNodeBuilder> addedUnknownNodes = new ArrayList<UnknownSchemaNodeBuilder>();
 
-    public RefineHolder(final int line, final String name) {
+    public RefineHolder(final String moduleName, final int line, final String name) {
+        super(moduleName, line);
         this.name = name;
-        this.line = line;
-    }
-
-    @Override
-    public int getLine() {
-        return line;
-    }
-
-    @Override
-    public Builder getParent() {
-        return parent;
-    }
-
-    @Override
-    public void setParent(final Builder parent) {
-        this.parent = parent;
     }
 
     public String getDefaultStr() {
@@ -125,16 +103,6 @@ public final class RefineHolder implements Builder {
         return name;
     }
 
-    @Override
-    public List<UnknownSchemaNodeBuilder> getUnknownNodeBuilders() {
-        return addedUnknownNodes;
-    }
-
-    @Override
-    public void addUnknownNodeBuilder(UnknownSchemaNodeBuilder unknownNode) {
-        addedUnknownNodes.add(unknownNode);
-    }
-
     @Override
     public Object build() {
         return null;
@@ -233,7 +201,7 @@ public final class RefineHolder implements Builder {
 
     @Override
     public String toString() {
-        return "revine " + name;
+        return "refine " + name;
     }
 
 }
@@ -96,38 +96,37 @@ public class RefineUtils {
      *            grouping which should contains node to refine
      * @param refine
      *            refine object containing informations about refine
-     * @param moduleName
-     *            current module name
      * @return
      */
     public static SchemaNodeBuilder getRefineNodeFromGroupingDefinition(final GroupingDefinition grouping,
-            final RefineHolder refine, final String moduleName) {
-        SchemaNodeBuilder result = null;
+            final RefineHolder refine) {
+        final String moduleName = refine.getModuleName();
         final int line = refine.getLine();
+        SchemaNodeBuilder result = null;
         final Object lookedUpNode = findRefineTargetNode(grouping, refine.getName());
         if (lookedUpNode instanceof LeafSchemaNode) {
-            result = createLeafBuilder((LeafSchemaNode) lookedUpNode, line);
+            result = createLeafBuilder((LeafSchemaNode) lookedUpNode, moduleName, line);
         } else if (lookedUpNode instanceof ContainerSchemaNode) {
-            result = createContainer((ContainerSchemaNode) lookedUpNode, line);
+            result = createContainer((ContainerSchemaNode) lookedUpNode, moduleName, line);
         } else if (lookedUpNode instanceof ListSchemaNode) {
-            result = createList((ListSchemaNode) lookedUpNode, line);
+            result = createList((ListSchemaNode) lookedUpNode, moduleName, line);
         } else if (lookedUpNode instanceof LeafListSchemaNode) {
-            result = createLeafList((LeafListSchemaNode) lookedUpNode, line);
+            result = createLeafList((LeafListSchemaNode) lookedUpNode, moduleName, line);
         } else if (lookedUpNode instanceof ChoiceNode) {
-            result = createChoice((ChoiceNode) lookedUpNode, line);
+            result = createChoice((ChoiceNode) lookedUpNode, moduleName, line);
         } else if (lookedUpNode instanceof AnyXmlSchemaNode) {
-            result = createAnyXml((AnyXmlSchemaNode) lookedUpNode, line);
+            result = createAnyXml((AnyXmlSchemaNode) lookedUpNode, moduleName, line);
         } else if (lookedUpNode instanceof GroupingDefinition) {
-            result = createGrouping((GroupingDefinition) lookedUpNode, line);
+            result = createGrouping((GroupingDefinition) lookedUpNode, moduleName, line);
         } else if (lookedUpNode instanceof TypeDefinition) {
-            result = createTypedef((ExtendedType) lookedUpNode, line);
+            result = createTypedef((ExtendedType) lookedUpNode, moduleName, line);
         } else {
             throw new YangParseException(moduleName, line, "Target '" + refine.getName() + "' can not be refined");
         }
         return result;
     }
 
-    public static void refineLeaf(LeafSchemaNodeBuilder leaf, RefineHolder refine, int line) {
+    public static void refineLeaf(LeafSchemaNodeBuilder leaf, RefineHolder refine) {
         String defaultStr = refine.getDefaultStr();
         Boolean mandatory = refine.isMandatory();
         MustDefinition must = refine.getMust();
@@ -256,8 +255,9 @@ public class RefineUtils {
      *            refine object containing information about refine process
      */
     public static void checkRefine(SchemaNodeBuilder node, RefineHolder refine) {
-        String name = node.getQName().getLocalName();
+        String moduleName = refine.getModuleName();
         int line = refine.getLine();
+        String name = node.getQName().getLocalName();
 
         String defaultStr = refine.getDefaultStr();
         Boolean mandatory = refine.isMandatory();
@@ -267,64 +267,66 @@ public class RefineUtils {
         Integer max = refine.getMaxElements();
 
         if (node instanceof AnyXmlBuilder) {
-            checkRefineDefault(node, defaultStr, line);
-            checkRefinePresence(node, presence, line);
-            checkRefineMinMax(name, line, min, max);
+            checkRefineDefault(node, defaultStr, moduleName, line);
+            checkRefinePresence(node, presence, moduleName, line);
+            checkRefineMinMax(name, min, max, moduleName, line);
         } else if (node instanceof ChoiceBuilder) {
-            checkRefinePresence(node, presence, line);
-            checkRefineMust(node, must, line);
-            checkRefineMinMax(name, line, min, max);
+            checkRefinePresence(node, presence, moduleName, line);
+            checkRefineMust(node, must, moduleName, line);
+            checkRefineMinMax(name, min, max, moduleName, line);
         } else if (node instanceof ContainerSchemaNodeBuilder) {
-            checkRefineDefault(node, defaultStr, line);
-            checkRefineMandatory(node, mandatory, line);
-            checkRefineMust(node, must, line);
-            checkRefineMinMax(name, line, min, max);
+            checkRefineDefault(node, defaultStr, moduleName, line);
+            checkRefineMandatory(node, mandatory, moduleName, line);
+            checkRefineMust(node, must, moduleName, line);
+            checkRefineMinMax(name, min, max, moduleName, line);
         } else if (node instanceof LeafSchemaNodeBuilder) {
-            checkRefinePresence(node, presence, line);
-            checkRefineMinMax(name, line, min, max);
+            checkRefinePresence(node, presence, moduleName, line);
+            checkRefineMinMax(name, min, max, moduleName, line);
         } else if (node instanceof LeafListSchemaNodeBuilder || node instanceof ListSchemaNodeBuilder) {
-            checkRefineDefault(node, defaultStr, line);
-            checkRefinePresence(node, presence, line);
-            checkRefineMandatory(node, mandatory, line);
+            checkRefineDefault(node, defaultStr, moduleName, line);
+            checkRefinePresence(node, presence, moduleName, line);
+            checkRefineMandatory(node, mandatory, moduleName, line);
         } else if (node instanceof GroupingBuilder || node instanceof TypeDefinitionBuilder
                 || node instanceof UsesNodeBuilder) {
-            checkRefineDefault(node, defaultStr, line);
-            checkRefinePresence(node, presence, line);
-            checkRefineMandatory(node, mandatory, line);
-            checkRefineMust(node, must, line);
-            checkRefineMinMax(name, line, min, max);
+            checkRefineDefault(node, defaultStr, moduleName, line);
+            checkRefinePresence(node, presence, moduleName, line);
+            checkRefineMandatory(node, mandatory, moduleName, line);
+            checkRefineMust(node, must, moduleName, line);
+            checkRefineMinMax(name, min, max, moduleName, line);
         }
     }
 
-    private static void checkRefineDefault(SchemaNodeBuilder node, String defaultStr, int line) {
+    private static void checkRefineDefault(SchemaNodeBuilder node, String defaultStr, String moduleName, int line) {
         if (defaultStr != null) {
-            throw new YangParseException(line, "Can not refine 'default' for '" + node.getQName().getLocalName() + "'.");
+            throw new YangParseException(moduleName, line, "Can not refine 'default' for '"
+                    + node.getQName().getLocalName() + "'.");
         }
     }
 
-    private static void checkRefineMandatory(SchemaNodeBuilder node, Boolean mandatory, int line) {
+    private static void checkRefineMandatory(SchemaNodeBuilder node, Boolean mandatory, String moduleName, int line) {
         if (mandatory != null) {
-            throw new YangParseException(line, "Can not refine 'mandatory' for '" + node.getQName().getLocalName()
-                    + "'.");
+            throw new YangParseException(moduleName, line, "Can not refine 'mandatory' for '"
+                    + node.getQName().getLocalName() + "'.");
         }
     }
 
-    private static void checkRefinePresence(SchemaNodeBuilder node, Boolean presence, int line) {
+    private static void checkRefinePresence(SchemaNodeBuilder node, Boolean presence, String moduleName, int line) {
         if (presence != null) {
-            throw new YangParseException(line, "Can not refine 'presence' for '" + node.getQName().getLocalName()
-                    + "'.");
+            throw new YangParseException(moduleName, line, "Can not refine 'presence' for '"
+                    + node.getQName().getLocalName() + "'.");
         }
     }
 
-    private static void checkRefineMust(SchemaNodeBuilder node, MustDefinition must, int line) {
+    private static void checkRefineMust(SchemaNodeBuilder node, MustDefinition must, String moduleName, int line) {
         if (must != null) {
-            throw new YangParseException(line, "Can not refine 'must' for '" + node.getQName().getLocalName() + "'.");
+            throw new YangParseException(moduleName, line, "Can not refine 'must' for '"
+                    + node.getQName().getLocalName() + "'.");
         }
     }
 
-    private static void checkRefineMinMax(String refineTargetName, int refineLine, Integer min, Integer max) {
+    private static void checkRefineMinMax(String refineTargetName, Integer min, Integer max, String moduleName, int line) {
         if (min != null || max != null) {
-            throw new YangParseException(refineLine, "Can not refine 'min-elements' or 'max-elements' for '"
+            throw new YangParseException(moduleName, line, "Can not refine 'min-elements' or 'max-elements' for '"
                     + refineTargetName + "'.");
         }
     }
@@ -343,10 +345,10 @@ public class RefineUtils {
      *            node to refine
      * @param refine
      *            refine object containing information about refine process
-     * @param line
-     *            current line in yang model
      */
-    public static void refineDefault(final Builder node, final RefineHolder refine, final int line) {
+    public static void refineDefault(final Builder node, final RefineHolder refine) {
+        final String moduleName = refine.getModuleName();
+        final int line = refine.getLine();
         Class<? extends Builder> cls = node.getClass();
 
         String description = refine.getDescription();
@@ -355,7 +357,7 @@ public class RefineUtils {
                 Method method = cls.getDeclaredMethod("setDescription", String.class);
                 method.invoke(node, description);
             } catch (Exception e) {
-                throw new YangParseException(line, "Cannot refine description in " + cls.getName(), e);
+                throw new YangParseException(moduleName, line, "Cannot refine description in " + cls.getName(), e);
             }
         }
 
@@ -365,7 +367,7 @@ public class RefineUtils {
                 Method method = cls.getDeclaredMethod("setReference", String.class);
                 method.invoke(node, reference);
             } catch (Exception e) {
-                throw new YangParseException(line, "Cannot refine reference in " + cls.getName(), e);
+                throw new YangParseException(moduleName, line, "Cannot refine reference in " + cls.getName(), e);
             }
         }
 
@@ -375,7 +377,7 @@ public class RefineUtils {
                 Method method = cls.getDeclaredMethod("setConfiguration", Boolean.class);
                 method.invoke(node, config);
             } catch (Exception e) {
-                throw new YangParseException(line, "Cannot refine config in " + cls.getName(), e);
+                throw new YangParseException(moduleName, line, "Cannot refine config in " + cls.getName(), e);
             }
         }
     }
@@ -392,9 +394,9 @@ public class RefineUtils {
      */
     public static void performRefine(SchemaNodeBuilder nodeToRefine, RefineHolder refine, int line) {
         checkRefine(nodeToRefine, refine);
-        refineDefault(nodeToRefine, refine, line);
+        refineDefault(nodeToRefine, refine);
         if (nodeToRefine instanceof LeafSchemaNodeBuilder) {
-            refineLeaf((LeafSchemaNodeBuilder) nodeToRefine, refine, line);
+            refineLeaf((LeafSchemaNodeBuilder) nodeToRefine, refine);
         } else if (nodeToRefine instanceof ContainerSchemaNodeBuilder) {
             refineContainer((ContainerSchemaNodeBuilder) nodeToRefine, refine, line);
         } else if (nodeToRefine instanceof ListSchemaNodeBuilder) {
@@ -229,7 +229,7 @@ public final class TypeConstraints {
 
         for (RangeConstraint range : typeRange) {
             if (range.getMin() instanceof UnknownBoundaryNumber || range.getMax() instanceof UnknownBoundaryNumber) {
-                throw new YangParseException(line, "Unresolved range constraints");
+                throw new YangParseException(moduleName, line, "Unresolved range constraints");
             }
             final long min = range.getMin().longValue();
             final long max = range.getMax().longValue();
@@ -268,7 +268,7 @@ public final class TypeConstraints {
 
         for (RangeConstraint range : typeRange) {
             if (range.getMin() instanceof UnknownBoundaryNumber || range.getMax() instanceof UnknownBoundaryNumber) {
-                throw new YangParseException(line, "Unresolved range constraints");
+                throw new YangParseException(moduleName, line, "Unresolved range constraints");
             }
             final long min = range.getMin().longValue();
             final long max = range.getMax().longValue();
@@ -308,7 +308,7 @@ public final class TypeConstraints {
 
         for (LengthConstraint length : typeLength) {
             if (length.getMin() instanceof UnknownBoundaryNumber || length.getMax() instanceof UnknownBoundaryNumber) {
-                throw new YangParseException(line, "Unresolved length constraints");
+                throw new YangParseException(moduleName, line, "Unresolved length constraints");
             }
             final long min = length.getMin().longValue();
             final long max = length.getMax().longValue();
@@ -347,7 +347,7 @@ public final class TypeConstraints {
 
         for (LengthConstraint length : typeLength) {
             if (length.getMin() instanceof UnknownBoundaryNumber || length.getMax() instanceof UnknownBoundaryNumber) {
-                throw new YangParseException(line, "Unresolved length constraints");
+                throw new YangParseException(moduleName, line, "Unresolved length constraints");
             }
             final long min = length.getMin().longValue();
             final long max = length.getMax().longValue();
@@ -8,7 +8,6 @@
 package org.opendaylight.controller.yang.parser.util;
 
 public class YangParseException extends RuntimeException {
-
     private static final long serialVersionUID = 1239548963471793178L;
 
     public YangParseException(final String errorMsg) {
@@ -19,24 +18,15 @@ public class YangParseException extends RuntimeException {
         super(errorMsg, exception);
     }
 
-    public YangParseException(final int line, final String errorMsg) {
-        super("Error on line " + line + ": " + errorMsg);
-    }
-
-    public YangParseException(final int line, final String errorMsg,
-            final Exception exception) {
-        super("Error on line " + line + ": " + errorMsg, exception);
-    }
-
     public YangParseException(final String moduleName, final int line,
             final String errorMsg) {
-        super("Error in module '" + moduleName + "' on line " + line + ": "
+        super("Error in module '" + moduleName + "' at line " + line + ": "
                 + errorMsg);
     }
 
     public YangParseException(final String moduleName, final int line,
             final String errorMsg, final Exception exception) {
-        super("Error in module '" + moduleName + "' on line " + line + ": "
+        super("Error in module '" + moduleName + "' at line " + line + ": "
                 + errorMsg, exception);
     }
 
@@ -17,6 +17,7 @@ import java.util.Set;
 import org.junit.Before;
 import org.junit.Test;
 import org.opendaylight.controller.yang.model.api.AnyXmlSchemaNode;
+import org.opendaylight.controller.yang.model.api.AugmentationSchema;
 import org.opendaylight.controller.yang.model.api.ChoiceNode;
 import org.opendaylight.controller.yang.model.api.ContainerSchemaNode;
 import org.opendaylight.controller.yang.model.api.DataSchemaNode;
@@ -228,4 +229,113 @@ public class GroupingTest {
         assertFalse(node_u.equals(node_g));
     }
 
+    @Test
+    public void testUsesUnderModule() {
+        // suffix _u = added by uses
+        // suffix _g = defined in grouping
+
+        Module testModule = TestUtils.findModule(modules, "custom");
+
+        // get grouping
+        Set<GroupingDefinition> groupings = testModule.getGroupings();
+        assertEquals(1, groupings.size());
+        GroupingDefinition grouping = groupings.iterator().next();
+
+        // get node containing uses
+        Module destination = TestUtils.findModule(modules, "nodes");
+
+        // check uses
+        Set<UsesNode> uses = destination.getUses();
+        assertEquals(1, uses.size());
+
+        // check uses process
+        AnyXmlSchemaNode data_u = (AnyXmlSchemaNode) destination.getDataChildByName("data");
+        assertNotNull(data_u);
+        assertTrue(data_u.isAddedByUses());
+
+        AnyXmlSchemaNode data_g = (AnyXmlSchemaNode) grouping.getDataChildByName("data");
+        assertNotNull(data_g);
+        assertFalse(data_g.isAddedByUses());
+        assertFalse(data_u.equals(data_g));
+
+        ChoiceNode how_u = (ChoiceNode) destination.getDataChildByName("how");
+        assertNotNull(how_u);
+        assertTrue(how_u.isAddedByUses());
+
+        ChoiceNode how_g = (ChoiceNode) grouping.getDataChildByName("how");
+        assertNotNull(how_g);
+        assertFalse(how_g.isAddedByUses());
+        assertFalse(how_u.equals(how_g));
+
+        LeafSchemaNode address_u = (LeafSchemaNode) destination.getDataChildByName("address");
+        assertNotNull(address_u);
+        assertNull(address_u.getDefault());
+        assertEquals("Target IP address", address_u.getDescription());
+        assertNull(address_u.getReference());
+        assertTrue(address_u.isConfiguration());
+        assertTrue(address_u.isAddedByUses());
+
+        LeafSchemaNode address_g = (LeafSchemaNode) grouping.getDataChildByName("address");
+        assertNotNull(address_g);
+        assertFalse(address_g.isAddedByUses());
+        assertNull(address_g.getDefault());
+        assertEquals("Target IP address", address_g.getDescription());
+        assertNull(address_g.getReference());
+        assertTrue(address_g.isConfiguration());
+        assertFalse(address_u.equals(address_g));
+
+        ContainerSchemaNode port_u = (ContainerSchemaNode) destination.getDataChildByName("port");
+        assertNotNull(port_u);
+        assertTrue(port_u.isAddedByUses());
+
+        ContainerSchemaNode port_g = (ContainerSchemaNode) grouping.getDataChildByName("port");
+        assertNotNull(port_g);
+        assertFalse(port_g.isAddedByUses());
+        assertFalse(port_u.equals(port_g));
+
+        ListSchemaNode addresses_u = (ListSchemaNode) destination.getDataChildByName("addresses");
+        assertNotNull(addresses_u);
+        assertTrue(addresses_u.isAddedByUses());
+
+        ListSchemaNode addresses_g = (ListSchemaNode) grouping.getDataChildByName("addresses");
+        assertNotNull(addresses_g);
+        assertFalse(addresses_g.isAddedByUses());
+        assertFalse(addresses_u.equals(addresses_g));
+
+        // grouping defined by 'uses'
+        Set<GroupingDefinition> groupings_u = destination.getGroupings();
+        assertEquals(1, groupings_u.size());
+        GroupingDefinition grouping_u = groupings_u.iterator().next();
+        assertTrue(grouping_u.isAddedByUses());
+
+        // grouping defined in 'grouping' node
+        Set<GroupingDefinition> groupings_g = grouping.getGroupings();
+        assertEquals(1, groupings_g.size());
+        GroupingDefinition grouping_g = groupings_g.iterator().next();
+        assertFalse(grouping_g.isAddedByUses());
+        assertFalse(grouping_u.equals(grouping_g));
+
+        List<UnknownSchemaNode> nodes_u = destination.getUnknownSchemaNodes();
+        assertEquals(1, nodes_u.size());
+        UnknownSchemaNode node_u = nodes_u.get(0);
+        assertTrue(node_u.isAddedByUses());
+
+        List<UnknownSchemaNode> nodes_g = grouping.getUnknownSchemaNodes();
+        assertEquals(1, nodes_g.size());
+        UnknownSchemaNode node_g = nodes_g.get(0);
+        assertFalse(node_g.isAddedByUses());
+        assertFalse(node_u.equals(node_g));
+
+        UsesNode un = uses.iterator().next();
+        Set<AugmentationSchema> usesAugments = un.getAugmentations();
+        assertEquals(1, usesAugments.size());
+        AugmentationSchema augment = usesAugments.iterator().next();
+        assertEquals("inner augment", augment.getDescription());
+        Set<DataSchemaNode> children = augment.getChildNodes();
+        assertEquals(1, children.size());
+        DataSchemaNode leaf = children.iterator().next();
+        assertTrue(leaf instanceof LeafSchemaNode);
+        assertEquals("name", leaf.getQName().getLocalName());
+    }
+
 }
@@ -305,10 +305,15 @@ public class TypesResolutionTest {
         TypeDefinition<?> testedType = TestUtils.findTypedef(typedefs, "service-type-ref");
         IdentityrefType baseType = (IdentityrefType) testedType.getBaseType();
         QName identity = baseType.getIdentity();
-        assertEquals(URI.create("urn:simple.container.demo"), identity.getNamespace());
+        assertEquals(URI.create("urn:custom.types.demo"), identity.getNamespace());
         assertEquals(TestUtils.createDate("2012-04-16"), identity.getRevision());
         assertEquals("iit", identity.getPrefix());
         assertEquals("service-type", identity.getLocalName());
+
+        LeafSchemaNode type = (LeafSchemaNode)tested.getDataChildByName("type");
+        assertNotNull(type);
+        TypeDefinition<?> leafType = type.getType();
+        assertEquals(testedType, leafType);
     }
 
 }
@@ -13,6 +13,7 @@ import java.io.FileInputStream;
 import java.io.IOException;
 import java.io.InputStream;
 import java.util.ArrayList;
+import java.util.Arrays;
 import java.util.List;
 
 import org.junit.Test;
@@ -43,8 +44,7 @@ public class YangParserNegativeTest {
                 fail("YangParseException should by thrown");
             }
         } catch (YangParseException e) {
-            assertTrue(e.getMessage().contains(
-                    "Error in module 'test2' on line 24: Referenced type 'int-ext' not found."));
+            assertEquals(e.getMessage(), "Error in module 'test2' at line 24: Referenced type 'int-ext' not found.");
         }
     }
 
@@ -116,8 +116,8 @@ public class YangParserNegativeTest {
                 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"));
+            String expected = "Error in module 'container' at line 10: Can not add 'container foo': node with same name already declared at line 6";
+            assertEquals(expected, e.getMessage());
         }
     }
 
@@ -130,8 +130,8 @@ public class YangParserNegativeTest {
                 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"));
+            String expected = "Error in module 'container-list' at line 10: Can not add 'list foo': node with same name already declared at line 6";
+            assertEquals(expected, e.getMessage());
         }
     }
 
@@ -144,8 +144,8 @@ public class YangParserNegativeTest {
                 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"));
+            String expected = "Error in module 'container-leaf' at line 10: Can not add 'leaf foo': node with same name already declared at line 6";
+            assertEquals(expected, e.getMessage());
         }
     }
 
@@ -158,7 +158,40 @@ public class YangParserNegativeTest {
                 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"));
+            String expected = "Error in module 'typedef' at line 10: typedef with same name 'int-ext' already declared at line 6";
+            assertEquals(expected, e.getMessage());
+        }
+    }
+
+    @Test
+    public void testDuplicityInAugmentTarget1() throws Exception {
+        try {
+            try (InputStream stream1 = new FileInputStream(getClass().getResource(
+                    "/negative-scenario/duplicity/augment0.yang").getPath());
+                    InputStream stream2 = new FileInputStream(getClass().getResource(
+                            "/negative-scenario/duplicity/augment1.yang").getPath())) {
+                TestUtils.loadModules(Arrays.asList(stream1, stream2));
+                fail("YangParseException should by thrown");
+            }
+        } catch (YangParseException e) {
+            String expected = "Error in module 'augment1' at line 11: Can not add 'leaf id' to 'container bar' in module 'augment0': node with same name already declared at line 9";
+            assertEquals(expected, e.getMessage());
+        }
+    }
+
+    @Test
+    public void testDuplicityInAugmentTarget2() throws Exception {
+        try {
+            try (InputStream stream1 = new FileInputStream(getClass().getResource(
+                    "/negative-scenario/duplicity/augment0.yang").getPath());
+                    InputStream stream2 = new FileInputStream(getClass().getResource(
+                            "/negative-scenario/duplicity/augment2.yang").getPath())) {
+                TestUtils.loadModules(Arrays.asList(stream1, stream2));
+                fail("YangParseException should by thrown");
+            }
+        } catch (YangParseException e) {
+            String expected = "Error in module 'augment2' at line 11: Can not add 'anyxml delta' to node 'choice-ext' in module 'augment0': case with same name already declared at line 18";
+            assertEquals(expected, e.getMessage());
         }
     }
 
@@ -145,7 +145,25 @@ public class YangParserTest {
     }
 
     @Test
-    public void testOrderingNestedChildNodes() {
+    public void testOrderingNestedChildNodes1() {
+        Module test = TestUtils.findModule(modules, "nodes");
+
+        Set<DataSchemaNode> childNodes = test.getChildNodes();
+        String[] expectedOrder = new String[] { "address", "addresses", "custom-union-leaf", "data", "datas",
+                "decimal-leaf", "decimal-leaf2", "ext", "how", "int32-leaf", "length-leaf", "mycont", "peer", "port",
+                "string-leaf", "transfer", "union-leaf" };
+        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 testOrderingNestedChildNodes2() {
         Module test = TestUtils.findModule(modules, "custom");
         Set<GroupingDefinition> groupings = test.getGroupings();
         assertEquals(1, groupings.size());
@@ -195,7 +213,7 @@ public class YangParserTest {
         // test DataNodeContainer args
         assertEquals(0, interfaces.getTypeDefinitions().size());
         assertEquals(1, interfaces.getChildNodes().size());
-        assertEquals(0, interfaces.getGroupings().size());
+        assertEquals(1, interfaces.getGroupings().size());
         assertEquals(0, interfaces.getUses().size());
 
         ListSchemaNode ifEntry = (ListSchemaNode) interfaces.getDataChildByName("ifEntry");
@@ -688,12 +706,12 @@ public class YangParserTest {
     @Test
     public void testAnyXml() {
         Module testModule = TestUtils.findModule(modules, "nodes");
-        AnyXmlSchemaNode data = (AnyXmlSchemaNode) testModule.getDataChildByName("data");
+        AnyXmlSchemaNode data = (AnyXmlSchemaNode) testModule.getDataChildByName("datas");
         assertNotNull("anyxml data not found", data);
 
         // test SchemaNode args
         QName qname = data.getQName();
-        assertEquals("data", qname.getLocalName());
+        assertEquals("datas", qname.getLocalName());
         assertEquals("n", qname.getPrefix());
         assertEquals(nodesNS, qname.getNamespace());
         assertEquals(nodesRev, qname.getRevision());
@@ -312,7 +312,7 @@ public class YangParserWithContextTest {
 
         IdentitySchemaNode baseIdentity = identity.getBaseIdentity();
         QName idBaseQName = baseIdentity.getQName();
-        assertEquals(URI.create("urn:simple.container.demo"), idBaseQName.getNamespace());
+        assertEquals(URI.create("urn:custom.types.demo"), idBaseQName.getNamespace());
         assertEquals(simpleDateFormat.parse("2012-04-16"), idBaseQName.getRevision());
         assertEquals("iit", idBaseQName.getPrefix());
         assertEquals("service-type", idBaseQName.getLocalName());
@@ -337,7 +337,7 @@ public class YangParserWithContextTest {
 
         UnknownSchemaNode un = unknownNodes.get(0);
         QName unType = un.getNodeType();
-        assertEquals(URI.create("urn:simple.container.demo"), unType.getNamespace());
+        assertEquals(URI.create("urn:custom.types.demo"), unType.getNamespace());
         assertEquals(simpleDateFormat.parse("2012-04-16"), unType.getRevision());
         assertEquals("custom", unType.getPrefix());
         assertEquals("mountpoint", unType.getLocalName());
similarity index 95%
rename from opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/test/resources/model/nodes.yang
rename to opendaylight/sal/yang-prototype/yang/yang-model-parser-impl/src/test/resources/model/nodes.yang
index e27dd0b9c09fdc74666c05abcd3985a90bf4cfd2..2cde38598bbc506809e75443212995d418ec06c1 100644 (file)
@@ -101,7 +101,7 @@ module nodes {
         }
     }
 
-    anyxml data {
+    anyxml datas {
         description
           "Copy of the source typesstore subset that matched
            the filter criteria (if any).  An empty types container
@@ -151,6 +151,15 @@ module nodes {
         }
     }
 
+    uses c:target {
+        augment "/mycont/innercont" {
+            description "inner augment";
+            leaf name {
+                type string;
+            }
+        }
+    }
+
     container peer {
         container destination {
             uses c:target {
similarity index 79%
rename from opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/test/resources/model/types.yang
rename to opendaylight/sal/yang-prototype/yang/yang-model-parser-impl/src/test/resources/model/types.yang
index d9d506438337ad7df2d390e063e3d26f175243b6..bff9543009b0e2b6b9d0c5863f171e42ae2c3cbb 100644 (file)
@@ -2,7 +2,7 @@ module types {
     yang-version 1;
     namespace "urn:simple.types.test";
     prefix "t";
-    
+
     organization "opendaylight";
     contact "http://www.opendaylight.org/";
     description "This is types-data test description";
@@ -37,7 +37,7 @@ module types {
             length "6..10";
         }
     }
-    
+
     typedef string-ext3 {
         type string-ext2 {
             pattern "[b-u]*";
@@ -77,21 +77,24 @@ module types {
     }
 
     container interfaces {
-         list ifEntry {
-             key "ifIndex";
+        grouping ifEntry {
+            container augment-holder;
+        }
+        list ifEntry {
+            key "ifIndex";
 
-             leaf ifIndex {
-                 type uint32;
-                 units minutes;
-             }
+            leaf ifIndex {
+                type uint32;
+                units minutes;
+            }
 
-             leaf ifMtu {
-                 type int32;
-             }
+            leaf ifMtu {
+                type int32;
+            }
 
-             min-elements 1;
-             max-elements 11;
-         }
+            min-elements 1;
+            max-elements 11;
+        }
     }
 
 }
diff --git a/opendaylight/sal/yang-prototype/yang/yang-model-parser-impl/src/test/resources/negative-scenario/duplicity/augment0.yang b/opendaylight/sal/yang-prototype/yang/yang-model-parser-impl/src/test/resources/negative-scenario/duplicity/augment0.yang
new file mode 100644 (file)
index 0000000..ff8519c
--- /dev/null
@@ -0,0 +1,25 @@
+module augment0 {
+    yang-version 1;
+    namespace "urn:simple.augment0.demo";
+    prefix "a0";
+
+    container foo {
+        description "foo container";
+        container bar {
+            leaf id {
+                type int8;
+            }
+            typedef int-ext {
+                type int8 {
+                    range "5..10";
+                }
+            }
+            choice choice-ext {
+                leaf delta {
+                    type int8;
+                }
+            }
+        }
+    }
+
+}
diff --git a/opendaylight/sal/yang-prototype/yang/yang-model-parser-impl/src/test/resources/negative-scenario/duplicity/augment1.yang b/opendaylight/sal/yang-prototype/yang/yang-model-parser-impl/src/test/resources/negative-scenario/duplicity/augment1.yang
new file mode 100644 (file)
index 0000000..6afb493
--- /dev/null
@@ -0,0 +1,16 @@
+module augment1 {
+    yang-version 1;
+    namespace "urn:simple.augment1.demo";
+    prefix "a1";
+
+    import augment0 {
+        prefix "a0";
+    }
+
+    augment "/a0:foo/a0:bar" {
+        leaf id {
+            type string;
+        }
+    }
+
+}
diff --git a/opendaylight/sal/yang-prototype/yang/yang-model-parser-impl/src/test/resources/negative-scenario/duplicity/augment2.yang b/opendaylight/sal/yang-prototype/yang/yang-model-parser-impl/src/test/resources/negative-scenario/duplicity/augment2.yang
new file mode 100644 (file)
index 0000000..4d87619
--- /dev/null
@@ -0,0 +1,14 @@
+module augment2 {
+    yang-version 1;
+    namespace "urn:simple.augment2.demo";
+    prefix "a2";
+
+    import augment0 {
+        prefix "a0";
+    }
+
+    augment "/a0:foo/a0:bar/a0:choice-ext" {
+        anyxml delta;
+    }
+
+}
@@ -1,15 +1,14 @@
 module custom-types-test {
 
-       yang-version 1;
-    namespace "urn:simple.container.demo";
+    yang-version 1;
+    namespace "urn:custom.types.demo";
     prefix "iit";
-    
+
     organization "opendaylight";
     contact "WILL-BE-DEFINED-LATER";
         revision 2012-04-16 {
     }
-    
-    
+
     typedef access-operations-type {
         type bits {
             bit create {
@@ -32,17 +31,21 @@ module custom-types-test {
         }
         description "NETCONF Access Operation.";
     }
-     
+
     leaf inst-id-leaf1 {
         type instance-identifier {
            require-instance false;
         }
     }
-     
+
     leaf inst-id-leaf2 {
         type instance-identifier;
     }
 
+    leaf type {
+        type service-type-ref;
+    }
+
     identity crypto-base {
         description "crypto-base description";
     }
@@ -51,7 +54,7 @@ module custom-types-test {
         base "crypto-base";
         description "crypto-alg description";
     }
-    
+
     leaf mybits {
         type bits {
             bit disable-nagle {
@@ -66,32 +69,28 @@ module custom-types-test {
         }
         default "auto-sense-speed";
     }
-    
-   typedef ip-version {
-     type enumeration {
-       enum unknown {
-         description
-          "An unknown or unspecified version of the Internet protocol.";
-       }
-       enum ipv4 {
-         value "19";
-         description
-          "The IPv4 protocol as defined in RFC 791.";
-       }
-       enum ipv6 {
-         value "7";
-         description
-          "The IPv6 protocol as defined in RFC 2460.";
-       }
-       enum default {
-         description 
-          "default ip";
-       }
-     }
-   }
-   
-  identity service-type {
-    description
+
+    typedef ip-version {
+        type enumeration {
+            enum unknown {
+                description "An unknown or unspecified version of the Internet protocol.";
+            }
+            enum ipv4 {
+                value "19";
+                description "The IPv4 protocol as defined in RFC 791.";
+            }
+            enum ipv6 {
+                value "7";
+                description "The IPv6 protocol as defined in RFC 2460.";
+            }
+            enum default {
+                description "default ip";
+            }
+        }
+    }
+
+    identity service-type {
+        description
             "Service identity base type. All service identities must be
              derived from this type. A service type uniquely defines a single
              atomic API contract, such as a Java interface, a set of C
@@ -101,15 +100,14 @@ module custom-types-test {
              of that interface should be attached to the derived identity MUST
              include a java-class keyword, whose name argument points to that
              interface.";
-  }
+    }
 
-  typedef service-type-ref {
-    description
+    typedef service-type-ref {
+        description
             "Internal type of references to service type identity.";
-
-    type identityref {
-      base service-type;
+        type identityref {
+            base service-type;
+        }
     }
-  }
 
 }
index b865ebe015952d56d5368153bfb50f156c79427b..402eb63a1a9cc83cfe6351bc4b5fb5cc4be7aef9 100644 (file)
@@ -1,15 +1,22 @@
-<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">\r
-  <modelVersion>4.0.0</modelVersion>\r
-  <parent>\r
-    <groupId>org.opendaylight.controller</groupId>\r
-    <artifactId>yang</artifactId>\r
-    <version>0.5.4-SNAPSHOT</version>\r
-  </parent>\r
-  <artifactId>yang-model-util</artifactId>\r
-  <dependencies>\r
-      <dependency>\r
-          <groupId>org.opendaylight.controller</groupId>\r
-          <artifactId>yang-model-api</artifactId>\r
-      </dependency>\r
-  </dependencies>\r
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"\r
+    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">\r
+\r
+    <parent>\r
+        <groupId>org.opendaylight.controller</groupId>\r
+        <artifactId>yang</artifactId>\r
+        <version>0.5.4-SNAPSHOT</version>\r
+    </parent>\r
+\r
+    <modelVersion>4.0.0</modelVersion>\r
+    <artifactId>yang-model-util</artifactId>\r
+    <name>${project.artifactId}</name>\r
+    <description>${project.artifactId}</description>\r
+\r
+    <dependencies>\r
+        <dependency>\r
+            <groupId>org.opendaylight.controller</groupId>\r
+            <artifactId>yang-model-api</artifactId>\r
+        </dependency>\r
+    </dependencies>\r
+\r
 </project>\r
index ad903e9e52c45e7e0f74ad950f487fee35fb3930..a56697e97a49e6327074e2dfc614eb8c5dcd64a3 100644 (file)
@@ -41,12 +41,9 @@ public abstract class AbstractUnsignedInteger implements UnsignedIntegerTypeDefi
 
     /**
      *
-     * @param actualPath
-     * @param namespace
-     * @param revision
-     * @param name
+     * @param path uint type schema path
+     * @param name qname
      * @param description
-     * @param MIN_VALUE
      * @param maxRange
      * @param units
      */
@@ -63,7 +60,9 @@ public abstract class AbstractUnsignedInteger implements UnsignedIntegerTypeDefi
     }
 
     /**
-     * @param name
+     *
+     * @param path uint type schema path
+     * @param name qname
      * @param description
      * @param rangeStatements
      * @param units
index 94391d2288eace0dc4b6d9265d97ee06893e2dcb..60b5a43bf4c9d82b55809f9742e97472d84490e9 100644 (file)
@@ -36,6 +36,8 @@ public final class BitsType implements BitsTypeDefinition {
     /**
      * Default constructor. <br>
      * Instantiates Bits type as empty bits list.
+     *
+     * @param path
      */
     public BitsType(final SchemaPath path) {
         super();
@@ -47,11 +49,8 @@ public final class BitsType implements BitsTypeDefinition {
     /**
      * Constructor with explicit definition of bits assigned to BitsType.
      *
-     * @param actualPath
-     * @param namespace
-     * @param revision
+     * @param path
      * @param bits
-     *            The bits assigned for Bits Type
      */
     public BitsType(final SchemaPath path, final List<Bit> bits) {
         super();
@@ -159,12 +158,10 @@ public final class BitsType implements BitsTypeDefinition {
         final int prime = 31;
         int result = 1;
         result = prime * result + ((bits == null) ? 0 : bits.hashCode());
-        result = prime * result
-                + ((description == null) ? 0 : description.hashCode());
+        result = prime * result + ((description == null) ? 0 : description.hashCode());
         result = prime * result + ((name == null) ? 0 : name.hashCode());
         result = prime * result + ((path == null) ? 0 : path.hashCode());
-        result = prime * result
-                + ((reference == null) ? 0 : reference.hashCode());
+        result = prime * result + ((reference == null) ? 0 : reference.hashCode());
         result = prime * result + ((units == null) ? 0 : units.hashCode());
         return result;
     }
index 14e440df029f1bb71b901a647d12c2cf548b617e..f12331cbb296565602f0a7902ae00e86b2bc4f50 100644 (file)
@@ -41,7 +41,7 @@
               org.apache.felix.dm
             </Import-Package>
             <Export-Package>
-              org.opendaylight.controller.sample.simpleforwarding
+              org.opendaylight.controller.samples.simpleforwarding
             </Export-Package>
             <Bundle-Activator>
               org.opendaylight.controller.samples.simpleforwarding.internal.Activator
index 7fd9bc17d1e4cf05c1a69d0bb169d3e6168ee90a..c24c93c65ddaa738136c065713461fe62e659b4c 100644 (file)
@@ -58,7 +58,6 @@ 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;
@@ -94,13 +93,15 @@ CommandProvider {
     private String subnetFileName = null, spanFileName = null,
             switchConfigFileName = null;
     private final List<NodeConnector> spanNodeConnectors = new CopyOnWriteArrayList<NodeConnector>();
-    private ConcurrentMap<InetAddress, Subnet> subnets; // set of Subnets keyed by the InetAddress
+    // set of Subnets keyed by the InetAddress
+    private ConcurrentMap<InetAddress, Subnet> subnets;
     private ConcurrentMap<String, SubnetConfig> subnetsConfigList;
     private ConcurrentMap<SpanConfig, SpanConfig> spanConfigList;
-    private ConcurrentMap<String, SwitchConfig> nodeConfigList; // manually configured parameters for the node like name and tier
+    // manually configured parameters for the node such as name, tier, mode
+    private ConcurrentMap<String, SwitchConfig> nodeConfigList;
     private ConcurrentMap<Long, String> configSaveEvent;
-    private ConcurrentMap<Node, Map<String, Property>> nodeProps; // properties are maintained in global container only
-    private ConcurrentMap<NodeConnector, Map<String, Property>> nodeConnectorProps; // properties are maintained in global container only
+    private ConcurrentMap<Node, Map<String, Property>> nodeProps;
+    private ConcurrentMap<NodeConnector, Map<String, Property>> nodeConnectorProps;
     private ConcurrentMap<Node, Map<String, NodeConnector>> nodeConnectorNames;
     private IInventoryService inventoryService;
     private final Set<ISwitchManagerAware> switchManagerAware = Collections
@@ -663,40 +664,30 @@ CommandProvider {
             modeChange = true;
         }
 
-        try {
-            String nodeId = cfgObject.getNodeId();
-            Node node = Node.fromString(nodeId);
-            Map<String, Property> propMapCurr = nodeProps.get(node);
-            Map<String, Property> propMap = new HashMap<String, Property>();
-            if (propMapCurr != null) {
-                for (String s : propMapCurr.keySet()) {
-                    propMap.put(s, propMapCurr.get(s).clone());
-                }
-            }
-            Property desc = new Description(cfgObject.getNodeDescription());
-            propMap.put(desc.getName(), desc);
-            Property tier = new Tier(Integer.parseInt(cfgObject.getTier()));
-            propMap.put(tier.getName(), tier);
+        String nodeId = cfgObject.getNodeId();
+        Node node = Node.fromString(nodeId);
+        Map<String, Property> propMapCurr = nodeProps.get(node);
+        if (propMapCurr == null) {
+            return;
+        }
+        Map<String, Property> propMap = new HashMap<String, Property>();
+        for (String s : propMapCurr.keySet()) {
+            propMap.put(s, propMapCurr.get(s).clone());
+        }
+        Property desc = new Description(cfgObject.getNodeDescription());
+        propMap.put(desc.getName(), desc);
+        Property tier = new Tier(Integer.parseInt(cfgObject.getTier()));
+        propMap.put(tier.getName(), tier);
 
-            if (propMapCurr == null) {
-                if (nodeProps.putIfAbsent(node, propMap) != null) {
-                    // TODO rollback using Transactionality
-                    return;
-                }
-            } else {
-                if (!nodeProps.replace(node, propMapCurr, propMap)) {
-                    // TODO rollback using Transactionality
-                    return;
-                }
-            }
+        if (!nodeProps.replace(node, propMapCurr, propMap)) {
+            // TODO rollback using Transactionality
+            return;
+        }
 
-            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());
-            }
-        } catch (Exception e) {
-            log.debug("updateSwitchConfig: {}", e.getMessage());
+        if (modeChange) {
+            notifyModeChange(node, cfgObject.isProactive());
         }
     }
 
@@ -888,10 +879,8 @@ CommandProvider {
         }
 
         // copy node properties from plugin
-        if (props != null) {
-            for (Property prop : props) {
-                propMap.put(prop.getName(), prop);
-            }
+        for (Property prop : props) {
+            propMap.put(prop.getName(), prop);
         }
 
         if (propMapCurr == null) {
@@ -934,7 +923,6 @@ CommandProvider {
     @Override
     public void updateNodeConnector(NodeConnector nodeConnector,
             UpdateType type, Set<Property> props) {
-        Node node = nodeConnector.getNode();
         Map<String, Property> propMap = new HashMap<String, Property>();
 
         log.debug("updateNodeConnector: {} type {} props {} for container {}",
@@ -954,14 +942,12 @@ CommandProvider {
                 }
             } else {
                 addNodeConnectorProp(nodeConnector, null);
-                addNodeProps(node, null);
             }
 
             addSpanPort(nodeConnector);
             break;
         case REMOVED:
             removeNodeConnectorAllProps(nodeConnector);
-            removeNodeProps(node);
 
             // clean up span config
             removeSpanPort(nodeConnector);
@@ -990,23 +976,15 @@ CommandProvider {
      */
     @Override
     public Map<String, Property> getNodeProps(Node node) {
-        if (isDefaultContainer) {
-            Map<String, Property> rv = null;
-            if (this.nodeProps != null) {
-                rv = this.nodeProps.get(node);
-                if (rv != null) {
-                    /* make a copy of it */
-                    rv = new HashMap<String, Property>(rv);
-                }
+        Map<String, Property> rv = new HashMap<String, Property>();
+        if (this.nodeProps != null) {
+            rv = this.nodeProps.get(node);
+            if (rv != null) {
+                /* make a copy of it */
+                rv = new HashMap<String, Property>(rv);
             }
-            return rv;
-        } else {
-            // get it from default container
-            ISwitchManager defaultSwitchManager = (ISwitchManager) ServiceHelper
-                    .getInstance(ISwitchManager.class,
-                            GlobalConstants.DEFAULT.toString(), this);
-            return defaultSwitchManager.getNodeProps(node);
         }
+        return rv;
     }
 
     @Override
@@ -1036,7 +1014,7 @@ CommandProvider {
                 return;
             }
             if (!propMapCurr.get(prop.getName()).equals(nodeProps.get(node).get(prop.getName()))) {
-                log.warn("Cluster conflict: Unable to add property {} to node {}.", prop.getName(), node.getID());
+                log.debug("Cluster conflict: Unable to add property {} to node {}.", prop.getName(), node.getID());
                 return;
             }
         }
@@ -1135,24 +1113,15 @@ CommandProvider {
     }
 
     @Override
-    public Map<String, Property> getNodeConnectorProps(
-            NodeConnector nodeConnector) {
-        if (isDefaultContainer) {
-            Map<String, Property> rv = null;
-            if (this.nodeConnectorProps != null) {
-                rv = this.nodeConnectorProps.get(nodeConnector);
-                if (rv != null) {
-                    rv = new HashMap<String, Property>(rv);
-                }
+    public Map<String, Property> getNodeConnectorProps(NodeConnector nodeConnector) {
+        Map<String, Property> rv = new HashMap<String, Property>();
+        if (this.nodeConnectorProps != null) {
+            rv = this.nodeConnectorProps.get(nodeConnector);
+            if (rv != null) {
+                rv = new HashMap<String, Property>(rv);
             }
-            return rv;
-        } else {
-            // get it from default container
-            ISwitchManager defaultSwitchManager = (ISwitchManager) ServiceHelper
-                    .getInstance(ISwitchManager.class,
-                            GlobalConstants.DEFAULT.toString(), this);
-            return defaultSwitchManager.getNodeConnectorProps(nodeConnector);
         }
+        return rv;
     }
 
     @Override
index f485fdd0dbf140e3c4ac51beb7fec0cc5ddce48a..1b1e6f49d153d3b57ccfeb8e120bf2c3d6c7581d 100644 (file)
 package org.opendaylight.controller.topologymanager;
 
 import java.io.Serializable;
-import java.util.ArrayList;
-import java.util.List;
+
 import javax.xml.bind.annotation.XmlAccessType;
 import javax.xml.bind.annotation.XmlAccessorType;
 import javax.xml.bind.annotation.XmlElement;
 import javax.xml.bind.annotation.XmlRootElement;
 
-import org.apache.commons.lang3.builder.HashCodeBuilder;
-import org.opendaylight.controller.sal.core.Node;
-import org.opendaylight.controller.sal.core.Node.NodeIDType;
-import org.opendaylight.controller.sal.core.NodeConnector.NodeConnectorIDType;
 import org.opendaylight.controller.sal.core.NodeConnector;
-import org.opendaylight.controller.sal.utils.GUIField;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -129,7 +123,7 @@ public class TopologyUserLinkConfig implements Serializable {
 
         if (!isValidNodeConnector(srcNodeConnector) ||
                 !isValidNodeConnector(dstNodeConnector)) {
-            logger.warn("Invalid NodeConnector");
+            logger.debug("Invalid NodeConnector in user link: {}", this);
             return false;
         }
 
index d0d9bfaa5ea144256dceeaae179e9ebef43e6221..0da1a2ee39ab73255aca9149095f15ceb6ac8c45 100644 (file)
@@ -9,8 +9,12 @@
 
 package org.opendaylight.controller.topologymanager.internal;
 
-import org.apache.felix.dm.Component;
+import java.util.Dictionary;
+import java.util.HashSet;
+import java.util.Hashtable;
+import java.util.Set;
 
+import org.apache.felix.dm.Component;
 import org.opendaylight.controller.clustering.services.IClusterContainerServices;
 import org.opendaylight.controller.configuration.IConfigurationContainerAware;
 import org.opendaylight.controller.sal.core.ComponentActivatorAbstractBase;
@@ -74,9 +78,14 @@ public class Activator extends ComponentActivatorAbstractBase {
     public void configureInstance(Component c, Object imp, String containerName) {
         if (imp.equals(TopologyManagerImpl.class)) {
             // export the service needed to listen to topology updates
+            Dictionary<String, Set<String>> props = new Hashtable<String, Set<String>>();
+            Set<String> propSet = new HashSet<String>();
+            propSet.add("topologymanager.configSaveEvent");
+            props.put("cachenames", propSet);
+
             c.setInterface(new String[] { IListenTopoUpdates.class.getName(),
                     ITopologyManager.class.getName(),
-                    IConfigurationContainerAware.class.getName() }, null);
+                    IConfigurationContainerAware.class.getName() }, props);
 
             c.add(createContainerServiceDependency(containerName).setService(
                     ITopologyService.class).setCallbacks("setTopoService",
index ce39fed5fcc4960efff1d8959335ced6be066893..a043cbe92595ff011483296bc1fc27be6bb7a9ee 100644 (file)
@@ -12,7 +12,7 @@ import java.io.FileNotFoundException;
 import java.io.IOException;
 import java.io.ObjectInputStream;
 import java.util.ArrayList;
-import java.util.Collections;
+import java.util.Date;
 import java.util.Dictionary;
 import java.util.EnumSet;
 import java.util.HashMap;
@@ -23,6 +23,7 @@ import java.util.Map;
 import java.util.Set;
 import java.util.concurrent.ConcurrentHashMap;
 import java.util.concurrent.ConcurrentMap;
+import java.util.concurrent.CopyOnWriteArraySet;
 
 import org.apache.commons.lang3.tuple.ImmutablePair;
 import org.apache.felix.dm.Component;
@@ -65,31 +66,34 @@ import org.slf4j.LoggerFactory;
 public class TopologyManagerImpl implements ITopologyManager,
 IConfigurationContainerAware, IListenTopoUpdates, IObjectReader,
 CommandProvider {
-    private static final Logger log = LoggerFactory
-            .getLogger(TopologyManagerImpl.class);
-    private ITopologyService topoService = null;
-    private IClusterContainerServices clusterContainerService = null;
+    private static final Logger log = LoggerFactory.getLogger(TopologyManagerImpl.class);
+    private static final String SAVE = "Save";
+    private ITopologyService topoService;
+    private IClusterContainerServices clusterContainerService;
     // DB of all the Edges with properties which constitute our topology
-    private ConcurrentMap<Edge, Set<Property>> edgesDB = null;
+    private ConcurrentMap<Edge, Set<Property>> edgesDB;
     // DB of all NodeConnector which are part of ISL Edges, meaning they
     // are connected to another NodeConnector on the other side of an ISL link.
     // NodeConnector of a Production Edge is not part of this DB.
-    private ConcurrentMap<NodeConnector, Set<Property>> nodeConnectorsDB = null;
+    private ConcurrentMap<NodeConnector, Set<Property>> nodeConnectorsDB;
     // DB of all the NodeConnectors with an Host attached to it
-    private ConcurrentMap<NodeConnector, ImmutablePair<Host, Set<Property>>> hostsDB = null;
+    private ConcurrentMap<NodeConnector, ImmutablePair<Host, Set<Property>>> hostsDB;
     // Topology Manager Aware listeners
-    private Set<ITopologyManagerAware> topologyManagerAware = Collections
-            .synchronizedSet(new HashSet<ITopologyManagerAware>());
+    private Set<ITopologyManagerAware> topologyManagerAware =
+            new CopyOnWriteArraySet<ITopologyManagerAware>();;
 
     private static String ROOT = GlobalConstants.STARTUPHOME.toString();
-    private String userLinksFileName = null;
-    private ConcurrentMap<String, TopologyUserLinkConfig> userLinks;
+    private String userLinksFileName;
+    private ConcurrentMap<String, TopologyUserLinkConfig> userLinksDB;
+    private ConcurrentMap<Long, String> configSaveEvent;
+
 
     void nonClusterObjectCreate() {
         edgesDB = new ConcurrentHashMap<Edge, Set<Property>>();
         hostsDB = new ConcurrentHashMap<NodeConnector, ImmutablePair<Host, Set<Property>>>();
-        userLinks = new ConcurrentHashMap<String, TopologyUserLinkConfig>();
         nodeConnectorsDB = new ConcurrentHashMap<NodeConnector, Set<Property>>();
+        userLinksDB = new ConcurrentHashMap<String, TopologyUserLinkConfig>();
+        configSaveEvent = new ConcurrentHashMap<Long, String>();
     }
 
     void setTopologyManagerAware(ITopologyManagerAware s) {
@@ -136,8 +140,12 @@ CommandProvider {
      *
      */
     void init(Component c) {
+
+        allocateCaches();
+        retrieveCaches();
+
         String containerName = null;
-        Dictionary props = c.getServiceProperties();
+        Dictionary<?, ?> props = c.getServiceProperties();
         if (props != null) {
             containerName = (String) props.get("containerName");
         } else {
@@ -145,57 +153,103 @@ CommandProvider {
             containerName = "UNKNOWN";
         }
 
-        if (this.clusterContainerService == null) {
-            log.error("Cluster Services is null, not expected!");
-            return;
-        }
+        userLinksFileName = ROOT + "userTopology_" + containerName + ".conf";
+        registerWithOSGIConsole();
+        loadConfiguration();
+    }
 
-        if (this.topoService == null) {
-            log.error("Topology Services is null, not expected!");
+    @SuppressWarnings({ "unchecked", "deprecation" })
+    private void allocateCaches(){
+        if (this.clusterContainerService == null) {
+            nonClusterObjectCreate();
+            log.error("Cluster Services unavailable, allocated non-cluster caches!");
             return;
         }
 
         try {
-            this.edgesDB = (ConcurrentMap<Edge, Set<Property>>) this.clusterContainerService
-                    .createCache("topologymanager.edgesDB", EnumSet
-                            .of(IClusterServices.cacheMode.NON_TRANSACTIONAL));
+            this.edgesDB = (ConcurrentMap<Edge, Set<Property>>) this.clusterContainerService.createCache(
+                    "topologymanager.edgesDB", EnumSet.of(IClusterServices.cacheMode.NON_TRANSACTIONAL));
         } catch (CacheExistException cee) {
-            log.error("topologymanager.edgesDB Cache already exists - "
-                    + "destroy and recreate if needed");
+            log.debug("topologymanager.edgesDB Cache already exists - destroy and recreate if needed");
         } catch (CacheConfigException cce) {
-            log.error("topologymanager.edgesDB Cache configuration invalid - "
-                    + "check cache mode");
+            log.error("topologymanager.edgesDB Cache configuration invalid - check cache mode");
         }
 
         try {
             this.hostsDB = (ConcurrentMap<NodeConnector, ImmutablePair<Host, Set<Property>>>) this.clusterContainerService
-                    .createCache("topologymanager.hostsDB", EnumSet
-                            .of(IClusterServices.cacheMode.NON_TRANSACTIONAL));
+                    .createCache("topologymanager.hostsDB", EnumSet.of(IClusterServices.cacheMode.NON_TRANSACTIONAL));
         } catch (CacheExistException cee) {
-            log.error("topologymanager.hostsDB Cache already exists - "
-                    + "destroy and recreate if needed");
+            log.debug("topologymanager.hostsDB Cache already exists - destroy and recreate if needed");
         } catch (CacheConfigException cce) {
-            log.error("topologymanager.hostsDB Cache configuration invalid - "
-                    + "check cache mode");
+            log.error("topologymanager.hostsDB Cache configuration invalid - check cache mode");
         }
 
         try {
             this.nodeConnectorsDB = (ConcurrentMap<NodeConnector, Set<Property>>) this.clusterContainerService
-                    .createCache("topologymanager.nodeConnectorDB", EnumSet
-                            .of(IClusterServices.cacheMode.NON_TRANSACTIONAL));
+                    .createCache("topologymanager.nodeConnectorDB", EnumSet.of(IClusterServices.cacheMode.NON_TRANSACTIONAL));
         } catch (CacheExistException cee) {
-            log.error("topologymanager.nodeConnectorDB Cache already exists"
-                    + " - destroy and recreate if needed");
+            log.debug("topologymanager.nodeConnectorDB Cache already exists - destroy and recreate if needed");
         } catch (CacheConfigException cce) {
-            log.error("topologymanager.nodeConnectorDB Cache configuration "
-                    + "invalid - check cache mode");
+            log.error("topologymanager.nodeConnectorDB Cache configuration invalid - check cache mode");
         }
 
-        userLinks = new ConcurrentHashMap<String, TopologyUserLinkConfig>();
+        try {
+            this.userLinksDB = (ConcurrentMap<String, TopologyUserLinkConfig>) this.clusterContainerService
+                    .createCache("topologymanager.userLinksDB", EnumSet.of(IClusterServices.cacheMode.NON_TRANSACTIONAL));
+        } catch (CacheExistException cee) {
+            log.debug("topologymanager.userLinksDB Cache already exists - destroy and recreate if needed");
+        } catch (CacheConfigException cce) {
+            log.error("topologymanager.userLinksDB Cache configuration invalid - check cache mode");
+        }
+
+        try {
+            this.configSaveEvent = (ConcurrentMap<Long, String>) this.clusterContainerService
+                    .createCache("topologymanager.configSaveEvent", EnumSet.of(IClusterServices.cacheMode.NON_TRANSACTIONAL));
+        } catch (CacheExistException cee) {
+            log.debug("topologymanager.configSaveEvent Cache already exists - destroy and recreate if needed");
+        } catch (CacheConfigException cce) {
+            log.error("topologymanager.configSaveEvent Cache configuration invalid - check cache mode");
+        }
+
+    }
+
+    @SuppressWarnings({ "unchecked", "deprecation" })
+    private void retrieveCaches() {
+        if (this.clusterContainerService == null) {
+            log.error("Cluster Services is null, can't retrieve caches.");
+            return;
+        }
+
+        this.edgesDB = (ConcurrentMap<Edge, Set<Property>>) this.clusterContainerService
+                .getCache("topologymanager.edgesDB");
+        if (edgesDB == null) {
+            log.error("Failed to get cache for topologymanager.edgesDB");
+        }
+
+        this.hostsDB = (ConcurrentMap<NodeConnector, ImmutablePair<Host, Set<Property>>>) this.clusterContainerService
+                .getCache("topologymanager.hostsDB");
+        if (hostsDB == null) {
+            log.error("Failed to get cache for topologymanager.hostsDB");
+        }
+
+        this.nodeConnectorsDB = (ConcurrentMap<NodeConnector, Set<Property>>) this.clusterContainerService
+                .getCache("topologymanager.nodeConnectorDB");
+        if (nodeConnectorsDB == null) {
+            log.error("Failed to get cache for topologymanager.nodeConnectorDB");
+        }
+
+        this.userLinksDB = (ConcurrentMap<String, TopologyUserLinkConfig>) this.clusterContainerService
+                .getCache("topologymanager.userLinksDB");
+        if (userLinksDB == null) {
+            log.error("Failed to get cache for topologymanager.userLinksDB");
+        }
+
+        this.configSaveEvent = (ConcurrentMap<Long, String>) this.clusterContainerService
+                .getCache("topologymanager.configSaveEvent");
+        if (configSaveEvent == null) {
+            log.error("Failed to get cache for topologymanager.configSaveEvent");
+        }
 
-        userLinksFileName = ROOT + "userTopology_" + containerName + ".conf";
-        registerWithOSGIConsole();
-        loadConfiguration();
     }
 
     /**
@@ -217,62 +271,38 @@ CommandProvider {
      *
      */
     void destroy() {
-        if (this.clusterContainerService == null) {
-            log.error("Cluster Services is null, not expected!");
-            this.edgesDB = null;
-            this.hostsDB = null;
-            this.nodeConnectorsDB = null;
-            return;
-        }
-        this.clusterContainerService.destroyCache("topologymanager.edgesDB");
-        this.edgesDB = null;
-        this.clusterContainerService.destroyCache("topologymanager.hostsDB");
-        this.hostsDB = null;
-        this.clusterContainerService
-        .destroyCache("topologymanager.nodeConnectorDB");
-        this.nodeConnectorsDB = null;
-        log.debug("Topology Manager DB Deallocated");
     }
 
     @SuppressWarnings("unchecked")
     private void loadConfiguration() {
         ObjectReader objReader = new ObjectReader();
-        ConcurrentMap<String, TopologyUserLinkConfig> confList = (ConcurrentMap<String, TopologyUserLinkConfig>) objReader
-                .read(this, userLinksFileName);
-
-        if (confList == null) {
-            return;
-        }
+        ConcurrentMap<String, TopologyUserLinkConfig> confList =
+                (ConcurrentMap<String, TopologyUserLinkConfig>) objReader.read(this, userLinksFileName);
 
-        for (TopologyUserLinkConfig conf : confList.values()) {
-            addUserLink(conf);
+        if (confList != null) {
+            for (TopologyUserLinkConfig conf : confList.values()) {
+                addUserLink(conf);
+            }
         }
     }
 
     @Override
     public Status saveConfig() {
-        // Publish the save config event to the cluster nodes
-        /**
-         * Get the CLUSTERING SERVICES WORKING BEFORE TRYING THIS
-         *
-         * configSaveEvent.put(new Date().getTime(), SAVE);
-         */
+        // Publish the save config event to the cluster
+        configSaveEvent.put(new Date().getTime(), SAVE );
         return saveConfigInternal();
     }
 
     public Status saveConfigInternal() {
-        Status retS;
         ObjectWriter objWriter = new ObjectWriter();
 
-        retS = objWriter
-                .write(new ConcurrentHashMap<String, TopologyUserLinkConfig>(
-                        userLinks), userLinksFileName);
+        Status saveStatus = objWriter.write(
+                new ConcurrentHashMap<String, TopologyUserLinkConfig>(userLinksDB), userLinksFileName);
 
-        if (retS.isSuccess()) {
-            return retS;
-        } else {
-            return new Status(StatusCode.INTERNALERROR, "Save failed");
+        if (! saveStatus.isSuccess()) {
+            return new Status(StatusCode.INTERNALERROR, "Topology save failed: " + saveStatus.getDescription());
         }
+        return saveStatus;
     }
 
     @Override
@@ -281,31 +311,25 @@ CommandProvider {
             return null;
         }
 
-        HashMap<Node, Set<Edge>> res = new HashMap<Node, Set<Edge>>();
-        for (Edge key : this.edgesDB.keySet()) {
+        Map<Node, Set<Edge>> res = new HashMap<Node, Set<Edge>>();
+        for (Edge edge : this.edgesDB.keySet()) {
             // Lets analyze the tail
-            Node node = key.getTailNodeConnector().getNode();
+            Node node = edge.getTailNodeConnector().getNode();
             Set<Edge> nodeEdges = res.get(node);
             if (nodeEdges == null) {
                 nodeEdges = new HashSet<Edge>();
+                res.put(node, nodeEdges);
             }
-            nodeEdges.add(key);
-            // We need to re-add to the MAP even if the element was
-            // already there so in case of clustered services the map
-            // gets updated in the cluster
-            res.put(node, nodeEdges);
+            nodeEdges.add(edge);
 
             // Lets analyze the head
-            node = key.getHeadNodeConnector().getNode();
+            node = edge.getHeadNodeConnector().getNode();
             nodeEdges = res.get(node);
             if (nodeEdges == null) {
                 nodeEdges = new HashSet<Edge>();
+                res.put(node, nodeEdges);
             }
-            nodeEdges.add(key);
-            // We need to re-add to the MAP even if the element was
-            // already there so in case of clustered services the map
-            // gets updated in the cluster
-            res.put(node, nodeEdges);
+            nodeEdges.add(edge);
         }
 
         return res;
@@ -341,10 +365,8 @@ CommandProvider {
      * @return true if it is a production link
      */
     public boolean isProductionLink(Edge e) {
-        return (e.getHeadNodeConnector().getType()
-                .equals(NodeConnector.NodeConnectorIDType.PRODUCTION) || e
-                .getTailNodeConnector().getType()
-                .equals(NodeConnector.NodeConnectorIDType.PRODUCTION));
+        return (e.getHeadNodeConnector().getType().equals(NodeConnector.NodeConnectorIDType.PRODUCTION)
+                || e.getTailNodeConnector().getType().equals(NodeConnector.NodeConnectorIDType.PRODUCTION));
     }
 
     /**
@@ -360,31 +382,20 @@ CommandProvider {
             return null;
         }
 
-        HashMap<Edge, Set<Property>> res = new HashMap<Edge, Set<Property>>();
-        for (Edge key : this.edgesDB.keySet()) {
+        Map<Edge, Set<Property>> edgeMap = new HashMap<Edge, Set<Property>>();
+        Set<Property> props;
+        for (Map.Entry<Edge, Set<Property>> edgeEntry : edgesDB.entrySet()) {
             // Sets of props are copied because the composition of
             // those properties could change with time
-            HashSet<Property> prop = new HashSet<Property>(
-                    this.edgesDB.get(key));
+            props = new HashSet<Property>(edgeEntry.getValue());
             // We can simply reuse the key because the object is
             // immutable so doesn't really matter that we are
             // referencing the only owned by a different table, the
             // meaning is the same because doesn't change with time.
-            res.put(key, prop);
+            edgeMap.put(edgeEntry.getKey(), props);
         }
 
-        return res;
-    }
-
-    // TODO remove with spring-dm removal
-    /**
-     * @param set
-     *            the topologyAware to set
-     */
-    public void setTopologyAware(Set<Object> set) {
-        for (Object s : set) {
-            setTopologyManagerAware((ITopologyManagerAware) s);
-        }
+        return edgeMap;
     }
 
     @Override
@@ -393,7 +404,7 @@ CommandProvider {
             return null;
         }
 
-        return (this.hostsDB.keySet());
+        return (new HashSet<NodeConnector>(this.hostsDB.keySet()));
     }
 
     @Override
@@ -402,90 +413,92 @@ CommandProvider {
             return null;
         }
         HashMap<Node, Set<NodeConnector>> res = new HashMap<Node, Set<NodeConnector>>();
-
-        for (NodeConnector p : this.hostsDB.keySet()) {
-            Node n = p.getNode();
-            Set<NodeConnector> pSet = res.get(n);
-            if (pSet == null) {
+        Node node;
+        Set<NodeConnector> portSet;
+        for (NodeConnector nc : this.hostsDB.keySet()) {
+            node = nc.getNode();
+            portSet = res.get(node);
+            if (portSet == null) {
                 // Create the HashSet if null
-                pSet = new HashSet<NodeConnector>();
-                res.put(n, pSet);
+                portSet = new HashSet<NodeConnector>();
+                res.put(node, portSet);
             }
 
             // Keep updating the HashSet, given this is not a
             // clustered map we can just update the set without
             // worrying to update the hashmap.
-            pSet.add(p);
+            portSet.add(nc);
         }
 
         return (res);
     }
 
     @Override
-    public Host getHostAttachedToNodeConnector(NodeConnector p) {
-        if (this.hostsDB == null) {
+    public Host getHostAttachedToNodeConnector(NodeConnector port) {
+        ImmutablePair<Host, Set<Property>> host;
+        if (this.hostsDB == null || (host = this.hostsDB.get(port)) == null) {
             return null;
         }
-        if (this.hostsDB.get(p) == null)
-            return null;
-
-        return (this.hostsDB.get(p).getLeft());
+        return host.getLeft();
     }
 
     @Override
-    public void updateHostLink(NodeConnector p, Host h, UpdateType t,
-            Set<Property> props) {
-        if (this.hostsDB == null) {
-            return;
+    public void updateHostLink(NodeConnector port, Host h, UpdateType t, Set<Property> props) {
+
+        // Clone the property set in case non null else just
+        // create an empty one. Caches allocated via infinispan
+        // don't allow null values
+        if (props == null) {
+            props = new HashSet<Property>();
+        } else {
+            props = new HashSet<Property>(props);
         }
+        ImmutablePair<Host, Set<Property>> thisHost = new ImmutablePair<Host, Set<Property>>(h, props);
 
         switch (t) {
         case ADDED:
         case CHANGED:
-            // Clone the property set in case non null else just
-            // create an empty one. Caches allocated via infinispan
-            // don't allow null values
-            if (props == null) {
-                props = new HashSet<Property>();
-            } else {
-                props = new HashSet<Property>(props);
-            }
-
-            this.hostsDB.put(p, new ImmutablePair(h, props));
+            this.hostsDB.put(port, thisHost);
             break;
         case REMOVED:
-            this.hostsDB.remove(p);
+            //remove only if hasn't been concurrently modified
+            this.hostsDB.remove(port, thisHost);
             break;
         }
     }
 
-    private TopoEdgeUpdate edgeUpdate(Edge e, UpdateType type,
-            Set<Property> props) {
+    private TopoEdgeUpdate edgeUpdate(Edge e, UpdateType type, Set<Property> props) {
         switch (type) {
         case ADDED:
             // Make sure the props are non-null
             if (props == null) {
-                props = (Set<Property>) new HashSet();
+                props = new HashSet<Property>();
             } else {
-                // Copy the set so noone is going to change the content
-                props = (Set<Property>) new HashSet(props);
+                props = new HashSet<Property>(props);
+            }
+
+            //in case of node switch-over to a different cluster controller,
+            //let's retain edge props
+            Set<Property> currentProps = this.edgesDB.get(e);
+            if (currentProps != null){
+                props.addAll(currentProps);
             }
 
             // Now make sure there is the creation timestamp for the
-            // edge, if not there timestamp with the first update
+            // edge, if not therestamp with the first update
             boolean found_create = false;
             for (Property prop : props) {
                 if (prop instanceof TimeStamp) {
                     TimeStamp t = (TimeStamp) prop;
                     if (t.getTimeStampName().equals("creation")) {
                         found_create = true;
+                        break;
                     }
                 }
             }
 
             if (!found_create) {
-                TimeStamp t = new TimeStamp(System.currentTimeMillis(),
-                        "creation");
+                TimeStamp t = new TimeStamp(System.currentTimeMillis(), "creation");
                 props.add(t);
             }
 
@@ -498,10 +511,8 @@ CommandProvider {
             // for now.
             // The DB only contains ISL ports
             if (isISLink(e)) {
-                this.nodeConnectorsDB.put(e.getHeadNodeConnector(),
-                        new HashSet<Property>());
-                this.nodeConnectorsDB.put(e.getTailNodeConnector(),
-                        new HashSet<Property>());
+                this.nodeConnectorsDB.put(e.getHeadNodeConnector(), new HashSet<Property>(1));
+                this.nodeConnectorsDB.put(e.getTailNodeConnector(), new HashSet<Property>(1));
             }
             log.trace("Edge {}  {}", e.toString(), type.name());
             break;
@@ -521,29 +532,29 @@ CommandProvider {
             log.trace("Edge {}  {}", e.toString(), type.name());
             break;
         case CHANGED:
-            Set<Property> old_props = this.edgesDB.get(e);
+            Set<Property> oldProps = this.edgesDB.get(e);
 
             // When property changes lets make sure we can change it
             // all except the creation time stamp because that should
             // be changed only when the edge is destroyed and created
             // again
-            TimeStamp tc = null;
-            for (Property prop : old_props) {
+            TimeStamp timeStamp = null;
+            for (Property prop : oldProps) {
                 if (prop instanceof TimeStamp) {
-                    TimeStamp t = (TimeStamp) prop;
-                    if (t.getTimeStampName().equals("creation")) {
-                        tc = t;
+                    TimeStamp tsProp = (TimeStamp) prop;
+                    if (tsProp.getTimeStampName().equals("creation")) {
+                        timeStamp = tsProp;
+                        break;
                     }
                 }
             }
 
             // Now lets make sure new properties are non-null
-            // Make sure the props are non-null
             if (props == null) {
-                props = (Set<Property>) new HashSet();
+                props = new HashSet<Property>();
             } else {
                 // Copy the set so noone is going to change the content
-                props = (Set<Property>) new HashSet(props);
+                props = new HashSet<Property>(props);
             }
 
             // Now lets remove the creation property if exist in the
@@ -554,13 +565,14 @@ CommandProvider {
                     TimeStamp t = (TimeStamp) prop;
                     if (t.getTimeStampName().equals("creation")) {
                         i.remove();
+                        break;
                     }
                 }
             }
 
             // Now lets add the creation timestamp in it
-            if (tc != null) {
-                props.add(tc);
+            if (timeStamp != null) {
+                props.add(timeStamp);
             }
 
             // Finally update
@@ -587,7 +599,7 @@ CommandProvider {
             try {
                 s.edgeUpdate(teuList);
             } catch (Exception exc) {
-                log.error("Exception on callback", exc);
+                log.error("Exception on edge update:", exc);
             }
         }
 
@@ -601,79 +613,78 @@ CommandProvider {
 
 
     private Edge getLinkTuple(TopologyUserLinkConfig link) {
-        Edge linkTuple = null;
         NodeConnector srcNodeConnector = NodeConnector.fromString(link.getSrcNodeConnector());
         NodeConnector dstNodeConnector = NodeConnector.fromString(link.getDstNodeConnector());
-        if (srcNodeConnector == null || dstNodeConnector == null) return null;
         try {
-            linkTuple = new Edge(srcNodeConnector, dstNodeConnector);
+            return new Edge(srcNodeConnector, dstNodeConnector);
         } catch (Exception e) {
+            return null;
         }
-        return linkTuple;
     }
 
     @Override
     public ConcurrentMap<String, TopologyUserLinkConfig> getUserLinks() {
-        return userLinks;
+        return new ConcurrentHashMap<String, TopologyUserLinkConfig>(userLinksDB);
     }
 
     @Override
-    public Status addUserLink(TopologyUserLinkConfig link) {
-        if (!link.isValid()) {
+    public Status addUserLink(TopologyUserLinkConfig userLink) {
+        if (!userLink.isValid()) {
             return new Status(StatusCode.BADREQUEST,
-                    "Configuration Invalid. Please check the parameters");
+                    "User link configuration invalid.");
         }
-        if (userLinks.get(link.getName()) != null) {
-            return new Status(StatusCode.CONFLICT, "Link with name : "
-                    + link.getName()
-                    + " already exists. Please use another name");
+        userLink.setStatus(TopologyUserLinkConfig.STATUS.LINKDOWN);
+
+        //Check if this link already configured
+        //NOTE: infinispan cache doesn't support Map.containsValue()
+        // (which is linear time in most ConcurrentMap impl anyway)
+        for (TopologyUserLinkConfig existingLink : userLinksDB.values()) {
+            if (existingLink.equals(userLink)) {
+                return new Status(StatusCode.CONFLICT, "Link configuration exists");
+            }
         }
-        if (userLinks.containsValue(link)) {
-            return new Status(StatusCode.CONFLICT, "Link configuration exists");
+        //attempt put, if mapping for this key already existed return conflict
+        if (userLinksDB.putIfAbsent(userLink.getName(), userLink) != null) {
+            return new Status(StatusCode.CONFLICT, "Link with name : " + userLink.getName()
+                    + " already exists. Please use another name");
         }
 
-        link.setStatus(TopologyUserLinkConfig.STATUS.LINKDOWN);
-        userLinks.put(link.getName(), link);
-
-        Edge linkTuple = getLinkTuple(link);
+        Edge linkTuple = getLinkTuple(userLink);
         if (linkTuple != null) {
             if (!isProductionLink(linkTuple)) {
                 edgeUpdate(linkTuple, UpdateType.ADDED, new HashSet<Property>());
             }
 
-            linkTuple = getReverseLinkTuple(link);
+            linkTuple = getReverseLinkTuple(userLink);
             if (linkTuple != null) {
-                link.setStatus(TopologyUserLinkConfig.STATUS.SUCCESS);
+                userLink.setStatus(TopologyUserLinkConfig.STATUS.SUCCESS);
                 if (!isProductionLink(linkTuple)) {
                     edgeUpdate(linkTuple, UpdateType.ADDED, new HashSet<Property>());
                 }
             }
         }
-        return new Status(StatusCode.SUCCESS, null);
+        return new Status(StatusCode.SUCCESS);
     }
 
     @Override
     public Status deleteUserLink(String linkName) {
         if (linkName == null) {
-            return new Status(StatusCode.BADREQUEST,
-                    "A valid linkName is required to Delete a link");
+            return new Status(StatusCode.BADREQUEST, "User link name cannot be null.");
         }
 
-        TopologyUserLinkConfig link = userLinks.get(linkName);
-
-        Edge linkTuple = getLinkTuple(link);
-        userLinks.remove(linkName);
-        if (linkTuple != null) {
-            if (!isProductionLink(linkTuple)) {
+        TopologyUserLinkConfig link = userLinksDB.remove(linkName);
+        Edge linkTuple;
+        if (link != null && (linkTuple = getLinkTuple(link)) != null) {
+            if (! isProductionLink(linkTuple)) {
                 edgeUpdate(linkTuple, UpdateType.REMOVED, null);
             }
 
             linkTuple = getReverseLinkTuple(link);
-            if ((linkTuple != null) && !isProductionLink(linkTuple)) {
+            if (isProductionLink(linkTuple)) {
                 edgeUpdate(linkTuple, UpdateType.REMOVED, null);
             }
         }
-        return new Status(StatusCode.SUCCESS, null);
+        return new Status(StatusCode.SUCCESS);
     }
 
     private void registerWithOSGIConsole() {
@@ -695,8 +706,8 @@ CommandProvider {
     }
 
     public void _printUserLink(CommandInterpreter ci) {
-        for (String name : this.userLinks.keySet()) {
-            TopologyUserLinkConfig linkConfig = userLinks.get(name);
+        for (String name : this.userLinksDB.keySet()) {
+            TopologyUserLinkConfig linkConfig = userLinksDB.get(name);
             ci.println("Name : " + name);
             ci.println(linkConfig);
             ci.println("Edge " + getLinkTuple(linkConfig));
@@ -770,7 +781,6 @@ CommandProvider {
     @Override
     public Object readObject(ObjectInputStream ois)
             throws FileNotFoundException, IOException, ClassNotFoundException {
-        // TODO Auto-generated method stub
         return ois.readObject();
     }