2 * ============LICENSE_START====================================================
4 * ===========================================================================
5 * Copyright (c) 2018 AT&T Intellectual Property. 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====================================================
22 package org.onap.aaf.misc.rosetta;
24 import java.io.IOException;
25 import java.io.Writer;
26 import java.util.ArrayList;
27 import java.util.HashMap;
28 import java.util.List;
30 import java.util.Stack;
32 import org.onap.aaf.misc.env.util.IndentPrintWriter;
33 import org.onap.aaf.misc.env.util.StringBuilderWriter;
35 public class OutXML extends Out{
36 private static final String XMLNS_XSI = "xmlns:xsi";
37 public static final String XML_INFO = "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>";
38 public static final String XML_SCHEMA_INSTANCE = "http://www.w3.org/2001/XMLSchema-instance";
41 private List<Prop> props;
43 public OutXML(String root, String ... params) {
45 props = new ArrayList<>();
46 for(String p : params) {
47 String[] tv=p.split("=");
49 props.add(new Prop(tv[0],tv[1]));
53 public OutXML(JaxInfo jaxInfo) {
54 this(jaxInfo.name,genNS(jaxInfo));
57 public OutXML(InXML inXML) {
58 this(inXML.jaxInfo.name,genNS(inXML.jaxInfo));
61 private static String[] genNS(JaxInfo jaxInfo) {
62 return new String[] {"xmlns=" + jaxInfo.ns};
67 public<IN,S> void extract(IN in, Writer writer, Parse<IN,S> prs, boolean ... options) throws IOException, ParseException {
68 Parsed<S> p = prs.newParsed();
69 Stack<Level> stack = new Stack<Level>();
70 // If it's an IndentPrintWriter, it is pretty printing.
71 boolean pretty = (options.length>0&&options[0]);
73 IndentPrintWriter ipw;
75 if(writer instanceof IndentPrintWriter) {
76 ipw = (IndentPrintWriter)writer;
78 writer = ipw = new IndentPrintWriter(writer);
83 boolean closeTag = false;
84 Level level = new Level(null);
85 while((p = prs.parse(in,p.reuse())).valid()) {
86 if(!p.hasName() && level.multi!=null) {
89 if(closeTag && p.event!=Parse.ATTRIB) {
91 if(pretty)writer.append('\n');
96 if(!(options.length>1&&options[1])) // if not a fragment, print XML Info data
97 if(pretty)ipw.println(XML_INFO);
98 else writer.append(XML_INFO);
102 case Parse.START_OBJ:
104 level = new Level(level);
106 closeTag = tag(writer,level.sbw,pretty,pretty,p.name,null);
107 } else if(root!=null && stack.size()==1) { // first Object
108 closeTag = tag(writer,level.sbw,pretty,pretty,root,null);
110 for(Prop prop : props) {
111 attrib(writer,pretty,prop.tag, prop.value,level);
118 closeTag = tag(writer,writer,pretty,false,p.name, XmlEscape.convert(p.sb));
120 writer.append(level.sbw.getBuffer());
123 case Parse.START_ARRAY:
124 level.multi = p.name;
126 case Parse.END_ARRAY:
128 closeTag = tag(writer,writer,pretty,false, p.name, XmlEscape.convert(p.sb));
133 attrib(writer,pretty,p.name, XmlEscape.convert(p.sb), level);
137 closeTag = tag(writer,writer,pretty, false,p.name, XmlEscape.convert(p.sb));
141 writer.append(level.sbw.getBuffer());
145 private class Level {
146 public final StringBuilderWriter sbw;
149 private Map<String,String> nses;
151 public Level(Level level) {
152 sbw = new StringBuilderWriter();
157 public boolean hasPrinted(String ns, String value, boolean create) {
160 if(prev!=null)rv = prev.hasPrinted(ns, value, false);
162 String v = nses.get(ns);
163 return value.equals(v); // note: accomodates not finding NS as well
167 if(nses == null) nses = new HashMap<>();
177 private boolean tag(Writer fore, Writer aft, boolean pretty, boolean returns, String tag, String data) throws IOException {
181 fore.append('>'); // if no data, it may need some attributes...
183 if(returns)fore.append('\n');
188 if(pretty)aft.append('\n');
192 private void attrib(Writer fore, boolean pretty, String tag, String value, Level level) throws IOException {
193 String realTag = tag.startsWith("__")?tag.substring(2):tag; // remove __
194 if(realTag.equals(Parsed.EXTENSION_TAG)) { // Convert Derived name into XML defined Inheritance
195 fore.append(" xsi:type=\"");
198 if(!level.hasPrinted(XMLNS_XSI, XML_SCHEMA_INSTANCE,true)) {
200 fore.append(XMLNS_XSI);
202 fore.append(XML_SCHEMA_INSTANCE);
206 if(realTag.startsWith("xmlns:") ) {
207 if(level.hasPrinted(realTag, value, true)) {
212 fore.append(realTag);
220 public String logName() {
221 return "Rosetta XML";