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.Stack;
28 import org.onap.aaf.misc.env.util.IndentPrintWriter;
30 public class OutJson extends Out {
33 public<IN,S> void extract(IN in, Writer writer, Parse<IN, S> prs, boolean ... options) throws IOException, ParseException {
34 Parsed<S> p = prs.newParsed();
35 IndentPrintWriter ipw;
36 if (options.length>0 && options[0]) { // is Pretty
37 ipw = writer instanceof IndentPrintWriter?(IndentPrintWriter)writer:new IndentPrintWriter(writer);
43 // If it's a fragment, print first Object Name. If root Object, skip first name
44 Stack<LevelStack> jsonLevel = new Stack<LevelStack>();
45 jsonLevel.push(new LevelStack(options.length>1 && options[1]));
46 boolean print = true, hadData=false;
47 char afterName=0, beforeName=0, maybe = 0, prev=0;
50 while ((p = prs.parse(in,p.reuse())).valid()) {
56 if (count==2) { // it's empty, write open/close on it's own
64 if (jsonLevel.peek().printObjectName) {
66 } else { // don't print names on first
69 maybe=jsonLevel.peek().listItem();
70 jsonLevel.push(new LevelStack(true));
73 if (p.hasData()) { // if we have data, we print that, so may need to prepend a comma.
74 maybe = jsonLevel.peek().listItem();
75 } else { // No data means just print,
76 p.name = ""; // XML tags come through with names, but no data
84 if ((prev==',' && !hadData) || prev==']')maybe=',';
85 else maybe = jsonLevel.peek().listItem();
87 jsonLevel.push(new LevelStack(false));
93 if (prev==',' && !hadData)maybe=',';
94 else maybe = jsonLevel.peek().listItem();
96 p.name = ""; // XML tags come through with names, but no data
108 maybe=jsonLevel.peek().listItem();
117 if (ipw==null)writer.append(maybe);
118 else ipw.println(maybe);
122 // commented out unreachable code (as it is, beforeName is never
123 // assigned any value except 0
124 //if (beforeName!=0) {
125 // if (ipw==null)writer.append(beforeName);
126 // else ipw.println(beforeName);
132 if (p.event==3)writer.append("__");
133 writer.append(p.name);
134 writer.append("\":");
139 escapedWrite(writer, p.sb);
141 } else if (p.sb.length()>0) {
147 if (ipw==null)writer.append(afterName);
151 ipw.println(afterName);
157 ipw.print(afterName);
160 if (prev=='}' || prev==',')ipw.println();
162 ipw.print(afterName);
166 ipw.println(afterName);
169 ipw.print(afterName);
184 hadData = p.hasData();
190 private void escapedWrite(Writer writer, StringBuilder sb) throws IOException {
192 for (int i=0;i<sb.length();++i) {
193 switch(c=sb.charAt(i)) {
203 // Passthrough on purpose
213 public String logName() {
214 return "Rosetta JSON";
217 private static class LevelStack {
218 public boolean printObjectName=false;
219 private boolean first_n_List=true;
221 public LevelStack(boolean printObjectName) {
222 this.printObjectName = printObjectName;
225 public char listItem() {