BUG-987: Fixed parsing of identity nodes. 04/6904/2
authorMartin Vitez <mvitez@cisco.com>
Mon, 12 May 2014 14:28:24 +0000 (16:28 +0200)
committerMartin Vitez <mvitez@cisco.com>
Mon, 12 May 2014 15:28:19 +0000 (17:28 +0200)
Change-Id: I97ff6ae9247b9a6b0b9f7d1ca6e48d56cd79e937
Signed-off-by: Martin Vitez <mvitez@cisco.com>
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/ModuleBuilder.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/ParserUtils.java

index 183c0d73d7af48c8db9e2383a09fd40aab9f6233..909773d987dd360e17df8371cd8cb6b68dfa725d 100644 (file)
@@ -13,7 +13,6 @@ import org.opendaylight.yangtools.yang.common.QName;
 import org.opendaylight.yangtools.yang.model.api.*;
 import org.opendaylight.yangtools.yang.parser.builder.api.AbstractSchemaNodeBuilder;
 import org.opendaylight.yangtools.yang.parser.util.Comparators;
-import org.opendaylight.yangtools.yang.parser.util.YangParseException;
 
 public final class IdentitySchemaNodeBuilder extends AbstractSchemaNodeBuilder {
     private boolean isBuilt;
@@ -29,21 +28,20 @@ public final class IdentitySchemaNodeBuilder extends AbstractSchemaNodeBuilder {
         instance = new IdentitySchemaNodeImpl(qname, path, derivedIdentities);
     }
 
+    IdentitySchemaNodeBuilder(final String moduleName, IdentitySchemaNode base) {
+        super(moduleName, 0, base.getQName());
+        schemaPath = base.getPath();
+        derivedIdentities.addAll(base.getDerivedIdentities());
+        unknownNodes.addAll(base.getUnknownSchemaNodes());
+        instance = new IdentitySchemaNodeImpl(qname, schemaPath, derivedIdentities);
+    }
+
     @Override
     public IdentitySchemaNode build() {
         if (!isBuilt) {
-            if (!(parentBuilder instanceof ModuleBuilder)) {
-                throw new YangParseException(moduleName, line, "Identity can be defined only under module (was" + parentBuilder + ")");
-            }
-            if (baseIdentity == null) {
-                if(baseIdentityBuilder != null) {
-                    baseIdentityBuilder.addDerivedIdentity(instance);
-                    baseIdentity = baseIdentityBuilder.build();
-                }
-            } else {
-                if(baseIdentity instanceof IdentitySchemaNodeImpl) {
-                    ((IdentitySchemaNodeImpl)baseIdentity).toBuilder().addDerivedIdentity(instance);
-                }
+            if(baseIdentityBuilder != null) {
+                baseIdentityBuilder.addDerivedIdentity(instance);
+                baseIdentity = baseIdentityBuilder.build();
             }
             instance.setBaseIdentity(baseIdentity);
 
@@ -109,10 +107,6 @@ public final class IdentitySchemaNodeBuilder extends AbstractSchemaNodeBuilder {
         this.baseIdentityBuilder = baseType;
     }
 
-    public void setBaseIdentity(final IdentitySchemaNode baseType) {
-        this.baseIdentity = baseType;
-    }
-
     public void addDerivedIdentity(IdentitySchemaNode derivedIdentity) {
         if (derivedIdentity != null) {
             derivedIdentities.add(derivedIdentity);
@@ -124,7 +118,7 @@ public final class IdentitySchemaNodeBuilder extends AbstractSchemaNodeBuilder {
         return "identity " + qname.getLocalName();
     }
 
-    private final class IdentitySchemaNodeImpl implements IdentitySchemaNode {
+    private static final class IdentitySchemaNodeImpl implements IdentitySchemaNode {
         private final QName qname;
         private final SchemaPath path;
         private IdentitySchemaNode baseIdentity;
@@ -190,10 +184,6 @@ public final class IdentitySchemaNodeBuilder extends AbstractSchemaNodeBuilder {
             }
         }
 
-        public IdentitySchemaNodeBuilder toBuilder() {
-            return IdentitySchemaNodeBuilder.this;
-        }
-
         @Override
         public int hashCode() {
             final int prime = 31;
index 3695ec5cf0e5d88cf9fc6978a443c68bfcbe9707..ced7b3ab393dfce4c1035bbe68c6cc74a63a5f84 100644 (file)
@@ -134,6 +134,7 @@ public class ModuleBuilder extends AbstractDataNodeContainerBuilder {
         schemaPath = new SchemaPath(Collections.<QName> emptyList(), true);
         submodule = false;
         instance = new ModuleImpl(base.getName(), base.getModuleSourcePath());
+        instance.setYangVersion(base.getYangVersion());
         actualPath.push(this);
         namespace = base.getNamespace();
         prefix = base.getPrefix();
@@ -149,7 +150,11 @@ public class ModuleBuilder extends AbstractDataNodeContainerBuilder {
         augments.addAll(base.getAugmentations());
         rpcs.addAll(base.getRpcs());
         notifications.addAll(base.getNotifications());
-        identities.addAll(base.getIdentities());
+
+        for (IdentitySchemaNode identityNode : base.getIdentities()) {
+            addedIdentities.add(new IdentitySchemaNodeBuilder(name, identityNode));
+        }
+
         features.addAll(base.getFeatures());
         deviations.addAll(base.getDeviations());
         extensions.addAll(base.getExtensionSchemaNodes());
@@ -1188,7 +1193,7 @@ public class ModuleBuilder extends AbstractDataNodeContainerBuilder {
             return source;
         }
 
-        // FIXME: prefix should not be taken into consideration, perhaps namespace too
+        // FIXME: perhaps namespace should not be taken into consideration
         @Override
         public int hashCode() {
             final int prime = 31;
@@ -1196,7 +1201,6 @@ public class ModuleBuilder extends AbstractDataNodeContainerBuilder {
             result = prime * result + ((namespace == null) ? 0 : namespace.hashCode());
             result = prime * result + ((name == null) ? 0 : name.hashCode());
             result = prime * result + ((revision == null) ? 0 : revision.hashCode());
-            result = prime * result + ((prefix == null) ? 0 : prefix.hashCode());
             result = prime * result + ((yangVersion == null) ? 0 : yangVersion.hashCode());
             return result;
         }
@@ -1234,13 +1238,6 @@ public class ModuleBuilder extends AbstractDataNodeContainerBuilder {
             } else if (!revision.equals(other.revision)) {
                 return false;
             }
-            if (prefix == null) {
-                if (other.prefix != null) {
-                    return false;
-                }
-            } else if (!prefix.equals(other.prefix)) {
-                return false;
-            }
             if (yangVersion == null) {
                 if (other.yangVersion != null) {
                     return false;
index 7448f130b2c3f615ab22d4e2f695b7ccc4bd1879..6c7824c8406b7f12172c313800039e1f6b9febe9 100644 (file)
@@ -8,6 +8,7 @@
 package org.opendaylight.yangtools.yang.parser.impl;
 
 import com.google.common.base.Preconditions;
+
 import org.antlr.v4.runtime.ANTLRInputStream;
 import org.antlr.v4.runtime.CommonTokenStream;
 import org.antlr.v4.runtime.tree.ParseTree;
@@ -21,7 +22,6 @@ import org.opendaylight.yangtools.yang.model.api.DataNodeContainer;
 import org.opendaylight.yangtools.yang.model.api.DataSchemaNode;
 import org.opendaylight.yangtools.yang.model.api.ExtensionDefinition;
 import org.opendaylight.yangtools.yang.model.api.GroupingDefinition;
-import org.opendaylight.yangtools.yang.model.api.IdentitySchemaNode;
 import org.opendaylight.yangtools.yang.model.api.Module;
 import org.opendaylight.yangtools.yang.model.api.ModuleIdentifier;
 import org.opendaylight.yangtools.yang.model.api.ModuleImport;
@@ -83,7 +83,6 @@ import java.util.TreeMap;
 import static com.google.common.base.Preconditions.checkNotNull;
 import static org.opendaylight.yangtools.yang.parser.util.ParserUtils.fillAugmentTarget;
 import static org.opendaylight.yangtools.yang.parser.util.ParserUtils.findBaseIdentity;
-import static org.opendaylight.yangtools.yang.parser.util.ParserUtils.findBaseIdentityFromContext;
 import static org.opendaylight.yangtools.yang.parser.util.ParserUtils.findModuleFromBuilders;
 import static org.opendaylight.yangtools.yang.parser.util.ParserUtils.findModuleFromContext;
 import static org.opendaylight.yangtools.yang.parser.util.ParserUtils.findSchemaNode;
@@ -615,6 +614,7 @@ public final class YangParserImpl implements YangModelParser {
         resolveUsesForGroupings(modules, null);
         resolveUsesForNodes(modules, null);
         resolveAugments(modules, null);
+        resolveIdentities(modules);
         resolveDeviations(modules);
 
         // build
@@ -660,6 +660,7 @@ public final class YangParserImpl implements YangModelParser {
         resolveUsesForGroupings(modules, context);
         resolveUsesForNodes(modules, context);
         resolveAugments(modules, context);
+        resolveIdentitiesWithContext(modules, context);
         resolveDeviationsWithContext(modules, context);
 
         // build
@@ -685,7 +686,6 @@ public final class YangParserImpl implements YangModelParser {
             for (Map.Entry<Date, ModuleBuilder> childEntry : entry.getValue().entrySet()) {
                 final ModuleBuilder module = childEntry.getValue();
                 resolveUnknownNodes(modules, module);
-                resolveIdentities(modules, module);
                 resolveDirtyNodes(modules, module);
             }
         }
@@ -705,7 +705,6 @@ public final class YangParserImpl implements YangModelParser {
             for (Map.Entry<Date, ModuleBuilder> childEntry : entry.getValue().entrySet()) {
                 final ModuleBuilder module = childEntry.getValue();
                 resolveUnknownNodesWithContext(modules, module, context);
-                resolveIdentitiesWithContext(modules, module, context);
                 resolveDirtyNodesWithContext(modules, module, context);
             }
         }
@@ -1065,6 +1064,29 @@ public final class YangParserImpl implements YangModelParser {
         return targetModule;
     }
 
+    private ModuleBuilder findTargetModule(final String prefix, final ModuleBuilder module,
+            final Map<String, TreeMap<Date, ModuleBuilder>> modules, final SchemaContext context, final int line) {
+        ModuleBuilder targetModule = null;
+
+        if (prefix == null || prefix.equals("")) {
+            targetModule = module;
+        } else {
+            targetModule = findModuleFromBuilders(modules, module, prefix, line);
+        }
+
+        if (targetModule == null && context != null) {
+            Module m = findModuleFromContext(context, module, prefix, line);
+            if (m != null) {
+                targetModule = new ModuleBuilder(m);
+                TreeMap<Date, ModuleBuilder> map = new TreeMap<>();
+                map.put(targetModule.getRevision(), targetModule);
+                modules.put(targetModule.getModuleName(), map);
+            }
+        }
+
+        return targetModule;
+    }
+
     /**
      * Go through identity statements defined in current module and resolve
      * their 'base' statement if present.
@@ -1074,18 +1096,24 @@ public final class YangParserImpl implements YangModelParser {
      * @param module
      *            module being resolved
      */
-    private void resolveIdentities(final Map<String, TreeMap<Date, ModuleBuilder>> modules, final ModuleBuilder module) {
-        final Set<IdentitySchemaNodeBuilder> identities = module.getAddedIdentities();
-        for (IdentitySchemaNodeBuilder identity : identities) {
-            final String baseIdentityName = identity.getBaseIdentityName();
-            final int line = identity.getLine();
-            if (baseIdentityName != null) {
-                IdentitySchemaNodeBuilder baseIdentity = findBaseIdentity(modules, module, baseIdentityName, line);
-                if (baseIdentity == null) {
-                    throw new YangParseException(module.getName(), identity.getLine(), "Failed to find base identity");
-                } else {
-                    identity.setBaseIdentity(baseIdentity);
+    private void resolveIdentities(final Map<String, TreeMap<Date, ModuleBuilder>> modules) {
+        for (Map.Entry<String, TreeMap<Date, ModuleBuilder>> entry : modules.entrySet()) {
+            for (Map.Entry<Date, ModuleBuilder> inner : entry.getValue().entrySet()) {
+                ModuleBuilder module = inner.getValue();
+                final Set<IdentitySchemaNodeBuilder> identities = module.getAddedIdentities();
+                for (IdentitySchemaNodeBuilder identity : identities) {
+                    final String baseIdentityName = identity.getBaseIdentityName();
+                    final int line = identity.getLine();
+                    if (baseIdentityName != null) {
+                        IdentitySchemaNodeBuilder baseIdentity = findBaseIdentity(modules, module, baseIdentityName, line);
+                        if (baseIdentity == null) {
+                            throw new YangParseException(module.getName(), identity.getLine(), "Failed to find base identity");
+                        } else {
+                            identity.setBaseIdentity(baseIdentity);
+                        }
+                    }
                 }
+
             }
         }
     }
@@ -1103,19 +1131,34 @@ public final class YangParserImpl implements YangModelParser {
      *            SchemaContext containing already resolved modules
      */
     private void resolveIdentitiesWithContext(final Map<String, TreeMap<Date, ModuleBuilder>> modules,
-            final ModuleBuilder module, final SchemaContext context) {
-        final Set<IdentitySchemaNodeBuilder> identities = module.getAddedIdentities();
-        for (IdentitySchemaNodeBuilder identity : identities) {
-            final String baseIdentityName = identity.getBaseIdentityName();
-            final int line = identity.getLine();
-            if (baseIdentityName != null) {
-                IdentitySchemaNodeBuilder baseIdentity = findBaseIdentity(modules, module, baseIdentityName, line);
-                if (baseIdentity == null) {
-                    IdentitySchemaNode baseId = findBaseIdentityFromContext(modules, module, baseIdentityName, line,
-                            context);
-                    identity.setBaseIdentity(baseId);
-                } else {
-                    identity.setBaseIdentity(baseIdentity);
+            final SchemaContext context) {
+        for (Map.Entry<String, TreeMap<Date, ModuleBuilder>> entry : modules.entrySet()) {
+            for (Map.Entry<Date, ModuleBuilder> inner : entry.getValue().entrySet()) {
+                ModuleBuilder module = inner.getValue();
+                final Set<IdentitySchemaNodeBuilder> identities = module.getAddedIdentities();
+                for (IdentitySchemaNodeBuilder identity : identities) {
+                    final String baseIdentityName = identity.getBaseIdentityName();
+                    final int line = identity.getLine();
+                    if (baseIdentityName != null) {
+
+                        IdentitySchemaNodeBuilder result = null;
+                        if (baseIdentityName.contains(":")) {
+                            String[] splittedBase = baseIdentityName.split(":");
+                            if (splittedBase.length > 2) {
+                                throw new YangParseException(module.getName(), line,
+                                        "Failed to parse identityref base: " + baseIdentityName);
+                            }
+                            String prefix = splittedBase[0];
+                            String name = splittedBase[1];
+                            ModuleBuilder dependentModule = findTargetModule(prefix, module, modules, context, line);
+                            if (dependentModule != null) {
+                                result = ParserUtils.findIdentity(dependentModule.getAddedIdentities(), name);
+                            }
+                        } else {
+                            result = ParserUtils.findIdentity(module.getAddedIdentities(), baseIdentityName);
+                        }
+                        identity.setBaseIdentity(result);
+                    }
                 }
             }
         }
index 2547296ef43f322c515b69c4886d7f6230bcc4f6..d295072f03400cde9b9e8131fa1f491423dd5b17 100644 (file)
@@ -17,7 +17,6 @@ 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.IdentitySchemaNode;
 import org.opendaylight.yangtools.yang.model.api.Module;
 import org.opendaylight.yangtools.yang.model.api.ModuleImport;
 import org.opendaylight.yangtools.yang.model.api.SchemaContext;
@@ -465,26 +464,7 @@ public final class ParserUtils {
         return result;
     }
 
-    public static IdentitySchemaNode findBaseIdentityFromContext(Map<String, TreeMap<Date, ModuleBuilder>> modules,
-            ModuleBuilder module, String baseString, int line, SchemaContext context) {
-        IdentitySchemaNode result = null;
-
-        String[] splittedBase = baseString.split(":");
-        if (splittedBase.length > 2) {
-            throw new YangParseException(module.getName(), line, "Failed to parse identityref base: " + baseString);
-        }
-        String prefix = splittedBase[0];
-        String name = splittedBase[1];
-        Module dependentModule = findModuleFromContext(context, module, prefix, line);
-        result = findIdentityNode(dependentModule.getIdentities(), name);
-
-        if (result == null) {
-            throw new YangParseException(module.getName(), line, "Failed to find base identity");
-        }
-        return result;
-    }
-
-    private static IdentitySchemaNodeBuilder findIdentity(Set<IdentitySchemaNodeBuilder> identities, String name) {
+    public static IdentitySchemaNodeBuilder findIdentity(Set<IdentitySchemaNodeBuilder> identities, String name) {
         for (IdentitySchemaNodeBuilder identity : identities) {
             if (identity.getQName().getLocalName().equals(name)) {
                 return identity;
@@ -493,15 +473,6 @@ public final class ParserUtils {
         return null;
     }
 
-    private static IdentitySchemaNode findIdentityNode(Set<IdentitySchemaNode> identities, String name) {
-        for (IdentitySchemaNode identity : identities) {
-            if (identity.getQName().getLocalName().equals(name)) {
-                return identity;
-            }
-        }
-        return null;
-    }
-
     /**
      * Get module in which this node is defined.
      *