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]