Update the API generation code and code generation sample
[controller.git] / opendaylight / sal / yang-prototype / code-generator / binding-generator-impl / src / main / java / org / opendaylight / controller / sal / binding / yang / types / TypeProviderImpl.java
index 2cc774ac83f3e1b94bfca4417031ecde18f8e692..54abd3daea520f97068e765f2838ec464dea45cf 100644 (file)
@@ -7,12 +7,39 @@
  */\r
 package org.opendaylight.controller.sal.binding.yang.types;\r
 \r
+import java.util.LinkedList;\r
+import java.util.List;\r
+import java.util.Queue;\r
+import java.util.Set;\r
+\r
+import org.opendaylight.controller.binding.generator.util.Types;\r
 import org.opendaylight.controller.sal.binding.generator.spi.TypeProvider;\r
 import org.opendaylight.controller.sal.binding.model.api.Type;\r
+import org.opendaylight.controller.yang.common.QName;\r
+import org.opendaylight.controller.yang.model.api.ContainerSchemaNode;\r
+import org.opendaylight.controller.yang.model.api.DataNodeContainer;\r
+import org.opendaylight.controller.yang.model.api.DataSchemaNode;\r
+import org.opendaylight.controller.yang.model.api.LeafListSchemaNode;\r
+import org.opendaylight.controller.yang.model.api.LeafSchemaNode;\r
+import org.opendaylight.controller.yang.model.api.ListSchemaNode;\r
+import org.opendaylight.controller.yang.model.api.Module;\r
+import org.opendaylight.controller.yang.model.api.ModuleImport;\r
+import org.opendaylight.controller.yang.model.api.RevisionAwareXPath;\r
+import org.opendaylight.controller.yang.model.api.SchemaContext;\r
+import org.opendaylight.controller.yang.model.api.SchemaPath;\r
 import org.opendaylight.controller.yang.model.api.TypeDefinition;\r
+import org.opendaylight.controller.yang.model.api.type.IdentityrefTypeDefinition;\r
+import org.opendaylight.controller.yang.model.api.type.LeafrefTypeDefinition;\r
+import org.opendaylight.controller.yang.model.util.Leafref;\r
 \r
 public class TypeProviderImpl implements TypeProvider {\r
 \r
+    private SchemaContext schemaContext;\r
+\r
+    public TypeProviderImpl(SchemaContext schemaContext) {\r
+        this.schemaContext = schemaContext;\r
+    }\r
+\r
     /*\r
      * (non-Javadoc)\r
      * \r
@@ -23,23 +50,234 @@ public class TypeProviderImpl implements TypeProvider {
     public Type javaTypeForYangType(String type) {\r
         Type t = BaseYangTypes.BASE_YANG_TYPES_PROVIDER\r
                 .javaTypeForYangType(type);\r
-        // TODO: this needs to be implemented in better way\r
-        // if(t == null) {\r
-        // t = BaseYangTypes.IETF_INET_TYPES_PROVIDER.javaTypeForYangType(type);\r
-        // }\r
         return t;\r
     }\r
 \r
     @Override\r
     public Type javaTypeForSchemaDefinitionType(final TypeDefinition<?> type) {\r
+        Type returnType = null;\r
         if (type != null) {\r
-            Type t = BaseYangTypes.BASE_YANG_TYPES_PROVIDER\r
-                    .javaTypeForSchemaDefinitionType(type);\r
+            if (type instanceof Leafref) {\r
+                final LeafrefTypeDefinition leafref = (LeafrefTypeDefinition) type;\r
+                returnType = provideTypeForLeafref(leafref);\r
+            } else if (type instanceof IdentityrefTypeDefinition) {\r
+\r
+            } else {\r
+                returnType = BaseYangTypes.BASE_YANG_TYPES_PROVIDER\r
+                        .javaTypeForSchemaDefinitionType(type);\r
+            }\r
+        }\r
+        return returnType;\r
+    }\r
+\r
+    public Type provideTypeForLeafref(final LeafrefTypeDefinition leafrefType) {\r
+        Type returnType = null;\r
+        if ((leafrefType != null) && (leafrefType.getPathStatement() != null)) {\r
+            final RevisionAwareXPath xpath = leafrefType.getPathStatement();\r
+            final String strXPath = xpath.toString();\r
+\r
+            if (strXPath != null) {\r
+                if (strXPath.matches(".*//[.* | .*//].*")) {\r
+                    returnType = Types.typeForClass(Object.class);\r
+                } else {\r
+                    final Module module = resolveModuleFromSchemaContext(leafrefType\r
+                            .getPath());\r
+                    if (module != null) {\r
+                        Queue<String> leafrefPath;\r
+                        if (!xpath.isAbsolute()) {\r
+                            leafrefPath = resolveRelativeXPath(xpath,\r
+                                    leafrefType.getPath());\r
+                        } else {\r
+                            leafrefPath = xpathToPrefixedPath(strXPath, module.getName());\r
+                        }\r
+\r
+                        if (leafrefPath != null) {\r
+                            final DataSchemaNode dataNode = findSchemaNodeForGivenPath(\r
+                                    module, leafrefPath);\r
+                            returnType = resolveTypeFromDataSchemaNode(dataNode);\r
+                        }\r
+                    }\r
+                }\r
+            }\r
+        }\r
+        return returnType;\r
+    }\r
 \r
-            if (t != null) {\r
-                return t;\r
+    private Type resolveTypeFromDataSchemaNode(final DataSchemaNode dataNode) {\r
+        Type returnType = null;\r
+        if (dataNode != null) {\r
+            if (dataNode instanceof LeafSchemaNode) {\r
+                final LeafSchemaNode leaf = (LeafSchemaNode) dataNode;\r
+                returnType = javaTypeForSchemaDefinitionType(leaf.getType());\r
+            } else if (dataNode instanceof LeafListSchemaNode) {\r
+                final LeafListSchemaNode leafList = (LeafListSchemaNode) dataNode;\r
+                returnType = javaTypeForSchemaDefinitionType(leafList.getType());\r
             }\r
         }\r
+        return returnType;\r
+    }\r
+\r
+    /**\r
+     * Search which starts from root of Module.\r
+     * \r
+     * @param module\r
+     * @param prefixedPath\r
+     * @return\r
+     */\r
+    private DataSchemaNode findSchemaNodeForGivenPath(final Module module,\r
+            final Queue<String> prefixedPath) {\r
+        if ((module != null) && (prefixedPath != null)) {\r
+            final String modulePrefix = module.getPrefix();\r
+            String childNodeName = prefixedPath.poll();\r
+            DataNodeContainer nextContainer = null;\r
+\r
+            if ((childNodeName != null)\r
+                    && childNodeName.equals(module.getName())) {\r
+                nextContainer = module;\r
+            }\r
+\r
+            DataSchemaNode schemaNode = null;\r
+            while ((nextContainer != null) && (prefixedPath.size() > 0)) {\r
+                childNodeName = prefixedPath.poll();\r
+                if (childNodeName.contains(":")) {\r
+                    final String[] prefixedChildNode = childNodeName.split(":");\r
+                    if ((modulePrefix != null)\r
+                            && modulePrefix.equals(prefixedChildNode[0])) {\r
+                        \r
+                        childNodeName = prefixedChildNode[1];\r
+                    } else {\r
+                        final Module nextModule = resolveModuleForPrefix(\r
+                                prefixedChildNode[0], module);\r
+                        final Queue<String> nextModulePrefixedPath = new LinkedList<String>();\r
+                        \r
+                        nextModulePrefixedPath.add(nextModule.getName());\r
+                        nextModulePrefixedPath.add(childNodeName);\r
+                        nextModulePrefixedPath.addAll(prefixedPath);\r
+                        prefixedPath.clear();\r
+                        \r
+                        schemaNode = findSchemaNodeForGivenPath(nextModule,\r
+                                nextModulePrefixedPath);\r
+                        \r
+                        return schemaNode;\r
+                    }\r
+                }\r
+                \r
+                schemaNode = nextContainer.getDataChildByName(childNodeName);\r
+                if (schemaNode instanceof ContainerSchemaNode) {\r
+                    nextContainer = (ContainerSchemaNode) schemaNode;\r
+                } else if (schemaNode instanceof ListSchemaNode) {\r
+                    nextContainer = (ListSchemaNode) schemaNode;\r
+                } else {\r
+                    return schemaNode;\r
+                }\r
+            }\r
+        }\r
+\r
         return null;\r
     }\r
+\r
+    private Module resolveModuleFromSchemaContext(final SchemaPath schemaPath) {\r
+        final Set<Module> modules = schemaContext.getModules();\r
+        final String moduleName = resolveModuleName(schemaPath);\r
+        if ((moduleName != null) && (modules != null)) {\r
+            for (final Module module : modules) {\r
+                if (module.getName().equals(moduleName)) {\r
+                    return module;\r
+                }\r
+            }\r
+        }\r
+        return null;\r
+    }\r
+\r
+    private String resolveModuleName(final SchemaPath schemaPath) {\r
+        if ((schemaPath != null) && (schemaPath.getPath() != null)) {\r
+            final QName qname = schemaPath.getPath().get(0);\r
+            if ((qname != null) && (qname.getLocalName() != null)) {\r
+                return qname.getLocalName();\r
+            }\r
+        }\r
+        return "";\r
+    }\r
+\r
+    private Queue<String> xpathToPrefixedPath(final String xpath, final String moduleName) {\r
+        final Queue<String> retQueue = new LinkedList<String>();\r
+        if ((xpath != null) && (moduleName != null)) {\r
+            final String[] prefixedPath = xpath.split("/");\r
+            \r
+            retQueue.add(moduleName);\r
+            if (prefixedPath != null) {\r
+                for (int i = 0; i < prefixedPath.length; ++i) {\r
+                    if (!prefixedPath[i].isEmpty()) {\r
+                        retQueue.add(prefixedPath[i]);\r
+                    }\r
+                }\r
+            }\r
+        }\r
+        return retQueue;\r
+    }\r
+\r
+    private Module resolveModuleForPrefix(final String prefix,\r
+            final Module parent) {\r
+        if ((prefix != null) && (parent != null)) {\r
+            final Set<ModuleImport> imports = parent.getImports();\r
+\r
+            if (imports != null) {\r
+                for (final ModuleImport impModule : imports) {\r
+                    final String impModPrefix = impModule.getPrefix();\r
+                    if ((impModPrefix != null) && prefix.equals(impModPrefix)) {\r
+                        return resolveModuleFromContext(prefix,\r
+                                impModule.getModuleName());\r
+                    }\r
+                }\r
+            }\r
+        }\r
+        return null;\r
+    }\r
+\r
+    private Module resolveModuleFromContext(final String prefix,\r
+            final String moduleName) {\r
+        final Set<Module> modules = schemaContext.getModules();\r
+\r
+        if ((prefix != null) && (moduleName != null) && (modules != null)) {\r
+            for (Module module : modules) {\r
+                if ((module != null) && prefix.equals(module.getPrefix())\r
+                        && moduleName.equals(module.getName())) {\r
+                    return module;\r
+                }\r
+            }\r
+        }\r
+        return null;\r
+    }\r
+\r
+    private Queue<String> resolveRelativeXPath(\r
+            final RevisionAwareXPath relativeXPath,\r
+            final SchemaPath leafrefSchemaPath) {\r
+        final Queue<String> absolutePath = new LinkedList<String>();\r
+\r
+        if ((relativeXPath != null) && !relativeXPath.isAbsolute()\r
+                && (leafrefSchemaPath != null)) {\r
+            final String strXPath = relativeXPath.toString();\r
+            if (strXPath != null) {\r
+                final String[] xpaths = strXPath.split("/");\r
+\r
+                if (xpaths != null) {\r
+                    int colCount = 0;\r
+                    while (xpaths[colCount].contains("..")) {\r
+                        ++colCount;\r
+                    }\r
+                    final List<QName> path = leafrefSchemaPath.getPath();\r
+                    if (path != null) {\r
+                        int lenght = path.size() - colCount;\r
+                        for (int i = 0; i < lenght; ++i) {\r
+                            absolutePath.add(path.get(i).getLocalName());\r
+                        }\r
+                        for (int i = colCount; i < xpaths.length; ++i) {\r
+                            absolutePath.add(xpaths[i]);\r
+                        }\r
+                    }\r
+                }\r
+            }\r
+        }\r
+        return absolutePath;\r
+    }\r
 }\r