54abd3daea520f97068e765f2838ec464dea45cf
[controller.git] / opendaylight / sal / yang-prototype / code-generator / binding-generator-impl / src / main / java / org / opendaylight / controller / sal / binding / yang / types / TypeProviderImpl.java
1 /*\r
2  * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.\r
3  *\r
4  * This program and the accompanying materials are made available under the\r
5  * terms of the Eclipse Public License v1.0 which accompanies this distribution,\r
6  * and is available at http://www.eclipse.org/legal/epl-v10.html\r
7  */\r
8 package org.opendaylight.controller.sal.binding.yang.types;\r
9 \r
10 import java.util.LinkedList;\r
11 import java.util.List;\r
12 import java.util.Queue;\r
13 import java.util.Set;\r
14 \r
15 import org.opendaylight.controller.binding.generator.util.Types;\r
16 import org.opendaylight.controller.sal.binding.generator.spi.TypeProvider;\r
17 import org.opendaylight.controller.sal.binding.model.api.Type;\r
18 import org.opendaylight.controller.yang.common.QName;\r
19 import org.opendaylight.controller.yang.model.api.ContainerSchemaNode;\r
20 import org.opendaylight.controller.yang.model.api.DataNodeContainer;\r
21 import org.opendaylight.controller.yang.model.api.DataSchemaNode;\r
22 import org.opendaylight.controller.yang.model.api.LeafListSchemaNode;\r
23 import org.opendaylight.controller.yang.model.api.LeafSchemaNode;\r
24 import org.opendaylight.controller.yang.model.api.ListSchemaNode;\r
25 import org.opendaylight.controller.yang.model.api.Module;\r
26 import org.opendaylight.controller.yang.model.api.ModuleImport;\r
27 import org.opendaylight.controller.yang.model.api.RevisionAwareXPath;\r
28 import org.opendaylight.controller.yang.model.api.SchemaContext;\r
29 import org.opendaylight.controller.yang.model.api.SchemaPath;\r
30 import org.opendaylight.controller.yang.model.api.TypeDefinition;\r
31 import org.opendaylight.controller.yang.model.api.type.IdentityrefTypeDefinition;\r
32 import org.opendaylight.controller.yang.model.api.type.LeafrefTypeDefinition;\r
33 import org.opendaylight.controller.yang.model.util.Leafref;\r
34 \r
35 public class TypeProviderImpl implements TypeProvider {\r
36 \r
37     private SchemaContext schemaContext;\r
38 \r
39     public TypeProviderImpl(SchemaContext schemaContext) {\r
40         this.schemaContext = schemaContext;\r
41     }\r
42 \r
43     /*\r
44      * (non-Javadoc)\r
45      * \r
46      * @see org.opendaylight.controller.yang.model.type.provider.TypeProvider#\r
47      * javaTypeForYangType(java.lang.String)\r
48      */\r
49     @Override\r
50     public Type javaTypeForYangType(String type) {\r
51         Type t = BaseYangTypes.BASE_YANG_TYPES_PROVIDER\r
52                 .javaTypeForYangType(type);\r
53         return t;\r
54     }\r
55 \r
56     @Override\r
57     public Type javaTypeForSchemaDefinitionType(final TypeDefinition<?> type) {\r
58         Type returnType = null;\r
59         if (type != null) {\r
60             if (type instanceof Leafref) {\r
61                 final LeafrefTypeDefinition leafref = (LeafrefTypeDefinition) type;\r
62                 returnType = provideTypeForLeafref(leafref);\r
63             } else if (type instanceof IdentityrefTypeDefinition) {\r
64 \r
65             } else {\r
66                 returnType = BaseYangTypes.BASE_YANG_TYPES_PROVIDER\r
67                         .javaTypeForSchemaDefinitionType(type);\r
68             }\r
69         }\r
70         return returnType;\r
71     }\r
72 \r
73     public Type provideTypeForLeafref(final LeafrefTypeDefinition leafrefType) {\r
74         Type returnType = null;\r
75         if ((leafrefType != null) && (leafrefType.getPathStatement() != null)) {\r
76             final RevisionAwareXPath xpath = leafrefType.getPathStatement();\r
77             final String strXPath = xpath.toString();\r
78 \r
79             if (strXPath != null) {\r
80                 if (strXPath.matches(".*//[.* | .*//].*")) {\r
81                     returnType = Types.typeForClass(Object.class);\r
82                 } else {\r
83                     final Module module = resolveModuleFromSchemaContext(leafrefType\r
84                             .getPath());\r
85                     if (module != null) {\r
86                         Queue<String> leafrefPath;\r
87                         if (!xpath.isAbsolute()) {\r
88                             leafrefPath = resolveRelativeXPath(xpath,\r
89                                     leafrefType.getPath());\r
90                         } else {\r
91                             leafrefPath = xpathToPrefixedPath(strXPath, module.getName());\r
92                         }\r
93 \r
94                         if (leafrefPath != null) {\r
95                             final DataSchemaNode dataNode = findSchemaNodeForGivenPath(\r
96                                     module, leafrefPath);\r
97                             returnType = resolveTypeFromDataSchemaNode(dataNode);\r
98                         }\r
99                     }\r
100                 }\r
101             }\r
102         }\r
103         return returnType;\r
104     }\r
105 \r
106     private Type resolveTypeFromDataSchemaNode(final DataSchemaNode dataNode) {\r
107         Type returnType = null;\r
108         if (dataNode != null) {\r
109             if (dataNode instanceof LeafSchemaNode) {\r
110                 final LeafSchemaNode leaf = (LeafSchemaNode) dataNode;\r
111                 returnType = javaTypeForSchemaDefinitionType(leaf.getType());\r
112             } else if (dataNode instanceof LeafListSchemaNode) {\r
113                 final LeafListSchemaNode leafList = (LeafListSchemaNode) dataNode;\r
114                 returnType = javaTypeForSchemaDefinitionType(leafList.getType());\r
115             }\r
116         }\r
117         return returnType;\r
118     }\r
119 \r
120     /**\r
121      * Search which starts from root of Module.\r
122      * \r
123      * @param module\r
124      * @param prefixedPath\r
125      * @return\r
126      */\r
127     private DataSchemaNode findSchemaNodeForGivenPath(final Module module,\r
128             final Queue<String> prefixedPath) {\r
129         if ((module != null) && (prefixedPath != null)) {\r
130             final String modulePrefix = module.getPrefix();\r
131             String childNodeName = prefixedPath.poll();\r
132             DataNodeContainer nextContainer = null;\r
133 \r
134             if ((childNodeName != null)\r
135                     && childNodeName.equals(module.getName())) {\r
136                 nextContainer = module;\r
137             }\r
138 \r
139             DataSchemaNode schemaNode = null;\r
140             while ((nextContainer != null) && (prefixedPath.size() > 0)) {\r
141                 childNodeName = prefixedPath.poll();\r
142                 if (childNodeName.contains(":")) {\r
143                     final String[] prefixedChildNode = childNodeName.split(":");\r
144                     if ((modulePrefix != null)\r
145                             && modulePrefix.equals(prefixedChildNode[0])) {\r
146                         \r
147                         childNodeName = prefixedChildNode[1];\r
148                     } else {\r
149                         final Module nextModule = resolveModuleForPrefix(\r
150                                 prefixedChildNode[0], module);\r
151                         final Queue<String> nextModulePrefixedPath = new LinkedList<String>();\r
152                         \r
153                         nextModulePrefixedPath.add(nextModule.getName());\r
154                         nextModulePrefixedPath.add(childNodeName);\r
155                         nextModulePrefixedPath.addAll(prefixedPath);\r
156                         prefixedPath.clear();\r
157                         \r
158                         schemaNode = findSchemaNodeForGivenPath(nextModule,\r
159                                 nextModulePrefixedPath);\r
160                         \r
161                         return schemaNode;\r
162                     }\r
163                 }\r
164                 \r
165                 schemaNode = nextContainer.getDataChildByName(childNodeName);\r
166                 if (schemaNode instanceof ContainerSchemaNode) {\r
167                     nextContainer = (ContainerSchemaNode) schemaNode;\r
168                 } else if (schemaNode instanceof ListSchemaNode) {\r
169                     nextContainer = (ListSchemaNode) schemaNode;\r
170                 } else {\r
171                     return schemaNode;\r
172                 }\r
173             }\r
174         }\r
175 \r
176         return null;\r
177     }\r
178 \r
179     private Module resolveModuleFromSchemaContext(final SchemaPath schemaPath) {\r
180         final Set<Module> modules = schemaContext.getModules();\r
181         final String moduleName = resolveModuleName(schemaPath);\r
182         if ((moduleName != null) && (modules != null)) {\r
183             for (final Module module : modules) {\r
184                 if (module.getName().equals(moduleName)) {\r
185                     return module;\r
186                 }\r
187             }\r
188         }\r
189         return null;\r
190     }\r
191 \r
192     private String resolveModuleName(final SchemaPath schemaPath) {\r
193         if ((schemaPath != null) && (schemaPath.getPath() != null)) {\r
194             final QName qname = schemaPath.getPath().get(0);\r
195             if ((qname != null) && (qname.getLocalName() != null)) {\r
196                 return qname.getLocalName();\r
197             }\r
198         }\r
199         return "";\r
200     }\r
201 \r
202     private Queue<String> xpathToPrefixedPath(final String xpath, final String moduleName) {\r
203         final Queue<String> retQueue = new LinkedList<String>();\r
204         if ((xpath != null) && (moduleName != null)) {\r
205             final String[] prefixedPath = xpath.split("/");\r
206             \r
207             retQueue.add(moduleName);\r
208             if (prefixedPath != null) {\r
209                 for (int i = 0; i < prefixedPath.length; ++i) {\r
210                     if (!prefixedPath[i].isEmpty()) {\r
211                         retQueue.add(prefixedPath[i]);\r
212                     }\r
213                 }\r
214             }\r
215         }\r
216         return retQueue;\r
217     }\r
218 \r
219     private Module resolveModuleForPrefix(final String prefix,\r
220             final Module parent) {\r
221         if ((prefix != null) && (parent != null)) {\r
222             final Set<ModuleImport> imports = parent.getImports();\r
223 \r
224             if (imports != null) {\r
225                 for (final ModuleImport impModule : imports) {\r
226                     final String impModPrefix = impModule.getPrefix();\r
227                     if ((impModPrefix != null) && prefix.equals(impModPrefix)) {\r
228                         return resolveModuleFromContext(prefix,\r
229                                 impModule.getModuleName());\r
230                     }\r
231                 }\r
232             }\r
233         }\r
234         return null;\r
235     }\r
236 \r
237     private Module resolveModuleFromContext(final String prefix,\r
238             final String moduleName) {\r
239         final Set<Module> modules = schemaContext.getModules();\r
240 \r
241         if ((prefix != null) && (moduleName != null) && (modules != null)) {\r
242             for (Module module : modules) {\r
243                 if ((module != null) && prefix.equals(module.getPrefix())\r
244                         && moduleName.equals(module.getName())) {\r
245                     return module;\r
246                 }\r
247             }\r
248         }\r
249         return null;\r
250     }\r
251 \r
252     private Queue<String> resolveRelativeXPath(\r
253             final RevisionAwareXPath relativeXPath,\r
254             final SchemaPath leafrefSchemaPath) {\r
255         final Queue<String> absolutePath = new LinkedList<String>();\r
256 \r
257         if ((relativeXPath != null) && !relativeXPath.isAbsolute()\r
258                 && (leafrefSchemaPath != null)) {\r
259             final String strXPath = relativeXPath.toString();\r
260             if (strXPath != null) {\r
261                 final String[] xpaths = strXPath.split("/");\r
262 \r
263                 if (xpaths != null) {\r
264                     int colCount = 0;\r
265                     while (xpaths[colCount].contains("..")) {\r
266                         ++colCount;\r
267                     }\r
268                     final List<QName> path = leafrefSchemaPath.getPath();\r
269                     if (path != null) {\r
270                         int lenght = path.size() - colCount;\r
271                         for (int i = 0; i < lenght; ++i) {\r
272                             absolutePath.add(path.get(i).getLocalName());\r
273                         }\r
274                         for (int i = colCount; i < xpaths.length; ++i) {\r
275                             absolutePath.add(xpaths[i]);\r
276                         }\r
277                     }\r
278                 }\r
279             }\r
280         }\r
281         return absolutePath;\r
282     }\r
283 }\r