Clover coverage report - dom4j - 1.6.1
Coverage timestamp: ma mei 16 2005 14:23:01 GMT+01:00
file stats: LOC: 484   Methods: 22
NCLOC: 164   Classes: 1
 
 Source file Conditionals Statements Methods TOTAL
XPPReader.java 0% 0% 0% 0%
coverage
 1    /*
 2    * Copyright 2001-2005 (C) MetaStuff, Ltd. All Rights Reserved.
 3    *
 4    * This software is open source.
 5    * See the bottom of this file for the licence.
 6    */
 7   
 8    package org.dom4j.io;
 9   
 10    import java.io.BufferedReader;
 11    import java.io.File;
 12    import java.io.FileReader;
 13    import java.io.IOException;
 14    import java.io.InputStream;
 15    import java.io.InputStreamReader;
 16    import java.io.Reader;
 17    import java.net.URL;
 18   
 19    import org.dom4j.Document;
 20    import org.dom4j.DocumentException;
 21    import org.dom4j.DocumentFactory;
 22    import org.dom4j.Element;
 23    import org.dom4j.ElementHandler;
 24    import org.dom4j.xpp.ProxyXmlStartTag;
 25   
 26    import org.gjt.xpp.XmlEndTag;
 27    import org.gjt.xpp.XmlPullParser;
 28    import org.gjt.xpp.XmlPullParserException;
 29    import org.gjt.xpp.XmlPullParserFactory;
 30   
 31    /**
 32    * <p>
 33    * <code>XPPReader</code> is a Reader of DOM4J documents that uses the fast <a
 34    * href="http://www.extreme.indiana.edu/soap/xpp/">XML Pull Parser 2.x </a>. It
 35    * does not currently support comments, CDATA or ProcessingInstructions or
 36    * validation but it is very fast for use in SOAP style environments.
 37    * </p>
 38    *
 39    * @author <a href="mailto:jstrachan@apache.org">James Strachan </a>
 40    * @version $Revision: 1.7 $
 41    */
 42    public class XPPReader {
 43    /** <code>DocumentFactory</code> used to create new document objects */
 44    private DocumentFactory factory;
 45   
 46    /** <code>XmlPullParser</code> used to parse XML */
 47    private XmlPullParser xppParser;
 48   
 49    /** <code>XmlPullParser</code> used to parse XML */
 50    private XmlPullParserFactory xppFactory;
 51   
 52    /** DispatchHandler to call when each <code>Element</code> is encountered */
 53    private DispatchHandler dispatchHandler;
 54   
 55  0 public XPPReader() {
 56    }
 57   
 58  0 public XPPReader(DocumentFactory factory) {
 59  0 this.factory = factory;
 60    }
 61   
 62    /**
 63    * <p>
 64    * Reads a Document from the given <code>File</code>
 65    * </p>
 66    *
 67    * @param file
 68    * is the <code>File</code> to read from.
 69    *
 70    * @return the newly created Document instance
 71    *
 72    * @throws DocumentException
 73    * if an error occurs during parsing.
 74    * @throws IOException
 75    * if a URL could not be made for the given File
 76    * @throws XmlPullParserException
 77    * DOCUMENT ME!
 78    */
 79  0 public Document read(File file) throws DocumentException, IOException,
 80    XmlPullParserException {
 81  0 String systemID = file.getAbsolutePath();
 82   
 83  0 return read(new BufferedReader(new FileReader(file)), systemID);
 84    }
 85   
 86    /**
 87    * <p>
 88    * Reads a Document from the given <code>URL</code>
 89    * </p>
 90    *
 91    * @param url
 92    * <code>URL</code> to read from.
 93    *
 94    * @return the newly created Document instance
 95    *
 96    * @throws DocumentException
 97    * if an error occurs during parsing.
 98    * @throws IOException
 99    * DOCUMENT ME!
 100    * @throws XmlPullParserException
 101    * DOCUMENT ME!
 102    */
 103  0 public Document read(URL url) throws DocumentException, IOException,
 104    XmlPullParserException {
 105  0 String systemID = url.toExternalForm();
 106   
 107  0 return read(createReader(url.openStream()), systemID);
 108    }
 109   
 110    /**
 111    * <p>
 112    * Reads a Document from the given URL or filename.
 113    * </p>
 114    *
 115    * <p>
 116    * If the systemID contains a <code>':'</code> character then it is
 117    * assumed to be a URL otherwise its assumed to be a file name. If you want
 118    * finer grained control over this mechansim then please explicitly pass in
 119    * either a {@link URL}or a {@link File}instance instead of a {@link
 120    * String} to denote the source of the document.
 121    * </p>
 122    *
 123    * @param systemID
 124    * is a URL for a document or a file name.
 125    *
 126    * @return the newly created Document instance
 127    *
 128    * @throws DocumentException
 129    * if an error occurs during parsing.
 130    * @throws IOException
 131    * if a URL could not be made for the given File
 132    * @throws XmlPullParserException
 133    * DOCUMENT ME!
 134    */
 135  0 public Document read(String systemID) throws DocumentException,
 136    IOException, XmlPullParserException {
 137  0 if (systemID.indexOf(':') >= 0) {
 138    // lets assume its a URL
 139  0 return read(new URL(systemID));
 140    } else {
 141    // lets assume that we are given a file name
 142  0 return read(new File(systemID));
 143    }
 144    }
 145   
 146    /**
 147    * <p>
 148    * Reads a Document from the given stream
 149    * </p>
 150    *
 151    * @param in
 152    * <code>InputStream</code> to read from.
 153    *
 154    * @return the newly created Document instance
 155    *
 156    * @throws DocumentException
 157    * if an error occurs during parsing.
 158    * @throws IOException
 159    * DOCUMENT ME!
 160    * @throws XmlPullParserException
 161    * DOCUMENT ME!
 162    */
 163  0 public Document read(InputStream in) throws DocumentException, IOException,
 164    XmlPullParserException {
 165  0 return read(createReader(in));
 166    }
 167   
 168    /**
 169    * <p>
 170    * Reads a Document from the given <code>Reader</code>
 171    * </p>
 172    *
 173    * @param reader
 174    * is the reader for the input
 175    *
 176    * @return the newly created Document instance
 177    *
 178    * @throws DocumentException
 179    * if an error occurs during parsing.
 180    * @throws IOException
 181    * DOCUMENT ME!
 182    * @throws XmlPullParserException
 183    * DOCUMENT ME!
 184    */
 185  0 public Document read(Reader reader) throws DocumentException, IOException,
 186    XmlPullParserException {
 187  0 getXPPParser().setInput(reader);
 188   
 189  0 return parseDocument();
 190    }
 191   
 192    /**
 193    * <p>
 194    * Reads a Document from the given array of characters
 195    * </p>
 196    *
 197    * @param text
 198    * is the text to parse
 199    *
 200    * @return the newly created Document instance
 201    *
 202    * @throws DocumentException
 203    * if an error occurs during parsing.
 204    * @throws IOException
 205    * DOCUMENT ME!
 206    * @throws XmlPullParserException
 207    * DOCUMENT ME!
 208    */
 209  0 public Document read(char[] text) throws DocumentException, IOException,
 210    XmlPullParserException {
 211  0 getXPPParser().setInput(text);
 212   
 213  0 return parseDocument();
 214    }
 215   
 216    /**
 217    * <p>
 218    * Reads a Document from the given stream
 219    * </p>
 220    *
 221    * @param in
 222    * <code>InputStream</code> to read from.
 223    * @param systemID
 224    * is the URI for the input
 225    *
 226    * @return the newly created Document instance
 227    *
 228    * @throws DocumentException
 229    * if an error occurs during parsing.
 230    * @throws IOException
 231    * DOCUMENT ME!
 232    * @throws XmlPullParserException
 233    * DOCUMENT ME!
 234    */
 235  0 public Document read(InputStream in, String systemID)
 236    throws DocumentException, IOException, XmlPullParserException {
 237  0 return read(createReader(in), systemID);
 238    }
 239   
 240    /**
 241    * <p>
 242    * Reads a Document from the given <code>Reader</code>
 243    * </p>
 244    *
 245    * @param reader
 246    * is the reader for the input
 247    * @param systemID
 248    * is the URI for the input
 249    *
 250    * @return the newly created Document instance
 251    *
 252    * @throws DocumentException
 253    * if an error occurs during parsing.
 254    * @throws IOException
 255    * DOCUMENT ME!
 256    * @throws XmlPullParserException
 257    * DOCUMENT ME!
 258    */
 259  0 public Document read(Reader reader, String systemID)
 260    throws DocumentException, IOException, XmlPullParserException {
 261  0 Document document = read(reader);
 262  0 document.setName(systemID);
 263   
 264  0 return document;
 265    }
 266   
 267    // Properties
 268    // -------------------------------------------------------------------------
 269  0 public XmlPullParser getXPPParser() throws XmlPullParserException {
 270  0 if (xppParser == null) {
 271  0 xppParser = getXPPFactory().newPullParser();
 272    }
 273   
 274  0 return xppParser;
 275    }
 276   
 277  0 public XmlPullParserFactory getXPPFactory() throws XmlPullParserException {
 278  0 if (xppFactory == null) {
 279  0 xppFactory = XmlPullParserFactory.newInstance();
 280    }
 281   
 282  0 return xppFactory;
 283    }
 284   
 285  0 public void setXPPFactory(XmlPullParserFactory xPPFactory) {
 286  0 this.xppFactory = xPPFactory;
 287    }
 288   
 289    /**
 290    * DOCUMENT ME!
 291    *
 292    * @return the <code>DocumentFactory</code> used to create document
 293    * objects
 294    */
 295  0 public DocumentFactory getDocumentFactory() {
 296  0 if (factory == null) {
 297  0 factory = DocumentFactory.getInstance();
 298    }
 299   
 300  0 return factory;
 301    }
 302   
 303    /**
 304    * <p>
 305    * This sets the <code>DocumentFactory</code> used to create new
 306    * documents. This method allows the building of custom DOM4J tree objects
 307    * to be implemented easily using a custom derivation of
 308    * {@link DocumentFactory}
 309    * </p>
 310    *
 311    * @param documentFactory
 312    * <code>DocumentFactory</code> used to create DOM4J objects
 313    */
 314  0 public void setDocumentFactory(DocumentFactory documentFactory) {
 315  0 this.factory = documentFactory;
 316    }
 317   
 318    /**
 319    * Adds the <code>ElementHandler</code> to be called when the specified
 320    * path is encounted.
 321    *
 322    * @param path
 323    * is the path to be handled
 324    * @param handler
 325    * is the <code>ElementHandler</code> to be called by the event
 326    * based processor.
 327    */
 328  0 public void addHandler(String path, ElementHandler handler) {
 329  0 getDispatchHandler().addHandler(path, handler);
 330    }
 331   
 332    /**
 333    * Removes the <code>ElementHandler</code> from the event based processor,
 334    * for the specified path.
 335    *
 336    * @param path
 337    * is the path to remove the <code>ElementHandler</code> for.
 338    */
 339  0 public void removeHandler(String path) {
 340  0 getDispatchHandler().removeHandler(path);
 341    }
 342   
 343    /**
 344    * When multiple <code>ElementHandler</code> instances have been
 345    * registered, this will set a default <code>ElementHandler</code> to be
 346    * called for any path which does <b>NOT </b> have a handler registered.
 347    *
 348    * @param handler
 349    * is the <code>ElementHandler</code> to be called by the event
 350    * based processor.
 351    */
 352  0 public void setDefaultHandler(ElementHandler handler) {
 353  0 getDispatchHandler().setDefaultHandler(handler);
 354    }
 355   
 356    // Implementation methods
 357    // -------------------------------------------------------------------------
 358  0 protected Document parseDocument() throws DocumentException, IOException,
 359    XmlPullParserException {
 360  0 Document document = getDocumentFactory().createDocument();
 361  0 Element parent = null;
 362  0 XmlPullParser parser = getXPPParser();
 363  0 parser.setNamespaceAware(true);
 364   
 365  0 ProxyXmlStartTag startTag = new ProxyXmlStartTag();
 366  0 XmlEndTag endTag = xppFactory.newEndTag();
 367   
 368  0 while (true) {
 369  0 int type = parser.next();
 370   
 371  0 switch (type) {
 372  0 case XmlPullParser.END_DOCUMENT:
 373  0 return document;
 374   
 375  0 case XmlPullParser.START_TAG: {
 376  0 parser.readStartTag(startTag);
 377   
 378  0 Element newElement = startTag.getElement();
 379   
 380  0 if (parent != null) {
 381  0 parent.add(newElement);
 382    } else {
 383  0 document.add(newElement);
 384    }
 385   
 386  0 parent = newElement;
 387   
 388  0 break;
 389    }
 390   
 391  0 case XmlPullParser.END_TAG: {
 392  0 parser.readEndTag(endTag);
 393   
 394  0 if (parent != null) {
 395  0 parent = parent.getParent();
 396    }
 397   
 398  0 break;
 399    }
 400   
 401  0 case XmlPullParser.CONTENT: {
 402  0 String text = parser.readContent();
 403   
 404  0 if (parent != null) {
 405  0 parent.addText(text);
 406    } else {
 407  0 String msg = "Cannot have text content outside of the "
 408    + "root document";
 409  0 throw new DocumentException(msg);
 410    }
 411   
 412  0 break;
 413    }
 414   
 415  0 default:
 416  0 throw new DocumentException("Error: unknown type: " + type);
 417    }
 418    }
 419    }
 420   
 421  0 protected DispatchHandler getDispatchHandler() {
 422  0 if (dispatchHandler == null) {
 423  0 dispatchHandler = new DispatchHandler();
 424    }
 425   
 426  0 return dispatchHandler;
 427    }
 428   
 429  0 protected void setDispatchHandler(DispatchHandler dispatchHandler) {
 430  0 this.dispatchHandler = dispatchHandler;
 431    }
 432   
 433    /**
 434    * Factory method to create a Reader from the given InputStream.
 435    *
 436    * @param in
 437    * DOCUMENT ME!
 438    *
 439    * @return DOCUMENT ME!
 440    *
 441    * @throws IOException
 442    * DOCUMENT ME!
 443    */
 444  0 protected Reader createReader(InputStream in) throws IOException {
 445  0 return new BufferedReader(new InputStreamReader(in));
 446    }
 447    }
 448   
 449    /*
 450    * Redistribution and use of this software and associated documentation
 451    * ("Software"), with or without modification, are permitted provided that the
 452    * following conditions are met:
 453    *
 454    * 1. Redistributions of source code must retain copyright statements and
 455    * notices. Redistributions must also contain a copy of this document.
 456    *
 457    * 2. Redistributions in binary form must reproduce the above copyright notice,
 458    * this list of conditions and the following disclaimer in the documentation
 459    * and/or other materials provided with the distribution.
 460    *
 461    * 3. The name "DOM4J" must not be used to endorse or promote products derived
 462    * from this Software without prior written permission of MetaStuff, Ltd. For
 463    * written permission, please contact dom4j-info@metastuff.com.
 464    *
 465    * 4. Products derived from this Software may not be called "DOM4J" nor may
 466    * "DOM4J" appear in their names without prior written permission of MetaStuff,
 467    * Ltd. DOM4J is a registered trademark of MetaStuff, Ltd.
 468    *
 469    * 5. Due credit should be given to the DOM4J Project - http://www.dom4j.org
 470    *
 471    * THIS SOFTWARE IS PROVIDED BY METASTUFF, LTD. AND CONTRIBUTORS ``AS IS'' AND
 472    * ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 473    * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 474    * ARE DISCLAIMED. IN NO EVENT SHALL METASTUFF, LTD. OR ITS CONTRIBUTORS BE
 475    * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 476    * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 477    * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 478    * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 479    * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 480    * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 481    * POSSIBILITY OF SUCH DAMAGE.
 482    *
 483    * Copyright 2001-2005 (C) MetaStuff, Ltd. All Rights Reserved.
 484    */