1 22 package org.objectweb.petals.binding.filetransferbc.listeners; 23 24 import java.io.File ; 25 import java.util.HashSet ; 26 import java.util.Set ; 27 import java.util.Timer ; 28 import java.util.logging.Level ; 29 import java.util.logging.Logger ; 30 31 import javax.activation.DataHandler ; 32 import javax.activation.FileDataSource ; 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 ; 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 ; 57 58 67 public class FileTransferBCListener extends PeriodicTask { 68 69 private String address; 70 71 private Logger logger; 72 73 private AbstractBindingComponent component; 74 75 private File outputDir; 76 77 private File wasteDir; 78 79 private String operation; 80 81 private QName service; 82 83 private QName interfaceName; 84 85 private ServiceEndpoint endpoint; 86 87 97 public FileTransferBCListener(Logger logger, 98 AbstractBindingComponent component, String address, long pollingPeriod) { 99 super(0, pollingPeriod); 100 this.component = component; 101 this.logger = logger; 102 this.address = address; 103 } 104 105 110 public void run() { 111 File inDir = new File (address); 112 if (inDir.exists() && inDir.listFiles().length > 0) 113 processDirectory(inDir); 114 } 115 116 123 protected void processDirectory(File currentDir) { 124 logger.log(Level.FINE, "Processing directory : " 125 + currentDir.getAbsolutePath()); 126 127 boolean isInOutOperation = false; 128 boolean operationFound = false; 129 130 Document serviceDesc = null; 131 try { 132 serviceDesc = component.getContext() 133 .getEndpointDescriptor(endpoint); 134 135 try { 138 operationFound = WSDLHelper.hasOperationNamed(serviceDesc, 139 operation, service); 140 isInOutOperation = WSDLHelper.isInOutOperation(serviceDesc, 141 operation, service); 142 } catch (Exception 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 161 public void init() throws FileTransferBCException { 162 163 SimpleServiceUnitManager suManager = (SimpleServiceUnitManager) component 165 .getServiceUnitManager(); 166 Consumes consumes = suManager.getConsumesFromAddress(address); 167 168 String out = retrieveOutputDir(consumes.getExtensions()); 170 171 outputDir = new File (out); 173 if (!outputDir.exists()) 174 outputDir.mkdirs(); 175 176 wasteDir = new File (outputDir, "waste"); 178 if (!wasteDir.exists()) 179 wasteDir.mkdirs(); 180 181 this.operation = PetalsExtensionsUtil 183 .extractValueFromKeyValueExtension(consumes.getExtensions(), 184 "operation"); 185 186 this.service = consumes.getServiceName(); 188 189 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 this.interfaceName = consumes.getInterfaceName(); 202 } 203 204 211 protected String retrieveOutputDir(Extensions extensions) { 212 String tmp = PetalsExtensionsUtil.extractValueFromKeyValueExtension( 213 extensions, "output-dir"); 214 215 if (tmp == null) { 217 tmp = getDefaultDirectoryName(); 218 } 219 220 return tmp; 221 } 222 223 228 protected String getDefaultDirectoryName() { 229 String baseDir = component.getContext().getInstallRoot(); 230 StringBuffer sb = new StringBuffer (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 247 public boolean handleInOnlyMessage(String body, Set <DataHandler > attachments) 248 throws FileTransferBCException { 249 boolean result = false; 250 251 try { 252 InOnly msg = component.getChannel().createExchangeFactory() 253 .createInOnlyExchange(); 254 255 NormalizedMessage nm = msg.createMessage(); 257 nm.setContent(SourceHelper.createContentSource(body)); 258 259 for (DataHandler 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 ex) { 271 throw new FileTransferBCException(ex.getMessage()); 272 } 273 274 return result; 275 } 276 277 288 public boolean handleInOutMessage(String body, Set <DataHandler > attachments) 289 throws FileTransferBCException { 290 boolean result = true; 291 InOut msg = null; 292 String response = ""; 293 String 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 for (DataHandler dh : attachments) { 304 nm.addAttachment(dh.getName(), dh); 305 } 306 msg.setInMessage(nm); 307 308 sendMessage(msg); 310 311 if (msg.getStatus().equals(ExchangeStatus.ERROR)) { 313 fileName = "fault"; 314 response = SourceHelper.createString(msg.getFault() 315 .getContent()); 316 317 } else { 318 fileName = "content"; 319 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 msg.setStatus(ExchangeStatus.DONE); 330 channel.send(msg); 331 332 } catch (Exception ex) { 333 throw new FileTransferBCException(ex.getMessage()); 334 } 335 336 return result; 337 } 338 339 348 private void handleNewFiles(File srcDir, boolean inOut) { 349 350 File [] srcFiles = srcDir.listFiles(); 352 String body = "<?xml version='1.0' encoding='UTF-8'?><info>attached file(s)</info>"; 353 Set <DataHandler > attachments = new HashSet <DataHandler >(); 354 for (File src : srcFiles) { 355 if (!src.isDirectory()) { 356 DataHandler dhFile = new DataHandler (new FileDataSource (src)); 357 attachments.add(dhFile); 358 } 359 } 360 361 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 383 public void handleRobustInOnlyMessage(String body, 384 Set <DataHandler > attachments, QName service, String operation, 385 String 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 for (DataHandler dh : attachments) { 397 nm.addAttachment(dh.getName(), dh); 398 } 399 400 sendMessage(msg); 402 403 if (msg.getStatus().equals(ExchangeStatus.ERROR)) { 405 IOUtils.writeStringToFile(SourceHelper.createString(msg 406 .getFault().getContent()), new File (dirDest), "fault"); 407 msg.setStatus(ExchangeStatus.DONE); 408 channel.send(msg); 409 } 410 411 } catch (Exception ex) { 412 throw new FileTransferBCException(ex.getMessage()); 413 } 414 } 415 416 424 private void moveFilesToWaste(File [] files) { 425 for (File file : files) { 426 file.renameTo(new File (wasteDir, file.getName())); 427 } 428 } 429 430 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 messageExchange.setInterfaceName(interfaceName); 450 messageExchange.setService(service); 451 messageExchange.setEndpoint(endpoint); 452 messageExchange.setOperation(QName.valueOf(operation)); 453 454 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 469 public Timer getTimer() { 470 return this.timer; 471 } 472 473 } 474 | Popular Tags |