View Javadoc

1   /*   Copyright 2004 BEA Systems, Inc.
2    *
3    *   Licensed under the Apache License, Version 2.0 (the "License");
4    *   you may not use this file except in compliance with the License.
5    *   You may obtain a copy of the License at
6    *
7    *       http://www.apache.org/licenses/LICENSE-2.0
8    *
9    *   Unless required by applicable law or agreed to in writing, software
10   *   distributed under the License is distributed on an "AS IS" BASIS,
11   *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12   *   See the License for the specific language governing permissions and
13   *   limitations under the License.
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