1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package com.bea.xml.stream;
17
18 import javax.xml.namespace.QName;
19 import javax.xml.stream.events.XMLEvent;
20 import javax.xml.stream.XMLStreamException;
21 import javax.xml.stream.events.Attribute;
22 import javax.xml.stream.events.Namespace;
23 import com.bea.xml.stream.util.ElementTypeNames;
24 import com.bea.xml.stream.AttributeBase;
25 import com.bea.xml.stream.NamespaceBase;
26
27 import java.io.Reader;
28 import java.io.IOException;
29 import java.util.HashMap;
30 import java.util.Map;
31 import java.util.List;
32 import java.util.ArrayList;
33 import java.util.Iterator;
34 import java.io.FileReader;
35
36 /***
37 * <p> This class replays events from a simple non-xml file format </p>
38 *
39 */
40
41
42 public class EventScanner {
43 protected Reader reader;
44 protected char currentChar;
45 protected int currentLine=0;
46 private boolean readEndDocument = false;
47 public EventScanner(){}
48 public EventScanner(Reader reader)
49 throws IOException
50 {
51 setReader(reader);
52 }
53 public void setReader(Reader reader)
54 throws IOException
55 {
56 this.reader = reader;
57 read();
58 skipSpace();
59 }
60
61 protected String readString(char delim)
62 throws IOException, XMLStreamException
63 {
64 StringBuffer buf = new StringBuffer();
65 while(getChar()!=delim) {
66 if (getChar() == '[' && delim ==']') {
67 read();
68 buf.append('[');
69 if (getChar() != ']')
70 buf.append(readString(']'));
71 buf.append(']');
72 read(']');
73 } else {
74 buf.append(getChar());
75 read();
76 }
77 }
78 return buf.toString();
79
80 }
81 protected char getChar() {
82 return currentChar;
83 }
84 protected void skipSpace()
85 throws IOException
86 {
87 while (currentChar == ' ' | currentChar == '\n' | currentChar == '\t' | currentChar =='\r')
88 read();
89 }
90 protected char read()
91 throws IOException
92 {
93 currentChar = (char) reader.read();
94 if (currentChar == '\n') currentLine++;
95 return currentChar;
96 }
97 protected char read(char c)
98 throws XMLStreamException, IOException
99 {
100 if (currentChar == c) return read();
101 else
102 throw new XMLStreamException("Unexpected character '"+currentChar+"' , expected '"+c+"' at line "+currentLine);
103 }
104 protected void read(String s)
105 throws XMLStreamException, IOException
106 {
107 for (int i=0; i < s.length(); i++)
108 read(s.charAt(i));
109 }
110 protected int readType()
111 throws XMLStreamException, IOException
112 {
113
114 read('[');
115 String typeName = readString(']');
116 int type= ElementTypeNames.getEventType(typeName);
117 read(']');
118 return type;
119 }
120 public EventState readStartElement()
121 throws XMLStreamException, IOException
122 {
123 EventState state = new EventState(XMLEvent.START_ELEMENT);
124 read('[');
125 state.setName(readName());
126 if (getChar()=='[') {
127 List atts = readAttributes();
128 Iterator i = atts.iterator();
129 while(i.hasNext()) {
130 Object obj = i.next();
131 if (obj instanceof Namespace)
132 state.addNamespace(obj);
133 else
134 state.addAttribute(obj);
135 }
136
137 }
138 read(']');
139 return state;
140 }
141 public EventState readEndElement()
142 throws XMLStreamException, IOException
143 {
144 EventState state =
145 new EventState(XMLEvent.END_ELEMENT);
146 read('[');
147 state.setName(readName());
148 read(']');
149 return state;
150 }
151
152 public EventState readProcessingInstruction()
153 throws XMLStreamException, IOException
154 {
155 EventState state =
156 new EventState(XMLEvent.PROCESSING_INSTRUCTION);
157 read('[');
158 String name = readString(']');
159 read(']');
160 String s = null;
161 if (getChar() == ',') {
162 read(",[");
163 s = readString(']');
164 read(']');
165 }
166 state.setData(name);
167 state.setExtraData(s);
168 return state;
169 }
170 public EventState readCharacterData()
171 throws XMLStreamException, IOException
172 {
173 EventState state =
174 new EventState(XMLEvent.CHARACTERS);
175 read('[');
176 state.setData(readString(']'));
177 read(']');
178 return state;
179 }
180 public EventState readCDATA()
181 throws XMLStreamException, IOException
182 {
183 EventState state =
184 new EventState(XMLEvent.CDATA);
185 read('[');
186 readString(']');
187 read(']');
188 return state;
189 }
190
191
192 public EventState readStartDocument()
193 throws XMLStreamException, IOException
194 {
195 EventState state =
196 new EventState(XMLEvent.START_DOCUMENT);
197 if (getChar() != ';') {
198 read('[');
199 read('[');
200 String version = readString(']');
201 read(']');
202 read(',');
203 read('[');
204 String encoding = readString(']');
205 read(']');
206 read(']');
207 state.setData(version);
208 state.setExtraData(encoding);
209 }
210 return state;
211 }
212
213
214 public EventState readDTD()
215 throws XMLStreamException, IOException
216 {
217 EventState state =
218 new EventState(XMLEvent.DTD);
219 read('[');
220 String dtd = readString(']');
221 read(']');
222 state.setData(dtd);
223 return state;
224 }
225 public EventState readEndDocument()
226 throws XMLStreamException
227 {
228 EventState state =
229 new EventState(XMLEvent.END_DOCUMENT);
230 return state;
231 }
232 public EventState readComment()
233 throws XMLStreamException, IOException
234 {
235 EventState state =
236 new EventState(XMLEvent.COMMENT);
237 read('[');
238 state.setData(readString(']'));
239 read(']');
240 return state;
241 }
242 public String getPrefix(String name) {
243 int index = name.indexOf(':');
244 if (index == -1) return null;
245 return name.substring(0,index);
246 }
247 public String getName(String name) {
248 int index = name.indexOf(':');
249 if (index == -1) return name;
250 return name.substring(index+1);
251 }
252 public QName readName()
253 throws XMLStreamException, IOException
254 {
255 read('[');
256 QName n = readName(']');
257 read(']');
258 return n;
259 }
260
261 public QName readName(char delim)
262 throws XMLStreamException, IOException
263 {
264 String uri = "";
265 String prefix = "";
266 if (getChar() == '\'') {
267 read('\'');
268 uri=readString('\'');
269 read('\'');
270 read(':');
271 }
272 String name = readString(delim);
273 prefix=getPrefix(name);
274 if (prefix == null) prefix = "";
275 String localName = getName(name);
276 return new QName(uri,localName,prefix);
277 }
278
279 public List readAttributes()
280 throws XMLStreamException, IOException
281 {
282 List attributes = new ArrayList();
283 while(getChar() == '[') {
284 attributes.add(readAttribute());
285 }
286 return attributes;
287 }
288
289 public Attribute readAttribute()
290 throws XMLStreamException, IOException
291 {
292 read('[');
293 read('[');
294 String type=readString(']');
295 read(']');
296 QName n = readName();
297 read("=[");
298 String value=readString(']');
299 read(']');
300 read(']');
301 if (type.equals("ATTRIBUTE"))
302 return new AttributeBase(n,value);
303 if (type.equals("DEFAULT"))
304 return new NamespaceBase(value);
305 if (type.equals("NAMESPACE"))
306 return (new NamespaceBase(n.getLocalPart(),
307 value));
308 throw new XMLStreamException("Parser Error expected (ATTRIBUTE|"+
309 "|DEFAULT|NAMESPACE");
310 }
311
312 public EventState readEntityReference ()
313 throws XMLStreamException, IOException
314 {
315 EventState state =
316 new EventState(XMLEvent.ENTITY_REFERENCE);
317 read('[');
318 state.setData(readString(']'));
319 read(']');
320 return state;
321 }
322 public EventState readSpace()
323 throws XMLStreamException, IOException
324 {
325 EventState state =
326 new EventState(XMLEvent.SPACE);
327 read('[');
328 String content = readString(']');
329 read(']');
330 state.setData(content);
331 return state;
332 }
333
334 public EventState readElement()
335 throws XMLStreamException, IOException
336 {
337 int type = readType();
338 EventState state;
339 switch(type) {
340 case XMLEvent.START_ELEMENT:
341 state=readStartElement();break;
342 case XMLEvent.END_ELEMENT:
343 state=readEndElement();break;
344 case XMLEvent.PROCESSING_INSTRUCTION:
345 state=readProcessingInstruction();break;
346 case XMLEvent.CHARACTERS:
347 state=readCharacterData();break;
348 case XMLEvent.COMMENT:
349 state=readComment();break;
350 case XMLEvent.START_DOCUMENT:
351 state=readStartDocument();break;
352 case XMLEvent.END_DOCUMENT:
353 readEndDocument = true;
354 state=readEndDocument();break;
355 case XMLEvent.ENTITY_REFERENCE:
356 state=readEntityReference() ;break;
357 case XMLEvent.SPACE:
358 state=readSpace();break;
359 case XMLEvent.DTD:
360 state=readDTD();break;
361 case XMLEvent.CDATA:
362 state=readCDATA();break;
363 default:
364 throw new XMLStreamException("Attempt to read unknown element ["+type+"]");
365 }
366 read(';');
367 skipSpace();
368 return state;
369 }
370
371 public boolean endDocumentIsPresent() {
372 return readEndDocument;
373 }
374
375 public boolean hasNext() throws IOException
376 {
377 return (reader.ready() && !readEndDocument);
378 }
379
380 public static void main(String args[])
381 throws Exception
382 {
383 EventScanner reader = new EventScanner(new FileReader(args[0]));
384 while(reader.hasNext())
385 System.out.println(reader.readElement());
386
387 }
388 }
389