View Javadoc

1   /*
2    * $Id: FtpMessageDispatcher.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.ftp;
12  
13  import org.mule.impl.MuleMessage;
14  import org.mule.providers.AbstractMessageDispatcher;
15  import org.mule.umo.UMOEvent;
16  import org.mule.umo.UMOMessage;
17  import org.mule.umo.endpoint.UMOEndpointURI;
18  import org.mule.umo.endpoint.UMOImmutableEndpoint;
19  import org.mule.umo.provider.UMOStreamMessageAdapter;
20  
21  import java.io.FilenameFilter;
22  import java.io.IOException;
23  import java.io.OutputStream;
24  import java.util.ArrayList;
25  import java.util.List;
26  
27  import org.apache.commons.io.IOUtils;
28  import org.apache.commons.io.output.ByteArrayOutputStream;
29  import org.apache.commons.net.ftp.FTPClient;
30  import org.apache.commons.net.ftp.FTPFile;
31  import org.apache.commons.net.ftp.FTPReply;
32  
33  public class FtpMessageDispatcher extends AbstractMessageDispatcher
34  {
35      protected final FtpConnector connector;
36  
37      public FtpMessageDispatcher(UMOImmutableEndpoint endpoint)
38      {
39          super(endpoint);
40          this.connector = (FtpConnector) endpoint.getConnector();
41      }
42  
43      protected void doDispose()
44      {
45          // no op
46      }
47  
48      protected void doDispatch(UMOEvent event) throws Exception
49      {
50          Object data = event.getTransformedMessage();
51          OutputStream out = connector.getOutputStream(event.getEndpoint(), event.getMessage());
52  
53          try
54          {
55              if (data instanceof UMOStreamMessageAdapter)
56              {
57                  IOUtils.copy(((UMOStreamMessageAdapter) data).getInputStream(), out);
58                  ((UMOStreamMessageAdapter) data).getOutputStream().close();
59              }
60              else
61              {
62                  byte[] dataBytes;
63                  if (data instanceof byte[])
64                  {
65                      dataBytes = (byte[]) data;
66                  }
67                  else
68                  {
69                      dataBytes = data.toString().getBytes();
70                  }
71                  IOUtils.write(dataBytes, out);
72              }
73          }
74          finally
75          {
76              out.close();
77          }
78      }
79  
80      protected UMOMessage doSend(UMOEvent event) throws Exception
81      {
82          doDispatch(event);
83          return event.getMessage();
84      }
85  
86      protected void doConnect() throws Exception
87      {
88          // what was this for?!
89          //connector.releaseFtp(endpoint.getEndpointURI());
90      }
91  
92      protected void doDisconnect() throws Exception
93      {
94          try
95          {
96              UMOEndpointURI uri = endpoint.getEndpointURI();
97              FTPClient client = connector.getFtp(uri);
98              connector.destroyFtp(uri, client);
99          }
100         catch (Exception e)
101         {
102             // pool may be closed
103         }
104     }
105 
106     /**
107      * Make a specific request to the underlying transport
108      *
109      * @param timeout the maximum time the operation should block before returning.
110      *            The call should return immediately if there is data available. If
111      *            no data becomes available before the timeout elapses, null will be
112      *            returned
113      * @return the result of the request wrapped in a UMOMessage object. Null will be
114      *         returned if no data was avaialable
115      * @throws Exception if the call to the underlying protocal cuases an exception
116      */
117     protected UMOMessage doReceive(long timeout) throws Exception
118     {
119         FTPClient client = connector.getFtp(endpoint.getEndpointURI());
120         try
121         {
122             logger.debug("entering doReceive()");
123             connector.enterActiveOrPassiveMode(client, endpoint);
124             connector.setupFileType(client, endpoint);
125             if (!client.changeWorkingDirectory(endpoint.getEndpointURI().getPath()))
126             {
127                 throw new IOException("Ftp error: " + client.getReplyCode());
128             }
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             return new MuleMessage(connector.getMessageAdapter(baos.toByteArray()));
170 
171         }
172         finally
173         {
174             logger.debug("leaving doReceive()");
175             connector.releaseFtp(endpoint.getEndpointURI(), client);
176         }
177     }
178 
179 }