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.yangtools.restconf.utils;
10 import com.google.common.base.Optional;
11 import com.google.common.base.Preconditions;
12 import com.google.common.collect.BiMap;
13 import com.google.common.collect.HashBiMap;
14 import java.io.IOException;
15 import java.io.InputStream;
17 import java.net.URLEncoder;
18 import java.util.AbstractMap.SimpleEntry;
19 import java.util.Arrays;
20 import java.util.Date;
21 import java.util.HashSet;
22 import java.util.List;
24 import java.util.Map.Entry;
26 import javax.xml.parsers.DocumentBuilder;
27 import javax.xml.parsers.DocumentBuilderFactory;
28 import javax.xml.parsers.ParserConfigurationException;
29 import org.eclipse.xtend2.lib.StringConcatenation;
30 import org.eclipse.xtext.xbase.lib.Functions;
31 import org.eclipse.xtext.xbase.lib.IterableExtensions;
32 import org.opendaylight.yangtools.yang.binding.DataObject;
33 import org.opendaylight.yangtools.yang.binding.RpcService;
34 import org.opendaylight.yangtools.yang.common.QName;
35 import org.opendaylight.yangtools.yang.data.api.CompositeNode;
36 import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier;
37 import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier.NodeIdentifier;
38 import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier.NodeIdentifierWithPredicates;
39 import org.opendaylight.yangtools.yang.data.api.Node;
40 import org.opendaylight.yangtools.yang.data.impl.codec.BindingIndependentMappingService;
41 import org.opendaylight.yangtools.yang.data.impl.codec.DeserializationException;
42 import org.opendaylight.yangtools.yang.data.impl.codec.xml.XmlCodecProvider;
43 import org.opendaylight.yangtools.yang.data.impl.codec.xml.XmlDocumentUtils;
44 import org.opendaylight.yangtools.yang.model.api.ContainerSchemaNode;
45 import org.opendaylight.yangtools.yang.model.api.DataNodeContainer;
46 import org.opendaylight.yangtools.yang.model.api.DataSchemaNode;
47 import org.opendaylight.yangtools.yang.model.api.ListSchemaNode;
48 import org.opendaylight.yangtools.yang.model.api.Module;
49 import org.opendaylight.yangtools.yang.model.api.SchemaContext;
50 import org.slf4j.Logger;
51 import org.slf4j.LoggerFactory;
52 import org.w3c.dom.Document;
53 import org.w3c.dom.Element;
54 import org.xml.sax.SAXException;
56 public class RestconfUtils {
58 private static final Logger logger = LoggerFactory.getLogger(RestconfUtils.class);
60 private static final BiMap<URI,String> uriToModuleName = new Functions.Function0<BiMap<URI,String>>() {
62 public BiMap<URI,String> apply() {
63 HashBiMap<URI,String> _create = HashBiMap.<URI, String>create();
69 public static Entry<String,DataSchemaNode> toRestconfIdentifier(org.opendaylight.yangtools.yang.binding.InstanceIdentifier<?> bindingIdentifier, BindingIndependentMappingService mappingService, SchemaContext schemaContext) {
70 InstanceIdentifier domIdentifier = mappingService.toDataDom(bindingIdentifier);
71 return toRestconfIdentifier(domIdentifier, schemaContext);
75 public static Entry<String,DataSchemaNode> toRestconfIdentifier(
76 InstanceIdentifier xmlInstanceIdentifier,
77 SchemaContext schemaContext) {
79 final List<InstanceIdentifier.PathArgument> elements = xmlInstanceIdentifier.getPath();
80 final StringBuilder ret = new StringBuilder();
81 InstanceIdentifier.PathArgument _head = IterableExtensions.<InstanceIdentifier.PathArgument>head(elements);
82 final QName startQName = _head.getNodeType();
83 URI _namespace = startQName.getNamespace();
84 Date _revision = startQName.getRevision();
85 final Module initialModule = schemaContext.findModuleByNamespaceAndRevision(_namespace, _revision);
86 DataNodeContainer node = (initialModule);
87 DataSchemaNode schemaNode = null;
88 for (final InstanceIdentifier.PathArgument element : elements) {
90 final DataSchemaNode potentialNode = node.getDataChildByName(element.getNodeType());
91 if (!isListOrContainer(potentialNode)) {
94 node = ((DataNodeContainer) potentialNode);
95 schemaNode = potentialNode;
96 ret.append(convertToRestconfIdentifier(element, node,schemaContext));
99 return new SimpleEntry<>(ret.toString(),schemaNode);
102 private static CharSequence convertContainerToRestconfIdentifier(final InstanceIdentifier.NodeIdentifier argument, final ContainerSchemaNode node, SchemaContext schemaContext) {
103 StringConcatenation _builder = new StringConcatenation();
104 _builder.append("/");
105 QName _nodeType = argument.getNodeType();
106 CharSequence _restconfIdentifier = toRestconfIdentifier(_nodeType,schemaContext);
107 _builder.append(_restconfIdentifier, "");
110 private static CharSequence convertListToRestconfIdentifier(final InstanceIdentifier.NodeIdentifierWithPredicates argument, final ListSchemaNode node,SchemaContext schemaContext) {
111 QName _nodeType = argument.getNodeType();
112 final CharSequence nodeIdentifier = toRestconfIdentifier(_nodeType,schemaContext);
113 final Map<QName,Object> keyValues = argument.getKeyValues();
114 StringConcatenation _builder = new StringConcatenation();
115 _builder.append("/");
116 _builder.append(nodeIdentifier, "");
117 _builder.append("/");
119 List<QName> _keyDefinition = node.getKeyDefinition();
120 boolean _hasElements = false;
121 for(final QName key : _keyDefinition) {
125 _builder.appendImmediate("/", "");
127 Object _get = keyValues.get(key);
128 String _uriString = toUriString(_get);
129 _builder.append(_uriString, "");
134 private static String toUriString(final Object object) {
135 boolean _tripleEquals = (object == null);
139 String _string = object.toString();
140 return URLEncoder.encode(_string);
143 public static CharSequence toRestconfIdentifier(final QName qname,SchemaContext schemaContext) {
144 URI _namespace = qname.getNamespace();
145 String module = uriToModuleName.get(_namespace);
146 boolean _tripleEquals = (module == null);
148 URI _namespace_1 = qname.getNamespace();
149 Date _revision = qname.getRevision();
150 final Module moduleSchema = schemaContext.findModuleByNamespaceAndRevision(_namespace_1, _revision);
151 boolean _tripleEquals_1 = (moduleSchema == null);
152 if (_tripleEquals_1) {
155 URI _namespace_2 = qname.getNamespace();
156 String _name = moduleSchema.getName();
157 uriToModuleName.put(_namespace_2, _name);
158 String _name_1 = moduleSchema.getName();
161 StringConcatenation _builder = new StringConcatenation();
162 _builder.append(module, "");
163 _builder.append(":");
164 String _localName = qname.getLocalName();
165 _builder.append(_localName, "");
168 private static CharSequence convertToRestconfIdentifier(final InstanceIdentifier.PathArgument argument, final DataNodeContainer node, SchemaContext schemaContext) {
169 if (argument instanceof InstanceIdentifier.NodeIdentifier
170 && node instanceof ContainerSchemaNode) {
171 return convertContainerToRestconfIdentifier((NodeIdentifier)argument, (ContainerSchemaNode) node,schemaContext);
172 } else if (argument instanceof InstanceIdentifier.NodeIdentifierWithPredicates
173 && node instanceof ListSchemaNode) {
174 return convertListToRestconfIdentifier((NodeIdentifierWithPredicates) argument,(ListSchemaNode) node,schemaContext);
176 throw new IllegalArgumentException("Unhandled parameter types: " +
177 Arrays.<Object>asList(argument, node).toString());
180 private static boolean isListOrContainer(final DataSchemaNode node) {
182 if ((node instanceof ListSchemaNode)) {
185 _or = ((node instanceof ListSchemaNode) || (node instanceof ContainerSchemaNode));
190 public static Module findModuleByNamespace(final URI namespace,SchemaContext schemaContext) {
191 boolean _tripleNotEquals = (namespace != null);
192 Preconditions.checkArgument(_tripleNotEquals);
193 final Set<Module> moduleSchemas = schemaContext.findModuleByNamespace(namespace);
194 Module _filterLatestModule = null;
195 if (moduleSchemas!=null) {
196 _filterLatestModule=filterLatestModule(moduleSchemas);
198 return _filterLatestModule;
201 private static Module filterLatestModule(final Iterable<Module> modules) {
202 Module latestModule = IterableExtensions.<Module>head(modules);
203 for (final Module module : modules) {
204 Date _revision = module.getRevision();
205 Date _revision_1 = latestModule.getRevision();
206 boolean _after = _revision.after(_revision_1);
208 latestModule = module;
214 public String findModuleNameByNamespace(final URI namespace,SchemaContext schemaContext) {
215 String moduleName = this.uriToModuleName.get(namespace);
216 boolean _tripleEquals = (moduleName == null);
218 final Module module = findModuleByNamespace(namespace, schemaContext);
219 boolean _tripleEquals_1 = (module == null);
220 if (_tripleEquals_1) {
223 String _name = module.getName();
225 this.uriToModuleName.put(namespace, moduleName);
230 public static Set<Class<? extends RpcService>> rpcServicesFromInputStream(InputStream inputStream, BindingIndependentMappingService mappingService){
232 DocumentBuilderFactory documentBuilder = DocumentBuilderFactory.newInstance();
233 documentBuilder.setNamespaceAware(true);
234 DocumentBuilder builder = documentBuilder.newDocumentBuilder();
235 Document doc = builder.parse(inputStream);
236 Element rootElement = doc.getDocumentElement();
238 List<Node<?>> domNodes = XmlDocumentUtils.toDomNodes(rootElement, Optional.<Set<DataSchemaNode>>absent());
240 Set<Class<? extends RpcService>> rpcServices = new HashSet<Class<? extends RpcService>>();
241 for (Node<?> node:domNodes){
242 rpcServices.add(mappingService.getRpcServiceClassFor(node.getNodeType().getNamespace().toString(),node.getNodeType().getRevision().toString()).get());
246 } catch (ParserConfigurationException e) {
247 logger.trace("Parse configuration exception {}",e);
248 } catch (SAXException e) {
249 logger.trace("SAX exception {}",e);
250 } catch (IOException e) {
251 logger.trace("IOException {}",e);
255 public static DataObject dataObjectFromInputStream(org.opendaylight.yangtools.yang.binding.InstanceIdentifier<?> path, InputStream inputStream, SchemaContext schemaContext, BindingIndependentMappingService mappingService, DataSchemaNode dataSchema) {
256 // Parse stream into w3c Document
258 DocumentBuilderFactory documentBuilder = DocumentBuilderFactory.newInstance();
259 documentBuilder.setNamespaceAware(true);
260 DocumentBuilder builder = documentBuilder.newDocumentBuilder();
261 Document doc = builder.parse(inputStream);
262 Element rootElement = doc.getDocumentElement();
263 Node<?> domNode = XmlDocumentUtils.toDomNode(rootElement, Optional.of(dataSchema), Optional.<XmlCodecProvider>absent());
264 DataObject dataObject = mappingService.dataObjectFromDataDom(path, (CompositeNode) domNode); //getDataFromResponse
266 } catch (DeserializationException e) {
269 } catch (ParserConfigurationException e) {
270 logger.trace("Parse configuration exception {}",e);
271 } catch (SAXException e) {
272 logger.trace("SAX exception {}", e);
273 } catch (IOException e) {
274 logger.trace("IOException {}", e);