1
2
3
4
5
6
7
8
9
10
11 package org.mule.providers.file;
12
13 import org.mule.config.MuleProperties;
14 import org.mule.config.i18n.CoreMessages;
15 import org.mule.providers.AbstractConnector;
16 import org.mule.providers.file.filters.FilenameWildcardFilter;
17 import org.mule.transformers.NoActionTransformer;
18 import org.mule.transformers.simple.ByteArrayToSerializable;
19 import org.mule.transformers.simple.SerializableToByteArray;
20 import org.mule.umo.UMOComponent;
21 import org.mule.umo.UMOException;
22 import org.mule.umo.UMOMessage;
23 import org.mule.umo.endpoint.UMOEndpoint;
24 import org.mule.umo.endpoint.UMOImmutableEndpoint;
25 import org.mule.umo.lifecycle.InitialisationException;
26 import org.mule.umo.provider.DispatchException;
27 import org.mule.umo.provider.UMOMessageReceiver;
28 import org.mule.util.FileUtils;
29 import org.mule.util.MapUtils;
30
31 import java.io.File;
32 import java.io.FileOutputStream;
33 import java.io.IOException;
34 import java.io.OutputStream;
35 import java.util.Map;
36 import java.util.Properties;
37
38 import org.apache.commons.logging.Log;
39 import org.apache.commons.logging.LogFactory;
40
41
42
43
44
45
46
47 public class FileConnector extends AbstractConnector
48 {
49
50
51
52 private static Log logger = LogFactory.getLog(FileConnector.class);
53
54
55
56 public static final String PROPERTY_POLLING_FREQUENCY = "pollingFrequency";
57 public static final String PROPERTY_FILE_AGE = "fileAge";
58 public static final String PROPERTY_FILENAME = "filename";
59 public static final String PROPERTY_ORIGINAL_FILENAME = "originalFilename";
60 public static final String PROPERTY_OUTPUT_PATTERN = "outputPattern";
61 public static final String PROPERTY_MOVE_TO_PATTERN = "moveToPattern";
62 public static final String PROPERTY_MOVE_TO_DIRECTORY = "moveToDirectory";
63 public static final String PROPERTY_DELETE_ON_READ = "autoDelete";
64 public static final String PROPERTY_DIRECTORY = "directory";
65 public static final String PROPERTY_SERVICE_OVERRIDE = "serviceOverrides";
66 public static final String PROPERTY_WRITE_TO_DIRECTORY = "writeToDirectoryName";
67 public static final String PROPERTY_FILE_SIZE = "fileSize";
68
69 public static final long DEFAULT_POLLING_FREQUENCY = 1000;
70
71
72
73
74
75 private long pollingFrequency = 0;
76
77 private String moveToPattern = null;
78
79 private String writeToDirectoryName = null;
80
81 private String moveToDirectoryName = null;
82
83 private String outputPattern = null;
84
85 private boolean outputAppend = false;
86
87 private boolean autoDelete = true;
88
89 private boolean checkFileAge = false;
90
91 private long fileAge = 0;
92
93 private FileOutputStream outputStream = null;
94
95 private boolean serialiseObjects = false;
96
97 public FilenameParser filenameParser;
98
99
100
101
102
103
104 public FileConnector()
105 {
106 super();
107
108
109
110 super.setMaxDispatchersActive(1);
111 filenameParser = new SimpleFilenameParser();
112 }
113
114
115 public void setMaxDispatchersActive(int value)
116 {
117 if (value != 1)
118 {
119 throw new IllegalArgumentException("MULE-1773: cannot configure maxDispatchersActive");
120 }
121 }
122
123
124 protected Object getReceiverKey(UMOComponent component, UMOEndpoint endpoint)
125 {
126 if (endpoint.getFilter() != null)
127 {
128 return endpoint.getEndpointURI().getAddress() + "/"
129 + ((FilenameWildcardFilter) endpoint.getFilter()).getPattern();
130 }
131 return endpoint.getEndpointURI().getAddress();
132 }
133
134
135
136
137
138
139
140
141
142
143
144 public UMOMessageReceiver createReceiver(UMOComponent component, UMOEndpoint endpoint) throws Exception
145 {
146 String readDir = endpoint.getEndpointURI().getAddress();
147 long polling = this.pollingFrequency;
148
149 String moveTo = moveToDirectoryName;
150 String moveToPattern = getMoveToPattern();
151
152 Map props = endpoint.getProperties();
153 if (props != null)
154 {
155
156 String move = (String) props.get(PROPERTY_MOVE_TO_DIRECTORY);
157 if (move != null)
158 {
159 moveTo = move;
160 }
161 String tempMoveToPattern = (String) props.get(PROPERTY_MOVE_TO_PATTERN);
162 if (tempMoveToPattern != null)
163 {
164 if (logger.isDebugEnabled())
165 {
166 logger.debug("set moveTo Pattern to: " + tempMoveToPattern);
167 }
168 moveToPattern = tempMoveToPattern;
169 }
170
171 String tempPolling = (String) props.get(PROPERTY_POLLING_FREQUENCY);
172 if (tempPolling != null)
173 {
174 polling = Long.parseLong(tempPolling);
175 }
176
177 if (polling <= 0)
178 {
179 polling = DEFAULT_POLLING_FREQUENCY;
180 }
181
182 if (logger.isDebugEnabled())
183 {
184 logger.debug("set polling frequency to: " + polling);
185 }
186 String tempFileAge = (String) props.get(PROPERTY_FILE_AGE);
187 if (tempFileAge != null)
188 {
189 try
190 {
191 setFileAge(Long.parseLong(tempFileAge));
192 }
193 catch (Exception ex1)
194 {
195 logger.error("Failed to set fileAge", ex1);
196 }
197 }
198 Map srvOverride = (Map) props.get(PROPERTY_SERVICE_OVERRIDE);
199 if (srvOverride != null)
200 {
201 if (serviceOverrides == null)
202 {
203 serviceOverrides = new Properties();
204 }
205 serviceOverrides.setProperty(MuleProperties.CONNECTOR_INBOUND_TRANSFORMER,
206 NoActionTransformer.class.getName());
207 serviceOverrides.setProperty(MuleProperties.CONNECTOR_OUTBOUND_TRANSFORMER,
208 NoActionTransformer.class.getName());
209 }
210 }
211
212 try
213 {
214 return serviceDescriptor.createMessageReceiver(this, component, endpoint, new Object[]{readDir,
215 moveTo, moveToPattern, new Long(polling)});
216
217 }
218 catch (Exception e)
219 {
220 throw new InitialisationException(
221 CoreMessages.failedToCreateObjectWith("Message Receiver",
222 serviceDescriptor.getMessageReceiver()), e, this);
223 }
224 }
225
226 public String getProtocol()
227 {
228 return "file";
229 }
230
231 public FilenameParser getFilenameParser()
232 {
233 return filenameParser;
234 }
235
236 public void setFilenameParser(FilenameParser filenameParser)
237 {
238 this.filenameParser = filenameParser;
239 }
240
241 protected void doDispose()
242 {
243 try
244 {
245 doStop();
246 }
247 catch (UMOException e)
248 {
249 logger.error(e.getMessage(), e);
250 }
251 }
252
253
254 protected void doInitialise() throws InitialisationException
255 {
256
257 }
258
259 protected void doConnect() throws Exception
260 {
261
262 }
263
264 protected void doDisconnect() throws Exception
265 {
266
267 }
268
269 protected void doStart() throws UMOException
270 {
271
272 }
273
274 protected void doStop() throws UMOException
275 {
276 if (outputStream != null)
277 {
278 try
279 {
280 outputStream.close();
281 }
282 catch (IOException e)
283 {
284 logger.warn("Failed to close file output stream on stop: " + e);
285 }
286 }
287 }
288
289
290
291
292 public String getMoveToDirectory()
293 {
294 return moveToDirectoryName;
295 }
296
297
298
299
300 public void setMoveToDirectory(String dir)
301 {
302 this.moveToDirectoryName = dir;
303 }
304
305
306
307
308 public boolean isOutputAppend()
309 {
310 return outputAppend;
311 }
312
313
314
315
316 public void setOutputAppend(boolean outputAppend)
317 {
318 this.outputAppend = outputAppend;
319 }
320
321
322
323
324 public String getOutputPattern()
325 {
326 return outputPattern;
327 }
328
329
330
331
332 public void setOutputPattern(String outputPattern)
333 {
334 this.outputPattern = outputPattern;
335 }
336
337
338
339
340 public FileOutputStream getOutputStream()
341 {
342 return outputStream;
343 }
344
345
346
347
348 public void setOutputStream(FileOutputStream outputStream)
349 {
350 this.outputStream = outputStream;
351 }
352
353
354
355
356 public long getPollingFrequency()
357 {
358 return pollingFrequency;
359 }
360
361
362
363
364 public void setPollingFrequency(long pollingFrequency)
365 {
366 this.pollingFrequency = pollingFrequency;
367 }
368
369
370
371
372 public long getFileAge()
373 {
374 return fileAge;
375 }
376
377 public boolean getCheckFileAge()
378 {
379 return checkFileAge;
380 }
381
382
383
384
385 public void setFileAge(long fileAge)
386 {
387 this.fileAge = fileAge;
388 this.checkFileAge = true;
389 }
390
391
392
393
394 public String getWriteToDirectory()
395 {
396 return writeToDirectoryName;
397 }
398
399
400
401
402 public void setWriteToDirectory(String dir) throws IOException
403 {
404 this.writeToDirectoryName = dir;
405 if (writeToDirectoryName != null)
406 {
407 File writeToDirectory = FileUtils.openDirectory((writeToDirectoryName));
408 if (!(writeToDirectory.canRead()) || !writeToDirectory.canWrite())
409 {
410 throw new IOException(
411 "Error on initialization, Write To directory does not exist or is not read/write");
412 }
413 }
414 }
415
416 public boolean isSerialiseObjects()
417 {
418 return serialiseObjects;
419 }
420
421 public void setSerialiseObjects(boolean serialiseObjects)
422 {
423
424 if (serialiseObjects)
425 {
426 if (serviceOverrides == null)
427 {
428 serviceOverrides = new Properties();
429 }
430 serviceOverrides.setProperty(MuleProperties.CONNECTOR_INBOUND_TRANSFORMER,
431 ByteArrayToSerializable.class.getName());
432 serviceOverrides.setProperty(MuleProperties.CONNECTOR_OUTBOUND_TRANSFORMER,
433 SerializableToByteArray.class.getName());
434 }
435
436 this.serialiseObjects = serialiseObjects;
437 }
438
439 public boolean isAutoDelete()
440 {
441 return autoDelete;
442 }
443
444 public void setAutoDelete(boolean autoDelete)
445 {
446 this.autoDelete = autoDelete;
447 if (!autoDelete)
448 {
449 if (serviceOverrides == null)
450 {
451 serviceOverrides = new Properties();
452 }
453 if (serviceOverrides.getProperty(MuleProperties.CONNECTOR_MESSAGE_ADAPTER) == null)
454 {
455 serviceOverrides.setProperty(MuleProperties.CONNECTOR_MESSAGE_ADAPTER,
456 FileMessageAdapter.class.getName());
457 }
458 }
459 }
460
461 public String getMoveToPattern()
462 {
463 return moveToPattern;
464 }
465
466 public void setMoveToPattern(String moveToPattern)
467 {
468 this.moveToPattern = moveToPattern;
469 }
470
471
472
473
474
475
476
477
478
479
480
481 public OutputStream getOutputStream(UMOImmutableEndpoint endpoint, UMOMessage message)
482 throws UMOException
483 {
484 String address = endpoint.getEndpointURI().getAddress();
485 String writeToDirectory = message.getStringProperty(
486 FileConnector.PROPERTY_WRITE_TO_DIRECTORY, null);
487 if (writeToDirectory == null)
488 {
489 writeToDirectory = getWriteToDirectory();
490 }
491 if (writeToDirectory != null)
492 {
493 address = getFilenameParser().getFilename(message, writeToDirectory);
494 }
495
496 String filename;
497 String outPattern = (String)endpoint.getProperty(FileConnector.PROPERTY_OUTPUT_PATTERN);
498 if (outPattern == null)
499 {
500 outPattern = message.getStringProperty(FileConnector.PROPERTY_OUTPUT_PATTERN, null);
501 }
502 if (outPattern == null)
503 {
504 outPattern = getOutputPattern();
505 }
506 try
507 {
508 if (outPattern != null)
509 {
510 filename = generateFilename(message, outPattern);
511 }
512 else
513 {
514 filename = message.getStringProperty(FileConnector.PROPERTY_FILENAME, null);
515 if (filename == null)
516 {
517 filename = generateFilename(message, null);
518 }
519 }
520
521 if (filename == null)
522 {
523 throw new IOException("Filename is null");
524 }
525 File file = FileUtils.createFile(address + "/" + filename);
526 if (logger.isInfoEnabled())
527 {
528 logger.info("Writing file to: " + file.getAbsolutePath());
529 }
530
531 return new FileOutputStream(file, MapUtils.getBooleanValue(endpoint.getProperties(),
532 "outputAppend", isOutputAppend()));
533 }
534 catch (IOException e)
535 {
536 throw new DispatchException(CoreMessages.streamingFailedNoStream(), message,
537 endpoint, e);
538 }
539 }
540
541 private String generateFilename(UMOMessage message, String pattern)
542 {
543 if (pattern == null)
544 {
545 pattern = getOutputPattern();
546 }
547 return getFilenameParser().getFilename(message, pattern);
548 }
549 }