Merge "HA - Cache synch for Topology Manager"
authorAlessandro Boch <aboch@cisco.com>
Thu, 18 Jul 2013 18:22:44 +0000 (18:22 +0000)
committerGerrit Code Review <gerrit@opendaylight.org>
Thu, 18 Jul 2013 18:22:44 +0000 (18:22 +0000)
92 files changed:
opendaylight/distribution/opendaylight/src/main/resources/configuration/config.ini
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/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/ExtendedTypedefTest.java [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/samples/maven-code-gen-sample/src/main/yang/typedef_of_typedef.yang [new file with mode: 0644]
opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/main/java/org/opendaylight/controller/yang/parser/builder/api/AbstractBuilder.java [new file with mode: 0644]
opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/main/java/org/opendaylight/controller/yang/parser/builder/api/AbstractDataNodeContainerBuilder.java
opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/main/java/org/opendaylight/controller/yang/parser/builder/api/AbstractSchemaNodeBuilder.java
opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/main/java/org/opendaylight/controller/yang/parser/builder/api/AbstractTypeAwareBuilder.java
opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/main/java/org/opendaylight/controller/yang/parser/builder/api/Builder.java
opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/main/java/org/opendaylight/controller/yang/parser/builder/impl/AnyXmlBuilder.java
opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/main/java/org/opendaylight/controller/yang/parser/builder/impl/AugmentationSchemaBuilderImpl.java
opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/main/java/org/opendaylight/controller/yang/parser/builder/impl/ChoiceBuilder.java
opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/main/java/org/opendaylight/controller/yang/parser/builder/impl/ChoiceCaseBuilder.java
opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/main/java/org/opendaylight/controller/yang/parser/builder/impl/ConstraintsBuilder.java
opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/main/java/org/opendaylight/controller/yang/parser/builder/impl/ContainerSchemaNodeBuilder.java
opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/main/java/org/opendaylight/controller/yang/parser/builder/impl/DeviationBuilder.java
opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/main/java/org/opendaylight/controller/yang/parser/builder/impl/ExtensionBuilder.java
opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/main/java/org/opendaylight/controller/yang/parser/builder/impl/FeatureBuilder.java
opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/main/java/org/opendaylight/controller/yang/parser/builder/impl/GroupingBuilderImpl.java
opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/main/java/org/opendaylight/controller/yang/parser/builder/impl/IdentitySchemaNodeBuilder.java
opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/main/java/org/opendaylight/controller/yang/parser/builder/impl/IdentityrefTypeBuilder.java
opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/main/java/org/opendaylight/controller/yang/parser/builder/impl/LeafListSchemaNodeBuilder.java
opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/main/java/org/opendaylight/controller/yang/parser/builder/impl/LeafSchemaNodeBuilder.java
opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/main/java/org/opendaylight/controller/yang/parser/builder/impl/ListSchemaNodeBuilder.java
opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/main/java/org/opendaylight/controller/yang/parser/builder/impl/ModuleBuilder.java
opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/main/java/org/opendaylight/controller/yang/parser/builder/impl/NotificationBuilder.java
opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/main/java/org/opendaylight/controller/yang/parser/builder/impl/RpcDefinitionBuilder.java
opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/main/java/org/opendaylight/controller/yang/parser/builder/impl/TypeDefinitionBuilderImpl.java
opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/main/java/org/opendaylight/controller/yang/parser/builder/impl/UnionTypeBuilder.java
opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/main/java/org/opendaylight/controller/yang/parser/builder/impl/UnknownSchemaNodeBuilder.java
opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/main/java/org/opendaylight/controller/yang/parser/builder/impl/UsesNodeBuilderImpl.java
opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/main/java/org/opendaylight/controller/yang/parser/impl/YangParserImpl.java
opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/main/java/org/opendaylight/controller/yang/parser/impl/YangParserListenerImpl.java
opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/main/java/org/opendaylight/controller/yang/parser/util/ParserListenerUtils.java
opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/main/java/org/opendaylight/controller/yang/parser/util/ParserUtils.java
opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/main/java/org/opendaylight/controller/yang/parser/util/RefineHolder.java
opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/main/java/org/opendaylight/controller/yang/parser/util/RefineUtils.java
opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/main/java/org/opendaylight/controller/yang/parser/util/TypeConstraints.java
opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/main/java/org/opendaylight/controller/yang/parser/util/YangParseException.java
opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/test/java/org/opendaylight/controller/yang/parser/impl/YangParserNegativeTest.java
opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/test/java/org/opendaylight/controller/yang/parser/impl/YangParserTest.java
opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/test/resources/model/types.yang
opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/test/resources/negative-scenario/duplicity/augment0.yang [new file with mode: 0644]
opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/test/resources/negative-scenario/duplicity/augment1.yang [new file with mode: 0644]
opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/test/resources/negative-scenario/duplicity/augment2.yang [new file with mode: 0644]
opendaylight/sal/yang-prototype/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/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

index 6e8a3555234ef8cd668a048fd299eddac823656e..6bf09bb368678b3be59a652bb192da49df5367e4 100644 (file)
@@ -64,8 +64,8 @@ org.eclipse.gemini.web.tomcat.config.path=configuration/tomcat-server.xml
 # of.discoveryInterval=300
 # 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 10 sec)
-# of.discoveryThreshold=10
+# 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
 
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 ebd5a68341b9caa5cc3166f415c3d0ed212d8bf4..b3cfde9c146983b4ac44f115178d5af16da606a6 100644 (file)
@@ -167,7 +167,7 @@ public class DiscoveryService implements IInventoryShimExternalListener, IDataPa
     public enum DiscoveryPeriod {
         INTERVAL        (300),
         AGEOUT          (120),
-        THRESHOLD       (10);
+        THRESHOLD       (30);
 
         private int time;   // sec
         private int tick;   // tick
index bcaf3a062a754e4ea5303723a4159a3226c75bdb..ec57cb4a3ca73185fe428bd25ccae4b6e0d7d60f 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);
         } else if (typeDef instanceof BitsTypeDefinition) {
-            genTOBuilder = ((TypeProviderImpl) typeProvider).bitsTypedefToTransferObject(
-                    typeBuilder.getPackageName(), typeDef, className);
+            genTOBuilder = ((TypeProviderImpl) typeProvider).bitsTypedefToTransferObject(typeBuilder.getPackageName(),
+                    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/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/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();
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/yang-model-parser-impl/src/main/java/org/opendaylight/controller/yang/parser/builder/api/AbstractBuilder.java b/opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/main/java/org/opendaylight/controller/yang/parser/builder/api/AbstractBuilder.java
new file mode 100644 (file)
index 0000000..786a7ec
--- /dev/null
@@ -0,0 +1,71 @@
+/*
+ * 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 java.util.ArrayList;
+import java.util.List;
+
+import org.opendaylight.controller.yang.model.api.UnknownSchemaNode;
+import org.opendaylight.controller.yang.parser.builder.impl.UnknownSchemaNodeBuilder;
+
+/**
+ * Basic implementation of Builder.
+ */
+public abstract class AbstractBuilder implements Builder {
+    protected String moduleName;
+    protected final int line;
+    protected Builder parent;
+
+    protected List<UnknownSchemaNode> unknownNodes;
+    protected final List<UnknownSchemaNodeBuilder> addedUnknownNodes = new ArrayList<UnknownSchemaNodeBuilder>();
+
+    protected AbstractBuilder(final String moduleName, final int line) {
+        this.moduleName = moduleName;
+        this.line = line;
+    }
+
+    @Override
+    public String getModuleName() {
+        return moduleName;
+    }
+
+    @Override
+    public void setModuleName(final String moduleName) {
+        this.moduleName = moduleName;
+    }
+
+    @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 void setUnknownNodes(List<UnknownSchemaNode> unknownNodes) {
+        this.unknownNodes = unknownNodes;
+    }
+
+}
index df85c5cbf09fe166630da10f8ae5f3347cabd055..d6867ce73592a3a3511e88ef451628cd915602a7 100644 (file)
@@ -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 node '" + qname.getLocalName() + "' 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);
     }
 
 }
index a786cd9ad754c954803937df3b8890d4afa47c05..2727bc95338dea28a4af59f9296b023869ccd7e0 100644 (file)
@@ -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
index 3e8dc6c8b09f6c817c568e90f969789be1c99592..23ded94c4039a6de64a5e797184daf67e1d0d2d3 100644 (file)
@@ -7,46 +7,22 @@
  */
 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.
  */
-public abstract class AbstractTypeAwareBuilder implements TypeAwareBuilder {
-    protected final int line;
+public abstract class AbstractTypeAwareBuilder extends AbstractBuilder implements TypeAwareBuilder {
     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) {
-        this.line = line;
+    public AbstractTypeAwareBuilder(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;
@@ -74,18 +50,4 @@ public abstract class AbstractTypeAwareBuilder implements TypeAwareBuilder {
         this.type = null;
     }
 
-    @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;
-    }
-
 }
index eb23eaba106e68888c754ea3ca87f5d121929d27..b849f20d2fb5c4da004ab11be3c6fa334aba0731 100644 (file)
@@ -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.
      *
index 42f714b8fcc33d741e8ea508f138f2479da3c17f..6b6063cc953a1063758e7a4f1ed7bd304cd20dd7 100644 (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();
index 6d8b78919bb7d9689d98bc5ecb04e8658e4b1bf6..cdb751f81bed1a703a60991d1fb16693bc4b2d11 100644 (file)
@@ -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
index 0fcfd339a583f95eb9fa7570404f3651922e0f58..1cd54cae62ab2a93ba050351fe90388267632bba 100644 (file)
@@ -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,41 @@ 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) {
+        String newCaseName = caseNode.getQName().getLocalName();
+        for (ChoiceCaseBuilder addedCase : addedCases) {
+            if (addedCase.getQName().getLocalName().equals(newCaseName)) {
+                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(),
+                    caseNode.getQName());
+            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(), caseNode.getQName().getLocalName());
+            caseNode.setPath(newPath);
+            caseBuilder.addChildNode(caseNode);
             addedCases.add(caseBuilder);
-        } else {
-            addedCases.add((ChoiceCaseBuilder) childNode);
         }
     }
 
index 46821b2e10cfc0bf3301144092665e6600f0b445..c5282bc0eafd314449612108742f607bc7347f86 100644 (file)
@@ -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
index 5ec825b382072ac642c32a466a040b5ac8ae4030..b2f1dff3a52dacc93e80b54e613c611cd3f787ff 100644 (file)
@@ -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;
index c85c12fcd5f6bcbdd6c593749c9c226bc4c3050c..0bc56d430a97d83d7a2944ddd9938bc3907126d4 100644 (file)
@@ -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);
     }
 
index 42347cbba364b35f1129fe8bfa6e52eac1404864..3bc9879de7213cf919394490098e678bf6b22d22 100644 (file)
@@ -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);
index fbd55ab7d9fda8249b963b654be0bf03bab6aa84..93a34e1050052b9f6e2dab726d89ba9ca42ddd54 100644 (file)
@@ -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);
     }
 
index 53129f100b8622515d759728cd278ef7801d397a..dd3fd11e925246f23373c3490f04cf2260fbd068 100644 (file)
@@ -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);
     }
 
index 20503488ce9802e019c99bd8e46f82e929d7f695..8a8f1211cb474c3894852d566abd6197a34b13f5 100644 (file)
@@ -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();
index 61ad3a74dd264459761537e308acf8c7ebed89e4..2e7c495d9eeebf08bb285f9c4f7493eca580b0c1 100644 (file)
@@ -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);
     }
 
index 43922fa71e80e1080c8f1356bda8dc450e26d781..ca6002930e8bbf7df185cacb3c1674493d4550e0 100644 (file)
@@ -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
index dcbe1dd432a7a1576af19899d60004268cac1f12..8e11ad22170f59da14ce98fb3869fe7ab6eee03a 100644 (file)
@@ -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();
index 2ab6407f256a59cec2e9314f0b3f4f3228532cb9..5c1da11afa29af161628a8374324076c85e66eed 100644 (file)
@@ -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();
index 9fc297e2ba1ce4367034ee13acd0973c5c618d11..5e369d08263909913a10db0458dd739fa0449ebe 100644 (file)
@@ -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);
     }
 
index a3409c5b77c0e64616437ac532512db7f1af6133..f424bcfdf939cfc14b9d9dcd8bd3dc066f0e96bc 100644 (file)
@@ -82,7 +82,7 @@ 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);
     }
@@ -320,85 +320,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);
 
+        String groupingName = qname.getLocalName();
         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());
+            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 +415,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) {
+            // 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,7 +443,7 @@ 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);
@@ -453,13 +463,11 @@ 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 == null) {
             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 {
@@ -467,8 +475,6 @@ public class ModuleBuilder extends AbstractDataNodeContainerBuilder {
             }
             refine.setParent(parent);
         }
-
-        path.add(refine.getName());
     }
 
     public RpcDefinitionBuilder addRpc(final int line, final QName qname) {
@@ -477,148 +483,183 @@ public class ModuleBuilder extends AbstractDataNodeContainerBuilder {
             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) {
+    public ContainerSchemaNodeBuilder addRpcOutput(final SchemaPath schemaPath, final QName qname, final int line) {
         final Builder parent = actualPath.getFirst();
         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) {
+    public NotificationBuilder addNotification(final int line, final QName qname) {
         if (!(actualPath.isEmpty())) {
             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) {
             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) {
             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);
 
+        String typedefName = qname.getLocalName();
         if (parent == null) {
             for (TypeDefinitionBuilder tdb : addedTypedefs) {
-                if (tdb.getQName().getLocalName().equals(builder.getQName().getLocalName())) {
-                    throw new YangParseException(name, builder.getLine(), "Duplicate node found at line "
-                            + tdb.getLine());
+                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 +667,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 +692,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 +705,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;
@@ -686,7 +727,7 @@ public class ModuleBuilder extends AbstractDataNodeContainerBuilder {
             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;
     }
@@ -696,13 +737,15 @@ public class ModuleBuilder extends AbstractDataNodeContainerBuilder {
         if (parent != null) {
             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,7 +758,7 @@ 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);
 
@@ -1083,7 +1126,16 @@ 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 == null => node is defined under module
@@ -1092,18 +1144,21 @@ public class ModuleBuilder extends AbstractDataNodeContainerBuilder {
             // 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 +1168,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 + "'.");
             }
         }
     }
index 14b701fe9eb9dd412a76665bdad0d471e45df1db..eab1cffcebadadc80b09cae88ffa7a1edb11899a 100644 (file)
@@ -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);
     }
 
index 65b15c583b672b30acc0be6531b91209d3202458..53190d0bb6df4ec6b83b57623404674c59a34060 100644 (file)
@@ -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);
     }
 
index 7ff78477637ef2757fc75c28ccd59167d7c5baaa..5f2ca1c028388c2273c13aa5d73ef5dd8dac2949 100644 (file)
@@ -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();
index fac500194407563d0c1cf623f415c4ac0b6a5ec8..6c57c25b988949587a68a878b9357fbd290f2a73 100644 (file)
@@ -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
index 267696bdae8383fbd911d3fd6488f372cc3f0a9b..e7b344b6fdce0a7da29563ce0d64563b2231f865 100644 (file)
@@ -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();
index 3b1eb33d3940b86187848d9cd2cd08397ecae963..ee07e8be4603ac99d14f68f2c0fbaf33abc97db6 100644 (file)
@@ -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
index 7d64b944219d122ad84d157cd383eb054bb02b10..0c1f5e27dddfe036a4b6fe6b562198508fecf67c 100644 (file)
@@ -921,7 +921,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);
                     }
@@ -1053,7 +1053,8 @@ 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 usesNode
      * @param targetGrouping
@@ -1088,7 +1089,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.");
                 }
 
@@ -1127,6 +1128,7 @@ public final class YangParserImpl implements YangModelParser {
     }
 
     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();
@@ -1143,21 +1145,21 @@ public final class YangParserImpl implements YangModelParser {
 
                 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.");
                 }
 
@@ -1169,13 +1171,13 @@ public final class YangParserImpl implements YangModelParser {
             }
         }
         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()));
             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()));
             parent.addTypedef(newType);
@@ -1189,7 +1191,7 @@ 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()));
             parent.addUnknownNodeBuilder(newNode);
index 155deced668e9bb19462c64eab3c752fd7ee1acb..77ac8a56201709baaa3f163476467d11412c1c97 100644 (file)
@@ -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();
@@ -528,8 +528,8 @@ public final class YangParserListenerImpl extends YangParserBaseListener {
         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 +699,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 +787,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);
 
index 5f291d74a3d0325e9d00994e635bbe4418e6e105..d2ca3a7695b57d9a3298d1c651fc83e01b0ef113 100644 (file)
@@ -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);
             }
         }
index 587c8bed4ef19272ce420e92d0ffca1b6aef0a1f..25232796cc9c3ba15307cf496b7ccc10ca6157f2 100644 (file)
@@ -482,7 +482,7 @@ public final class ParserUtils {
                 }
             }
             correctAugmentChildPath(builder, target.getPath());
-            target.addChildNode(builder);
+            target.addCase(builder);
         }
     }
 
@@ -750,8 +750,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 +764,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 +779,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 +793,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 +804,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 +814,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 +836,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 +855,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());
@@ -1084,7 +1086,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 +1123,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());
index 44bb56be1c1e9b51e986661ba74b9527d6ed5abf..9e57d80aa9fe60991a2b2644e4244bc9b7ca8424 100644 (file)
@@ -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;
     }
 
 }
index 69c90caadf95178d15cfcb1d93008d485c010812..11d00cc05c7c59de00c9513ef22877d1bbc56d80 100644 (file)
@@ -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) {
index 4d2c5b582321c907860b801edeb57499a2ab9f6b..08422c839242e079dcf49392b3eb049a6cd54b04 100644 (file)
@@ -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();
index c9fd7235599b968b7f5f9dcef7fdc4d1a6b371e2..6939261a5701477676092acc5c2a4f8416ea8e98 100644 (file)
@@ -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);
     }
 
index fb73bd6e5b7eb6937ce95e9fd70bb4450b8bc955..0412013405c5ac8c317bb169fe28f359496a26f2 100644 (file)
@@ -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 node '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());
         }
     }
 
index f2478e741dddeb3dd65db2740f334e599ffe0274..83109ea9b1b590e2e4accef06bdf1bc6ceb874fe 100644 (file)
@@ -195,7 +195,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");
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/code-generator/yang-model-parser-impl/src/test/resources/negative-scenario/duplicity/augment0.yang b/opendaylight/sal/yang-prototype/code-generator/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/code-generator/yang-model-parser-impl/src/test/resources/negative-scenario/duplicity/augment1.yang b/opendaylight/sal/yang-prototype/code-generator/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/code-generator/yang-model-parser-impl/src/test/resources/negative-scenario/duplicity/augment2.yang b/opendaylight/sal/yang-prototype/code-generator/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;
+    }
+
+}
index 741e2177ff9376cb8a1b80c555ec826ea751a6ab..1946bcd5e3082e095f9319d509fb4feee23b7490 100644 (file)
             </dependency>
         </dependencies>
     </dependencyManagement>
+
+
     <build>
+        <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>
+          </plugins>
+        </pluginManagement>
+
         <plugins>
             <plugin>
                 <groupId>org.apache.maven.plugins</groupId>
                 </executions> 
             </plugin>
             <plugin>
-            <artifactId>maven-source-plugin</artifactId>
+               <artifactId>maven-source-plugin</artifactId>
                 <executions>
                     <execution>
                         <id>attach-sources</id>
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..7a1b756
     <artifactId>yang-data-impl</artifactId>\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
         <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
 </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 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;
+        }
+
     }
 
 }