Project dom4j 1.5.2 [5/2/05 10:13 PM]
 
Coverage - org/dom4j/io/SAXModifier.java
  /*
   * Copyright 2001-2004 (C) MetaStuff, Ltd. All Rights Reserved.
   * 
   * This software is open source. 
   * See the bottom of this file for the licence.
   * 
   * $Id: SAXModifier.java,v 1.2 2004/10/16 19:03:41 maartenc Exp $
   */
 
  package org.dom4j.io;
 
  import java.io.File;
  import java.io.InputStream;
  import java.io.Reader;
  import java.net.URL;
  import java.util.HashMap;
  import java.util.Iterator;
  import java.util.Map;
 
  import org.dom4j.Document;
  import org.dom4j.DocumentException;
  import org.dom4j.DocumentFactory;
  import org.xml.sax.InputSource;
  import org.xml.sax.SAXException;
  import org.xml.sax.XMLReader;
 
  /**
   * The SAXModifier reads, modifies and writes XML documents using SAX. <br>
   * Registered {@link ElementModifier} objects can provide modifications to (part of) the xml tree,
   * while the document is still being processed. This makes it possible to change large xml documents
   * without having them in memory.<br>
   * The modified document is written when the {@link XMLWriter} is specified.
   * 
   * @see org.dom4j.io.SAXReader
   * @see org.dom4j.io.XMLWriter
   * @author Wonne Keysers (Realsoftware.be)
   */
  public class SAXModifier {
 
     private XMLWriter xmlWriter;
     private XMLReader xmlReader;
 
     private boolean pruneElements;
     private SAXModifyReader modifyReader;
0x      private HashMap modifiers = new HashMap();
 
     /**
      * Creates a new modifier.<br>
      * The XMLReader to parse the source will be created via the org.xml.sax.driver system property
      * or JAXP if the system property is not set.
      */
0x      public SAXModifier() {
0x      }
 
     /**
      * Creates a new modifier.<br>
      * The XMLReader to parse the source will be created via the org.xml.sax.driver system property
      * or JAXP if the system property is not set.
      * 
      * @param pruneElements Set to true when the modified document must NOT be kept in memory.
      */
0x      public SAXModifier(boolean pruneElements) {
0x         this.pruneElements = pruneElements;
0x      }
 
     /**
      * Creates a new modifier that will the specified {@link org.xml.sax.XMLReader}
      * to parse the source.
      * 
      * @param xmlReader The XMLReader to use
      */
0x      public SAXModifier(XMLReader xmlReader) {
0x         this.xmlReader = xmlReader;
0x      }
 
     /**
      * Creates a new modifier that will the specified {@link org.xml.sax.XMLReader}
      * to parse the source.
      * 
      * @param xmlReader The XMLReader to use
      * @param pruneElements Set to true when the modified document must NOT be kept in memory.
      */
0x      public SAXModifier(XMLReader xmlReader, boolean pruneElements) {
0x         this.xmlReader = xmlReader;
0x      }
 
     /** 
      * Reads a Document from the given {@link java.io.File}
      * and writes it to the specified {@link XMLWriter} using SAX.
      * Registered {@link ElementModifier} objects are invoked on the fly.
      *
      * @param source is the <code>File</code> to read from.
      * @return the newly created Document instance
      * @throws {@link org.dom4j.DocumentException} if an error occurs during parsing.
      */
     public Document modify(File source) throws DocumentException {
        try {
0x            return installModifyReader().read(source);
        }
        catch (SAXModifyException ex) {
0x            Throwable cause = ex.getCause();
0x            throw new DocumentException(cause.getMessage(), cause);
        }
     }
 
     /** 
      * Reads a Document from the given {@link org.xml.sax.InputSource}
      * and writes it to the specified {@link XMLWriter} using SAX.
      * Registered {@link ElementModifier} objects are invoked on the fly.
      *
      * @param source is the <code>org.xml.sax.InputSource</code> to read from.
      * @return the newly created Document instance
      * @throws {@link org.dom4j.DocumentException} if an error occurs during parsing.
      */
     public Document modify(InputSource source) throws DocumentException {
        try {
0x            return installModifyReader().read(source);
        }
        catch (SAXModifyException ex) {
0x            Throwable cause = ex.getCause();
0x            throw new DocumentException(cause.getMessage(), cause);
        }
     }
 
     /** 
      * Reads a Document from the given {@link java.io.InputStream}
      * and writes it to the specified {@link XMLWriter} using SAX.
      * Registered {@link ElementModifier} objects are invoked on the fly.
      *
      * @param source is the <code>java.io.InputStream</code> to read from.
      * @return the newly created Document instance
      * @throws {@link org.dom4j.DocumentException} if an error occurs during parsing.
      */
     public Document modify(InputStream source) throws DocumentException {
        try {
0x            return installModifyReader().read(source);
        }
        catch (SAXModifyException ex) {
0x            Throwable cause = ex.getCause();
0x            throw new DocumentException(cause.getMessage(), cause);
        }
     }
 
     /** 
      * Reads a Document from the given {@link java.io.InputStream}
      * and writes it to the specified {@link XMLWriter} using SAX.
      * Registered {@link ElementModifier} objects are invoked on the fly.
      *
      * @param source is the <code>java.io.InputStream</code> to read from.
      * @return the newly created Document instance
      * @throws {@link org.dom4j.DocumentException} if an error occurs during parsing.
      */
     public Document modify(InputStream source, String systemId) throws DocumentException {
        try {
0x            return installModifyReader().read(source);
        }
        catch (SAXModifyException ex) {
0x            Throwable cause = ex.getCause();
0x            throw new DocumentException(cause.getMessage(), cause);
        }
     }
 
     /** 
      * Reads a Document from the given {@link java.io.Reader}
      * and writes it to the specified {@link XMLWriter} using SAX.
      * Registered {@link ElementModifier} objects are invoked on the fly.
      *
      * @param source is the <code>java.io.Reader</code> to read from.
      * @return the newly created Document instance
      * @throws {@link org.dom4j.DocumentException} if an error occurs during parsing.
      */
     public Document modify(Reader source) throws DocumentException {
        try {
0x            return installModifyReader().read(source);
        }
        catch (SAXModifyException ex) {
0x            Throwable cause = ex.getCause();
0x            throw new DocumentException(cause.getMessage(), cause);
        }
     }
 
     /** 
      * Reads a Document from the given {@link java.io.Reader}
      * and writes it to the specified {@link XMLWriter} using SAX.
      * Registered {@link ElementModifier} objects are invoked on the fly.
      *
      * @param source is the <code>java.io.Reader</code> to read from.
      * @return the newly created Document instance
      * @throws {@link org.dom4j.DocumentException} if an error occurs during parsing.
      */
     public Document modify(Reader source, String systemId) throws DocumentException {
        try {
0x            return installModifyReader().read(source);
        }
        catch (SAXModifyException ex) {
0x            Throwable cause = ex.getCause();
0x            throw new DocumentException(cause.getMessage(), cause);
        }
     }
 
     /** 
      * Reads a Document from the given {@link java.net.URL}
      * and writes it to the specified {@link XMLWriter} using SAX.
      * Registered {@link ElementModifier} objects are invoked on the fly.
      *
      * @param source is the <code>java.net.URL</code> to read from.
      * @return the newly created Document instance
      * @throws {@link org.dom4j.DocumentException} if an error occurs during parsing.
      */
     public Document modify(URL source) throws DocumentException {
        try {
0x            return installModifyReader().read(source);
        }
        catch (SAXModifyException ex) {
0x            Throwable cause = ex.getCause();
0x            throw new DocumentException(cause.getMessage(), cause);
        }
     }
 
     /** 
      * Reads a Document from the given URL or filename
      * and writes it to the specified {@link XMLWriter} using SAX.
      * Registered {@link ElementModifier} objects are invoked on the fly.
      *
      * @param source is the URL or filename to read from.
      * @return the newly created Document instance
      * @throws {@link org.dom4j.DocumentException} if an error occurs during parsing.
      */
     public Document modify(String source) throws DocumentException {
        try {
0x            return installModifyReader().read(source);
        }
        catch (SAXModifyException ex) {
0x            Throwable cause = ex.getCause();
0x            throw new DocumentException(cause.getMessage(), cause);
        }
     }
 
     /** 
      * Adds the {@link ElementModifier} to be called
      * when the specified element path is encounted while parsing the source.
      *
      * @param path The element path to be handled
      * @param modifier The {@link ElementModifier} to be called by the event based processor.
      */
     public void addModifier(String path, ElementModifier modifier) {
0x         this.modifiers.put(path, modifier);
0x      }
 
     /**
      * Removes all registered {@link ElementModifier} instances from the event based processor.
      */
     public void resetModifiers() {
0x         this.modifiers.clear();
0x         getSAXModifyReader().resetHandlers();
0x      }
 
     /**
      * Removes the {@link ElementModifier} from the event based processor,
      * for the specified element path.
      *
      * @param path The path to remove the {@link ElementModifier} for.
      */
     public void removeModifier(String path) {
0x         this.modifiers.remove(path);
0x         getSAXModifyReader().removeHandler(path);
0x      }
 
     /**
      * Get the {@link org.dom4j.DocumentFactory} used to create the DOM4J document structure
      * 
      * @return <code>DocumentFactory</code> that will be used
      */
     public DocumentFactory getDocumentFactory() {
0x         return getSAXModifyReader().getDocumentFactory();
     }
 
     /**
      * Sets the {@link org.dom4j.DocumentFactory} used to create the DOM4J document tree.
      * 
      * @param factory <code>DocumentFactory</code> to be used
      */
     public void setDocumentFactory(DocumentFactory factory) {
0x         getSAXModifyReader().setDocumentFactory(factory);
0x      }
 
     /**
      * Returns the current {@link XMLWriter}.  
      * @return XMLWriter
      */
     public XMLWriter getXMLWriter() {
0x         return this.xmlWriter;
     }
 
     /**
      * Sets the {@link XMLWriter} used to write the modified document.
      * @param xmlWriter The writer to use.
      */
     public void setXMLWriter(XMLWriter xmlWriter) {
0x         this.xmlWriter = xmlWriter;
0x      }
 
     /**
      * Returns true when xml elements are not kept in memory while parsing.
      * The {@link org.dom4j.Document} returned by the modify methods will be null.
      * @return Returns the pruneElements.
      */
     public boolean isPruneElements() {
0x         return pruneElements;
     }
 
     private SAXReader installModifyReader() throws DocumentException {
        try {
0x            SAXModifyReader reader = getSAXModifyReader();
           
0/2 0x            if (isPruneElements()) {
0x               modifyReader.setDispatchHandler(new PruningDispatchHandler());
           }
           
0x            reader.resetHandlers();
           
0x            Iterator modifierIt = this.modifiers.entrySet().iterator();
0/2 0x            while(modifierIt.hasNext()){
0x               Map.Entry entry = (Map.Entry)modifierIt.next();
              
0x               SAXModifyElementHandler modifierHandler
                  = new SAXModifyElementHandler((ElementModifier)entry.getValue());
0x               reader.addHandler((String)entry.getKey(), modifierHandler);
           }
 
0x            reader.setXMLWriter(getXMLWriter());
0x            reader.setXMLReader(getXMLReader());
 
0x            return reader;
        }
        catch (SAXException ex) {
0x            throw new DocumentException(ex.getMessage(), ex);
        }
     }
 
     private XMLReader getXMLReader() throws SAXException {
0/2 0x         if (this.xmlReader == null) {
0x            xmlReader = SAXHelper.createXMLReader(false);
        }
0x         return this.xmlReader;
     }
 
     private SAXModifyReader getSAXModifyReader() {
0/2 0x         if (modifyReader == null) {
0x            modifyReader = new SAXModifyReader();
        }
 
0x         return modifyReader;
     }
 
  }
 
 
 
 
  /*
   * 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://www.dom4j.org
   *
   * 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-2004 (C) MetaStuff, Ltd. All Rights Reserved.
   *
   * $Id: SAXModifier.java,v 1.2 2004/10/16 19:03:41 maartenc Exp $
   */