blob: 4fd56131e28c05f12e38be6964c24ba2dccdfaa3 [file] [log] [blame]
Shankara-Huaweid5823ab2016-11-22 10:14:52 +05301/*
Brian O'Connora09fe5b2017-08-03 21:12:30 -07002 * Copyright 2016-present Open Networking Foundation
Shankara-Huaweid5823ab2016-11-22 10:14:52 +05303 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package org.onosproject.yms.app.ych.defaultcodecs.xml;
18
19import org.dom4j.Document;
20import org.dom4j.DocumentException;
21import org.dom4j.DocumentHelper;
22import org.dom4j.Element;
23import org.dom4j.Namespace;
24import org.onosproject.yms.app.ych.YchException;
25import org.onosproject.yms.app.ych.defaultcodecs.netconf.NetconfCodec;
26import org.onosproject.yms.app.ych.defaultcodecs.utils.DefaultCodecUtils;
27import org.onosproject.yms.app.ydt.DefaultYdtWalker;
28import org.onosproject.yms.app.ydt.YangRequestWorkBench;
29import org.onosproject.yms.app.ydt.YdtExtendedBuilder;
30import org.onosproject.yms.app.ydt.YdtExtendedContext;
31import org.onosproject.yms.app.ydt.YdtExtendedWalker;
32import org.onosproject.yms.app.ysr.YangSchemaRegistry;
33import org.onosproject.yms.ych.YangCompositeEncoding;
34import org.onosproject.yms.ych.YangDataTreeCodec;
35import org.onosproject.yms.ydt.YdtBuilder;
36import org.onosproject.yms.ydt.YmsOperationType;
37
38import java.util.Map;
39
40import static org.onosproject.yms.ych.YangProtocolEncodingFormat.XML;
41import static org.onosproject.yms.ydt.YdtContextOperationType.CREATE;
42
43/**
44 * Represents an implementation of YCH data tree codec interface.
45 */
46public class DefaultXmlCodec implements YangDataTreeCodec {
47
48 private static final String E_RESTCONF_ROOT = "/onos/restconf";
49 private static final String E_YDT_ROOT_NODE = "YDT extended root node " +
50 "is null.";
51 private static final String E_ROOT_ELEMENT = "Root element in XML " +
52 "input string is not well-formed.";
53 private static final String E_ROOT_KEY_ELEMENT = "Root element " +
54 "(filter, config, data) in XML input string is not found.";
55
56
57 /**
58 * Creates a new YANG xml codec.
59 */
60 public DefaultXmlCodec() {
61 }
62
63 /**
64 * Returns the xml string from YDT.
65 *
66 * @param ydtBuilder YDT builder
67 * @return the xml string from YDT
68 */
69 private String buildXmlForYdt(YdtBuilder ydtBuilder) {
70
71 YdtExtendedBuilder extBuilder = (YdtExtendedBuilder) ydtBuilder;
72 YdtExtendedContext rootNode = extBuilder.getRootNode();
73
74 if (rootNode == null) {
75 throw new YchException(E_YDT_ROOT_NODE);
76 }
77
78 // Creating the root element for xml.
79 Element rootElement =
80 DocumentHelper.createDocument().addElement(rootNode.getName());
81
82 // Adding the name space if exist for root name.
83 if (rootNode.getNamespace() != null) {
84 rootElement.add(Namespace.get(rootNode.getNamespace()));
85 }
86
Jon Halla3fcf672017-03-28 16:53:22 -070087 if ("config".equals(rootElement.getName())) {
Sean Condonb0720e72017-01-10 12:29:02 +000088 rootElement.add(new Namespace("nc", "urn:ietf:params:xml:ns:netconf:base:1.0"));
89 }
90
Shankara-Huaweid5823ab2016-11-22 10:14:52 +053091 // Adding the attribute if exist
92 Map<String, String> tagAttrMap = extBuilder.getRootTagAttributeMap();
93 if (tagAttrMap != null && !tagAttrMap.isEmpty()) {
94 for (Map.Entry<String, String> attr : tagAttrMap.entrySet()) {
95 rootElement.addAttribute(attr.getKey(), attr.getValue());
96 }
97 }
98
99 XmlCodecYdtListener listener = new XmlCodecYdtListener(XML, rootNode);
100 listener.getElementStack().push(rootElement);
101
102 // Walk through YDT and build the xml.
103 YdtExtendedWalker extWalker = new DefaultYdtWalker();
104 extWalker.walk(listener, rootNode);
105
106 return rootElement.asXML();
107 }
108
109 @Override
110 public String encodeYdtToProtocolFormat(YdtBuilder ydtBuilder) {
111 return buildXmlForYdt(ydtBuilder);
112 }
113
114 @Override
115 public YangCompositeEncoding encodeYdtToCompositeProtocolFormat(
116 YdtBuilder ydtBuilder) {
117
118 YangCompositeEncodingImpl encoding = new YangCompositeEncodingImpl();
119 encoding.setResourceIdentifier(null);
120 encoding.setResourceInformation(buildXmlForYdt(ydtBuilder));
121 return encoding;
122 }
123
124 @Override
125 public YdtBuilder decodeCompositeProtocolDataToYdt(
126 YangCompositeEncoding protoData,
127 Object schemaReg,
128 YmsOperationType opType) {
129
130 YdtExtendedBuilder extBuilder =
131 new YangRequestWorkBench(E_RESTCONF_ROOT, null,
132 opType,
133 (YangSchemaRegistry) schemaReg,
134 false);
135
136 DefaultCodecUtils.convertUriToYdt(protoData.getResourceIdentifier(),
137 extBuilder,
138 CREATE);
139 Document document;
140
141 try {
142 document = DocumentHelper
143 .parseText(protoData.getResourceInformation());
144 } catch (DocumentException e) {
145 throw new YchException(E_ROOT_ELEMENT);
146 }
147
148 XmlCodecListener listener = new XmlCodecListener();
149 listener.setYdtExtBuilder(extBuilder);
150
151 // Walk through xml and build the yang data tree.
152 XmlWalker walker = new DefaultXmlCodecWalker();
153 walker.walk(listener, document.getRootElement(),
154 document.getRootElement());
155 return extBuilder;
156 }
157
158 @Override
159 public YdtBuilder decodeProtocolDataToYdt(String protoData,
160 Object schemaReg,
161 YmsOperationType opType) {
162 Document document;
163
164 try {
165 document = DocumentHelper.parseText(protoData);
166 } catch (DocumentException e) {
167 throw new YchException(E_ROOT_ELEMENT);
168 }
169
170 NetconfCodec codec = new NetconfCodec();
171 // Find the root element in xml string
172 Element rootElement =
173 codec.getDataRootElement(document.getRootElement(), opType);
174
175 if (rootElement == null) {
176 throw new YchException(E_ROOT_KEY_ELEMENT);
177 }
178
179 // Get the YDT builder for the logical root name.
180 YdtExtendedBuilder extBuilder =
181 new YangRequestWorkBench(rootElement.getName(),
182 rootElement.getNamespaceURI(),
183 opType,
184 (YangSchemaRegistry) schemaReg,
185 false);
186
187 XmlCodecListener listener = new XmlCodecListener();
188 listener.setYdtExtBuilder(extBuilder);
189 // Walk through xml and build the yang data tree.
190 XmlWalker walker = new DefaultXmlCodecWalker();
191 walker.walk(listener, rootElement, rootElement);
192 return extBuilder;
193 }
194}