1 package org.jbpm.bpel.wsdl.util; 2 3 import java.io.File ; 4 import java.io.FileInputStream ; 5 import java.io.IOException ; 6 import java.net.URI ; 7 import java.net.URISyntaxException ; 8 import java.util.Iterator ; 9 import java.util.List ; 10 import java.util.Map ; 11 import java.util.zip.ZipInputStream ; 12 13 import javax.wsdl.Binding; 14 import javax.wsdl.BindingFault; 15 import javax.wsdl.BindingInput; 16 import javax.wsdl.BindingOperation; 17 import javax.wsdl.BindingOutput; 18 import javax.wsdl.Definition; 19 import javax.wsdl.Fault; 20 import javax.wsdl.Import; 21 import javax.wsdl.Operation; 22 import javax.wsdl.OperationType; 23 import javax.wsdl.Port; 24 import javax.wsdl.PortType; 25 import javax.wsdl.Service; 26 import javax.wsdl.WSDLException; 27 import javax.wsdl.extensions.ExtensionRegistry; 28 import javax.wsdl.extensions.soap.SOAPAddress; 29 import javax.wsdl.extensions.soap.SOAPBinding; 30 import javax.wsdl.extensions.soap.SOAPBody; 31 import javax.wsdl.extensions.soap.SOAPFault; 32 import javax.wsdl.extensions.soap.SOAPOperation; 33 import javax.xml.namespace.QName ; 34 35 import org.apache.commons.logging.Log; 36 import org.apache.commons.logging.LogFactory; 37 38 import com.ibm.wsdl.Constants; 39 import com.ibm.wsdl.extensions.soap.SOAPConstants; 40 41 import org.jbpm.jpdl.par.ProcessArchive; 42 import org.jbpm.jpdl.xml.Problem; 43 44 import org.jbpm.bpel.def.BpelDefinition; 45 import org.jbpm.bpel.def.BpelVisitorSupport; 46 import org.jbpm.bpel.def.ImportsDefinition; 47 import org.jbpm.bpel.def.Scope; 48 import org.jbpm.bpel.service.def.PartnerLinkDefinition; 49 import org.jbpm.bpel.service.soap.SoapBindConstants; 50 51 55 public class PortComponentsGenerator { 56 57 private String outputDirectory; 58 private String wsdlDirectory = "wsdl"; 59 private String interfaceFile = "interface.wsdl"; 60 private String implementationFile = "implementation.wsdl"; 61 62 private static final String ADDRESS_LOCATION_URI = "REPLACE_WITH_ACTUAL_URI"; 63 64 static final Log log = LogFactory.getLog(PortComponentsGenerator.class); 65 66 70 public String getOutputDirectory() { 71 return outputDirectory; 72 } 73 74 public void setOutputDirectory(String outputDirectory) { 75 this.outputDirectory = outputDirectory; 76 } 77 78 82 public String getWsdlDirectory() { 83 return wsdlDirectory; 84 } 85 86 public void setWsdlDirectory(String wsdlDirectory) { 87 this.wsdlDirectory = wsdlDirectory; 88 } 89 90 public String getImplementationFile() { 91 return implementationFile; 92 } 93 94 public void setImplementationFile(String implementationFile) { 95 this.implementationFile = implementationFile; 96 } 97 98 public String getInterfaceFile() { 99 return interfaceFile; 100 } 101 102 public void setInterfaceFile(String interfaceFile) { 103 this.interfaceFile = interfaceFile; 104 } 105 106 public void generatePortComponents(BpelDefinition process) { 107 new PortBuilder().visit(process); 108 } 109 110 public void generatePortComponent(PartnerLinkDefinition partnerLink, BpelDefinition process) 111 throws WSDLException { 112 File partnerLinkDir = new File (outputDirectory, partnerLink.getName()); 114 partnerLinkDir.mkdir(); 115 File wsdlDir = new File (partnerLinkDir, wsdlDirectory); 116 wsdlDir.mkdir(); 117 Definition implDefinition = generateImplDefinition(partnerLink, process); 119 List myNamespaceImports = implDefinition.getImports(implDefinition.getTargetNamespace()); 121 Import interfaceImport = (Import) myNamespaceImports.get(0); 122 URI location = URI.create(interfaceImport.getLocationURI()); 123 if (!location.isAbsolute()) { 124 WsdlUtil.writeFile(interfaceImport.getDefinition(), new File (wsdlDir, interfaceFile)); 126 log.debug("wrote interface wsdl document: " + interfaceFile); 127 interfaceImport.setLocationURI(interfaceFile); 128 } 129 WsdlUtil.writeFile(implDefinition, new File (wsdlDir, implementationFile)); 131 log.debug("wrote implementation wsdl document: " + implementationFile); 132 } 133 134 public Definition generateImplDefinition(PartnerLinkDefinition partnerLink, BpelDefinition process) 135 throws WSDLException { 136 PortType portType = partnerLink.getMyRole().getPortType(); 138 QName portTypeName = portType.getQName(); 139 ImportsDefinition imports = process.getImports(); 141 org.jbpm.bpel.def.Import bpelImport = imports.getDeclaringImport(portTypeName, Constants.Q_ELEM_PORT_TYPE); 142 Definition def = WsdlUtil.getFactory().newDefinition(); 144 Map namespaces = ( (Definition)bpelImport.getDocument() ).getNamespaces(); 146 Iterator namespaceIt = namespaces.keySet().iterator(); 147 while(namespaceIt.hasNext()) { 148 String prefix = (String ) namespaceIt.next(); 149 String namespaceUri = (String ) namespaces.get(prefix); 150 def.addNamespace(prefix, namespaceUri); 151 } 152 String targetNamespace = bpelImport.getNamespace(); 153 def.setTargetNamespace(targetNamespace); 154 Import ifaceImport = generateImport(def, bpelImport); 156 def.addImport(ifaceImport); 157 Binding binding = generateBinding(def, portType); 159 def.addBinding(binding); 160 Iterator operationIt = binding.getPortType().getOperations().iterator(); 162 while (operationIt.hasNext()) { 163 Operation operation = (Operation) operationIt.next(); 164 BindingOperation bindingOperation = generateBindOperation(def, operation); 165 binding.addBindingOperation(bindingOperation); 166 } 167 Service service = generateService(def, binding); 169 def.addService(service); 170 return def; 171 } 172 173 protected Import generateImport(Definition def, org.jbpm.bpel.def.Import bpelImport) { 174 Import interfaceImport = def.createImport(); 175 interfaceImport.setNamespaceURI(bpelImport.getNamespace()); 176 interfaceImport.setLocationURI(bpelImport.getLocation()); 177 interfaceImport.setDefinition((Definition) bpelImport.getDocument()); 178 return interfaceImport; 179 } 180 181 protected Binding generateBinding(Definition def, PortType portType) throws WSDLException { 182 Binding binding = def.createBinding(); 184 binding.setUndefined(false); 186 binding.setQName(new QName (def.getTargetNamespace(), portType.getQName().getLocalPart() + "Binding")); 187 binding.setPortType(portType); 188 def.addNamespace("soap", SOAPConstants.Q_ELEM_SOAP_BINDING.getNamespaceURI()); 189 190 ExtensionRegistry extRegistry = def.getExtensionRegistry(); 192 SOAPBinding soapBinding = (SOAPBinding) extRegistry.createExtension( 193 Binding.class, SOAPConstants.Q_ELEM_SOAP_BINDING); 194 soapBinding.setStyle(SoapBindConstants.RPC_STYLE); 195 soapBinding.setTransportURI(SoapBindConstants.HTTP_TRANSPORT_URI); 196 binding.addExtensibilityElement(soapBinding); 197 return binding; 198 } 199 200 protected BindingOperation generateBindOperation(Definition def, Operation operation) 201 throws WSDLException { 202 BindingOperation bindOperation = def.createBindingOperation(); 204 bindOperation.setOperation(operation); 205 bindOperation.setName(operation.getName()); 206 SOAPOperation soapOper = (SOAPOperation) def.getExtensionRegistry().createExtension( 208 BindingOperation.class, SOAPConstants.Q_ELEM_SOAP_OPERATION); 209 soapOper.setSoapActionURI(generateSoapAction(def, operation)); 210 bindOperation.addExtensibilityElement(soapOper); 211 BindingInput bindInput = generateBindInput(def, operation); 213 bindOperation.setBindingInput(bindInput); 214 if (operation.getStyle().equals(OperationType.REQUEST_RESPONSE)) { 216 BindingOutput bindOutput = generateBindOutput(def, operation); 217 bindOperation.setBindingOutput(bindOutput); 218 Iterator faultIt = operation.getFaults().values().iterator(); 220 while (faultIt.hasNext()) { 221 Fault fault = (Fault) faultIt.next(); 222 BindingFault bindFault = generateBindFault(def, fault); 223 bindOperation.addBindingFault(bindFault); 224 } 225 } 226 return bindOperation; 227 } 228 229 protected BindingInput generateBindInput(Definition def, Operation operation) 230 throws WSDLException { 231 BindingInput bindInput = def.createBindingInput(); 232 SOAPBody soapBody = (SOAPBody) def.getExtensionRegistry().createExtension( 234 BindingInput.class, SOAPConstants.Q_ELEM_SOAP_BODY); 235 soapBody.setUse(SoapBindConstants.LITERAL_USE); 236 soapBody.setNamespaceURI(generateSoapBodyNamespace(def, operation)); 237 bindInput.addExtensibilityElement(soapBody); 238 return bindInput; 239 } 240 241 protected BindingOutput generateBindOutput(Definition def, Operation operation) 242 throws WSDLException { 243 BindingOutput bindOutput = def.createBindingOutput(); 245 SOAPBody soapBody = (SOAPBody) def.getExtensionRegistry().createExtension( 247 BindingOutput.class, SOAPConstants.Q_ELEM_SOAP_BODY); 248 soapBody.setUse(SoapBindConstants.LITERAL_USE); 249 soapBody.setNamespaceURI(generateSoapBodyNamespace(def, operation)); 250 bindOutput.addExtensibilityElement(soapBody); 251 return bindOutput; 252 } 253 254 protected BindingFault generateBindFault(Definition def, Fault fault) throws WSDLException { 255 String faultName = fault.getName(); 256 BindingFault bindFault = def.createBindingFault(); 258 bindFault.setName(faultName); 259 SOAPFault soapFault = (SOAPFault) def.getExtensionRegistry().createExtension( 261 BindingFault.class, SOAPConstants.Q_ELEM_SOAP_FAULT); 262 soapFault.setName(faultName); 263 soapFault.setUse(SoapBindConstants.LITERAL_USE); 264 bindFault.addExtensibilityElement(soapFault); 265 return bindFault; 266 } 267 268 protected Service generateService(Definition def, Binding binding) throws WSDLException { 269 String targetNamespace = def.getTargetNamespace(); 270 String portTypeLocalName = binding.getPortType().getQName().getLocalPart(); 271 Service service = def.createService(); 273 service.setQName(new QName (targetNamespace, portTypeLocalName + "Service")); 274 Port port = def.createPort(); 276 port.setName(portTypeLocalName + "Port"); 277 port.setBinding(binding); 278 service.addPort(port); 279 SOAPAddress soapAddress = (SOAPAddress) def.getExtensionRegistry().createExtension( 281 Port.class, SOAPConstants.Q_ELEM_SOAP_ADDRESS); 282 soapAddress.setLocationURI(ADDRESS_LOCATION_URI); 283 port.addExtensibilityElement(soapAddress); 284 return service; 285 } 286 287 protected String generateSoapAction(Definition def, Operation operation) { 288 try { 289 return new URI (def.getTargetNamespace()).resolve(new URI (operation.getName())).toString(); 290 } 291 catch (URISyntaxException e) { 292 return ""; 293 } 294 } 295 296 protected String generateSoapBodyNamespace(Definition def, Operation operation) { 297 return def.getTargetNamespace(); 298 } 299 300 private class PortBuilder extends BpelVisitorSupport { 301 302 private BpelDefinition process; 303 304 PortBuilder() { 305 } 306 307 308 public void visit(BpelDefinition process) { 309 this.process = process; 310 propagate(process); 311 } 312 313 314 public void visit(Scope scope) { 315 Iterator partnerLinkIt = scope.getPartnerLinks().iterator(); 316 while (partnerLinkIt.hasNext()) { 317 PartnerLinkDefinition partnerLink = (PartnerLinkDefinition) partnerLinkIt.next(); 318 try { 319 generatePortComponent(partnerLink, process); 320 } 321 catch (WSDLException e) { 322 log.error(e); 323 throw new RuntimeException ("could not generate port component: " + partnerLink.getName(), e); 324 } 325 } 326 propagate(scope); 327 } 328 } 329 330 public static void main(String [] args) { 331 PortComponentsGenerator generator = new PortComponentsGenerator(); 332 333 int argCount = args.length; 334 switch (argCount) { 335 case 3: 336 if ("-d".equals(args[0])) { 337 generator.setOutputDirectory(args[1]); 338 generatePortComponents(generator, args[2]); 339 } 340 else { 341 log.error(args[0] + " is an invalid option or argument"); 342 usage(); 343 } 344 break; 345 case 1: 346 generatePortComponents(generator, args[0]); 347 break; 348 default: 349 log.error("invalid number of arguments"); 350 usage(); 351 } 352 } 353 354 private static void generatePortComponents(PortComponentsGenerator generator, String fileName) { 355 ZipInputStream archiveStream = null; 356 try { 357 archiveStream = new ZipInputStream (new FileInputStream (fileName)); 358 ProcessArchive archive = new ProcessArchive(archiveStream); 359 BpelDefinition definition = (BpelDefinition) archive.parseProcessDefinition(); 360 List problems = archive.getProblems(); 362 if (problems.isEmpty()) { 363 generator.generatePortComponents(definition); 365 } 366 else { 367 Iterator problemIt = problems.iterator(); 368 while (problemIt.hasNext()) { 369 Problem problem = (Problem) problemIt.next(); 370 log.error("problem parsing process definition", problem.getException()); 371 } 372 log.error(problems.size() + " problem(s) found"); 373 } 374 } 375 catch (Exception e) { 376 log.error("generation failed", e); 377 } 378 finally { 379 if (archiveStream != null) { 380 try { 381 archiveStream.close(); 382 } 383 catch (IOException e) { 384 log.warn("could not close file: " + fileName, e); 385 } 386 } 387 } 388 } 389 390 private static void usage() { 391 log.info("usage: PortComponentsGenerator [options] process_archive"); 392 log.info("where [options] include:"); 393 log.info("-d <directory> specify where to place generated output files"); 394 } 395 } 396 | Popular Tags |