Fix license issues in dmaap dr
[dmaap/datarouter.git] / datarouter-prov / src / main / java / org / json / JSONWriter.java
1 /*******************************************************************************\r
2  * ============LICENSE_START==================================================\r
3  * * org.onap.dmaap\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
10  * * \r
11  *  *      http://www.apache.org/licenses/LICENSE-2.0\r
12  * * \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
19  * *\r
20  * * ECOMP is a trademark and service mark of AT&T Intellectual Property.\r
21  * *\r
22  ******************************************************************************/\r
23 package org.json;\r
24 \r
25 import java.io.IOException;\r
26 import java.io.Writer;\r
27 \r
28 \r
29 \r
30 public class JSONWriter {\r
31     private static final int maxdepth = 200;\r
32 \r
33     /**\r
34      * The comma flag determines if a comma should be output before the next\r
35      * value.\r
36      */\r
37     private boolean comma;\r
38 \r
39     /**\r
40      * The current mode. Values:\r
41      * 'a' (array),\r
42      * 'd' (done),\r
43      * 'i' (initial),\r
44      * 'k' (key),\r
45      * 'o' (object).\r
46      */\r
47     protected char mode;\r
48 \r
49     /**\r
50      * The object/array stack.\r
51      */\r
52     private final JSONObject stack[];\r
53 \r
54     /**\r
55      * The stack top index. A value of 0 indicates that the stack is empty.\r
56      */\r
57     private int top;\r
58 \r
59     /**\r
60      * The writer that will receive the output.\r
61      */\r
62     protected Writer writer;\r
63 \r
64     /**\r
65      * Make a fresh JSONWriter. It can be used to build one JSON text.\r
66      */\r
67     public JSONWriter(Writer w) {\r
68         this.comma = false;\r
69         this.mode = 'i';\r
70         this.stack = new JSONObject[maxdepth];\r
71         this.top = 0;\r
72         this.writer = w;\r
73     }\r
74 \r
75     /**\r
76      * Append a value.\r
77      * @param string A string value.\r
78      * @return this\r
79      * @throws JSONException If the value is out of sequence.\r
80      */\r
81     private JSONWriter append(String string) throws JSONException {\r
82         if (string == null) {\r
83             throw new JSONException("Null pointer");\r
84         }\r
85         if (this.mode == 'o' || this.mode == 'a') {\r
86             try {\r
87                 if (this.comma && this.mode == 'a') {\r
88                     this.writer.write(',');\r
89                 }\r
90                 this.writer.write(string);\r
91             } catch (IOException e) {\r
92                 throw new JSONException(e);\r
93             }\r
94             if (this.mode == 'o') {\r
95                 this.mode = 'k';\r
96             }\r
97             this.comma = true;\r
98             return this;\r
99         }\r
100         throw new JSONException("Value out of sequence.");\r
101     }\r
102 \r
103     /**\r
104      * Begin appending a new array. All values until the balancing\r
105      * <code>endArray</code> will be appended to this array. The\r
106      * <code>endArray</code> method must be called to mark the array's end.\r
107      * @return this\r
108      * @throws JSONException If the nesting is too deep, or if the object is\r
109      * started in the wrong place (for example as a key or after the end of the\r
110      * outermost array or object).\r
111      */\r
112     public JSONWriter array() throws JSONException {\r
113         if (this.mode == 'i' || this.mode == 'o' || this.mode == 'a') {\r
114             this.push(null);\r
115             this.append("[");\r
116             this.comma = false;\r
117             return this;\r
118         }\r
119         throw new JSONException("Misplaced array.");\r
120     }\r
121 \r
122     /**\r
123      * End something.\r
124      * @param mode Mode\r
125      * @param c Closing character\r
126      * @return this\r
127      * @throws JSONException If unbalanced.\r
128      */\r
129     private JSONWriter end(char mode, char c) throws JSONException {\r
130         if (this.mode != mode) {\r
131             throw new JSONException(mode == 'a'\r
132                 ? "Misplaced endArray."\r
133                 : "Misplaced endObject.");\r
134         }\r
135         this.pop(mode);\r
136         try {\r
137             this.writer.write(c);\r
138         } catch (IOException e) {\r
139             throw new JSONException(e);\r
140         }\r
141         this.comma = true;\r
142         return this;\r
143     }\r
144 \r
145     /**\r
146      * End an array. This method most be called to balance calls to\r
147      * <code>array</code>.\r
148      * @return this\r
149      * @throws JSONException If incorrectly nested.\r
150      */\r
151     public JSONWriter endArray() throws JSONException {\r
152         return this.end('a', ']');\r
153     }\r
154 \r
155     /**\r
156      * End an object. This method most be called to balance calls to\r
157      * <code>object</code>.\r
158      * @return this\r
159      * @throws JSONException If incorrectly nested.\r
160      */\r
161     public JSONWriter endObject() throws JSONException {\r
162         return this.end('k', '}');\r
163     }\r
164 \r
165     /**\r
166      * Append a key. The key will be associated with the next value. In an\r
167      * object, every value must be preceded by a key.\r
168      * @param string A key string.\r
169      * @return this\r
170      * @throws JSONException If the key is out of place. For example, keys\r
171      *  do not belong in arrays or if the key is null.\r
172      */\r
173     public JSONWriter key(String string) throws JSONException {\r
174         if (string == null) {\r
175             throw new JSONException("Null key.");\r
176         }\r
177         if (this.mode == 'k') {\r
178             try {\r
179                 this.stack[this.top - 1].putOnce(string, Boolean.TRUE);\r
180                 if (this.comma) {\r
181                     this.writer.write(',');\r
182                 }\r
183                 this.writer.write(JSONObject.quote(string));\r
184                 this.writer.write(':');\r
185                 this.comma = false;\r
186                 this.mode = 'o';\r
187                 return this;\r
188             } catch (IOException e) {\r
189                 throw new JSONException(e);\r
190             }\r
191         }\r
192         throw new JSONException("Misplaced key.");\r
193     }\r
194 \r
195 \r
196     /**\r
197      * Begin appending a new object. All keys and values until the balancing\r
198      * <code>endObject</code> will be appended to this object. The\r
199      * <code>endObject</code> method must be called to mark the object's end.\r
200      * @return this\r
201      * @throws JSONException If the nesting is too deep, or if the object is\r
202      * started in the wrong place (for example as a key or after the end of the\r
203      * outermost array or object).\r
204      */\r
205     public JSONWriter object() throws JSONException {\r
206         if (this.mode == 'i') {\r
207             this.mode = 'o';\r
208         }\r
209         if (this.mode == 'o' || this.mode == 'a') {\r
210             this.append("{");\r
211             this.push(new JSONObject());\r
212             this.comma = false;\r
213             return this;\r
214         }\r
215         throw new JSONException("Misplaced object.");\r
216 \r
217     }\r
218 \r
219 \r
220     /**\r
221      * Pop an array or object scope.\r
222      * @param c The scope to close.\r
223      * @throws JSONException If nesting is wrong.\r
224      */\r
225     private void pop(char c) throws JSONException {\r
226         if (this.top <= 0) {\r
227             throw new JSONException("Nesting error.");\r
228         }\r
229         char m = this.stack[this.top - 1] == null ? 'a' : 'k';\r
230         if (m != c) {\r
231             throw new JSONException("Nesting error.");\r
232         }\r
233         this.top -= 1;\r
234         this.mode = this.top == 0\r
235             ? 'd'\r
236             : this.stack[this.top - 1] == null\r
237             ? 'a'\r
238             : 'k';\r
239     }\r
240 \r
241     /**\r
242      * Push an array or object scope.\r
243      * @param jo The scope to open.\r
244      * @throws JSONException If nesting is too deep.\r
245      */\r
246     private void push(JSONObject jo) throws JSONException {\r
247         if (this.top >= maxdepth) {\r
248             throw new JSONException("Nesting too deep.");\r
249         }\r
250         this.stack[this.top] = jo;\r
251         this.mode = jo == null ? 'a' : 'k';\r
252         this.top += 1;\r
253     }\r
254 \r
255 \r
256     /**\r
257      * Append either the value <code>true</code> or the value\r
258      * <code>false</code>.\r
259      * @param b A boolean.\r
260      * @return this\r
261      * @throws JSONException\r
262      */\r
263     public JSONWriter value(boolean b) throws JSONException {\r
264         return this.append(b ? "true" : "false");\r
265     }\r
266 \r
267     /**\r
268      * Append a double value.\r
269      * @param d A double.\r
270      * @return this\r
271      * @throws JSONException If the number is not finite.\r
272      */\r
273     public JSONWriter value(double d) throws JSONException {\r
274         return this.value(new Double(d));\r
275     }\r
276 \r
277     /**\r
278      * Append a long value.\r
279      * @param l A long.\r
280      * @return this\r
281      * @throws JSONException\r
282      */\r
283     public JSONWriter value(long l) throws JSONException {\r
284         return this.append(Long.toString(l));\r
285     }\r
286 \r
287 \r
288     /**\r
289      * Append an object value.\r
290      * @param object The object to append. It can be null, or a Boolean, Number,\r
291      *   String, JSONObject, or JSONArray, or an object that implements JSONString.\r
292      * @return this\r
293      * @throws JSONException If the value is out of sequence.\r
294      */\r
295     public JSONWriter value(Object object) throws JSONException {\r
296         return this.append(JSONObject.valueToString(object));\r
297     }\r
298 }\r