2 * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
4 * This program and the accompanying materials are made available under the
5 * terms of the Eclipse Public License v1.0 which accompanies this distribution,
6 * and is available at http://www.eclipse.org/legal/epl-v10.html
8 package org.opendaylight.controller.sal.binding.yang.types;
10 import java.util.LinkedList;
11 import java.util.List;
12 import java.util.Queue;
15 import org.opendaylight.controller.binding.generator.util.Types;
16 import org.opendaylight.controller.sal.binding.generator.spi.TypeProvider;
17 import org.opendaylight.controller.sal.binding.model.api.Type;
18 import org.opendaylight.controller.yang.common.QName;
19 import org.opendaylight.controller.yang.model.api.ContainerSchemaNode;
20 import org.opendaylight.controller.yang.model.api.DataNodeContainer;
21 import org.opendaylight.controller.yang.model.api.DataSchemaNode;
22 import org.opendaylight.controller.yang.model.api.LeafListSchemaNode;
23 import org.opendaylight.controller.yang.model.api.LeafSchemaNode;
24 import org.opendaylight.controller.yang.model.api.ListSchemaNode;
25 import org.opendaylight.controller.yang.model.api.Module;
26 import org.opendaylight.controller.yang.model.api.ModuleImport;
27 import org.opendaylight.controller.yang.model.api.RevisionAwareXPath;
28 import org.opendaylight.controller.yang.model.api.SchemaContext;
29 import org.opendaylight.controller.yang.model.api.SchemaPath;
30 import org.opendaylight.controller.yang.model.api.TypeDefinition;
31 import org.opendaylight.controller.yang.model.api.type.IdentityrefTypeDefinition;
32 import org.opendaylight.controller.yang.model.api.type.LeafrefTypeDefinition;
33 import org.opendaylight.controller.yang.model.util.ExtendedType;
34 import org.opendaylight.controller.yang.model.util.Leafref;
36 public class TypeProviderImpl implements TypeProvider {
38 private SchemaContext schemaContext;
40 public TypeProviderImpl(SchemaContext schemaContext) {
41 this.schemaContext = schemaContext;
47 * @see org.opendaylight.controller.yang.model.type.provider.TypeProvider#
48 * javaTypeForYangType(java.lang.String)
51 public Type javaTypeForYangType(String type) {
52 Type t = BaseYangTypes.BASE_YANG_TYPES_PROVIDER
53 .javaTypeForYangType(type);
58 public Type javaTypeForSchemaDefinitionType(final TypeDefinition<?> typeDefinition) {
59 Type returnType = null;
60 if (typeDefinition != null) {
61 if (typeDefinition instanceof Leafref) {
62 final LeafrefTypeDefinition leafref = (LeafrefTypeDefinition) typeDefinition;
63 returnType = provideTypeForLeafref(leafref);
64 } else if (typeDefinition instanceof IdentityrefTypeDefinition) {
66 } else if (typeDefinition instanceof ExtendedType) {
67 final TypeDefinition<?> baseType = typeDefinition.getBaseType();
68 return javaTypeForSchemaDefinitionType(baseType);
71 returnType = baseTypeForExtendedType(typeDefinition);
77 public Type baseTypeForExtendedType(final TypeDefinition<?> typeDefinition) {
78 Type returnType = null;
79 if (typeDefinition != null) {
80 if (typeDefinition instanceof ExtendedType) {
81 final TypeDefinition<?> extType = typeDefinition.getBaseType();
82 return baseTypeForExtendedType(extType);
84 returnType = BaseYangTypes.BASE_YANG_TYPES_PROVIDER
85 .javaTypeForSchemaDefinitionType(typeDefinition);
91 public Type provideTypeForLeafref(final LeafrefTypeDefinition leafrefType) {
92 Type returnType = null;
93 if ((leafrefType != null) && (leafrefType.getPathStatement() != null)
94 && (leafrefType.getPath() != null)) {
96 final RevisionAwareXPath xpath = leafrefType.getPathStatement();
97 final String strXPath = xpath.toString();
99 if (strXPath != null) {
100 if (strXPath.matches(".*//[.* | .*//].*")) {
101 returnType = Types.typeForClass(Object.class);
103 final Module module = resolveModuleFromSchemaPath(leafrefType
105 if (module != null) {
106 Queue<String> leafrefPath;
107 if (!xpath.isAbsolute()) {
108 leafrefPath = resolveRelativeXPath(xpath,
109 leafrefType.getPath());
111 leafrefPath = xpathToPrefixedPath(strXPath,
114 if (leafrefPath != null) {
115 final DataSchemaNode dataNode = findSchemaNodeForGivenPath(
116 module, leafrefPath);
117 returnType = resolveTypeFromDataSchemaNode(dataNode);
126 private Type resolveTypeFromDataSchemaNode(final DataSchemaNode dataNode) {
127 Type returnType = null;
128 if (dataNode != null) {
129 if (dataNode instanceof LeafSchemaNode) {
130 final LeafSchemaNode leaf = (LeafSchemaNode) dataNode;
131 returnType = javaTypeForSchemaDefinitionType(leaf.getType());
132 } else if (dataNode instanceof LeafListSchemaNode) {
133 final LeafListSchemaNode leafList = (LeafListSchemaNode) dataNode;
134 returnType = javaTypeForSchemaDefinitionType(leafList.getType());
141 * Search which starts from root of Module.
144 * @param prefixedPath
147 private DataSchemaNode findSchemaNodeForGivenPath(final Module module,
148 final Queue<String> prefixedPath) {
149 if ((module != null) && (prefixedPath != null)) {
150 DataNodeContainer nextContainer = module;
151 final String modulePrefix = module.getPrefix();
153 String childNodeName = null;
154 DataSchemaNode schemaNode = null;
155 while ((nextContainer != null) && (prefixedPath.size() > 0)) {
156 childNodeName = prefixedPath.poll();
157 if (childNodeName.contains(":")) {
158 final String[] prefixedChildNode = childNodeName.split(":");
159 if ((modulePrefix != null)
160 && modulePrefix.equals(prefixedChildNode[0])) {
162 childNodeName = prefixedChildNode[1];
164 final Module nextModule = resolveModuleForPrefix(
165 prefixedChildNode[0], module);
166 final Queue<String> nextModulePrefixedPath = new LinkedList<String>();
167 nextModulePrefixedPath.add(childNodeName);
168 nextModulePrefixedPath.addAll(prefixedPath);
169 prefixedPath.clear();
171 schemaNode = findSchemaNodeForGivenPath(nextModule,
172 nextModulePrefixedPath);
178 schemaNode = nextContainer.getDataChildByName(childNodeName);
179 if (schemaNode instanceof ContainerSchemaNode) {
180 nextContainer = (ContainerSchemaNode) schemaNode;
181 } else if (schemaNode instanceof ListSchemaNode) {
182 nextContainer = (ListSchemaNode) schemaNode;
192 private Module resolveModuleFromSchemaPath(final SchemaPath schemaPath) {
193 if ((schemaPath != null) && (schemaPath.getPath() != null)) {
194 final QName qname = schemaPath.getPath().get(0);
196 if ((qname != null) && (qname.getNamespace() != null)) {
198 .findModuleByNamespace(qname.getNamespace());
204 private Queue<String> xpathToPrefixedPath(final String xpath,
205 final String moduleName) {
206 final Queue<String> retQueue = new LinkedList<String>();
207 if ((xpath != null) && (moduleName != null)) {
208 final String[] prefixedPath = xpath.split("/");
210 if (prefixedPath != null) {
211 for (int i = 0; i < prefixedPath.length; ++i) {
212 if (!prefixedPath[i].isEmpty()) {
213 retQueue.add(prefixedPath[i]);
221 private Module resolveModuleForPrefix(final String prefix,
222 final Module parent) {
223 if ((prefix != null) && (parent != null)) {
224 final Set<ModuleImport> imports = parent.getImports();
226 if (imports != null) {
227 for (final ModuleImport impModule : imports) {
228 final String impModPrefix = impModule.getPrefix();
229 if ((impModPrefix != null) && prefix.equals(impModPrefix)) {
230 return resolveModuleFromContext(prefix,
231 impModule.getModuleName());
239 private Module resolveModuleFromContext(final String prefix,
240 final String moduleName) {
241 final Set<Module> modules = schemaContext.getModules();
243 if ((prefix != null) && (moduleName != null) && (modules != null)) {
244 for (Module module : modules) {
245 if ((module != null) && prefix.equals(module.getPrefix())
246 && moduleName.equals(module.getName())) {
254 private Queue<String> resolveRelativeXPath(
255 final RevisionAwareXPath relativeXPath,
256 final SchemaPath leafrefSchemaPath) {
257 final Queue<String> absolutePath = new LinkedList<String>();
259 if ((relativeXPath != null) && !relativeXPath.isAbsolute()
260 && (leafrefSchemaPath != null)) {
261 final String strXPath = relativeXPath.toString();
262 if (strXPath != null) {
263 final String[] xpaths = strXPath.split("/");
265 if (xpaths != null) {
267 while (xpaths[colCount].contains("..")) {
270 final List<QName> path = leafrefSchemaPath.getPath();
272 int lenght = path.size() - colCount;
273 for (int i = 0; i < lenght; ++i) {
274 absolutePath.add(path.get(i).getLocalName());
276 for (int i = colCount; i < xpaths.length; ++i) {
277 absolutePath.add(xpaths[i]);