1 10 11 package org.mule.providers.file; 12 13 import java.io.File ; 14 import java.io.FileInputStream ; 15 import java.io.FileOutputStream ; 16 import java.io.FilenameFilter ; 17 import java.io.IOException ; 18 import java.io.RandomAccessFile ; 19 import java.nio.channels.FileChannel ; 20 import java.nio.channels.FileLock ; 21 22 import org.apache.commons.io.IOUtils; 23 import org.mule.MuleException; 24 import org.mule.config.i18n.Message; 25 import org.mule.config.i18n.Messages; 26 import org.mule.impl.MuleMessage; 27 import org.mule.providers.ConnectException; 28 import org.mule.providers.PollingMessageReceiver; 29 import org.mule.umo.UMOComponent; 30 import org.mule.umo.UMOException; 31 import org.mule.umo.endpoint.UMOEndpoint; 32 import org.mule.umo.lifecycle.InitialisationException; 33 import org.mule.umo.provider.UMOConnector; 34 import org.mule.umo.provider.UMOMessageAdapter; 35 import org.mule.umo.routing.RoutingException; 36 import org.mule.util.FileUtils; 37 38 42 43 public class FileMessageReceiver extends PollingMessageReceiver 44 { 45 private String readDir = null; 46 private String moveDir = null; 47 private File readDirectory = null; 48 private File moveDirectory = null; 49 private String moveToPattern = null; 50 private FilenameFilter filenameFilter = null; 51 52 public FileMessageReceiver(UMOConnector connector, 53 UMOComponent component, 54 UMOEndpoint endpoint, 55 String readDir, 56 String moveDir, 57 String moveToPattern, 58 Long frequency) throws InitialisationException 59 { 60 super(connector, component, endpoint, frequency); 61 this.readDir = readDir; 62 this.moveDir = moveDir; 63 this.moveToPattern = moveToPattern; 64 if (endpoint.getFilter() instanceof FilenameFilter ) 65 { 66 filenameFilter = (FilenameFilter )endpoint.getFilter(); 67 } 68 } 69 70 public void doConnect() throws Exception 71 { 72 if (readDir != null) 73 { 74 readDirectory = FileUtils.openDirectory(readDir); 75 if (!(readDirectory.canRead())) 76 { 77 throw new ConnectException(new Message(Messages.FILE_X_DOES_NOT_EXIST, 78 readDirectory.getAbsolutePath()), this); 79 } 80 else 81 { 82 logger.debug("Listening on endpointUri: " + readDirectory.getAbsolutePath()); 83 } 84 } 85 86 if (moveDir != null) 87 { 88 moveDirectory = FileUtils.openDirectory((moveDir)); 89 if (!(moveDirectory.canRead()) || !moveDirectory.canWrite()) 90 { 91 throw new ConnectException(new Message("file", 5), this); 92 } 93 } 94 } 95 96 public void doDisconnect() throws Exception 97 { 98 } 100 101 public void poll() 102 { 103 try 104 { 105 File [] files = this.listFiles(); 106 for (int i = 0; i < files.length; i++) 107 { 108 this.processFile(files[i]); 109 } 110 } 111 catch (Exception e) 112 { 113 this.handleException(e); 114 } 115 } 116 117 public synchronized void processFile(final File sourceFile) throws UMOException 118 { 119 boolean checkFileAge = ((FileConnector)connector).getCheckFileAge(); 120 if (checkFileAge) 121 { 122 long fileAge = ((FileConnector)connector).getFileAge(); 123 long lastMod = sourceFile.lastModified(); 124 long now = (new java.util.Date ()).getTime(); 125 if ((now - lastMod) < fileAge) 126 { 127 return; 128 } 129 } 130 131 if (!attemptFileLock(sourceFile)) 133 { 134 return; 135 } 136 137 File destinationFile = null; 138 String sourceFileOriginalName = sourceFile.getName(); 139 UMOMessageAdapter msgAdapter = connector.getMessageAdapter(sourceFile); 140 msgAdapter.setProperty(FileConnector.PROPERTY_ORIGINAL_FILENAME, sourceFileOriginalName); 141 142 if (moveDir != null) 144 { 145 String destinationFileName = sourceFileOriginalName; 146 147 if (moveToPattern != null) 148 { 149 destinationFileName = ((FileConnector) connector).getFilenameParser().getFilename(msgAdapter, 150 moveToPattern); 151 } 152 153 destinationFile = FileUtils.newFile(moveDir, destinationFileName); 155 } 156 157 boolean fileWasMoved = false; 158 159 try 160 { 161 if (!(sourceFile.canRead() && sourceFile.exists() && sourceFile.isFile())) 163 { 164 throw new MuleException(new Message(Messages.FILE_X_DOES_NOT_EXIST, sourceFileOriginalName)); 165 } 166 167 if (destinationFile != null) 168 { 169 fileWasMoved = this.moveFile(sourceFile, destinationFile); 171 172 if (!fileWasMoved) 174 { 175 throw new MuleException(new Message("file", 4, sourceFile.getAbsolutePath(), 176 destinationFile.getAbsolutePath())); 177 } 178 179 msgAdapter = connector.getMessageAdapter(destinationFile); 181 msgAdapter.setProperty(FileConnector.PROPERTY_FILENAME, destinationFile.getName()); 182 msgAdapter.setProperty(FileConnector.PROPERTY_ORIGINAL_FILENAME, sourceFileOriginalName); 183 } 184 185 if (((FileConnector) connector).isAutoDelete()) 188 { 189 if (destinationFile == null) 191 { 192 if (!sourceFile.delete()) 194 { 195 throw new MuleException(new Message("file", 3, sourceFile.getAbsolutePath())); 197 } 198 } 199 else 200 { 201 } 204 } 205 206 this.routeMessage(new MuleMessage(msgAdapter), endpoint.isSynchronous()); 208 } 209 catch (Exception e) 210 { 211 boolean fileWasRolledBack = false; 212 213 if (fileWasMoved) 215 { 216 fileWasRolledBack = this.rollbackFileMove(destinationFile, sourceFile.getAbsolutePath()); 217 } 218 219 Exception ex = new RoutingException(new Message("file", 2, sourceFile.getName(), 221 (fileWasRolledBack ? "successful" : "unsuccessful")), new MuleMessage(msgAdapter), endpoint, 222 e); 223 this.handleException(ex); 224 } 225 } 226 227 234 protected boolean attemptFileLock(final File sourceFile) 235 { 236 FileLock lock = null; 240 FileChannel channel = null; 241 boolean fileCanBeLocked = false; 242 try 243 { 244 channel = new RandomAccessFile (sourceFile, "rw").getChannel(); 245 246 lock = channel.tryLock(); 249 } 250 catch (IOException e) 251 { 252 } 254 finally { 255 if (lock != null) 256 { 257 fileCanBeLocked = true; 259 try 260 { 261 lock.release(); 263 } 264 catch (IOException e) 265 { 266 } 268 } 269 270 if (channel != null) 271 { 272 try 273 { 274 channel.close(); 276 } 277 catch (IOException e) 278 { 279 } 281 } 282 } 283 284 return fileCanBeLocked; 285 } 286 287 290 protected boolean moveFile(File sourceFile, File destinationFile) 291 { 292 boolean success = sourceFile.renameTo(destinationFile); 294 295 if (!success) 296 { 297 FileInputStream fis = null; 299 FileOutputStream fos = null; 300 try 301 { 302 fis = new FileInputStream (sourceFile); 303 fos = new FileOutputStream (destinationFile); 304 FileChannel srcChannel = fis.getChannel(); 305 FileChannel dstChannel = fos.getChannel(); 306 dstChannel.transferFrom(srcChannel, 0, srcChannel.size()); 307 srcChannel.close(); 308 dstChannel.close(); 309 success = sourceFile.delete(); 310 } 311 catch (IOException ioex) 312 { 313 success = false; 315 } 316 finally 317 { 318 IOUtils.closeQuietly(fis); 319 IOUtils.closeQuietly(fos); 320 } 321 } 322 323 return success; 324 } 325 326 329 protected boolean rollbackFileMove(File sourceFile, String destinationFilePath) 330 { 331 boolean result = false; 332 try 333 { 334 result = this.moveFile(sourceFile, FileUtils.newFile(destinationFilePath)); 335 } 336 catch (Throwable t) 337 { 338 logger.debug("rollback of file move failed: " + t.getMessage()); 339 } 340 return result; 341 } 342 343 349 File [] listFiles() throws MuleException 350 { 351 try 352 { 353 File [] todoFiles = readDirectory.listFiles(filenameFilter); 354 return (todoFiles == null ? new File [0] : todoFiles); 357 } 358 catch (Exception e) 359 { 360 throw new MuleException(new Message("file", 1), e); 361 } 362 } 363 364 } 365 | Popular Tags |