Statistics
| Revision:

gvsig-projects-pool / org.gvsig.vcsgis / trunk / org.gvsig.vcsgis / org.gvsig.vcsgis.lib / org.gvsig.vcsgis.lib.impl / src / main / java / org / gvsig / vcsgis / lib / SAJParserImpl.java @ 2715

History | View | Annotate | Download (14.5 KB)

1
/*
2
 * gvSIG. Desktop Geographic Information System.
3
 * 
4
 * Copyright (C) 2007-2020 gvSIG Association.
5
 * 
6
 * This program is free software; you can redistribute it and/or
7
 * modify it under the terms of the GNU General Public License
8
 * as published by the Free Software Foundation; either version 3
9
 * of the License, or (at your option) any later version.
10
 * 
11
 * This program is distributed in the hope that it will be useful,
12
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14
 * GNU General Public License for more details.
15
 * 
16
 * You should have received a copy of the GNU General Public License 
17
 * along with this program. If not, see <https://www.gnu.org/licenses/>. 
18
 * 
19
 * For any additional information, do not hesitate to contact us
20
 * at info AT gvsig.com, or visit our website www.gvsig.com.
21
 */
22

    
23
package org.gvsig.vcsgis.lib;
24

    
25
import java.io.InputStream;
26
import java.io.Reader;
27
import java.util.ArrayList;
28
import java.util.List;
29
import javax.json.JsonArrayBuilder;
30
import javax.json.JsonException;
31
import javax.json.JsonObjectBuilder;
32
import javax.json.JsonValue;
33
import javax.json.stream.JsonParser;
34

    
35
/**
36
 *
37
 * @author gvSIG Team
38
 */
39
public class SAJParserImpl {
40

    
41
    public interface SAJParserContext {
42
        public JsonObjectBuilder getObjectBuilder();
43
        public JsonArrayBuilder getArrayBuilder();
44
        public String getName();
45
        public String getAttrName();
46
        public Long getIndex();
47
        public String getPathName();
48
        public void setArrayBuilder(JsonArrayBuilder arrayBuilder);
49
    }
50
    
51
    public interface SAJParserHandler {
52
        public void handle(SAJParserContext context, JsonParser.Event e, Object value);
53
    }
54

    
55
    private class SAJParserContextImpl implements SAJParserContext {
56
    
57
        private JsonObjectBuilder objectBuilder;
58
        private JsonArrayBuilder arrayBuilder;
59
        private String name;
60
        private Long index;
61
        private String attrname;
62
        private int stackIndex;
63
        private String pathName;
64

    
65
        public SAJParserContextImpl() {
66
            
67
        }
68

    
69
        @Override
70
        public JsonArrayBuilder getArrayBuilder() {
71
            return arrayBuilder;
72
        }
73

    
74
        @Override
75
        public void setArrayBuilder(JsonArrayBuilder arrayBuilder) {
76
            this.arrayBuilder = arrayBuilder;
77
        }
78
        
79
        @Override
80
        public String getName() {
81
            return name;
82
        }
83
        
84
        @Override
85
        public String getAttrName() {
86
            return attrname;
87
        }
88

    
89
        @Override
90
        public JsonObjectBuilder getObjectBuilder() {
91
            return objectBuilder;
92
        }
93

    
94
        @Override
95
        public Long getIndex() {
96
            return index;
97
        }
98
        
99
        @Override
100
        public String getPathName() {
101
            if( this.pathName==null ) {
102
                StringBuilder builder = new StringBuilder();
103
                for (int i = 0; i <= this.stackIndex; i++) {
104
                    if( getContext(i).name != null ) {
105
                        builder.append("/");
106
                        builder.append(getContext(i).name);
107
                    } else if( getContext(i).index != null ) {
108
                        builder.append("/?");
109
//                        builder.append(getContext(i).index);
110
                    } else if( i!=0 ) {
111
                        builder.append("/?");
112
                    }
113
                }
114
                this.pathName = builder.toString();
115
            }
116
            return this.pathName;
117
        }
118
    }
119
    
120
    private final JsonParser parser;
121
    private final SAJParserHandler handler;
122
    private final List<SAJParserContextImpl> contextsStack;
123
    
124
    public SAJParserImpl(InputStream is, SAJParserHandler handler) {
125
        this(javax.json.Json.createParser(is), handler);
126
    }
127
    
128
    public SAJParserImpl(Reader reader, SAJParserHandler handler) {
129
        this(javax.json.Json.createParser(reader), handler);
130
    }
131
    
132
    public SAJParserImpl(JsonParser parser, SAJParserHandler handler) {
133
        this.parser = parser;
134
        this.handler = handler;
135
        this.contextsStack = new ArrayList(10);
136
        
137
    }
138

    
139
    private SAJParserContextImpl getContext(int index) {
140
        return this.contextsStack.get(index);
141
    }
142
    
143
    public JsonParser getParser() {
144
        return parser;
145
    }
146

    
147
    public void close() {
148
        this.parser.close();
149
    }
150
    
151
    private JsonObjectBuilder createObjectBuilder() {
152
        return javax.json.Json.createObjectBuilder();
153
    }
154
    
155
    private JsonArrayBuilder createArrayBuilder() {
156
        return javax.json.Json.createArrayBuilder();
157
    }
158
    
159
    private SAJParserContextImpl createContext(JsonObjectBuilder objectBuilder, String name) {
160
        return createContext(objectBuilder, null, name, null);
161
    }
162
        
163
    private SAJParserContextImpl createContext(JsonArrayBuilder arrayBuilder, String name) {
164
        return createContext(null, arrayBuilder, name, null);
165
    }
166
        
167
    private SAJParserContextImpl createContext(JsonArrayBuilder arrayBuilder,  long index) {    
168
        return createContext(null, arrayBuilder, null, index);
169
    }
170
    
171
    private SAJParserContextImpl createContext(JsonObjectBuilder objectBuilder,  long index) {    
172
        return createContext(objectBuilder, null, null, index);
173
    }
174
    
175
    private SAJParserContextImpl createContext(JsonArrayBuilder arrayBuilder) {    
176
        return createContext(null, arrayBuilder, null, null);
177
    }
178
    
179
    private SAJParserContextImpl createContext(JsonObjectBuilder objectBuilder) {    
180
        return createContext(objectBuilder, null, null, null);
181
    }
182
    
183
    private SAJParserContextImpl createContext(JsonObjectBuilder objectBuilder, JsonArrayBuilder arrayBuilder,  String name, Long index) {
184
        SAJParserContextImpl context = new SAJParserContextImpl();
185
        context.arrayBuilder = arrayBuilder;
186
        context.objectBuilder = objectBuilder;
187
        context.name = name;
188
        context.index = index;                
189
        this.contextsStack.add(context);
190
        context.stackIndex = this.contextsStack.size()-1;
191
        return context;
192
    }
193
    
194
    private void deleteContext(SAJParserContextImpl context) {
195
        this.contextsStack.remove(context.stackIndex);
196
        if( context.stackIndex!=this.contextsStack.size() ) {
197
            for (int i = 0; i < contextsStack.size(); i++) {
198
                contextsStack.get(i).stackIndex = i;
199
                contextsStack.get(i).pathName = null;
200
            }
201
        }
202
    }
203
    
204
    public void parse() {
205
        if (parser.hasNext()) {
206
            JsonParser.Event e = parser.next();
207
            if (e == JsonParser.Event.START_ARRAY) {
208
                SAJParserContextImpl context = createContext(createArrayBuilder());
209
                this.handler.handle(context, e, null);
210
                this.readArray(context);
211
                deleteContext(context);
212
            } else if (e == JsonParser.Event.START_OBJECT) {
213
                SAJParserContextImpl context = createContext(createObjectBuilder());
214
                this.handler.handle(context, e, null);
215
                this.readObject(context);
216
                deleteContext(context);
217
            }
218
        }
219
    }
220

    
221
    private void readArray(SAJParserContextImpl context) {
222
        SAJParserContextImpl context2;
223
        context.index = 0L;
224
        while(parser.hasNext()) {
225
            JsonParser.Event e = parser.next();
226
            switch (e) {
227
                case START_ARRAY:
228
                    context2 = createContext(createArrayBuilder(), context.index);
229
                    this.handler.handle(context2, e, context2.arrayBuilder);
230
                    this.readArray(context2);
231
                    if( context.arrayBuilder!=null ) {
232
                        if( context2.arrayBuilder==null ) {
233
                            context.arrayBuilder.addNull();
234
                        } else {
235
                            context.arrayBuilder.add(context2.arrayBuilder);
236
                        }
237
                    }
238
                    deleteContext(context2);
239
                    break;
240
                case START_OBJECT:
241
                    context2 = createContext(createObjectBuilder(), context.index);
242
                    this.handler.handle(context2, e, context2.objectBuilder);
243
                    this.readObject(context2);
244
                    if( context.arrayBuilder!=null ) {
245
                        if( context2.objectBuilder==null ) {
246
                            context.arrayBuilder.addNull();
247
                        } else {
248
                            context.arrayBuilder.add(context2.objectBuilder);
249
                        }
250
                    }
251
                    deleteContext(context2);
252
                    break;
253
                case VALUE_STRING:
254
                    this.handler.handle(context, e, parser.getString());
255
                    if( context.arrayBuilder!=null ) {
256
                        context.arrayBuilder.add(parser.getString());
257
                    }
258
                    break;
259
                case VALUE_NUMBER:
260
                    if (parser.isIntegralNumber()) { // FIXME: BigInteger are truncateds
261
                        this.handler.handle(context, e, parser.getInt());
262
                        if( context.arrayBuilder!=null ) {
263
                            context.arrayBuilder.add(parser.getInt());
264
                        }
265
                    } else {
266
                        this.handler.handle(context, e, parser.getBigDecimal());
267
                        if( context.arrayBuilder!=null ) {
268
                            context.arrayBuilder.add(parser.getBigDecimal());
269
                        }
270
                    }
271
                    break;
272
                case VALUE_TRUE:
273
                    this.handler.handle(context, e, true);
274
                    if( context.arrayBuilder!=null ) {
275
                        context.arrayBuilder.add(JsonValue.TRUE);
276
                    }
277
                    break;
278
                case VALUE_FALSE:
279
                    this.handler.handle(context, e, false);
280
                    if( context.arrayBuilder!=null ) {
281
                        context.arrayBuilder.add(JsonValue.FALSE);
282
                    }
283
                    break;
284
                case VALUE_NULL:
285
                    this.handler.handle(context, e, null);
286
                    if( context.arrayBuilder!=null ) {
287
                        context.arrayBuilder.add(JsonValue.NULL);
288
                    }
289
                    break;
290
                case END_ARRAY:
291
                    this.handler.handle(context, e, context.arrayBuilder);
292
                    return;
293
                default:
294
                    throw new JsonException("Internal Error");
295
            }
296
            context.index += 1L;
297
        }
298
        throw new JsonException("Internal Error");
299
    }
300
    
301
    private void readObject(SAJParserContextImpl context) {
302
        SAJParserContextImpl context2;
303
        while(parser.hasNext()) {
304
            JsonParser.Event e = parser .next();
305
            switch (e) {
306
                case START_ARRAY:
307
                    context2 = createContext(createArrayBuilder(), context.attrname);
308
                    this.handler.handle(context2, e, context2.arrayBuilder);
309
                    this.readArray(context2);
310
                    if( context.objectBuilder!=null ) {
311
                        if( context2.arrayBuilder==null ) {
312
                            context.objectBuilder.addNull(context.attrname);
313
                        } else {
314
                            context.objectBuilder.add(context.attrname, context2.arrayBuilder);
315
                        }
316
                    }
317
                    deleteContext(context2);
318
                    break;
319
                case START_OBJECT:
320
                    context2 = createContext(createObjectBuilder(), context.attrname);
321
                    this.handler.handle(context2, e, context2.objectBuilder);
322
                    this.readObject(context2);
323
                    if( context.objectBuilder!=null ) {
324
                        if( context2.objectBuilder==null ) {
325
                            context.objectBuilder.addNull(context.attrname);
326
                        } else {
327
                            context.objectBuilder.add(context.attrname, context2.objectBuilder);
328
                        }
329
                    }
330
                    deleteContext(context2);
331
                    break;
332
                case KEY_NAME:
333
                    context.attrname = parser.getString();
334
                    break;
335
                case VALUE_STRING:
336
                    this.handler.handle(context, e, parser.getString());
337
                    if( context.objectBuilder!=null ) {
338
                        context.objectBuilder.add(context.attrname, parser.getString());
339
                    }
340
                    break;
341
                case VALUE_NUMBER:
342
                    if (parser.isIntegralNumber()) { // FIXME: BigInteger are truncateds
343
                        this.handler.handle(context, e, parser.getInt());
344
                        if( context.objectBuilder!=null ) {
345
                            context.objectBuilder.add(context.attrname, parser.getInt());
346
                        }
347
                    } else {
348
                        this.handler.handle(context, e, parser.getBigDecimal());
349
                        if( context.objectBuilder!=null ) {
350
                            context.objectBuilder.add(context.attrname, parser.getBigDecimal());
351
                        }
352
                    }
353
                    break;
354
                case VALUE_TRUE:
355
                    this.handler.handle(context, e, true);
356
                    if( context.objectBuilder!=null ) {
357
                        context.objectBuilder.add(context.attrname, JsonValue.TRUE);
358
                    }
359
                    break;
360
                case VALUE_FALSE:
361
                    this.handler.handle(context, e, false);
362
                    if( context.objectBuilder!=null ) {
363
                        context.objectBuilder.add(context.attrname, JsonValue.FALSE);
364
                    }
365
                    break;
366
                case VALUE_NULL:
367
                    this.handler.handle(context, e, null);
368
                    if( context.objectBuilder!=null ) {
369
                        context.objectBuilder.addNull(context.attrname);
370
                    }
371
                    break;
372
                case END_OBJECT:
373
                    context.attrname = null;
374
                    this.handler.handle(context, e, context.objectBuilder);
375
                    return;
376
                default:
377
                    throw new JsonException("Internal Error");
378
            }
379
        }
380
        throw new JsonException("Internal Error");
381
    }
382
    
383
}