cziegeler 02/05/08 00:03:59
Modified: src/scratchpad/src/org/apache/cocoon/transformation
SourceWritingTransformer.java
src/webapp/WEB-INF cocoon.xconf
Added: src/java/org/apache/cocoon/components/source/impl
FileSource.java FileSourceFactory.java
Log:
Added Writeable support for files
Revision Changes Path
1.1
xml-cocoon2/src/java/org/apache/cocoon/components/source/impl/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.impl;
import org.apache.excalibur.source.SourceException;
import org.apache.excalibur.source.impl.URLSource;
import org.apache.cocoon.components.source.WriteableSource;
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.net.URL;
import java.util.ConcurrentModificationException;
import java.util.Map;
/**
* A <code>org.apache.cocoon.components.source.WriteableSource</code>
* for 'file:/' system IDs.
*
* @author <a href="mailto:[EMAIL PROTECTED]">Sylvain Wallez</a>
* @version $Id: FileSource.java,v 1.1 2002/05/08 07:03:58 cziegeler Exp $
*/
public class FileSource
extends URLSource
implements WriteableSource {
/** The underlying file. */
protected File file;
/**
* Initialize a new object from a <code>URL</code>.
* @param parameters This is optional
*/
public void init(URL url,
Map parameters )
throws IOException {
super.init( url, parameters );
if (!isFile) {
throw new IllegalArgumentException("Malformed url for a file
source : " + url);
}
this.file = new File(this.systemId.substring(5)); // 5 ==
"file:".length()
}
/**
* A file outputStream that will rename the temp file to the destination
file upon close()
* and discard the temp file upon cancel().
*/
private class FileSourceOutputStream extends FileOutputStream {
private File tmpFile;
private boolean isClosed = false;
public FileSourceOutputStream(File tmpFile) throws IOException {
super(tmpFile);
this.tmpFile = tmpFile;
}
public FileSource getSource() {
return FileSource.this;
}
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.isClosed = true;
}
}
public boolean canCancel() {
return !this.isClosed;
}
public void cancel() throws Exception {
if (this.isClosed) {
throw new IllegalStateException("Cannot cancel : outputstrem
is already closed");
}
this.isClosed = true;
super.close();
this.tmpFile.delete();
}
public void finalize() {
if (!this.isClosed && tmpFile.exists()) {
// Something wrong happened while writing : delete temp file
tmpFile.delete();
}
}
}
/**
* Does this source actually exist ?
*
* @return true if the resource exists.
*/
public boolean exists() {
return this.file.exists();
}
/**
* 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.
*
* 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.
*
* @return a stream to write to
* @throws ConcurrentModificationException if another thread is currently
* writing to this file.
*/
public OutputStream getOutputStream()
throws IOException, SourceException {
// Create a temp file. It will replace the right one when writing
terminates,
// and serve as a lock to prevent concurrent writes.
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 FileSourceOutputStream(tmpFile);
}
/**
* Can the data sent to an <code>OutputStream</code> returned by
* [EMAIL PROTECTED] #getOutputStream()} be cancelled ?
*
* @return true if the stream can be cancelled
*/
public boolean canCancel(OutputStream stream) {
if (stream instanceof FileSourceOutputStream) {
FileSourceOutputStream fsos = (FileSourceOutputStream)stream;
if (fsos.getSource() == this) {
return fsos.canCancel();
}
}
// Not a valid stream for this source
throw new IllegalArgumentException("The stream is not associated to
this source");
}
/**
* Cancel the data sent to an <code>OutputStream</code> returned by
* [EMAIL PROTECTED] #getOutputStream()}.
* <p>
* After cancel, the stream should no more be used.
*/
public void cancel(OutputStream stream) throws SourceException {
if (stream instanceof FileSourceOutputStream) {
FileSourceOutputStream fsos = (FileSourceOutputStream)stream;
if (fsos.getSource() == this) {
try {
fsos.cancel();
} catch (Exception e) {
throw new SourceException("Exception during cancel.", e);
}
return;
}
}
// Not a valid stream for this source
throw new IllegalArgumentException("The stream is not associated to
this source");
}
}
1.1
xml-cocoon2/src/java/org/apache/cocoon/components/source/impl/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.impl;
import org.apache.avalon.framework.logger.AbstractLogEnabled;
import org.apache.avalon.framework.thread.ThreadSafe;
import org.apache.excalibur.source.Source;
import org.apache.excalibur.source.SourceFactory;
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.Map;
/**
* A factory for 'file:' sources.
*
* @author <a href="mailto:[EMAIL PROTECTED]">Sylvain Wallez</a>
* @version $Id: FileSourceFactory.java,v 1.1 2002/05/08 07:03:58 cziegeler
Exp $
*/
public class FileSourceFactory
extends AbstractLogEnabled
implements SourceFactory, ThreadSafe {
/**
* Get a <code>Source</code> object.
* @param parameters This is optional.
*/
public Source getSource( String location, Map parameters )
throws MalformedURLException, IOException
{
if( this.getLogger().isDebugEnabled() )
{
this.getLogger().debug( "Creating source object for " + location
);
}
final FileSource source = new FileSource();
source.init( new URL(location), parameters );
return source;
}
}
1.5 +14 -5
xml-cocoon2/src/scratchpad/src/org/apache/cocoon/transformation/SourceWritingTransformer.java
Index: SourceWritingTransformer.java
===================================================================
RCS file:
/home/cvs/xml-cocoon2/src/scratchpad/src/org/apache/cocoon/transformation/SourceWritingTransformer.java,v
retrieving revision 1.4
retrieving revision 1.5
diff -u -r1.4 -r1.5
--- SourceWritingTransformer.java 7 May 2002 08:17:46 -0000 1.4
+++ SourceWritingTransformer.java 8 May 2002 07:03:59 -0000 1.5
@@ -64,7 +64,8 @@
import org.apache.cocoon.caching.CacheValidity;
import org.apache.cocoon.caching.Cacheable;
import org.apache.cocoon.environment.SourceResolver;
-import org.apache.cocoon.environment.WriteableSource;
+import org.apache.cocoon.components.source.WriteableSource;
+import org.apache.cocoon.components.source.WriteableSAXSource;
import org.apache.cocoon.ProcessingException;
import org.apache.cocoon.ResourceNotFoundException;
import org.apache.cocoon.webapps.session.connector.ResourceConnector;
@@ -407,7 +408,7 @@
}
} else {
this.message = "could not get a ContentHandler";
- this.ch = (XMLConsumer)wsource.getContentHandler();
+ this.ch =
(XMLConsumer)((WriteableSAXSource)wsource).getContentHandler();
}
this.addRecorder( this.ch );
this.startDocument();
@@ -417,7 +418,11 @@
getLogger().warn("failed, " + this.message, e);
this.failed = true;
try {
- this.wsource.cancel(this.ch);
+ if (this.isSerializer) {
+ this.wsource.cancel(this.os);
+ } else {
+ ((WriteableSAXSource)this.wsource).cancel(this.ch);
+ }
} catch (Exception e2) {
getLogger().warn("failed to cancel: " + this.target, e2);
this.message += " and failed to cancel";
@@ -536,7 +541,11 @@
this.failed = true;
try {
this.message = "Failed to cancel source";
- this.wsource.cancel(this.ch);
+ if (this.isSerializer) {
+ this.wsource.cancel(this.os);
+ } else {
+
((WriteableSAXSource)this.wsource).cancel(this.ch);
+ }
} catch (Exception e2) {
getLogger().warn("failed to cancel: " + this.target,
e2);
}
@@ -591,7 +600,7 @@
}
} else if (this.ch != null) {
try {
- this.wsource.cancel(this.ch);
+ ((WriteableSAXSource)this.wsource).cancel(this.ch);
} catch (Exception e) {
getLogger().error("failed to cancel in recycle() method:
ContentHandler");
}
1.20 +2 -0 xml-cocoon2/src/webapp/WEB-INF/cocoon.xconf
Index: cocoon.xconf
===================================================================
RCS file: /home/cvs/xml-cocoon2/src/webapp/WEB-INF/cocoon.xconf,v
retrieving revision 1.19
retrieving revision 1.20
diff -u -r1.19 -r1.20
--- cocoon.xconf 7 May 2002 10:37:17 -0000 1.19
+++ cocoon.xconf 8 May 2002 07:03:59 -0000 1.20
@@ -178,6 +178,8 @@
<component-instance
class="org.apache.excalibur.source.impl.ResourceSourceFactory" name="resource"/>
<component-instance
class="org.apache.cocoon.components.source.impl.ContextSourceFactory"
name="context"/>
<component-instance
class="org.apache.cocoon.components.source.impl.CocoonSourceFactory"
name="cocoon"/>
+ <!-- file protocol : this is a WriteableSource -->
+ <component-instance
class="org.apache.cocoon.components.source.impl.FileSourceFactory" name="file"
/>
</source-factories>
<!-- The XMLizer converts different mime-types to XML -->
----------------------------------------------------------------------
In case of troubles, e-mail: [EMAIL PROTECTED]
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]