Update ChoiceSchemaNode design
[yangtools.git] / yang / yang-data-impl / src / main / java / org / opendaylight / yangtools / yang / data / impl / leafref / LeafRefContextTreeBuilder.java
index 38dfb7550daad06abffbedb2255378c5a1403a48..ddda315c076b02e991ae311b29bdaf761929ac99 100644 (file)
@@ -7,11 +7,14 @@
  */
 package org.opendaylight.yangtools.yang.data.impl.leafref;
 
+import static com.google.common.base.Preconditions.checkNotNull;
+
 import java.io.ByteArrayInputStream;
 import java.io.IOException;
-import java.nio.charset.Charset;
+import java.nio.charset.StandardCharsets;
 import java.util.Collection;
 import java.util.LinkedList;
+import java.util.List;
 import java.util.Set;
 import org.opendaylight.yangtools.yang.model.api.ChoiceCaseNode;
 import org.opendaylight.yangtools.yang.model.api.ChoiceSchemaNode;
@@ -22,22 +25,21 @@ import org.opendaylight.yangtools.yang.model.api.LeafSchemaNode;
 import org.opendaylight.yangtools.yang.model.api.Module;
 import org.opendaylight.yangtools.yang.model.api.SchemaContext;
 import org.opendaylight.yangtools.yang.model.api.TypeDefinition;
-import org.opendaylight.yangtools.yang.model.util.Leafref;
+import org.opendaylight.yangtools.yang.model.api.TypedSchemaNode;
+import org.opendaylight.yangtools.yang.model.api.type.LeafrefTypeDefinition;
 
 class LeafRefContextTreeBuilder {
+    private final List<LeafRefContext> leafRefs = new LinkedList<>();
     private final SchemaContext schemaContext;
-    private final LinkedList<LeafRefContext> leafRefs;
 
-    public LeafRefContextTreeBuilder(final SchemaContext schemaContext) {
+    LeafRefContextTreeBuilder(final SchemaContext schemaContext) {
         this.schemaContext = schemaContext;
-        this.leafRefs = new LinkedList<LeafRefContext>();
     }
 
     public LeafRefContext buildLeafRefContextTree() throws IOException,
             LeafRefYangSyntaxErrorException {
-        final LeafRefContextBuilder rootBuilder = new LeafRefContextBuilder(
-                schemaContext.getQName(), schemaContext.getPath(),
-                schemaContext);
+        final LeafRefContextBuilder rootBuilder = new LeafRefContextBuilder(schemaContext.getQName(),
+            schemaContext.getPath(), schemaContext);
 
         final Set<Module> modules = schemaContext.getModules();
         for (final Module module : modules) {
@@ -100,10 +102,8 @@ class LeafRefContextTreeBuilder {
         } else if (node instanceof ChoiceSchemaNode) {
 
             final ChoiceSchemaNode choice = (ChoiceSchemaNode) node;
-            final Set<ChoiceCaseNode> cases = choice.getCases();
             // :FIXME choice without case
-
-            for (final ChoiceCaseNode caseNode : cases) {
+            for (final ChoiceCaseNode caseNode : choice.getCases().values()) {
                 final LeafRefContext childLeafRefContext = buildLeafRefContextReferencingTree(
                         caseNode, currentModule);
 
@@ -115,39 +115,27 @@ class LeafRefContextTreeBuilder {
                 }
             }
 
-        } else if (node instanceof LeafSchemaNode
-                || node instanceof LeafListSchemaNode) {
-
-            TypeDefinition<?> type = null;
-
-            if (node instanceof LeafSchemaNode) {
-                type = ((LeafSchemaNode) node).getType();
-            } else {
-                type = ((LeafListSchemaNode) node).getType();
-            }
+        } else if (node instanceof TypedSchemaNode) {
+            final TypeDefinition<?> type = ((TypedSchemaNode) node).getType();
 
-            // FIXME: fix case when type is e.g. typdef -> typedef -> leafref
-            if (type instanceof Leafref) {
-                final Leafref leafrefType = (Leafref) type;
-                final String leafRefPathString = leafrefType.getPathStatement()
-                        .toString();
+            // FIXME: fix case when type is e.g. typedef -> typedef -> leafref
+            if (type instanceof LeafrefTypeDefinition) {
+                final LeafrefTypeDefinition leafrefType = (LeafrefTypeDefinition) type;
+                final String leafRefPathString = leafrefType.getPathStatement().toString();
 
-                currentLeafRefContextBuilder
-                        .setLeafRefTargetPathString(leafRefPathString);
+                currentLeafRefContextBuilder.setLeafRefTargetPathString(leafRefPathString);
                 currentLeafRefContextBuilder.setReferencing(true);
 
-                final LeafRefPathParserImpl leafRefPathParser = new LeafRefPathParserImpl(
-                        schemaContext, currentModule, node);
+                final LeafRefPathParserImpl leafRefPathParser = new LeafRefPathParserImpl(schemaContext,
+                        checkNotNull(getBaseTypeModule(leafrefType), "Unable to find base module for leafref %s", node),
+                        node);
 
-                final ByteArrayInputStream leafRefPathInputStream = new ByteArrayInputStream(
-                        leafRefPathString.getBytes(Charset.forName("UTF-8")));
-                final LeafRefPath leafRefPath = leafRefPathParser
-                        .parseLeafRefPathSourceToSchemaPath(leafRefPathInputStream);
+                final LeafRefPath leafRefPath = leafRefPathParser.parseLeafRefPathSourceToSchemaPath(
+                    new ByteArrayInputStream(leafRefPathString.getBytes(StandardCharsets.UTF_8)));
 
                 currentLeafRefContextBuilder.setLeafRefTargetPath(leafRefPath);
 
-                final LeafRefContext currentLeafRefContext = currentLeafRefContextBuilder
-                        .build();
+                final LeafRefContext currentLeafRefContext = currentLeafRefContextBuilder.build();
                 leafRefs.add(currentLeafRefContext);
                 return currentLeafRefContext;
             }
@@ -156,6 +144,18 @@ class LeafRefContextTreeBuilder {
         return currentLeafRefContextBuilder.build();
     }
 
+    private Module getBaseTypeModule(final LeafrefTypeDefinition leafrefType) {
+        /*
+         * Find the first definition of supplied leafref type and return the
+         * module which contains this definition.
+         */
+        LeafrefTypeDefinition baseLeafRefType = leafrefType;
+        while (baseLeafRefType.getBaseType() != null) {
+            baseLeafRefType = baseLeafRefType.getBaseType();
+        }
+        return schemaContext.findModule(baseLeafRefType.getQName().getModule()).orElse(null);
+    }
+
     private LeafRefContext buildLeafRefContextReferencedByTree(
             final DataSchemaNode node, final Module currentModule) throws IOException,
             LeafRefYangSyntaxErrorException {
@@ -180,32 +180,21 @@ class LeafRefContextTreeBuilder {
                 }
             }
         } else if (node instanceof ChoiceSchemaNode) {
+            for (final ChoiceCaseNode caseNode : ((ChoiceSchemaNode) node).getCases().values()) {
+                final LeafRefContext childLeafRefContext = buildLeafRefContextReferencedByTree(caseNode, currentModule);
 
-            final ChoiceSchemaNode choice = (ChoiceSchemaNode) node;
-            final Set<ChoiceCaseNode> cases = choice.getCases();
-
-            for (final ChoiceCaseNode caseNode : cases) {
-                final LeafRefContext childLeafRefContext = buildLeafRefContextReferencedByTree(
-                        caseNode, currentModule);
-
-                if (childLeafRefContext.hasReferencedChild()
-                        || childLeafRefContext.isReferenced()) {
-                    currentLeafRefContextBuilder.addReferencedByChild(
-                            childLeafRefContext,
-                            childLeafRefContext.getNodeName());
+                if (childLeafRefContext.hasReferencedChild() || childLeafRefContext.isReferenced()) {
+                    currentLeafRefContextBuilder.addReferencedByChild(childLeafRefContext,
+                        childLeafRefContext.getNodeName());
                 }
             }
 
-        } else if (node instanceof LeafSchemaNode
-                || node instanceof LeafListSchemaNode) {
-
-            final LinkedList<LeafRefContext> foundLeafRefs = getLeafRefsFor(node,
-                    currentModule);
+        } else if (node instanceof LeafSchemaNode || node instanceof LeafListSchemaNode) {
+            final List<LeafRefContext> foundLeafRefs = getLeafRefsFor(node, currentModule);
             if (!foundLeafRefs.isEmpty()) {
                 currentLeafRefContextBuilder.setReferencedBy(true);
                 for (final LeafRefContext leafRef : foundLeafRefs) {
-                    currentLeafRefContextBuilder.addReferencedByLeafRefCtx(
-                            leafRef.getNodeName(), leafRef);
+                    currentLeafRefContextBuilder.addReferencedByLeafRefCtx(leafRef.getNodeName(), leafRef);
                 }
             }
         }
@@ -213,12 +202,12 @@ class LeafRefContextTreeBuilder {
         return currentLeafRefContextBuilder.build();
     }
 
-    private LinkedList<LeafRefContext> getLeafRefsFor(final DataSchemaNode node,
+    private List<LeafRefContext> getLeafRefsFor(final DataSchemaNode node,
             final Module module) {
         final LeafRefPath nodeXPath = LeafRefUtils.schemaPathToLeafRefPath(
                 node.getPath(), module);
 
-        final LinkedList<LeafRefContext> foundLeafRefs = new LinkedList<LeafRefContext>();
+        final List<LeafRefContext> foundLeafRefs = new LinkedList<>();
 
         for (final LeafRefContext leafref : leafRefs) {
             final LeafRefPath leafRefTargetPath = leafref
@@ -231,27 +220,4 @@ class LeafRefContextTreeBuilder {
         return foundLeafRefs;
     }
 
-    // private LeafRefContext buildLeafRefContextTreeFor(LeafRefContext parent,
-    // Module module) {
-    //
-    // Collection<DataSchemaNode> childNodes = module.getChildNodes();
-    // for (DataSchemaNode childNode : childNodes) {
-    // LeafRefContext childLeafRefContext = buildLeafRefContextTreeFor(parent,
-    // childNode);
-    //
-    // if(childLeafRefContext.hasReferencedByChild() ||
-    // childLeafRefContext.isReferencedBy()) {
-    // parent.addReferencedByChild(childLeafRefContext,
-    // childLeafRefContext.getCurrentNodeQName());
-    // }
-    // if(childLeafRefContext.hasReferencingChild() ||
-    // childLeafRefContext.isReferencing()) {
-    // parent.addReferencingChild(childLeafRefContext,
-    // childLeafRefContext.getCurrentNodeQName());
-    // }
-    // }
-    //
-    // return node;
-    // }
-
 }