| /* |
| * Copyright 2016-present Open Networking Laboratory |
| * |
| * Licensed under the Apache License, Version 2.0 (the "License"); |
| * you may not use this file except in compliance with the License. |
| * You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| |
| package org.onosproject.yms.app.ych.defaultcodecs.xml; |
| |
| import org.dom4j.Document; |
| import org.dom4j.DocumentException; |
| import org.dom4j.DocumentHelper; |
| import org.dom4j.Element; |
| import org.dom4j.Namespace; |
| import org.onosproject.yms.app.ych.YchException; |
| import org.onosproject.yms.app.ych.defaultcodecs.netconf.NetconfCodec; |
| import org.onosproject.yms.app.ych.defaultcodecs.utils.DefaultCodecUtils; |
| import org.onosproject.yms.app.ydt.DefaultYdtWalker; |
| import org.onosproject.yms.app.ydt.YangRequestWorkBench; |
| import org.onosproject.yms.app.ydt.YdtExtendedBuilder; |
| import org.onosproject.yms.app.ydt.YdtExtendedContext; |
| import org.onosproject.yms.app.ydt.YdtExtendedWalker; |
| import org.onosproject.yms.app.ysr.YangSchemaRegistry; |
| import org.onosproject.yms.ych.YangCompositeEncoding; |
| import org.onosproject.yms.ych.YangDataTreeCodec; |
| import org.onosproject.yms.ydt.YdtBuilder; |
| import org.onosproject.yms.ydt.YmsOperationType; |
| |
| import java.util.Map; |
| |
| import static org.onosproject.yms.ych.YangProtocolEncodingFormat.XML; |
| import static org.onosproject.yms.ydt.YdtContextOperationType.CREATE; |
| |
| /** |
| * Represents an implementation of YCH data tree codec interface. |
| */ |
| public class DefaultXmlCodec implements YangDataTreeCodec { |
| |
| private static final String E_RESTCONF_ROOT = "/onos/restconf"; |
| private static final String E_YDT_ROOT_NODE = "YDT extended root node " + |
| "is null."; |
| private static final String E_ROOT_ELEMENT = "Root element in XML " + |
| "input string is not well-formed."; |
| private static final String E_ROOT_KEY_ELEMENT = "Root element " + |
| "(filter, config, data) in XML input string is not found."; |
| |
| |
| /** |
| * Creates a new YANG xml codec. |
| */ |
| public DefaultXmlCodec() { |
| } |
| |
| /** |
| * Returns the xml string from YDT. |
| * |
| * @param ydtBuilder YDT builder |
| * @return the xml string from YDT |
| */ |
| private String buildXmlForYdt(YdtBuilder ydtBuilder) { |
| |
| YdtExtendedBuilder extBuilder = (YdtExtendedBuilder) ydtBuilder; |
| YdtExtendedContext rootNode = extBuilder.getRootNode(); |
| |
| if (rootNode == null) { |
| throw new YchException(E_YDT_ROOT_NODE); |
| } |
| |
| // Creating the root element for xml. |
| Element rootElement = |
| DocumentHelper.createDocument().addElement(rootNode.getName()); |
| |
| // Adding the name space if exist for root name. |
| if (rootNode.getNamespace() != null) { |
| rootElement.add(Namespace.get(rootNode.getNamespace())); |
| } |
| |
| // Adding the attribute if exist |
| Map<String, String> tagAttrMap = extBuilder.getRootTagAttributeMap(); |
| if (tagAttrMap != null && !tagAttrMap.isEmpty()) { |
| for (Map.Entry<String, String> attr : tagAttrMap.entrySet()) { |
| rootElement.addAttribute(attr.getKey(), attr.getValue()); |
| } |
| } |
| |
| XmlCodecYdtListener listener = new XmlCodecYdtListener(XML, rootNode); |
| listener.getElementStack().push(rootElement); |
| |
| // Walk through YDT and build the xml. |
| YdtExtendedWalker extWalker = new DefaultYdtWalker(); |
| extWalker.walk(listener, rootNode); |
| |
| return rootElement.asXML(); |
| } |
| |
| @Override |
| public String encodeYdtToProtocolFormat(YdtBuilder ydtBuilder) { |
| return buildXmlForYdt(ydtBuilder); |
| } |
| |
| @Override |
| public YangCompositeEncoding encodeYdtToCompositeProtocolFormat( |
| YdtBuilder ydtBuilder) { |
| |
| YangCompositeEncodingImpl encoding = new YangCompositeEncodingImpl(); |
| encoding.setResourceIdentifier(null); |
| encoding.setResourceInformation(buildXmlForYdt(ydtBuilder)); |
| return encoding; |
| } |
| |
| @Override |
| public YdtBuilder decodeCompositeProtocolDataToYdt( |
| YangCompositeEncoding protoData, |
| Object schemaReg, |
| YmsOperationType opType) { |
| |
| YdtExtendedBuilder extBuilder = |
| new YangRequestWorkBench(E_RESTCONF_ROOT, null, |
| opType, |
| (YangSchemaRegistry) schemaReg, |
| false); |
| |
| DefaultCodecUtils.convertUriToYdt(protoData.getResourceIdentifier(), |
| extBuilder, |
| CREATE); |
| Document document; |
| |
| try { |
| document = DocumentHelper |
| .parseText(protoData.getResourceInformation()); |
| } catch (DocumentException e) { |
| throw new YchException(E_ROOT_ELEMENT); |
| } |
| |
| XmlCodecListener listener = new XmlCodecListener(); |
| listener.setYdtExtBuilder(extBuilder); |
| |
| // Walk through xml and build the yang data tree. |
| XmlWalker walker = new DefaultXmlCodecWalker(); |
| walker.walk(listener, document.getRootElement(), |
| document.getRootElement()); |
| return extBuilder; |
| } |
| |
| @Override |
| public YdtBuilder decodeProtocolDataToYdt(String protoData, |
| Object schemaReg, |
| YmsOperationType opType) { |
| Document document; |
| |
| try { |
| document = DocumentHelper.parseText(protoData); |
| } catch (DocumentException e) { |
| throw new YchException(E_ROOT_ELEMENT); |
| } |
| |
| NetconfCodec codec = new NetconfCodec(); |
| // Find the root element in xml string |
| Element rootElement = |
| codec.getDataRootElement(document.getRootElement(), opType); |
| |
| if (rootElement == null) { |
| throw new YchException(E_ROOT_KEY_ELEMENT); |
| } |
| |
| // Get the YDT builder for the logical root name. |
| YdtExtendedBuilder extBuilder = |
| new YangRequestWorkBench(rootElement.getName(), |
| rootElement.getNamespaceURI(), |
| opType, |
| (YangSchemaRegistry) schemaReg, |
| false); |
| |
| XmlCodecListener listener = new XmlCodecListener(); |
| listener.setYdtExtBuilder(extBuilder); |
| // Walk through xml and build the yang data tree. |
| XmlWalker walker = new DefaultXmlCodecWalker(); |
| walker.walk(listener, rootElement, rootElement); |
| return extBuilder; |
| } |
| } |