BUG-1210: refactored imports handling in parser.
[yangtools.git] / yang / yang-parser-impl / src / main / java / org / opendaylight / yangtools / yang / parser / builder / impl / BuilderUtils.java
index 082ff6953837f19fe57d22e48a22f4814db5ffe4..70eb185ca25b3063538a62c2285526d1a96d08ef 100644 (file)
@@ -13,13 +13,11 @@ import com.google.common.base.Preconditions;
 import com.google.common.base.Splitter;
 import com.google.common.collect.Collections2;
 import com.google.common.io.ByteSource;
-
 import java.io.ByteArrayOutputStream;
 import java.io.File;
 import java.io.FileNotFoundException;
 import java.io.IOException;
 import java.io.InputStream;
-import java.net.URI;
 import java.util.ArrayList;
 import java.util.Collection;
 import java.util.Date;
@@ -29,6 +27,7 @@ import java.util.List;
 import java.util.Map;
 import java.util.Set;
 import java.util.TreeMap;
+
 import org.apache.commons.io.IOUtils;
 import org.opendaylight.yangtools.yang.common.QName;
 import org.opendaylight.yangtools.yang.model.api.AnyXmlSchemaNode;
@@ -67,8 +66,9 @@ import org.slf4j.LoggerFactory;
 public final class BuilderUtils {
 
     private static final Logger LOG = LoggerFactory.getLogger(BuilderUtils.class);
-    private static final Splitter SLASH_SPLITTER = Splitter.on('/');
+    private static final Splitter SLASH_SPLITTER = Splitter.on('/').omitEmptyStrings();
     private static final Splitter COLON_SPLITTER = Splitter.on(':');
+    private static final Date NULL_DATE = new Date(0L);
     private static final String INPUT = "input";
     private static final String OUTPUT = "output";
 
@@ -123,25 +123,6 @@ public final class BuilderUtils {
         return schemaPath.createChild(qname);
     }
 
-    /**
-     * Get module import referenced by given prefix.
-     *
-     * @param builder
-     *            module to search
-     * @param prefix
-     *            prefix associated with import
-     * @return ModuleImport based on given prefix
-     */
-    public static ModuleImport getModuleImport(final ModuleBuilder builder, final String prefix) {
-        for (ModuleImport mi : builder.getModuleImports()) {
-            if (mi.getPrefix().equals(prefix)) {
-                return mi;
-
-            }
-        }
-        return null;
-    }
-
     /**
      * Find dependent module based on given prefix
      *
@@ -157,15 +138,15 @@ public final class BuilderUtils {
      */
     public static ModuleBuilder findModuleFromBuilders(final Map<String, TreeMap<Date, ModuleBuilder>> modules,
             final ModuleBuilder module, final String prefix, final int line) {
-        ModuleBuilder dependentModule = null;
-        Date dependentModuleRevision = null;
+        ModuleBuilder dependentModule;
+        Date dependentModuleRevision;
 
         if (prefix == null) {
             dependentModule = module;
         } else if (prefix.equals(module.getPrefix())) {
             dependentModule = module;
         } else {
-            ModuleImport dependentModuleImport = getModuleImport(module, prefix);
+            ModuleImport dependentModuleImport = module.getImport(prefix);
             if (dependentModuleImport == null) {
                 throw new YangParseException(module.getName(), line, "No import found with prefix '" + prefix + "'.");
             }
@@ -193,20 +174,19 @@ public final class BuilderUtils {
      * @param currentModule
      *            current module
      * @param prefix
-     *            current prefix used to reference dependent module
+     *            prefix used to reference dependent module
      * @param line
      *            current line in yang model
-     * @return module based on given prefix if found in context, null otherwise
+     * @return module based on import with given prefix if found in context,
+     *         null otherwise
+     * @throws YangParseException
+     *             if no import found with given prefix
      */
     public static Module findModuleFromContext(final SchemaContext context, final ModuleBuilder currentModule,
             final String prefix, final int line) {
-        if (context == null) {
-            throw new YangParseException(currentModule.getName(), line, "Cannot find module with prefix '" + prefix
-                    + "'.");
-        }
         TreeMap<Date, Module> modulesByRevision = new TreeMap<>();
 
-        ModuleImport dependentModuleImport = BuilderUtils.getModuleImport(currentModule, prefix);
+        ModuleImport dependentModuleImport = currentModule.getImport(prefix);
         if (dependentModuleImport == null) {
             throw new YangParseException(currentModule.getName(), line, "No import found with prefix '" + prefix + "'.");
         }
@@ -217,18 +197,22 @@ public final class BuilderUtils {
             if (contextModule.getName().equals(dependentModuleName)) {
                 Date revision = contextModule.getRevision();
                 if (revision == null) {
-                    revision = new Date(0L);
+                    revision = NULL_DATE;
                 }
                 modulesByRevision.put(revision, contextModule);
             }
         }
 
-        Module result = null;
+        Module result;
         if (dependentModuleRevision == null) {
             result = modulesByRevision.get(modulesByRevision.firstKey());
         } else {
             result = modulesByRevision.get(dependentModuleRevision);
         }
+        if (result == null) {
+            throw new YangParseException(currentModule.getName(), line, "Module not found for prefix " + prefix);
+        }
+
         return result;
     }
 
@@ -240,22 +224,20 @@ public final class BuilderUtils {
      * @return SchemaPath from given String
      */
     public static SchemaPath parseXPathString(final String xpathString) {
-        final boolean absolute = xpathString.indexOf('/') == 0;
+        final boolean absolute = !xpathString.isEmpty() && xpathString.charAt(0) == '/';
 
-        final List<QName> path = new ArrayList<QName>();
+        final List<QName> path = new ArrayList<>();
         for (String pathElement : SLASH_SPLITTER.split(xpathString)) {
-            if (pathElement.length() > 0) {
-                final Iterator<String> it = COLON_SPLITTER.split(pathElement).iterator();
-                final String s = it.next();
+            final Iterator<String> it = COLON_SPLITTER.split(pathElement).iterator();
+            final String s = it.next();
 
-                final QName name;
-                if (it.hasNext()) {
-                    name = new QName(null, null, s, it.next());
-                } else {
-                    name = new QName(null, null, null, s);
-                }
-                path.add(name);
+            final QName name;
+            if (it.hasNext()) {
+                name = new QName(null, null, s, it.next());
+            } else {
+                name = new QName(null, null, null, s);
             }
+            path.add(name);
         }
         return SchemaPath.create(path, absolute);
     }
@@ -372,33 +354,6 @@ public final class BuilderUtils {
         }
     }
 
-    /**
-     * Set config flag to new value.
-     *
-     * @param node
-     *            node to update
-     * @param config
-     *            new config value
-     */
-    public static void setNodeConfig(final DataSchemaNodeBuilder node, final Boolean config) {
-        if (node instanceof ContainerSchemaNodeBuilder || node instanceof LeafSchemaNodeBuilder
-                || node instanceof LeafListSchemaNodeBuilder || node instanceof ListSchemaNodeBuilder
-                || node instanceof ChoiceBuilder || node instanceof AnyXmlBuilder) {
-            node.setConfiguration(config);
-        }
-        if (node instanceof DataNodeContainerBuilder) {
-            DataNodeContainerBuilder dataNodeChild = (DataNodeContainerBuilder) node;
-            for (DataSchemaNodeBuilder inner : dataNodeChild.getChildNodeBuilders()) {
-                setNodeConfig(inner, config);
-            }
-        } else if (node instanceof ChoiceBuilder) {
-            ChoiceBuilder choiceChild = (ChoiceBuilder) node;
-            for (ChoiceCaseBuilder inner : choiceChild.getCases()) {
-                setNodeConfig(inner, config);
-            }
-        }
-    }
-
     public static DataSchemaNodeBuilder findSchemaNode(final List<QName> path, final SchemaNodeBuilder parentNode) {
         DataSchemaNodeBuilder node = null;
         SchemaNodeBuilder parent = parentNode;
@@ -662,7 +617,7 @@ public final class BuilderUtils {
                 throw new YangParseException(module.getName(), line, "Failed to parse identityref base: " + baseString);
             }
 
-            ModuleBuilder dependentModule = findModuleFromBuilders(modules, module, prefix, line);
+            ModuleBuilder dependentModule = getModuleByPrefix(module, prefix);
             if (dependentModule == null) {
                 return null;
             }
@@ -697,7 +652,6 @@ public final class BuilderUtils {
         while (!(parent instanceof ModuleBuilder)) {
             parent = parent.getParent();
         }
-        Preconditions.checkState(parent instanceof ModuleBuilder);
         ModuleBuilder parentModule = (ModuleBuilder) parent;
         if (parentModule.isSubmodule()) {
             parentModule = parentModule.getParent();
@@ -706,12 +660,11 @@ public final class BuilderUtils {
     }
 
     public static Set<DataSchemaNodeBuilder> wrapChildNodes(final String moduleName, final int line,
-            final Set<DataSchemaNode> nodes, final SchemaPath parentPath, final URI ns, final Date rev,
-            final String pref) {
+            final Set<DataSchemaNode> nodes, final SchemaPath parentPath, final QName parentQName) {
         Set<DataSchemaNodeBuilder> result = new HashSet<>();
 
         for (DataSchemaNode node : nodes) {
-            QName qname = new QName(ns, rev, pref, node.getQName().getLocalName());
+            QName qname = QName.create(parentQName, node.getQName().getLocalName());
             DataSchemaNodeBuilder wrapped = wrapChildNode(moduleName, line, node, parentPath, qname);
             result.add(wrapped);
         }
@@ -744,11 +697,10 @@ public final class BuilderUtils {
     }
 
     public static Set<GroupingBuilder> wrapGroupings(final String moduleName, final int line,
-            final Set<GroupingDefinition> nodes, final SchemaPath parentPath, final URI ns, final Date rev,
-            final String pref) {
+            final Set<GroupingDefinition> nodes, final SchemaPath parentPath, final QName parentQName) {
         Set<GroupingBuilder> result = new HashSet<>();
         for (GroupingDefinition node : nodes) {
-            QName qname = new QName(ns, rev, pref, node.getQName().getLocalName());
+            QName qname = QName.create(parentQName, node.getQName().getLocalName());
             SchemaPath schemaPath = parentPath.createChild(qname);
             result.add(new GroupingBuilderImpl(moduleName, line, qname, schemaPath, node));
         }
@@ -756,12 +708,11 @@ public final class BuilderUtils {
     }
 
     public static Set<TypeDefinitionBuilder> wrapTypedefs(final String moduleName, final int line,
-            final DataNodeContainer dataNode, final SchemaPath parentPath, final URI ns, final Date rev,
-            final String pref) {
+            final DataNodeContainer dataNode, final SchemaPath parentPath, final QName parentQName) {
         Set<TypeDefinition<?>> nodes = dataNode.getTypeDefinitions();
         Set<TypeDefinitionBuilder> result = new HashSet<>();
         for (TypeDefinition<?> node : nodes) {
-            QName qname = new QName(ns, rev, pref, node.getQName().getLocalName());
+            QName qname = QName.create(parentQName, node.getQName().getLocalName());
             SchemaPath schemaPath = parentPath.createChild(qname);
             result.add(new TypeDefinitionBuilderImpl(moduleName, line, qname, schemaPath, ((ExtendedType) node)));
         }
@@ -769,11 +720,10 @@ public final class BuilderUtils {
     }
 
     public static List<UnknownSchemaNodeBuilderImpl> wrapUnknownNodes(final String moduleName, final int line,
-            final List<UnknownSchemaNode> nodes, final SchemaPath parentPath, final URI ns, final Date rev,
-            final String pref) {
+            final List<UnknownSchemaNode> nodes, final SchemaPath parentPath, final QName parentQName) {
         List<UnknownSchemaNodeBuilderImpl> result = new ArrayList<>();
         for (UnknownSchemaNode node : nodes) {
-            QName qname = new QName(ns, rev, pref, node.getQName().getLocalName());
+            QName qname = QName.create(parentQName, node.getQName().getLocalName());
             SchemaPath schemaPath = parentPath.createChild(qname);
             result.add(new UnknownSchemaNodeBuilderImpl(moduleName, line, qname, schemaPath, node));
         }
@@ -795,4 +745,12 @@ public final class BuilderUtils {
         }
     }
 
+    public static ModuleBuilder getModuleByPrefix(ModuleBuilder module, String prefix) {
+        if (prefix == null || prefix.isEmpty() || prefix.equals(module.getPrefix())) {
+            return module;
+        } else {
+            return module.getImportedModule(prefix);
+        }
+    }
+
 }