Merge changes I14f284cc,I65bfdb56
authorTony Tkacik <ttkacik@cisco.com>
Thu, 10 Oct 2013 10:21:54 +0000 (10:21 +0000)
committerGerrit Code Review <gerrit@opendaylight.org>
Thu, 10 Oct 2013 10:21:54 +0000 (10:21 +0000)
* changes:
  Added support for identity statement.
  Fixed bug in resolving refine statement. (Bug 111)

14 files changed:
code-generator/binding-type-provider/src/main/java/org/opendaylight/yangtools/sal/binding/yang/types/TypeProviderImpl.java
yang/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/IdentitySchemaNode.java
yang/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/type/IdentityrefTypeDefinition.java
yang/yang-model-util/src/main/java/org/opendaylight/yangtools/yang/model/util/IdentityrefType.java
yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/builder/impl/IdentitySchemaNodeBuilder.java
yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/builder/impl/IdentityrefTypeBuilder.java
yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/impl/YangParserImpl.java
yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/util/GroupingUtils.java
yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/util/ParserUtils.xtend
yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/validator/YangModelBasicValidationListener.java
yang/yang-parser-impl/src/test/java/org/opendaylight/yangtools/yang/parser/impl/GroupingTest.java
yang/yang-parser-impl/src/test/java/org/opendaylight/yangtools/yang/parser/impl/TypesResolutionTest.java
yang/yang-parser-impl/src/test/resources/model/nodes.yang
yang/yang-parser-impl/src/test/resources/types/custom-types-test@2012-4-4.yang

index 858c2e0f09198de27a9ee3cc642541ebdc192c8c..a8abe38c70729cefc93c05a9e8c2e06e3b9c73a1 100644 (file)
@@ -246,7 +246,7 @@ public final class TypeProviderImpl implements TypeProvider {
      *         <code>idref</code>
      */
     private Type provideTypeForIdentityref(IdentityrefTypeDefinition idref) {
-        QName baseIdQName = idref.getIdentity();
+        QName baseIdQName = idref.getIdentity().getQName();
         Module module = schemaContext.findModuleByNamespaceAndRevision(baseIdQName.getNamespace(),
                 baseIdQName.getRevision());
         IdentitySchemaNode identity = null;
index bd93d7d4807a2f24ccd56cd9121707f3da96ae6f..3fea02a510ad0f24a9fc8dd528ab802425042963 100644 (file)
@@ -7,6 +7,8 @@
  */\r
 package org.opendaylight.yangtools.yang.model.api;\r
 \r
+import java.util.Set;\r
+\r
 /**\r
  * Interface describing YANG 'identity' statement.\r
  * <p>\r
@@ -24,4 +26,11 @@ public interface IdentitySchemaNode extends SchemaNode {
      */\r
     IdentitySchemaNode getBaseIdentity();\r
 \r
+    /**\r
+     * Get identities derived from this identity.\r
+     * \r
+     * @return collection of identities derived from this identity\r
+     */\r
+    Set<IdentitySchemaNode> getDerivedIdentities();\r
+\r
 }\r
index 1449f03fb9fcbd4cb18c347b350327072caca6c1..8b567a716186aeacb16586141f03962d49937b53 100644 (file)
@@ -7,7 +7,7 @@
  */
 package org.opendaylight.yangtools.yang.model.api.type;
 
-import org.opendaylight.yangtools.yang.common.QName;
+import org.opendaylight.yangtools.yang.model.api.IdentitySchemaNode;
 import org.opendaylight.yangtools.yang.model.api.TypeDefinition;
 
 /**
@@ -19,11 +19,11 @@ import org.opendaylight.yangtools.yang.model.api.TypeDefinition;
 public interface IdentityrefTypeDefinition extends TypeDefinition<IdentityrefTypeDefinition> {
 
     /**
-     * Returns QName of the identity to which the instance of this type refers.
+     * Returns identity to which the instance of this type refers.
      * 
-     * @return QName of referenced identity which is specified with the
-     *         <code>identity</code> YANG statement
+     * @return identity which is specified with the <code>identity</code> YANG
+     *         statement
      */
-    QName getIdentity();
+    IdentitySchemaNode getIdentity();
 
 }
index d7ba3dc771d5143c5536ae987acdf313e0a35664..e34e0078588607c581c4f81e18d0ba37a9c170bf 100644 (file)
@@ -11,6 +11,7 @@ import java.util.Collections;
 import java.util.List;
 
 import org.opendaylight.yangtools.yang.common.QName;
+import org.opendaylight.yangtools.yang.model.api.IdentitySchemaNode;
 import org.opendaylight.yangtools.yang.model.api.SchemaPath;
 import org.opendaylight.yangtools.yang.model.api.Status;
 import org.opendaylight.yangtools.yang.model.api.UnknownSchemaNode;
@@ -27,10 +28,10 @@ public final class IdentityrefType implements IdentityrefTypeDefinition {
     private final SchemaPath path;
     private static final String DESCRIPTION = "The identityref type is used to reference an existing identity.";
     private static final String REFERENCE = "https://tools.ietf.org/html/rfc6020#section-9.10";
-    private final QName identity;
+    private final IdentitySchemaNode identity;
     private static final String UNITS = "";
 
-    public IdentityrefType(QName identity, SchemaPath schemaPath) {
+    public IdentityrefType(IdentitySchemaNode identity, SchemaPath schemaPath) {
         this.identity = identity;
         this.path = schemaPath;
     }
@@ -76,7 +77,7 @@ public final class IdentityrefType implements IdentityrefTypeDefinition {
     }
 
     @Override
-    public QName getIdentity() {
+    public IdentitySchemaNode getIdentity() {
         return identity;
     }
 
@@ -87,7 +88,7 @@ public final class IdentityrefType implements IdentityrefTypeDefinition {
 
     @Override
     public String toString() {
-        return "identityref " + identity.getLocalName();
+        return "identityref " + identity.getQName().getLocalName();
     }
 
 }
index aa8bbea613d88e264c002cd2eb6c2b596b6da9fc..74099b5334b6d6440032148dbd6aac9ec88150c8 100644 (file)
@@ -9,7 +9,9 @@ package org.opendaylight.yangtools.yang.parser.builder.impl;
 
 import java.util.ArrayList;
 import java.util.Collections;
+import java.util.HashSet;
 import java.util.List;
+import java.util.Set;
 
 import org.opendaylight.yangtools.yang.common.QName;
 import org.opendaylight.yangtools.yang.model.api.IdentitySchemaNode;
@@ -22,8 +24,9 @@ import org.opendaylight.yangtools.yang.parser.util.Comparators;
 public final class IdentitySchemaNodeBuilder extends AbstractSchemaNodeBuilder {
     private boolean isBuilt;
     private final IdentitySchemaNodeImpl instance;
-    private IdentitySchemaNodeBuilder baseIdentityBuilder;
     private IdentitySchemaNode baseIdentity;
+    private IdentitySchemaNodeBuilder baseIdentityBuilder;
+    private final Set<IdentitySchemaNode> derivedIdentities = new HashSet<>();
     private String baseIdentityName;
 
     IdentitySchemaNodeBuilder(final String moduleName, final int line, final QName qname) {
@@ -39,17 +42,18 @@ public final class IdentitySchemaNodeBuilder extends AbstractSchemaNodeBuilder {
             instance.setReference(reference);
             instance.setStatus(status);
 
-            if (baseIdentity == null) {
-                if (baseIdentityBuilder != null) {
-                    instance.setBaseIdentity(baseIdentityBuilder.build());
-                }
-            } else {
+            if (baseIdentity == null && baseIdentityBuilder != null) {
+                baseIdentity = baseIdentityBuilder.build();
+            }
+            if (baseIdentity != null) {
                 instance.setBaseIdentity(baseIdentity);
             }
 
+            instance.setDerivedIdentities(derivedIdentities);
+
             // UNKNOWN NODES
             if (unknownNodes == null) {
-                unknownNodes = new ArrayList<UnknownSchemaNode>();
+                unknownNodes = new ArrayList<>();
                 for (UnknownSchemaNodeBuilder b : addedUnknownNodes) {
                     unknownNodes.add(b.build());
                 }
@@ -79,14 +83,19 @@ public final class IdentitySchemaNodeBuilder extends AbstractSchemaNodeBuilder {
         this.baseIdentity = baseType;
     }
 
+    public void addDerivedIdentity(IdentitySchemaNode derived) {
+        derivedIdentities.add(derived);
+    }
+
     @Override
     public String toString() {
         return "identity " + qname.getLocalName();
     }
 
-    private final class IdentitySchemaNodeImpl implements IdentitySchemaNode {
+    public final class IdentitySchemaNodeImpl implements IdentitySchemaNode {
         private final QName qname;
         private IdentitySchemaNode baseIdentity;
+        private Set<IdentitySchemaNode> derivedIdentities = Collections.emptySet();
         private String description;
         private String reference;
         private Status status = Status.CURRENT;
@@ -111,6 +120,17 @@ public final class IdentitySchemaNodeBuilder extends AbstractSchemaNodeBuilder {
             this.baseIdentity = baseIdentity;
         }
 
+        @Override
+        public Set<IdentitySchemaNode> getDerivedIdentities() {
+            return derivedIdentities;
+        }
+
+        private void setDerivedIdentities(Set<IdentitySchemaNode> derivedIdentities) {
+            if (derivedIdentities != null) {
+                this.derivedIdentities = derivedIdentities;
+            }
+        }
+
         @Override
         public String getDescription() {
             return description;
@@ -160,6 +180,10 @@ public final class IdentitySchemaNodeBuilder extends AbstractSchemaNodeBuilder {
             }
         }
 
+        public IdentitySchemaNodeBuilder toBuilder() {
+            return IdentitySchemaNodeBuilder.this;
+        }
+
         @Override
         public int hashCode() {
             final int prime = 31;
index 76732c9bae3a93434dfa4aaad1023e5a88c5359f..b8b77e20c833c29c60f356c55ea2d64b9c72abf4 100644 (file)
@@ -32,7 +32,7 @@ public final class IdentityrefTypeBuilder extends AbstractTypeAwareBuilder imple
 
     private final String baseString;
     private final SchemaPath schemaPath;
-    private QName baseQName;
+    private IdentitySchemaNodeBuilder baseIdentity;
 
     public IdentityrefTypeBuilder(final String moduleName, final int line, final String baseString,
             final SchemaPath schemaPath) {
@@ -48,15 +48,15 @@ public final class IdentityrefTypeBuilder extends AbstractTypeAwareBuilder imple
 
     @Override
     public IdentityrefType build() {
-        return new IdentityrefType(baseQName, schemaPath);
+        return new IdentityrefType(baseIdentity.build(), schemaPath);
     }
 
     public String getBaseString() {
         return baseString;
     }
 
-    public void setBaseQName(QName baseQName) {
-        this.baseQName = baseQName;
+    public void setBaseIdentity(IdentitySchemaNodeBuilder baseIdentity) {
+        this.baseIdentity = baseIdentity;
     }
 
     @Override
@@ -214,7 +214,7 @@ public final class IdentityrefTypeBuilder extends AbstractTypeAwareBuilder imple
         final StringBuilder result = new StringBuilder(IdentityrefTypeBuilder.class.getSimpleName());
         result.append("[");
         result.append(", base=");
-        result.append(baseQName);
+        result.append(baseIdentity);
         result.append("]");
         return result.toString();
     }
index eeae990a2daecccbffd38101f4d1872314b27bb6..954f6c9261018b20eeab9ecbeb27744de8b94030 100644 (file)
@@ -129,7 +129,7 @@ public final class YangParserImpl implements YangModelParser {
         List<ModuleBuilder> sorted = ModuleDependencySort.sort(builders);
 
         final LinkedHashMap<String, TreeMap<Date, ModuleBuilder>> modules = orderModules(sorted);
-        return new LinkedHashSet<>(buildWithContext(modules, null).values());
+        return new LinkedHashSet<>(build(modules).values());
     }
 
     @Override
@@ -413,8 +413,8 @@ public final class YangParserImpl implements YangModelParser {
         for (Map.Entry<String, TreeMap<Date, ModuleBuilder>> entry : modules.entrySet()) {
             for (Map.Entry<Date, ModuleBuilder> childEntry : entry.getValue().entrySet()) {
                 final ModuleBuilder module = childEntry.getValue();
-                resolveDirtyNodes(modules, module);
                 resolveIdentities(modules, module);
+                resolveDirtyNodes(modules, module);
                 resolveUnknownNodes(modules, module);
             }
         }
@@ -425,8 +425,8 @@ public final class YangParserImpl implements YangModelParser {
         for (Map.Entry<String, TreeMap<Date, ModuleBuilder>> entry : modules.entrySet()) {
             for (Map.Entry<Date, ModuleBuilder> childEntry : entry.getValue().entrySet()) {
                 final ModuleBuilder module = childEntry.getValue();
-                resolveDirtyNodesWithContext(modules, module, context);
                 resolveIdentitiesWithContext(modules, module, context);
+                resolveDirtyNodesWithContext(modules, module, context);
                 resolveUnknownNodesWithContext(modules, module, context);
             }
         }
@@ -451,7 +451,13 @@ public final class YangParserImpl implements YangModelParser {
                 } else if (nodeToResolve.getTypedef() instanceof IdentityrefTypeBuilder) {
                     // special handling for identityref types
                     IdentityrefTypeBuilder idref = (IdentityrefTypeBuilder) nodeToResolve.getTypedef();
-                    nodeToResolve.setType(new IdentityrefType(findFullQName(modules, module, idref), idref.getPath()));
+                    IdentitySchemaNodeBuilder identity = findBaseIdentity(modules, module, idref.getBaseString(),
+                            idref.getLine());
+                    if (identity == null) {
+                        throw new YangParseException(module.getName(), idref.getLine(), "Failed to find base identity");
+                    }
+                    idref.setBaseIdentity(identity);
+                    nodeToResolve.setType(idref.build());
                 } else {
                     resolveType(nodeToResolve, modules, module);
                 }
@@ -470,7 +476,10 @@ public final class YangParserImpl implements YangModelParser {
                 } else if (nodeToResolve.getTypedef() instanceof IdentityrefTypeBuilder) {
                     // special handling for identityref types
                     IdentityrefTypeBuilder idref = (IdentityrefTypeBuilder) nodeToResolve.getTypedef();
-                    nodeToResolve.setType(new IdentityrefType(findFullQName(modules, module, idref), idref.getPath()));
+                    IdentitySchemaNodeBuilder identity = findBaseIdentity(modules, module, idref.getBaseString(),
+                            idref.getLine());
+                    idref.setBaseIdentity(identity);
+                    nodeToResolve.setType(idref.build());
                 } else {
                     resolveTypeWithContext(nodeToResolve, modules, module, context);
                 }
@@ -745,35 +754,16 @@ public final class YangParserImpl implements YangModelParser {
         final Set<IdentitySchemaNodeBuilder> identities = module.getIdentities();
         for (IdentitySchemaNodeBuilder identity : identities) {
             final String baseIdentityName = identity.getBaseIdentityName();
+            final int line = identity.getLine();
             if (baseIdentityName != null) {
-                String baseIdentityPrefix;
-                String baseIdentityLocalName;
-                if (baseIdentityName.contains(":")) {
-                    final String[] splitted = baseIdentityName.split(":");
-                    baseIdentityPrefix = splitted[0];
-                    baseIdentityLocalName = splitted[1];
-                } else {
-                    baseIdentityPrefix = module.getPrefix();
-                    baseIdentityLocalName = baseIdentityName;
-                }
-                final ModuleBuilder dependentModule = findModuleFromBuilders(modules, module, baseIdentityPrefix,
-                        identity.getLine());
-
-                IdentitySchemaNodeBuilder baseIdentity = null;
-                final Set<IdentitySchemaNodeBuilder> dependentModuleIdentities = dependentModule.getIdentities();
-                for (IdentitySchemaNodeBuilder idBuilder : dependentModuleIdentities) {
-                    if (idBuilder.getQName().getLocalName().equals(baseIdentityLocalName)) {
-                        baseIdentity = idBuilder;
-                        break;
-                    }
-                }
+                IdentitySchemaNodeBuilder baseIdentity = findBaseIdentity(modules, module, baseIdentityName, line);
                 if (baseIdentity == null) {
-                    throw new YangParseException(module.getName(), identity.getLine(),
-                            "Base identity " + baseIdentityName + " not found");
+                    throw new YangParseException(module.getName(), identity.getLine(), "Failed to find base identity");
                 } else {
                     identity.setBaseIdentity(baseIdentity);
+                    IdentitySchemaNode built = identity.build();
+                    baseIdentity.addDerivedIdentity(built);
                 }
-
             }
         }
     }
@@ -795,37 +785,22 @@ public final class YangParserImpl implements YangModelParser {
         final Set<IdentitySchemaNodeBuilder> identities = module.getIdentities();
         for (IdentitySchemaNodeBuilder identity : identities) {
             final String baseIdentityName = identity.getBaseIdentityName();
+            final int line = identity.getLine();
             if (baseIdentityName != null) {
-                String baseIdentityPrefix;
-                String baseIdentityLocalName;
-                if (baseIdentityName.contains(":")) {
-                    final String[] splitted = baseIdentityName.split(":");
-                    baseIdentityPrefix = splitted[0];
-                    baseIdentityLocalName = splitted[1];
-                } else {
-                    baseIdentityPrefix = module.getPrefix();
-                    baseIdentityLocalName = baseIdentityName;
-                }
-                final ModuleBuilder dependentModuleBuilder = findModuleFromBuilders(modules, module,
-                        baseIdentityPrefix, identity.getLine());
-
-                if (dependentModuleBuilder == null) {
-                    final Module dependentModule = findModuleFromContext(context, module, baseIdentityPrefix,
-                            identity.getLine());
-                    final Set<IdentitySchemaNode> dependentModuleIdentities = dependentModule.getIdentities();
-                    for (IdentitySchemaNode idNode : dependentModuleIdentities) {
-                        if (idNode.getQName().getLocalName().equals(baseIdentityLocalName)) {
-                            identity.setBaseIdentity(idNode);
-                        }
+                IdentitySchemaNodeBuilder baseIdentity = findBaseIdentity(modules, module, baseIdentityName, line);
+                if (baseIdentity == null) {
+                    IdentitySchemaNode baseId = findBaseIdentityFromContext(modules, module, baseIdentityName, line,
+                            context);
+                    identity.setBaseIdentity(baseId);
+                    IdentitySchemaNode built = identity.build();
+                    if (baseId instanceof IdentitySchemaNodeBuilder.IdentitySchemaNodeImpl) {
+                        ((IdentitySchemaNodeBuilder.IdentitySchemaNodeImpl) baseId).toBuilder().addDerivedIdentity(
+                                built);
                     }
                 } else {
-                    final Set<IdentitySchemaNodeBuilder> dependentModuleIdentities = dependentModuleBuilder
-                            .getIdentities();
-                    for (IdentitySchemaNodeBuilder idBuilder : dependentModuleIdentities) {
-                        if (idBuilder.getQName().getLocalName().equals(baseIdentityLocalName)) {
-                            identity.setBaseIdentity(idBuilder);
-                        }
-                    }
+                    identity.setBaseIdentity(baseIdentity);
+                    IdentitySchemaNode built = identity.build();
+                    baseIdentity.addDerivedIdentity(built);
                 }
             }
         }
index 6af2c24118cd7283625b72170f8609344f862ce6..6f3bb1757ab261fcf59ecb1cb1e267a45433088c 100644 (file)
@@ -616,13 +616,19 @@ public final class GroupingUtils {
      */
     public static void performRefine(UsesNodeBuilder usesNode) {
         for (RefineHolder refine : usesNode.getRefines()) {
-            DataSchemaNodeBuilder nodeToRefine = null;
-            for (DataSchemaNodeBuilder dataNode : usesNode.getParent().getChildNodeBuilders()) {
-                if (refine.getName().equals(dataNode.getQName().getLocalName())) {
-                    nodeToRefine = dataNode;
-                    break;
+            String refineTargetPath = refine.getName();
+
+            String[] splitted = refineTargetPath.split("/");
+            Builder currentNode = usesNode.getParent();
+            for (String pathElement : splitted) {
+                if (currentNode instanceof DataNodeContainerBuilder) {
+                    currentNode = ((DataNodeContainerBuilder) currentNode).getDataChildByName(pathElement);
+                } else if (currentNode instanceof ChoiceBuilder) {
+                    currentNode = ((ChoiceBuilder) currentNode).getCaseNodeByName(pathElement);
                 }
             }
+
+            DataSchemaNodeBuilder nodeToRefine = (DataSchemaNodeBuilder) currentNode;
             if (nodeToRefine == null) {
                 throw new YangParseException(refine.getModuleName(), refine.getLine(), "Refine target node '"
                         + refine.getName() + "' not found");
index eff2d4f24816c1217d139cebcc5a9e5ec63f4af1..da4cb1e57a6f55b2dce64674a9425b1d13ce7bb4 100644 (file)
@@ -12,11 +12,13 @@ import java.util.Arrays;
 import java.util.Date;
 import java.util.List;
 import java.util.Map;
+import java.util.Set;
 import java.util.TreeMap;
 
 import org.opendaylight.yangtools.yang.common.QName;
 import org.opendaylight.yangtools.yang.model.api.ChoiceNode;
 import org.opendaylight.yangtools.yang.model.api.DataNodeContainer;
+import org.opendaylight.yangtools.yang.model.api.IdentitySchemaNode;
 import org.opendaylight.yangtools.yang.model.api.Module;
 import org.opendaylight.yangtools.yang.model.api.ModuleImport;
 import org.opendaylight.yangtools.yang.model.api.NotificationDefinition;
@@ -35,7 +37,7 @@ import org.opendaylight.yangtools.yang.parser.builder.impl.ChoiceBuilder.ChoiceN
 import org.opendaylight.yangtools.yang.parser.builder.impl.ChoiceCaseBuilder;
 import org.opendaylight.yangtools.yang.parser.builder.impl.ChoiceCaseBuilder.ChoiceCaseNodeImpl;
 import org.opendaylight.yangtools.yang.parser.builder.impl.ContainerSchemaNodeBuilder.ContainerSchemaNodeImpl;
-import org.opendaylight.yangtools.yang.parser.builder.impl.IdentityrefTypeBuilder;
+import org.opendaylight.yangtools.yang.parser.builder.impl.IdentitySchemaNodeBuilder;
 import org.opendaylight.yangtools.yang.parser.builder.impl.ListSchemaNodeBuilder.ListSchemaNodeImpl;
 import org.opendaylight.yangtools.yang.parser.builder.impl.ModuleBuilder;
 import org.opendaylight.yangtools.yang.parser.builder.impl.NotificationBuilder.NotificationDefinitionImpl;
@@ -566,25 +568,63 @@ public final class ParserUtils {
             return true;
         }
 
-        public static def QName findFullQName(Map<String, TreeMap<Date, ModuleBuilder>> modules,
-            ModuleBuilder module, IdentityrefTypeBuilder idref) {
-            var QName result = null;
-            val String baseString = idref.getBaseString();
-            if (baseString.contains(":")) {
-                val String[] splittedBase = baseString.split(":");
-                if (splittedBase.length > 2) {
-                    throw new YangParseException(module.getName(), idref.getLine(),
-                        "Failed to parse identityref base: " + baseString);
-                }
-                val prefix = splittedBase.get(0);
-                val name = splittedBase.get(1);
-                val dependentModule = findModuleFromBuilders(modules, module, prefix, idref.getLine());
-                result = new QName(dependentModule.getNamespace(), dependentModule.getRevision(), prefix, name);
-            } else {
-                result = new QName(module.getNamespace(), module.getRevision(), module.getPrefix(), baseString);
+    public static def IdentitySchemaNodeBuilder findBaseIdentity(Map<String, TreeMap<Date, ModuleBuilder>> modules,
+        ModuleBuilder module, String baseString, int line) {
+        var IdentitySchemaNodeBuilder result = null;
+        if (baseString.contains(":")) {
+            val String[] splittedBase = baseString.split(":");
+            if (splittedBase.length > 2) {
+                throw new YangParseException(module.getName(), line, "Failed to parse identityref base: " +
+                    baseString);
+            }
+            val prefix = splittedBase.get(0);
+            val name = splittedBase.get(1);
+            val dependentModule = findModuleFromBuilders(modules, module, prefix, line);
+            if (dependentModule !== null) {
+                result = findIdentity(dependentModule.identities, name);
+            }
+        } else {
+            result = findIdentity(module.identities, baseString);
+        }
+        return result;
+    }
+
+    public static def IdentitySchemaNode findBaseIdentityFromContext(Map<String, TreeMap<Date, ModuleBuilder>> modules,
+            ModuleBuilder module, String baseString, int line, SchemaContext context) {
+        var IdentitySchemaNode result = null;
+
+        val String[] splittedBase = baseString.split(":");
+        if (splittedBase.length > 2) {
+            throw new YangParseException(module.getName(), line, "Failed to parse identityref base: " + baseString);
+        }
+        val prefix = splittedBase.get(0);
+        val name = splittedBase.get(1);
+        val dependentModule = findModuleFromContext(context, module, prefix, line);
+        result = findIdentityNode(dependentModule.identities, name);
+
+        if (result == null) {
+            throw new YangParseException(module.name, line, "Failed to find base identity");
+        }
+        return result;
+    }
+
+    private static def IdentitySchemaNodeBuilder findIdentity(Set<IdentitySchemaNodeBuilder> identities, String name) {
+        for (identity : identities) {
+            if (identity.QName.localName.equals(name)) {
+                return identity;
             }
-            return result;
         }
+        return null;
+    }
+
+    private static def IdentitySchemaNode findIdentityNode(Set<IdentitySchemaNode> identities, String name) {
+        for (identity : identities) {
+            if (identity.QName.localName.equals(name)) {
+                return identity;
+            }
+        }
+        return null;
+    }
 
         /**
      * Get module in which this node is defined.
index d46f5077805157171c5278e1e0e12601c4ba9626..12a97c19e38751544f0f74e9211464461b8f2769 100644 (file)
@@ -488,7 +488,7 @@ final class YangModelBasicValidationListener extends YangParserBaseListener {
      */
     @Override
     public void enterRefine_stmt(Refine_stmtContext ctx) {
-        BasicValidations.checkIdentifier(ctx);
+        BasicValidations.checkSchemaNodeIdentifier(ctx);
     }
 
     /**
index c6c559481eb9b118d727022a79e00399a8e1a78b..f89c76208b22638777c90ae3cb9b0f7de23b1a3c 100644 (file)
@@ -53,25 +53,27 @@ public class GroupingTest {
         assertEquals(1, usesNodes.size());
         UsesNode usesNode = usesNodes.iterator().next();
         Map<SchemaPath, SchemaNode> refines = usesNode.getRefines();
-        assertEquals(3, refines.size());
+        assertEquals(4, refines.size());
 
         LeafSchemaNode refineLeaf = null;
         ContainerSchemaNode refineContainer = null;
         ListSchemaNode refineList = null;
+        LeafSchemaNode refineInnerLeaf = null;
         for (Map.Entry<SchemaPath, SchemaNode> entry : refines.entrySet()) {
             SchemaNode value = entry.getValue();
-            if (value instanceof LeafSchemaNode) {
+            if ("address".equals(value.getQName().getLocalName())) {
                 refineLeaf = (LeafSchemaNode) value;
-            } else if (value instanceof ContainerSchemaNode) {
+            } else if ("port".equals(value.getQName().getLocalName())) {
                 refineContainer = (ContainerSchemaNode) value;
-            } else if (value instanceof ListSchemaNode) {
+            } else if ("addresses".equals(value.getQName().getLocalName())) {
                 refineList = (ListSchemaNode) value;
+            } else if ("id".equals(value.getQName().getLocalName())) {
+                refineInnerLeaf = (LeafSchemaNode)value;
             }
         }
 
         // leaf address
         assertNotNull(refineLeaf);
-        assertEquals("address", refineLeaf.getQName().getLocalName());
         assertEquals("IP address of target node", refineLeaf.getDescription());
         assertEquals("address reference added by refine", refineLeaf.getReference());
         assertFalse(refineLeaf.isConfiguration());
@@ -81,6 +83,7 @@ public class GroupingTest {
         MustDefinition leafMust = leafMustConstraints.iterator().next();
         assertEquals("\"ifType != 'ethernet' or (ifType = 'ethernet' and ifMTU = 1500)\"", leafMust.toString());
 
+
         // container port
         assertNotNull(refineContainer);
         Set<MustDefinition> mustConstraints = refineContainer.getConstraints().getMustConstraints();
@@ -97,6 +100,10 @@ public class GroupingTest {
         assertFalse(refineList.isConfiguration());
         assertEquals(2, (int) refineList.getConstraints().getMinElements());
         assertEquals(12, (int) refineList.getConstraints().getMaxElements());
+
+        // leaf id
+        assertNotNull(refineInnerLeaf);
+        assertEquals("id of address", refineInnerLeaf.getDescription());
     }
 
     @Test
index d80ebd778528cd40bf0fc2685ef37bff8e58eba7..aff89762e089feac5ea0b2241128c604fd6c03f5 100644 (file)
@@ -12,7 +12,6 @@ import static org.junit.Assert.*;
 import java.io.File;
 import java.io.FileNotFoundException;
 import java.net.URI;
-import java.util.ArrayList;
 import java.util.List;
 import java.util.Set;
 
@@ -176,16 +175,27 @@ public class TypesResolutionTest {
     public void testIdentity() {
         Module tested = TestUtils.findModule(testedModules, "custom-types-test");
         Set<IdentitySchemaNode> identities = tested.getIdentities();
-        IdentitySchemaNode testedIdentity = null;
+        assertEquals(5, identities.size());
+        IdentitySchemaNode cryptoAlg = null;
+        IdentitySchemaNode cryptoBase = null;
         for (IdentitySchemaNode id : identities) {
             if (id.getQName().getLocalName().equals("crypto-alg")) {
-                testedIdentity = id;
-                IdentitySchemaNode baseIdentity = id.getBaseIdentity();
-                assertEquals("crypto-base", baseIdentity.getQName().getLocalName());
-                assertNull(baseIdentity.getBaseIdentity());
+                cryptoAlg = id;
+            } else if ("crypto-base".equals(id.getQName().getLocalName())) {
+                cryptoBase = id;
             }
         }
-        assertNotNull(testedIdentity);
+        assertNotNull(cryptoAlg);
+        IdentitySchemaNode baseIdentity = cryptoAlg.getBaseIdentity();
+        assertEquals("crypto-base", baseIdentity.getQName().getLocalName());
+        assertTrue(cryptoAlg.getDerivedIdentities().isEmpty());
+        assertNull(baseIdentity.getBaseIdentity());
+
+
+        assertNotNull(cryptoBase);
+        baseIdentity = cryptoAlg.getBaseIdentity();
+        assertNull(cryptoBase.getBaseIdentity());
+        assertEquals(3, cryptoBase.getDerivedIdentities().size());
     }
 
     @Test
@@ -305,7 +315,7 @@ public class TypesResolutionTest {
         Set<TypeDefinition<?>> typedefs = tested.getTypeDefinitions();
         TypeDefinition<?> testedType = TestUtils.findTypedef(typedefs, "service-type-ref");
         IdentityrefType baseType = (IdentityrefType) testedType.getBaseType();
-        QName identity = baseType.getIdentity();
+        QName identity = baseType.getIdentity().getQName();
         assertEquals(URI.create("urn:custom.types.demo"), identity.getNamespace());
         assertEquals(TestUtils.createDate("2012-04-16"), identity.getRevision());
         assertEquals("iit", identity.getPrefix());
index 73fc9718a1dcdd49af7ec338cf5f65715b33e2d4..1389db1c5319c55e0f03abd747c235c8057a38c2 100644 (file)
@@ -180,13 +180,16 @@ module nodes {
                     config false;
                     presence "presence is required";
                 }
-                refine addresses {
+                refine "addresses" {
                     description "description of addresses defined by refine";
                     reference "addresses reference added by refine";
                     config false;
                     min-elements 2;
                     max-elements 12;
                 }
+                refine addresses/id {
+                    description "id of address";
+                }
             }
         }
     }
index 68e008c1d5910b912ba01a3d4e6825145cea4315..050d5c0de9866828215fc25f91f4a9dc03006119 100644 (file)
@@ -64,6 +64,11 @@ module custom-types-test {
         type service-type-ref;
     }
 
+    identity crypto-id {
+        base "crypto-base";
+        description "crypto-id description";
+    }
+
     identity crypto-base {
         description "crypto-base description";
     }
@@ -73,6 +78,11 @@ module custom-types-test {
         description "crypto-alg description";
     }
 
+    identity crypto-def {
+        base "crypto-base";
+        description "crypto-def description";
+    }
+
     leaf mybits {
         type bits {
             bit disable-nagle {