Coverage Report - org.mule.providers.file.FileConnector
 
Classes in this File Line Coverage Branch Coverage Complexity
FileConnector
0%
0/146
0%
0/33
2.143
 
 1  
 /*
 2  
  * $Id: FileConnector.java 7976 2007-08-21 14:26:13Z dirk.olmes $
 3  
  * --------------------------------------------------------------------------------------
 4  
  * Copyright (c) MuleSource, Inc.  All rights reserved.  http://www.mulesource.com
 5  
  *
 6  
  * The software in this package is published under the terms of the CPAL v1.0
 7  
  * license, a copy of which has been included with this distribution in the
 8  
  * LICENSE.txt file.
 9  
  */
 10  
 
 11  
 package org.mule.providers.file;
 12  
 
 13  
 import org.mule.config.MuleProperties;
 14  
 import org.mule.config.i18n.CoreMessages;
 15  
 import org.mule.providers.AbstractConnector;
 16  
 import org.mule.providers.file.filters.FilenameWildcardFilter;
 17  
 import org.mule.transformers.NoActionTransformer;
 18  
 import org.mule.transformers.simple.ByteArrayToSerializable;
 19  
 import org.mule.transformers.simple.SerializableToByteArray;
 20  
 import org.mule.umo.UMOComponent;
 21  
 import org.mule.umo.UMOException;
 22  
 import org.mule.umo.UMOMessage;
 23  
 import org.mule.umo.endpoint.UMOEndpoint;
 24  
 import org.mule.umo.endpoint.UMOImmutableEndpoint;
 25  
 import org.mule.umo.lifecycle.InitialisationException;
 26  
 import org.mule.umo.provider.DispatchException;
 27  
 import org.mule.umo.provider.UMOMessageReceiver;
 28  
 import org.mule.util.FileUtils;
 29  
 import org.mule.util.MapUtils;
 30  
 
 31  
 import java.io.File;
 32  
 import java.io.FileOutputStream;
 33  
 import java.io.IOException;
 34  
 import java.io.OutputStream;
 35  
 import java.util.Map;
 36  
 import java.util.Properties;
 37  
 
 38  
 import org.apache.commons.logging.Log;
 39  
 import org.apache.commons.logging.LogFactory;
 40  
 
 41  
 /**
 42  
  * <code>FileConnector</code> is used for setting up listeners on a directory and
 43  
  * for writing files to a directory. The connecotry provides support for defining
 44  
  * file output patterns and filters for receiving files.
 45  
  */
 46  
 
 47  
 public class FileConnector extends AbstractConnector
 48  
 {
 49  
     /**
 50  
      * logger used by this class
 51  
      */
 52  0
     private static Log logger = LogFactory.getLog(FileConnector.class);
 53  
 
 54  
     // These are properties that can be overridden on the Receiver by the endpoint
 55  
     // declaration
 56  
     public static final String PROPERTY_POLLING_FREQUENCY = "pollingFrequency";
 57  
     public static final String PROPERTY_FILE_AGE = "fileAge";
 58  
     public static final String PROPERTY_FILENAME = "filename";
 59  
     public static final String PROPERTY_ORIGINAL_FILENAME = "originalFilename";
 60  
     public static final String PROPERTY_OUTPUT_PATTERN = "outputPattern";
 61  
     public static final String PROPERTY_MOVE_TO_PATTERN = "moveToPattern";
 62  
     public static final String PROPERTY_MOVE_TO_DIRECTORY = "moveToDirectory";
 63  
     public static final String PROPERTY_DELETE_ON_READ = "autoDelete";
 64  
     public static final String PROPERTY_DIRECTORY = "directory";
 65  
     public static final String PROPERTY_SERVICE_OVERRIDE = "serviceOverrides";
 66  
     public static final String PROPERTY_WRITE_TO_DIRECTORY = "writeToDirectoryName";
 67  
 
 68  
     public static final long DEFAULT_POLLING_FREQUENCY = 1000;
 69  
 
 70  
     /**
 71  
      * Time in milliseconds to poll. On each poll the poll() method is called
 72  
      */
 73  0
     private long pollingFrequency = 0;
 74  
 
 75  0
     private String moveToPattern = null;
 76  
 
 77  0
     private String writeToDirectoryName = null;
 78  
 
 79  0
     private String moveToDirectoryName = null;
 80  
 
 81  0
     private String outputPattern = null;
 82  
 
 83  0
     private boolean outputAppend = false;
 84  
 
 85  0
     private boolean autoDelete = true;
 86  
 
 87  0
     private boolean checkFileAge = false;
 88  
 
 89  0
     private long fileAge = 0;
 90  
 
 91  0
     private FileOutputStream outputStream = null;
 92  
 
 93  0
     private boolean serialiseObjects = false;
 94  
 
 95  
     public FilenameParser filenameParser;
 96  
 
 97  
     /*
 98  
      * (non-Javadoc)
 99  
      * 
 100  
      * @see org.mule.providers.AbstractConnector#doInitialise()
 101  
      */
 102  
     public FileConnector()
 103  0
     {
 104  0
         filenameParser = new SimpleFilenameParser();
 105  0
     }
 106  
 
 107  
     protected Object getReceiverKey(UMOComponent component, UMOEndpoint endpoint)
 108  
     {
 109  0
         if (endpoint.getFilter() != null)
 110  
         {
 111  0
             return endpoint.getEndpointURI().getAddress() + "/"
 112  
                    + ((FilenameWildcardFilter) endpoint.getFilter()).getPattern();
 113  
         }
 114  0
         return endpoint.getEndpointURI().getAddress();
 115  
     }
 116  
 
 117  
     /**
 118  
      * Registers a listener for a particular directory The following properties can
 119  
      * be overriden in the endpoint declaration
 120  
      * <ul>
 121  
      * <li>moveToDirectory</li>
 122  
      * <li>filterPatterns</li>
 123  
      * <li>filterClass</li>
 124  
      * <li>pollingFrequency</li>
 125  
      * </ul>
 126  
      */
 127  
     public UMOMessageReceiver createReceiver(UMOComponent component, UMOEndpoint endpoint) throws Exception
 128  
     {
 129  0
         String readDir = endpoint.getEndpointURI().getAddress();
 130  0
         long polling = this.pollingFrequency;
 131  
 
 132  0
         String moveTo = moveToDirectoryName;
 133  0
         String moveToPattern = getMoveToPattern();
 134  
 
 135  0
         Map props = endpoint.getProperties();
 136  0
         if (props != null)
 137  
         {
 138  
             // Override properties on the endpoint for the specific endpoint
 139  0
             String move = (String) props.get(PROPERTY_MOVE_TO_DIRECTORY);
 140  0
             if (move != null)
 141  
             {
 142  0
                 moveTo = move;
 143  
             }
 144  0
             String tempMoveToPattern = (String) props.get(PROPERTY_MOVE_TO_PATTERN);
 145  0
             if (tempMoveToPattern != null)
 146  
             {
 147  0
                 if (logger.isDebugEnabled())
 148  
                 {
 149  0
                     logger.debug("set moveTo Pattern to: " + tempMoveToPattern);
 150  
                 }
 151  0
                 moveToPattern = tempMoveToPattern;
 152  
             }
 153  
 
 154  0
             String tempPolling = (String) props.get(PROPERTY_POLLING_FREQUENCY);
 155  0
             if (tempPolling != null)
 156  
             {
 157  0
                 polling = Long.parseLong(tempPolling);
 158  
             }
 159  
 
 160  0
             if (polling <= 0)
 161  
             {
 162  0
                 polling = DEFAULT_POLLING_FREQUENCY;
 163  
             }
 164  
 
 165  0
             if (logger.isDebugEnabled())
 166  
             {
 167  0
                 logger.debug("set polling frequency to: " + polling);
 168  
             }
 169  0
             String tempFileAge = (String) props.get(PROPERTY_FILE_AGE);
 170  0
             if (tempFileAge != null)
 171  
             {
 172  
                 try
 173  
                 {
 174  0
                     setFileAge(Long.parseLong(tempFileAge));
 175  
                 }
 176  0
                 catch (Exception ex1)
 177  
                 {
 178  0
                     logger.error("Failed to set fileAge", ex1);
 179  0
                 }
 180  
             }
 181  0
             Map srvOverride = (Map) props.get(PROPERTY_SERVICE_OVERRIDE);
 182  0
             if (srvOverride != null) 
 183  
             {
 184  0
                 if (serviceOverrides == null) 
 185  
                 {
 186  0
                     serviceOverrides = new Properties();
 187  
                 }
 188  0
                 serviceOverrides.setProperty(MuleProperties.CONNECTOR_INBOUND_TRANSFORMER,
 189  
                     NoActionTransformer.class.getName());
 190  0
                 serviceOverrides.setProperty(MuleProperties.CONNECTOR_OUTBOUND_TRANSFORMER,
 191  
                     NoActionTransformer.class.getName());
 192  
             }
 193  
         }
 194  
 
 195  
         try
 196  
         {
 197  0
             return serviceDescriptor.createMessageReceiver(this, component, endpoint, new Object[]{readDir,
 198  
                 moveTo, moveToPattern, new Long(polling)});
 199  
 
 200  
         }
 201  0
         catch (Exception e)
 202  
         {
 203  0
             throw new InitialisationException(
 204  
                 CoreMessages.failedToCreateObjectWith("Message Receiver", 
 205  
                     serviceDescriptor.getMessageReceiver()), e, this);
 206  
         }
 207  
     }
 208  
 
 209  
     public String getProtocol()
 210  
     {
 211  0
         return "file";
 212  
     }
 213  
 
 214  
     public FilenameParser getFilenameParser()
 215  
     {
 216  0
         return filenameParser;
 217  
     }
 218  
 
 219  
     public void setFilenameParser(FilenameParser filenameParser)
 220  
     {
 221  0
         this.filenameParser = filenameParser;
 222  0
     }
 223  
 
 224  
     protected void doDispose()
 225  
     {
 226  
         try
 227  
         {
 228  0
             doStop();
 229  
         }
 230  0
         catch (UMOException e)
 231  
         {
 232  0
             logger.error(e.getMessage(), e);
 233  0
         }
 234  0
     }
 235  
 
 236  
 
 237  
     protected void doInitialise() throws InitialisationException
 238  
     {
 239  
         // template method, nothing to do
 240  0
     }
 241  
 
 242  
     protected void doConnect() throws Exception
 243  
     {
 244  
         // template method, nothing to do
 245  0
     }
 246  
 
 247  
     protected void doDisconnect() throws Exception
 248  
     {
 249  
         // template method, nothing to do
 250  0
     }
 251  
 
 252  
     protected void doStart() throws UMOException
 253  
     {
 254  
         // template method, nothing to do
 255  0
     }
 256  
 
 257  
     protected void doStop() throws UMOException
 258  
     {
 259  0
         if (outputStream != null)
 260  
         {
 261  
             try
 262  
             {
 263  0
                 outputStream.close();
 264  
             }
 265  0
             catch (IOException e)
 266  
             {
 267  0
                 logger.warn("Failed to close file output stream on stop: " + e);
 268  0
             }
 269  
         }
 270  0
     }
 271  
 
 272  
     /**
 273  
      * @return Returns the moveToDirectoryName.
 274  
      */
 275  
     public String getMoveToDirectory()
 276  
     {
 277  0
         return moveToDirectoryName;
 278  
     }
 279  
 
 280  
     /**
 281  
      * @param dir The moveToDirectoryName to set.
 282  
      */
 283  
     public void setMoveToDirectory(String dir)
 284  
     {
 285  0
         this.moveToDirectoryName = dir;
 286  0
     }
 287  
 
 288  
     /**
 289  
      * @return Returns the outputAppend.
 290  
      */
 291  
     public boolean isOutputAppend()
 292  
     {
 293  0
         return outputAppend;
 294  
     }
 295  
 
 296  
     /**
 297  
      * @param outputAppend The outputAppend to set.
 298  
      */
 299  
     public void setOutputAppend(boolean outputAppend)
 300  
     {
 301  0
         this.outputAppend = outputAppend;
 302  0
     }
 303  
 
 304  
     /**
 305  
      * @return Returns the outputPattern.
 306  
      */
 307  
     public String getOutputPattern()
 308  
     {
 309  0
         return outputPattern;
 310  
     }
 311  
 
 312  
     /**
 313  
      * @param outputPattern The outputPattern to set.
 314  
      */
 315  
     public void setOutputPattern(String outputPattern)
 316  
     {
 317  0
         this.outputPattern = outputPattern;
 318  0
     }
 319  
 
 320  
     /**
 321  
      * @return Returns the outputStream.
 322  
      */
 323  
     public FileOutputStream getOutputStream()
 324  
     {
 325  0
         return outputStream;
 326  
     }
 327  
 
 328  
     /**
 329  
      * @param outputStream The outputStream to set.
 330  
      */
 331  
     public void setOutputStream(FileOutputStream outputStream)
 332  
     {
 333  0
         this.outputStream = outputStream;
 334  0
     }
 335  
 
 336  
     /**
 337  
      * @return Returns the pollingFrequency.
 338  
      */
 339  
     public long getPollingFrequency()
 340  
     {
 341  0
         return pollingFrequency;
 342  
     }
 343  
 
 344  
     /**
 345  
      * @param pollingFrequency The pollingFrequency to set.
 346  
      */
 347  
     public void setPollingFrequency(long pollingFrequency)
 348  
     {
 349  0
         this.pollingFrequency = pollingFrequency;
 350  0
     }
 351  
 
 352  
     /**
 353  
      * @return Returns the fileAge.
 354  
      */
 355  
     public long getFileAge()
 356  
     {
 357  0
         return fileAge;
 358  
     }
 359  
 
 360  
     public boolean getCheckFileAge()
 361  
     {
 362  0
         return checkFileAge;
 363  
     }
 364  
 
 365  
     /**
 366  
      * @param fileAge The fileAge in milliseconds to set.
 367  
      */
 368  
     public void setFileAge(long fileAge)
 369  
     {
 370  0
         this.fileAge = fileAge;
 371  0
         this.checkFileAge = true;
 372  0
     }
 373  
 
 374  
     /**
 375  
      * @return Returns the writeToDirectory.
 376  
      */
 377  
     public String getWriteToDirectory()
 378  
     {
 379  0
         return writeToDirectoryName;
 380  
     }
 381  
 
 382  
     /**
 383  
      * @param dir The writeToDirectory to set.
 384  
      */
 385  
     public void setWriteToDirectory(String dir) throws IOException
 386  
     {
 387  0
         this.writeToDirectoryName = dir;
 388  0
         if (writeToDirectoryName != null)
 389  
         {
 390  0
             File writeToDirectory = FileUtils.openDirectory((writeToDirectoryName));
 391  0
             if (!(writeToDirectory.canRead()) || !writeToDirectory.canWrite())
 392  
             {
 393  0
                 throw new IOException(
 394  
                     "Error on initialization, Write To directory does not exist or is not read/write");
 395  
             }
 396  
         }
 397  0
     }
 398  
 
 399  
     public boolean isSerialiseObjects()
 400  
     {
 401  0
         return serialiseObjects;
 402  
     }
 403  
 
 404  
     public void setSerialiseObjects(boolean serialiseObjects)
 405  
     {
 406  
         // set serialisable transformers on the connector if this is set
 407  0
         if (serialiseObjects)
 408  
         {
 409  0
             if (serviceOverrides == null)
 410  
             {
 411  0
                 serviceOverrides = new Properties();
 412  
             }
 413  0
             serviceOverrides.setProperty(MuleProperties.CONNECTOR_INBOUND_TRANSFORMER,
 414  
                 ByteArrayToSerializable.class.getName());
 415  0
             serviceOverrides.setProperty(MuleProperties.CONNECTOR_OUTBOUND_TRANSFORMER,
 416  
                 SerializableToByteArray.class.getName());
 417  
         }
 418  
 
 419  0
         this.serialiseObjects = serialiseObjects;
 420  0
     }
 421  
 
 422  
     public boolean isAutoDelete()
 423  
     {
 424  0
         return autoDelete;
 425  
     }
 426  
 
 427  
     public void setAutoDelete(boolean autoDelete)
 428  
     {
 429  0
         this.autoDelete = autoDelete;
 430  0
         if (!autoDelete)
 431  
         {
 432  0
             if (serviceOverrides == null)
 433  
             {
 434  0
                 serviceOverrides = new Properties();
 435  
             }
 436  0
             if (serviceOverrides.getProperty(MuleProperties.CONNECTOR_MESSAGE_ADAPTER) == null)
 437  
             {
 438  0
                 serviceOverrides.setProperty(MuleProperties.CONNECTOR_MESSAGE_ADAPTER,
 439  
                     FileMessageAdapter.class.getName());
 440  
             }
 441  
         }
 442  0
     }
 443  
 
 444  
     public String getMoveToPattern()
 445  
     {
 446  0
         return moveToPattern;
 447  
     }
 448  
 
 449  
     public void setMoveToPattern(String moveToPattern)
 450  
     {
 451  0
         this.moveToPattern = moveToPattern;
 452  0
     }
 453  
 
 454  
     /**
 455  
      * Well get the output stream (if any) for this type of transport. Typically this
 456  
      * will be called only when Streaming is being used on an outbound endpoint
 457  
      *
 458  
      * @param endpoint the endpoint that releates to this Dispatcher
 459  
      * @param message the current message being processed
 460  
      * @return the output stream to use for this request or null if the transport
 461  
      *         does not support streaming
 462  
      * @throws org.mule.umo.UMOException
 463  
      */
 464  
     public OutputStream getOutputStream(UMOImmutableEndpoint endpoint, UMOMessage message)
 465  
         throws UMOException
 466  
     {
 467  0
         String address = endpoint.getEndpointURI().getAddress();
 468  0
         String writeToDirectory = message.getStringProperty(
 469  
             FileConnector.PROPERTY_WRITE_TO_DIRECTORY, null);
 470  0
         if (writeToDirectory == null)
 471  
         {
 472  0
             writeToDirectory = getWriteToDirectory();
 473  
         }
 474  0
         if (writeToDirectory != null)
 475  
         {
 476  0
             address = getFilenameParser().getFilename(message, writeToDirectory);
 477  
         }
 478  
 
 479  
         String filename;
 480  0
         String outPattern = (String)endpoint.getProperty(FileConnector.PROPERTY_OUTPUT_PATTERN);
 481  0
         if (outPattern == null)
 482  
         {
 483  0
             outPattern = message.getStringProperty(FileConnector.PROPERTY_OUTPUT_PATTERN, null);
 484  
         }
 485  0
         if (outPattern == null)
 486  
         {
 487  0
             outPattern = getOutputPattern();
 488  
         }
 489  
         try
 490  
         {
 491  0
             if (outPattern != null)
 492  
             {
 493  0
                 filename = generateFilename(message, outPattern);
 494  
             }
 495  
             else
 496  
             {
 497  0
                 filename = message.getStringProperty(FileConnector.PROPERTY_FILENAME, null);
 498  0
                 if (filename == null)
 499  
                 {
 500  0
                     filename = generateFilename(message, null);
 501  
                 }
 502  
             }
 503  
 
 504  0
             if (filename == null)
 505  
             {
 506  0
                 throw new IOException("Filename is null");
 507  
             }
 508  0
             File file = FileUtils.createFile(address + "/" + filename);
 509  0
             if (logger.isInfoEnabled())
 510  
             {
 511  0
                 logger.info("Writing file to: " + file.getAbsolutePath());
 512  
             }
 513  
 
 514  0
             return new FileOutputStream(file, MapUtils.getBooleanValue(endpoint.getProperties(),
 515  
                 "outputAppend", isOutputAppend()));
 516  
         }
 517  0
         catch (IOException e)
 518  
         {
 519  0
             throw new DispatchException(CoreMessages.streamingFailedNoStream(), message,
 520  
                 endpoint, e);
 521  
         }
 522  
     }
 523  
 
 524  
     private String generateFilename(UMOMessage message, String pattern)
 525  
     {
 526  0
         if (pattern == null)
 527  
         {
 528  0
             pattern = getOutputPattern();
 529  
         }
 530  0
         return getFilenameParser().getFilename(message, pattern);
 531  
     }
 532  
 }