You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@camel.apache.org by da...@apache.org on 2009/01/24 15:05:37 UTC

svn commit: r737359 [1/2] - in /camel/trunk/camel-core/src: main/java/org/apache/camel/component/file/ main/java/org/apache/camel/component/file/strategy/ main/resources/META-INF/services/org/apache/camel/ test/java/org/apache/camel/component/file/

Author: davsclaus
Date: Sat Jan 24 14:05:36 2009
New Revision: 737359

URL: http://svn.apache.org/viewvc?rev=737359&view=rev
Log:
CAMEL-1241: Generic VFS improved. Work in progress.

Added:
    camel/trunk/camel-core/src/main/java/org/apache/camel/component/file/NewFileComponent.java   (with props)
    camel/trunk/camel-core/src/main/java/org/apache/camel/component/file/NewFileConsumer.java   (with props)
    camel/trunk/camel-core/src/main/java/org/apache/camel/component/file/NewFileEndpoint.java   (with props)
    camel/trunk/camel-core/src/main/java/org/apache/camel/component/file/NewFileOperations.java   (with props)
    camel/trunk/camel-core/src/main/java/org/apache/camel/component/file/strategy/GenericFileDefaultRenamer.java   (with props)
    camel/trunk/camel-core/src/main/java/org/apache/camel/component/file/strategy/GenericFileDeleteProcessStrategy.java   (with props)
    camel/trunk/camel-core/src/main/java/org/apache/camel/component/file/strategy/GenericFileExpressionRenamer.java   (with props)
    camel/trunk/camel-core/src/main/java/org/apache/camel/component/file/strategy/GenericFileNoOpProcessStrategy.java   (with props)
    camel/trunk/camel-core/src/main/java/org/apache/camel/component/file/strategy/GenericFileProcessStrategyFactory.java   (with props)
    camel/trunk/camel-core/src/main/java/org/apache/camel/component/file/strategy/GenericFileProcessStrategySupport.java   (with props)
    camel/trunk/camel-core/src/main/java/org/apache/camel/component/file/strategy/GenericFileRenameExclusiveReadLockStrategy.java   (with props)
    camel/trunk/camel-core/src/main/java/org/apache/camel/component/file/strategy/GenericFileRenameProcessStrategy.java   (with props)
    camel/trunk/camel-core/src/main/java/org/apache/camel/component/file/strategy/GenericFileRenamer.java   (with props)
    camel/trunk/camel-core/src/test/java/org/apache/camel/component/file/NewFileConsumeTest.java   (with props)
    camel/trunk/camel-core/src/test/java/org/apache/camel/component/file/NewFileProduceTest.java   (with props)
Modified:
    camel/trunk/camel-core/src/main/java/org/apache/camel/component/file/GenericFile.java
    camel/trunk/camel-core/src/main/java/org/apache/camel/component/file/GenericFileComponent.java
    camel/trunk/camel-core/src/main/java/org/apache/camel/component/file/GenericFileConsumer.java
    camel/trunk/camel-core/src/main/java/org/apache/camel/component/file/GenericFileConverter.java
    camel/trunk/camel-core/src/main/java/org/apache/camel/component/file/GenericFileEndpoint.java
    camel/trunk/camel-core/src/main/java/org/apache/camel/component/file/GenericFileExchange.java
    camel/trunk/camel-core/src/main/java/org/apache/camel/component/file/GenericFileOperations.java
    camel/trunk/camel-core/src/main/java/org/apache/camel/component/file/GenericFileProducer.java
    camel/trunk/camel-core/src/main/resources/META-INF/services/org/apache/camel/TypeConverter

Modified: camel/trunk/camel-core/src/main/java/org/apache/camel/component/file/GenericFile.java
URL: http://svn.apache.org/viewvc/camel/trunk/camel-core/src/main/java/org/apache/camel/component/file/GenericFile.java?rev=737359&r1=737358&r2=737359&view=diff
==============================================================================
--- camel/trunk/camel-core/src/main/java/org/apache/camel/component/file/GenericFile.java (original)
+++ camel/trunk/camel-core/src/main/java/org/apache/camel/component/file/GenericFile.java Sat Jan 24 14:05:36 2009
@@ -16,15 +16,13 @@
  */
 package org.apache.camel.component.file;
 
-import java.io.OutputStream;
-
 import org.apache.camel.util.ObjectHelper;
 
 /**
  * Generic File. Specific implementations of a file based endpoint need to
  * provide a File for transfer.
  */
-public abstract class GenericFile<T> {
+public class GenericFile<T> {
 
     private String absoluteFileName;
     private String relativeFileName;
@@ -32,11 +30,7 @@
     private long fileLength;
     private long lastModified;
     private T file;
-    private OutputStream body;
-
-    public GenericFile() {
-        super();
-    }
+    private Object body;
 
     @Override
     public GenericFile<T> clone() {
@@ -50,7 +44,7 @@
      * @return a clone of the source
      */
     public GenericFile<T> copyFrom(GenericFile<T> source) {
-        GenericFile<T> result = null;
+        GenericFile<T> result;
         try {
             result = source.getClass().newInstance();
         } catch (Exception e) {
@@ -123,11 +117,11 @@
         this.file = file;
     }
 
-    public OutputStream getBody() {
+    public Object getBody() {
         return body;
     }
 
-    public void setBody(OutputStream os) {
+    public void setBody(Object os) {
         this.body = os;
     }
 

Modified: camel/trunk/camel-core/src/main/java/org/apache/camel/component/file/GenericFileComponent.java
URL: http://svn.apache.org/viewvc/camel/trunk/camel-core/src/main/java/org/apache/camel/component/file/GenericFileComponent.java?rev=737359&r1=737358&r2=737359&view=diff
==============================================================================
--- camel/trunk/camel-core/src/main/java/org/apache/camel/component/file/GenericFileComponent.java (original)
+++ camel/trunk/camel-core/src/main/java/org/apache/camel/component/file/GenericFileComponent.java Sat Jan 24 14:05:36 2009
@@ -28,7 +28,7 @@
 /**
  * Base class file component. To be extended.
  */
-public abstract class GenericFileComponent extends DefaultComponent {
+public abstract class GenericFileComponent<T> extends DefaultComponent {
 
     public GenericFileComponent() {
     }
@@ -37,14 +37,13 @@
         super(context);
     }
 
-    protected GenericFileEndpoint createEndpoint(String uri, String remaining, Map parameters) throws Exception {
+    protected GenericFileEndpoint<T> createEndpoint(String uri, String remaining, Map parameters) throws Exception {
 
         // create the correct endpoint based on the protocol
-        final GenericFileEndpoint endpoint;
-
+        final GenericFileEndpoint<T> endpoint;
 
         // call to subclasses to build their custom version of a GenericFileEndpoint
-        endpoint = buildFileEndpoint(uri);
+        endpoint = buildFileEndpoint(uri, remaining, parameters);
 
         // sort by using file language
         String sortBy = getAndRemoveParameter(parameters, "sortBy", String.class);
@@ -58,16 +57,22 @@
         setProperties(endpoint.getConfiguration(), parameters);
         setProperties(endpoint, parameters);
 
+        afterPropertiesSet(endpoint);
+
         return endpoint;
     }
 
     /**
      * File Components implements this method
+     */
+    protected abstract GenericFileEndpoint<T> buildFileEndpoint(String uri, String remaining, Map parameters) throws Exception;
+
+    /**
+     * File Components implements this method
      *
-     * @param uri uri we are building from
-     * @return GenericFileEndpoint
+     * @param endpoint the newly created endpoint to do some custom post configuration
      */
-    protected abstract GenericFileEndpoint buildFileEndpoint(String uri) throws Exception;
+    protected abstract void afterPropertiesSet(GenericFileEndpoint<T> endpoint) throws Exception;
 
     /**
      * Helper to create a sort comparator

Modified: camel/trunk/camel-core/src/main/java/org/apache/camel/component/file/GenericFileConsumer.java
URL: http://svn.apache.org/viewvc/camel/trunk/camel-core/src/main/java/org/apache/camel/component/file/GenericFileConsumer.java?rev=737359&r1=737358&r2=737359&view=diff
==============================================================================
--- camel/trunk/camel-core/src/main/java/org/apache/camel/component/file/GenericFileConsumer.java (original)
+++ camel/trunk/camel-core/src/main/java/org/apache/camel/component/file/GenericFileConsumer.java Sat Jan 24 14:05:36 2009
@@ -16,8 +16,6 @@
  */
 package org.apache.camel.component.file;
 
-import java.io.ByteArrayOutputStream;
-import java.io.OutputStream;
 import java.util.ArrayList;
 import java.util.Collections;
 import java.util.List;
@@ -33,13 +31,13 @@
 /**
  * Base class for remote file consumers.
  */
-public abstract class GenericFileConsumer extends ScheduledPollConsumer {
+public abstract class GenericFileConsumer<T> extends ScheduledPollConsumer {
     protected final transient Log log = LogFactory.getLog(getClass());
-    protected GenericFileEndpoint endpoint;
-    protected GenericFileOperations operations;
+    protected GenericFileEndpoint<T> endpoint;
+    protected GenericFileOperations<T> operations;
     protected boolean loggedIn;
 
-    public GenericFileConsumer(GenericFileEndpoint endpoint, Processor processor, GenericFileOperations operations) {
+    public GenericFileConsumer(GenericFileEndpoint<T> endpoint, Processor processor, GenericFileOperations<T> operations) {
         super(endpoint, processor);
         this.endpoint = endpoint;
         this.operations = operations;
@@ -55,7 +53,7 @@
         prePollCheck();
 
         // gather list of files to process
-        List<GenericFile> files = new ArrayList<GenericFile>();
+        List<GenericFile<T>> files = new ArrayList<GenericFile<T>>();
 
         String name = endpoint.getConfiguration().getFile();
         boolean isDirectory = endpoint.getConfiguration().isDirectory();
@@ -73,9 +71,9 @@
         // sort using build in sorters that is expression based
         // first we need to convert to RemoteFileExchange objects so we can sort
         // using expressions
-        List<GenericFileExchange> exchanges = new ArrayList<GenericFileExchange>(files.size());
-        for (GenericFile file : files) {
-            GenericFileExchange exchange = endpoint.createExchange(file);
+        List<GenericFileExchange<T>> exchanges = new ArrayList<GenericFileExchange<T>>(files.size());
+        for (GenericFile<T> file : files) {
+            GenericFileExchange<T> exchange = endpoint.createExchange(file);
             endpoint.configureMessage(file, exchange.getIn());
             exchanges.add(exchange);
         }
@@ -90,7 +88,7 @@
             log.debug("Total " + total + " files to consume");
         }
         for (int index = 0; index < total; index++) {
-            GenericFileExchange exchange = exchanges.get(index);
+            GenericFileExchange<T> exchange = exchanges.get(index);
             // add current index and total as headers
             exchange.getIn().setHeader(FileComponent.HEADER_FILE_BATCH_INDEX, index);
             exchange.getIn().setHeader(FileComponent.HEADER_FILE_BATCH_TOTAL, total);
@@ -111,7 +109,7 @@
      * @param fileName current directory or file
      * @param fileList current list of files gathered
      */
-    protected abstract void pollDirectory(String fileName, List<GenericFile> fileList);
+    protected abstract void pollDirectory(String fileName, List<GenericFile<T>> fileList);
 
     /**
      * Polls the given file
@@ -119,14 +117,22 @@
      * @param fileName the file name
      * @param fileList current list of files gathered
      */
-    protected abstract void pollFile(String fileName, List<GenericFile> fileList);
+    protected abstract void pollFile(String fileName, List<GenericFile<T>> fileList);
+
+    /**
+     * Creates a GenericFile based on the given type T.
+     *
+     * @param file the concrete file type
+     * @return a new generic file representing the type
+     */
+    protected abstract GenericFile<T> asGenericFile(T file);
 
     /**
      * Processes the exchange
      *
      * @param exchange the exchange
      */
-    protected void processExchange(final GenericFileExchange exchange) {
+    protected void processExchange(final GenericFileExchange<T> exchange) {
         if (log.isTraceEnabled()) {
             log.trace("Processing remote file: " + exchange.getGenericFile());
         }
@@ -138,7 +144,7 @@
 
                 // must use file from exchange as it can be updated due the
                 // preMoveNamePrefix/preMoveNamePostfix options
-                final GenericFile target = exchange.getGenericFile();
+                final GenericFile<T> target = exchange.getGenericFile();
                 // must use full name when downloading so we have the correct path
                 final String name = target.getAbsoluteFileName();
 
@@ -147,9 +153,7 @@
                     log.trace("Retreiving file: " + name + " from: " + endpoint);
                 }
 
-                OutputStream os = new ByteArrayOutputStream();
-                target.setBody(os);
-                operations.retrieveFile(name, os);
+                operations.retrieveFile(target.getFile(), name, exchange);
 
                 if (log.isTraceEnabled()) {
                     log.trace("Retrieved file: " + name + " from: " + endpoint);
@@ -162,10 +166,9 @@
                 // the exchange can happen asynchronously
                 getAsyncProcessor().process(exchange, new AsyncCallback() {
                     public void done(boolean sync) {
-                        final GenericFile file = exchange.getGenericFile();
+                        final GenericFile<T> file = exchange.getGenericFile();
                         boolean failed = exchange.isFailed();
-                        boolean handled = DeadLetterChannel
-                                .isFailureHandled(exchange);
+                        boolean handled = DeadLetterChannel.isFailureHandled(exchange);
 
                         if (log.isDebugEnabled()) {
                             log.debug("Done processing file: " + file.getAbsoluteFileName() + ". Status is: "
@@ -175,14 +178,11 @@
                         boolean committed = false;
                         try {
                             if (!failed || handled) {
-                                // commit the file strategy if there was no
-                                // failure or already handled by the
-                                // DeadLetterChannel
+                                // commit the file strategy if there was no failure or already handled by the DeadLetterChannel
                                 processStrategyCommit(processStrategy, exchange, file, handled);
                                 committed = true;
                             } else {
-                                // there was an exception but it was not handled
-                                // by the DeadLetterChannel
+                                // there was an exception but it was not handled by the DeadLetterChannel
                                 handleException(exchange.getException());
                             }
                         } finally {
@@ -212,7 +212,7 @@
      *                        was handled by the failure processor (usually the DeadLetterChannel).
      */
     protected void processStrategyCommit(GenericFileProcessStrategy processStrategy,
-                                         GenericFileExchange exchange, GenericFile file, boolean failureHandled) {
+                                         GenericFileExchange exchange, GenericFile<T> file, boolean failureHandled) {
         if (endpoint.isIdempotent()) {
             // only add to idempotent repository if we could process the file
             // use file.getAbsoluteFileName as key for the idempotent repository
@@ -241,7 +241,7 @@
      * @param file            the file processed
      */
     protected void processStrategyRollback(GenericFileProcessStrategy processStrategy,
-                                           GenericFileExchange exchange, GenericFile file) {
+                                           GenericFileExchange exchange, GenericFile<T> file) {
         if (log.isDebugEnabled()) {
             log.debug("Rolling back remote file strategy: " + processStrategy + " for file: " + file);
         }
@@ -256,7 +256,7 @@
      * @param isDirectory wether the file is a directory or a file
      * @return <tt>true</tt> to include the file, <tt>false</tt> to skip it
      */
-    protected boolean isValidFile(GenericFile file, boolean isDirectory) {
+    protected boolean isValidFile(GenericFile<T> file, boolean isDirectory) {
         if (!isMatched(file, isDirectory)) {
             if (log.isTraceEnabled()) {
                 log.trace("Remote file did not match. Will skip this remote file: " + file);
@@ -290,7 +290,7 @@
      * @return <tt>true</tt> if the remote file is matched, <tt>false</tt> if
      *         not
      */
-    protected boolean isMatched(GenericFile file, boolean isDirectory) {
+    protected boolean isMatched(GenericFile<T> file, boolean isDirectory) {
         String name = file.getFileName();
 
         // folders/names starting with dot is always skipped (eg. ".", ".camel", ".camelLock")

Modified: camel/trunk/camel-core/src/main/java/org/apache/camel/component/file/GenericFileConverter.java
URL: http://svn.apache.org/viewvc/camel/trunk/camel-core/src/main/java/org/apache/camel/component/file/GenericFileConverter.java?rev=737359&r1=737358&r2=737359&view=diff
==============================================================================
--- camel/trunk/camel-core/src/main/java/org/apache/camel/component/file/GenericFileConverter.java (original)
+++ camel/trunk/camel-core/src/main/java/org/apache/camel/component/file/GenericFileConverter.java Sat Jan 24 14:05:36 2009
@@ -20,7 +20,6 @@
 import java.io.ByteArrayOutputStream;
 import java.io.IOException;
 import java.io.InputStream;
-import java.io.OutputStream;
 
 import org.apache.camel.Converter;
 import org.apache.camel.Exchange;
@@ -62,8 +61,7 @@
 
     @Converter
     public static String toString(GenericFile file, Exchange exchange) throws IOException {
-        OutputStream os = file.getBody();
-        return os != null ? os.toString() : null;
+        return exchange.getContext().getTypeConverter().convertTo(String.class, file.getBody());
     }
 
 }

Modified: camel/trunk/camel-core/src/main/java/org/apache/camel/component/file/GenericFileEndpoint.java
URL: http://svn.apache.org/viewvc/camel/trunk/camel-core/src/main/java/org/apache/camel/component/file/GenericFileEndpoint.java?rev=737359&r1=737358&r2=737359&view=diff
==============================================================================
--- camel/trunk/camel-core/src/main/java/org/apache/camel/component/file/GenericFileEndpoint.java (original)
+++ camel/trunk/camel-core/src/main/java/org/apache/camel/component/file/GenericFileEndpoint.java Sat Jan 24 14:05:36 2009
@@ -27,6 +27,7 @@
 import org.apache.camel.Expression;
 import org.apache.camel.Message;
 import org.apache.camel.Processor;
+import org.apache.camel.component.file.strategy.GenericFileProcessStrategyFactory;
 import org.apache.camel.impl.ScheduledPollEndpoint;
 import org.apache.camel.language.simple.FileLanguage;
 import org.apache.camel.spi.IdempotentRepository;
@@ -39,7 +40,7 @@
 /**
  * Generic Endpoint
  */
-public abstract class GenericFileEndpoint extends ScheduledPollEndpoint {
+public abstract class GenericFileEndpoint<T> extends ScheduledPollEndpoint {
 
     protected static final transient String DEFAULT_STRATEGYFACTORY_CLASS = "org.apache.camel.component.file.strategy.GenericFileProcessStrategyFactory";
     protected static final transient int DEFAULT_IDEMPOTENT_CACHE_SIZE = 1000;
@@ -50,6 +51,13 @@
     protected GenericFileOperations operations;
     protected GenericFileConfiguration configuration;
 
+    // TODO: Consider remove setNames
+    // TODO: Consider filename should always be specified when producing (to get rid of auto generating with id as filename)
+    // TODO: bufferSize & append can be moved to NewFileEndpoint as FTP does not support it
+    protected boolean directory = true;
+    protected boolean autoCreate = true;
+    protected int bufferSize = 128 * 1024;
+    protected boolean append = true;
     protected boolean noop;
     protected String tempPrefix;
     protected String moveNamePrefix;
@@ -67,7 +75,7 @@
     protected boolean idempotent;
     protected IdempotentRepository idempotentRepository;
     protected GenericFileFilter filter;
-    protected Comparator<GenericFile> sorter;
+    protected Comparator<GenericFile<T>> sorter;
     protected Comparator<GenericFileExchange> sortBy;
     protected String readLock = "none";
     protected long readLockTimeout;
@@ -93,13 +101,12 @@
         return true;
     }
 
-    public abstract GenericFileConsumer createConsumer(Processor processor) throws Exception;
+    public abstract GenericFileConsumer<T> createConsumer(Processor processor) throws Exception;
 
-    public abstract GenericFileProducer createProducer() throws Exception;
+    public abstract GenericFileProducer<T> createProducer() throws Exception;
 
-    public abstract GenericFileExchange createExchange(GenericFile file);
+    public abstract GenericFileExchange<T> createExchange(GenericFile<T> file);
 
-    public abstract GenericFileExchange createExchange();
 
     /**
      * Returns the first portion of the "protocol" in use. We use this so we can
@@ -136,13 +143,16 @@
         Class<?> factory = null;
         try {
             FactoryFinder finder = getCamelContext().createFactoryFinder("META-INF/services/org/apache/camel/component/");
-            factory = finder.findClass("ftp", "strategy.factory.");
+            factory = finder.findClass(getUriProtocol(), "strategy.factory.");
         } catch (ClassNotFoundException e) {
             log.debug("'strategy.factory.class' not found", e);
         } catch (IOException e) {
             log.debug("No strategy factory defined in 'META-INF/services/org/apache/camel/component/'", e);
         }
 
+        // TODO: remove me this new factory is listed in the MET-INF file
+        factory = GenericFileProcessStrategyFactory.class;
+
         if (factory == null) {
             // use default
             factory = ObjectHelper.loadClass(DEFAULT_STRATEGYFACTORY_CLASS);
@@ -307,11 +317,11 @@
         this.filter = filter;
     }
 
-    public Comparator<GenericFile> getSorter() {
+    public Comparator<GenericFile<T>> getSorter() {
         return sorter;
     }
 
-    public void setSorter(Comparator<GenericFile> sorter) {
+    public void setSorter(Comparator<GenericFile<T>> sorter) {
         this.sorter = sorter;
     }
 
@@ -375,6 +385,38 @@
         this.readLockTimeout = readLockTimeout;
     }
 
+    public int getBufferSize() {
+        return bufferSize;
+    }
+
+    public void setBufferSize(int bufferSize) {
+        this.bufferSize = bufferSize;
+    }
+
+    public boolean isAppend() {
+        return append;
+    }
+
+    public void setAppend(boolean append) {
+        this.append = append;
+    }
+
+    public boolean isDirectory() {
+        return directory;
+    }
+
+    public void setDirectory(boolean directory) {
+        this.directory = directory;
+    }
+
+    public boolean isAutoCreate() {
+        return autoCreate;
+    }
+
+    public void setAutoCreate(boolean autoCreate) {
+        this.autoCreate = autoCreate;
+    }
+
     /**
      * Should the file be moved after consuming?
      */

Modified: camel/trunk/camel-core/src/main/java/org/apache/camel/component/file/GenericFileExchange.java
URL: http://svn.apache.org/viewvc/camel/trunk/camel-core/src/main/java/org/apache/camel/component/file/GenericFileExchange.java?rev=737359&r1=737358&r2=737359&view=diff
==============================================================================
--- camel/trunk/camel-core/src/main/java/org/apache/camel/component/file/GenericFileExchange.java (original)
+++ camel/trunk/camel-core/src/main/java/org/apache/camel/component/file/GenericFileExchange.java Sat Jan 24 14:05:36 2009
@@ -22,9 +22,11 @@
 import org.apache.camel.ExchangePattern;
 import org.apache.camel.impl.DefaultExchange;
 
-public class GenericFileExchange extends DefaultExchange {
+public class GenericFileExchange<T> extends DefaultExchange {
 
-    private GenericFile genericFile;
+    private GenericFile<T> genericFile;
+
+    // TODO: Consider removing some of he constructors
 
     public GenericFileExchange(CamelContext context) {
         super(context);
@@ -42,14 +44,14 @@
         super(fromEndpoint);
     }
 
-    public GenericFileExchange(GenericFileEndpoint endpoint, ExchangePattern pattern, GenericFile genericFile) {
+    public GenericFileExchange(GenericFileEndpoint endpoint, ExchangePattern pattern, GenericFile<T> genericFile) {
         super(endpoint, pattern);
-        setRemoteFile(genericFile);
+        setGenericFile(genericFile);
     }
 
-    public GenericFileExchange(DefaultExchange parent, GenericFile genericFile) {
+    public GenericFileExchange(DefaultExchange parent, GenericFile<T> genericFile) {
         super(parent);
-        setRemoteFile(genericFile);
+        setGenericFile(genericFile);
     }
 
     public GenericFileExchange(Endpoint fromEndpoint, ExchangePattern pattern) {
@@ -57,7 +59,7 @@
     }
 
 
-    protected void populateHeaders(GenericFile genericFile) {
+    protected void populateHeaders(GenericFile<T> genericFile) {
         if (genericFile != null) {
             getIn().setHeader("file.absoluteName", genericFile.getAbsoluteFileName());
             getIn().setHeader("file.relativeName", genericFile.getRelativeFileName());
@@ -77,11 +79,11 @@
         }
     }
 
-    public GenericFile getGenericFile() {
+    public GenericFile<T> getGenericFile() {
         return genericFile;
     }
 
-    public void setRemoteFile(GenericFile genericFile) {
+    public void setGenericFile(GenericFile<T> genericFile) {
         setIn(new GenericFileMessage(genericFile));
         this.genericFile = genericFile;
         populateHeaders(genericFile);

Modified: camel/trunk/camel-core/src/main/java/org/apache/camel/component/file/GenericFileOperations.java
URL: http://svn.apache.org/viewvc/camel/trunk/camel-core/src/main/java/org/apache/camel/component/file/GenericFileOperations.java?rev=737359&r1=737358&r2=737359&view=diff
==============================================================================
--- camel/trunk/camel-core/src/main/java/org/apache/camel/component/file/GenericFileOperations.java (original)
+++ camel/trunk/camel-core/src/main/java/org/apache/camel/component/file/GenericFileOperations.java Sat Jan 24 14:05:36 2009
@@ -16,10 +16,10 @@
  */
 package org.apache.camel.component.file;
 
-import java.io.InputStream;
-import java.io.OutputStream;
 import java.util.List;
 
+import org.apache.camel.Exchange;
+
 public interface GenericFileOperations<T> {
 
     /**
@@ -59,23 +59,23 @@
      * Retrieves the remote file (download)
      *
      * @param name name of the file
-     * @param out  stream to write the content of the file into
+     * @param exchange  stream to write the content of the file into
      * @return true if file has been retrieved, false if not
      * @throws GenericFileOperationFailedException
      *          can be thrown
      */
-    boolean retrieveFile(String name, OutputStream out) throws GenericFileOperationFailedException;
+    boolean retrieveFile(T file, String name, Exchange exchange) throws GenericFileOperationFailedException;
 
     /**
      * Stores the content as a new remote file (upload)
      *
      * @param name name of new file
-     * @param body content of the file
+     * @param exchange with the content content of the file
      * @return true if the file was stored, false if not
      * @throws GenericFileOperationFailedException
      *          can be thrown
      */
-    boolean storeFile(String name, InputStream body) throws GenericFileOperationFailedException;
+    boolean storeFile(String name, Exchange exchange) throws GenericFileOperationFailedException;
 
     /**
      * Gets the current remote directory
@@ -84,7 +84,7 @@
      * @throws GenericFileOperationFailedException
      *          can be thrown
      */
-    String getCurrentDirectory() throws GenericFileOperationFailedException;
+    String getCurrentDirectory(T file) throws GenericFileOperationFailedException;
 
     /**
      * Change the current remote directory
@@ -93,7 +93,7 @@
      * @throws GenericFileOperationFailedException
      *          can be thrown
      */
-    void changeCurrentDirectory(String path) throws GenericFileOperationFailedException;
+    T changeCurrentDirectory(T file, String path) throws GenericFileOperationFailedException;
 
     /**
      * List the files in the current remote directory
@@ -102,7 +102,7 @@
      * @throws GenericFileOperationFailedException
      *          can be thrown
      */
-    List listFiles() throws GenericFileOperationFailedException;
+    List<T> listFiles(T file) throws GenericFileOperationFailedException;
 
     /**
      * List the files in the given remote directory
@@ -112,6 +112,6 @@
      * @throws GenericFileOperationFailedException
      *          can be thrown
      */
-    List listFiles(String path) throws GenericFileOperationFailedException;
+    List<T> listFiles(T file, String path) throws GenericFileOperationFailedException;
 
 }

Modified: camel/trunk/camel-core/src/main/java/org/apache/camel/component/file/GenericFileProducer.java
URL: http://svn.apache.org/viewvc/camel/trunk/camel-core/src/main/java/org/apache/camel/component/file/GenericFileProducer.java?rev=737359&r1=737358&r2=737359&view=diff
==============================================================================
--- camel/trunk/camel-core/src/main/java/org/apache/camel/component/file/GenericFileProducer.java (original)
+++ camel/trunk/camel-core/src/main/java/org/apache/camel/component/file/GenericFileProducer.java Sat Jan 24 14:05:36 2009
@@ -16,8 +16,7 @@
  */
 package org.apache.camel.component.file;
 
-import java.io.IOException;
-import java.io.InputStream;
+import java.io.File;
 
 import org.apache.camel.Exchange;
 import org.apache.camel.Expression;
@@ -31,11 +30,11 @@
 /**
  * Generic file producer
  */
-public class GenericFileProducer extends DefaultProducer {
+public class GenericFileProducer<T> extends DefaultProducer {
     private final transient Log log = LogFactory.getLog(GenericFileProducer.class);
-    private GenericFileOperations operations;
+    private GenericFileOperations<T> operations;
 
-    protected GenericFileProducer(GenericFileEndpoint endpoint, GenericFileOperations operations) {
+    protected GenericFileProducer(GenericFileEndpoint<T> endpoint, GenericFileOperations<T> operations) {
         super(endpoint);
         this.operations = operations;
     }
@@ -43,12 +42,12 @@
     /**
      * Convenience method
      */
-    protected GenericFileEndpoint getGenericFileEndpoint() {
-        return (GenericFileEndpoint) getEndpoint();
+    protected GenericFileEndpoint<T> getGenericFileEndpoint() {
+        return (GenericFileEndpoint<T>) getEndpoint();
     }
 
     public void process(Exchange exchange) throws Exception {
-        GenericFileExchange fileExchange = (GenericFileExchange) getEndpoint().createExchange(exchange);
+        GenericFileExchange<T> fileExchange = (GenericFileExchange<T>) getGenericFileEndpoint().createExchange(exchange);
         processExchange(fileExchange);
         ExchangeHelper.copyResults(exchange, fileExchange);
     }
@@ -59,7 +58,7 @@
      * @param exchange fileExchange
      * @throws Exception is thrown if some error
      */
-    protected void processExchange(GenericFileExchange exchange) throws Exception {
+    protected void processExchange(GenericFileExchange<T> exchange) throws Exception {
         if (log.isTraceEnabled()) {
             log.trace("Processing " + exchange);
         }
@@ -101,22 +100,17 @@
     }
 
     protected void writeFile(Exchange exchange, String fileName) throws GenericFileOperationFailedException {
-        InputStream payload = exchange.getIn().getBody(InputStream.class);
-        try {
-            // build directory
-            int lastPathIndex = fileName.lastIndexOf('/');
-            if (lastPathIndex != -1) {
-                String directory = fileName.substring(0, lastPathIndex);
-                if (!operations.buildDirectory(directory)) {
-                    log.warn("Couldn't build directory: " + directory + " (could be because of denied permissions)");
-                }
-            }
-            boolean success = operations.storeFile(fileName, payload);
-            if (!success) {
-                throw new GenericFileOperationFailedException("Error writing file: " + fileName);
+        // build directory
+        int lastPathIndex = fileName.lastIndexOf('/');
+        if (lastPathIndex != -1) {
+            String directory = fileName.substring(0, lastPathIndex);
+            if (!operations.buildDirectory(directory)) {
+                log.warn("Couldn't build directory: " + directory + " (could be because of denied permissions)");
             }
-        } finally {
-            ObjectHelper.close(payload, "Closing payload", log);
+        }
+        boolean success = operations.storeFile(fileName, exchange);
+        if (!success) {
+            throw new GenericFileOperationFailedException("Error writing file: " + fileName);
         }
     }
 
@@ -146,15 +140,20 @@
         }
 
         String endpointFile = getGenericFileEndpoint().getConfiguration().getFile();
-        if (getGenericFileEndpoint().getConfiguration().isDirectory()) {
-            // If the path isn't empty, we need to add a trailing / if it isn't
-            // already there
+        if (getGenericFileEndpoint().isDirectory() || getGenericFileEndpoint().getConfiguration().isDirectory()) {
+            // Its a directory so we should use it as a basepath for the filename
+            // If the path isn't empty, we need to add a trailing / if it isn't already there
             String baseDir = "";
             if (endpointFile.length() > 0) {
+                // TODO windows or unix slashes. Maybe we should replace all \ to /
                 baseDir = endpointFile + (endpointFile.endsWith("/") ? "" : "/");
             }
-            String fileName = (name != null) ? name : getGenericFileEndpoint().getGeneratedFileName(exchange.getIn());
-            answer = baseDir + fileName;
+            if (name != null) {
+                answer = baseDir + name;
+            } else {
+                // use a generated filename if no name provided
+                answer = baseDir + getGenericFileEndpoint().getGeneratedFileName(exchange.getIn());
+            }
         } else {
             answer = endpointFile;
         }

Added: camel/trunk/camel-core/src/main/java/org/apache/camel/component/file/NewFileComponent.java
URL: http://svn.apache.org/viewvc/camel/trunk/camel-core/src/main/java/org/apache/camel/component/file/NewFileComponent.java?rev=737359&view=auto
==============================================================================
--- camel/trunk/camel-core/src/main/java/org/apache/camel/component/file/NewFileComponent.java (added)
+++ camel/trunk/camel-core/src/main/java/org/apache/camel/component/file/NewFileComponent.java Sat Jan 24 14:05:36 2009
@@ -0,0 +1,55 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.camel.component.file;
+
+import java.io.File;
+import java.util.Map;
+
+/**
+ *
+ */
+public class NewFileComponent extends GenericFileComponent<File> {
+
+    protected GenericFileEndpoint<File> buildFileEndpoint(String uri, String remaining, Map parameters) throws Exception {
+        File file = new File(remaining);
+
+        NewFileEndpoint result = new NewFileEndpoint(uri, this);
+        result.setFile(file);
+
+        GenericFileConfiguration config = new GenericFileConfiguration();
+
+        // TODO: This code should be looked at, the parent stuff is might not needed
+        File parent = file.getParentFile();
+        if (parent != null) {
+            file = new File(parent, file.getName());
+        }
+        config.setFile(file.getPath());
+        config.setDirectory(file.isDirectory());
+
+        result.setConfiguration(config);
+
+        NewFileOperations operations = new NewFileOperations(result);
+        result.setOperations(operations);
+
+        return result;
+    }
+
+    protected void afterPropertiesSet(GenericFileEndpoint<File> endpoint) throws Exception {
+        // noop
+        // TODO: Could be a noop in parent and only override if needed
+    }
+}

Propchange: camel/trunk/camel-core/src/main/java/org/apache/camel/component/file/NewFileComponent.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: camel/trunk/camel-core/src/main/java/org/apache/camel/component/file/NewFileComponent.java
------------------------------------------------------------------------------
    svn:keywords = Rev Date

Added: camel/trunk/camel-core/src/main/java/org/apache/camel/component/file/NewFileConsumer.java
URL: http://svn.apache.org/viewvc/camel/trunk/camel-core/src/main/java/org/apache/camel/component/file/NewFileConsumer.java?rev=737359&view=auto
==============================================================================
--- camel/trunk/camel-core/src/main/java/org/apache/camel/component/file/NewFileConsumer.java (added)
+++ camel/trunk/camel-core/src/main/java/org/apache/camel/component/file/NewFileConsumer.java Sat Jan 24 14:05:36 2009
@@ -0,0 +1,98 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.camel.component.file;
+
+import java.io.File;
+import java.util.List;
+
+import org.apache.camel.Processor;
+
+/**
+ *
+ */
+public class NewFileConsumer extends GenericFileConsumer<File> {
+
+    public NewFileConsumer(GenericFileEndpoint<File> endpoint, Processor processor, GenericFileOperations<File> operations) {
+        super(endpoint, processor, operations);
+    }
+
+    protected void pollDirectory(String fileName, List<GenericFile<File>> fileList) {
+        File fileOrDirectory = new File(fileName);
+
+        if (!fileOrDirectory.exists()) {
+            return;
+        }
+
+        if (log.isTraceEnabled()) {
+            log.trace("Polling directory: " + fileOrDirectory.getPath());
+        }
+        File[] files = fileOrDirectory.listFiles();
+        for (File file : files) {
+            // createa a generic file
+            GenericFile<File> gf = asGenericFile(file);
+
+            if (file.isDirectory()) {
+                if (endpoint.isRecursive() && isValidFile(gf, true)) {
+                    // recursive scan and add the sub files and folders
+                    String directory = fileName + "/" + file.getName();
+                    pollDirectory(directory, fileList);
+                }
+            } else if (file.isFile()) {
+                if (isValidFile(gf, false)) {
+                    // matched file so add
+                    fileList.add(gf);
+                }
+            } else {
+                log.debug("Ignoring unsupported file type " + file);
+            }
+        }
+    }
+
+    protected void pollFile(String fileName, List<GenericFile<File>> fileList) {
+        File file = new File(fileName);
+
+        if (!file.exists()) {
+            return;
+        }
+
+        // createa a generic file
+        GenericFile<File> gf = asGenericFile(file);
+
+        if (isValidFile(gf, false)) {
+            // matched file so add
+            fileList.add(gf);
+        }
+
+    }
+
+    protected GenericFile<File> asGenericFile(File file) {
+        GenericFile<File> answer = new GenericFile<File>();
+        answer.setFile(file);
+        answer.setFileLength(file.length());
+        answer.setFileName(file.getName());
+        answer.setAbsoluteFileName(file.getAbsolutePath());
+        answer.setLastModified(file.lastModified());
+        if (file.getParent() != null) {
+            answer.setRelativeFileName(file.getParent() + "/" + file.getName());
+        } else {
+            answer.setRelativeFileName(file.getName());
+        }
+        // use file as body as we have converters if needed as stream
+        answer.setBody(file);
+        return answer;
+    }
+}

Propchange: camel/trunk/camel-core/src/main/java/org/apache/camel/component/file/NewFileConsumer.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: camel/trunk/camel-core/src/main/java/org/apache/camel/component/file/NewFileConsumer.java
------------------------------------------------------------------------------
    svn:keywords = Rev Date

Added: camel/trunk/camel-core/src/main/java/org/apache/camel/component/file/NewFileEndpoint.java
URL: http://svn.apache.org/viewvc/camel/trunk/camel-core/src/main/java/org/apache/camel/component/file/NewFileEndpoint.java?rev=737359&view=auto
==============================================================================
--- camel/trunk/camel-core/src/main/java/org/apache/camel/component/file/NewFileEndpoint.java (added)
+++ camel/trunk/camel-core/src/main/java/org/apache/camel/component/file/NewFileEndpoint.java Sat Jan 24 14:05:36 2009
@@ -0,0 +1,97 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.camel.component.file;
+
+import java.io.File;
+
+import org.apache.camel.Component;
+import org.apache.camel.Processor;
+import org.apache.camel.processor.idempotent.MemoryIdempotentRepository;
+
+/**
+ *
+ */
+public class NewFileEndpoint extends GenericFileEndpoint<File> {
+
+    private NewFileOperations operations;
+    private File file;
+
+    public NewFileEndpoint() {
+    }
+
+    public NewFileEndpoint(String endpointUri, Component component) {
+        super(endpointUri, component);
+    }
+
+    public NewFileConsumer createConsumer(Processor processor) throws Exception {
+        NewFileConsumer result = new NewFileConsumer(this, processor, operations);
+
+        if (isDelete() && (getMoveNamePrefix() != null || getMoveNamePostfix() != null || getExpression() != null)) {
+            throw new IllegalArgumentException("You cannot set delete=true and a moveNamePrefix, moveNamePostfix or expression option");
+        }
+
+        // if noop=true then idempotent should also be configured
+        if (isNoop() && !isIdempotent()) {
+            log.info("Endpoint is configured with noop=true so forcing endpoint to be idempotent as well");
+            setIdempotent(true);
+        }
+
+        // if idempotent and no repository set then create a default one
+        if (isIdempotent() && idempotentRepository == null) {
+            log.info("Using default memory based idempotent repository with cache max size: " + DEFAULT_IDEMPOTENT_CACHE_SIZE);
+            idempotentRepository = MemoryIdempotentRepository.memoryIdempotentRepository(DEFAULT_IDEMPOTENT_CACHE_SIZE);
+        }
+
+        configureConsumer(result);
+        return result;
+    }
+
+    public GenericFileProducer<File> createProducer() throws Exception {
+        return new GenericFileProducer<File>(this, operations);
+    }
+
+    public GenericFileExchange<File> createExchange(GenericFile<File> file) {
+        GenericFileExchange<File> exchange = new GenericFileExchange<File>(getCamelContext());
+        exchange.setGenericFile(file);
+        return exchange;
+    }
+
+    public GenericFileExchange createExchange() {
+        return new GenericFileExchange(getCamelContext());
+    }
+
+    protected String getUriProtocol() {
+        // TODO: should be "file" when its ready
+        return "newfile";
+    }
+
+    public NewFileOperations getOperations() {
+        return operations;
+    }
+
+    public void setOperations(NewFileOperations operations) {
+        this.operations = operations;
+    }
+
+    public File getFile() {
+        return file;
+    }
+
+    public void setFile(File file) {
+        this.file = file;
+    }
+}

Propchange: camel/trunk/camel-core/src/main/java/org/apache/camel/component/file/NewFileEndpoint.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: camel/trunk/camel-core/src/main/java/org/apache/camel/component/file/NewFileEndpoint.java
------------------------------------------------------------------------------
    svn:keywords = Rev Date

Added: camel/trunk/camel-core/src/main/java/org/apache/camel/component/file/NewFileOperations.java
URL: http://svn.apache.org/viewvc/camel/trunk/camel-core/src/main/java/org/apache/camel/component/file/NewFileOperations.java?rev=737359&view=auto
==============================================================================
--- camel/trunk/camel-core/src/main/java/org/apache/camel/component/file/NewFileOperations.java (added)
+++ camel/trunk/camel-core/src/main/java/org/apache/camel/component/file/NewFileOperations.java Sat Jan 24 14:05:36 2009
@@ -0,0 +1,167 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.camel.component.file;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.RandomAccessFile;
+import java.nio.ByteBuffer;
+import java.nio.channels.FileChannel;
+import java.util.Arrays;
+import java.util.List;
+
+import org.apache.camel.Exchange;
+import org.apache.camel.InvalidPayloadException;
+import org.apache.camel.util.ExchangeHelper;
+import org.apache.camel.util.ObjectHelper;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+/**
+ *
+ */
+public class NewFileOperations implements GenericFileOperations<File> {
+
+    private static final transient Log LOG = LogFactory.getLog(NewFileOperations.class);
+    private final NewFileEndpoint endpoint;
+
+    public NewFileOperations(final NewFileEndpoint endpoint) {
+        this.endpoint = endpoint;
+    }
+
+    public boolean deleteFile(String name) throws GenericFileOperationFailedException {
+        File file = new File(name);
+        return file.exists() && file.delete();
+    }
+
+    public boolean renameFile(String from, String to) throws GenericFileOperationFailedException {
+        File file = new File(from);
+        return file.exists() && file.renameTo(new File(to));
+    }
+
+    public boolean buildDirectory(String directory) throws GenericFileOperationFailedException {
+        File dir = new File(directory);
+        if (dir.exists()) {
+            return true;
+        }
+        return endpoint.isAutoCreate() && dir.mkdirs();
+    }
+
+    public String getCurrentDirectory(File file) throws GenericFileOperationFailedException {
+        return file.getPath();
+    }
+
+    public File changeCurrentDirectory(File file, String path) throws GenericFileOperationFailedException {
+        return new File(path);
+    }
+
+    public List<File> listFiles(File file) throws GenericFileOperationFailedException {
+        return Arrays.asList(file.listFiles());
+    }
+
+    public List<File> listFiles(File file, String path) throws GenericFileOperationFailedException {
+        return listFiles(new File(path));
+    }
+
+    public boolean retrieveFile(File file, String name, Exchange exchange) throws GenericFileOperationFailedException {
+        return false;
+    }
+
+    public boolean storeFile(String name, Exchange exchange) throws GenericFileOperationFailedException {
+        File file = new File(name);
+        try {
+            boolean fileSource = exchange.getIn().getBody() instanceof File;
+            if (fileSource) {
+                File source = ExchangeHelper.getMandatoryInBody(exchange, File.class);
+                writeFileByFile(source, file);
+            } else {
+                InputStream in = ExchangeHelper.getMandatoryInBody(exchange, InputStream.class);
+                writeFileByStream(in, file);
+            }
+        } catch (IOException e) {
+            throw new GenericFileOperationFailedException("Can not store file: " + file, e);
+        } catch (InvalidPayloadException e) {
+            throw new GenericFileOperationFailedException("Can not store file: " + file, e);
+        }
+
+        return true;
+    }
+
+    private void writeFileByFile(File source, File target) throws IOException {
+        FileChannel in = new FileInputStream(source).getChannel();
+        FileChannel out = null;
+        try {
+            out = prepareOutputFileChannel(target, out);
+
+            if (LOG.isTraceEnabled()) {
+                LOG.trace("Using FileChannel to transfer from: " + in + " to: " + out);
+            }
+            in.transferTo(0, in.size(), out);
+        } finally {
+            ObjectHelper.close(in, source.getName(), LOG);
+            ObjectHelper.close(out, source.getName(), LOG);
+        }
+    }
+
+    private void writeFileByStream(InputStream in, File target) throws IOException {
+        FileChannel out = null;
+        try {
+            out = prepareOutputFileChannel(target, out);
+
+            if (LOG.isTraceEnabled()) {
+                LOG.trace("Using InputStream to transfer from: " + in + " to: " + out);
+            }
+            int size = endpoint.getBufferSize();
+            byte[] buffer = new byte[size];
+            ByteBuffer byteBuffer = ByteBuffer.wrap(buffer);
+            while (true) {
+                int count = in.read(buffer);
+                if (count <= 0) {
+                    break;
+                } else if (count < size) {
+                    byteBuffer = ByteBuffer.wrap(buffer, 0, count);
+                    out.write(byteBuffer);
+                    break;
+                } else {
+                    out.write(byteBuffer);
+                    byteBuffer.clear();
+                }
+            }
+        } finally {
+            ObjectHelper.close(in, target.getName(), LOG);
+            ObjectHelper.close(out, target.getName(), LOG);
+        }
+    }
+
+    /**
+     * Creates and prepares the output file channel. Will position itself in correct position if eg. it should append
+     * or override any existing content.
+     */
+    private FileChannel prepareOutputFileChannel(File target, FileChannel out) throws IOException {
+        if (endpoint.isAppend()) {
+            out = new RandomAccessFile(target, "rw").getChannel();
+            out = out.position(out.size());
+        } else {
+            out = new FileOutputStream(target).getChannel();
+        }
+        return out;
+    }
+
+}

Propchange: camel/trunk/camel-core/src/main/java/org/apache/camel/component/file/NewFileOperations.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: camel/trunk/camel-core/src/main/java/org/apache/camel/component/file/NewFileOperations.java
------------------------------------------------------------------------------
    svn:keywords = Rev Date

Added: camel/trunk/camel-core/src/main/java/org/apache/camel/component/file/strategy/GenericFileDefaultRenamer.java
URL: http://svn.apache.org/viewvc/camel/trunk/camel-core/src/main/java/org/apache/camel/component/file/strategy/GenericFileDefaultRenamer.java?rev=737359&view=auto
==============================================================================
--- camel/trunk/camel-core/src/main/java/org/apache/camel/component/file/strategy/GenericFileDefaultRenamer.java (added)
+++ camel/trunk/camel-core/src/main/java/org/apache/camel/component/file/strategy/GenericFileDefaultRenamer.java Sat Jan 24 14:05:36 2009
@@ -0,0 +1,81 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.camel.component.file.strategy;
+
+import org.apache.camel.component.file.GenericFile;
+import org.apache.camel.component.file.GenericFileExchange;
+
+public class GenericFileDefaultRenamer implements GenericFileRenamer {
+
+    private String namePrefix;
+    private String namePostfix;
+
+    public GenericFileDefaultRenamer() {
+    }
+
+    public GenericFileDefaultRenamer(String namePrefix, String namePostfix) {
+        this.namePrefix = namePrefix;
+        this.namePostfix = namePostfix;
+    }
+
+    public GenericFile renameFile(GenericFileExchange exchange, GenericFile file) {
+        String newName = renameFileName(file.getFileName());
+
+        // clone and change the name
+        GenericFile result = file.clone();
+        result.changeFileName(newName);
+        return result;
+    }
+
+    public String getNamePostfix() {
+        return namePostfix;
+    }
+
+    /**
+     * Sets the name postfix appended to moved files. For example
+     * to rename all the files from * to *.done set this value to ".done"
+     */
+    public void setNamePostfix(String namePostfix) {
+        this.namePostfix = namePostfix;
+    }
+
+    public String getNamePrefix() {
+        return namePrefix;
+    }
+
+    /**
+     * Sets the name prefix appended to moved files. For example
+     * to move processed files into a hidden directory called ".camel"
+     * set this value to ".camel/"
+     */
+    public void setNamePrefix(String namePrefix) {
+        this.namePrefix = namePrefix;
+    }
+
+    protected String renameFileName(String name) {
+        StringBuffer buffer = new StringBuffer();
+        if (namePrefix != null) {
+            buffer.append(namePrefix);
+        }
+        buffer.append(name);
+        if (namePostfix != null) {
+            buffer.append(namePostfix);
+        }
+        return buffer.toString();
+    }
+
+}

Propchange: camel/trunk/camel-core/src/main/java/org/apache/camel/component/file/strategy/GenericFileDefaultRenamer.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: camel/trunk/camel-core/src/main/java/org/apache/camel/component/file/strategy/GenericFileDefaultRenamer.java
------------------------------------------------------------------------------
    svn:keywords = Rev Date

Added: camel/trunk/camel-core/src/main/java/org/apache/camel/component/file/strategy/GenericFileDeleteProcessStrategy.java
URL: http://svn.apache.org/viewvc/camel/trunk/camel-core/src/main/java/org/apache/camel/component/file/strategy/GenericFileDeleteProcessStrategy.java?rev=737359&view=auto
==============================================================================
--- camel/trunk/camel-core/src/main/java/org/apache/camel/component/file/strategy/GenericFileDeleteProcessStrategy.java (added)
+++ camel/trunk/camel-core/src/main/java/org/apache/camel/component/file/strategy/GenericFileDeleteProcessStrategy.java Sat Jan 24 14:05:36 2009
@@ -0,0 +1,35 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.camel.component.file.strategy;
+
+import org.apache.camel.component.file.GenericFile;
+import org.apache.camel.component.file.GenericFileEndpoint;
+import org.apache.camel.component.file.GenericFileExchange;
+import org.apache.camel.component.file.GenericFileOperationFailedException;
+import org.apache.camel.component.file.GenericFileOperations;
+
+public class GenericFileDeleteProcessStrategy extends GenericFileProcessStrategySupport {
+
+    @Override
+    public void commit(GenericFileOperations operations, GenericFileEndpoint endpoint, GenericFileExchange exchange, GenericFile file) throws Exception {
+        boolean deleted = operations.deleteFile(file.getAbsoluteFileName());
+        if (!deleted) {
+            throw new GenericFileOperationFailedException("Cannot delete file: " + file);
+        }
+    }
+
+}
\ No newline at end of file

Propchange: camel/trunk/camel-core/src/main/java/org/apache/camel/component/file/strategy/GenericFileDeleteProcessStrategy.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: camel/trunk/camel-core/src/main/java/org/apache/camel/component/file/strategy/GenericFileDeleteProcessStrategy.java
------------------------------------------------------------------------------
    svn:keywords = Rev Date

Added: camel/trunk/camel-core/src/main/java/org/apache/camel/component/file/strategy/GenericFileExpressionRenamer.java
URL: http://svn.apache.org/viewvc/camel/trunk/camel-core/src/main/java/org/apache/camel/component/file/strategy/GenericFileExpressionRenamer.java?rev=737359&view=auto
==============================================================================
--- camel/trunk/camel-core/src/main/java/org/apache/camel/component/file/strategy/GenericFileExpressionRenamer.java (added)
+++ camel/trunk/camel-core/src/main/java/org/apache/camel/component/file/strategy/GenericFileExpressionRenamer.java Sat Jan 24 14:05:36 2009
@@ -0,0 +1,46 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.camel.component.file.strategy;
+
+import org.apache.camel.Expression;
+import org.apache.camel.component.file.GenericFile;
+import org.apache.camel.component.file.GenericFileExchange;
+import org.apache.camel.util.ObjectHelper;
+
+public class GenericFileExpressionRenamer implements GenericFileRenamer {
+    private Expression expression;
+
+    public GenericFile renameFile(GenericFileExchange exchange, GenericFile file) {
+        ObjectHelper.notNull(expression, "expression");
+
+        Object eval = expression.evaluate(exchange);
+        String newName = exchange.getContext().getTypeConverter().convertTo(String.class, eval);
+
+        // clone and change the name
+        GenericFile result = file.clone();
+        result.changeFileName(newName);
+        return result;
+    }
+
+    public Expression getExpression() {
+        return expression;
+    }
+
+    public void setExpression(Expression expression) {
+        this.expression = expression;
+    }    
+}

Propchange: camel/trunk/camel-core/src/main/java/org/apache/camel/component/file/strategy/GenericFileExpressionRenamer.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: camel/trunk/camel-core/src/main/java/org/apache/camel/component/file/strategy/GenericFileExpressionRenamer.java
------------------------------------------------------------------------------
    svn:keywords = Rev Date

Added: camel/trunk/camel-core/src/main/java/org/apache/camel/component/file/strategy/GenericFileNoOpProcessStrategy.java
URL: http://svn.apache.org/viewvc/camel/trunk/camel-core/src/main/java/org/apache/camel/component/file/strategy/GenericFileNoOpProcessStrategy.java?rev=737359&view=auto
==============================================================================
--- camel/trunk/camel-core/src/main/java/org/apache/camel/component/file/strategy/GenericFileNoOpProcessStrategy.java (added)
+++ camel/trunk/camel-core/src/main/java/org/apache/camel/component/file/strategy/GenericFileNoOpProcessStrategy.java Sat Jan 24 14:05:36 2009
@@ -0,0 +1,21 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.camel.component.file.strategy;
+
+public class GenericFileNoOpProcessStrategy extends GenericFileProcessStrategySupport {
+
+}

Propchange: camel/trunk/camel-core/src/main/java/org/apache/camel/component/file/strategy/GenericFileNoOpProcessStrategy.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: camel/trunk/camel-core/src/main/java/org/apache/camel/component/file/strategy/GenericFileNoOpProcessStrategy.java
------------------------------------------------------------------------------
    svn:keywords = Rev Date

Added: camel/trunk/camel-core/src/main/java/org/apache/camel/component/file/strategy/GenericFileProcessStrategyFactory.java
URL: http://svn.apache.org/viewvc/camel/trunk/camel-core/src/main/java/org/apache/camel/component/file/strategy/GenericFileProcessStrategyFactory.java?rev=737359&view=auto
==============================================================================
--- camel/trunk/camel-core/src/main/java/org/apache/camel/component/file/strategy/GenericFileProcessStrategyFactory.java (added)
+++ camel/trunk/camel-core/src/main/java/org/apache/camel/component/file/strategy/GenericFileProcessStrategyFactory.java Sat Jan 24 14:05:36 2009
@@ -0,0 +1,108 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.camel.component.file.strategy;
+
+import java.util.Map;
+
+import org.apache.camel.Expression;
+import org.apache.camel.component.file.GenericFileExclusiveReadLockStrategy;
+import org.apache.camel.component.file.GenericFileProcessStrategy;
+import org.apache.camel.util.ObjectHelper;
+
+public final class GenericFileProcessStrategyFactory {
+
+    private GenericFileProcessStrategyFactory() {
+    }
+
+    public static GenericFileProcessStrategy createGenericFileProcessStrategy(Map<String, Object> params) {
+
+        // We assume a value is present only if its value not null for String and 'true' for boolean
+        boolean isNoop = params.get("noop") != null;
+        boolean isDelete = params.get("delete") != null;
+        String moveNamePrefix = (String) params.get("moveNamePrefix");
+        String moveNamePostfix = (String) params.get("moveNamePostfix");
+        String preMoveNamePrefix = (String) params.get("preMoveNamePrefix");
+        String preMoveNamePostfix = (String) params.get("preMoveNamePostfix");
+        Expression expression = (Expression) params.get("expression");
+        Expression preMoveExpression = (Expression) params.get("preMoveExpression");
+        boolean move = moveNamePrefix != null || moveNamePostfix != null;
+        boolean preMove = preMoveNamePrefix != null || preMoveNamePostfix != null;
+
+        if (isNoop) {
+            GenericFileNoOpProcessStrategy strategy = new GenericFileNoOpProcessStrategy();
+            strategy.setExclusiveReadLockStrategy(getExclusiveReadLockStrategy(params));
+            return strategy;
+        } else if (isDelete) {
+            GenericFileDeleteProcessStrategy strategy = new GenericFileDeleteProcessStrategy();
+            strategy.setExclusiveReadLockStrategy(getExclusiveReadLockStrategy(params));
+            return strategy;
+        } else if (move || preMove) {
+            GenericFileRenameProcessStrategy strategy = new GenericFileRenameProcessStrategy();
+            strategy.setExclusiveReadLockStrategy(getExclusiveReadLockStrategy(params));
+            if (move) {
+                strategy.setCommitRenamer(new GenericFileDefaultRenamer(moveNamePrefix, moveNamePostfix));
+            }
+            if (preMove) {
+                strategy.setBeginRenamer(new GenericFileDefaultRenamer(preMoveNamePrefix, preMoveNamePostfix));
+            }
+            return strategy;
+        } else if (expression != null || preMoveExpression != null) {
+            GenericFileRenameProcessStrategy strategy = new GenericFileRenameProcessStrategy();
+            strategy.setExclusiveReadLockStrategy(getExclusiveReadLockStrategy(params));
+            if (expression != null) {
+                GenericFileExpressionRenamer renamer = new GenericFileExpressionRenamer();
+                renamer.setExpression(expression);
+                strategy.setCommitRenamer(renamer);
+            }
+            if (preMoveExpression != null) {
+                GenericFileExpressionRenamer renamer = new GenericFileExpressionRenamer();
+                renamer.setExpression(preMoveExpression);
+                strategy.setBeginRenamer(renamer);
+            }
+            return strategy;
+        } else {
+            // default strategy will do nothing
+            GenericFileNoOpProcessStrategy strategy = new GenericFileNoOpProcessStrategy();
+            strategy.setExclusiveReadLockStrategy(getExclusiveReadLockStrategy(params));
+            return strategy;
+        }
+    }
+
+    private static GenericFileExclusiveReadLockStrategy getExclusiveReadLockStrategy(Map<String, Object> params) {
+        GenericFileExclusiveReadLockStrategy strategy = (GenericFileExclusiveReadLockStrategy) params.get("exclusiveReadLockStrategy");
+        if (strategy != null) {
+            return strategy;
+        }
+
+        // no explicit stategy set then fallback to readLock option
+        String readLock = (String) params.get("readLock");
+        if (ObjectHelper.isNotEmpty(readLock)) {
+            if ("none".equals(readLock) || "false".equals(readLock)) {
+                return null;
+            } else if ("rename".equals(readLock)) {
+                GenericFileRenameExclusiveReadLockStrategy readLockStrategy = new GenericFileRenameExclusiveReadLockStrategy();
+                Long timeout = (Long) params.get("readLockTimeout");
+                if (timeout != null) {
+                    readLockStrategy.setTimeout(timeout);
+                }
+                return readLockStrategy;
+            }
+        }
+
+        return null;
+    }
+}

Propchange: camel/trunk/camel-core/src/main/java/org/apache/camel/component/file/strategy/GenericFileProcessStrategyFactory.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: camel/trunk/camel-core/src/main/java/org/apache/camel/component/file/strategy/GenericFileProcessStrategyFactory.java
------------------------------------------------------------------------------
    svn:keywords = Rev Date

Added: camel/trunk/camel-core/src/main/java/org/apache/camel/component/file/strategy/GenericFileProcessStrategySupport.java
URL: http://svn.apache.org/viewvc/camel/trunk/camel-core/src/main/java/org/apache/camel/component/file/strategy/GenericFileProcessStrategySupport.java?rev=737359&view=auto
==============================================================================
--- camel/trunk/camel-core/src/main/java/org/apache/camel/component/file/strategy/GenericFileProcessStrategySupport.java (added)
+++ camel/trunk/camel-core/src/main/java/org/apache/camel/component/file/strategy/GenericFileProcessStrategySupport.java Sat Jan 24 14:05:36 2009
@@ -0,0 +1,58 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.camel.component.file.strategy;
+
+import org.apache.camel.component.file.GenericFile;
+import org.apache.camel.component.file.GenericFileEndpoint;
+import org.apache.camel.component.file.GenericFileExchange;
+import org.apache.camel.component.file.GenericFileExclusiveReadLockStrategy;
+import org.apache.camel.component.file.GenericFileOperations;
+import org.apache.camel.component.file.GenericFileProcessStrategy;
+
+public abstract class GenericFileProcessStrategySupport implements GenericFileProcessStrategy {
+    private GenericFileExclusiveReadLockStrategy exclusiveReadLockStrategy;
+
+    public boolean begin(GenericFileOperations operations, GenericFileEndpoint endpoint, GenericFileExchange exchange, GenericFile file) throws Exception {
+        // is we use excluse read then acquire the exclusive read (waiting until we got it)
+        if (exclusiveReadLockStrategy != null) {
+            boolean lock = exclusiveReadLockStrategy.acquireExclusiveReadLock(operations, file);
+            if (!lock) {
+                // do not begin sice we could not get the exclusive read lcok
+                return false;
+            }
+        }
+
+        return true;
+    }
+
+    public void commit(GenericFileOperations operations, GenericFileEndpoint endpoint, GenericFileExchange exchange, GenericFile file) throws Exception {
+        // nothing
+    }
+
+    public void rollback(GenericFileOperations operations, GenericFileEndpoint endpoint, GenericFileExchange exchange, GenericFile file) {
+        // nothing
+    }
+
+    public GenericFileExclusiveReadLockStrategy getExclusiveReadLockStrategy() {
+        return exclusiveReadLockStrategy;
+    }
+
+    public void setExclusiveReadLockStrategy(GenericFileExclusiveReadLockStrategy exclusiveReadLockStrategy) {
+        this.exclusiveReadLockStrategy = exclusiveReadLockStrategy;
+    }
+}
+

Propchange: camel/trunk/camel-core/src/main/java/org/apache/camel/component/file/strategy/GenericFileProcessStrategySupport.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: camel/trunk/camel-core/src/main/java/org/apache/camel/component/file/strategy/GenericFileProcessStrategySupport.java
------------------------------------------------------------------------------
    svn:keywords = Rev Date

Added: camel/trunk/camel-core/src/main/java/org/apache/camel/component/file/strategy/GenericFileRenameExclusiveReadLockStrategy.java
URL: http://svn.apache.org/viewvc/camel/trunk/camel-core/src/main/java/org/apache/camel/component/file/strategy/GenericFileRenameExclusiveReadLockStrategy.java?rev=737359&view=auto
==============================================================================
--- camel/trunk/camel-core/src/main/java/org/apache/camel/component/file/strategy/GenericFileRenameExclusiveReadLockStrategy.java (added)
+++ camel/trunk/camel-core/src/main/java/org/apache/camel/component/file/strategy/GenericFileRenameExclusiveReadLockStrategy.java Sat Jan 24 14:05:36 2009
@@ -0,0 +1,101 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.camel.component.file.strategy;
+
+import org.apache.camel.component.file.GenericFile;
+import org.apache.camel.component.file.GenericFileExclusiveReadLockStrategy;
+import org.apache.camel.component.file.GenericFileOperations;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+/**
+ * Acquires exclusive read lock to the given file. Will wait until the lock is granted.
+ * After granting the read lock it is realeased, we just want to make sure that when we start
+ * consuming the file its not currently in progress of being written by third party.
+ */
+public class GenericFileRenameExclusiveReadLockStrategy implements GenericFileExclusiveReadLockStrategy {
+    private static final transient Log LOG = LogFactory.getLog(GenericFileRenameExclusiveReadLockStrategy.class);
+    private long timeout;
+
+    public boolean acquireExclusiveReadLock(GenericFileOperations operations, GenericFile file) {
+        if (LOG.isTraceEnabled()) {
+            LOG.trace("Waiting for exclusive read lock to file: " + file);
+        }
+
+        // the trick is to try to rename the file, if we can rename then we have exclusive read
+        // since its a Generic file we cannot use java.nio to get a RW lock
+        String newName = file.getFileName() + ".camelExclusiveReadLock";
+
+        // clone and change the name
+        GenericFile newFile = file.clone();
+        newFile.changeFileName(newName);
+
+        long start = System.currentTimeMillis();
+
+        boolean exclusive = false;
+        while (!exclusive) {
+             // timeout check
+            if (timeout > 0) {
+                long delta = System.currentTimeMillis() - start;
+                if (delta > timeout) {
+                    LOG.debug("Could not acquire read lock within " + timeout + " millis. Will skip the file: " + file);
+                    // we could not get the lock within the timeout period, so return false
+                    return false;
+                }
+            }
+            
+            exclusive = operations.renameFile(file.getAbsoluteFileName(), newFile.getAbsoluteFileName());
+            if (exclusive) {
+                if (LOG.isDebugEnabled()) {
+                    LOG.debug("Acquired exclusive read lock to file: " + file);
+                }
+                // rename it back so we can read it
+                operations.renameFile(newFile.getAbsoluteFileName(), file.getAbsoluteFileName());
+            } else {
+                sleep();
+            }
+        }
+
+        return true;
+    }
+
+    private void sleep() {
+        LOG.trace("Exclusive read lock not granted. Sleeping for 1000 millis.");
+        try {
+            Thread.sleep(1000);
+        } catch (InterruptedException e) {
+            // ignore
+        }
+    }
+
+    public long getTimeout() {
+        return timeout;
+    }
+
+    /**
+     * Sets an optional timeout period.
+     * <p/>
+     * If the readlock could not be granted within the timeperiod then the wait is stopped and the
+     * {@link #acquireExclusiveReadLock(org.apache.camel.component.file.GenericFileOperations, org.apache.camel.component.file.GenericFile)}
+     *  acquireExclusiveReadLock} returns <tt>false</tt>.
+     *
+     * @param timeout period in millis
+     */
+    public void setTimeout(long timeout) {
+        this.timeout = timeout;
+    }
+}

Propchange: camel/trunk/camel-core/src/main/java/org/apache/camel/component/file/strategy/GenericFileRenameExclusiveReadLockStrategy.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: camel/trunk/camel-core/src/main/java/org/apache/camel/component/file/strategy/GenericFileRenameExclusiveReadLockStrategy.java
------------------------------------------------------------------------------
    svn:keywords = Rev Date

Added: camel/trunk/camel-core/src/main/java/org/apache/camel/component/file/strategy/GenericFileRenameProcessStrategy.java
URL: http://svn.apache.org/viewvc/camel/trunk/camel-core/src/main/java/org/apache/camel/component/file/strategy/GenericFileRenameProcessStrategy.java?rev=737359&view=auto
==============================================================================
--- camel/trunk/camel-core/src/main/java/org/apache/camel/component/file/strategy/GenericFileRenameProcessStrategy.java (added)
+++ camel/trunk/camel-core/src/main/java/org/apache/camel/component/file/strategy/GenericFileRenameProcessStrategy.java Sat Jan 24 14:05:36 2009
@@ -0,0 +1,118 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.camel.component.file.strategy;
+
+import java.io.IOException;
+
+import org.apache.camel.component.file.GenericFile;
+import org.apache.camel.component.file.GenericFileEndpoint;
+import org.apache.camel.component.file.GenericFileExchange;
+import org.apache.camel.component.file.GenericFileOperationFailedException;
+import org.apache.camel.component.file.GenericFileOperations;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+public class GenericFileRenameProcessStrategy extends GenericFileProcessStrategySupport {
+    private static final transient Log LOG = LogFactory.getLog(org.apache.camel.component.file.strategy.GenericFileRenameProcessStrategy.class);
+    private GenericFileRenamer beginRenamer;
+    private GenericFileRenamer commitRenamer;
+
+    public GenericFileRenameProcessStrategy() {
+    }
+
+    public GenericFileRenameProcessStrategy(String namePrefix, String namePostfix) {
+        this(new GenericFileDefaultRenamer(namePrefix, namePostfix), null);
+    }
+
+    public GenericFileRenameProcessStrategy(String namePrefix, String namePostfix, String preNamePrefix, String preNamePostfix) {
+        this(new GenericFileDefaultRenamer(namePrefix, namePostfix), new GenericFileDefaultRenamer(preNamePrefix, preNamePostfix));
+    }
+
+    public GenericFileRenameProcessStrategy(GenericFileRenamer commitRenamer, GenericFileRenamer beginRenamer) {
+        this.commitRenamer = commitRenamer;
+        this.beginRenamer = beginRenamer;
+    }
+
+    @Override
+    public boolean begin(GenericFileOperations operations, GenericFileEndpoint endpoint, GenericFileExchange exchange, GenericFile file) throws Exception {
+        if (beginRenamer != null) {
+            GenericFile newName = beginRenamer.renameFile(exchange, file);
+            GenericFile to = renameFile(operations, file, newName);
+            exchange.setGenericFile(to);
+        }
+
+        return true;
+    }
+
+    @Override
+    public void commit(GenericFileOperations operations, GenericFileEndpoint endpoint, GenericFileExchange exchange, GenericFile file) throws Exception {
+        if (commitRenamer != null) {
+            GenericFile newName = commitRenamer.renameFile(exchange, file);
+            renameFile(operations, file, newName);
+        }
+    }
+
+    private static GenericFile renameFile(GenericFileOperations operations, GenericFile from, GenericFile to) throws IOException {
+        // deleting any existing files before renaming
+        boolean deleted = false;
+        try {
+            deleted = operations.deleteFile(to.getAbsoluteFileName());
+        } catch (GenericFileOperationFailedException e) {
+            // ignore the file does not exists
+        }
+
+        if (!deleted) {
+            // if we could not delete any existing file then maybe the folder is missing
+            // build folder if needed
+            String name = to.getAbsoluteFileName();
+            int lastPathIndex = name.lastIndexOf('/');
+            if (lastPathIndex != -1) {
+                String directory = name.substring(0, lastPathIndex);
+                if (!operations.buildDirectory(directory)) {
+                    LOG.warn("Cannot build directory: " + directory + " (maybe because of denied permissions)");
+                }
+            }
+        }
+
+        if (LOG.isDebugEnabled()) {
+            LOG.debug("Renaming file: " + from + " to: " + to);
+        }
+        boolean renamed = operations.renameFile(from.getAbsoluteFileName(), to.getAbsoluteFileName());
+        if (!renamed) {
+            throw new GenericFileOperationFailedException("Cannot rename file: " + from + " to: " + to);
+        }
+
+        return to;
+    }
+
+    public GenericFileRenamer getBeginRenamer() {
+        return beginRenamer;
+    }
+
+    public void setBeginRenamer(GenericFileRenamer beginRenamer) {
+        this.beginRenamer = beginRenamer;
+    }
+
+    public GenericFileRenamer getCommitRenamer() {
+        return commitRenamer;
+    }
+
+    public void setCommitRenamer(GenericFileRenamer commitRenamer) {
+        this.commitRenamer = commitRenamer;
+    }
+
+}

Propchange: camel/trunk/camel-core/src/main/java/org/apache/camel/component/file/strategy/GenericFileRenameProcessStrategy.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: camel/trunk/camel-core/src/main/java/org/apache/camel/component/file/strategy/GenericFileRenameProcessStrategy.java
------------------------------------------------------------------------------
    svn:keywords = Rev Date

Added: camel/trunk/camel-core/src/main/java/org/apache/camel/component/file/strategy/GenericFileRenamer.java
URL: http://svn.apache.org/viewvc/camel/trunk/camel-core/src/main/java/org/apache/camel/component/file/strategy/GenericFileRenamer.java?rev=737359&view=auto
==============================================================================
--- camel/trunk/camel-core/src/main/java/org/apache/camel/component/file/strategy/GenericFileRenamer.java (added)
+++ camel/trunk/camel-core/src/main/java/org/apache/camel/component/file/strategy/GenericFileRenamer.java Sat Jan 24 14:05:36 2009
@@ -0,0 +1,36 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.camel.component.file.strategy;
+
+import org.apache.camel.component.file.GenericFile;
+import org.apache.camel.component.file.GenericFileExchange;
+
+/**
+ * Used for renaming files.
+ */
+public interface GenericFileRenamer {
+
+    /**
+     * Renames the given file
+     *
+     * @param exchange  the exchange
+     * @param file      the original file.
+     * @return the renamed file name.
+     */
+    GenericFile renameFile(GenericFileExchange exchange, GenericFile file);
+
+}

Propchange: camel/trunk/camel-core/src/main/java/org/apache/camel/component/file/strategy/GenericFileRenamer.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: camel/trunk/camel-core/src/main/java/org/apache/camel/component/file/strategy/GenericFileRenamer.java
------------------------------------------------------------------------------
    svn:keywords = Rev Date