KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > xmlpull > v1 > sax2 > Driver


1 /* -*- mode: Java; c-basic-offset: 4; indent-tabs-mode: nil; -*- //------100-columns-wide------>|*/
2
3 package org.xmlpull.v1.sax2;
4
5 import java.io.InputStream JavaDoc;
6 import java.io.InputStreamReader JavaDoc;
7 import java.io.IOException JavaDoc;
8 import java.io.Reader JavaDoc;
9
10 // not J2ME classes
11
import java.net.URL JavaDoc;
12 import java.net.MalformedURLException JavaDoc;
13
14
15 // not J2ME classes
16
import java.io.FileInputStream JavaDoc;
17 import java.io.FileNotFoundException JavaDoc;
18 import java.io.StringReader JavaDoc;
19 import java.io.StringWriter JavaDoc;
20 import java.io.UnsupportedEncodingException JavaDoc;
21
22 import org.xml.sax.Attributes JavaDoc;
23 import org.xml.sax.DTDHandler JavaDoc;
24 import org.xml.sax.ContentHandler JavaDoc;
25 import org.xml.sax.EntityResolver JavaDoc;
26 import org.xml.sax.ErrorHandler JavaDoc;
27 import org.xml.sax.InputSource JavaDoc;
28 import org.xml.sax.Locator JavaDoc;
29 import org.xml.sax.SAXException JavaDoc;
30 import org.xml.sax.SAXParseException JavaDoc;
31 import org.xml.sax.SAXNotRecognizedException JavaDoc;
32 import org.xml.sax.SAXNotSupportedException JavaDoc;
33 import org.xml.sax.XMLReader JavaDoc;
34 import org.xml.sax.helpers.DefaultHandler JavaDoc;
35
36 import org.xmlpull.v1.XmlPullParser;
37 import org.xmlpull.v1.XmlPullParserException;
38 import org.xmlpull.v1.XmlPullParserFactory;
39
40 /**
41  * SAX2 Driver that puslls events from XmlPullParser
42  * and comverts them into SAX2 callbacks.
43  *
44  * @author <a HREF="http://www.extreme.indiana.edu/~aslom/">Aleksander Slominski</a>
45  * @author <a HREF="mailto:hkrug@rationalizer.com">Holger Krug</a>
46  */

47
48 public class Driver implements Locator JavaDoc, XMLReader JavaDoc, Attributes JavaDoc
49 {
50
51     protected static final String JavaDoc DECLARATION_HANDLER_PROPERTY =
52         "http://xml.org/sax/properties/declaration-handler";
53
54     protected static final String JavaDoc LEXICAL_HANDLER_PROPERTY =
55         "http://xml.org/sax/properties/lexical-handler";
56
57     protected static final String JavaDoc NAMESPACES_FEATURE =
58         "http://xml.org/sax/features/namespaces";
59
60     protected static final String JavaDoc NAMESPACE_PREFIXES_FEATURE =
61         "http://xml.org/sax/features/namespace-prefixes";
62
63     protected static final String JavaDoc VALIDATION_FEATURE =
64         "http://xml.org/sax/features/validation";
65
66     protected static final String JavaDoc APACHE_SCHEMA_VALIDATION_FEATURE =
67         "http://apache.org/xml/features/validation/schema";
68
69     protected static final String JavaDoc APACHE_DYNAMIC_VALIDATION_FEATURE =
70         "http://apache.org/xml/features/validation/dynamic";
71
72     protected ContentHandler JavaDoc contentHandler = new DefaultHandler JavaDoc();
73     protected ErrorHandler JavaDoc errorHandler = new DefaultHandler JavaDoc();;
74
75     protected String JavaDoc systemId;
76
77     protected XmlPullParser pp;
78
79     //private final static boolean DEBUG = false;
80

81     /**
82      */

83     public Driver() throws XmlPullParserException {
84         XmlPullParserFactory factory = XmlPullParserFactory.newInstance();
85         factory.setNamespaceAware(true);
86         pp = factory.newPullParser();
87     }
88
89     public Driver(XmlPullParser pp) throws XmlPullParserException {
90         this.pp = pp;
91     }
92
93     // -- Attributes interface
94

95     public int getLength() { return pp.getAttributeCount(); }
96     public String JavaDoc getURI(int index) { return pp.getAttributeNamespace(index); }
97     public String JavaDoc getLocalName(int index) { return pp.getAttributeName(index); }
98     public String JavaDoc getQName(int index) {
99         String JavaDoc prefix = pp.getAttributePrefix(index);
100         if(prefix != null) {
101             return prefix+':'+pp.getAttributeName(index);
102         } else {
103             return pp.getAttributeName(index);
104         }
105     }
106     public String JavaDoc getType(int index) { return pp.getAttributeType(index); }
107     public String JavaDoc getValue(int index) { return pp.getAttributeValue(index); }
108
109     public int getIndex(String JavaDoc uri, String JavaDoc localName) {
110         for (int i = 0; i < pp.getAttributeCount(); i++)
111         {
112             if(pp.getAttributeNamespace(i).equals(uri)
113                && pp.getAttributeName(i).equals(localName))
114             {
115                 return i;
116             }
117
118         }
119         return -1;
120     }
121
122     public int getIndex(String JavaDoc qName) {
123         for (int i = 0; i < pp.getAttributeCount(); i++)
124         {
125             if(pp.getAttributeName(i).equals(qName))
126             {
127                 return i;
128             }
129
130         }
131         return -1;
132     }
133
134     public String JavaDoc getType(String JavaDoc uri, String JavaDoc localName) {
135         for (int i = 0; i < pp.getAttributeCount(); i++)
136         {
137             if(pp.getAttributeNamespace(i).equals(uri)
138                && pp.getAttributeName(i).equals(localName))
139             {
140                 return pp.getAttributeType(i);
141             }
142
143         }
144         return null;
145     }
146     public String JavaDoc getType(String JavaDoc qName) {
147         for (int i = 0; i < pp.getAttributeCount(); i++)
148         {
149             if(pp.getAttributeName(i).equals(qName))
150             {
151                 return pp.getAttributeType(i);
152             }
153
154         }
155         return null;
156     }
157     public String JavaDoc getValue(String JavaDoc uri, String JavaDoc localName) {
158         return pp.getAttributeValue(uri, localName);
159     }
160     public String JavaDoc getValue(String JavaDoc qName) {
161         return pp.getAttributeValue(null, qName);
162     }
163
164     // -- Locator interface
165

166     public String JavaDoc getPublicId() { return null; }
167     public String JavaDoc getSystemId() { return systemId; }
168     public int getLineNumber() { return pp.getLineNumber(); }
169     public int getColumnNumber() { return pp.getColumnNumber(); }
170
171     // --- XMLReader interface
172

173     public boolean getFeature(String JavaDoc name)
174         throws SAXNotRecognizedException JavaDoc, SAXNotSupportedException JavaDoc
175     {
176         if(NAMESPACES_FEATURE.equals(name)) {
177             return pp.getFeature(pp.FEATURE_PROCESS_NAMESPACES);
178         } else if(NAMESPACE_PREFIXES_FEATURE.equals(name)) {
179             return pp.getFeature(pp.FEATURE_REPORT_NAMESPACE_ATTRIBUTES);
180         } else if(VALIDATION_FEATURE.equals(name)) {
181             return pp.getFeature(pp.FEATURE_VALIDATION);
182             // } else if(APACHE_SCHEMA_VALIDATION_FEATURE.equals(name)) {
183
// return false; //TODO
184
// } else if(APACHE_DYNAMIC_VALIDATION_FEATURE.equals(name)) {
185
// return false; //TODO
186
} else {
187             return pp.getFeature(name);
188             //throw new SAXNotRecognizedException("unrecognized feature "+name);
189
}
190     }
191
192     public void setFeature (String JavaDoc name, boolean value)
193         throws SAXNotRecognizedException JavaDoc, SAXNotSupportedException JavaDoc
194     {
195         try {
196             if(NAMESPACES_FEATURE.equals(name)) {
197                 pp.setFeature(pp.FEATURE_PROCESS_NAMESPACES, value);
198             } else if(NAMESPACE_PREFIXES_FEATURE.equals(name)) {
199                 if(pp.getFeature(pp.FEATURE_REPORT_NAMESPACE_ATTRIBUTES) != value) {
200                     pp.setFeature(pp.FEATURE_REPORT_NAMESPACE_ATTRIBUTES, value);
201                 }
202             } else if(VALIDATION_FEATURE.equals(name)) {
203                 pp.setFeature(pp.FEATURE_VALIDATION, value);
204                 // } else if(APACHE_SCHEMA_VALIDATION_FEATURE.equals(name)) {
205
// // can ignore as validation must be false ...
206
// // if(true == value) {
207
// // throw new SAXNotSupportedException("schema validation is not supported");
208
// // }
209
// } else if(APACHE_DYNAMIC_VALIDATION_FEATURE.equals(name)) {
210
// if(true == value) {
211
// throw new SAXNotSupportedException("dynamic validation is not supported");
212
// }
213
} else {
214                 pp.setFeature(name, value);
215                 //throw new SAXNotRecognizedException("unrecognized feature "+name);
216
}
217         } catch(XmlPullParserException ex) {
218             throw new SAXNotSupportedException JavaDoc("problem with setting feature "+name+": "+ex);
219         }
220     }
221
222     public Object JavaDoc getProperty (String JavaDoc name)
223         throws SAXNotRecognizedException JavaDoc, SAXNotSupportedException JavaDoc
224     {
225         if(DECLARATION_HANDLER_PROPERTY.equals(name)) {
226             return null;
227         } else if(LEXICAL_HANDLER_PROPERTY.equals(name)) {
228             return null;
229         } else {
230             return pp.getProperty(name);
231             //throw new SAXNotRecognizedException("not recognized get property "+name);
232
}
233     }
234
235     public void setProperty (String JavaDoc name, Object JavaDoc value)
236         throws SAXNotRecognizedException JavaDoc, SAXNotSupportedException JavaDoc
237     {
238         //
239
if(DECLARATION_HANDLER_PROPERTY.equals(name)) {
240             throw new SAXNotSupportedException JavaDoc("not supported setting property "+name);//+" to "+value);
241
} else if(LEXICAL_HANDLER_PROPERTY.equals(name)) {
242             throw new SAXNotSupportedException JavaDoc("not supported setting property "+name);//+" to "+value);
243
} else {
244             try {
245                 pp.setProperty(name, value);
246             } catch(XmlPullParserException ex) {
247                 throw new SAXNotSupportedException JavaDoc("not supported set property "+name+": "+ ex);
248             }
249             //throw new SAXNotRecognizedException("not recognized set property "+name);
250
}
251     }
252
253     public void setEntityResolver (EntityResolver JavaDoc resolver) {}
254
255     public EntityResolver JavaDoc getEntityResolver () { return null; }
256
257     public void setDTDHandler (DTDHandler JavaDoc handler) {}
258
259     public DTDHandler JavaDoc getDTDHandler () { return null; }
260
261     public void setContentHandler (ContentHandler JavaDoc handler)
262     {
263         this.contentHandler = handler;
264     }
265
266     public ContentHandler JavaDoc getContentHandler() { return contentHandler; }
267
268     public void setErrorHandler(ErrorHandler JavaDoc handler) {
269         this.errorHandler = handler;
270     }
271
272     public ErrorHandler JavaDoc getErrorHandler() { return errorHandler; }
273
274     public void parse(InputSource JavaDoc source) throws SAXException JavaDoc, IOException JavaDoc
275     {
276
277         systemId = source.getSystemId();
278         contentHandler.setDocumentLocator(this);
279
280         Reader JavaDoc reader = source.getCharacterStream();
281         try {
282             if (reader == null) {
283                 InputStream JavaDoc stream = source.getByteStream();
284                 String JavaDoc encoding = source.getEncoding();
285
286                 if (stream == null) {
287                     systemId = source.getSystemId();
288                     if(systemId == null) {
289                         SAXParseException JavaDoc saxException = new SAXParseException JavaDoc(
290                             "null source systemId" , this);
291                         errorHandler.fatalError(saxException);
292                         return;
293                     }
294                     try {
295                         URL JavaDoc url = new URL JavaDoc(systemId);
296                         stream = url.openStream();
297                     } catch (MalformedURLException JavaDoc nue) {
298                         try {
299                             stream = new FileInputStream JavaDoc(systemId);
300                         } catch (FileNotFoundException JavaDoc fnfe) {
301                             SAXParseException JavaDoc saxException = new SAXParseException JavaDoc(
302                                 "could not open file with systemId "+systemId, this, fnfe);
303                             errorHandler.fatalError(saxException);
304                             return;
305                         }
306                     }
307                 }
308                 pp.setInput(stream, encoding);
309             } else {
310                 pp.setInput(reader);
311             }
312         } catch (XmlPullParserException ex) {
313             SAXParseException JavaDoc saxException = new SAXParseException JavaDoc(
314                 "parsing initialization error: "+ex, this, ex);
315             //if(DEBUG) ex.printStackTrace();
316
errorHandler.fatalError(saxException);
317             return;
318         }
319
320         // start parsing - move to first start tag
321
try {
322             contentHandler.startDocument();
323             // get first event
324
pp.next();
325             // it should be start tag...
326
if(pp.getEventType() != pp.START_TAG) {
327                 SAXParseException JavaDoc saxException = new SAXParseException JavaDoc(
328                     "expected start tag not"+pp.getPositionDescription(), this);
329                 //throw saxException;
330
errorHandler.fatalError(saxException);
331                 return;
332             }
333         } catch (XmlPullParserException ex) {
334             SAXParseException JavaDoc saxException = new SAXParseException JavaDoc(
335                 "parsing initialization error: "+ex, this, ex);
336             //ex.printStackTrace();
337
errorHandler.fatalError(saxException);
338             return;
339         }
340
341         // now real parsing can start!
342

343         parseSubTree(pp);
344
345         // and finished ...
346

347         contentHandler.endDocument();
348     }
349
350     public void parse(String JavaDoc systemId) throws SAXException JavaDoc, IOException JavaDoc {
351         parse(new InputSource JavaDoc(systemId));
352     }
353
354
355     public void parseSubTree(XmlPullParser pp) throws SAXException JavaDoc, IOException JavaDoc {
356         this.pp = pp;
357         boolean namespaceAware = pp.getFeature(pp.FEATURE_PROCESS_NAMESPACES);
358         try {
359             if(pp.getEventType() != pp.START_TAG) {
360                 throw new SAXException JavaDoc(
361                     "start tag must be read before skiping subtree"+pp.getPositionDescription());
362             }
363             int[] holderForStartAndLength = new int[2];
364             StringBuffer JavaDoc rawName = new StringBuffer JavaDoc();
365             String JavaDoc prefix = null;
366             String JavaDoc name = null;
367             int level = pp.getDepth() - 1;
368             int type = pp.START_TAG;
369
370             LOOP:
371             do {
372                 switch(type) {
373                     case XmlPullParser.START_TAG:
374                         if(namespaceAware) {
375                             int depth = pp.getDepth() - 1;
376                             int countPrev =
377                                 (level > depth) ? pp.getNamespaceCount(depth) : 0;
378                             //int countPrev = pp.getNamespaceCount(pp.getDepth() - 1);
379
int count = pp.getNamespaceCount(depth + 1);
380                             for (int i = countPrev; i < count; i++)
381                             {
382                                 contentHandler.startPrefixMapping(
383                                     pp.getNamespacePrefix(i),
384                                     pp.getNamespaceUri(i)
385                                 );
386                             }
387                             name = pp.getName();
388                             prefix = pp.getPrefix();
389                             if(prefix != null) {
390                                 rawName.setLength(0);
391                                 rawName.append(prefix);
392                                 rawName.append(':');
393                                 rawName.append(name);
394                             }
395                             startElement(pp.getNamespace(),
396                                          name,
397                                          prefix != null ? name : rawName.toString());
398                         } else {
399                             startElement(pp.getNamespace(),
400                                          pp.getName(),
401                                          pp.getName());
402                         }
403                         //++level;
404

405                         break;
406                     case XmlPullParser.TEXT:
407                         char[] chars = pp.getTextCharacters(holderForStartAndLength);
408                         contentHandler.characters(chars,
409                                                   holderForStartAndLength[0], //start
410
holderForStartAndLength[1] //len
411
);
412                         break;
413                     case XmlPullParser.END_TAG:
414                         //--level;
415
if(namespaceAware) {
416                             name = pp.getName();
417                             prefix = pp.getPrefix();
418                             if(prefix != null) {
419                                 rawName.setLength(0);
420                                 rawName.append(prefix);
421                                 rawName.append(':');
422                                 rawName.append(name);
423                             }
424                             contentHandler.endElement(pp.getNamespace(),
425                                                       name,
426                                                       prefix != null ? name : rawName.toString()
427                                                      );
428                             // when entering show prefixes for all levels!!!!
429
int depth = pp.getDepth();
430                             int countPrev =
431                                 (level > depth) ? pp.getNamespaceCount(pp.getDepth()) : 0;
432                             int count = pp.getNamespaceCount(pp.getDepth() - 1);
433                             // undeclare them in reverse order
434
for (int i = count - 1; i >= countPrev; i--)
435                             {
436                                 contentHandler.endPrefixMapping(
437                                     pp.getNamespacePrefix(i)
438                                 );
439                             }
440                         } else {
441                             contentHandler.endElement(pp.getNamespace(),
442                                                       pp.getName(),
443                                                       pp.getName()
444                                                      );
445
446                         }
447                         break;
448                     case XmlPullParser.END_DOCUMENT:
449                         break LOOP;
450                 }
451                 type = pp.next();
452             } while(pp.getDepth() > level);
453         } catch (XmlPullParserException ex) {
454             SAXParseException JavaDoc saxException = new SAXParseException JavaDoc("parsing error: "+ex, this, ex);
455             ex.printStackTrace();
456             errorHandler.fatalError(saxException);
457         }
458     }
459
460     /**
461      * Calls {@link ContentHandler.startElement(String, String, String, Attributes) startElement}
462      * on the <code>ContentHandler</code> with <code>this</code> driver object as the
463      * {@link Attributes} implementation. In default implementation
464      * {@link Attributes} object is valid only during this method call and may not
465      * be stored. Sub-classes can overwrite this method to cache attributes.
466      */

467     protected void startElement(String JavaDoc namespace, String JavaDoc localName, String JavaDoc qName) throws SAXException JavaDoc {
468         contentHandler.startElement(namespace, localName, qName, this);
469     }
470
471 }
472
473
474
475
Popular Tags