source: josm/trunk/src/org/glassfish/json/JsonStructureParser.java@ 8877

Last change on this file since 8877 was 6756, checked in by Don-vip, 10 years ago

fix #9590 - replace org.json with GPL-compliant jsonp + remove mention of old world image removed in r1680

File size: 8.7 KB
Line 
1/*
2 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
3 *
4 * Copyright (c) 2012-2013 Oracle and/or its affiliates. All rights reserved.
5 *
6 * The contents of this file are subject to the terms of either the GNU
7 * General Public License Version 2 only ("GPL") or the Common Development
8 * and Distribution License("CDDL") (collectively, the "License"). You
9 * may not use this file except in compliance with the License. You can
10 * obtain a copy of the License at
11 * https://glassfish.dev.java.net/public/CDDL+GPL_1_1.html
12 * or packager/legal/LICENSE.txt. See the License for the specific
13 * language governing permissions and limitations under the License.
14 *
15 * When distributing the software, include this License Header Notice in each
16 * file and include the License file at packager/legal/LICENSE.txt.
17 *
18 * GPL Classpath Exception:
19 * Oracle designates this particular file as subject to the "Classpath"
20 * exception as provided by Oracle in the GPL Version 2 section of the License
21 * file that accompanied this code.
22 *
23 * Modifications:
24 * If applicable, add the following below the License Header, with the fields
25 * enclosed by brackets [] replaced by your own identifying information:
26 * "Portions Copyright [year] [name of copyright owner]"
27 *
28 * Contributor(s):
29 * If you wish your version of this file to be governed by only the CDDL or
30 * only the GPL Version 2, indicate your decision by adding "[Contributor]
31 * elects to include this software in this distribution under the [CDDL or GPL
32 * Version 2] license." If you don't indicate a single choice of license, a
33 * recipient has the option to distribute your version of this file under
34 * either the CDDL, the GPL Version 2 or to extend the choice of license to
35 * its licensees as provided above. However, if you add GPL Version 2 code
36 * and therefore, elected the GPL Version 2 license, then the option applies
37 * only if the new code is made subject to such option by the copyright
38 * holder.
39 */
40
41package org.glassfish.json;
42
43import javax.json.*;
44import javax.json.stream.JsonLocation;
45import javax.json.stream.JsonParser;
46import java.math.BigDecimal;
47import java.util.*;
48
49/**
50 * {@link JsonParser} implementation on top of JsonArray/JsonObject
51 *
52 * @author Jitendra Kotamraju
53 */
54class JsonStructureParser implements JsonParser {
55
56 private Scope current;
57 private Event state;
58 private final Deque<Scope> scopeStack = new ArrayDeque<Scope>();
59
60 JsonStructureParser(JsonArray array) {
61 current = new ArrayScope(array);
62 }
63
64 JsonStructureParser(JsonObject object) {
65 current = new ObjectScope(object);
66 }
67
68 @Override
69 public String getString() {
70 if (state == Event.KEY_NAME) {
71 return ((ObjectScope)current).key;
72 } else if (state == Event.VALUE_STRING) {
73 return ((JsonString)current.getJsonValue()).getString();
74 }
75 throw new IllegalStateException(JsonMessages.PARSER_GETSTRING_ERR(state));
76 }
77
78 @Override
79 public boolean isIntegralNumber() {
80 if (state == Event.VALUE_NUMBER) {
81 return ((JsonNumber)current.getJsonValue()).isIntegral();
82 }
83 throw new IllegalStateException(JsonMessages.PARSER_ISINTEGRALNUMBER_ERR(state));
84 }
85
86 @Override
87 public int getInt() {
88 if (state == Event.VALUE_NUMBER) {
89 return ((JsonNumber)current.getJsonValue()).intValue();
90 }
91 throw new IllegalStateException(JsonMessages.PARSER_GETINT_ERR(state));
92 }
93
94 @Override
95 public long getLong() {
96 if (state == Event.VALUE_NUMBER) {
97 return ((JsonNumber)current.getJsonValue()).longValue();
98 }
99 throw new IllegalStateException(JsonMessages.PARSER_GETLONG_ERR(state));
100 }
101
102 @Override
103 public BigDecimal getBigDecimal() {
104 if (state == Event.VALUE_NUMBER) {
105 return ((JsonNumber)current.getJsonValue()).bigDecimalValue();
106 }
107 throw new IllegalStateException(JsonMessages.PARSER_GETBIGDECIMAL_ERR(state));
108 }
109
110 @Override
111 public JsonLocation getLocation() {
112 return JsonLocationImpl.UNKNOWN;
113 }
114
115 @Override
116 public boolean hasNext() {
117 return !((state == Event.END_OBJECT || state == Event.END_ARRAY) && scopeStack.isEmpty());
118 }
119
120 @Override
121 public Event next() {
122 if (!hasNext()) {
123 throw new NoSuchElementException();
124 }
125 transition();
126 return state;
127 }
128
129 private void transition() {
130 if (state == null) {
131 state = current instanceof ArrayScope ? Event.START_ARRAY : Event.START_OBJECT;
132 } else {
133 if (state == Event.END_OBJECT || state == Event.END_ARRAY) {
134 current = scopeStack.pop();
135 }
136 if (current instanceof ArrayScope) {
137 if (current.hasNext()) {
138 current.next();
139 state = getState(current.getJsonValue());
140 if (state == Event.START_ARRAY || state == Event.START_OBJECT) {
141 scopeStack.push(current);
142 current = Scope.createScope(current.getJsonValue());
143 }
144 } else {
145 state = Event.END_ARRAY;
146 }
147 } else {
148 // ObjectScope
149 if (state == Event.KEY_NAME) {
150 state = getState(current.getJsonValue());
151 if (state == Event.START_ARRAY || state == Event.START_OBJECT) {
152 scopeStack.push(current);
153 current = Scope.createScope(current.getJsonValue());
154 }
155 } else {
156 if (current.hasNext()) {
157 current.next();
158 state = Event.KEY_NAME;
159 } else {
160 state = Event.END_OBJECT;
161 }
162 }
163 }
164 }
165 }
166
167 @Override
168 public void close() {
169 // no-op
170 }
171
172 private static Event getState(JsonValue value) {
173 switch (value.getValueType()) {
174 case ARRAY:
175 return Event.START_ARRAY;
176 case OBJECT:
177 return Event.START_OBJECT;
178 case STRING:
179 return Event.VALUE_STRING;
180 case NUMBER:
181 return Event.VALUE_NUMBER;
182 case TRUE:
183 return Event.VALUE_TRUE;
184 case FALSE:
185 return Event.VALUE_FALSE;
186 case NULL:
187 return Event.VALUE_NULL;
188 default:
189 throw new JsonException("Unknown value type="+value.getValueType());
190 }
191 }
192
193 private static abstract class Scope implements Iterator {
194 abstract JsonValue getJsonValue();
195
196 static Scope createScope(JsonValue value) {
197 if (value instanceof JsonArray) {
198 return new ArrayScope((JsonArray)value);
199 } else if (value instanceof JsonObject) {
200 return new ObjectScope((JsonObject)value);
201 }
202 throw new JsonException("Cannot be called for value="+value);
203 }
204 }
205
206 private static class ArrayScope extends Scope {
207 private final Iterator<JsonValue> it;
208 private JsonValue value;
209
210 ArrayScope(JsonArray array) {
211 this.it = array.iterator();
212 }
213
214 @Override
215 public boolean hasNext() {
216 return it.hasNext();
217 }
218
219 @Override
220 public JsonValue next() {
221 value = it.next();
222 return value;
223 }
224
225 @Override
226 public void remove() {
227 throw new UnsupportedOperationException();
228 }
229
230 @Override
231 JsonValue getJsonValue() {
232 return value;
233 }
234
235 }
236
237 private static class ObjectScope extends Scope {
238 private final Iterator<Map.Entry<String, JsonValue>> it;
239 private JsonValue value;
240 private String key;
241
242 ObjectScope(JsonObject object) {
243 this.it = object.entrySet().iterator();
244 }
245
246 @Override
247 public boolean hasNext() {
248 return it.hasNext();
249 }
250
251 @Override
252 public Map.Entry<String, JsonValue> next() {
253 Map.Entry<String, JsonValue> next = it.next();
254 this.key = next.getKey();
255 this.value = next.getValue();
256 return next;
257 }
258
259 @Override
260 public void remove() {
261 throw new UnsupportedOperationException();
262 }
263
264 @Override
265 JsonValue getJsonValue() {
266 return value;
267 }
268
269 }
270
271}
Note: See TracBrowser for help on using the repository browser.