2  * ============LICENSE_START=======================================================
 
   4  * ================================================================================
 
   5  * Copyright (C) 2018 Huawei Technologies Co., Ltd. All rights reserved.
 
   6  * ================================================================================
 
   7  * Licensed under the Apache License, Version 2.0 (the "License");
 
   8  * you may not use this file except in compliance with the License.
 
   9  * You may obtain a copy of the License at
 
  11  *      http://www.apache.org/licenses/LICENSE-2.0
 
  13  * Unless required by applicable law or agreed to in writing, software
 
  14  * distributed under the License is distributed on an "AS IS" BASIS,
 
  15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 
  16  * See the License for the specific language governing permissions and
 
  17  * limitations under the License.
 
  18  * ============LICENSE_END=========================================================
 
  21 package org.onap.ccsdk.sli.plugins.yangserializers.dfserializer;
 
  23 import org.dom4j.Element;
 
  24 import org.onap.ccsdk.sli.core.sli.SvcLogicException;
 
  25 import org.onap.ccsdk.sli.plugins.yangserializers.pnserializer.Namespace;
 
  26 import org.onap.ccsdk.sli.plugins.yangserializers.pnserializer.PropertiesNode;
 
  27 import org.opendaylight.yangtools.yang.model.api.Module;
 
  28 import org.opendaylight.yangtools.yang.model.api.SchemaContext;
 
  29 import org.opendaylight.yangtools.yang.model.api.TypeDefinition;
 
  30 import org.w3c.dom.Document;
 
  31 import org.xml.sax.InputSource;
 
  32 import org.xml.sax.SAXException;
 
  34 import javax.xml.parsers.DocumentBuilder;
 
  35 import javax.xml.parsers.DocumentBuilderFactory;
 
  36 import javax.xml.parsers.ParserConfigurationException;
 
  37 import javax.xml.transform.Transformer;
 
  38 import javax.xml.transform.TransformerException;
 
  39 import javax.xml.transform.TransformerFactory;
 
  40 import javax.xml.transform.dom.DOMSource;
 
  41 import javax.xml.transform.stream.StreamResult;
 
  42 import java.io.IOException;
 
  43 import java.io.StringReader;
 
  44 import java.io.StringWriter;
 
  45 import java.io.Writer;
 
  47 import java.net.URISyntaxException;
 
  48 import java.util.Iterator;
 
  50 import static javax.xml.transform.OutputKeys.INDENT;
 
  51 import static org.onap.ccsdk.sli.plugins.yangserializers.dfserializer.XmlNodeType.OBJECT_NODE;
 
  52 import static org.onap.ccsdk.sli.plugins.yangserializers.dfserializer.XmlNodeType.TEXT_NODE;
 
  53 import static org.onap.ccsdk.sli.plugins.yangserializers.pnserializer.MdsalPropertiesNodeUtils.getRevision;
 
  56  * Utilities for data format serializer.
 
  58 public final class DfSerializerUtil {
 
  60     static final String JSON_WRITE_ERR = "Unable to write to JSON from " +
 
  63     static final String NODE_TYPE_ERR = "The node type %s is not supported.";
 
  65     static final String JSON_LIS_ERR = "The JSON serializer doesn't have " +
 
  68     static final String XML_LIS_ERR = "The XML serializer doesn't have XML " +
 
  71     static final String JSON_TREE_ERR = "Unable to form JSON tree object from" +
 
  72             " the JSON body provided.";
 
  74     static final String XML_TREE_ERR = "Unable to form XML tree object from " +
 
  75             "the XML body provided.";
 
  77     static final String FORMAT_ERR = "Only JSON and XML formats are supported" +
 
  78             ". %s is not supported";
 
  80     static final String PROP_NODE_ERR = "The property node doesn't have " +
 
  81             "schema node bound to it.";
 
  83     static final String DF_ERR = "Type mismatch for the node %s. The schema " +
 
  84             "node does not match with the data format node type %s.";
 
  86     static final String UTF_HEADER = "<?xml version=\"1.0\" " +
 
  87             "encoding=\"UTF-8\"?>";
 
  89     static final String XML_PREFIX = "yangid";
 
  91     private static final String YES = "yes";
 
  93     private static final String INDENT_XMLNS = "{http://xml.apache" +
 
  94             ".org/xslt}indent-amount";
 
  96     private static final String XML_PARSE_ERR = "Unable to parse the xml to " +
 
  99     private static final String URI_ERR = "Unable to parse the URI";
 
 102     private DfSerializerUtil() {
 
 106      * Returns the writer which contains the pretty formatted XML string.
 
 108      * @param input  input XML
 
 109      * @param indent indentation level
 
 110      * @return writer with XML
 
 111      * @throws SvcLogicException when transformation of source fails
 
 113     static Writer getXmlWriter(String input, String indent) 
 
 114             throws SvcLogicException {
 
 116             Transformer transformer = TransformerFactory.newInstance()
 
 118             transformer.setOutputProperty(INDENT, YES);
 
 119             transformer.setOutputProperty(INDENT_XMLNS, indent);
 
 120             StreamResult result = new StreamResult(new StringWriter());
 
 121             DOMSource source = new DOMSource(parseXml(input));
 
 122             transformer.transform(source, result);
 
 123             return result.getWriter();
 
 124         } catch (TransformerException e) {
 
 125             throw new SvcLogicException(XML_PARSE_ERR + input, e);
 
 130      * Parses the XML and converts it into dom document which can be used for
 
 131      * formatting the XML.
 
 133      * @param in input XML
 
 134      * @return dom document of XML
 
 135      * @throws SvcLogicException when document building fails
 
 137     private static Document parseXml(String in) throws SvcLogicException {
 
 138         DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
 
 141             db = dbf.newDocumentBuilder();
 
 142             InputSource is = new InputSource(new StringReader(in));
 
 144         } catch (SAXException | IOException | ParserConfigurationException e) {
 
 145             throw new SvcLogicException(XML_PARSE_ERR + in, e);
 
 150      * Returns the resolved namespace object from the input received from the
 
 151      * abstract data format.
 
 153      * @param mName  module name
 
 154      * @param mUri   module URI
 
 155      * @param ctx    schema context
 
 156      * @param parent parent properties node
 
 158      * @throws SvcLogicException when resolving namespace fails
 
 160     static Namespace getResolvedNamespace(String mName, String mUri,
 
 162                                           PropertiesNode parent)
 
 163             throws SvcLogicException {
 
 164         if (mName == null && mUri == null) {
 
 165             Namespace parentNs = parent.namespace();
 
 166             return new Namespace(parentNs.moduleName(), parentNs.moduleNs(),
 
 167                                  parentNs.revision());
 
 173             it = ctx.findModules(mName).iterator();
 
 177                modUri = new URI(mUri);
 
 178             } catch (URISyntaxException e) {
 
 179                 throw new SvcLogicException(URI_ERR, e);
 
 181             it = ctx.findModules(modUri).iterator();
 
 189         return new Namespace(mod.getName(), mod.getQNameModule().getNamespace(),
 
 190                              getRevision(mod.getRevision()));
 
 194      * Returns the node type of a XML element.
 
 196      * @param element XML element
 
 197      * @return node type of the XML element
 
 199     static XmlNodeType getXmlNodeType(Element element) {
 
 200         Element newElement = element.createCopy();
 
 201         newElement.remove(element.getNamespace());
 
 202         return newElement.hasContent() && newElement.isTextOnly() ?
 
 203                 TEXT_NODE : OBJECT_NODE;
 
 207      * Resolves the super type to the base type from type definition.
 
 209      * @param type super type
 
 210      * @return base type definition
 
 212     static TypeDefinition<?> resolveBaseTypeFrom(TypeDefinition<?> type) {
 
 213         TypeDefinition superType;
 
 214         for(superType = type; superType.getBaseType() != null;
 
 215             superType = superType.getBaseType()) {