1 /*******************************************************************************
\r
2 * ============LICENSE_START====================================================
\r
4 * * ===========================================================================
\r
5 * * Copyright © 2017 AT&T Intellectual Property. All rights reserved.
\r
6 * * ===========================================================================
\r
7 * * Licensed under the Apache License, Version 2.0 (the "License");
\r
8 * * you may not use this file except in compliance with the License.
\r
9 * * You may obtain a copy of the License at
\r
11 * * http://www.apache.org/licenses/LICENSE-2.0
\r
13 * * Unless required by applicable law or agreed to in writing, software
\r
14 * * distributed under the License is distributed on an "AS IS" BASIS,
\r
15 * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
\r
16 * * See the License for the specific language governing permissions and
\r
17 * * limitations under the License.
\r
18 * * ============LICENSE_END====================================================
\r
20 * * ECOMP is a trademark and service mark of AT&T Intellectual Property.
\r
22 ******************************************************************************/
\r
23 package org.onap.aaf.rosetta;
\r
25 import java.io.IOException;
\r
26 import java.io.Reader;
\r
27 import java.io.Writer;
\r
28 import java.util.List;
\r
30 import org.onap.aaf.inno.env.Env;
\r
31 import org.onap.aaf.inno.env.TimeTaken;
\r
32 import org.onap.aaf.rosetta.Saved.State;
\r
35 * An Out Object that will save off produced Parsed Stream and
\r
36 * a Parse (In) Object that will reproduce Parsed Stream on demand
\r
40 public class Saved extends Out implements Parse<Reader, State>{
\r
41 private static final String ROSETTA_SAVED = "Rosetta Saved";
\r
42 private final static int INIT_SIZE=128;
\r
43 private Content content[];
\r
45 private boolean append = false;
\r
48 * Read from Parsed Stream and save
\r
51 public<IN,S> void extract(IN in, Writer ignore, Parse<IN,S> parser, boolean ... options) throws IOException, ParseException {
\r
52 Parsed<S> p = parser.newParsed();
\r
54 // reuse array if not too big
\r
55 if(content==null||content.length>INIT_SIZE*3) {
\r
56 content = new Content[INIT_SIZE];
\r
63 // Note: idx needs to be -1 on initialization and no appendages
\r
64 while((p = parser.parse(in,p.reuse())).valid()) {
\r
65 if(!(append && (p.event==START_DOC || p.event==END_DOC))) { // skip any start/end of document in appendages
\r
66 if(++idx>=content.length) {
\r
67 Content temp[] = new Content[content.length*2];
\r
68 System.arraycopy(content, 0, temp, 0, idx);
\r
71 content[idx]= new Content(p);
\r
77 public Parsed<State> parse(Reader ignore, Parsed<State> parsed) throws ParseException {
\r
79 if((i=parsed.state.count++)<=idx)
\r
80 content[i].load(parsed);
\r
82 parsed.event = Parse.NONE;
\r
86 public Content[] cut(char event, int count) {
\r
88 for(int i=idx;i>=0;--i) {
\r
89 if(content[i].event==event) count--;
\r
91 Content[] appended = new Content[idx-i+1];
\r
92 System.arraycopy(content, i, appended, 0, appended.length);
\r
97 return new Content[0];
\r
100 public void paste(Content[] appended) {
\r
101 if(appended!=null) {
\r
102 if(idx+appended.length>content.length) {
\r
103 Content temp[] = new Content[content.length*2];
\r
104 System.arraycopy(content, 0, temp, 0, idx);
\r
107 System.arraycopy(appended,0,content,idx+1,appended.length);
\r
108 idx+=appended.length;
\r
110 this.append = false;
\r
113 public static class State {
\r
114 public int count = 0;
\r
117 public static class Content {
\r
118 private boolean isString;
\r
119 private char event;
\r
120 private String name;
\r
121 private List<Prop> props;
\r
122 private String str;
\r
124 public Content(Parsed<?> p) {
\r
125 isString = p.isString;
\r
128 // avoid copying, because most elements don't have content
\r
129 // Cannot set to "equals", because sb ends up being cleared (and reused)
\r
130 str = p.sb.length()==0?null:p.sb.toString();
\r
133 public void load(Parsed<State> p) {
\r
134 p.isString = isString;
\r
141 public String toString() {
\r
142 StringBuilder sb = new StringBuilder();
\r
147 if(isString)sb.append('"');
\r
149 if(isString)sb.append('"');
\r
152 boolean comma = false;
\r
153 for(Prop prop : props) {
\r
154 if(comma)sb.append(',');
\r
156 sb.append(prop.tag);
\r
158 sb.append(prop.value);
\r
161 return sb.toString();
\r
166 public Parsed<State> newParsed() {
\r
167 Parsed<State> ps = new Parsed<State>(new State());
\r
172 * Convenience function
\r
175 * @throws IOException
\r
176 * @throws ParseException
\r
178 public<IN,S> void load(IN in, Parse<IN, S> parser) throws IOException, ParseException {
\r
179 extract(in,(Writer)null, parser);
\r
184 public TimeTaken start(Env env) {
\r
185 return env.start(ROSETTA_SAVED, 0);
\r
189 public String logName() {
\r
190 return ROSETTA_SAVED;
\r