Merge "Prevent stub and integrationtest plugins to go into the distribution of openda...
[controller.git] / opendaylight / sal / yang-prototype / yang / yang-model-util / src / main / java / org / opendaylight / controller / yang / model / util / SchemaContextUtil.java
1 /*
2  * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.
3  *
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
7  */
8 package org.opendaylight.controller.yang.model.util;
9
10 import java.util.LinkedList;
11 import java.util.List;
12 import java.util.Queue;
13 import java.util.Set;
14
15 import org.opendaylight.controller.yang.common.QName;
16 import org.opendaylight.controller.yang.model.api.ContainerSchemaNode;
17 import org.opendaylight.controller.yang.model.api.DataNodeContainer;
18 import org.opendaylight.controller.yang.model.api.DataSchemaNode;
19 import org.opendaylight.controller.yang.model.api.ListSchemaNode;
20 import org.opendaylight.controller.yang.model.api.Module;
21 import org.opendaylight.controller.yang.model.api.ModuleImport;
22 import org.opendaylight.controller.yang.model.api.RevisionAwareXPath;
23 import org.opendaylight.controller.yang.model.api.SchemaContext;
24 import org.opendaylight.controller.yang.model.api.SchemaNode;
25 import org.opendaylight.controller.yang.model.api.SchemaPath;
26
27 public final class SchemaContextUtil {
28
29     private final SchemaContext context;
30
31     public SchemaContextUtil(final SchemaContext context) {
32         this.context = context;
33     }
34     
35     public SchemaContext getContext() {
36         return context;
37     }
38     
39     public DataSchemaNode findDataSchemaNode(final SchemaPath schemaPath) {
40         if (schemaPath != null) {
41             final Module module = resolveModuleFromSchemaPath(schemaPath);
42             final Queue<String> prefixedPath = schemaPathToQueuedPath(schemaPath);
43             
44             if ((module != null) && (prefixedPath != null)) {
45                 return findSchemaNodeForGivenPath(module, prefixedPath);
46             }
47         }
48         return null;
49     }
50     
51     public DataSchemaNode findDataSchemaNode(final Module module,
52             final RevisionAwareXPath nonCondXPath) {
53         if (nonCondXPath != null) {
54             final String strXPath = nonCondXPath.toString();
55
56             if (strXPath != null) {
57                 if (strXPath.matches(".*//[.* | .*//].*")) {
58                     // TODO: function to escape conditions in path   
59                 }
60                 if (nonCondXPath.isAbsolute()) {
61                     final Queue<String> queuedPath = xpathToQueuedPath(strXPath);
62                     if (queuedPath != null) {
63                         final DataSchemaNode dataNode = findSchemaNodeForGivenPath(
64                                 module, queuedPath);
65                         return dataNode;
66                     }
67                 }
68             }
69         }
70         return null;
71     }
72
73     public DataSchemaNode findDataSchemaNodeForRelativeXPath(
74             final Module module, final SchemaNode actualSchemaNode,
75             final RevisionAwareXPath relativeXPath) {
76         if ((actualSchemaNode != null) && (relativeXPath != null)
77                 && !relativeXPath.isAbsolute()) {
78
79             final SchemaPath actualNodePath = actualSchemaNode.getPath();
80             if (actualNodePath != null) {
81                 final Queue<String> queuedPath = resolveRelativeXPath(
82                         relativeXPath, actualNodePath);
83
84                 if (queuedPath != null) {
85                     final DataSchemaNode dataNode = findSchemaNodeForGivenPath(
86                             module, queuedPath);
87                     return dataNode;
88                 }
89             }
90         }
91
92         return null;
93     }
94     
95     public Module resolveModuleFromSchemaPath(final SchemaPath schemaPath) {
96         if ((schemaPath != null) && (schemaPath.getPath() != null)) {
97             final QName qname = schemaPath.getPath().get(0);
98
99             if ((qname != null) && (qname.getNamespace() != null)) {
100                 return context
101                         .findModuleByNamespace(qname.getNamespace());
102             }
103         }
104         return null;
105     }
106     
107     /**
108      * Search which starts from root of Module.
109      * 
110      * @param module
111      * @param prefixedPath
112      * @return
113      */
114     private DataSchemaNode findSchemaNodeForGivenPath(final Module module,
115             final Queue<String> prefixedPath) {
116         if ((module != null) && (prefixedPath != null)) {
117             DataNodeContainer nextContainer = module;
118             final String modulePrefix = module.getPrefix();
119
120             String childNodeName = null;
121             DataSchemaNode schemaNode = null;
122             while ((nextContainer != null) && (prefixedPath.size() > 0)) {
123                 childNodeName = prefixedPath.poll();
124                 if (childNodeName.contains(":")) {
125                     final String[] prefixedChildNode = childNodeName.split(":");
126                     if ((modulePrefix != null)
127                             && modulePrefix.equals(prefixedChildNode[0])) {
128
129                         childNodeName = prefixedChildNode[1];
130                     } else {
131                         final Module nextModule = resolveModuleForPrefix(
132                                 prefixedChildNode[0], module);
133                         final Queue<String> nextModulePrefixedPath = new LinkedList<String>();
134                         nextModulePrefixedPath.add(childNodeName);
135                         nextModulePrefixedPath.addAll(prefixedPath);
136                         prefixedPath.clear();
137
138                         schemaNode = findSchemaNodeForGivenPath(nextModule,
139                                 nextModulePrefixedPath);
140
141                         return schemaNode;
142                     }
143                 }
144
145                 schemaNode = nextContainer.getDataChildByName(childNodeName);
146                 if (schemaNode instanceof ContainerSchemaNode) {
147                     nextContainer = (ContainerSchemaNode) schemaNode;
148                 } else if (schemaNode instanceof ListSchemaNode) {
149                     nextContainer = (ListSchemaNode) schemaNode;
150                 } else {
151                     return schemaNode;
152                 }
153             }
154         }
155         return null;
156     }
157
158     private Module resolveModuleForPrefix(final String prefix,
159             final Module parent) {
160         if ((prefix != null) && (parent != null)) {
161             final Set<ModuleImport> imports = parent.getImports();
162
163             if (imports != null) {
164                 for (final ModuleImport impModule : imports) {
165                     final String impModPrefix = impModule.getPrefix();
166                     if ((impModPrefix != null) && prefix.equals(impModPrefix)) {
167                         return resolveModuleFromContext(prefix,
168                                 impModule.getModuleName());
169                     }
170                 }
171             }
172         }
173         return null;
174     }
175
176     private Module resolveModuleFromContext(final String prefix,
177             final String moduleName) {
178         final Set<Module> modules = context.getModules();
179
180         if ((prefix != null) && (moduleName != null) && (modules != null)) {
181             for (Module module : modules) {
182                 if ((module != null) && prefix.equals(module.getPrefix())
183                         && moduleName.equals(module.getName())) {
184                     return module;
185                 }
186             }
187         }
188         return null;
189     }
190
191     private Queue<String> xpathToQueuedPath(final String xpath) {
192         final Queue<String> retQueue = new LinkedList<String>();
193         if ((xpath != null)) {
194             final String[] prefixedPath = xpath.split("/");
195
196             if (prefixedPath != null) {
197                 for (int i = 0; i < prefixedPath.length; ++i) {
198                     if (!prefixedPath[i].isEmpty()) {
199                         retQueue.add(prefixedPath[i]);
200                     }
201                 }
202             }
203         }
204         return retQueue;
205     }
206     
207     private Queue<String> schemaPathToQueuedPath(final SchemaPath schemaPath) {
208         final Queue<String> retQueue = new LinkedList<String>();
209         if ((schemaPath != null) && (schemaPath.getPath() != null)) {
210             final List<QName> listPath = schemaPath.getPath();
211             
212             for (final QName qname : listPath) {
213                 if (qname != null) {
214                     final String prefix = qname.getPrefix();
215                     final String localName = qname.getLocalName();
216                     
217                     final StringBuilder builder = new StringBuilder();
218                     if (prefix != null) {
219                         builder.append(prefix);
220                         builder.append(":");
221                     }
222                     builder.append(localName);
223                     retQueue.add(builder.toString());
224                 }
225             }
226         }
227         return retQueue;
228     }
229     
230     private Queue<String> resolveRelativeXPath(
231             final RevisionAwareXPath relativeXPath,
232             final SchemaPath leafrefSchemaPath) {
233         final Queue<String> absolutePath = new LinkedList<String>();
234
235         if ((relativeXPath != null) && !relativeXPath.isAbsolute()
236                 && (leafrefSchemaPath != null)) {
237             final String strXPath = relativeXPath.toString();
238             if (strXPath != null) {
239                 final String[] xpaths = strXPath.split("/");
240
241                 if (xpaths != null) {
242                     int colCount = 0;
243                     while (xpaths[colCount].contains("..")) {
244                         ++colCount;
245                     }
246                     final List<QName> path = leafrefSchemaPath.getPath();
247                     if (path != null) {
248                         int lenght = path.size() - colCount;
249                         for (int i = 0; i < lenght; ++i) {
250                             absolutePath.add(path.get(i).getLocalName());
251                         }
252                         for (int i = colCount; i < xpaths.length; ++i) {
253                             absolutePath.add(xpaths[i]);
254                         }
255                     }
256                 }
257             }
258         }
259         return absolutePath;
260     }
261 }