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