[ONOS-5088] YANG SBI Broker Implementation.

Change-Id: Ibe87e095a4c209c54e3e90aceca0ec9097c5ede0
diff --git a/apps/yms/app/src/main/java/org/onosproject/yms/app/ych/defaultcodecs/xml/DefaultXmlCodec.java b/apps/yms/app/src/main/java/org/onosproject/yms/app/ych/defaultcodecs/xml/DefaultXmlCodec.java
new file mode 100644
index 0000000..915863e
--- /dev/null
+++ b/apps/yms/app/src/main/java/org/onosproject/yms/app/ych/defaultcodecs/xml/DefaultXmlCodec.java
@@ -0,0 +1,190 @@
+/*
+ * 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;
+    }
+}