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