AT&T 2.0.19 Code drop, stage 1
[aaf/authz.git] / misc / rosetta / src / main / java / org / onap / aaf / misc / rosetta / InJson.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
27 import org.onap.aaf.misc.env.Env;
28 import org.onap.aaf.misc.env.TimeTaken;
29 import org.onap.aaf.misc.rosetta.InJson.State;
30
31 public class InJson implements Parse<Reader, State> {
32         public Parsed<State> parse(Reader r, Parsed<State> parsed) throws ParseException {
33                 // First things first, if there's a "leftover" event, process that immediately
34                 State state = (State)parsed.state;
35                 if(state.unsent > 0) {
36                         parsed.event = state.unsent;
37                         state.unsent = 0;
38                         return parsed;
39                 }
40                 
41                 int ch;
42                 char c;
43                 StringBuilder sb = parsed.sb;
44                 boolean inQuotes = false, escaped = false;
45                 boolean go = true;
46                 try {
47                         // Gather data from Reader, looking for special characters when not in Quotes
48                         while(go && (ch=r.read())>=0) {
49                                 if(state.braces>=0 || ch==Parse.START_OBJ) { // ignore garbage/whitespace before content
50                                         c=(char)ch;
51                                         // Character is a quote.  
52                                         if(c=='"') {
53                                                 if(inQuotes) {
54                                                         if(escaped) {  // if escaped Quote, add to data.
55                                                                 sb.append(c);
56                                                                 escaped = false;
57                                                         } else {
58                                                                 inQuotes = false;
59                                                         }
60                                                 } else {
61                                                         parsed.isString=true;
62                                                         inQuotes = true;
63                                                 }
64                                         } else { // Not a Quote
65                                                 if(inQuotes) {
66                                                         if(c=='\\') {
67                                                                 if(escaped) {
68                                                                         sb.append("\\\\");
69                                                                         escaped = false;
70                                                                 } else {
71                                                                         escaped = true;
72                                                                 }
73                                                         } else {
74                                                                 sb.append(c);
75                                                         }
76                                                 } else {
77                                                         switch(c) {
78                                                                 case ':':
79                                                                         parsed.dataIsName();
80                                                                         parsed.isString = false;
81                                                                         break;
82                                                                 case Parse.START_OBJ:
83                                                                         if(state.braces++ == 0) {
84                                                                                 parsed.event = START_DOC;
85                                                                                 state.unsent = c;
86                                                                         } else {
87                                                                                 parsed.event = c;
88                                                                         }
89                                                                         go = false;
90                                                                         break;
91                                                                 case Parse.END_OBJ:
92                                                                         if(--state.braces == 0) {
93                                                                                 parsed.event = c;
94                                                                                 state.unsent = END_DOC;
95                                                                         } else {
96                                                                                 parsed.event = c;
97                                                                         }
98                                                                         go = false;
99                                                                         break;
100                                                                 // These three end the data gathering, and send it along with the event that is ending the data gathering
101                                                                 case Parse.NEXT:
102                                                                         if(parsed.name.startsWith("__")) {
103                                                                                 parsed.event = Parse.ATTRIB;
104                                                                                 parsed.name = parsed.name.substring(2);
105                                                                         } else {
106                                                                                 parsed.event = c;
107                                                                         }
108                                                                         go = false;
109                                                                         break;
110                                                                 case Parse.START_ARRAY:
111                                                                 case Parse.END_ARRAY:
112                                                                         parsed.event = c;
113                                                                         go = false;
114                                                                         break;
115                                                                                 
116                                                                 // The Escape Sequence, for Quote marks within Quotes
117                                                                 case '\\':
118                                                                 // Ignore these, unless within quotes, at which point data-gather
119                                                                 case ' ':
120                                                                 case '\b':
121                                                                 case '\f':
122                                                                 case '\n':
123                                                                 case '\r':
124                                                                 case '\t':
125                                                                         break;
126                                                                 // Normal data... gather it
127                                                                 default:
128                                                                         sb.append(c);
129                                                         }
130                                                 }
131                                         }
132                                 }
133                         }
134                         return parsed;
135                 } catch (IOException e) {
136                         throw new ParseException(e);
137                 }
138         }
139
140         public static class State {
141                 public int braces = 0;
142                 public char unsent = 0;
143         }
144         
145 //      @Override
146         public Parsed<State> newParsed() {
147                 return new Parsed<State>(new State()); // no State needed
148         }
149
150 //      @Override
151         public TimeTaken start(Env env) {
152                 return env.start("Rosetta JSON In", Env.JSON);
153         }
154 }