Added support to generate types from Choices and Cases added by augmentation. 65/565/1
authorlsedlak <lsedlak@cisco.com>
Wed, 3 Jul 2013 15:37:59 +0000 (17:37 +0200)
committerlsedlak <lsedlak@cisco.com>
Wed, 3 Jul 2013 15:37:59 +0000 (17:37 +0200)
Added implementation into BindingGeneratorImpl to suppor of generating Generated Types for Choices and Cases from augmentations;
Extended ChoiceNode API and ChoiceNodeBuilder to getCaseNodeByName methods;
Fixed findSchemaNodeForGivenPath in SchemaContextUtil to support of traversal through Choice and Case nodes in data schema tree;

Signed-off-by: Lukas Sedlak <lsedlak@cisco.com>
opendaylight/sal/yang-prototype/code-generator/binding-generator-impl/src/main/java/org/opendaylight/controller/sal/binding/generator/impl/BindingGeneratorImpl.java
opendaylight/sal/yang-prototype/code-generator/binding-generator-impl/src/test/java/org/opendaylight/controller/sal/binding/generator/impl/ChoiceCaseGenTypesTest.java
opendaylight/sal/yang-prototype/code-generator/binding-generator-impl/src/test/resources/choice-case-type-test-models/augment-monitoring@2013-07-01.yang
opendaylight/sal/yang-prototype/code-generator/binding-generator-impl/src/test/resources/choice-case-type-test-models/choice-monitoring@2013-07-01.yang [new file with mode: 0644]
opendaylight/sal/yang-prototype/code-generator/binding-generator-impl/src/test/resources/choice-case-type-test-models/ietf-netconf-monitoring@2010-10-04.yang [deleted file]
opendaylight/sal/yang-prototype/code-generator/samples/maven-code-gen-sample/src/main/yang/augment-monitoring@2013-07-01.yang [new file with mode: 0644]
opendaylight/sal/yang-prototype/code-generator/samples/maven-code-gen-sample/src/main/yang/choice-monitoring@2013-07-01.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/impl/ChoiceBuilder.java
opendaylight/sal/yang-prototype/yang/yang-model-api/src/main/java/org/opendaylight/controller/yang/model/api/ChoiceNode.java
opendaylight/sal/yang-prototype/yang/yang-model-util/src/main/java/org/opendaylight/controller/yang/model/util/SchemaContextUtil.java

index 8b68050..ebefa10 100644 (file)
@@ -523,20 +523,38 @@ public final class BindingGeneratorImpl implements BindingGenerator {
         if ((targetSchemaNode != null) && (targetSchemaNode.getQName() != null)
                 && (targetSchemaNode.getQName().getLocalName() != null)) {
             final Module targetModule = findParentModule(schemaContext, targetSchemaNode);
-
             final String targetBasePackage = moduleNamespaceToPackageName(targetModule);
             final String targetPackageName = packageNameForGeneratedType(targetBasePackage, targetSchemaNode.getPath());
-
             final String targetSchemaNodeName = targetSchemaNode.getQName().getLocalName();
             final Set<DataSchemaNode> augChildNodes = augSchema.getChildNodes();
-            final GeneratedTypeBuilder augTypeBuilder = addRawAugmentGenTypeDefinition(augmentPackageName,
-                    targetPackageName, targetSchemaNodeName, augSchema);
-            if (augTypeBuilder != null) {
-                genTypes.add(augTypeBuilder.toInstance());
+
+            if (!(targetSchemaNode instanceof ChoiceNode)) {
+                final GeneratedTypeBuilder augTypeBuilder = addRawAugmentGenTypeDefinition(augmentPackageName,
+                        targetPackageName, targetSchemaNodeName, augSchema);
+                final GeneratedType augType = augTypeBuilder.toInstance();
+                genTypes.add(augType);
+            } else {
+                final Type refChoiceType = new ReferencedTypeImpl(targetPackageName,
+                        parseToClassName(targetSchemaNodeName));
+                final ChoiceNode choiceTarget = (ChoiceNode) targetSchemaNode;
+                final Set<ChoiceCaseNode> choiceCaseNodes = choiceTarget.getCases();
+                genTypes.addAll(augmentCasesToGenTypes(augmentPackageName, refChoiceType, choiceCaseNodes));
             }
             genTypes.addAll(augmentationBodyToGenTypes(augmentPackageName, augChildNodes));
+        }
+        return genTypes;
+    }
 
+    private List<GeneratedType> augmentCasesToGenTypes(final String augmentPackageName, final Type refChoiceType,
+            final Set<ChoiceCaseNode> choiceCaseNodes) {
+        if (augmentPackageName == null) {
+            throw new IllegalArgumentException("Augment Package Name string cannot be NULL!");
         }
+        if (choiceCaseNodes == null) {
+            throw new IllegalArgumentException("Set of Choice Case Nodes cannot be NULL!");
+        }
+        final List<GeneratedType> genTypes = generateTypesFromAugmentedChoiceCases(augmentPackageName, refChoiceType,
+                choiceCaseNodes);
         return genTypes;
     }
 
@@ -576,23 +594,35 @@ public final class BindingGeneratorImpl implements BindingGenerator {
                 } else if (childNode instanceof ListSchemaNode) {
                     genTypes.addAll(listToGenType(augBasePackageName, (ListSchemaNode) childNode));
                 }
+            } else if (childNode instanceof ChoiceNode) {
+                final ChoiceNode choice = (ChoiceNode) childNode;
+                for (final ChoiceCaseNode caseNode : choice.getCases()) {
+                    augSchemaIts.add(new DataNodeIterator(caseNode));
+                }
+                genTypes.addAll(choiceToGeneratedType(augBasePackageName, (ChoiceNode) childNode));
             }
         }
 
         for (final DataNodeIterator it : augSchemaIts) {
             final List<ContainerSchemaNode> augContainers = it.allContainers();
             final List<ListSchemaNode> augLists = it.allLists();
+            final List<ChoiceNode> augChoices = it.allChoices();
 
-            if ((augContainers != null) && !augContainers.isEmpty()) {
+            if (augContainers != null) {
                 for (final ContainerSchemaNode container : augContainers) {
                     genTypes.add(containerToGenType(augBasePackageName, container));
                 }
             }
-            if ((augLists != null) && !augLists.isEmpty()) {
+            if (augLists != null) {
                 for (final ListSchemaNode list : augLists) {
                     genTypes.addAll(listToGenType(augBasePackageName, list));
                 }
             }
+            if (augChoices != null) {
+                for (final ChoiceNode choice : augChoices) {
+                    genTypes.addAll(choiceToGeneratedType(augBasePackageName, choice));
+                }
+            }
         }
         return genTypes;
     }
@@ -719,7 +749,37 @@ public final class BindingGeneratorImpl implements BindingGenerator {
 
         final List<GeneratedType> generatedTypes = new ArrayList<>();
         for (final ChoiceCaseNode caseNode : caseNodes) {
-            if (caseNode != null) {
+            if (caseNode != null && !caseNode.isAddedByUses()) {
+                final String packageName = packageNameForGeneratedType(basePackageName, caseNode.getPath());
+                final GeneratedTypeBuilder caseTypeBuilder = addDefaultInterfaceDefinition(packageName, caseNode);
+                caseTypeBuilder.addImplementsType(refChoiceType);
+
+                final Set<DataSchemaNode> childNodes = caseNode.getChildNodes();
+                if (childNodes != null) {
+                    resolveDataSchemaNodes(basePackageName, caseTypeBuilder, childNodes);
+                }
+                generatedTypes.add(caseTypeBuilder.toInstance());
+            }
+        }
+
+        return generatedTypes;
+    }
+
+    private List<GeneratedType> generateTypesFromAugmentedChoiceCases(final String basePackageName,
+            final Type refChoiceType, final Set<ChoiceCaseNode> caseNodes) {
+        if (basePackageName == null) {
+            throw new IllegalArgumentException("Base Package Name cannot be NULL!");
+        }
+        if (refChoiceType == null) {
+            throw new IllegalArgumentException("Referenced Choice Type cannot be NULL!");
+        }
+        if (caseNodes == null) {
+            throw new IllegalArgumentException("Set of Choice Case Nodes cannot be NULL!");
+        }
+
+        final List<GeneratedType> generatedTypes = new ArrayList<>();
+        for (final ChoiceCaseNode caseNode : caseNodes) {
+            if (caseNode != null && caseNode.isAugmenting()) {
                 final String packageName = packageNameForGeneratedType(basePackageName, caseNode.getPath());
                 final GeneratedTypeBuilder caseTypeBuilder = addDefaultInterfaceDefinition(packageName, caseNode);
                 caseTypeBuilder.addImplementsType(refChoiceType);
@@ -862,11 +922,13 @@ public final class BindingGeneratorImpl implements BindingGenerator {
     }
 
     /**
-     * Method instantiates new Generated Type Builder and sets the implements definitions of Data Object and
-     * Augmentable.
-     *
-     * @param packageName Generated Type Package Name
-     * @param schemaNode Schema Node definition
+     * Method instantiates new Generated Type Builder and sets the implements
+     * definitions of Data Object and Augmentable.
+     * 
+     * @param packageName
+     *            Generated Type Package Name
+     * @param schemaNode
+     *            Schema Node definition
      * @return Generated Type Builder instance for Schema Node definition
      */
     private GeneratedTypeBuilder addDefaultInterfaceDefinition(final String packageName, final SchemaNode schemaNode) {
@@ -877,7 +939,7 @@ public final class BindingGeneratorImpl implements BindingGenerator {
     }
 
     /**
-     *
+     * 
      * @param packageName
      * @param schemaNode
      * @return
diff --git a/opendaylight/sal/yang-prototype/code-generator/binding-generator-impl/src/test/resources/choice-case-type-test-models/choice-monitoring@2013-07-01.yang b/opendaylight/sal/yang-prototype/code-generator/binding-generator-impl/src/test/resources/choice-case-type-test-models/choice-monitoring@2013-07-01.yang
new file mode 100644 (file)
index 0000000..2362783
--- /dev/null
@@ -0,0 +1,129 @@
+module choice-monitoring {
+  yang-version 1;
+  namespace "urn:ietf:params:xml:ns:yang:choice-monitoring";
+  prefix "ncm";
+
+  import ietf-yang-types { prefix yang; }
+  import ietf-inet-types { prefix inet; }
+
+  organization "OPEN DAYLIGHT";
+  contact "http://www.opendaylight.org/";
+
+  description
+    "Test model for testing of resolving choice, case nodes and generation types from them.";
+
+  revision 2013-07-01 {
+
+  }
+
+  typedef tls-fingerprint-type {
+    type string {
+      pattern '([0-9a-fA-F]){2}(:([0-9a-fA-F]){2})*';
+    }
+  }
+
+  typedef netconf-datastore-type {
+    type enumeration {
+      enum running;
+      enum candidate;
+      enum startup;
+    }
+  }
+
+  container netconf-state {
+    config false;
+
+    container datastores {
+      list datastore {
+        key name;
+
+        leaf name {
+          type netconf-datastore-type;
+        }
+        container locks {
+          choice lock-type {
+
+            case global-lock {
+                container global-lock {
+
+                leaf locked-by-session {
+                  type uint32;
+                  mandatory true;
+                }
+
+                leaf locked-time {
+                  type yang:date-and-time;
+                  mandatory true;
+                }
+
+                container capabilities {
+                  leaf-list capability {
+                      type inet:uri;
+                  }
+                }
+              }
+            }
+
+            case partial-lock {
+              list partial-lock {
+                  key lock-id;
+
+                  leaf lock-id {
+                    type uint32;
+                  }
+                  leaf-list select {
+                    type yang:xpath1.0;
+                    min-elements 1;
+                  }
+                  leaf-list locked-node {
+                    type string;
+                  }
+              }
+            }
+
+            case fingerprint {
+              choice algorithm-and-hash {
+                  mandatory true;
+                  case md5 {
+                    leaf md5 {
+                      type tls-fingerprint-type;
+                    }
+                  }
+
+                  case sha1 {
+                    leaf sha1 {
+                      type tls-fingerprint-type;
+                    }
+                  }
+                  
+                  case sha224 {
+                    leaf sha224 {
+                      type tls-fingerprint-type;
+                    }
+                  }
+                  
+                  case sha256 {
+                    leaf sha256 {
+                      type tls-fingerprint-type;
+                    }
+                  }
+                  
+                  case sha384 {
+                    leaf sha384 {
+                      type tls-fingerprint-type;
+                    }
+                  }                
+                  
+                  case sha512 {
+                    leaf sha512 {
+                      type tls-fingerprint-type;
+                    }
+                  }
+              }
+            }
+          }
+        }
+      }
+    }
+  }
+}
diff --git a/opendaylight/sal/yang-prototype/code-generator/binding-generator-impl/src/test/resources/choice-case-type-test-models/ietf-netconf-monitoring@2010-10-04.yang b/opendaylight/sal/yang-prototype/code-generator/binding-generator-impl/src/test/resources/choice-case-type-test-models/ietf-netconf-monitoring@2010-10-04.yang
deleted file mode 100644 (file)
index 695fb1d..0000000
+++ /dev/null
@@ -1,254 +0,0 @@
-module ietf-netconf-monitoring {
-
-  namespace "urn:ietf:params:xml:ns:yang:ietf-netconf-monitoring";
-  prefix "ncm";
-
-  import ietf-yang-types { prefix yang; }
-  import ietf-inet-types { prefix inet; }
-
-  organization
-    "IETF NETCONF (Network Configuration) Working Group";
-
-  contact
-    "WG Web:   <http://tools.ietf.org/wg/netconf/>
-     WG List:  <mailto:netconf@ietf.org>
-
-     WG Chair: Mehmet Ersue
-               <mailto:mehmet.ersue@nsn.com>
-
-     WG Chair: Bert Wijnen
-               <mailto:bertietf@bwijnen.net>
-
-     Editor:   Mark Scott
-               <mailto:mark.scott@ericsson.com>
-
-     Editor:   Martin Bjorklund
-               <mailto:mbj@tail-f.com>";
-
-  description
-    "NETCONF Monitoring Module.
-     All elements in this module are read-only.
-
-     Copyright (c) 2010 IETF Trust and the persons identified as
-     authors of the code. All rights reserved.
-
-     Redistribution and use in source and binary forms, with or
-     without modification, is permitted pursuant to, and subject
-     to the license terms contained in, the Simplified BSD
-     License set forth in Section 4.c of the IETF Trust's
-     Legal Provisions Relating to IETF Documents
-     (http://trustee.ietf.org/license-info).
-
-     This version of this YANG module is part of RFC 6022; see
-     the RFC itself for full legal notices.";
-
-  revision 2010-10-04 {
-    description
-      "Initial revision.";
-    reference
-      "RFC 6022: YANG Module for NETCONF Monitoring";
-  }
-
-  typedef tls-fingerprint-type {
-    type string {
-      pattern '([0-9a-fA-F]){2}(:([0-9a-fA-F]){2})*';
-    }
-    description
-      "A cryptographic signature (fingerprint) value that can be used to
-       uniquely reference other data of potentially arbitrary length.";
-  }
-
-  typedef netconf-datastore-type {
-    type enumeration {
-      enum running;
-      enum candidate;
-      enum startup;
-    }
-    description
-      "Enumeration of possible NETCONF datastore types.";
-    reference
-      "RFC 4741: NETCONF Configuration Protocol";
-  }
-
-  container netconf-state {
-    config false;
-    description
-      "The netconf-state container is the root of the monitoring
-       data model.";
-
-    container datastores {
-      description
-        "Contains the list of NETCONF configuration datastores.";
-
-      list datastore {
-        key name;
-        description
-          "List of NETCONF configuration datastores supported by
-           the NETCONF server and related information.";
-
-        leaf name {
-          type netconf-datastore-type;
-          description
-            "Name of the datastore associated with this list entry.";
-        }
-        container locks {
-          presence
-            "This container is present only if the datastore
-             is locked.";
-          description
-            "The NETCONF <lock> and <partial-lock> operations allow
-             a client to lock specific resources in a datastore.  The
-             NETCONF server will prevent changes to the locked
-             resources by all sessions except the one that acquired
-             the lock(s).
-
-             Monitoring information is provided for each datastore
-             entry including details such as the session that acquired
-             the lock, the type of lock (global or partial) and the
-             list of locked resources.  Multiple locks per datastore
-             are supported.";
-
-          choice lock-type {
-            description
-              "Indicates if a global lock or a set of partial locks
-               are set.";
-
-            case global-lock {
-                container global-lock {
-                description
-                  "Present if the global lock is set.";
-
-                leaf locked-by-session {
-                  type uint32;
-                  mandatory true;
-                  description
-                    "The session ID of the session that has locked
-                     this resource.  Both a global lock and a partial
-                     lock MUST contain the NETCONF session-id.
-
-                     If the lock is held by a session that is not managed
-                      by the NETCONF server (e.g., a CLI session), a session
-                     id of 0 (zero) is reported.";
-                  reference
-                    "RFC 4741: NETCONF Configuration Protocol";
-                }
-                leaf locked-time {
-                  type yang:date-and-time;
-                  mandatory true;
-                  description
-                    "The date and time of when the resource was
-                      locked.";
-                }
-
-                container capabilities {
-                  description
-                  "Contains the list of NETCONF capabilities supported by the
-                      server.";
-
-                  leaf-list capability {
-                      type inet:uri;
-                        description
-                          "List of NETCONF capabilities supported by the server.";
-                  }
-                }
-              }
-            }
-
-            case partial-lock {
-              list partial-lock {
-                  key lock-id;
-                  description
-                    "List of partial locks.";
-                  reference
-                    "RFC 5717: Partial Lock Remote Procedure Call (RPC) for
-                     NETCONF";
-
-                  leaf lock-id {
-                    type uint32;
-                    description
-                      "This is the lock id returned in the <partial-lock>
-                       response.";
-                  }
-                  leaf-list select {
-                    type yang:xpath1.0;
-                    min-elements 1;
-                    description
-                      "The xpath expression that was used to request
-                       the lock.  The select expression indicates the
-                       original intended scope of the lock.";
-                  }
-                  leaf-list locked-node {
-                    type string;
-                    description
-                      "The list of instance-identifiers (i.e., the
-                       locked nodes). The scope of the partial lock is defined by the list
-                       of locked nodes.";
-                  }
-              }
-            }
-
-            case fingerprint {
-              choice algorithm-and-hash {
-                  mandatory true;
-                  case md5 {
-                    leaf md5 {
-                      type tls-fingerprint-type;
-                    }
-                  }
-                  
-                  case sha1 {
-                    leaf sha1 {
-                      type tls-fingerprint-type;
-                    }
-                  }
-                  
-                  case sha224 {
-                    leaf sha224 {
-                      type tls-fingerprint-type;
-                    }
-                  }
-                  
-                  case sha256 {
-                    leaf sha256 {
-                      type tls-fingerprint-type;
-                    }
-                  }
-                  
-                  case sha384 {
-                    leaf sha384 {
-                      type tls-fingerprint-type;
-                    }
-                  }                
-                  
-                  case sha512 {
-                    leaf sha512 {
-                      type tls-fingerprint-type;
-                    }
-                  }
-                  
-                  description
-                    "Specifies the signature algorithm and cryptographic
-                      signature (fingerprint) used to identify an X.509
-                      certificate.
-
-                      Implementations of this YANG module MAY, but are not
-                      required to, implement all of these cryptographic signature
-                      algorithms.  Implementations of this YANG module MUST
-                      implement at least one of these cryptographic signature
-                      algorithms.
-
-                      The available choices may be extended in the future as
-                      stronger cryptographic signature algorithms become
-                      available and are deemed necessary.";
-
-                  reference
-                    "RFC 5246: The Transport Layer Security (TLS) Protocol
-                      Version 1.2; Section 7.4.1.4.1,  Signature Algorithms";
-              }  // choice algorithm-and-hash
-            }
-          }
-        }
-      }
-    }
-  }
-}
diff --git a/opendaylight/sal/yang-prototype/code-generator/samples/maven-code-gen-sample/src/main/yang/augment-monitoring@2013-07-01.yang b/opendaylight/sal/yang-prototype/code-generator/samples/maven-code-gen-sample/src/main/yang/augment-monitoring@2013-07-01.yang
new file mode 100644 (file)
index 0000000..4683598
--- /dev/null
@@ -0,0 +1,88 @@
+module augment-monitoring {
+    yang-version 1;
+    namespace "urn:ietf:params:xml:ns:yang:augment-monitoring";
+    prefix "amon";
+
+    import choice-monitoring { prefix nm; }
+
+    organization "OPEN DAYLIGHT";
+    contact "http://www.opendaylight.org/";
+
+    revision "2013-07-01" {
+            reference "NO REF";
+    }
+
+    augment "/nm:netconf-state/nm:datastores/nm:datastore/nm:locks/nm:lock-type" {
+        case autonomous-lock {
+            container autonomous-def {
+                leaf lock-id {
+                    type int32;
+                }
+
+                leaf lock-time {
+                    type uint32;
+                }
+            }
+        }
+
+        case anonymous-lock {
+            leaf lock-time {
+                type uint32;
+            }
+        }
+
+        leaf leaf-aug-case {
+            type string;
+        }
+    }
+
+    augment "/nm:netconf-state/nm:datastores/nm:datastore/nm:locks/nm:lock-type/nm:partial-lock" {
+        choice aug-case-by-choice {
+            case foo {
+                leaf foo {
+                    type string;
+                }
+            }
+
+            case bar {
+                leaf bar {
+                    type boolean;
+                }
+            }
+        }
+    }
+
+    augment "/nm:netconf-state/nm:datastores/nm:datastore" {
+        choice storage-format {
+            case xml {
+                container xml-def {
+                    leaf file-name {
+                        type string;
+                    }
+                }
+            }
+
+            case yang {
+                leaf yang-file-name {
+                    type string;
+                }
+            }
+
+            case unknown-files {
+                list files {
+                    key "file-name";
+
+                    leaf file-name {
+                        type string;
+                    }
+
+                    container file-data {
+                        leaf utf8-data {
+                            type string;
+                        }
+                    }
+                }
+            }
+        }
+    }
+}
\ No newline at end of file
diff --git a/opendaylight/sal/yang-prototype/code-generator/samples/maven-code-gen-sample/src/main/yang/choice-monitoring@2013-07-01.yang b/opendaylight/sal/yang-prototype/code-generator/samples/maven-code-gen-sample/src/main/yang/choice-monitoring@2013-07-01.yang
new file mode 100644 (file)
index 0000000..2362783
--- /dev/null
@@ -0,0 +1,129 @@
+module choice-monitoring {
+  yang-version 1;
+  namespace "urn:ietf:params:xml:ns:yang:choice-monitoring";
+  prefix "ncm";
+
+  import ietf-yang-types { prefix yang; }
+  import ietf-inet-types { prefix inet; }
+
+  organization "OPEN DAYLIGHT";
+  contact "http://www.opendaylight.org/";
+
+  description
+    "Test model for testing of resolving choice, case nodes and generation types from them.";
+
+  revision 2013-07-01 {
+
+  }
+
+  typedef tls-fingerprint-type {
+    type string {
+      pattern '([0-9a-fA-F]){2}(:([0-9a-fA-F]){2})*';
+    }
+  }
+
+  typedef netconf-datastore-type {
+    type enumeration {
+      enum running;
+      enum candidate;
+      enum startup;
+    }
+  }
+
+  container netconf-state {
+    config false;
+
+    container datastores {
+      list datastore {
+        key name;
+
+        leaf name {
+          type netconf-datastore-type;
+        }
+        container locks {
+          choice lock-type {
+
+            case global-lock {
+                container global-lock {
+
+                leaf locked-by-session {
+                  type uint32;
+                  mandatory true;
+                }
+
+                leaf locked-time {
+                  type yang:date-and-time;
+                  mandatory true;
+                }
+
+                container capabilities {
+                  leaf-list capability {
+                      type inet:uri;
+                  }
+                }
+              }
+            }
+
+            case partial-lock {
+              list partial-lock {
+                  key lock-id;
+
+                  leaf lock-id {
+                    type uint32;
+                  }
+                  leaf-list select {
+                    type yang:xpath1.0;
+                    min-elements 1;
+                  }
+                  leaf-list locked-node {
+                    type string;
+                  }
+              }
+            }
+
+            case fingerprint {
+              choice algorithm-and-hash {
+                  mandatory true;
+                  case md5 {
+                    leaf md5 {
+                      type tls-fingerprint-type;
+                    }
+                  }
+
+                  case sha1 {
+                    leaf sha1 {
+                      type tls-fingerprint-type;
+                    }
+                  }
+                  
+                  case sha224 {
+                    leaf sha224 {
+                      type tls-fingerprint-type;
+                    }
+                  }
+                  
+                  case sha256 {
+                    leaf sha256 {
+                      type tls-fingerprint-type;
+                    }
+                  }
+                  
+                  case sha384 {
+                    leaf sha384 {
+                      type tls-fingerprint-type;
+                    }
+                  }                
+                  
+                  case sha512 {
+                    leaf sha512 {
+                      type tls-fingerprint-type;
+                    }
+                  }
+              }
+            }
+          }
+        }
+      }
+    }
+  }
+}
index 1b4283a..01acc11 100644 (file)
@@ -376,6 +376,36 @@ public final class ChoiceBuilder extends AbstractSchemaNodeBuilder implements Da
             return cases;
         }
 
+        @Override
+        public ChoiceCaseNode getCaseNodeByName(final QName name) {
+            if (name == null) {
+                throw new IllegalArgumentException("Choice Case QName cannot be NULL!");
+            }
+            for (final ChoiceCaseNode caseNode : cases) {
+                if (caseNode != null) {
+                    if (name.equals(caseNode.getQName())) {
+                        return caseNode;
+                    }
+                }
+            }
+            return null;
+        }
+
+        @Override
+        public ChoiceCaseNode getCaseNodeByName(final String name) {
+            if (name == null) {
+                throw new IllegalArgumentException("Choice Case string Name cannot be NULL!");
+            }
+            for (final ChoiceCaseNode caseNode : cases) {
+                if (caseNode != null && (caseNode.getQName() != null)) {
+                    if (name.equals(caseNode.getQName().getLocalName())) {
+                        return caseNode;
+                    }
+                }
+            }
+            return null;
+        }
+
         private void setCases(Set<ChoiceCaseNode> cases) {
             if (cases != null) {
                 this.cases = cases;
index ee4163d..140ef84 100644 (file)
@@ -7,6 +7,8 @@
  */
 package org.opendaylight.controller.yang.model.api;
 
+import org.opendaylight.controller.yang.common.QName;
+
 import java.util.Set;
 
 /**
@@ -20,6 +22,22 @@ public interface ChoiceNode extends DataSchemaNode, AugmentationTarget {
      */
     Set<ChoiceCaseNode> getCases();
 
+    /**
+     * @param name
+     *            QName of seeked Choice Case Node
+     * @return child case node of this Choice if child with given name is
+     *         present, <code>null</code> otherwise
+     */
+    ChoiceCaseNode getCaseNodeByName(QName name);
+
+    /**
+     * @param name
+     *            name of seeked child as String
+     * @return child case node (or local name of case node) of this Choice if child with given name is
+     *         present, <code>null</code> otherwise
+     */
+    ChoiceCaseNode getCaseNodeByName(String name);
+
     String getDefaultCase();
 
 }
index 13c2ba7..44ef804 100644 (file)
@@ -14,21 +14,12 @@ import java.util.Queue;
 import java.util.Set;
 
 import org.opendaylight.controller.yang.common.QName;
-import org.opendaylight.controller.yang.model.api.ContainerSchemaNode;
-import org.opendaylight.controller.yang.model.api.DataNodeContainer;
-import org.opendaylight.controller.yang.model.api.DataSchemaNode;
-import org.opendaylight.controller.yang.model.api.ListSchemaNode;
-import org.opendaylight.controller.yang.model.api.Module;
-import org.opendaylight.controller.yang.model.api.ModuleImport;
-import org.opendaylight.controller.yang.model.api.RevisionAwareXPath;
-import org.opendaylight.controller.yang.model.api.SchemaContext;
-import org.opendaylight.controller.yang.model.api.SchemaNode;
-import org.opendaylight.controller.yang.model.api.SchemaPath;
-import org.opendaylight.controller.yang.model.api.TypeDefinition;
+import org.opendaylight.controller.yang.model.api.*;
 
 public final class SchemaContextUtil {
 
-    private SchemaContextUtil() {}
+    private SchemaContextUtil() {
+    }
 
     public static DataSchemaNode findDataSchemaNode(final SchemaContext context, final SchemaPath schemaPath) {
         if (schemaPath != null) {
@@ -52,11 +43,9 @@ public final class SchemaContextUtil {
                     // TODO: function to escape conditions in path
                 }
                 if (nonCondXPath.isAbsolute()) {
-                    final Queue<QName> qnamedPath = xpathToQNamePath(context, module,
-                            strXPath);
+                    final Queue<QName> qnamedPath = xpathToQNamePath(context, module, strXPath);
                     if (qnamedPath != null) {
-                        final DataSchemaNode dataNode = findSchemaNodeForGivenPath(context,
-                                module, qnamedPath);
+                        final DataSchemaNode dataNode = findSchemaNodeForGivenPath(context, module, qnamedPath);
                         return dataNode;
                     }
                 }
@@ -65,20 +54,16 @@ public final class SchemaContextUtil {
         return null;
     }
 
-    public static DataSchemaNode findDataSchemaNodeForRelativeXPath(final SchemaContext context,
-            final Module module, final SchemaNode actualSchemaNode,
-            final RevisionAwareXPath relativeXPath) {
-        if ((actualSchemaNode != null) && (relativeXPath != null)
-                && !relativeXPath.isAbsolute()) {
+    public static DataSchemaNode findDataSchemaNodeForRelativeXPath(final SchemaContext context, final Module module,
+            final SchemaNode actualSchemaNode, final RevisionAwareXPath relativeXPath) {
+        if ((actualSchemaNode != null) && (relativeXPath != null) && !relativeXPath.isAbsolute()) {
 
             final SchemaPath actualNodePath = actualSchemaNode.getPath();
             if (actualNodePath != null) {
-                final Queue<QName> qnamePath = resolveRelativeXPath(context, module,
-                        relativeXPath, actualNodePath);
+                final Queue<QName> qnamePath = resolveRelativeXPath(context, module, relativeXPath, actualNodePath);
 
                 if (qnamePath != null) {
-                    final DataSchemaNode dataNode = findSchemaNodeForGivenPath(context,
-                            module, qnamePath);
+                    final DataSchemaNode dataNode = findSchemaNodeForGivenPath(context, module, qnamePath);
                     return dataNode;
                 }
             }
@@ -87,8 +72,7 @@ public final class SchemaContextUtil {
         return null;
     }
 
-    private static Module resolveModuleFromSchemaPath(final SchemaContext
-        context, final SchemaPath schemaPath) {
+    private static Module resolveModuleFromSchemaPath(final SchemaContext context, final SchemaPath schemaPath) {
         if ((schemaPath != null) && (schemaPath.getPath() != null)) {
             final List<QName> path = schemaPath.getPath();
             if (!path.isEmpty()) {
@@ -102,11 +86,10 @@ public final class SchemaContextUtil {
         return null;
     }
 
-    public static Module findParentModuleForTypeDefinition(
-            final SchemaContext context, final TypeDefinition<?> type) {
+    public static Module findParentModuleForTypeDefinition(final SchemaContext context, final TypeDefinition<?> type) {
         final SchemaPath schemaPath = type.getPath();
         if ((schemaPath != null) && (schemaPath.getPath() != null)) {
-            if(type instanceof ExtendedType) {
+            if (type instanceof ExtendedType) {
                 List<QName> path = schemaPath.getPath();
                 final QName qname = path.get(path.size() - 1);
 
@@ -136,14 +119,14 @@ public final class SchemaContextUtil {
 
         final SchemaPath schemaPath = schemaNode.getPath();
         if (schemaPath == null) {
-            throw new IllegalStateException("Schema Path for Schema Node is not " +
-                    "set properly (Schema Path is NULL)");
+            throw new IllegalStateException("Schema Path for Schema Node is not "
+                    "set properly (Schema Path is NULL)");
         }
         final List<QName> qnamedPath = schemaPath.getPath();
         if (qnamedPath == null || qnamedPath.isEmpty()) {
-            throw new IllegalStateException("Schema Path contains invalid state of path parts." +
-                    "The Schema Path MUST contain at least ONE QName which defines namespace and Local name" +
-                    "of path.");
+            throw new IllegalStateException("Schema Path contains invalid state of path parts."
+                    + "The Schema Path MUST contain at least ONE QName which defines namespace and Local name"
+                    "of path.");
         }
         final QName qname = qnamedPath.get(qnamedPath.size() - 1);
         return context.findModuleByNamespace(qname.getNamespace());
@@ -151,12 +134,11 @@ public final class SchemaContextUtil {
 
     private static DataSchemaNode findSchemaNodeForGivenPath(final SchemaContext context, final Module module,
             final Queue<QName> qnamedPath) {
-        if ((module != null) && (module.getNamespace() != null)
-                && (qnamedPath != null)) {
+        if ((module != null) && (module.getNamespace() != null) && (qnamedPath != null)) {
             DataNodeContainer nextNode = module;
             final URI moduleNamespace = module.getNamespace();
 
-            QName childNodeQName = null;
+            QName childNodeQName;
             DataSchemaNode schemaNode = null;
             while ((nextNode != null) && !qnamedPath.isEmpty()) {
                 childNodeQName = qnamedPath.peek();
@@ -169,14 +151,20 @@ public final class SchemaContextUtil {
                             nextNode = (ContainerSchemaNode) schemaNode;
                         } else if (schemaNode instanceof ListSchemaNode) {
                             nextNode = (ListSchemaNode) schemaNode;
+                        } else if (schemaNode instanceof ChoiceNode) {
+                            final ChoiceNode choice = (ChoiceNode) schemaNode;
+                            qnamedPath.poll();
+                            if (!qnamedPath.isEmpty()) {
+                                childNodeQName = qnamedPath.peek();
+                                nextNode = choice.getCaseNodeByName(childNodeQName);
+                                schemaNode = (DataSchemaNode)nextNode;
+                            }
                         } else {
                             nextNode = null;
                         }
                     } else if (!childNodeNamespace.equals(moduleNamespace)) {
-                        final Module nextModule = context
-                                .findModuleByNamespace(childNodeNamespace);
-                        schemaNode = findSchemaNodeForGivenPath(context, nextModule,
-                                qnamedPath);
+                        final Module nextModule = context.findModuleByNamespace(childNodeNamespace);
+                        schemaNode = findSchemaNodeForGivenPath(context, nextModule, qnamedPath);
                         return schemaNode;
                     }
                     qnamedPath.poll();
@@ -207,22 +195,18 @@ public final class SchemaContextUtil {
         if (parentModule != null && prefixedPathPart != null) {
             if (prefixedPathPart.contains(":")) {
                 final String[] prefixedName = prefixedPathPart.split(":");
-                final Module module = resolveModuleForPrefix(context, parentModule,
-                        prefixedName[0]);
+                final Module module = resolveModuleForPrefix(context, parentModule, prefixedName[0]);
                 if (module != null) {
-                    return new QName(module.getNamespace(), module
-                            .getRevision(), prefixedName[1]);
+                    return new QName(module.getNamespace(), module.getRevision(), prefixedName[1]);
                 }
             } else {
-                return new QName(parentModule.getNamespace(),
-                        parentModule.getRevision(), prefixedPathPart);
+                return new QName(parentModule.getNamespace(), parentModule.getRevision(), prefixedPathPart);
             }
         }
         return null;
     }
 
-    private static Module resolveModuleForPrefix(final SchemaContext context, final Module module,
-            final String prefix) {
+    private static Module resolveModuleForPrefix(final SchemaContext context, final Module module, final String prefix) {
         if ((module != null) && (prefix != null)) {
             if (prefix.equals(module.getPrefix())) {
                 return module;
@@ -232,8 +216,7 @@ public final class SchemaContextUtil {
 
             for (final ModuleImport mi : imports) {
                 if (prefix.equals(mi.getPrefix())) {
-                    return context.findModuleByName(mi.getModuleName(),
-                            mi.getRevision());
+                    return context.findModuleByName(mi.getModuleName(), mi.getRevision());
                 }
             }
         }
@@ -241,12 +224,10 @@ public final class SchemaContextUtil {
     }
 
     private static Queue<QName> resolveRelativeXPath(final SchemaContext context, final Module module,
-            final RevisionAwareXPath relativeXPath,
-            final SchemaPath leafrefSchemaPath) {
+            final RevisionAwareXPath relativeXPath, final SchemaPath leafrefSchemaPath) {
         final Queue<QName> absolutePath = new LinkedList<>();
 
-        if ((module != null) && (relativeXPath != null) && !relativeXPath.isAbsolute()
-                && (leafrefSchemaPath != null)) {
+        if ((module != null) && (relativeXPath != null) && !relativeXPath.isAbsolute() && (leafrefSchemaPath != null)) {
             final String strXPath = relativeXPath.toString();
             if (strXPath != null) {
                 final String[] xpaths = strXPath.split("/");

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