View Javadoc

1   /*
2    * $Id: FtpMessageDispatcher.java 10747 2008-02-08 03:16:21Z 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.AbstractMessageDispatcher;
15  import org.mule.providers.file.FileConnector;
16  import org.mule.umo.UMOEvent;
17  import org.mule.umo.UMOMessage;
18  import org.mule.umo.endpoint.UMOEndpointURI;
19  import org.mule.umo.endpoint.UMOImmutableEndpoint;
20  import org.mule.umo.provider.UMOStreamMessageAdapter;
21  
22  import java.io.FilenameFilter;
23  import java.io.IOException;
24  import java.io.OutputStream;
25  import java.util.ArrayList;
26  import java.util.List;
27  
28  import org.apache.commons.io.IOUtils;
29  import org.apache.commons.io.output.ByteArrayOutputStream;
30  import org.apache.commons.net.ftp.FTPClient;
31  import org.apache.commons.net.ftp.FTPFile;
32  import org.apache.commons.net.ftp.FTPReply;
33  
34  public class FtpMessageDispatcher extends AbstractMessageDispatcher
35  {
36      protected final FtpConnector connector;
37  
38      public FtpMessageDispatcher(UMOImmutableEndpoint endpoint)
39      {
40          super(endpoint);
41          this.connector = (FtpConnector) endpoint.getConnector();
42      }
43  
44      protected void doDispose()
45      {
46          // no op
47      }
48  
49      protected void doDispatch(UMOEvent event) throws Exception
50      {
51          Object data = event.getTransformedMessage();
52          OutputStream out = connector.getOutputStream(event.getEndpoint(), event.getMessage());
53  
54          try
55          {
56              if (data instanceof UMOStreamMessageAdapter)
57              {
58                  IOUtils.copy(((UMOStreamMessageAdapter) data).getInputStream(), out);
59                  OutputStream outputStream = ((UMOStreamMessageAdapter) data).getOutputStream();
60                  if (outputStream != null)
61                  {
62                      outputStream.close();
63                  }
64              }
65              else
66              {
67                  byte[] dataBytes;
68                  if (data instanceof byte[])
69                  {
70                      dataBytes = (byte[]) data;
71                  }
72                  else
73                  {
74                      dataBytes = data.toString().getBytes(event.getEncoding());
75                  }
76                  IOUtils.write(dataBytes, out);
77              }
78          }
79          finally
80          {
81              out.close();
82          }
83      }
84  
85      protected UMOMessage doSend(UMOEvent event) throws Exception
86      {
87          doDispatch(event);
88          return event.getMessage();
89      }
90  
91      protected void doConnect() throws Exception
92      {
93          // what was this for?!
94          //connector.releaseFtp(endpoint.getEndpointURI());
95      }
96  
97      protected void doDisconnect() throws Exception
98      {
99          try
100         {
101             UMOEndpointURI uri = endpoint.getEndpointURI();
102             FTPClient client = connector.getFtp(uri);
103             connector.destroyFtp(uri, client);
104         }
105         catch (Exception e)
106         {
107             // pool may be closed
108         }
109     }
110 
111     /**
112      * Make a specific request to the underlying transport
113      *
114      * @param timeout the maximum time the operation should block before returning.
115      *            The call should return immediately if there is data available. If
116      *            no data becomes available before the timeout elapses, null will be
117      *            returned
118      * @return the result of the request wrapped in a UMOMessage object. Null will be
119      *         returned if no data was avaialable
120      * @throws Exception if the call to the underlying protocal cuases an exception
121      */
122     protected UMOMessage doReceive(long timeout) throws Exception
123     {
124         FTPClient client = null;
125         try
126         {
127             logger.debug("entering doReceive()");
128             client = connector.createFtpClient(endpoint);
129             
130             FilenameFilter filenameFilter = null;
131             if (endpoint.getFilter() instanceof FilenameFilter)
132             {
133                 filenameFilter = (FilenameFilter) endpoint.getFilter();
134             }
135 
136             FTPFile[] files = client.listFiles();
137             if (!FTPReply.isPositiveCompletion(client.getReplyCode()))
138             {
139                 throw new IOException("Ftp error: " + client.getReplyCode());
140             }
141             if (files == null || files.length == 0)
142             {
143                 return null;
144             }
145             List fileList = new ArrayList();
146             for (int i = 0; i < files.length; i++)
147             {
148                 if (files[i].isFile())
149                 {
150                     if (filenameFilter == null || filenameFilter.accept(null, files[i].getName()))
151                     {
152                         fileList.add(files[i]);
153                         // only read the first one
154                         break;
155                     }
156                 }
157             }
158             if (fileList.size() == 0)
159             {
160                 return null;
161             }
162 
163             FTPFile file = (FTPFile) fileList.get(0);
164             ByteArrayOutputStream baos = new ByteArrayOutputStream();
165             if (!client.retrieveFile(file.getName(), baos))
166             {
167                 throw new IOException("Ftp error: " + client.getReplyCode());
168             }
169             
170             UMOMessage reply = new MuleMessage(connector.getMessageAdapter(baos.toByteArray()));
171             reply.setProperty(FileConnector.PROPERTY_ORIGINAL_FILENAME, file.getName());
172             reply.setProperty(FileConnector.PROPERTY_FILE_SIZE, new Long(file.getSize()));
173             return reply;
174         }
175         finally
176         {
177             logger.debug("leaving doReceive()");
178             connector.releaseFtp(endpoint.getEndpointURI(), client);
179         }
180     }
181 
182 }