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.yang.model.util;
11 import java.util.LinkedList;
12 import java.util.List;
13 import java.util.Queue;
16 import org.opendaylight.controller.yang.common.QName;
17 import org.opendaylight.controller.yang.model.api.ContainerSchemaNode;
18 import org.opendaylight.controller.yang.model.api.DataNodeContainer;
19 import org.opendaylight.controller.yang.model.api.DataSchemaNode;
20 import org.opendaylight.controller.yang.model.api.ListSchemaNode;
21 import org.opendaylight.controller.yang.model.api.Module;
22 import org.opendaylight.controller.yang.model.api.ModuleImport;
23 import org.opendaylight.controller.yang.model.api.RevisionAwareXPath;
24 import org.opendaylight.controller.yang.model.api.SchemaContext;
25 import org.opendaylight.controller.yang.model.api.SchemaNode;
26 import org.opendaylight.controller.yang.model.api.SchemaPath;
27 import org.opendaylight.controller.yang.model.api.TypeDefinition;
29 public final class SchemaContextUtil {
31 private SchemaContextUtil() {}
33 public static DataSchemaNode findDataSchemaNode(final SchemaContext context, final SchemaPath schemaPath) {
34 if (schemaPath != null) {
35 final Module module = resolveModuleFromSchemaPath(context, schemaPath);
36 final Queue<QName> prefixedPath = new LinkedList<QName>(schemaPath.getPath());
38 if ((module != null) && (prefixedPath != null)) {
39 return findSchemaNodeForGivenPath(context, module, prefixedPath);
45 public static DataSchemaNode findDataSchemaNode(final SchemaContext context, final Module module,
46 final RevisionAwareXPath nonCondXPath) {
47 if (nonCondXPath != null) {
48 final String strXPath = nonCondXPath.toString();
50 if (strXPath != null) {
51 if (strXPath.matches(".*//[.* | .*//].*")) {
52 // TODO: function to escape conditions in path
54 if (nonCondXPath.isAbsolute()) {
55 final Queue<QName> qnamedPath = xpathToQNamePath(context, module,
57 if (qnamedPath != null) {
58 final DataSchemaNode dataNode = findSchemaNodeForGivenPath(context,
68 public static DataSchemaNode findDataSchemaNodeForRelativeXPath(final SchemaContext context,
69 final Module module, final SchemaNode actualSchemaNode,
70 final RevisionAwareXPath relativeXPath) {
71 if ((actualSchemaNode != null) && (relativeXPath != null)
72 && !relativeXPath.isAbsolute()) {
74 final SchemaPath actualNodePath = actualSchemaNode.getPath();
75 if (actualNodePath != null) {
76 final Queue<QName> qnamePath = resolveRelativeXPath(context, module,
77 relativeXPath, actualNodePath);
79 if (qnamePath != null) {
80 final DataSchemaNode dataNode = findSchemaNodeForGivenPath(context,
90 public static Module resolveModuleFromSchemaPath(final SchemaContext context, final SchemaPath schemaPath) {
91 if ((schemaPath != null) && (schemaPath.getPath() != null)) {
92 List<QName> path = schemaPath.getPath();
93 final QName qname = path.get(path.size()-1);
95 if ((qname != null) && (qname.getNamespace() != null)) {
96 return context.findModuleByNamespace(qname.getNamespace());
102 public static Module resolveModuleFromTypePath(final SchemaContext context, final TypeDefinition<?> type) {
103 final SchemaPath schemaPath = type.getPath();
104 if ((schemaPath != null) && (schemaPath.getPath() != null)) {
105 if(type instanceof ExtendedType) {
106 List<QName> path = schemaPath.getPath();
107 final QName qname = path.get(path.size()-1);
109 if ((qname != null) && (qname.getNamespace() != null)) {
110 return context.findModuleByNamespace(qname.getNamespace());
113 LinkedList<QName> path = new LinkedList<QName>(schemaPath.getPath());
115 final QName qname = path.get(path.size()-1);
117 if ((qname != null) && (qname.getNamespace() != null)) {
118 return context.findModuleByNamespace(qname.getNamespace());
126 public static Module findParentModule(final SchemaContext context, final SchemaNode schemaNode) {
127 if (context == null) {
128 throw new IllegalArgumentException("Schema Context reference cannot be NULL!");
130 if (schemaNode == null) {
131 throw new IllegalArgumentException("Schema Node cannot be NULL!");
134 final SchemaPath schemaPath = schemaNode.getPath();
135 if (schemaPath == null) {
136 throw new IllegalStateException("Schema Path for Schema Node is not " +
137 "set properly (Schema Path is NULL)");
139 final List<QName> qnamedPath = schemaPath.getPath();
140 if (qnamedPath == null || qnamedPath.isEmpty()) {
141 throw new IllegalStateException("Schema Path contains invalid state of path parts." +
142 "The Schema Path MUST contain at least ONE QName which defines namespace and Local name" +
145 final QName qname = qnamedPath.get(0);
146 return context.findModuleByNamespace(qname.getNamespace());
149 private static DataSchemaNode findSchemaNodeForGivenPath(final SchemaContext context, final Module module,
150 final Queue<QName> qnamedPath) {
151 if ((module != null) && (module.getNamespace() != null)
152 && (qnamedPath != null)) {
153 DataNodeContainer nextNode = module;
154 final URI moduleNamespace = module.getNamespace();
156 QName childNodeQName = null;
157 DataSchemaNode schemaNode = null;
158 while ((nextNode != null) && !qnamedPath.isEmpty()) {
159 childNodeQName = qnamedPath.peek();
160 if (childNodeQName != null) {
161 final URI childNodeNamespace = childNodeQName.getNamespace();
163 schemaNode = nextNode.getDataChildByName(childNodeQName);
164 if (schemaNode != null) {
165 if (schemaNode instanceof ContainerSchemaNode) {
166 nextNode = (ContainerSchemaNode) schemaNode;
167 } else if (schemaNode instanceof ListSchemaNode) {
168 nextNode = (ListSchemaNode) schemaNode;
172 } else if (!childNodeNamespace.equals(moduleNamespace)) {
173 final Module nextModule = context
174 .findModuleByNamespace(childNodeNamespace);
175 schemaNode = findSchemaNodeForGivenPath(context, nextModule,
187 private static Queue<QName> xpathToQNamePath(final SchemaContext context, final Module parentModule,
188 final String xpath) {
189 final Queue<QName> path = new LinkedList<QName>();
191 final String[] prefixedPath = xpath.split("/");
193 for (int i = 0; i < prefixedPath.length; ++i) {
194 if (!prefixedPath[i].isEmpty()) {
195 path.add(stringPathPartToQName(context, parentModule, prefixedPath[i]));
202 private static QName stringPathPartToQName(final SchemaContext context, final Module parentModule,
203 final String prefixedPathPart) {
204 if (parentModule != null && prefixedPathPart != null) {
205 if (prefixedPathPart.contains(":")) {
206 final String[] prefixedName = prefixedPathPart.split(":");
207 final Module module = resolveModuleForPrefix(context, parentModule,
209 if (module != null) {
210 return new QName(module.getNamespace(), module
211 .getRevision(), prefixedName[1]);
214 return new QName(parentModule.getNamespace(),
215 parentModule.getRevision(), prefixedPathPart);
221 private static Module resolveModuleForPrefix(final SchemaContext context, final Module module,
222 final String prefix) {
223 if ((module != null) && (prefix != null)) {
224 if (prefix.equals(module.getPrefix())) {
228 final Set<ModuleImport> imports = module.getImports();
230 for (final ModuleImport mi : imports) {
231 if (prefix.equals(mi.getPrefix())) {
232 return context.findModuleByName(mi.getModuleName(),
240 private static Queue<QName> resolveRelativeXPath(final SchemaContext context, final Module module,
241 final RevisionAwareXPath relativeXPath,
242 final SchemaPath leafrefSchemaPath) {
243 final Queue<QName> absolutePath = new LinkedList<QName>();
245 if ((module != null) && (relativeXPath != null) && !relativeXPath.isAbsolute()
246 && (leafrefSchemaPath != null)) {
247 final String strXPath = relativeXPath.toString();
248 if (strXPath != null) {
249 final String[] xpaths = strXPath.split("/");
251 if (xpaths != null) {
253 while (xpaths[colCount].contains("..")) {
256 final List<QName> path = leafrefSchemaPath.getPath();
258 int lenght = path.size() - colCount - 1;
259 for (int i = 0; i < lenght; ++i) {
260 absolutePath.add(path.get(i));
262 for (int i = colCount; i < xpaths.length; ++i) {
263 absolutePath.add(stringPathPartToQName(context, module, xpaths[i]));