efb4ce4bf975c2b2512e0255819951eb5a5eca06
[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 }