OSDN Git Service

imported from subversion repository
[xerial/xerial-core.git] / src / main / java / org / xerial / json / JSONStreamReader.java
1 /*--------------------------------------------------------------------------\r
2  *  Copyright 2009 Taro L. Saito\r
3  *\r
4  *  Licensed under the Apache License, Version 2.0 (the "License");\r
5  *  you may not use this file except in compliance with the License.\r
6  *  You may obtain a copy of the License at\r
7  *\r
8  *     http://www.apache.org/licenses/LICENSE-2.0\r
9  *\r
10  *  Unless required by applicable law or agreed to in writing, software\r
11  *  distributed under the License is distributed on an "AS IS" BASIS,\r
12  *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
13  *  See the License for the specific language governing permissions and\r
14  *  limitations under the License.\r
15  *--------------------------------------------------------------------------*/\r
16 //--------------------------------------\r
17 // XerialJ\r
18 //\r
19 // JSONStreamReader.java\r
20 // Since: Mar 31, 2009 2:06:34 PM\r
21 //\r
22 // $URL: http://www.xerial.org/svn/project/XerialJ/trunk/xerial-core/src/main/java/org/xerial/json/JSONStreamReader.java $\r
23 // $Author: leo $\r
24 //--------------------------------------\r
25 package org.xerial.json;\r
26 \r
27 import java.io.IOException;\r
28 import java.io.Reader;\r
29 \r
30 import org.xerial.core.XerialException;\r
31 import org.xerial.util.ArrayDeque;\r
32 import org.xerial.util.log.Logger;\r
33 import org.xerial.util.tree.TreeEvent;\r
34 import org.xerial.util.tree.TreeStreamReader;\r
35 import org.xerial.util.tree.TreeEvent.EventType;\r
36 import org.xerial.util.xml.impl.TreeEventQueue;\r
37 \r
38 /**\r
39  * JSON stream reader\r
40  * \r
41  * @author leo\r
42  * \r
43  */\r
44 public class JSONStreamReader implements TreeStreamReader\r
45 {\r
46     private static Logger _logger = Logger.getLogger(JSONStreamReader.class);\r
47 \r
48     private final JSONPullParser jsonPullParser;\r
49     private final TreeEventQueue eventQueue = new TreeEventQueue();\r
50     private JSONEvent lastEvent = null;\r
51 \r
52     private ArrayDeque<TreeEvent> pendingEventQueue = new ArrayDeque<TreeEvent>();\r
53 \r
54     public JSONStreamReader(Reader jsonStream) throws IOException\r
55     {\r
56         jsonPullParser = new JSONPullParser(jsonStream);\r
57     }\r
58 \r
59     public TreeEvent peekNext() throws XerialException\r
60     {\r
61         if (!eventQueue.isEmpty())\r
62         {\r
63             return eventQueue.peekFirst();\r
64         }\r
65 \r
66         if (lastEvent == JSONEvent.EndJSON)\r
67             return null;\r
68 \r
69         readNext();\r
70 \r
71         return peekNext();\r
72     }\r
73 \r
74     public TreeEvent next() throws XerialException\r
75     {\r
76         if (!eventQueue.isEmpty())\r
77         {\r
78             TreeEvent e = eventQueue.pop();\r
79             return e;\r
80         }\r
81 \r
82         if (lastEvent == JSONEvent.EndJSON)\r
83             return null;\r
84 \r
85         readNext();\r
86 \r
87         return next();\r
88 \r
89     }\r
90 \r
91     private void flushPendingEvent()\r
92     {\r
93         while (!pendingEventQueue.isEmpty())\r
94             eventQueue.push(pendingEventQueue.removeFirst());\r
95 \r
96     }\r
97 \r
98     private void readNext() throws XerialException\r
99     {\r
100         if (lastEvent == JSONEvent.EndJSON)\r
101             return;\r
102 \r
103         lastEvent = jsonPullParser.next();\r
104         switch (lastEvent)\r
105         {\r
106         case StartObject:\r
107         {\r
108             flushPendingEvent();\r
109 \r
110             String key = jsonPullParser.getKeyName();\r
111             pendingEventQueue.addLast(TreeEvent.newVisitEvent(key, null));\r
112             break;\r
113         }\r
114         case EndObject:\r
115         {\r
116             flushPendingEvent();\r
117             String key = jsonPullParser.getKeyName();\r
118             eventQueue.push(TreeEvent.newLeaveEvent(key));\r
119             break;\r
120         }\r
121         case String:\r
122         case Integer:\r
123         case Double:\r
124         case Boolean:\r
125         case Null:\r
126         {\r
127             String key = jsonPullParser.getKeyName();\r
128             String value = lastEvent != JSONEvent.Null ? jsonPullParser.getText() : null;\r
129 \r
130             // if first child element is value attribute\r
131             if (key != null)\r
132             {\r
133                 if (key.equals("value") && !pendingEventQueue.isEmpty())\r
134                 {\r
135                     TreeEvent e = pendingEventQueue.peekLast();\r
136                     if (e.event == EventType.VISIT)\r
137                     {\r
138                         pendingEventQueue.removeLast();\r
139                         pendingEventQueue.addLast(TreeEvent.newVisitEvent(e.nodeName, value));\r
140                         break;\r
141                     }\r
142                 }\r
143             }\r
144 \r
145             flushPendingEvent();\r
146             eventQueue.push(TreeEvent.newVisitEvent(key, value));\r
147             eventQueue.push(TreeEvent.newLeaveEvent(key));\r
148             break;\r
149         }\r
150         case StartArray:\r
151         case EndArray:\r
152         case EndJSON:\r
153             // do nothing\r
154             break;\r
155         }\r
156 \r
157     }\r
158 \r
159 }\r