View Javadoc

1   /*
2    * $Id: FileMessageRequester.java 22000 2011-05-27 11:39:02Z tcarlson $
3    * --------------------------------------------------------------------------------------
4    * Copyright (c) MuleSoft, Inc.  All rights reserved.  http://www.mulesoft.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.transport.file;
12  
13  import org.mule.DefaultMuleMessage;
14  import org.mule.api.DefaultMuleException;
15  import org.mule.api.MuleException;
16  import org.mule.api.MuleMessage;
17  import org.mule.api.endpoint.InboundEndpoint;
18  import org.mule.api.lifecycle.CreateException;
19  import org.mule.api.routing.filter.Filter;
20  import org.mule.transport.AbstractMessageRequester;
21  import org.mule.transport.file.i18n.FileMessages;
22  import org.mule.util.FileUtils;
23  
24  import java.io.File;
25  import java.io.FileFilter;
26  import java.io.FileNotFoundException;
27  import java.io.FilenameFilter;
28  import java.io.IOException;
29  
30  /**
31   * <code>FileMessageRequester</code> is used to read/write files to the filesystem
32   */
33  public class FileMessageRequester extends AbstractMessageRequester
34  {
35      private final FileConnector connector;
36  
37      private FilenameFilter filenameFilter = null;
38      private FileFilter fileFilter = null;
39      
40      public FileMessageRequester(InboundEndpoint endpoint) throws MuleException
41      {
42          super(endpoint);
43          this.connector = (FileConnector) endpoint.getConnector();
44          
45          Filter filter = endpoint.getFilter();
46          if (filter instanceof FilenameFilter)
47          {
48              filenameFilter = (FilenameFilter) filter;
49          }
50          else if (filter instanceof FileFilter)
51          {
52              fileFilter = (FileFilter) filter;
53          }
54          else if (filter != null)
55          {
56              throw new CreateException(FileMessages.invalidFileFilter(endpoint.getEndpointURI()), this);
57          }
58      }
59  
60      /**
61       * There is no associated session for a file connector
62       * 
63       * @throws org.mule.api.MuleException
64       */
65      public Object getDelegateSession() throws MuleException
66      {
67          return null;
68      }
69  
70      /**
71       * Will attempt to do a receive from a directory, if the endpointUri resolves to
72       * a file name the file will be returned, otherwise the first file in the
73       * directory according to the filename filter configured on the connector.
74       * 
75       * @param timeout this is ignored when doing a receive on this dispatcher
76       * @return a message containing file contents or null if there was notthing to
77       *         receive
78       * @throws Exception
79       */
80      @Override
81      protected MuleMessage doRequest(long timeout) throws Exception
82      {
83          File file = FileUtils.newFile(endpoint.getEndpointURI().getAddress());
84          File result = null;
85  
86          if (file.exists())
87          {
88              if (file.isFile())
89              {
90                  result = file;
91              }
92              else if (file.isDirectory())
93              {
94                  if (fileFilter != null)
95                  {
96                      result = FileMessageDispatcher.getNextFile(
97                          endpoint.getEndpointURI().getAddress(), fileFilter);
98                  }
99                  else
100                 {
101                     result = FileMessageDispatcher.getNextFile(
102                         endpoint.getEndpointURI().getAddress(), filenameFilter);
103                 }
104             }
105             
106             if (result != null)
107             {
108                 boolean checkFileAge = connector.getCheckFileAge();
109                 if (checkFileAge)
110                 {
111                     long fileAge = connector.getFileAge();
112                     long lastMod = result.lastModified();
113                     long now = System.currentTimeMillis();
114                     long thisFileAge = now - lastMod;
115                     if (thisFileAge < fileAge)
116                     {
117                         if (logger.isDebugEnabled())
118                         {
119                             logger.debug("The file has not aged enough yet, will return nothing for: "
120                                          + result.getCanonicalPath());
121                         }
122                         return null;
123                     }
124                 }
125 
126                 // Don't we need to try to obtain a file lock as we do with receiver
127                 String sourceFileOriginalName = result.getName();
128 
129                 // set up destination file
130                 File destinationFile = null;
131                 String movDir = getMoveDirectory();
132                 if (movDir != null)
133                 {
134                     String destinationFileName = sourceFileOriginalName;
135                     String moveToPattern = getMoveToPattern();
136                     if (moveToPattern != null)
137                     {
138                         // This isn't nice but is needed as MuleMessage is required to
139                         // resolve the destination file name
140                         DefaultMuleMessage parserMesssage = new DefaultMuleMessage(null,
141                             connector.getMuleContext());
142                         parserMesssage.setOutboundProperty(FileConnector.PROPERTY_ORIGINAL_FILENAME, sourceFileOriginalName);
143 
144                         destinationFileName =
145                             connector.getFilenameParser().getFilename(parserMesssage, moveToPattern);
146                     }
147                     // don't use new File() directly, see MULE-1112
148                     destinationFile = FileUtils.newFile(movDir, destinationFileName);
149                 }
150 
151                 MuleMessage returnMessage = null;
152                 String encoding = endpoint.getEncoding();
153                 try
154                 {
155                     if (connector.isStreaming())
156                     {
157                         ReceiverFileInputStream receiverStream = new ReceiverFileInputStream(result,
158                             connector.isAutoDelete(), destinationFile);
159                         returnMessage = createMuleMessage(receiverStream, encoding);
160                     }
161                     else
162                     {
163                         returnMessage = createMuleMessage(result, encoding);
164                     }
165                 }
166                 catch (FileNotFoundException e)
167                 {
168                     // we can ignore since we did manage to acquire a lock, but just
169                     // in case
170                     logger.error("File being read disappeared!", e);
171                     return null;
172                 }
173                 returnMessage.setOutboundProperty(FileConnector.PROPERTY_ORIGINAL_FILENAME, sourceFileOriginalName);
174 
175                 if (!connector.isStreaming())
176                 {
177                     moveOrDelete(result, destinationFile);
178                 }
179 
180                 // If we are streaming no need to move/delete now, that will be
181                 // done when stream is closed
182                 return returnMessage;
183             }
184         }
185         return null;
186     }
187 
188     private void moveOrDelete(final File sourceFile, File destinationFile) throws DefaultMuleException
189     {
190 
191         if (destinationFile != null)
192         {
193             // move sourceFile to new destination
194             try
195             {
196                 FileUtils.moveFile(sourceFile, destinationFile);
197             }
198             catch (IOException e)
199             {
200                 throw new DefaultMuleException(FileMessages.failedToMoveFile(sourceFile.getAbsolutePath(),
201                     destinationFile.getAbsolutePath()));
202             }
203         }
204         if (connector.isAutoDelete())
205         {
206             // no moveTo directory
207             if (destinationFile == null)
208             {
209                 // delete source
210                 if (!sourceFile.delete())
211                 {
212                     throw new DefaultMuleException(FileMessages.failedToDeleteFile(sourceFile));
213                 }
214             }
215             else
216             {
217                 // nothing to do here since moveFile() should have deleted
218                 // the source file for us
219             }
220         }
221 
222     }
223 
224     @Override
225     protected void doDispose()
226     {
227         // no op
228     }
229 
230     @Override
231     protected void doConnect() throws Exception
232     {
233         // no op
234     }
235 
236     @Override
237     protected void doDisconnect() throws Exception
238     {
239         // no op
240     }
241 
242     protected String getMoveDirectory()
243     {
244         String moveDirectory = (String) endpoint.getProperty(FileConnector.PROPERTY_MOVE_TO_DIRECTORY);
245         if (moveDirectory == null)
246         {
247             moveDirectory = connector.getMoveToDirectory();
248         }
249         return moveDirectory;
250     }
251 
252     protected String getMoveToPattern()
253     {
254         String pattern = (String) endpoint.getProperty(FileConnector.PROPERTY_MOVE_TO_PATTERN);
255         if (pattern == null)
256         {
257             pattern = connector.getMoveToPattern();
258         }
259         return pattern;
260     }
261 
262 }