AT&T 2.0.19 Code drop, stage 1
[aaf/authz.git] / misc / rosetta / src / main / java / org / onap / aaf / misc / rosetta / Saved.java
1 /**
2  * ============LICENSE_START====================================================
3  * org.onap.aaf
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
10  * 
11  *      http://www.apache.org/licenses/LICENSE-2.0
12  * 
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====================================================
19  *
20  */
21
22 package org.onap.aaf.misc.rosetta;
23
24 import java.io.IOException;
25 import java.io.Reader;
26 import java.io.Writer;
27 import java.util.List;
28
29 import org.onap.aaf.misc.env.Env;
30 import org.onap.aaf.misc.env.TimeTaken;
31 import org.onap.aaf.misc.rosetta.Saved.State;
32
33 /**
34  * An Out Object that will save off produced Parsed Stream and 
35  * a Parse (In) Object that will reproduce Parsed Stream on demand
36  *  
37  * @author Jonathan
38  *
39  */
40 public class Saved extends Out implements Parse<Reader, State>{
41         private static final String ROSETTA_SAVED = "Rosetta Saved";
42         private final static int INIT_SIZE=128;
43         private Content content[];
44         private int idx;
45         private boolean append = false;
46         
47         /**
48          * Read from Parsed Stream and save
49          */
50         // @Override
51         public<IN,S> void extract(IN in, Writer ignore, Parse<IN,S> parser, boolean ... options) throws IOException, ParseException {
52                 Parsed<S> p = parser.newParsed();
53                 if(!append) {
54                         // reuse array  if not too big
55                         if(content==null||content.length>INIT_SIZE*3) {
56                                 content = new Content[INIT_SIZE];
57                                 idx = -1;
58                         } else do {
59                                 content[idx]=null;
60                         } while(--idx>=0);
61                 }
62                 
63                 // Note: idx needs to be -1 on initialization and no appendages
64                 while((p = parser.parse(in,p.reuse())).valid()) {
65                         if(!(append && (p.event==START_DOC || p.event==END_DOC))) { // skip any start/end of document in appendages
66                                 if(++idx>=content.length) {
67                                         Content temp[] = new Content[content.length*2];
68                                         System.arraycopy(content, 0, temp, 0, idx);
69                                         content = temp;
70                                 }
71                                 content[idx]= new Content(p);
72                         }
73                 }
74         }
75         
76         // @Override
77         public Parsed<State> parse(Reader ignore, Parsed<State> parsed) throws ParseException {
78                 int i;
79                 if((i=parsed.state.count++)<=idx) 
80                         content[i].load(parsed);
81                 else 
82                         parsed.event = Parse.NONE; 
83                 return parsed;
84         }
85
86         public Content[] cut(char event, int count) {
87                 append = true;
88                 for(int i=idx;i>=0;--i) {
89                         if(content[i].event==event) count--;
90                         if(count==0) {
91                                 Content[] appended = new Content[idx-i+1];
92                                 System.arraycopy(content, i, appended, 0, appended.length);
93                                 idx = i-1;
94                                 return appended;
95                         }
96                 }
97                 return new Content[0];
98         }
99
100         public void paste(Content[] appended) {
101                 if(appended!=null) {
102                         if(idx+appended.length>content.length) {
103                                 Content temp[] = new Content[content.length*2];
104                                 System.arraycopy(content, 0, temp, 0, idx);
105                                 content = temp;
106                         }
107                         System.arraycopy(appended,0,content,idx+1,appended.length);
108                         idx+=appended.length;
109                 }
110                 this.append = false;
111         }
112
113         public static class State {
114                 public int count = 0;
115         }
116         
117         public static class Content {
118                 private boolean isString;
119                 private char event;
120                 private String name;
121                 private List<Prop> props;
122                 private String str;
123                 
124                 public Content(Parsed<?> p) {
125                         isString = p.isString;
126                         event = p.event;
127                         name = p.name;
128                         // avoid copying, because most elements don't have content
129                         // Cannot set to "equals", because sb ends up being cleared (and reused)
130                         str = p.sb.length()==0?null:p.sb.toString();
131                 }
132
133                 public void load(Parsed<State> p) {
134                         p.isString = isString;
135                         p.event = event;
136                         p.name = name;
137                         if(str!=null)
138                                 p.sb.append(str);
139                 }
140                 
141                 public String toString() {
142                         StringBuilder sb = new StringBuilder();
143                         sb.append(event);
144                         sb.append(" - ");
145                         sb.append(name);
146                         sb.append(": ");
147                         if(isString)sb.append('"');
148                         sb.append(str);
149                         if(isString)sb.append('"');
150                         sb.append(' ');
151                         if(props!=null) {
152                                 boolean comma = false;
153                                 for(Prop prop : props) {
154                                         if(comma)sb.append(',');
155                                         else comma = true;
156                                         sb.append(prop.tag);
157                                         sb.append('=');
158                                         sb.append(prop.value);
159                                 }
160                         }
161                         return sb.toString();
162                 }
163         }
164         
165         //// @Override
166         public Parsed<State> newParsed() {
167                 Parsed<State> ps = new Parsed<State>(new State());
168                 return ps;
169         }
170
171         /**
172          * Convenience function
173          * @param rdr
174          * @param in
175          * @throws IOException
176          * @throws ParseException
177          */
178         public<IN,S> void load(IN in, Parse<IN, S> parser) throws IOException, ParseException {
179                 extract(in,(Writer)null, parser);
180         }
181
182
183         // @Override
184         public TimeTaken start(Env env) {
185                 return env.start(ROSETTA_SAVED, 0);
186         }
187         
188         @Override
189         public String logName() {
190                 return ROSETTA_SAVED;
191         }
192
193
194 }