[jboss-svn-commits] JBL Code SVN: r23852 - in labs/jbossesb/workspace/skeagh: examples/file-router and 11 other directories.

jboss-svn-commits at lists.jboss.org jboss-svn-commits at lists.jboss.org
Thu Nov 13 06:29:30 EST 2008


Author: beve
Date: 2008-11-13 06:29:30 -0500 (Thu, 13 Nov 2008)
New Revision: 23852

Added:
   labs/jbossesb/workspace/skeagh/routing/file/src/main/java/org/jboss/esb/file/FileOutboundRouter.java
   labs/jbossesb/workspace/skeagh/routing/file/src/main/java/org/jboss/esb/file/eval/
   labs/jbossesb/workspace/skeagh/routing/file/src/main/java/org/jboss/esb/file/eval/PatternEvaluator.java
   labs/jbossesb/workspace/skeagh/routing/file/src/main/java/org/jboss/esb/file/eval/PatternEvaluatorImpl.java
   labs/jbossesb/workspace/skeagh/routing/file/src/main/java/org/jboss/esb/file/eval/package.html
   labs/jbossesb/workspace/skeagh/routing/file/src/main/java/org/jboss/esb/file/util/
   labs/jbossesb/workspace/skeagh/routing/file/src/main/java/org/jboss/esb/file/util/FileRouterUtil.java
   labs/jbossesb/workspace/skeagh/routing/file/src/main/java/org/jboss/esb/file/util/package.html
   labs/jbossesb/workspace/skeagh/routing/file/src/main/java/org/jboss/esb/file/writers/
   labs/jbossesb/workspace/skeagh/routing/file/src/main/java/org/jboss/esb/file/writers/FileWriter.java
   labs/jbossesb/workspace/skeagh/routing/file/src/main/java/org/jboss/esb/file/writers/FileWriterImpl.java
   labs/jbossesb/workspace/skeagh/routing/file/src/main/java/org/jboss/esb/file/writers/package.html
   labs/jbossesb/workspace/skeagh/routing/file/src/test/java/org/jboss/esb/file/FileOutboundRouterTest.java
   labs/jbossesb/workspace/skeagh/routing/file/src/test/java/org/jboss/esb/file/file-outbound-router.xml
   labs/jbossesb/workspace/skeagh/routing/file/src/test/java/org/jboss/esb/file/writers/
   labs/jbossesb/workspace/skeagh/routing/file/src/test/java/org/jboss/esb/file/writers/DefaultFileWriterTest.java
Modified:
   labs/jbossesb/workspace/skeagh/commons/src/main/java/org/jboss/esb/util/FileUtil.java
   labs/jbossesb/workspace/skeagh/examples/file-router/README.TXT
   labs/jbossesb/workspace/skeagh/examples/file-router/pom.xml
   labs/jbossesb/workspace/skeagh/examples/file-router/src/main/resources/jboss-esb.xml
   labs/jbossesb/workspace/skeagh/routing/file/pom.xml
   labs/jbossesb/workspace/skeagh/routing/file/src/main/java/org/jboss/esb/file/FileInboundRouter.java
   labs/jbossesb/workspace/skeagh/routing/file/src/main/java/org/jboss/esb/file/composers/AbstractFileMessageComposer.java
   labs/jbossesb/workspace/skeagh/routing/file/src/main/java/org/jboss/esb/file/lifecycle/DefaultFileLifecycle.java
   labs/jbossesb/workspace/skeagh/routing/file/src/main/java/org/jboss/esb/file/lifecycle/FileLifecycle.java
   labs/jbossesb/workspace/skeagh/routing/file/src/main/java/org/jboss/esb/file/lifecycle/FileLifecycleConfig.java
   labs/jbossesb/workspace/skeagh/routing/file/src/test/java/org/jboss/esb/file/FileInboundRouterTest.java
   labs/jbossesb/workspace/skeagh/routing/file/src/test/java/org/jboss/esb/file/file-inbound-router_01.xml
   labs/jbossesb/workspace/skeagh/routing/file/src/test/java/org/jboss/esb/file/lifecycle/DefaultFileLifecycleTest.java
   labs/jbossesb/workspace/skeagh/routing/file/src/test/java/org/jboss/esb/file/lifecycle/FileLifecycleConfigTest.java
Log:
Work for https://jira.jboss.org/jira/browse/JBESB-2014 "Create Inbound and Outbound Routers for File"


Modified: labs/jbossesb/workspace/skeagh/commons/src/main/java/org/jboss/esb/util/FileUtil.java
===================================================================
--- labs/jbossesb/workspace/skeagh/commons/src/main/java/org/jboss/esb/util/FileUtil.java	2008-11-13 05:51:22 UTC (rev 23851)
+++ labs/jbossesb/workspace/skeagh/commons/src/main/java/org/jboss/esb/util/FileUtil.java	2008-11-13 11:29:30 UTC (rev 23852)
@@ -23,7 +23,6 @@
 package org.jboss.esb.util;
 
 import org.apache.log4j.Logger;
-
 import java.io.*;
 import java.util.UUID;
 
@@ -265,5 +264,69 @@
 
         return fileBuffer.toByteArray();
     }
+
+    /**
+     *
+     * @param fromExpression The expression that may or may not contain a directory path.
+     * @return File The file object to the directory in the fromExpression or null if no directory existed.
+     */
+    public static File evalTargetDirectory(final String fromExpression)
+    {
+        AssertArgument.isNotNullAndNotEmpty(fromExpression, "expression");
+
+        final int indexOfFileSeparator = fromExpression.indexOf(File.separatorChar);
+        final int indexOfVariable = fromExpression.indexOf('$');
+
+        // A path was specified.
+        if (indexOfFileSeparator != -1)
+        {
+            if (indexOfVariable != -1)
+            {
+                return new File(fromExpression.substring(0, indexOfVariable));
+            }
+            else
+            {
+                // No variables exist in expression. This is simply a path to a file.
+                // Return the File object to the parent and not the file itself.
+                return new File(fromExpression).getParentFile();
+            }
+        }
+
+        return null;
+    }
+
+    /**
+     *
+     * @param from The expression to remove path information from
+     * @return String
+     */
+    public static String removePath(final String from)
+    {
+        String newName = from;
+        final int indexOfFileSeparator = newName.lastIndexOf(File.separatorChar);
+        if (indexOfFileSeparator != -1)
+        {
+            newName = newName.substring(indexOfFileSeparator + 1);
+        }
+        return newName;
+    }
+
+    /**
+     * Simply checks that the directory exists and if not throws an exception.
+     *
+     * @param directory The directory to check.
+     * @throws IOException If the directory does not exist or could not be created.
+     */
+    public static void createDestinationDirectory(final File directory) throws IOException
+    {
+        if (!directory.exists())
+        {
+            final boolean created = directory.mkdirs();
+            if (!created && !directory.exists())
+            {
+                throw new IOException("Could not create the directory '" + directory + "'. Please make sure that proper access rights have been given to all parent directories");
+            }
+        }
+    }
 }
 

Modified: labs/jbossesb/workspace/skeagh/examples/file-router/README.TXT
===================================================================
--- labs/jbossesb/workspace/skeagh/examples/file-router/README.TXT	2008-11-13 05:51:22 UTC (rev 23851)
+++ labs/jbossesb/workspace/skeagh/examples/file-router/README.TXT	2008-11-13 11:29:30 UTC (rev 23852)
@@ -15,7 +15,7 @@
         4.  Open a new console window ("Window 3")
         5.  Copy src/text/resources/sample.txt to target/input. This file will be picked up by the the ESB. 
 			Switch back to "Window 2) and see the output from the Service.
-			The processed file will now have moved to the specified 'processedDir'(target/output by default).
+			The processed file will now have moved to the specified outbound routers configured directory.
 
 Things to try
 =============

Modified: labs/jbossesb/workspace/skeagh/examples/file-router/pom.xml
===================================================================
--- labs/jbossesb/workspace/skeagh/examples/file-router/pom.xml	2008-11-13 05:51:22 UTC (rev 23851)
+++ labs/jbossesb/workspace/skeagh/examples/file-router/pom.xml	2008-11-13 11:29:30 UTC (rev 23852)
@@ -125,9 +125,6 @@
 							<tasks>
 								<property name="runtime-classpath" refid="maven.runtime.classpath"/>
 								<mkdir dir="${basedir}/target/input"/>
-								<mkdir dir="${basedir}/target/working"/>
-								<mkdir dir="${basedir}/target/output"/>
-								<mkdir dir="${basedir}/target/error"/>
 							</tasks>
 						</configuration>
 					</execution>

Modified: labs/jbossesb/workspace/skeagh/examples/file-router/src/main/resources/jboss-esb.xml
===================================================================
--- labs/jbossesb/workspace/skeagh/examples/file-router/src/main/resources/jboss-esb.xml	2008-11-13 05:51:22 UTC (rev 23851)
+++ labs/jbossesb/workspace/skeagh/examples/file-router/src/main/resources/jboss-esb.xml	2008-11-13 11:29:30 UTC (rev 23852)
@@ -9,23 +9,16 @@
     <services>
         <service serviceCategory="examples" serviceName="InboundRouter-File" serviceDescription="First Example" class="org.jboss.esb.examples.filerouter.MyTestService">
             <inRouter name="fileRouter" class="org.jboss.esb.file.FileInboundRouter">
-                <!-- Mandatory properties -->
                 <property name="scheduleResourceId">schedule1</property>
-                <property name="inputDir">../target/input</property>
-                
-                <!-- Optional properties -->
-                <property name="fileSelectorPattern">*.txt</property>
-                <property name="fileSelector">org.jboss.esb.file.filtering.WildcardFileSelector</property>
-                <property name="fileEncoding">UTF-8</property>
-                <property name="workingDir">../target/working</property>
-                <property name="workingRenamePattern">${name}-${timestamp}.working</property>
-                <property name="processedDir">../target/output</property>
-                <property name="processedRenamePattern">${name}-${timestamp}.done</property>
-                <property name="errorDir">../target/error</property>
-                <property name="errrorRenamePattern">${name}-${timestamp}.error</property>
+                <property name="fileSelectorPattern">../target/input/*.txt</property>
+                <property name="workingRenamePattern">../target/working/${name}-${timestamp}.working</property>
+                <property name="processedRenamePattern">../target/output/${name}-${timestamp}.done</property>
+                <property name="errrorRenamePattern">../target/error/${name}-${timestamp}.error</property>
                 <property name="messageComposer">org.jboss.esb.file.composers.FileStringMessageComposer</property>
-                <property name="fileLifecycleFactory">org.jboss.esb.file.lifecycle.DefaultFileLifecycleFactory</property>
             </inRouter>
+            <outRouter name="fileOutboundRouter" class="org.jboss.esb.file.FileOutboundRouter">
+                <property name="fileNamePattern">../target/another-service-pickup-dir/${name}.out</property>
+            </outRouter>
         </service>
     </services>
 </jbossesb>

Modified: labs/jbossesb/workspace/skeagh/routing/file/pom.xml
===================================================================
--- labs/jbossesb/workspace/skeagh/routing/file/pom.xml	2008-11-13 05:51:22 UTC (rev 23851)
+++ labs/jbossesb/workspace/skeagh/routing/file/pom.xml	2008-11-13 11:29:30 UTC (rev 23852)
@@ -23,7 +23,7 @@
                 <extensions>true</extensions>
                 <configuration>
                     <instructions>
-                        <Export-Package>org.jboss.esb.file*</Export-Package>
+                        <Export-Package>org.jboss.esb.file.*</Export-Package>
                         <Import-Package>*;resolution:=optional</Import-Package> 
                         <Embed-Dependency>jbossesb-commons, log4j</Embed-Dependency>
                         <Embed-Transitive>true</Embed-Transitive>

Modified: labs/jbossesb/workspace/skeagh/routing/file/src/main/java/org/jboss/esb/file/FileInboundRouter.java
===================================================================
--- labs/jbossesb/workspace/skeagh/routing/file/src/main/java/org/jboss/esb/file/FileInboundRouter.java	2008-11-13 05:51:22 UTC (rev 23851)
+++ labs/jbossesb/workspace/skeagh/routing/file/src/main/java/org/jboss/esb/file/FileInboundRouter.java	2008-11-13 11:29:30 UTC (rev 23852)
@@ -33,14 +33,14 @@
 import org.jboss.esb.api.message.MessageProcessingException;
 import org.jboss.esb.api.routing.InboundRouter;
 import org.jboss.esb.api.routing.MessageDispatcher;
-import org.jboss.esb.classpath.ClassUtil;
-import org.jboss.esb.file.composers.FileBytesMessageComposer;
 import org.jboss.esb.file.filtering.FileSelector;
 import org.jboss.esb.file.filtering.WildcardFileFilter;
 import org.jboss.esb.file.lifecycle.FileLifecycle;
 import org.jboss.esb.file.lifecycle.FileLifecycleFactory;
+import org.jboss.esb.file.util.FileRouterUtil;
 import org.jboss.esb.schedule.AbstractScheduleListener;
 import org.jboss.esb.schedule.SchedulingException;
+import org.jboss.esb.util.FileUtil;
 
 /**
  * Simple schedule based file {@link InboundRouter}.
@@ -49,7 +49,8 @@
  * <p/>
  *
  * Example config:<br/>
- * <pre>@{code
+ * <pre>{@code
+ *
  * <resources>
  *     <resource id="schedule1" class="org.jboss.esb.schedule.SimpleSchedule">
  *         <property name="frequency">100</property>
@@ -59,23 +60,19 @@
  *
  * <inRouter name="fileRouter" class="org.jboss.esb.file.FileInboundRouter">
  *     <property name="scheduleResourceId">schedule1</property>
- *     <property name="inputDir">target/</property>
- *     <property name="fileSelectorPattern">*.txt</property>
+ *     <property name="fileSelectorPattern">target/*.txt</property>
  * </inRouter>
+ *
  * }</pre>
  * <p/>
  * Property description:
  * <lu>
  *  <li>scheduleResourceId      - the id of the schedule that this router will use.</li>
- *  <li>inputDir                - the directory from where files will be picked up.</li>
  *  <li>fileSelectorPattern     - the file matching pattern used to filter files to pick up from the inputDir. Default: '*'</li>
  *  <li>fileSelector            - the concrete {@link FileSelector} implementation to use. Default: org.jboss.esb.file.filtering.WildcardFileSelector </li>
  *  <li>fileEncoding            - the file encoding to use when reading the file. Default: UTF-8.</li>
- *  <li>workingDir              - the directory from where files will be places during processing.</li>
  *  <li>workingRenamePattern    - the pattern used for naming files that the esb is processing. Default: ${name}.working</li>
- *  <li>processedDir            - the directory where files will be placed after successful processing.</li>
  *  <li>processedRenamePattern  - the pattern used for naming files that have be processed successfully. Default: ${name}.processed}</li>
- *  <li>errorDir                - the directory where files will be placed when a processing error occurs.</li>
  *  <li>errorRenamePattern      - the pattern used for naming files when a processing error occurs. Default: ${name}.error</li>
  *  <li>messageComposer         - the concrete {@link MessageComposer} implementation to use. Default: org.jboss.esb.file.composers.FileStringMessageComposer</li>
  *  <li>fileLifecycleFactory    - the concrete {@link FileLifecycleFactory} implementation to use. Default: org.jboss.esb.file.lifecycle.DefaultFileLifecycleFactory</li>
@@ -92,12 +89,6 @@
     private static Logger logger = Logger.getLogger(FileInboundRouter.class);
 
     /**
-     * Name of the directory to "listen" to.
-     */
-    @Property(use = Use.REQUIRED, name = "inputDir")
-    private String inputDirName;
-
-    /**
      * The file selector pattern use.
      */
      @Property(use = Use.OPTIONAL, name = "fileSelectorPattern", defaultVal = "*")
@@ -122,36 +113,18 @@
     private String workingRenamePattern;
 
     /**
-     * The directory where files that are being processed are placed.
-     */
-    @Property(use = Use.OPTIONAL, name = "workingDir")
-    private String workingDir;
-
-    /**
      * The rename pattern for a file when an error occurs.
      */
     @Property(use = Use.OPTIONAL, name = "errorRenamePattern", defaultVal = "${name}.error")
     private String errorRenamePattern;
 
     /**
-     * The directory where files will be places if an error occurs while processing.
-     */
-    @Property(use = Use.OPTIONAL, name = "errorDir")
-    private String errorDir;
-
-    /**
      * The processed rename pattern for a successfully processed file.
      */
     @Property(use = Use.OPTIONAL, name = "processedRenamePattern", defaultVal = "${name}.processed")
     private String processedRenamePattern;
 
     /**
-     * The directory where files that have been successfully processed are placed.
-     */
-    @Property(use = Use.OPTIONAL, name = "processedDir")
-    private String processedDir;
-
-    /**
      * The message composer to use.
      */
      @Property(use = Use.OPTIONAL, name = "messageComposer", defaultVal = "org.jboss.esb.file.composers.FileBytesMessageComposer")
@@ -216,34 +189,26 @@
     @Initialize
     public final void initialize() throws ConfigurationException
     {
-        inputDir = getFileDir();
+        inputDir = FileRouterUtil.createTargetDirectory(fileSelectorPattern);
 
         // Config the file selector...
-        properties.put(WildcardFileFilter.MATCH_PATTERN, fileSelectorPattern);
+        properties.put(WildcardFileFilter.MATCH_PATTERN, FileUtil.removePath(fileSelectorPattern));
         fileSelector = FileSelector.Factory.newInstance(fileSelectorImpl, properties);
 
         // Config the file lifecycle factory...
-        properties.setProperty(FileLifecycle.WORKING_DIRECTORY, workingDir != null ? workingDir : inputDirName);
         properties.setProperty(FileLifecycle.WORKING_RENAME_PATTERN, workingRenamePattern);
-        properties.setProperty(FileLifecycle.ERROR_DIRECTORY, errorDir != null ? errorDir : inputDirName);
         properties.setProperty(FileLifecycle.ERROR_RENAME_PATTERN, errorRenamePattern);
         properties.setProperty(FileLifecycle.PROCESSED_RENAME_PATTERN, processedRenamePattern);
-        properties.setProperty(FileLifecycle.PROCESSED_DIRECTORY, processedDir != null ? processedDir : inputDirName);
         fileLifecycleFactory = FileLifecycleFactory.Factory.newInstance(fileLifecycleFactoryName, properties);
 
         // Config the message composer...
-        messageComposer = createMessageComposer(messageComposerClass);
+        messageComposer = (MessageComposer<FileLifecycle>) FileRouterUtil.createInstance(messageComposerClass);
         properties.put("encoding", fileEncoding);
         messageComposer.setConfiguration(properties);
 
         if (logger.isDebugEnabled())
         {
-            logger.debug("-------- Config for FileInboundRouter '" + objectName + "'");
-            logger.debug("Listening for files in dir '" + inputDir.getAbsolutePath() + "'");
-            logger.debug("FileSelector : '" + fileSelector.getClass().getName() + "'");
-            logger.debug("FileLifecycleFactory : '" + fileLifecycleFactory.getClass().getName() + "'");
-            logger.debug("MessageComposer : '" + messageComposer.getClass().getName() + "'");
-            logger.debug("-------- End Config for FileInboundRouter '" + objectName + "'");
+            logger.debug(this);
         }
     }
 
@@ -262,26 +227,30 @@
         {
             return;
         }
-
         logger.info(" Schedule triggered for '" + objectName + "'");
+
         final InvocationContext invocationContext = new InvocationContext();
-        final Message message = createEsbMessage(invocationContext);
 
-        if (message != null)
+        final FileLifecycle fileLifecycle = selectFile(invocationContext);
+        if (fileLifecycle == null)
         {
+            // no file so just return.
+            return;
+        }
 
-            final FileLifecycle fileLifecycle = getFileLifeCycle(invocationContext);
-            try
-            {
-                dispatcher.dispatch(message, invocationContext);
-                fileLifecycle.toProcessed();
-            }
-            catch (final Exception e)
-            {
-                fileLifecycle.toError();
-                throw new SchedulingException(e.getMessage(), e);
-            }
-
+        final Message message = createEsbMessage(fileLifecycle, invocationContext);
+        try
+        {
+            dispatcher.dispatch(message, invocationContext);
+            fileLifecycle.toProcessed();
+        }
+        catch (final Exception e)
+        {
+            fileLifecycle.toError();
+            throw new SchedulingException(e.getMessage(), e);
+        }
+        finally
+        {
             onProcessingComplete(message, fileLifecycle);
         }
     }
@@ -304,26 +273,35 @@
         this.dispatcher = dispatcher;
     }
 
-    /**
-     * Gets the name of the input directoy that this router listens to.
-     *
-     * @return String   The name of the input directory.
-     */
-    public final String getInputDirName()
+    /**
+     * Returs a string representation of this router.
+     *
+     * @return String The string representation.
+     */
+    @Override
+    public final String toString()
     {
-        return inputDirName;
+        StringBuilder sb = new StringBuilder();
+        sb.append("InboundRouter[name='").append(objectName);
+        sb.append("', inputDir='").append(inputDir);
+        sb.append("', fileSelectorPattern='").append(fileSelectorPattern);
+        sb.append("', fileSelector='").append(fileSelector.getClass().getName());
+        sb.append("', fileLifecycleFactory : '" + fileLifecycleFactory.getClass().getName());
+        sb.append("', messageComposer : '" + messageComposer.getClass().getName());
+        sb.append("']");
+        return sb.toString();
     }
 
     /**
-     * Creates an esb Message Object by taking the content of one file and
-     * setting it as the messages payload.
+     * Selects a file from the input directory and creates a {@link FileLifecycle}
+     * using the picked up file.
      *
      * @param invocationContext The invocation context.
-     * @return Message  Esb Message or null if no files were found.
+     * @return FileLifecycle    {@link FileLifecycle} associated with the file.
      *
      * @throws SchedulingException If en exception occurs while trying to compose the message.
      */
-    private Message createEsbMessage(final InvocationContext invocationContext) throws SchedulingException
+    private FileLifecycle selectFile(final InvocationContext invocationContext) throws SchedulingException
     {
         final File[] files = fileSelector.select(inputDir);
 
@@ -356,63 +334,40 @@
                 // Another listener has already transitioned the file to working (in between calls).  Try the next file...
             }
         }
+        return fileLifecycle;
 
-        try
-        {
-            return messageComposer.compose(fileLifecycle, invocationContext);
-        }
-        catch (final MessageProcessingException e)
-        {
-            fileLifecycle.toError();
-            throw new SchedulingException("Unable to compose message from file '" + files[0].getAbsolutePath() + "'.", e);
-        }
-    }
+    }
 
     /**
-     * Will return a File object referens to {@link #inputDirName}.
+     * Creates an esb Message Object by taking the content of one file and
+     * setting it as the messages payload.
      *
-     * @return File File object referens to {@link #inputDirName}.
+     * @param fileLifecycle The file lifecycle holding among other things the file in process.
+     * @param invocationContext The invocation context.
+     * @return Message          Esb Message or null if no files were found.
      *
-     * @throws ConfigurationException If the directory does not exist, is not a directory, or not read/write able.
+     * @throws SchedulingException If en exception occurs while trying to compose the message.
      */
-    private File getFileDir() throws ConfigurationException
+    private Message createEsbMessage(final FileLifecycle fileLifecycle, final InvocationContext invocationContext) throws SchedulingException
     {
-        final File fileDir = new File(inputDirName);
-
-        // Check the file listen directory...
-        if (!fileDir.exists())
+        try
         {
-            throw new ConfigurationException("Directory '" + fileDir.getAbsolutePath() + "' doesn't exist.");
+            return messageComposer.compose(fileLifecycle, invocationContext);
         }
-        if (!fileDir.isDirectory())
+        catch (final MessageProcessingException e)
         {
-            throw new ConfigurationException("File '" + fileDir.getAbsolutePath() + "' is not a directory.");
+            fileLifecycle.toError();
+            throw new SchedulingException("Unable to compose message from file '" + fileLifecycle.getFile().getAbsolutePath() + "'.", e);
         }
-        if (!fileDir.canRead() || !fileDir.canWrite())
-        {
-            throw new ConfigurationException("Directory '" + fileDir.getAbsolutePath() + "' must be readable and writeable.");
-        }
-
-        return fileDir;
     }
 
     /**
-     * Gets the FileLifecycle from the invocation context.
-     *
-     * @param invocationContext The invocation context.
-     * @return FileLifecycle From the context.
-     */
-    private FileLifecycle getFileLifeCycle(final InvocationContext invocationContext)
-    {
-        return (FileLifecycle)invocationContext.getContextObject(FileLifecycle.class.getName());
-    }
-
-    /**
      * TODO: not sure if this method is actually needed.
      *
-     * @param message The ESB Message object.
+     * @param message       The ESB Message object.
      * @param fileLifecycle The FileLifecycle.
-     * @return Message The ESB Message object.
+     * @return Message      The ESB Message object.
+     *
      * @throws SchedulingException If an exception occurs while decomposing.
      */
     private Message onProcessingComplete(final Message message, final FileLifecycle fileLifecycle) throws SchedulingException
@@ -432,48 +387,4 @@
         return null;
     }
 
-    /**
-     * Creates a new instance of the passed in class name. It must implement
-     * MessageComposer.
-     *
-     * @param className The name of the class to create.
-     * @return MessageComposer  The newly created instance.
-     * @throws ConfigurationException If it was not able to create the class.
-     */
-    @SuppressWarnings("unchecked")
-    private MessageComposer<FileLifecycle> createMessageComposer(final String className) throws ConfigurationException
-    {
-        String messageComposerClassName = getMessageComposerClassName(className);
-        try
-        {
-            Class<?> forName = ClassUtil.forName(messageComposerClassName, FileInboundRouter.class);
-            return (MessageComposer<FileLifecycle>) forName.newInstance();
-        }
-        catch (final ClassNotFoundException e)
-        {
-            throw new ConfigurationException("Could not load message composer class '" + messageComposerClassName + "'. Exception was: " + e);
-        }
-        catch (final InstantiationException e)
-        {
-            throw new ConfigurationException("InstantiationException:" + e);
-        }
-        catch (final IllegalAccessException e)
-        {
-            throw new ConfigurationException("IllegalAccessException:" + e);
-        }
-    }
-
-    /**
-     * @param className The name of the class.
-     * @return String The name of the class.
-     */
-    private String getMessageComposerClassName(final String className)
-    {
-        // We may need to expand the classname...
-        if (className.indexOf('.') == -1)
-        {
-            return FileBytesMessageComposer.class.getPackage().getName() + "." + className;
-        }
-        return className;
-    }
 }

Added: labs/jbossesb/workspace/skeagh/routing/file/src/main/java/org/jboss/esb/file/FileOutboundRouter.java
===================================================================
--- labs/jbossesb/workspace/skeagh/routing/file/src/main/java/org/jboss/esb/file/FileOutboundRouter.java	                        (rev 0)
+++ labs/jbossesb/workspace/skeagh/routing/file/src/main/java/org/jboss/esb/file/FileOutboundRouter.java	2008-11-13 11:29:30 UTC (rev 23852)
@@ -0,0 +1,177 @@
+/*
+ * JBoss, Home of Professional Open Source Copyright 2008, Red Hat Middleware
+ * LLC, and individual contributors by the @authors tag. See the copyright.txt
+ * in the distribution for a full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it under the
+ * terms of the GNU Lesser General Public License as published by the Free
+ * Software Foundation; either version 2.1 of the License, or (at your option)
+ * any later version.
+ *
+ * This software is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this software; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA, or see the FSF
+ * site: http://www.fsf.org.
+ */
+package org.jboss.esb.file;
+
+import java.io.File;
+
+import org.apache.log4j.Logger;
+import org.jboss.esb.api.annotations.Initialize;
+import org.jboss.esb.api.annotations.Property;
+import org.jboss.esb.api.annotations.Property.Use;
+import org.jboss.esb.api.context.InvocationContext;
+import org.jboss.esb.api.exception.ConfigurationException;
+import org.jboss.esb.api.message.Message;
+import org.jboss.esb.api.routing.OutboundRouter;
+import org.jboss.esb.api.routing.RoutingException;
+import org.jboss.esb.file.eval.PatternEvaluator;
+import org.jboss.esb.file.util.FileRouterUtil;
+import org.jboss.esb.file.writers.FileWriter;
+
+/**
+ * FileOutboundRouter is an OutboundRouter implementation that writes
+ * the ESB Message payload to a file on the file system.
+ *
+ * Example config:<br/>
+ * <pre>{@code
+ *
+ * <resources>
+ *     <resource id="schedule1" class="org.jboss.esb.schedule.SimpleSchedule">
+ *         <property name="frequency">100</property>
+ *         <property name="execCount">1</property>
+ *     </resource>
+ * </resources>
+ *
+ * <outRouter name="outfileRouter" class="org.jboss.esb.file.FileOutboundRouter">
+ *     <property name="scheduleResourceId">schedule1</property>
+ *     <property name="fileNamePattern">target/{name}.out</property>
+ * </outRouter>
+ *
+ * }</pre>
+ * <p/>
+ * Property description:
+ * <lu>
+ *  <li>scheduleResourceId      - the id of the schedule that this router will use.</li>
+ *  <li>fileNamePattern         - the file naming pattern used to name the output file.</li>
+ *  <li>fileWriterImpl          - the concrete {@link FileWriter} implementation to use. Default: org.jboss.esb.file.writers.FileWriterImpl</li>
+ *  <li>patternEvaluatorImpl    - the concrete {@link PatternEvaluator} implementation to use. Default: org.jboss.esb.file.eval.PatternEvaluatorImpl</li>
+ * </lu>
+ *
+ * @author <a href="mailto:dbevenius at jboss.com">Daniel Bevenius</a>
+ *
+ */
+public class FileOutboundRouter implements OutboundRouter
+{
+    /**
+     * Logger.
+     */
+    private final Logger logger = Logger.getLogger(FileInboundRouter.class);
+
+    /**
+     * The file rename pattern.
+     */
+    @Property(use = Use.REQUIRED, name = "fileNamePattern")
+    private String fileNamePattern;
+
+    /**
+     * The {@link FileWriter} implementation to be used.
+     */
+    @Property(use = Use.OPTIONAL, name = "fileWriterImpl", defaultVal = "org.jboss.esb.file.writers.FileWriterImpl")
+    private String fileWriterImpl;
+
+    /**
+     * The {@link PatternEvaluator} implementation to be used.
+     */
+    @Property(use = Use.OPTIONAL, name = "patternEvaluatorImpl", defaultVal = "org.jboss.esb.file.eval.PatternEvaluatorImpl")
+    private String patternEvaluatorImpl;
+
+    /**
+     * Name of this router. Will be injected by the deployment runtime.
+     */
+    private Object objectName;
+
+    /**
+     * Strategy for writing the message payload out to a file.
+     */
+    private FileWriter fileWriter;
+
+    /**
+     * Strategy for evaluating file names.
+     */
+    private PatternEvaluator patternEvaluator;
+
+    /**
+     * The output directory for files. This is extracted from the fileNamePattern.
+     */
+    private File outputDir;
+
+    /**
+     * Creates the output directory, the file writer strategy, and also
+     * creates the pattern evaluator to be used.
+     *
+     * @throws ConfigurationException If the configuration error is found.
+     */
+    @Initialize
+    public final void initialize() throws ConfigurationException
+    {
+        outputDir = FileRouterUtil.createTargetDirectory(fileNamePattern);
+        fileWriter = (FileWriter) FileRouterUtil.createInstance(fileWriterImpl);
+        patternEvaluator = (PatternEvaluator) FileRouterUtil.createInstance(patternEvaluatorImpl);
+
+        if (logger.isDebugEnabled())
+        {
+            logger.debug(this);
+        }
+    }
+
+    /**
+     * Performs the routing of the Message contents to a file.
+     *
+     * @param message The ESB Message object.
+     * @throws RoutingException If an error occurs while trying to write the file.
+     */
+    public final void route(final Message message) throws RoutingException
+    {
+        final InvocationContext invocationContext = InvocationContext.getContext();
+        final File toFile = new File(outputDir, patternEvaluator.evalFileName(fileNamePattern, invocationContext));
+        fileWriter.write(message, toFile, invocationContext);
+    }
+
+    /**
+     * Gets the pattern used when creating the destination file.
+     *
+     * @return String The set file name pattern.
+     */
+    public final String getFileNamePattern()
+    {
+        return fileNamePattern;
+    }
+
+    /**
+     * Gets the output directory.
+     *
+     * @return File The ouput directory
+     */
+    public final File getOutputDir()
+    {
+        return outputDir;
+    }
+
+    /**
+     * Returs a string representation of this router.
+     * @return String The string representation.
+     */
+    @Override
+    public final String toString()
+    {
+        return "OutboundRouter[name='" + objectName + "', outputDir='" + outputDir + "', fileNamePattern='" + fileNamePattern + "']";
+    }
+
+}

Modified: labs/jbossesb/workspace/skeagh/routing/file/src/main/java/org/jboss/esb/file/composers/AbstractFileMessageComposer.java
===================================================================
--- labs/jbossesb/workspace/skeagh/routing/file/src/main/java/org/jboss/esb/file/composers/AbstractFileMessageComposer.java	2008-11-13 05:51:22 UTC (rev 23851)
+++ labs/jbossesb/workspace/skeagh/routing/file/src/main/java/org/jboss/esb/file/composers/AbstractFileMessageComposer.java	2008-11-13 11:29:30 UTC (rev 23852)
@@ -105,7 +105,7 @@
         {
             throw new MessageProcessingException("Error reading input file '" + currentFile.getAbsolutePath() + "'.", e);
         }
-        catch (final Throwable t)
+        catch (final Exception t)
         {
             throw new MessageProcessingException("Error creating message from input file '" + currentFile.getAbsolutePath() + "'.", t);
         }

Added: labs/jbossesb/workspace/skeagh/routing/file/src/main/java/org/jboss/esb/file/eval/PatternEvaluator.java
===================================================================
--- labs/jbossesb/workspace/skeagh/routing/file/src/main/java/org/jboss/esb/file/eval/PatternEvaluator.java	                        (rev 0)
+++ labs/jbossesb/workspace/skeagh/routing/file/src/main/java/org/jboss/esb/file/eval/PatternEvaluator.java	2008-11-13 11:29:30 UTC (rev 23852)
@@ -0,0 +1,66 @@
+/*
+ * JBoss, Home of Professional Open Source Copyright 2008, Red Hat Middleware
+ * LLC, and individual contributors by the @authors tag. See the copyright.txt
+ * in the distribution for a full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it under the
+ * terms of the GNU Lesser General Public License as published by the Free
+ * Software Foundation; either version 2.1 of the License, or (at your option)
+ * any later version.
+ *
+ * This software is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this software; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA, or see the FSF
+ * site: http://www.fsf.org.
+ */
+package org.jboss.esb.file.eval;
+
+import org.jboss.esb.api.context.InvocationContext;
+
+/**
+ * PatternEvaluator.
+ *
+ * @author <a href="mailto:dbevenius at jboss.com">Daniel Bevenius</a>
+ *
+ */
+public interface PatternEvaluator
+{
+    /**
+     * String used as a replacement key.
+     */
+    String FILE_NAME = "${name}";
+
+    /**
+     * String used as a replacement key.
+     */
+    String PREFIX_TOKEN = "${prefix}";
+
+    /**
+     * String used as a replacement key.
+     */
+    String SUFFIX_TOKEN = "${suffix}";
+
+    /**
+     * String used as a replacement key.
+     */
+    String LIFECYCLE_ID_TOKEN = "${lifecycleid}";
+
+    /**
+     * String used as a replacement token.
+     */
+    String TIMESTAMP_TOKEN = "${timestamp}";
+
+    /**
+     * Evals a pattern into a valid file name.
+     *
+     * @param filePattern The file pattern to evaluate.
+     * @param invocationContext The invokation context.
+     * @return String A valid file name.
+     */
+    String evalFileName(final String filePattern, final InvocationContext invocationContext);
+}

Added: labs/jbossesb/workspace/skeagh/routing/file/src/main/java/org/jboss/esb/file/eval/PatternEvaluatorImpl.java
===================================================================
--- labs/jbossesb/workspace/skeagh/routing/file/src/main/java/org/jboss/esb/file/eval/PatternEvaluatorImpl.java	                        (rev 0)
+++ labs/jbossesb/workspace/skeagh/routing/file/src/main/java/org/jboss/esb/file/eval/PatternEvaluatorImpl.java	2008-11-13 11:29:30 UTC (rev 23852)
@@ -0,0 +1,58 @@
+/*
+ * JBoss, Home of Professional Open Source Copyright 2008, Red Hat Middleware
+ * LLC, and individual contributors by the @authors tag. See the copyright.txt
+ * in the distribution for a full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it under the
+ * terms of the GNU Lesser General Public License as published by the Free
+ * Software Foundation; either version 2.1 of the License, or (at your option)
+ * any later version.
+ *
+ * This software is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this software; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA, or see the FSF
+ * site: http://www.fsf.org.
+ */
+package org.jboss.esb.file.eval;
+
+import java.io.File;
+
+import org.jboss.esb.api.context.InvocationContext;
+import org.jboss.esb.file.composers.AbstractFileMessageComposer;
+import org.jboss.esb.util.FileUtil;
+
+/**
+ * Impl.
+ *
+ * @author <a href="mailto:dbevenius at jboss.com">Daniel Bevenius</a>
+ *
+ */
+public class PatternEvaluatorImpl implements PatternEvaluator
+{
+    /**
+     *
+     * @param filePattern The file pattern.
+     * @param invocationContext The invokation context.
+     * @return String the file name.
+     */
+    public final String evalFileName(final String filePattern, final InvocationContext invocationContext)
+    {
+        String newName = FileUtil.removePath(filePattern);
+
+        File file = (File) invocationContext.getContextObject(AbstractFileMessageComposer.PROP_FILE_OBJ);
+        if (file != null)
+        {
+            newName = newName.replace(FILE_NAME, file.getName());
+        }
+
+        newName = newName.replace(TIMESTAMP_TOKEN, String.valueOf(System.currentTimeMillis()));
+
+        return newName;
+    }
+
+}

Added: labs/jbossesb/workspace/skeagh/routing/file/src/main/java/org/jboss/esb/file/eval/package.html
===================================================================
--- labs/jbossesb/workspace/skeagh/routing/file/src/main/java/org/jboss/esb/file/eval/package.html	                        (rev 0)
+++ labs/jbossesb/workspace/skeagh/routing/file/src/main/java/org/jboss/esb/file/eval/package.html	2008-11-13 11:29:30 UTC (rev 23852)
@@ -0,0 +1,8 @@
+<html>
+<head></head>
+<body>
+JBoss Routing - File Evaluators.
+
+<h1>Overview</h1>
+</body>
+</html>
\ No newline at end of file

Modified: labs/jbossesb/workspace/skeagh/routing/file/src/main/java/org/jboss/esb/file/lifecycle/DefaultFileLifecycle.java
===================================================================
--- labs/jbossesb/workspace/skeagh/routing/file/src/main/java/org/jboss/esb/file/lifecycle/DefaultFileLifecycle.java	2008-11-13 05:51:22 UTC (rev 23851)
+++ labs/jbossesb/workspace/skeagh/routing/file/src/main/java/org/jboss/esb/file/lifecycle/DefaultFileLifecycle.java	2008-11-13 11:29:30 UTC (rev 23852)
@@ -25,9 +25,13 @@
 import java.util.UUID;
 
 import org.apache.log4j.Logger;
+import org.jboss.esb.util.AssertArgument;
+import org.jboss.esb.util.FileUtil;
 
 /**
- * Default file lifecycle. <p/> If the "processedRenamePattern" property is not
+ * Default file lifecycle.
+ * <p/>
+ * If the "processedRenamePattern" property is not
  * specified, the file is deleted.
  *
  * @author <a href="mailto:tom.fennelly at jboss.com">tom.fennelly at jboss.com</a>
@@ -106,7 +110,7 @@
      */
     public final File toWorking()
     {
-        return renameFile(config.getWorkingDir(), config.getWorkingRenamePattern());
+        return renameFile(config.getWorkingRenamePattern());
     }
 
     /**
@@ -117,7 +121,7 @@
      */
     public final File toError()
     {
-        return renameFile(config.getErrorDir(), config.getErrorRenamePattern());
+        return renameFile(config.getErrorRenamePattern());
     }
 
     /**
@@ -130,7 +134,7 @@
     {
         if (config.getProcessedRenamePattern() != null)
         {
-            return renameFile(config.getProcessedDir(), config.getProcessedRenamePattern());
+            return renameFile(config.getProcessedRenamePattern());
         }
         else
         {
@@ -171,11 +175,12 @@
      */
     public final String evalNameExpression(final String renameExpression)
     {
-        String newName = renameExpression;
+        String newName = FileUtil.removePath(renameExpression);
 
         newName = newName.replace(FILE_NAME, fileName);
         newName = newName.replace(LIFECYCLE_ID_TOKEN, lifecycleId);
         newName = newName.replace(TIMESTAMP_TOKEN, String.valueOf(System.currentTimeMillis()));
+
         if (prefix != null)
         {
             newName = newName.replace(PREFIX_TOKEN, prefix);
@@ -219,39 +224,77 @@
      * Renames the file(getFile()) using the passed in rename expression,
      * and specifies the output directory.
      *
-     * @param toDir The target directory for this rename operation. If null then the current files directory is used as the output directory.
      * @param renameExpression The name expression for the destination file.
      * @return File File object to the renamed file, or null if the current file does not have a parent directory.
      */
-    private File renameFile(final File toDir, final String renameExpression)
+    private File renameFile(final String renameExpression)
     {
-        final File currentRevision = getFile();
-        final String newName = evalNameExpression(renameExpression);
+        final File toDirectory = parseTargetDirectory(renameExpression);
+        createTargetDirectories(toDirectory);
 
-        final File dir = toDir == null ? currentRevision.getParentFile() : toDir;
+        final File toFile = new File(toDirectory, evalNameExpression(renameExpression));
+        checkThatDestinationFileDoesNotExists(toFile);
 
-        if (dir != null)
+        final boolean renameResult = getFile().renameTo(toFile);
+        if (!renameResult)
         {
+            throw new IllegalStateException("Was not able to rename file '" + getFile() + "' to '" + toFile + "'");
+        }
 
-            final File toFile = new File(dir, newName);
+        fileHistory.add(toFile);
+        return toFile;
+    }
 
-            if (!toFile.exists())
-            {
-                dir.mkdirs();
-                currentRevision.renameTo(toFile);
-                if (toFile.exists())
-                {
-                    fileHistory.add(toFile);
-                    return toFile;
-                }
-            }
-            else
-            {
-                log.warn("The file '" + toFile.getAbsolutePath() + "' already exists."
-                        + "Cannot continue processing. Please specify a different renaming "
-                        + "pattern, for example you might want to add ${timestamp}.processed.");
-            }
+    /**
+     * Simply checks if the passed in file exists.
+     *
+     * @param file File object to check if it exists. If so an IllegalStateException will be thrown.
+     */
+    private void checkThatDestinationFileDoesNotExists(final File file)
+    {
+        if (file.exists())
+        {
+            final String errorMsg = "The file '" + file.getAbsolutePath() + "' already exists."
+                    + "Cannot continue processing. Please specify a different renaming "
+                    + "pattern, for example you might want to add ${timestamp}.processed.";
+            throw new IllegalStateException(errorMsg);
         }
-        return null;
     }
+
+    /**
+     * Will try to create the passed in directory and call parent directories.
+     *
+     * @param dir The directory path.
+     */
+    private void createTargetDirectories(final File dir)
+    {
+        final boolean mkdirsResult = dir.mkdirs();
+        if (!mkdirsResult && !dir.exists())
+        {
+            throw new IllegalStateException("Could not create the directory '" + dir + "'. Please make sure that proper access rights have been given to all parent directories");
+        }
+    }
+
+    /**
+     * Retrieves the path information contained in the passed in expression.
+     *
+     * @param fromExpression The expression pattern which might contain a path.
+     * @return File A file object to the path specified in the expression.
+     *
+     */
+    public final File parseTargetDirectory(final String fromExpression)
+    {
+        AssertArgument.isNotNullAndNotEmpty(fromExpression, "expression");
+
+        File directory = FileUtil.evalTargetDirectory(fromExpression);
+        if (directory != null)
+        {
+            return directory;
+        }
+        else
+        {
+            return getFile().getParentFile();
+        }
+    }
+
 }

Modified: labs/jbossesb/workspace/skeagh/routing/file/src/main/java/org/jboss/esb/file/lifecycle/FileLifecycle.java
===================================================================
--- labs/jbossesb/workspace/skeagh/routing/file/src/main/java/org/jboss/esb/file/lifecycle/FileLifecycle.java	2008-11-13 05:51:22 UTC (rev 23851)
+++ labs/jbossesb/workspace/skeagh/routing/file/src/main/java/org/jboss/esb/file/lifecycle/FileLifecycle.java	2008-11-13 11:29:30 UTC (rev 23852)
@@ -41,29 +41,14 @@
     /**
      * Key used in properties map.
      */
-    String WORKING_DIRECTORY = "workingDirectory";
-
-    /**
-     * Key used in properties map.
-     */
     String ERROR_RENAME_PATTERN = "errorRenamePattern";
 
     /**
      * Key used in properties map.
      */
-    String ERROR_DIRECTORY = "errorDirectory";
-
-    /**
-     * Key used in properties map.
-     */
     String PROCESSED_RENAME_PATTERN = "processedRenamePattern";
 
     /**
-     * Key used in properties map.
-     */
-    String PROCESSED_DIRECTORY = "processedDirectory";
-
-    /**
      * String used as a replacement key.
      */
     String FILE_NAME = "${name}";

Modified: labs/jbossesb/workspace/skeagh/routing/file/src/main/java/org/jboss/esb/file/lifecycle/FileLifecycleConfig.java
===================================================================
--- labs/jbossesb/workspace/skeagh/routing/file/src/main/java/org/jboss/esb/file/lifecycle/FileLifecycleConfig.java	2008-11-13 05:51:22 UTC (rev 23851)
+++ labs/jbossesb/workspace/skeagh/routing/file/src/main/java/org/jboss/esb/file/lifecycle/FileLifecycleConfig.java	2008-11-13 11:29:30 UTC (rev 23852)
@@ -19,7 +19,6 @@
  */
 package org.jboss.esb.file.lifecycle;
 
-import java.io.File;
 import java.util.Properties;
 
 import org.jboss.esb.api.exception.ConfigurationException;
@@ -47,21 +46,6 @@
     private String processedRenamePattern;
 
     /**
-     * The directory where files that are in process(working) are placed.
-     */
-    private File workingDir;
-
-    /**
-     * The directory where processed file will be places.
-     */
-    private File processedDir;
-
-    /**
-     * The directory where error files will be placed.
-     */
-    private File errorDir;
-
-    /**
      * Configures this instance.
      *
      * @param properties The properties used in initialize this instance.
@@ -72,10 +56,6 @@
         workingRenamePattern = properties.getProperty(FileLifecycle.WORKING_RENAME_PATTERN, FileLifecycle.PREFIX_TOKEN + "." + FileLifecycle.SUFFIX_TOKEN + ".working");
         errorRenamePattern = properties.getProperty(FileLifecycle.ERROR_RENAME_PATTERN, FileLifecycle.PREFIX_TOKEN + "." + FileLifecycle.SUFFIX_TOKEN + ".error");
         processedRenamePattern = properties.getProperty(FileLifecycle.PROCESSED_RENAME_PATTERN, FileLifecycle.PREFIX_TOKEN + "." + FileLifecycle.SUFFIX_TOKEN + ".processed");
-
-        workingDir = getFileRefToDir(FileLifecycle.WORKING_DIRECTORY, properties);
-        processedDir = getFileRefToDir(FileLifecycle.PROCESSED_DIRECTORY, properties);
-        errorDir = getFileRefToDir(FileLifecycle.ERROR_DIRECTORY, properties);
     }
 
     /**
@@ -102,58 +82,4 @@
         return processedRenamePattern;
     }
 
-    /**
-     * Gets the name of the directory in-process(working) files files
-     * will be stored.
-     *
-     * @return File File object to the directory working files are stored.
-     */
-    public final File getWorkingDir()
-    {
-        return workingDir;
-    }
-
-    /**
-     * Gets the name of the directory where processed files
-     * will be stored.
-     *
-     * @return File File object to the directory where processed files are stored.
-     */
-    public final File getProcessedDir()
-    {
-        return processedDir;
-    }
-
-    /**
-     * Gets the name of the directory where error files
-     * will be stored.
-     *
-     * @return File File object to the directory where error files are stored.
-     */
-    public final File getErrorDir()
-    {
-        return errorDir;
-    }
-
-    /**
-     *
-     * @param propertyName The name of the property to extract.
-     * @param properties The properties.
-     * @return File File object to directory, or null if the propertyName did not exist in the properties object.
-     * @throws ConfigurationException If the directory was specified in the properties but does not exist in the file system.
-     */
-    private File getFileRefToDir(final String propertyName, final Properties properties) throws ConfigurationException
-    {
-        final String dirName = properties.getProperty(propertyName);
-        if (dirName != null)
-        {
-            final File directory = new File(dirName);
-            if (!directory.exists())
-            {
-                throw new ConfigurationException("The directory '" + directory.getAbsolutePath() + "' specified for '" + propertyName + "' does not exist.");
-            }
-            return directory;
-        }
-        return null;
-    }
 }

Added: labs/jbossesb/workspace/skeagh/routing/file/src/main/java/org/jboss/esb/file/util/FileRouterUtil.java
===================================================================
--- labs/jbossesb/workspace/skeagh/routing/file/src/main/java/org/jboss/esb/file/util/FileRouterUtil.java	                        (rev 0)
+++ labs/jbossesb/workspace/skeagh/routing/file/src/main/java/org/jboss/esb/file/util/FileRouterUtil.java	2008-11-13 11:29:30 UTC (rev 23852)
@@ -0,0 +1,97 @@
+/*
+ * JBoss, Home of Professional Open Source Copyright 2008, Red Hat Middleware
+ * LLC, and individual contributors by the @authors tag. See the copyright.txt
+ * in the distribution for a full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it under the
+ * terms of the GNU Lesser General Public License as published by the Free
+ * Software Foundation; either version 2.1 of the License, or (at your option)
+ * any later version.
+ *
+ * This software is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this software; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA, or see the FSF
+ * site: http://www.fsf.org.
+ */
+package org.jboss.esb.file.util;
+
+import java.io.File;
+import java.io.IOException;
+
+import org.jboss.esb.api.exception.ConfigurationException;
+import org.jboss.esb.classpath.ClassUtil;
+import org.jboss.esb.file.FileOutboundRouter;
+import org.jboss.esb.util.FileUtil;
+
+/**
+ * Utility methods that are common to File Routers, both inbound and
+ * outbound.
+ *
+ * @author <a href="mailto:dbevenius at jboss.com">Daniel Bevenius</a>
+ *
+ */
+public final class FileRouterUtil
+{
+    /**
+     * Private constructor.
+     */
+    private FileRouterUtil()
+    {
+    }
+
+    /**
+     * Creates a new instance of the passed in class name.
+     *
+     * @param className The name of the class to create. Must be an instance of FileWriter
+     * @return Object New instance of the class.
+     * @throws ConfigurationException If it was not able to create the class.
+     */
+    public static Object createInstance(final String className) throws ConfigurationException
+    {
+        try
+        {
+            final Class<?> forName = ClassUtil.forName(className, FileOutboundRouter.class);
+            return forName.newInstance();
+        }
+        catch (final ClassNotFoundException e)
+        {
+            throw new ConfigurationException("Could not load class '" + className + "'. Exception was: " + e);
+        }
+        catch (final InstantiationException e)
+        {
+            throw new ConfigurationException("InstantiationException:" + e);
+        }
+        catch (final IllegalAccessException e)
+        {
+            throw new ConfigurationException("IllegalAccessException:" + e);
+        }
+    }
+
+    /**
+     * Creates the output directory by parsing the fileNamePattern
+     * for a parent directory.
+     *
+     * @param pattern The file name pattern to parse.
+     * @return File The directory.
+     * @throws ConfigurationException If it was not possible to create the directory
+     */
+    public static File createTargetDirectory(final String pattern) throws ConfigurationException
+    {
+        final File dir = FileUtil.evalTargetDirectory(pattern);
+        try
+        {
+            FileUtil.createDestinationDirectory(dir);
+        }
+        catch (IOException e)
+        {
+            throw new ConfigurationException(e.getMessage(), e);
+        }
+        return dir;
+    }
+
+}

Added: labs/jbossesb/workspace/skeagh/routing/file/src/main/java/org/jboss/esb/file/util/package.html
===================================================================
--- labs/jbossesb/workspace/skeagh/routing/file/src/main/java/org/jboss/esb/file/util/package.html	                        (rev 0)
+++ labs/jbossesb/workspace/skeagh/routing/file/src/main/java/org/jboss/esb/file/util/package.html	2008-11-13 11:29:30 UTC (rev 23852)
@@ -0,0 +1,8 @@
+<html>
+<head></head>
+<body>
+JBoss Routing - File Util.
+
+<h1>Overview</h1>
+</body>
+</html>
\ No newline at end of file

Added: labs/jbossesb/workspace/skeagh/routing/file/src/main/java/org/jboss/esb/file/writers/FileWriter.java
===================================================================
--- labs/jbossesb/workspace/skeagh/routing/file/src/main/java/org/jboss/esb/file/writers/FileWriter.java	                        (rev 0)
+++ labs/jbossesb/workspace/skeagh/routing/file/src/main/java/org/jboss/esb/file/writers/FileWriter.java	2008-11-13 11:29:30 UTC (rev 23852)
@@ -0,0 +1,46 @@
+/*
+ * JBoss, Home of Professional Open Source Copyright 2008, Red Hat Middleware
+ * LLC, and individual contributors by the @authors tag. See the copyright.txt
+ * in the distribution for a full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it under the
+ * terms of the GNU Lesser General Public License as published by the Free
+ * Software Foundation; either version 2.1 of the License, or (at your option)
+ * any later version.
+ *
+ * This software is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this software; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA, or see the FSF
+ * site: http://www.fsf.org.
+ */
+package org.jboss.esb.file.writers;
+
+import java.io.File;
+import org.jboss.esb.api.context.InvocationContext;
+import org.jboss.esb.api.message.Message;
+import org.jboss.esb.api.routing.RoutingException;
+
+/**
+ * A FileWriter takes care of the actual writing of a message's payload
+ * to a file on the file system.
+ *
+ * @author <a href="mailto:dbevenius at jboss.com">Daniel Bevenius</a>
+ *
+ */
+public interface FileWriter
+{
+    /**
+     * Write the ESB Messages payload to the passed in file.
+     *
+     * @param message The ESB Message object whose payload should be written.
+     * @param toFile The file that should be written to.
+     * @param invocationContext The InvokcationContext from which additional infomation may be retrieved.
+     * @throws RoutingException If an error occurs while trying to write to the file.
+     */
+    void write(final Message message, final File toFile, final InvocationContext invocationContext) throws RoutingException;
+}

Added: labs/jbossesb/workspace/skeagh/routing/file/src/main/java/org/jboss/esb/file/writers/FileWriterImpl.java
===================================================================
--- labs/jbossesb/workspace/skeagh/routing/file/src/main/java/org/jboss/esb/file/writers/FileWriterImpl.java	                        (rev 0)
+++ labs/jbossesb/workspace/skeagh/routing/file/src/main/java/org/jboss/esb/file/writers/FileWriterImpl.java	2008-11-13 11:29:30 UTC (rev 23852)
@@ -0,0 +1,194 @@
+/*
+ * JBoss, Home of Professional Open Source Copyright 2008, Red Hat Middleware
+ * LLC, and individual contributors by the @authors tag. See the copyright.txt
+ * in the distribution for a full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it under the
+ * terms of the GNU Lesser General Public License as published by the Free
+ * Software Foundation; either version 2.1 of the License, or (at your option)
+ * any later version.
+ *
+ * This software is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this software; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA, or see the FSF
+ * site: http://www.fsf.org.
+ */
+package org.jboss.esb.file.writers;
+
+import java.io.BufferedWriter;
+import java.io.Closeable;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.io.OutputStream;
+import java.io.OutputStreamWriter;
+import java.io.Writer;
+
+import org.apache.log4j.Logger;
+import org.jboss.esb.api.context.InvocationContext;
+import org.jboss.esb.api.message.Message;
+import org.jboss.esb.api.routing.RoutingException;
+import org.jboss.esb.util.AssertArgument;
+
+/**
+ * Default implementation of a FileWriter.
+ *
+ * @author <a href="mailto:dbevenius at jboss.com">Daniel Bevenius</a>
+ *
+ */
+public class FileWriterImpl implements FileWriter
+{
+    /**
+     * Logger.
+     */
+    private final Logger logger = Logger.getLogger(FileWriterImpl.class);
+
+    /**
+     * Write the ESB Messages payload to the passed in file.
+     *
+     * @param message The ESB Message object whose payload should be written.
+     * @param toFile The file that should be written to.
+     * @param invocationContext The InvokcationContext from which additional infomation may be retrieved.
+     * @throws RoutingException If an error occurs while trying to write to the file.
+     */
+    public final void write(final Message message, final File toFile, final InvocationContext invocationContext) throws RoutingException
+    {
+        AssertArgument.isNotNull(message, "message");
+        AssertArgument.isNotNull(toFile, "toFile");
+
+        FileOutputStream fileOutputStream = null;
+        try
+        {
+            fileOutputStream = new FileOutputStream(toFile);
+
+            final Object payload = message.getPayload();
+            if (payload instanceof String)
+            {
+                final byte[] bytes = ((String)payload).getBytes();
+                writeBytes(bytes, fileOutputStream);
+            }
+            else if (payload instanceof byte[])
+            {
+                final byte[] bytes = (byte[])payload;
+                writeBytes(bytes, fileOutputStream);
+            }
+            else if (payload instanceof InputStreamReader)
+            {
+                final InputStreamReader reader = (InputStreamReader)payload;
+                writeInputStream(reader, fileOutputStream);
+            }
+            else if (payload instanceof FileInputStream)
+            {
+                final FileInputStream fis = (FileInputStream)payload;
+                writeFileInputStream(fis, fileOutputStream);
+            }
+        }
+        catch (final FileNotFoundException e)
+        {
+            throw new RoutingException("Could not find file '" + toFile.getAbsolutePath() + "'.", e);
+        }
+        catch (final IOException e)
+        {
+            throw new RoutingException("IOException while trying to save file " + toFile.getAbsolutePath() + "'.", e);
+        }
+        finally
+        {
+            close(fileOutputStream);
+        }
+    }
+
+    /**
+     *
+     * @param inputStream This input stream to read from.
+     * @param to The output stream to write to
+     * @throws IOException If an IOException is raised while trying to write to the stream.
+     */
+    private void writeFileInputStream(final FileInputStream inputStream, final FileOutputStream to) throws IOException
+    {
+        try
+        {
+            byte[] buffer = new byte[1024];
+            while (true)
+            {
+                int bytesRead = inputStream.read(buffer);
+                if (bytesRead == -1)
+                {
+                    break;
+                }
+                to.write(buffer, 0, bytesRead);
+            }
+        }
+        finally
+        {
+           inputStream.close();
+        }
+    }
+
+    /**
+     *
+     * Note that this method does not close the passed in reader.
+     *
+     * @param reader This input stream to read from.
+     * @param to The output stream to write to
+     * @throws IOException If an IOException is raised while trying to write to the stream.
+     */
+    private void writeInputStream(final InputStreamReader reader, final FileOutputStream to) throws IOException
+    {
+        final Writer writer = new BufferedWriter(new OutputStreamWriter(to));
+        try
+        {
+            while (true)
+            {
+                int bytesRead = reader.read();
+                if (bytesRead == -1)
+                {
+                    break;
+                }
+                writer.write(bytesRead);
+                writer.flush();
+            }
+        }
+        finally
+        {
+            reader.close();
+        }
+    }
+
+    /**
+     *
+     * @param bytes The bytes write to the output stream.
+     * @param out The output stream.
+     * @throws IOException If an exception occurs while writing to the output stream.
+     */
+    private void writeBytes(final byte[] bytes, final OutputStream out) throws IOException
+    {
+        out.write(bytes);
+    }
+
+    /**
+     * Just closes the passed in closeable.
+     * Only logs if an IOException occurrs while closing.
+     *
+     * @param closable The closeable
+     */
+    private void close(final Closeable closable)
+    {
+        try
+        {
+            closable.close();
+        }
+        catch (final IOException e)
+        {
+            logger.error("IOException while trying to close output stream", e);
+        }
+    }
+
+}

Added: labs/jbossesb/workspace/skeagh/routing/file/src/main/java/org/jboss/esb/file/writers/package.html
===================================================================
--- labs/jbossesb/workspace/skeagh/routing/file/src/main/java/org/jboss/esb/file/writers/package.html	                        (rev 0)
+++ labs/jbossesb/workspace/skeagh/routing/file/src/main/java/org/jboss/esb/file/writers/package.html	2008-11-13 11:29:30 UTC (rev 23852)
@@ -0,0 +1,8 @@
+<html>
+<head></head>
+<body>
+JBoss Routing - File - Writers
+
+<h1>Overview</h1>
+</body>
+</html>
\ No newline at end of file

Modified: labs/jbossesb/workspace/skeagh/routing/file/src/test/java/org/jboss/esb/file/FileInboundRouterTest.java
===================================================================
--- labs/jbossesb/workspace/skeagh/routing/file/src/test/java/org/jboss/esb/file/FileInboundRouterTest.java	2008-11-13 05:51:22 UTC (rev 23851)
+++ labs/jbossesb/workspace/skeagh/routing/file/src/test/java/org/jboss/esb/file/FileInboundRouterTest.java	2008-11-13 11:29:30 UTC (rev 23852)
@@ -71,7 +71,7 @@
         fileRouter.initialize();
         fileRouter.onSchedule();
 
-        String[] list = files(inputFile.getParentFile(), "-processed");
+        String[] list = getFilesFromDir(inputFile.getParentFile(), "-processed");
         assertTrue("One file should have been created", list.length == 1);
         processedFile = new File(inputFile.getParentFile(), list[0]);
 
@@ -94,15 +94,15 @@
         assertNotNull(context.getContextObject(AbstractFileMessageComposer.PROP_FILE_OBJ));
         assertNotNull(context.getContextObject(AbstractFileMessageComposer.PROP_FILE_LENGTH));
 
-        final String[] list = files(inputFile.getParentFile(), "-processed");
+        final String[] list = getFilesFromDir(inputFile.getParentFile(), "-processed");
         processedFile = new File(inputFile.getParentFile(), list[0]);
     }
 
     @Test
     public void onScheduleWithDifferentOutputDirectory() throws IOException, ConfigurationException, SchedulingException, DeploymentException
     {
-        final InboundRouterConfig inboundRouterConfig = DeploymentUtil.getInboundRouter("fileRouter2", runtime);
-        final FileInboundRouter fileRouter = (FileInboundRouter) inboundRouterConfig.getRouter();
+        final InboundRouterConfig routerConfig = DeploymentUtil.getInboundRouter("fileRouter2", runtime);
+        final FileInboundRouter fileRouter = (FileInboundRouter) routerConfig.getRouter();
         fileRouter.setDispatcher(dispatcher);
 
         final File processedDir = new File(inputFile.getParentFile() + File.separator + "processedDir");
@@ -111,7 +111,7 @@
         fileRouter.initialize();
         fileRouter.onSchedule();
 
-        final String[] list = files(processedDir, ".processed");
+        final String[] list = getFilesFromDir(processedDir, ".processed");
         assertNotNull(list);
         assertTrue(list.length > 0);
         processedFile = new File(processedDir, list[0]);
@@ -143,7 +143,7 @@
 
     private File createFile(final FileInboundRouter fileRouter, final String payload) throws IOException
     {
-        final File workingDir = new File(fileRouter.getInputDirName());
+        final File workingDir = new File("target" + File.separator + "test-classes");
         final File file = new File(workingDir, "fileRouterTest.txt");
 
         final FileWriter fileWriter = new FileWriter(file);
@@ -161,6 +161,7 @@
     private class MockDispatcher implements MessageDispatcher
     {
         private Message message;
+
         public Message getMessage()
         {
             return message;
@@ -186,14 +187,15 @@
 
     }
 
-    private String[] files(final File dir, final String suffix)
+    private String[] getFilesFromDir(final File dir, final String suffix)
     {
-        String[] list = dir.list(new FilenameFilter() {
-            public boolean accept(File dir, String name)
+        String[] files = dir.list( new FilenameFilter()
+        {
+            public boolean accept(final File dir, final String fileName)
             {
-                return name.endsWith(suffix);
+                return fileName.endsWith(suffix);
             }
         });
-        return list;
+        return files;
     }
 }

Added: labs/jbossesb/workspace/skeagh/routing/file/src/test/java/org/jboss/esb/file/FileOutboundRouterTest.java
===================================================================
--- labs/jbossesb/workspace/skeagh/routing/file/src/test/java/org/jboss/esb/file/FileOutboundRouterTest.java	                        (rev 0)
+++ labs/jbossesb/workspace/skeagh/routing/file/src/test/java/org/jboss/esb/file/FileOutboundRouterTest.java	2008-11-13 11:29:30 UTC (rev 23852)
@@ -0,0 +1,102 @@
+/*
+ * JBoss, Home of Professional Open Source Copyright 2008, Red Hat Middleware
+ * LLC, and individual contributors by the @authors tag. See the copyright.txt
+ * in the distribution for a full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it under the
+ * terms of the GNU Lesser General Public License as published by the Free
+ * Software Foundation; either version 2.1 of the License, or (at your option)
+ * any later version.
+ *
+ * This software is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this software; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA, or see the FSF
+ * site: http://www.fsf.org.
+ */
+package org.jboss.esb.file;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import java.io.File;
+import java.io.IOException;
+import org.jboss.esb.api.context.InvocationContext;
+import org.jboss.esb.api.exception.ConfigurationException;
+import org.jboss.esb.api.message.Message;
+import org.jboss.esb.api.routing.RoutingException;
+import org.jboss.esb.api.service.ServiceName;
+import org.jboss.esb.deploy.DeploymentException;
+import org.jboss.esb.deploy.DeploymentRuntime;
+import org.jboss.esb.deploy.DeploymentUtil;
+import org.jboss.esb.deploy.config.OutboundRouterConfig;
+import org.jboss.esb.file.composers.AbstractFileMessageComposer;
+import org.jboss.esb.util.FileUtil;
+import org.junit.BeforeClass;
+import org.junit.Test;
+
+
+/**
+ * Test class for {@link FileOutboundRouter}.
+ *
+ * @author <a href="mailto:dbevenius at jboss.com">Daniel Bevenius</a>
+ *
+ */
+public class FileOutboundRouterTest
+{
+    private static DeploymentRuntime runtime;
+    private static OutboundRouterConfig outboundRouterConfig;
+
+    @Test
+    public void initialize() throws RoutingException, ConfigurationException
+    {
+        final FileOutboundRouter router = (FileOutboundRouter) outboundRouterConfig.getRouter();
+        router.initialize();
+
+        final File expectedOutputDir = new File("target" + File.separator + "test-classes");
+        final File actualOutputDir = router.getOutputDir();
+        assertEquals(expectedOutputDir.getAbsolutePath(), actualOutputDir.getAbsolutePath());
+
+        final String expectedNamePattern = "target/test-classes/${name}.out";
+        final String actualNamePattern = router.getFileNamePattern();
+        assertEquals(expectedNamePattern, actualNamePattern);
+    }
+
+    @Test
+    public void route() throws ConfigurationException, RoutingException, IOException
+    {
+        final FileOutboundRouter router = (FileOutboundRouter) outboundRouterConfig.getRouter();
+        router.initialize();
+
+        setFileNameInInvocationContext("file1");
+
+        final String payload = "Text payload string";
+        final Message message = new Message();
+        message.setPayload(payload.getBytes());
+
+        router.route(message);
+
+        final File testFile = new File(router.getOutputDir(), "file1.out");
+        byte[] fileContent = FileUtil.readFile(testFile);
+        assertEquals(payload, new String(fileContent));
+    }
+
+    private void setFileNameInInvocationContext(final String fileName)
+    {
+        InvocationContext invocationContext = new InvocationContext();
+        invocationContext.setContextObject(AbstractFileMessageComposer.PROP_FILE_OBJ, new File(fileName));
+        InvocationContext.setContext(invocationContext);
+    }
+
+    @BeforeClass
+    public static void classSetup() throws DeploymentException, IOException
+    {
+        runtime = DeploymentUtil.createRuntime(FileInboundRouterTest.class.getResourceAsStream("file-outbound-router.xml"));
+        outboundRouterConfig = DeploymentUtil.getOutboundRouter(new ServiceName("serviceCat", "serviceName"), "fileOutboundRouter", runtime);
+        assertNotNull("There should have been an router named 'fileRouter' in the config", outboundRouterConfig);
+    }
+
+}

Modified: labs/jbossesb/workspace/skeagh/routing/file/src/test/java/org/jboss/esb/file/file-inbound-router_01.xml
===================================================================
--- labs/jbossesb/workspace/skeagh/routing/file/src/test/java/org/jboss/esb/file/file-inbound-router_01.xml	2008-11-13 05:51:22 UTC (rev 23851)
+++ labs/jbossesb/workspace/skeagh/routing/file/src/test/java/org/jboss/esb/file/file-inbound-router_01.xml	2008-11-13 11:29:30 UTC (rev 23852)
@@ -11,8 +11,7 @@
         <service serviceCategory="service-cat" serviceName="service-a" serviceDescription="TestService" class="org.jboss.esb.file.MyTestService">
             <inRouter name="fileRouter" class="org.jboss.esb.file.FileInboundRouter">
                 <property name="scheduleResourceId">schedule1</property>
-                <property name="fileSelectorPattern">*.txt</property>
-                <property name="inputDir">target/test-classes/</property>
+                <property name="fileSelectorPattern">target/test-classes/*.txt</property>
                 <property name="workingRenamePattern">${name}-${timestamp}.${suffix}</property>
                 <property name="processedRenamePattern">${name}-${timestamp}-processed</property>
             </inRouter>
@@ -21,11 +20,9 @@
         <service serviceCategory="service-cat" serviceName="service-b" serviceDescription="TestService" class="org.jboss.esb.file.MyTestService">
             <inRouter name="fileRouter2" class="org.jboss.esb.file.FileInboundRouter">
                 <property name="scheduleResourceId">schedule1</property>
-                <property name="inputDir">target/test-classes/</property>
-                <property name="fileSelectorPattern">*.txt</property>
-                <property name="workingRenamePattern">${name}-${timestamp}.${suffix}</property>
-                <property name="processedDir">target/test-classes/processedDir</property>
-                <property name="processedRenamePattern">${name}.processed</property>
+                <property name="fileSelectorPattern">target/test-classes/*.txt</property>
+                <property name="workingRenamePattern">target/test/classes/${name}-${timestamp}.${suffix}</property>
+                <property name="processedRenamePattern">target/test-classes/processedDir/${name}.processed</property>
             </inRouter>
         </service>
     </services> 

Added: labs/jbossesb/workspace/skeagh/routing/file/src/test/java/org/jboss/esb/file/file-outbound-router.xml
===================================================================
--- labs/jbossesb/workspace/skeagh/routing/file/src/test/java/org/jboss/esb/file/file-outbound-router.xml	                        (rev 0)
+++ labs/jbossesb/workspace/skeagh/routing/file/src/test/java/org/jboss/esb/file/file-outbound-router.xml	2008-11-13 11:29:30 UTC (rev 23852)
@@ -0,0 +1,18 @@
+<jbossesb xmlns="http://www.jboss.org/jbossesb/xsd/jbossesb-5.0.xsd">
+
+	<resources>
+        <resource id="schedule1" class="org.jboss.esb.schedule.SimpleSchedule">
+            <property name="frequency">100</property>
+            <property name="execCount">1</property>
+        </resource>
+    </resources>
+
+    <services>
+        <service serviceCategory="serviceCat" serviceName="serviceName" serviceDescription="TestService" class="org.jboss.esb.file.MyTestService">
+            <outRouter name="fileOutboundRouter" class="org.jboss.esb.file.FileOutboundRouter">
+                <property name="fileNamePattern">target/test-classes/${name}.out</property>
+            </outRouter>
+        </service>
+    </services> 
+    
+</jbossesb>
\ No newline at end of file

Modified: labs/jbossesb/workspace/skeagh/routing/file/src/test/java/org/jboss/esb/file/lifecycle/DefaultFileLifecycleTest.java
===================================================================
--- labs/jbossesb/workspace/skeagh/routing/file/src/test/java/org/jboss/esb/file/lifecycle/DefaultFileLifecycleTest.java	2008-11-13 05:51:22 UTC (rev 23851)
+++ labs/jbossesb/workspace/skeagh/routing/file/src/test/java/org/jboss/esb/file/lifecycle/DefaultFileLifecycleTest.java	2008-11-13 11:29:30 UTC (rev 23852)
@@ -20,14 +20,16 @@
  */
 package org.jboss.esb.file.lifecycle;
 
-import static org.junit.Assert.*;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
 
 import java.io.File;
 import java.io.IOException;
-import java.util.List;
 import java.util.Properties;
 
 import org.jboss.esb.api.exception.ConfigurationException;
+import org.junit.Before;
 import org.junit.Test;
 
 /**
@@ -38,119 +40,200 @@
  */
 public class DefaultFileLifecycleTest
 {
+    /* Instance under test */
+    private DefaultFileLifecycle fileLifecycle;
+    private File testFile;
+    private File targetDir;
+    private File processedDir;
+    private File workingDir;
+    private FileLifecycleConfig fileLifecycleConfig;
+    private File errorDir;
+
     @Test
     public void setFile() throws IOException
     {
-        final DefaultFileLifecycle fileLifecycle = new DefaultFileLifecycle();
-        File file = File.createTempFile("junit", ".test");
-        file.deleteOnExit();
-        fileLifecycle.setFile(file);
+        assertEquals(1, fileLifecycle.getFileHistory().size());
+    }
 
-        List<File> fileHistory = fileLifecycle.getFileHistory();
-        assertEquals(1, fileHistory.size());
+    @Test
+    public void getFileHistory() throws IOException
+    {
+        assertEquals(1, fileLifecycle.getFileHistory().size());
 
-        final File file2 = File.createTempFile("junit2", ".test");
-        file2.deleteOnExit();
+        final File file2 = createTestFile("target", "testfile2");
+
         fileLifecycle.setFile(file2);
-        assertEquals(1, fileHistory.size());
+        assertEquals(1, fileLifecycle.getFileHistory().size());
     }
 
     @Test
+    public void evalNameExpression() throws IOException
+    {
+        final String pattern = "${name}-testing";
+        final String evaluated = fileLifecycle.evalNameExpression(pattern);
+        assertEquals( testFile.getName() + "-testing", evaluated);
+    }
+
+    @Test
+    public void getTargetDirectoryWithVariable() throws IOException
+    {
+        final String pattern = "${name}-testing";
+        File actualOutputDir = fileLifecycle.parseTargetDirectory(pattern);
+        assertEquals(targetDir, actualOutputDir);
+    }
+
+    @Test
+    public void getTargetDirectoryWithVariableAndPrefix() throws IOException
+    {
+        final String pattern = "someprefix-${name}-testing";
+        File actualOutputDir = fileLifecycle.parseTargetDirectory(pattern);
+        assertEquals(targetDir, actualOutputDir);
+    }
+
+    @Test
+    public void getTargetDirectoryWithPrefixAndNoVariable() throws IOException
+    {
+        final String pattern = "someprefix-testing";
+        File actualOutputDir = fileLifecycle.parseTargetDirectory(pattern);
+        assertEquals(targetDir, actualOutputDir);
+    }
+
+    @Test
+    public void getTargetDirectoryAbsoluteTargetDir() throws IOException
+    {
+        final String pattern = targetDir.getAbsolutePath() + File.separator + "${name}-testing";
+        final File actualOutputDir = fileLifecycle.parseTargetDirectory(pattern);
+        assertEquals(targetDir.getAbsolutePath(), actualOutputDir.getAbsolutePath());
+    }
+
+    @Test
+    public void getTargetDirectoryRelativeTargetDir() throws IOException
+    {
+        final String pattern = targetDir.getName() + File.separator + "${name}-testing";
+        final File actualOutputDir = fileLifecycle.parseTargetDirectory(pattern);
+        assertEquals(targetDir.getAbsolutePath(), actualOutputDir.getAbsolutePath());
+    }
+
+    @Test
+    public void getTargetDirectoryWithDifferentOuputDirectory() throws IOException
+    {
+        final String pattern = processedDir.getPath() + File.separator + "${name}-testing";
+        final File actualOutputDir = fileLifecycle.parseTargetDirectory(pattern);
+        assertEquals(processedDir, actualOutputDir);
+    }
+
+    @Test
+    public void getTargetDirectoryWithDifferentRelativeOuputDirectory() throws IOException
+    {
+        final String pattern = targetDir + File.separator + processedDir.getName() + File.separator + "${name}-testing";
+        final File actualOutputDir = fileLifecycle.parseTargetDirectory(pattern);
+        assertEquals(processedDir, actualOutputDir);
+    }
+
+    @Test
+    public void getTargetDirectoryWithDifferentRelativeOuputDirectoryNoVariables() throws IOException
+    {
+        final String pattern = targetDir + File.separator + processedDir.getName() + File.separator + "testing";
+        final File actualOutputDir = fileLifecycle.parseTargetDirectory(pattern);
+        assertEquals(processedDir.getAbsolutePath(), actualOutputDir.getAbsolutePath());
+    }
+
+    @Test
     public void toWorking() throws ConfigurationException, IOException
     {
-        final DefaultFileLifecycle fileLifecycle = new DefaultFileLifecycle();
-        final FileLifecycleConfig fileLifecycleConfig = new FileLifecycleConfig();
+        final String renamePattern = workingDir.getAbsoluteFile() + File.separator + "${name}.working";
+
         final Properties properties = new Properties();
-        final File workingDir = new File("workingDir");
-        final File testFile = File.createTempFile("fileLifecycleTest-toWorking", ".unit");
-        testFile.deleteOnExit();
+        properties.put(FileLifecycle.WORKING_RENAME_PATTERN, renamePattern);
+        fileLifecycleConfig.setConfiguration(properties);
+        fileLifecycle.setConfiguration(fileLifecycleConfig);
 
-        try
-        {
-            workingDir.mkdir();
-            properties.setProperty(FileLifecycle.WORKING_DIRECTORY, workingDir.getAbsolutePath());
-            fileLifecycleConfig.setConfiguration(properties);
-            fileLifecycle.setConfiguration(fileLifecycleConfig);
+        fileLifecycle.setFile(testFile);
+        fileLifecycle.toWorking();
 
-            fileLifecycle.setFile(testFile);
-            fileLifecycle.toWorking();
-
-            File workingFile = new File(workingDir, testFile.getName() + ".working");
-            assertTrue("File should have been moved to the working directory", workingFile.exists());
-            workingFile.delete();
-        }
-        finally
-        {
-            if (workingDir != null && workingDir.exists())
-            {
-                workingDir.delete();
-            }
-        }
+        File workingFile = new File(workingDir, testFile.getName() + ".working");
+        workingFile.deleteOnExit();
+        assertTrue("File should have been moved to the working directory", workingFile.exists());
     }
 
     @Test
     public void toError() throws ConfigurationException, IOException
     {
-        final DefaultFileLifecycle fileLifecycle = new DefaultFileLifecycle();
-        final FileLifecycleConfig fileLifecycleConfig = new FileLifecycleConfig();
+        final String renamePattern = errorDir.getAbsoluteFile() + File.separator + "${name}.error";
+
         final Properties properties = new Properties();
-        final File errorDir = new File("errorDir");
-        final File testFile = File.createTempFile("fileLifecycleTest-toError", ".unit");
-        testFile.deleteOnExit();
+        properties.put(FileLifecycle.ERROR_RENAME_PATTERN, renamePattern);
+        fileLifecycleConfig.setConfiguration(properties);
+        fileLifecycle.setConfiguration(fileLifecycleConfig);
 
-        try
-        {
-            errorDir.mkdir();
-            properties.setProperty(FileLifecycle.ERROR_DIRECTORY, errorDir.getAbsolutePath());
-            fileLifecycleConfig.setConfiguration(properties);
-            fileLifecycle.setConfiguration(fileLifecycleConfig);
+        fileLifecycle.setFile(testFile);
+        fileLifecycle.toError();
 
-            fileLifecycle.setFile(testFile);
-            fileLifecycle.toError();
-
-            File errorFile = new File(errorDir, testFile.getName() + ".error");
-            assertTrue("File should have been moved to the error directory", errorFile.exists());
-            errorFile.delete();
-        }
-        finally
-        {
-            if (errorDir != null && errorDir.exists())
-            {
-                errorDir.delete();
-            }
-        }
+        File errorFile = new File(errorDir, testFile.getName() + ".error");
+        errorFile.deleteOnExit();
+        assertTrue("File should have been moved to the error directory", errorFile.exists());
     }
 
     @Test
     public void toProcessed() throws ConfigurationException, IOException
     {
-        final DefaultFileLifecycle fileLifecycle = new DefaultFileLifecycle();
-        final FileLifecycleConfig fileLifecycleConfig = new FileLifecycleConfig();
+        final String renamePattern = processedDir.getAbsoluteFile() + File.separator + "${name}.done";
+
         final Properties properties = new Properties();
-        final File processedDir = new File("processedDir");
-        final File testFile = File.createTempFile("fileLifecycleTest-toProcessed", ".unit");
-        testFile.deleteOnExit();
+        properties.put(FileLifecycle.PROCESSED_RENAME_PATTERN, renamePattern);
+        fileLifecycleConfig.setConfiguration(properties);
+        fileLifecycle.setConfiguration(fileLifecycleConfig);
 
+        fileLifecycle.setFile(testFile);
+        fileLifecycle.toProcessed();
+
+        File processedFile = new File(processedDir, testFile.getName() + ".done");
+        processedFile.deleteOnExit();
+        assertTrue("File should have been moved to the processed directory", processedFile.exists());
+    }
+
+    @Before
+    public void setup()
+    {
+        fileLifecycle = new DefaultFileLifecycle();
+        fileLifecycleConfig = new FileLifecycleConfig();
+        testFile = createTestFile("target", DefaultFileLifecycleTest.class.getSimpleName());
+        fileLifecycle.setFile(testFile);
+
+        targetDir = new File(testFile.getParent());
+        processedDir = new File(testFile.getParent(), "processed");
+
+        workingDir = new File(testFile.getParent(), "working");
+
+        errorDir = new File(testFile.getParent(), "error");
+    }
+
+    private File createTestFile(final String dirname, final String filename)
+    {
+        return createTestFile(dirname, filename, true);
+    }
+
+    private File createTestFile(final String dirname, final String filename, final boolean deleteOnExit)
+    {
+        final File testFile = new File(getOutputDir(dirname), filename);
         try
         {
-            processedDir.mkdir();
-            properties.setProperty(FileLifecycle.PROCESSED_DIRECTORY, processedDir.getAbsolutePath());
-            fileLifecycleConfig.setConfiguration(properties);
-            fileLifecycle.setConfiguration(fileLifecycleConfig);
-
-            fileLifecycle.setFile(testFile);
-            fileLifecycle.toProcessed();
-
-            File processedFile = new File(processedDir, testFile.getName() + ".processed");
-            assertTrue("File should have been moved to the processed directory", processedFile.exists());
-            processedFile.delete();
+            testFile.createNewFile();
         }
-        finally
+        catch (IOException e)
         {
-            if (processedDir != null && processedDir.exists())
-            {
-                processedDir.delete();
-            }
+            fail(e.getMessage());
         }
+
+        if (deleteOnExit)
+        {
+            testFile.deleteOnExit();
+        }
+        return testFile;
     }
+
+    private File getOutputDir(final String dirname)
+    {
+        return new File(dirname + File.separator);
+    }
 }

Modified: labs/jbossesb/workspace/skeagh/routing/file/src/test/java/org/jboss/esb/file/lifecycle/FileLifecycleConfigTest.java
===================================================================
--- labs/jbossesb/workspace/skeagh/routing/file/src/test/java/org/jboss/esb/file/lifecycle/FileLifecycleConfigTest.java	2008-11-13 05:51:22 UTC (rev 23851)
+++ labs/jbossesb/workspace/skeagh/routing/file/src/test/java/org/jboss/esb/file/lifecycle/FileLifecycleConfigTest.java	2008-11-13 11:29:30 UTC (rev 23852)
@@ -21,9 +21,7 @@
 package org.jboss.esb.file.lifecycle;
 
 import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertTrue;
 
-import java.io.File;
 import java.util.Properties;
 
 import org.jboss.esb.api.exception.ConfigurationException;
@@ -94,92 +92,6 @@
         assertEquals(pattern, fileLifecycleConfig.getProcessedRenamePattern());
     }
 
-    @Test ( expected = ConfigurationException.class )
-    public void shouldThrowIfProcessDirDoesNotExist() throws ConfigurationException
-    {
-        final File processedDir = new File("processedDir");
-        configProperties.setProperty(FileLifecycle.PROCESSED_DIRECTORY, processedDir.getAbsolutePath());
-        fileLifecycleConfig.setConfiguration(configProperties);
-    }
-
-    @Test
-    public void setConfigurationProcessedDir() throws ConfigurationException
-    {
-        final File processedDir = new File("processedDir");
-        try
-        {
-            processedDir.mkdir();
-            configProperties.setProperty(FileLifecycle.PROCESSED_DIRECTORY, processedDir.getAbsolutePath());
-            fileLifecycleConfig.setConfiguration(configProperties);
-            assertTrue(fileLifecycleConfig.getProcessedDir().exists());
-        }
-        finally
-        {
-            if (processedDir != null && processedDir.exists())
-            {
-                processedDir.delete();
-            }
-        }
-    }
-
-    @Test ( expected = ConfigurationException.class )
-    public void shouldThrowIfErrorDirDoesNotExist() throws ConfigurationException
-    {
-        final File errorDir = new File("errorDir");
-        configProperties.setProperty(FileLifecycle.ERROR_DIRECTORY, errorDir.getAbsolutePath());
-        fileLifecycleConfig.setConfiguration(configProperties);
-    }
-
-    @Test
-    public void setConfigurationErrorDir() throws ConfigurationException
-    {
-        final File errorDir = new File("errorDir");
-        try
-        {
-            errorDir.mkdir();
-            configProperties.setProperty(FileLifecycle.ERROR_DIRECTORY, errorDir.getAbsolutePath());
-            fileLifecycleConfig.setConfiguration(configProperties);
-
-            assertTrue(fileLifecycleConfig.getErrorDir().exists());
-        }
-        finally
-        {
-            if (errorDir != null && errorDir.exists())
-            {
-                errorDir.delete();
-            }
-        }
-    }
-
-    @Test ( expected = ConfigurationException.class )
-    public void shouldThrowIfWorkingDirDoesNotExist() throws ConfigurationException
-    {
-        final File workingDir = new File("workingDir");
-        configProperties.setProperty(FileLifecycle.WORKING_DIRECTORY, workingDir.getAbsolutePath());
-        fileLifecycleConfig.setConfiguration(configProperties);
-    }
-
-    @Test
-    public void setConfigurationWorkingDir() throws ConfigurationException
-    {
-        final File workingDir = new File("workingDir");
-        try
-        {
-            workingDir.mkdir();
-            configProperties.setProperty(FileLifecycle.WORKING_DIRECTORY, workingDir.getAbsolutePath());
-            fileLifecycleConfig.setConfiguration(configProperties);
-            assertTrue(fileLifecycleConfig.getWorkingDir().exists());
-        }
-        finally
-        {
-            if (workingDir != null && workingDir.exists())
-            {
-                workingDir.delete();
-            }
-        }
-    }
-
-
     @Before
     public void setup()
     {

Added: labs/jbossesb/workspace/skeagh/routing/file/src/test/java/org/jboss/esb/file/writers/DefaultFileWriterTest.java
===================================================================
--- labs/jbossesb/workspace/skeagh/routing/file/src/test/java/org/jboss/esb/file/writers/DefaultFileWriterTest.java	                        (rev 0)
+++ labs/jbossesb/workspace/skeagh/routing/file/src/test/java/org/jboss/esb/file/writers/DefaultFileWriterTest.java	2008-11-13 11:29:30 UTC (rev 23852)
@@ -0,0 +1,135 @@
+/*
+ * JBoss, Home of Professional Open Source Copyright 2008, Red Hat Middleware
+ * LLC, and individual contributors by the @authors tag. See the copyright.txt
+ * in the distribution for a full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it under the
+ * terms of the GNU Lesser General Public License as published by the Free
+ * Software Foundation; either version 2.1 of the License, or (at your option)
+ * any later version.
+ *
+ * This software is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this software; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA, or see the FSF
+ * site: http://www.fsf.org.
+ */
+package org.jboss.esb.file.writers;
+
+import static org.junit.Assert.assertEquals;
+
+import java.io.ByteArrayInputStream;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.io.InputStreamReader;
+
+import org.jboss.esb.api.message.Message;
+import org.jboss.esb.api.routing.RoutingException;
+import org.jboss.esb.util.FileUtil;
+import org.junit.Before;
+import org.junit.Test;
+
+/**
+ * Test for {@link FileWriterImpl}
+ *
+ * @author <a href="mailto:dbevenius at jboss.com">Daniel Bevenius</a>
+ *
+ */
+public class DefaultFileWriterTest
+{
+    private static final String TEXT_PAYLOAD_STRING = "Text payload string";
+    private FileWriterImpl fileWriter = new FileWriterImpl();
+    private File testFile;
+
+    @Test
+    public void writeString() throws RoutingException, IOException
+    {
+        final Message message = createMessage(TEXT_PAYLOAD_STRING);
+
+        fileWriter.write(message, testFile, null);
+
+        String fileContent = FileUtil.readTextFile(testFile);
+        assertEquals(TEXT_PAYLOAD_STRING, fileContent);
+    }
+
+    @Test
+    public void writeByteArray() throws RoutingException, IOException
+    {
+        final Message message = createMessage(TEXT_PAYLOAD_STRING.getBytes());
+
+        fileWriter.write(message, testFile, null);
+
+        byte[] fileContent = FileUtil.readFile(testFile);
+        assertEquals(TEXT_PAYLOAD_STRING, new String(fileContent));
+    }
+
+    @Test
+    public void writeNullPayload() throws IOException, RoutingException
+    {
+        final Message message = createMessage(null);
+
+        fileWriter.write(message, testFile, null);
+
+        /*
+         * The logic here is that one might simply want to use a file to signal
+         * another system to start work. The payload would null and this will
+         * create an empty file.
+         */
+        assertEquals("", FileUtil.readTextFile(testFile));
+    }
+
+    @Test
+    public void writeInputStreamReader() throws IOException, RoutingException
+    {
+        final ByteArrayInputStream bin = new ByteArrayInputStream(TEXT_PAYLOAD_STRING.getBytes());
+        final InputStreamReader inputStreamReader = new InputStreamReader(bin);
+
+        final Message message = createMessage(inputStreamReader);
+        fileWriter.write(message, testFile, null);
+
+        assertEquals(TEXT_PAYLOAD_STRING, FileUtil.readTextFile(testFile));
+    }
+
+    @Test
+    public void writeFileInputStream() throws IOException, RoutingException
+    {
+        final File sourceFile = createTestFile(TEXT_PAYLOAD_STRING);
+        final FileInputStream fileInputStream = new FileInputStream(sourceFile);
+
+        final Message message = createMessage(fileInputStream);
+        fileWriter.write(message, testFile, null);
+
+        assertEquals(TEXT_PAYLOAD_STRING, FileUtil.readTextFile(testFile));
+    }
+
+    @Before
+    public void setup() throws IOException
+    {
+        testFile = File.createTempFile("DefaultFileWriterTest", ".test");
+        testFile.deleteOnExit();
+    }
+
+    private Message createMessage(final Object payload)
+    {
+        final Message message = new Message();
+        message.setPayload(payload);
+        return message;
+    }
+
+    private File createTestFile(final String content) throws IOException
+    {
+        final File file = File.createTempFile("DefaultFileWriterTest2", ".test");
+        file.deleteOnExit();
+        java.io.FileWriter writer = new java.io.FileWriter(file);
+        writer.write(content);
+        writer.flush();
+        writer.close();
+        return file;
+    }
+
+}




More information about the jboss-svn-commits mailing list