Coverage Report - org.mule.providers.ftp.FtpMessageReceiver
 
Classes in this File Line Coverage Branch Coverage Complexity
FtpMessageReceiver
86%
48/56
53%
17/32
2.9
FtpMessageReceiver$1
N/A
N/A
2.9
FtpMessageReceiver$FtpWork
79%
11/14
N/A
2.9
 
 1  
 /*
 2  
  * $Id: FtpMessageReceiver.java 9388 2007-10-26 09:57:08Z 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.ftp;
 12  
 
 13  
 import org.mule.impl.MuleMessage;
 14  
 import org.mule.providers.AbstractPollingMessageReceiver;
 15  
 import org.mule.providers.file.FileConnector;
 16  
 import org.mule.umo.UMOComponent;
 17  
 import org.mule.umo.UMOMessage;
 18  
 import org.mule.umo.endpoint.UMOEndpoint;
 19  
 import org.mule.umo.lifecycle.InitialisationException;
 20  
 import org.mule.umo.provider.UMOConnector;
 21  
 
 22  
 import java.io.FilenameFilter;
 23  
 import java.io.IOException;
 24  
 import java.text.MessageFormat;
 25  
 import java.util.ArrayList;
 26  
 import java.util.Collections;
 27  
 import java.util.HashSet;
 28  
 import java.util.List;
 29  
 import java.util.Set;
 30  
 
 31  
 import javax.resource.spi.work.Work;
 32  
 
 33  
 import org.apache.commons.io.output.ByteArrayOutputStream;
 34  
 import org.apache.commons.net.ftp.FTPClient;
 35  
 import org.apache.commons.net.ftp.FTPFile;
 36  
 import org.apache.commons.net.ftp.FTPReply;
 37  
 
 38  
 public class FtpMessageReceiver extends AbstractPollingMessageReceiver
 39  
 {
 40  
     protected final FtpConnector connector;
 41  
     protected final FilenameFilter filenameFilter;
 42  
 
 43  
     // there's nothing like homegrown pseudo-2PC.. :/
 44  
     // shared state management like this should go into the connector and use
 45  
     // something like commons-tx
 46  10
     protected final Set scheduledFiles = Collections.synchronizedSet(new HashSet());
 47  10
     protected final Set currentFiles = Collections.synchronizedSet(new HashSet());
 48  
 
 49  
     public FtpMessageReceiver(UMOConnector connector,
 50  
                               UMOComponent component,
 51  
                               UMOEndpoint endpoint,
 52  
                               long frequency) throws InitialisationException
 53  
     {
 54  10
         super(connector, component, endpoint);
 55  10
         this.setFrequency(frequency);
 56  
 
 57  10
         this.connector = (FtpConnector)connector;
 58  
 
 59  10
         if (endpoint.getFilter() instanceof FilenameFilter)
 60  
         {
 61  0
             this.filenameFilter = (FilenameFilter)endpoint.getFilter();
 62  
         }
 63  
         else
 64  
         {
 65  10
             this.filenameFilter = null;
 66  
         }
 67  10
     }
 68  
 
 69  
     public void poll() throws Exception
 70  
     {
 71  10
         FTPFile[] files = listFiles();
 72  
 
 73  6
         synchronized (scheduledFiles)
 74  
         {
 75  12
             for (int i = 0; i < files.length; i++)
 76  
             {
 77  6
                 final FTPFile file = files[i];
 78  6
                 final String fileName = file.getName();
 79  
 
 80  6
                 if (!scheduledFiles.contains(fileName) && !currentFiles.contains(fileName))
 81  
                 {
 82  6
                     scheduledFiles.add(fileName);
 83  6
                     getWorkManager().scheduleWork(new FtpWork(fileName, file));
 84  
                 }
 85  
             }
 86  6
         }
 87  6
     }
 88  
 
 89  
     protected FTPFile[] listFiles() throws Exception
 90  
     {
 91  10
         FTPClient client = null;
 92  
         try
 93  
         {
 94  10
             client = connector.createFtpClient(endpoint);
 95  6
             FTPFile[] files = client.listFiles();
 96  
 
 97  6
             if (!FTPReply.isPositiveCompletion(client.getReplyCode()))
 98  
             {
 99  0
                 throw new IOException("Failed to list files. Ftp error: " + client.getReplyCode());
 100  
             }
 101  
 
 102  6
             if (files == null || files.length == 0)
 103  
             {
 104  0
                 return files;
 105  
             }
 106  
 
 107  6
             List v = new ArrayList();
 108  
 
 109  12
             for (int i = 0; i < files.length; i++)
 110  
             {
 111  6
                 if (files[i].isFile())
 112  
                 {
 113  6
                     if (filenameFilter == null || filenameFilter.accept(null, files[i].getName()))
 114  
                     {
 115  6
                         v.add(files[i]);
 116  
                     }
 117  
                 }
 118  
             }
 119  
 
 120  6
             return (FTPFile[]) v.toArray(new FTPFile[v.size()]);
 121  
         }
 122  
         finally
 123  
         {
 124  10
             if (client != null)
 125  
             {
 126  6
                 connector.releaseFtp(endpoint.getEndpointURI(), client);
 127  
             }
 128  
         }
 129  
     }
 130  
 
 131  
     protected void processFile(FTPFile file) throws Exception
 132  
     {
 133  6
         logger.debug("entering processFile()");
 134  
         
 135  6
         FTPClient client = null;
 136  
         try
 137  
         {
 138  6
             client = connector.createFtpClient(endpoint);
 139  
             
 140  6
             final String fileName = file.getName();
 141  
             
 142  
             UMOMessage message;
 143  6
             if (endpoint.isStreaming())
 144  
             {
 145  6
                 message = new MuleMessage(
 146  
                         connector.getStreamMessageAdapter(client.retrieveFileStream(fileName), null));
 147  
             }
 148  
             else
 149  
             {
 150  0
                 ByteArrayOutputStream baos = new ByteArrayOutputStream();
 151  0
                 if (!client.retrieveFile(fileName, baos))
 152  
                 {
 153  0
                     throw new IOException(MessageFormat.format("Failed to retrieve file {0}. Ftp error: {1}",
 154  
                                                                new Object[] {fileName, new Integer(client.getReplyCode())}));
 155  
                 }
 156  0
                 message = new MuleMessage(connector.getMessageAdapter(baos.toByteArray()));
 157  
             }
 158  
 
 159  6
             message.setProperty(FileConnector.PROPERTY_ORIGINAL_FILENAME, fileName);
 160  6
             message.setProperty(FileConnector.PROPERTY_FILE_SIZE, new Long(file.getSize()));
 161  6
             routeMessage(message);
 162  
 
 163  6
             if (!client.deleteFile(fileName))
 164  
             {
 165  0
                 throw new IOException(MessageFormat.format("Failed to delete file {0}. Ftp error: {1}",
 166  
                                                            new Object[] {fileName, new Integer(client.getReplyCode())}));
 167  
             }
 168  
         }
 169  
         finally
 170  
         {
 171  6
             logger.debug("leaving processFile()");
 172  6
             if (client != null)
 173  
             {
 174  6
                 connector.releaseFtp(endpoint.getEndpointURI(), client);
 175  
             }
 176  
         }
 177  6
     }
 178  
 
 179  
     protected void doConnect() throws Exception
 180  
     {
 181  
         // why?!
 182  
         //connector.releaseFtp(getEndpointURI());
 183  4
     }
 184  
 
 185  
     protected void doDisconnect() throws Exception
 186  
     {
 187  
         // no op
 188  4
     }
 189  
 
 190  
     protected void doDispose()
 191  
     {
 192  
         // template method
 193  6
     }
 194  
 
 195  6
     private final class FtpWork implements Work
 196  
     {
 197  
         private final String name;
 198  
         private final FTPFile file;
 199  
 
 200  
         private FtpWork(String name, FTPFile file)
 201  6
         {
 202  6
             this.name = name;
 203  6
             this.file = file;
 204  6
         }
 205  
 
 206  
         public void run()
 207  
         {
 208  
             try
 209  
             {
 210  6
                 currentFiles.add(name);
 211  6
                 processFile(file);
 212  
             }
 213  0
             catch (Exception e)
 214  
             {
 215  0
                 connector.handleException(e);
 216  
             }
 217  
             finally
 218  
             {
 219  6
                 currentFiles.remove(name);
 220  6
                 scheduledFiles.remove(name);
 221  6
             }
 222  6
         }
 223  
 
 224  
         public void release()
 225  
         {
 226  
             // no op
 227  0
         }
 228  
     }
 229  
 
 230  
 }