Package org.dom4j.io

Source Code of org.dom4j.io.XPPReader

/*
* Copyright 2001-2005 (C) MetaStuff, Ltd. All Rights Reserved.
*
* This software is open source.
* See the bottom of this file for the licence.
*/

package org.dom4j.io;

import org.dom4j.*;
import org.dom4j.xpp.ProxyXmlStartTag;
import org.gjt.xpp.XmlEndTag;
import org.gjt.xpp.XmlPullParser;
import org.gjt.xpp.XmlPullParserException;
import org.gjt.xpp.XmlPullParserFactory;

import java.io.*;
import java.net.URL;

/**
* <p>
* <code>XPPReader</code> is a Reader of DOM4J documents that uses the fast <a
* href="http://www.extreme.indiana.edu/soap/xpp/">XML Pull Parser 2.x </a>. It
* does not currently support comments, CDATA or ProcessingInstructions or
* validation but it is very fast for use in SOAP style environments.
* </p>
*
* @author <a href="mailto:jstrachan@apache.org">James Strachan </a>
* @version $Revision: 1.7 $
*/
public class XPPReader {
  /**
   * <code>DocumentFactory</code> used to create new document objects
   */
  private DocumentFactory factory;

  /**
   * <code>XmlPullParser</code> used to parse XML
   */
  private XmlPullParser xppParser;

  /**
   * <code>XmlPullParser</code> used to parse XML
   */
  private XmlPullParserFactory xppFactory;

  /**
   * DispatchHandler to call when each <code>Element</code> is encountered
   */
  private DispatchHandler dispatchHandler;

  public XPPReader() {
  }

  public XPPReader(DocumentFactory factory) {
    this.factory = factory;
  }

  /**
   * <p>
   * Reads a Document from the given <code>File</code>
   * </p>
   *
   * @param file is the <code>File</code> to read from.
   * @return the newly created Document instance
   * @throws DocumentException      if an error occurs during parsing.
   * @throws IOException            if a URL could not be made for the given File
   * @throws XmlPullParserException DOCUMENT ME!
   */
  public Document read(File file) throws DocumentException, IOException,
      XmlPullParserException {
    String systemID = file.getAbsolutePath();

    return read(new BufferedReader(new FileReader(file)), systemID);
  }

  /**
   * <p>
   * Reads a Document from the given <code>URL</code>
   * </p>
   *
   * @param url <code>URL</code> to read from.
   * @return the newly created Document instance
   * @throws DocumentException      if an error occurs during parsing.
   * @throws IOException            DOCUMENT ME!
   * @throws XmlPullParserException DOCUMENT ME!
   */
  public Document read(URL url) throws DocumentException, IOException,
      XmlPullParserException {
    String systemID = url.toExternalForm();

    return read(createReader(url.openStream()), systemID);
  }

  /**
   * <p>
   * Reads a Document from the given URL or filename.
   * </p>
   * <p/>
   * <p>
   * If the systemID contains a <code>':'</code> character then it is
   * assumed to be a URL otherwise its assumed to be a file name. If you want
   * finer grained control over this mechansim then please explicitly pass in
   * either a {@link URL}or a {@link File}instance instead of a {@link
   * String} to denote the source of the document.
   * </p>
   *
   * @param systemID is a URL for a document or a file name.
   * @return the newly created Document instance
   * @throws DocumentException      if an error occurs during parsing.
   * @throws IOException            if a URL could not be made for the given File
   * @throws XmlPullParserException DOCUMENT ME!
   */
  public Document read(String systemID) throws DocumentException,
      IOException, XmlPullParserException {
    if (systemID.indexOf(':') >= 0) {
      // lets assume its a URL
      return read(new URL(systemID));
    } else {
      // lets assume that we are given a file name
      return read(new File(systemID));
    }
  }

  /**
   * <p>
   * Reads a Document from the given stream
   * </p>
   *
   * @param in <code>InputStream</code> to read from.
   * @return the newly created Document instance
   * @throws DocumentException      if an error occurs during parsing.
   * @throws IOException            DOCUMENT ME!
   * @throws XmlPullParserException DOCUMENT ME!
   */
  public Document read(InputStream in) throws DocumentException, IOException,
      XmlPullParserException {
    return read(createReader(in));
  }

  /**
   * <p>
   * Reads a Document from the given <code>Reader</code>
   * </p>
   *
   * @param reader is the reader for the input
   * @return the newly created Document instance
   * @throws DocumentException      if an error occurs during parsing.
   * @throws IOException            DOCUMENT ME!
   * @throws XmlPullParserException DOCUMENT ME!
   */
  public Document read(Reader reader) throws DocumentException, IOException,
      XmlPullParserException {
    getXPPParser().setInput(reader);

    return parseDocument();
  }

  /**
   * <p>
   * Reads a Document from the given array of characters
   * </p>
   *
   * @param text is the text to parse
   * @return the newly created Document instance
   * @throws DocumentException      if an error occurs during parsing.
   * @throws IOException            DOCUMENT ME!
   * @throws XmlPullParserException DOCUMENT ME!
   */
  public Document read(char[] text) throws DocumentException, IOException,
      XmlPullParserException {
    getXPPParser().setInput(text);

    return parseDocument();
  }

  /**
   * <p>
   * Reads a Document from the given stream
   * </p>
   *
   * @param in       <code>InputStream</code> to read from.
   * @param systemID is the URI for the input
   * @return the newly created Document instance
   * @throws DocumentException      if an error occurs during parsing.
   * @throws IOException            DOCUMENT ME!
   * @throws XmlPullParserException DOCUMENT ME!
   */
  public Document read(InputStream in, String systemID)
      throws DocumentException, IOException, XmlPullParserException {
    return read(createReader(in), systemID);
  }

  /**
   * <p>
   * Reads a Document from the given <code>Reader</code>
   * </p>
   *
   * @param reader   is the reader for the input
   * @param systemID is the URI for the input
   * @return the newly created Document instance
   * @throws DocumentException      if an error occurs during parsing.
   * @throws IOException            DOCUMENT ME!
   * @throws XmlPullParserException DOCUMENT ME!
   */
  public Document read(Reader reader, String systemID)
      throws DocumentException, IOException, XmlPullParserException {
    Document document = read(reader);
    document.setName(systemID);

    return document;
  }

  // Properties
  // -------------------------------------------------------------------------

  public XmlPullParser getXPPParser() throws XmlPullParserException {
    if (xppParser == null) {
      xppParser = getXPPFactory().newPullParser();
    }

    return xppParser;
  }

  public XmlPullParserFactory getXPPFactory() throws XmlPullParserException {
    if (xppFactory == null) {
      xppFactory = XmlPullParserFactory.newInstance();
    }

    return xppFactory;
  }

  public void setXPPFactory(XmlPullParserFactory xPPFactory) {
    this.xppFactory = xPPFactory;
  }

  /**
   * DOCUMENT ME!
   *
   * @return the <code>DocumentFactory</code> used to create document
   *         objects
   */
  public DocumentFactory getDocumentFactory() {
    if (factory == null) {
      factory = DocumentFactory.getInstance();
    }

    return factory;
  }

  /**
   * <p>
   * This sets the <code>DocumentFactory</code> used to create new
   * documents. This method allows the building of custom DOM4J tree objects
   * to be implemented easily using a custom derivation of
   * {@link DocumentFactory}
   * </p>
   *
   * @param documentFactory <code>DocumentFactory</code> used to create DOM4J objects
   */
  public void setDocumentFactory(DocumentFactory documentFactory) {
    this.factory = documentFactory;
  }

  /**
   * Adds the <code>ElementHandler</code> to be called when the specified
   * path is encounted.
   *
   * @param path    is the path to be handled
   * @param handler is the <code>ElementHandler</code> to be called by the event
   *                based processor.
   */
  public void addHandler(String path, ElementHandler handler) {
    getDispatchHandler().addHandler(path, handler);
  }

  /**
   * Removes the <code>ElementHandler</code> from the event based processor,
   * for the specified path.
   *
   * @param path is the path to remove the <code>ElementHandler</code> for.
   */
  public void removeHandler(String path) {
    getDispatchHandler().removeHandler(path);
  }

  /**
   * When multiple <code>ElementHandler</code> instances have been
   * registered, this will set a default <code>ElementHandler</code> to be
   * called for any path which does <b>NOT </b> have a handler registered.
   *
   * @param handler is the <code>ElementHandler</code> to be called by the event
   *                based processor.
   */
  public void setDefaultHandler(ElementHandler handler) {
    getDispatchHandler().setDefaultHandler(handler);
  }

  // Implementation methods
  // -------------------------------------------------------------------------

  protected Document parseDocument() throws DocumentException, IOException,
      XmlPullParserException {
    Document document = getDocumentFactory().createDocument();
    Element parent = null;
    XmlPullParser parser = getXPPParser();
    parser.setNamespaceAware(true);

    ProxyXmlStartTag startTag = new ProxyXmlStartTag();
    XmlEndTag endTag = xppFactory.newEndTag();

    while (true) {
      int type = parser.next();

      switch (type) {
        case XmlPullParser.END_DOCUMENT:
          return document;

        case XmlPullParser.START_TAG: {
          parser.readStartTag(startTag);

          Element newElement = startTag.getElement();

          if (parent != null) {
            parent.add(newElement);
          } else {
            document.add(newElement);
          }

          parent = newElement;

          break;
        }

        case XmlPullParser.END_TAG: {
          parser.readEndTag(endTag);

          if (parent != null) {
            parent = parent.getParent();
          }

          break;
        }

        case XmlPullParser.CONTENT: {
          String text = parser.readContent();

          if (parent != null) {
            parent.addText(text);
          } else {
            String msg = "Cannot have text content outside of the "
                + "root document";
            throw new DocumentException(msg);
          }

          break;
        }

        default:
          throw new DocumentException("Error: unknown type: " + type);
      }
    }
  }

  protected DispatchHandler getDispatchHandler() {
    if (dispatchHandler == null) {
      dispatchHandler = new DispatchHandler();
    }

    return dispatchHandler;
  }

  protected void setDispatchHandler(DispatchHandler dispatchHandler) {
    this.dispatchHandler = dispatchHandler;
  }

  /**
   * Factory method to create a Reader from the given InputStream.
   *
   * @param in DOCUMENT ME!
   * @return DOCUMENT ME!
   * @throws IOException DOCUMENT ME!
   */
  protected Reader createReader(InputStream in) throws IOException {
    return new BufferedReader(new InputStreamReader(in));
  }
}

/*
* Redistribution and use of this software and associated documentation
* ("Software"), with or without modification, are permitted provided that the
* following conditions are met:
*
* 1. Redistributions of source code must retain copyright statements and
* notices. Redistributions must also contain a copy of this document.
*
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* 3. The name "DOM4J" must not be used to endorse or promote products derived
* from this Software without prior written permission of MetaStuff, Ltd. For
* written permission, please contact dom4j-info@metastuff.com.
*
* 4. Products derived from this Software may not be called "DOM4J" nor may
* "DOM4J" appear in their names without prior written permission of MetaStuff,
* Ltd. DOM4J is a registered trademark of MetaStuff, Ltd.
*
* 5. Due credit should be given to the DOM4J Project - http://dom4j.sourceforge.net
*
* THIS SOFTWARE IS PROVIDED BY METASTUFF, LTD. AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL METASTUFF, LTD. OR ITS CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* Copyright 2001-2005 (C) MetaStuff, Ltd. All Rights Reserved.
*/ 
TOP

Related Classes of org.dom4j.io.XPPReader

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.