sylvain     02/02/22 15:25:19

  Modified:    src/java/org/apache/cocoon/components/source URLSource.java
               src/java/org/apache/cocoon/generation xmldb.xconf
               src/java/org/apache/cocoon/xml XMLUtils.java
  Added:       src/java/org/apache/cocoon/components/source
                        AbstractStreamSource.java
                        AbstractStreamWriteableSource.java FileSource.java
                        FileSourceFactory.java
               src/java/org/apache/cocoon/environment WriteableSource.java
  Log:
  New WriteableSource to write anywhere
  
  Revision  Changes    Path
  1.11      +7 -102    
xml-cocoon2/src/java/org/apache/cocoon/components/source/URLSource.java
  
  Index: URLSource.java
  ===================================================================
  RCS file: 
/home/cvs/xml-cocoon2/src/java/org/apache/cocoon/components/source/URLSource.java,v
  retrieving revision 1.10
  retrieving revision 1.11
  diff -u -r1.10 -r1.11
  --- URLSource.java    22 Feb 2002 07:00:13 -0000      1.10
  +++ URLSource.java    22 Feb 2002 23:25:18 -0000      1.11
  @@ -86,35 +86,10 @@
    * Description of a source which is described by an URL.
    *
    * @author <a href="mailto:[EMAIL PROTECTED]";>Carsten Ziegeler</a>
  - * @version CVS $Id: URLSource.java,v 1.10 2002/02/22 07:00:13 cziegeler Exp $
  + * @version CVS $Id: URLSource.java,v 1.11 2002/02/22 23:25:18 sylvain Exp $
    */
   
  -public class URLSource implements ModifiableSource {
  -
  -    /** Is JTidy available? */
  -    private static Class jtidyClass;
  -
  -    /** Properties used for converting HTML to XML */
  -    private static Properties xmlProperties;
  -
  -    /** The TrAX factory for serializing xml */
  -    public static TransformerFactory transformerFactory = 
TransformerFactory.newInstance();
  -
  -    /**
  -     * Test if JTidy is available
  -     */
  -    static {
  -        jtidyClass = null;
  -        try {
  -            jtidyClass = ClassUtils.loadClass("org.w3c.tidy.Tidy");
  -        } catch (ClassNotFoundException cnfe) {
  -            // ignore
  -        }
  -        xmlProperties = new Properties();
  -        xmlProperties.put(OutputKeys.METHOD, "xml");
  -        xmlProperties.put(OutputKeys.OMIT_XML_DECLARATION, "no");
  -    }
  -
  +public class URLSource extends AbstractStreamSource {
   
       /** Identifier for file urls */
       private final String FILE = "file:";
  @@ -143,9 +118,6 @@
       /** Are we initialized? */
       private boolean gotInfos;
   
  -    /** The ComponentManager needed for streaming */
  -    private ComponentManager manager;
  -
       /** The <code>SourceParameters</code> for post */
       private SourceParameters postParameters;
   
  @@ -157,7 +129,7 @@
        */
       public URLSource(URL url, ComponentManager manager)
       throws IOException {
  -        this.manager = manager;
  +        super(manager);
           this.systemId = url.toExternalForm();
           this.isFile = systemId.startsWith(FILE);
           if (this.isFile == true) {
  @@ -168,6 +140,10 @@
           this.url = url;
           this.gotInfos = false;
       }
  +    
  +    protected boolean isHTMLContent() {
  +        return this.isHTMLContent;
  +    }
   
       /**
        * Get the last modification date and content length of the source.
  @@ -359,76 +335,6 @@
       }
   
       /**
  -     * Return a new <code>InputSource</code> object
  -     *
  -     * @throws ResourceNotFoundException if file not found or
  -     *         HTTP location does not exist.
  -     * @throws IOException if I/O error occured.
  -     */
  -    public InputSource getInputSource()
  -    throws IOException, ProcessingException {
  -        InputStream stream = this.getInputStream();
  -        if ( this.isHTMLContent && null != jtidyClass  ) {
  -            try {
  -                // FIXME (CZ) we need to speed up this!
  -                final Object xhtmlconvert = jtidyClass.newInstance();
  -                Method m = jtidyClass.getMethod("setXmlOut", new Class[] { 
Class.forName("java.lang.Boolean")});
  -                m.invoke(xhtmlconvert, new Object[] { new Boolean(true) });
  -                m = jtidyClass.getMethod("setXHTML", new Class[] 
{Class.forName("java.lang.Boolean")});
  -                m.invoke(xhtmlconvert, new Object[] { new Boolean(true) });
  -                m = jtidyClass.getMethod("setShowWarnings", new Class[] { 
Class.forName("java.lang.Boolean")});
  -                m.invoke(xhtmlconvert, new Object[] { new Boolean(false) });
  -                m = jtidyClass.getMethod("parseDOM", new Class[] { 
Class.forName("java.io.InputStream"), Class.forName("java.io.OutputStream")});
  -                final Document doc = (Document)m.invoke(xhtmlconvert, new Object[] 
{ stream, null });
  -                final StringWriter writer = new StringWriter();
  -                final Transformer transformer;
  -                transformer = transformerFactory.newTransformer();
  -                transformer.setOutputProperties(xmlProperties);
  -                transformer.transform(new DOMSource(doc), new StreamResult(writer));
  -                final String xmlstring = writer.toString();
  -                InputSource newObject = new InputSource(new 
java.io.StringReader(xmlstring));
  -                newObject.setSystemId(this.systemId);
  -                return newObject;
  -            } catch (Exception ignore) {
  -                // Let someone else worry about what we got . This is as before.
  -                this.refresh();
  -                stream = this.getInputStream();
  -            }
  -        }
  -        InputSource newObject = new InputSource(stream);
  -        newObject.setSystemId(this.systemId);
  -        return newObject;
  -    }
  -
  -    /**
  -     * Stream content to a content handler or to an XMLConsumer.
  -     *
  -     * @throws ResourceNotFoundException if file not found or
  -     *         HTTP location does not exist.
  -     * @throws SAXException if failed to parse source document.
  -     */
  -    public void toSAX(ContentHandler handler)
  -    throws SAXException, ProcessingException {
  -        Parser parser = null;
  -        try {
  -            parser = (Parser)this.manager.lookup(Parser.ROLE);
  -
  -            parser.parse( this.getInputSource(), handler);
  -        } catch (SAXException e) {
  -            // Preserve original exception
  -            throw e;
  -        } catch (Exception e){
  -            throw new ProcessingException("Exception during processing of "
  -                                          + this.systemId, e);
  -        } finally {
  -            if (parser != null) this.manager.release(parser);
  -        }
  -    }
  -
  -    public void recycle() {
  -    }
  -
  -    /**
        * Set the post parameters
        */
       public void setPostParameters(SourceParameters pars) {
  @@ -441,5 +347,4 @@
       public void setFollowRedirects(boolean flag) {
           this.followRedirects = flag;
       }
  -
   }
  
  
  
  1.1                  
xml-cocoon2/src/java/org/apache/cocoon/components/source/AbstractStreamSource.java
  
  Index: AbstractStreamSource.java
  ===================================================================
  /*
   * The Apache Software License, Version 1.1
   *
   *
   * Copyright (c) 2001 The Apache Software Foundation.  All rights
   * reserved.
   *
   * Redistribution and use in source and binary forms, with or without
   * modification, are permitted provided that the following conditions
   * are met:
   *
   * 1. Redistributions of source code must retain the above copyright
   *    notice, this list of conditions and the following disclaimer.
   *
   * 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 end-user documentation included with the redistribution,
   *    if any, must include the following acknowledgment:
   *       "This product includes software developed by the
   *        Apache Software Foundation (http://www.apache.org/)."
   *    Alternately, this acknowledgment may appear in the software itself,
   *    if and wherever such third-party acknowledgments normally appear.
   *
   * 4. The names "Apache Cocoon" and "Apache Software Foundation" must
   *    not be used to endorse or promote products derived from this
   *    software without prior written permission. For written
   *    permission, please contact [EMAIL PROTECTED]
   *
   * 5. Products derived from this software may not be called "Apache",
   *    nor may "Apache" appear in their name, without prior written
   *    permission of the Apache Software Foundation.
   *
   * THIS SOFTWARE IS PROVIDED ``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 THE APACHE SOFTWARE FOUNDATION 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.
   * ====================================================================
   *
   * This software consists of voluntary contributions made by many
   * individuals on behalf of the Apache Software Foundation.  For more
   * information on the Apache Software Foundation, please see
   * <http://www.apache.org/>.
   */
  
  package org.apache.cocoon.components.source;
  
  import org.apache.avalon.excalibur.xml.Parser;
  import org.apache.avalon.excalibur.source.SourceParameters;
  import org.apache.avalon.excalibur.source.SourceUtil;
  import org.apache.avalon.framework.component.ComponentManager;
  import org.apache.cocoon.ProcessingException;
  import org.apache.cocoon.environment.ModifiableSource;
  import org.apache.cocoon.util.ClassUtils;
  import org.apache.cocoon.xml.XMLConsumer;
  import org.xml.sax.ContentHandler;
  import org.xml.sax.InputSource;
  import org.xml.sax.SAXException;
  import org.xml.sax.ext.LexicalHandler;
  import org.w3c.dom.Document;
  import java.io.File;
  import java.io.FileInputStream;
  import java.io.FileNotFoundException;
  import java.io.IOException;
  import java.io.InputStream;
  import java.io.StringWriter;
  import java.lang.reflect.Method;
  import java.net.HttpURLConnection;
  import java.net.URLConnection;
  import java.net.URL;
  import java.util.Iterator;
  import java.util.Properties;
  import javax.xml.transform.OutputKeys;
  import javax.xml.transform.Transformer;
  import javax.xml.transform.TransformerFactory;
  import javax.xml.transform.dom.DOMSource;
  import javax.xml.transform.stream.StreamResult;
  
  /**
   * This abstract class provides convenience methods to implement
   * a stream based Source. Implement getInputStream(), getSystemId() and
   * optionally override refresh(), recycle(), getLastModified() and
   * getContentLength() to obtain a valid Source implementation.
   * <p>
   * This base implementation provides services to parse HTML sources
   * (HTML is not valid XML) using JTidy, if present. The source is
   * considered to contain HTML if <code>isHTMLContent()</code> returns
   * true.
   *
   * @author <a href="mailto:[EMAIL PROTECTED]";>Sylvain Wallez</a>
   * @author <a href="mailto:[EMAIL PROTECTED]";>Carsten Ziegeler</a>
   * @version $Id: AbstractStreamSource.java,v 1.1 2002/02/22 23:25:18 sylvain Exp $
   */
  
  public abstract class AbstractStreamSource implements ModifiableSource {
  // FIXME(SW) : this implements *Modifiable*Source just to call refresh()
  //             if JTidy fails. Can we avoid this ?
  
      /** Is JTidy available? */
      private static Class jtidyClass;
  
      /** Properties used for converting HTML to XML */
      private static Properties xmlProperties;
  
      /** The TrAX factory for serializing xml */
      public static TransformerFactory transformerFactory = 
TransformerFactory.newInstance();
  
      /**
       * Test if JTidy is available
       */
      static {
          jtidyClass = null;
          try {
              jtidyClass = ClassUtils.loadClass("org.w3c.tidy.Tidy");
          } catch (ClassNotFoundException cnfe) {
              // ignore
          }
          xmlProperties = new Properties();
          xmlProperties.put(OutputKeys.METHOD, "xml");
          xmlProperties.put(OutputKeys.OMIT_XML_DECLARATION, "no");
      }
  
      /** The ComponentManager needed for streaming */
      protected ComponentManager manager;
  
      /**
       * Construct a new object
       */
      protected AbstractStreamSource(ComponentManager manager) {
          this.manager = manager;
      }
      
      /**
       * Does this source contain HTML ? If true, JTidy will be used (if available) to
       * parse the input as XML.
       * <p>
       * The default here is to return false. Concrete subclasses should override
       * this if needed.
       */
      protected boolean isHTMLContent() {
          return false;
      }
  
      /**
       * Return a new <code>InputSource</code> object
       */
      public InputSource getInputSource() throws IOException, ProcessingException {
          
          InputStream stream = this.getInputStream();
          if (jtidyClass != null && isHTMLContent()) {
              try {
                  // FIXME (CZ) we need to speed up this!
                  final Object xhtmlconvert = jtidyClass.newInstance();
                  Method m = jtidyClass.getMethod("setXmlOut", new Class[] { 
Class.forName("java.lang.Boolean")});
                  m.invoke(xhtmlconvert, new Object[] { new Boolean(true) });
                  m = jtidyClass.getMethod("setXHTML", new Class[] 
{Class.forName("java.lang.Boolean")});
                  m.invoke(xhtmlconvert, new Object[] { new Boolean(true) });
                  m = jtidyClass.getMethod("setShowWarnings", new Class[] { 
Class.forName("java.lang.Boolean")});
                  m.invoke(xhtmlconvert, new Object[] { new Boolean(false) });
                  m = jtidyClass.getMethod("parseDOM", new Class[] { 
Class.forName("java.io.InputStream"), Class.forName("java.io.OutputStream")});
                  final Document doc = (Document)m.invoke(xhtmlconvert, new Object[] { 
stream, null });
                  final StringWriter writer = new StringWriter();
                  final Transformer transformer;
                  transformer = transformerFactory.newTransformer();
                  transformer.setOutputProperties(xmlProperties);
                  transformer.transform(new DOMSource(doc), new StreamResult(writer));
                  final String xmlstring = writer.toString();
                  InputSource newObject = new InputSource(new 
java.io.StringReader(xmlstring));
                  newObject.setSystemId(this.getSystemId());
                  return newObject;
              } catch (Exception ignore) {
                  // Let someone else worry about what we got . This is as before.
                  this.refresh();
                  stream = this.getInputStream();
              }
          }
          InputSource newObject = new InputSource(stream);
          newObject.setSystemId(this.getSystemId());
          return newObject;
      }
  
      /**
       * Stream content to a content handler or to an XMLConsumer.
       *
       * @throws ResourceNotFoundException if file not found or
       *         HTTP location does not exist.
       * @throws SAXException if failed to parse source document.
       */
      public void toSAX(ContentHandler handler) throws SAXException, 
ProcessingException {
          Parser parser = null;
          try {
              parser = (Parser)this.manager.lookup(Parser.ROLE);
  
              parser.parse( this.getInputSource(), handler);
          } catch (SAXException e) {
              // Preserve original exception
              throw e;
          } catch (Exception e){
              throw new ProcessingException("Exception during processing of "
                                            + this.getSystemId(), e);
          } finally {
              if (parser != null) this.manager.release(parser);
          }
      }
      
      /**
       * Override this method to set the Content Length
       *
       */
      public long getContentLength() {
        return -1;
      }
  
      /**
       * Override this method to set the Last Modification date
       *
       */
      public long getLastModified() {
        return 0;
      }
      
      /**
       * To be overriden in concrete subclasses if needed.
       */
      public void recycle() {
      }
      
      /**
       * To be overriden in concrete subclasses if needed.
       */
      public void refresh() {
      }
  }
  
  
  
  1.1                  
xml-cocoon2/src/java/org/apache/cocoon/components/source/AbstractStreamWriteableSource.java
  
  Index: AbstractStreamWriteableSource.java
  ===================================================================
  /*
   * The Apache Software License, Version 1.1
   *
   *
   * Copyright (c) 2001 The Apache Software Foundation.  All rights
   * reserved.
   *
   * Redistribution and use in source and binary forms, with or without
   * modification, are permitted provided that the following conditions
   * are met:
   *
   * 1. Redistributions of source code must retain the above copyright
   *    notice, this list of conditions and the following disclaimer.
   *
   * 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 end-user documentation included with the redistribution,
   *    if any, must include the following acknowledgment:
   *       "This product includes software developed by the
   *        Apache Software Foundation (http://www.apache.org/)."
   *    Alternately, this acknowledgment may appear in the software itself,
   *    if and wherever such third-party acknowledgments normally appear.
   *
   * 4. The names "Apache Cocoon" and "Apache Software Foundation" must
   *    not be used to endorse or promote products derived from this
   *    software without prior written permission. For written
   *    permission, please contact [EMAIL PROTECTED]
   *
   * 5. Products derived from this software may not be called "Apache",
   *    nor may "Apache" appear in their name, without prior written
   *    permission of the Apache Software Foundation.
   *
   * THIS SOFTWARE IS PROVIDED ``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 THE APACHE SOFTWARE FOUNDATION 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.
   * ====================================================================
   *
   * This software consists of voluntary contributions made by many
   * individuals on behalf of the Apache Software Foundation.  For more
   * information on the Apache Software Foundation, please see
   * <http://www.apache.org/>.
   */
  package org.apache.cocoon.components.source;
  
  import org.apache.avalon.framework.component.ComponentException;
  import org.apache.avalon.framework.component.ComponentManager;
  import org.apache.avalon.framework.component.ComponentSelector;
  
  import org.apache.cocoon.environment.WriteableSource;
  import org.apache.cocoon.serialization.Serializer;
  import org.apache.cocoon.xml.AbstractXMLPipe;
  import org.apache.cocoon.ProcessingException;
  
  import org.xml.sax.ContentHandler;
  import org.xml.sax.SAXException;
  
  import java.io.File;
  import java.io.FileInputStream;
  import java.io.FileOutputStream;
  import java.io.FilterOutputStream;
  import java.io.InputStream;
  import java.io.IOException;
  import java.io.OutputStream;
  import java.net.URL;
  
  /**
   * This abstract class provides convenience methods to implement
   * a stream based <code>WriteableSource</code>. Implement getOutputStream()
   * to obtain a valid implementation.
   * <p>
   * This base implementation creates a <code>ContentHandler</code> by using
   * the sitemap 'xml' serializer to write SAX events to the stream returned by
   * <code>getOutputStream()</code>.
   *
   * @author <a href="mailto:[EMAIL PROTECTED]";>Sylvain Wallez</a>
   * @version $Id: AbstractStreamWriteableSource.java,v 1.1 2002/02/22 23:25:18 
sylvain Exp $
   */
  
  public abstract class AbstractStreamWriteableSource extends AbstractStreamSource 
implements WriteableSource {
      
      protected AbstractStreamWriteableSource(ComponentManager manager) {
          super(manager);
      }
  
      /**
       * Get a <code>ContentHandler</code> to write a SAX stream to this source. It
       * uses the 'xml' serializer to serialize events, and thus this serializer
       * must exist in this source's component manager.
       */
      public ContentHandler getContentHandler() throws SAXException, 
ProcessingException {
          
          Serializer serializer;
          
          // Get the serializer
          try {
              ComponentSelector selector =
                  (ComponentSelector)this.manager.lookup(Serializer.ROLE + "Selector");
              serializer = (Serializer)selector.select("xml");
          } catch(ComponentException ce) {
              throw new ProcessingException("Cannot get 'xml' serializer");
          }
          
          // Connect the output stream to the serializer
          final OutputStream output;
          try {
              output = getOutputStream();
              serializer.setOutputStream(getOutputStream());
          } catch(IOException ioe) {
              throw new ProcessingException("Cannot open stream for " + 
this.getSystemId(), ioe);
          }        
          
          // Wrap the serializer in a pipe that will close the output stream
          // at the end of the document
          AbstractXMLPipe result = new AbstractXMLPipe() {
  
              public void endDocument() throws SAXException {
                  super.endDocument();
                  try {
                      output.close();
                  }
                  catch(Exception e) {
                      throw new SAXException("Error while closing output stream", e);
                  }
              }
          };
          
          result.setConsumer(serializer);
          
          return result;
      }
  }
      
  
  
  1.1                  
xml-cocoon2/src/java/org/apache/cocoon/components/source/FileSource.java
  
  Index: FileSource.java
  ===================================================================
  /*
   * The Apache Software License, Version 1.1
   *
   *
   * Copyright (c) 2001 The Apache Software Foundation.  All rights
   * reserved.
   *
   * Redistribution and use in source and binary forms, with or without
   * modification, are permitted provided that the following conditions
   * are met:
   *
   * 1. Redistributions of source code must retain the above copyright
   *    notice, this list of conditions and the following disclaimer.
   *
   * 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 end-user documentation included with the redistribution,
   *    if any, must include the following acknowledgment:
   *       "This product includes software developed by the
   *        Apache Software Foundation (http://www.apache.org/)."
   *    Alternately, this acknowledgment may appear in the software itself,
   *    if and wherever such third-party acknowledgments normally appear.
   *
   * 4. The names "Apache Cocoon" and "Apache Software Foundation" must
   *    not be used to endorse or promote products derived from this
   *    software without prior written permission. For written
   *    permission, please contact [EMAIL PROTECTED]
   *
   * 5. Products derived from this software may not be called "Apache",
   *    nor may "Apache" appear in their name, without prior written
   *    permission of the Apache Software Foundation.
   *
   * THIS SOFTWARE IS PROVIDED ``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 THE APACHE SOFTWARE FOUNDATION 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.
   * ====================================================================
   *
   * This software consists of voluntary contributions made by many
   * individuals on behalf of the Apache Software Foundation.  For more
   * information on the Apache Software Foundation, please see
   * <http://www.apache.org/>.
   */
  package org.apache.cocoon.components.source;
  
  import org.apache.avalon.framework.component.ComponentManager;
  
  import org.apache.cocoon.environment.WriteableSource;
  import org.apache.cocoon.ProcessingException;
  
  import java.io.File;
  import java.io.FileInputStream;
  import java.io.FileOutputStream;
  import java.io.FilterOutputStream;
  import java.io.InputStream;
  import java.io.IOException;
  import java.io.OutputStream;
  
  import java.net.MalformedURLException;
  
  import java.util.ConcurrentModificationException;
  
  /**
   * A <code>WriteableSource</code> for 'file:/' system IDs.
   *
   * @author <a href="mailto:[EMAIL PROTECTED]";>Sylvain Wallez</a>
   * @version $Id: FileSource.java,v 1.1 2002/02/22 23:25:18 sylvain Exp $
   */
  
  public class FileSource extends AbstractStreamWriteableSource implements 
WriteableSource {
      
      /** The underlying file. */
      private File file;
      
      /** The system ID for this source (lazily created by getSystemId()) */
      private String systemId = null;
      
      /** Is this an html file ? */
      private boolean isHTMLContent;
      
      /**
       * Create a file source from a 'file:' url and a component manager.
       */
      public FileSource(String url, ComponentManager manager) {
          
          super(manager);
          
          if (!url.startsWith("file:")) {
              throw new IllegalArgumentException("Malformed url for a file source : " 
+ url);
          }
          
          if (url.endsWith(".htm") || url.endsWith(".html")) {
              this.isHTMLContent = true;
          }
          
          this.file = new File(url.substring(5)); // 5 == "file:".length()
      }
      
      /**
       * Returns <code>true</code> if the file name ends with ".htm" or ".html".
       */
      protected boolean isHTMLContent() {
          return this.isHTMLContent;
      }
      
      /**
       * Return the unique identifer for this source
       */
      public String getSystemId() {
          if (this.systemId == null) {
              try {
                  this.systemId = this.file.toURL().toExternalForm();
              } catch(MalformedURLException mue) {
                  // Can this really happen ?
                  this.systemId = "file:" + this.file.getPath();
              }
          }
          return this.systemId;
      }
  
      /**
       * Get the input stream for this source.
       */
      public InputStream getInputStream() throws IOException, ProcessingException {
          return new FileInputStream(this.file);
      }
      
      public long getLastModified() {
          return this.file.lastModified();
      }
      
      public long getContentLength() {
          return this.file.length();
      }
      
      /**
       * Get an output stream to write to this source. The output stream returned
       * actually writes to a temp file that replaces the real one on close. This
       * temp file is used as lock to forbid multiple simultaneous writes. The
       * real file is updated atomically when the output stream is closed.
       *
       * @throws ConcurrentModificationException if another thread is currently
       *         writing to this file.
       */
      public OutputStream getOutputStream() throws IOException, ProcessingException {
          
          // Create a temp file. It will replace the right one when writing terminates,
          // and serve as a lock to prevent concurrent writes.
          final File tmpFile = new File(this.file.getPath() + ".tmp");
          
          // Ensure the directory exists
          tmpFile.getParentFile().mkdirs();
          
          // Can we write the file ?
          if (this.file.exists() && !this.file.canWrite()) {
              throw new IOException("Cannot write to file " + this.file.getPath());
          }
          
          // Check if it temp file already exists, meaning someone else currently 
writing
          if (!tmpFile.createNewFile()) {
              throw new ConcurrentModificationException("File " + this.file.getPath() +
                " is already being written by another thread");
          }
          
          // Return a stream that will rename the temp file on close.
          return new FilterOutputStream(new FileOutputStream(tmpFile)) {
              boolean closed = false;
  
              public void close() throws IOException {
                  super.close();
  
                  try {
                      // Delete destination file
                      if (FileSource.this.file.exists()) {
                          FileSource.this.file.delete();
                      }
                      // Rename temp file to destination file
                      tmpFile.renameTo(FileSource.this.file);
                      
                  } finally {
                      // Ensure temp file is deleted, ie lock is released.
                      // If there was a failure above, written data is lost.
                      if (tmpFile.exists()) {
                          tmpFile.delete();
                      }
                      this.closed = true;
                  }
              }
              
              public void finalize() {
                  if (!this.closed && tmpFile.exists()) {
                      // Something wrong happened while writing : delete temp file
                      tmpFile.delete();
                  }
              }
          };
      }
  }
      
  
  
  1.1                  
xml-cocoon2/src/java/org/apache/cocoon/components/source/FileSourceFactory.java
  
  Index: FileSourceFactory.java
  ===================================================================
  /*
   * The Apache Software License, Version 1.1
   *
   *
   * Copyright (c) 2001 The Apache Software Foundation.  All rights
   * reserved.
   *
   * Redistribution and use in source and binary forms, with or without
   * modification, are permitted provided that the following conditions
   * are met:
   *
   * 1. Redistributions of source code must retain the above copyright
   *    notice, this list of conditions and the following disclaimer.
   *
   * 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 end-user documentation included with the redistribution,
   *    if any, must include the following acknowledgment:
   *       "This product includes software developed by the
   *        Apache Software Foundation (http://www.apache.org/)."
   *    Alternately, this acknowledgment may appear in the software itself,
   *    if and wherever such third-party acknowledgments normally appear.
   *
   * 4. The names "Apache Cocoon" and "Apache Software Foundation" must
   *    not be used to endorse or promote products derived from this
   *    software without prior written permission. For written
   *    permission, please contact [EMAIL PROTECTED]
   *
   * 5. Products derived from this software may not be called "Apache",
   *    nor may "Apache" appear in their name, without prior written
   *    permission of the Apache Software Foundation.
   *
   * THIS SOFTWARE IS PROVIDED ``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 THE APACHE SOFTWARE FOUNDATION 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.
   * ====================================================================
   *
   * This software consists of voluntary contributions made by many
   * individuals on behalf of the Apache Software Foundation.  For more
   * information on the Apache Software Foundation, please see
   * <http://www.apache.org/>.
   */
  
  package org.apache.cocoon.components.source;
  
  import org.apache.avalon.framework.component.ComponentException;
  import org.apache.avalon.framework.component.ComponentManager;
  import org.apache.avalon.framework.component.Composable;
  import org.apache.avalon.framework.thread.ThreadSafe;
  
  import org.apache.cocoon.components.source.SourceFactory;
  import org.apache.cocoon.environment.Environment;
  import org.apache.cocoon.environment.Source;
  import org.apache.cocoon.ProcessingException;
  
  import java.io.IOException;
  import java.net.MalformedURLException;
  import java.net.URL;
  
  /**
   * A factory for 'file:' sources.
   *
   * @author <a href="mailto:[EMAIL PROTECTED]";>Sylvain Wallez</a>
   * @version $Id: FileSourceFactory.java,v 1.1 2002/02/22 23:25:18 sylvain Exp $
   */
  
  public class FileSourceFactory implements SourceFactory, Composable, ThreadSafe {
      
      private ComponentManager manager;
  
      public void compose(ComponentManager manager) throws ComponentException {
          this.manager = manager;
      }
      
      public Source getSource(Environment environment, String location)
        throws ProcessingException, MalformedURLException, IOException {
          return new FileSource(location, this.manager);
      }
  
      public Source getSource(Environment environment, URL base, String location)
        throws ProcessingException, MalformedURLException, IOException {
          return getSource(environment, new URL(base, location).toExternalForm());
      }
  }
      
  
  
  1.1                  
xml-cocoon2/src/java/org/apache/cocoon/environment/WriteableSource.java
  
  Index: WriteableSource.java
  ===================================================================
  /*
   * The Apache Software License, Version 1.1
   *
   *
   * Copyright (c) 2001 The Apache Software Foundation.  All rights
   * reserved.
   *
   * Redistribution and use in source and binary forms, with or without
   * modification, are permitted provided that the following conditions
   * are met:
   *
   * 1. Redistributions of source code must retain the above copyright
   *    notice, this list of conditions and the following disclaimer.
   *
   * 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 end-user documentation included with the redistribution,
   *    if any, must include the following acknowledgment:
   *       "This product includes software developed by the
   *        Apache Software Foundation (http://www.apache.org/)."
   *    Alternately, this acknowledgment may appear in the software itself,
   *    if and wherever such third-party acknowledgments normally appear.
   *
   * 4. The names "Apache Cocoon" and "Apache Software Foundation" must
   *    not be used to endorse or promote products derived from this
   *    software without prior written permission. For written
   *    permission, please contact [EMAIL PROTECTED]
   *
   * 5. Products derived from this software may not be called "Apache",
   *    nor may "Apache" appear in their name, without prior written
   *    permission of the Apache Software Foundation.
   *
   * THIS SOFTWARE IS PROVIDED ``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 THE APACHE SOFTWARE FOUNDATION 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.
   * ====================================================================
   *
   * This software consists of voluntary contributions made by many
   * individuals on behalf of the Apache Software Foundation.  For more
   * information on the Apache Software Foundation, please see
   * <http://www.apache.org/>.
   */
  
  package org.apache.cocoon.environment;
  
  import java.io.IOException;
  import java.io.OutputStream;
  
  import org.apache.cocoon.ProcessingException;
  
  import org.xml.sax.ContentHandler;
  import org.xml.sax.SAXException;
  
  /**
   * A {@link Source} that can be written to. It provides two methods that
   * allow for SAX-based and byte-based output.
   * <p>
   * Callers will use the most appropriate method for their use and
   * it's up to the implementation to handle both sources. For example,
   * an XML-based implementation can use a parser to convert bytes written
   * to the <code>OutputStream</code> to SAX events, and a byte-based
   * implementation (such as file), can use a serializer to convert
   * SAX events to a byte stream.
   *
   * @author <a href="[EMAIL PROTECTED]">Sylvain Wallez</a>
   * @version CVS $Id: WriteableSource.java,v 1.1 2002/02/22 23:25:19 sylvain Exp $
   */
  public interface WriteableSource extends ModifiableSource {
  
  //FIXME(SW) : should this be also Parameterizable to accept more parameters
  // such as user/password, headers, etc ?
  
      /**
       * Get a <code>ContentHandler</code> where an XML document can
       * be written using SAX events.
       * <p>
       * Care should be taken that the returned handler can actually
       * be a {@link org.apache.cocoon.xml.XMLConsumer} supporting also
       * lexical events such as comments.
       *
       * @return a handler for SAX events
       */
      ContentHandler getContentHandler() throws SAXException, ProcessingException;
      
      /**
       * Get an <code>InputStream</code> where raw bytes can be written to.
       * The signification of these bytes is implementation-dependent and
       * is not restricted to a serialized XML document.
       *
       * @return a stream to write to
       */ 
      OutputStream getOutputStream() throws IOException, ProcessingException;
      
  }
  
  
  1.2       +3 -0      xml-cocoon2/src/java/org/apache/cocoon/generation/xmldb.xconf
  
  Index: xmldb.xconf
  ===================================================================
  RCS file: /home/cvs/xml-cocoon2/src/java/org/apache/cocoon/generation/xmldb.xconf,v
  retrieving revision 1.1
  retrieving revision 1.2
  diff -u -r1.1 -r1.2
  --- xmldb.xconf       11 Feb 2002 16:39:26 -0000      1.1
  +++ xmldb.xconf       22 Feb 2002 23:25:19 -0000      1.2
  @@ -4,6 +4,9 @@
       sitemap components.
     -->
     <source-handler logger="core.source-handler">
  +    <!-- file protocol : this is a WriteableSource -->
  +    <protocol name="file" 
class="org.apache.cocoon.components.source.FileSourceFactory"/>
  +
       <!-- xmldb pseudo protocol -->
       <protocol name="xmldb" 
class="org.apache.cocoon.components.source.XMLDBSourceFactory">
         <!-- dbXML driver -->
  
  
  
  1.5       +41 -9     xml-cocoon2/src/java/org/apache/cocoon/xml/XMLUtils.java
  
  Index: XMLUtils.java
  ===================================================================
  RCS file: /home/cvs/xml-cocoon2/src/java/org/apache/cocoon/xml/XMLUtils.java,v
  retrieving revision 1.4
  retrieving revision 1.5
  diff -u -r1.4 -r1.5
  --- XMLUtils.java     22 Feb 2002 07:03:58 -0000      1.4
  +++ XMLUtils.java     22 Feb 2002 23:25:19 -0000      1.5
  @@ -52,25 +52,28 @@
   
   import java.util.ArrayList;
   
  -import org.w3c.dom.NodeList;
  -import org.w3c.dom.Node;
  -import org.w3c.dom.Element;
   import org.w3c.dom.Attr;
   import org.w3c.dom.Document;
  +import org.w3c.dom.Element;
  +import org.w3c.dom.Node;
   import org.w3c.dom.NamedNodeMap;
  +import org.w3c.dom.NodeList;
  +
  +import org.xml.sax.ContentHandler;
  +import org.xml.sax.ext.LexicalHandler;
   
   /**
  - * XML utility methods
  + * XML utility methods.
    *
    * @author <a href="mailto:[EMAIL PROTECTED]";>Nicola Ken Barozzi</a>
  - * @version CVS $Id: XMLUtils.java,v 1.4 2002/02/22 07:03:58 cziegeler Exp $
  - * @created 18 January 2002
  + * @author <a href="mailto:[EMAIL PROTECTED]";>Sylvain Wallez</a>
  + * @version CVS $Id: XMLUtils.java,v 1.5 2002/02/22 23:25:19 sylvain Exp $
    */
   public class XMLUtils{
   
  -   //using parent because some dom implementations like jtidy are bugged,
  -   //cannot get parent or delete child
  -   public static void stripDuplicateAttributes(Node node, Node parent) {
  +    //using parent because some dom implementations like jtidy are bugged,
  +    //cannot get parent or delete child
  +    public static void stripDuplicateAttributes(Node node, Node parent) {
           // The output depends on the type of the node
           switch(node.getNodeType()) {
           case Node.DOCUMENT_NODE: {
  @@ -127,5 +130,34 @@
               //do nothing
               break;
           }
  +    }
  +    
  +    /**
  +     * Get an <code>XMLConsumer</code> from a <code>ContentHandler</code> and
  +     * a <code>LexicalHandler</code>. If the content handler is already an
  +     * <code>XMLConsumer</code>, it is returned as is, otherwise it is wrapped
  +     * in an <code>XMLConsumer</code> with the lexical handler.
  +     *
  +     * @param ch the content handler, which should not be <code>null</code>
  +     * @param lh the lexical handler, which can be <code>null</code>
  +     * @return an <code>XMLConsumer</code> for <code>ch</code> an <code>lh</code>
  +     */
  +    public static XMLConsumer getConsumer(ContentHandler ch, LexicalHandler lh) {
  +        if (ch instanceof XMLConsumer)
  +          return (XMLConsumer)ch;
  +        else
  +          return new ContentHandlerWrapper(ch, lh);
  +    }
  +    
  +    /**
  +     * Get an <code>XMLConsumer</code> from <code>ContentHandler</code>. If the
  +     * content handler is already an <code>XMLConsumer</code>, it is returned as
  +     * is, otherwise it is wrapped in an <code>XMLConsumer</code>.
  +     *
  +     * @param ch the content handler, which should not be <code>null</code>
  +     * @return an <code>XMLConsumer</code> for <code>ch</code>
  +     */
  +    public static XMLConsumer getConsumer(ContentHandler ch) {
  +        return getConsumer(ch, null);
       }
   }
  
  
  

----------------------------------------------------------------------
In case of troubles, e-mail:     [EMAIL PROTECTED]
To unsubscribe, e-mail:          [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]

Reply via email to