KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > objectweb > petals > binding > filetransferbc > listeners > FileTransferBCListener


1 /**
2  * PETALS - PETALS Services Platform.
3  * Copyright (c) 2005 EBM Websourcing, http://www.ebmwebsourcing.com/
4  *
5  * This library is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU Lesser General Public
7  * License as published by the Free Software Foundation; either
8  * version 2.1 of the License, or (at your option) any later version.
9  * This library is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12  * Lesser General Public License for more details.
13  *
14  * You should have received a copy of the GNU Lesser General Public
15  * License along with this library; if not, write to the Free Software
16  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17  *
18  * -------------------------------------------------------------------------
19  * Id : ${file_name} 154 ${date} rbarraza
20  * -------------------------------------------------------------------------
21  */

22 package org.objectweb.petals.binding.filetransferbc.listeners;
23
24 import java.io.File JavaDoc;
25 import java.util.HashSet JavaDoc;
26 import java.util.Set JavaDoc;
27 import java.util.Timer JavaDoc;
28 import java.util.logging.Level JavaDoc;
29 import java.util.logging.Logger JavaDoc;
30
31 import javax.activation.DataHandler JavaDoc;
32 import javax.activation.FileDataSource JavaDoc;
33 import javax.jbi.JBIException;
34 import javax.jbi.messaging.DeliveryChannel;
35 import javax.jbi.messaging.ExchangeStatus;
36 import javax.jbi.messaging.InOnly;
37 import javax.jbi.messaging.InOut;
38 import javax.jbi.messaging.MessageExchange;
39 import javax.jbi.messaging.MessagingException;
40 import javax.jbi.messaging.NormalizedMessage;
41 import javax.jbi.messaging.RobustInOnly;
42 import javax.jbi.servicedesc.ServiceEndpoint;
43 import javax.xml.namespace.QName JavaDoc;
44
45 import org.objectweb.petals.binding.filetransferbc.FileTransferBCException;
46 import org.objectweb.petals.binding.filetransferbc.IOUtils;
47 import org.objectweb.petals.component.common.bc.AbstractBindingComponent;
48 import org.objectweb.petals.component.common.su.SimpleServiceUnitManager;
49 import org.objectweb.petals.component.common.util.PetalsExtensionsUtil;
50 import org.objectweb.petals.component.common.util.SourceHelper;
51 import org.objectweb.petals.component.common.util.WSDLHelper;
52 import org.objectweb.petals.tools.jbicommon.descriptor.Consumes;
53 import org.objectweb.petals.tools.jbicommon.descriptor.Extensions;
54 import org.objectweb.petals.tools.jbicommon.util.PeriodicTask;
55 import org.objectweb.petals.tools.jbicommon.util.StringHelper;
56 import org.w3c.dom.Document JavaDoc;
57
58 /**
59  * The task which scans the file transfer working directories. It builds JBI
60  * message with files as attachments and send them to the defined endpoint.
61  *
62  * @version $Rev: 250 $Date: {date}
63  * @since Petals 1.0
64  * @author Christophe HAMERLING - eBM WebSourcing
65  *
66  */

67 public class FileTransferBCListener extends PeriodicTask {
68
69     private String JavaDoc address;
70
71     private Logger JavaDoc logger;
72
73     private AbstractBindingComponent component;
74
75     private File JavaDoc outputDir;
76     
77     private File JavaDoc wasteDir;
78
79     private String JavaDoc operation;
80
81     private QName JavaDoc service;
82
83     private QName JavaDoc interfaceName;
84
85     private ServiceEndpoint endpoint;
86
87     /**
88      * Creates a new instance of {@link FileTransferBCListener}
89      *
90      * @param logger
91      * @param channel
92      * @param context
93      * @param jbiListener
94      * @param mapDirConfig
95      * @param dir
96      */

97     public FileTransferBCListener(Logger JavaDoc logger,
98         AbstractBindingComponent component, String JavaDoc address, long pollingPeriod) {
99         super(0, pollingPeriod);
100         this.component = component;
101         this.logger = logger;
102         this.address = address;
103     }
104
105     /*
106      * (non-Javadoc)
107      *
108      * @see java.lang.Runnable#run()
109      */

110     public void run() {
111         File JavaDoc inDir = new File JavaDoc(address);
112         if (inDir.exists() && inDir.listFiles().length > 0)
113             processDirectory(inDir);
114     }
115
116     /**
117      * Scan the current directory. Get the files and send them to destination
118      * through a JBI message.
119      *
120      * @param currentDir
121      * the directory to get files from
122      */

123     protected void processDirectory(File JavaDoc currentDir) {
124         logger.log(Level.FINE, "Processing directory : "
125             + currentDir.getAbsolutePath());
126
127         boolean isInOutOperation = false;
128         boolean operationFound = false;
129         
130         Document JavaDoc serviceDesc = null;
131         try {
132             serviceDesc = component.getContext()
133                 .getEndpointDescriptor(endpoint);
134
135             // Determines if the operation exists and if it is an inOnly or
136
// inOut operation
137
try {
138                 operationFound = WSDLHelper.hasOperationNamed(serviceDesc,
139                     operation, service);
140                 isInOutOperation = WSDLHelper.isInOutOperation(serviceDesc,
141                     operation, service);
142             } catch (Exception JavaDoc e) {
143                 operationFound = false;
144                 isInOutOperation = false;
145                 this.logger.log(Level.WARNING, e.getMessage());
146             }
147
148             if (operationFound)
149                 handleNewFiles(currentDir, isInOutOperation);
150
151         } catch (JBIException e) {
152             this.logger.log(Level.INFO,
153                 "Error verifying operation definition ", e.getMessage());
154         }
155     }
156
157     /**
158      * Init data
159      *
160      */

161     public void init() throws FileTransferBCException {
162
163         // Get required datas
164
SimpleServiceUnitManager suManager = (SimpleServiceUnitManager) component
165             .getServiceUnitManager();
166         Consumes consumes = suManager.getConsumesFromAddress(address);
167
168         // get output directory
169
String JavaDoc out = retrieveOutputDir(consumes.getExtensions());
170
171         // create the output direcotry if it not exists
172
outputDir = new File JavaDoc(out);
173         if (!outputDir.exists())
174             outputDir.mkdirs();
175
176         // create the waste dir used to save transfered files
177
wasteDir = new File JavaDoc(outputDir, "waste");
178         if (!wasteDir.exists())
179             wasteDir.mkdirs();
180
181         // get operation name
182
this.operation = PetalsExtensionsUtil
183             .extractValueFromKeyValueExtension(consumes.getExtensions(),
184                 "operation");
185
186         // get servive name
187
this.service = consumes.getServiceName();
188
189         // get service endpoint
190
if (consumes.getEndpointName() != null
191             && consumes.getServiceName() != null) {
192             this.endpoint = component.getContext().getEndpoint(service,
193                 consumes.getEndpointName());
194             
195             if (endpoint == null) {
196                 throw new FileTransferBCException("Could not get endpoint " + consumes.getEndpointName());
197             }
198         }
199
200         // get interface name
201
this.interfaceName = consumes.getInterfaceName();
202     }
203
204     /**
205      * Retrieve the output directory from the consumes bean. If the output
206      * directory has not been set, set the default directory to the component
207      * installation root.
208      *
209      * @param extensions
210      */

211     protected String JavaDoc retrieveOutputDir(Extensions extensions) {
212         String JavaDoc tmp = PetalsExtensionsUtil.extractValueFromKeyValueExtension(
213             extensions, "output-dir");
214
215         // output dir has not been set, get JBI output directory
216
if (tmp == null) {
217             tmp = getDefaultDirectoryName();
218         }
219
220         return tmp;
221     }
222     
223     /**
224      * Get the default directory name
225      *
226      * @return
227      */

228     protected String JavaDoc getDefaultDirectoryName() {
229         String JavaDoc baseDir = component.getContext().getInstallRoot();
230         StringBuffer JavaDoc sb = new StringBuffer JavaDoc(baseDir.substring(0, baseDir
231             .length()
232             - "install".length()));
233         sb.append("work");
234         sb.append(File.separator);
235         return sb.toString();
236     }
237
238     /**
239      * Handle an InOnly message
240      *
241      * @param body
242      * @param service
243      * @param operation
244      * @return
245      * @throws FileTransferBCException
246      */

247     public boolean handleInOnlyMessage(String JavaDoc body, Set JavaDoc<DataHandler JavaDoc> attachments)
248         throws FileTransferBCException {
249         boolean result = false;
250
251         try {
252             InOnly msg = component.getChannel().createExchangeFactory()
253                 .createInOnlyExchange();
254
255             // Create and send messageExchange
256
NormalizedMessage nm = msg.createMessage();
257             nm.setContent(SourceHelper.createContentSource(body));
258
259             // add attachments
260
for (DataHandler JavaDoc dh : attachments) {
261                 nm.addAttachment(dh.getName(), dh);
262             }
263             msg.setInMessage(nm);
264
265             sendMessage(msg);
266             if (ExchangeStatus.DONE.equals(msg.getStatus())) {
267                 result = true;
268             }
269
270         } catch (Exception JavaDoc ex) {
271             throw new FileTransferBCException(ex.getMessage());
272         }
273
274         return result;
275     }
276
277     /**
278      * Handle an inout message. Send the files through JBI and wait for a
279      * response. If the response contains files, the files are written to disk.
280      *
281      * @param body
282      * @param service
283      * @param operation
284      * @param destDir
285      * @return
286      * @throws FileTransferBCException
287      */

288     public boolean handleInOutMessage(String JavaDoc body, Set JavaDoc<DataHandler JavaDoc> attachments)
289         throws FileTransferBCException {
290         boolean result = true;
291         InOut msg = null;
292         String JavaDoc response = "";
293         String JavaDoc fileName = "";
294         DeliveryChannel channel = component.getChannel();
295
296         try {
297             msg = channel.createExchangeFactory().createInOutExchange();
298
299             NormalizedMessage nm = msg.createMessage();
300             nm.setContent(SourceHelper.createContentSource(body));
301
302             // add attachments
303
for (DataHandler JavaDoc dh : attachments) {
304                 nm.addAttachment(dh.getName(), dh);
305             }
306             msg.setInMessage(nm);
307
308             // send the message
309
sendMessage(msg);
310
311             // Verify if request was success,if not, handle the error message
312
if (msg.getStatus().equals(ExchangeStatus.ERROR)) {
313                 fileName = "fault";
314                 response = SourceHelper.createString(msg.getFault()
315                     .getContent());
316
317             } else {
318                 fileName = "content";
319                 // if there wasn't errors , binding component handle out reponse
320
NormalizedMessage nmOut = msg.getMessage("OUT");
321                 response = SourceHelper.createString(nmOut.getContent());
322
323                 IOUtils.writeAttachmentsToFiles(nmOut, outputDir);
324             }
325
326             IOUtils.writeStringToFile(response, outputDir, fileName);
327
328             // Send status DONE to complete the exchange
329
msg.setStatus(ExchangeStatus.DONE);
330             channel.send(msg);
331
332         } catch (Exception JavaDoc ex) {
333             throw new FileTransferBCException(ex.getMessage());
334         }
335
336         return result;
337     }
338
339     /**
340      * Handle the files of the directory
341      *
342      * @param srcDir
343      * @param inOut
344      * @param service
345      * @param operation
346      * @param destDir
347      */

348     private void handleNewFiles(File JavaDoc srcDir, boolean inOut) {
349
350         // Create body and attachements
351
File JavaDoc[] srcFiles = srcDir.listFiles();
352         String JavaDoc body = "<?xml version='1.0' encoding='UTF-8'?><info>attached file(s)</info>";
353         Set JavaDoc<DataHandler JavaDoc> attachments = new HashSet JavaDoc<DataHandler JavaDoc>();
354         for (File JavaDoc src : srcFiles) {
355             if (!src.isDirectory()) {
356                 DataHandler JavaDoc dhFile = new DataHandler JavaDoc(new FileDataSource JavaDoc(src));
357                 attachments.add(dhFile);
358             }
359         }
360
361         // send files through JBI
362
try {
363             if (!inOut) {
364                 handleInOnlyMessage(body, attachments);
365             } else {
366                 handleInOutMessage(body, attachments);
367             }
368         } catch (FileTransferBCException e) {
369             this.logger.log(Level.WARNING, e.getMessage());
370         } finally {
371             moveFilesToWaste(srcFiles);
372         }
373     }
374
375     /**
376      * Handle RobustInOnly messages
377      *
378      * @param mailCorps
379      * @param service
380      * @param operation
381      * @throws SMTPBCException
382      */

383     public void handleRobustInOnlyMessage(String JavaDoc body,
384         Set JavaDoc<DataHandler JavaDoc> attachments, QName JavaDoc service, String JavaDoc operation,
385         String JavaDoc dirDest) throws FileTransferBCException {
386
387         DeliveryChannel channel = component.getChannel();
388
389         try {
390             RobustInOnly msg = channel.createExchangeFactory()
391                 .createRobustInOnlyExchange();
392             NormalizedMessage nm = msg.createMessage();
393             nm.setContent(SourceHelper.createContentSource(body));
394
395             // add attachments
396
for (DataHandler JavaDoc dh : attachments) {
397                 nm.addAttachment(dh.getName(), dh);
398             }
399
400             // send message
401
sendMessage(msg);
402
403             // if error occured, write it to file
404
if (msg.getStatus().equals(ExchangeStatus.ERROR)) {
405                 IOUtils.writeStringToFile(SourceHelper.createString(msg
406                     .getFault().getContent()), new File JavaDoc(dirDest), "fault");
407                 msg.setStatus(ExchangeStatus.DONE);
408                 channel.send(msg);
409             }
410
411         } catch (Exception JavaDoc ex) {
412             throw new FileTransferBCException(ex.getMessage());
413         }
414     }
415
416     /**
417      * Move the files to the waste directory.
418      *
419      * @param files
420      * the files to move
421      * @param parentDir
422      * the parent directory (waste directory is included)
423      */

424     private void moveFilesToWaste(File JavaDoc[] files) {
425         for (File JavaDoc file : files) {
426             file.renameTo(new File JavaDoc(wasteDir, file.getName()));
427         }
428     }
429
430     /**
431      * Send message to endpoint
432      *
433      * @param messageExchange
434      * @throws MessagingException
435      */

436     private void sendMessage(final MessageExchange messageExchange)
437         throws MessagingException {
438
439         if (StringHelper.isNullOrEmpty(address)) {
440             throw new MessagingException(
441                 "You must provide a non null and non empty address");
442         }
443         if (messageExchange == null) {
444             throw new MessagingException(
445                 "You must provide a non null MessageExchange");
446         }
447
448         // set message exchange properties
449
messageExchange.setInterfaceName(interfaceName);
450         messageExchange.setService(service);
451         messageExchange.setEndpoint(endpoint);
452         messageExchange.setOperation(QName.valueOf(operation));
453
454         // send message
455
try {
456             component.getChannel().sendSync(messageExchange);
457         } catch (JBIException e) {
458             throw new MessagingException(
459                 "Failed to send the mapped message to the delivery channel.");
460         }
461
462     }
463
464     /**
465      * Get the timer for this task
466      *
467      * @return
468      */

469     public Timer JavaDoc getTimer() {
470         return this.timer;
471     }
472
473 }
474
Popular Tags