Java tutorial
/* * JBoss, Home of Professional Open Source * Copyright 2005, JBoss Inc., and individual contributors as indicated * by the @authors tag. * * This is free software; you can redistribute it and/or modify it * under the terms of the JBPM BPEL PUBLIC LICENSE AGREEMENT as * published by JBoss Inc.; either version 1.0 of the License, or * (at your option) any later version. * * This software is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. */ package org.jbpm.bpel.tools; import java.io.File; import java.io.IOException; import java.net.URI; import java.net.URISyntaxException; import java.util.ArrayList; import java.util.Collections; import java.util.HashMap; import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.Set; import javax.wsdl.Binding; import javax.wsdl.BindingFault; import javax.wsdl.BindingInput; import javax.wsdl.BindingOperation; import javax.wsdl.BindingOutput; import javax.wsdl.Definition; import javax.wsdl.Fault; import javax.wsdl.Import; import javax.wsdl.Input; import javax.wsdl.Message; import javax.wsdl.Operation; import javax.wsdl.Output; import javax.wsdl.Part; import javax.wsdl.Port; import javax.wsdl.PortType; import javax.wsdl.Service; import javax.wsdl.WSDLException; import javax.wsdl.extensions.ExtensionRegistry; import javax.wsdl.extensions.soap.SOAPAddress; import javax.wsdl.extensions.soap.SOAPBinding; import javax.wsdl.extensions.soap.SOAPBody; import javax.wsdl.extensions.soap.SOAPFault; import javax.wsdl.extensions.soap.SOAPOperation; import javax.wsdl.xml.WSDLWriter; import javax.xml.namespace.QName; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.w3c.dom.Element; import com.ibm.wsdl.Constants; import com.ibm.wsdl.extensions.soap.SOAPConstants; import org.jbpm.bpel.deploy.DeploymentDescriptor; import org.jbpm.bpel.deploy.MyRoleDescriptor; import org.jbpm.bpel.deploy.PartnerLinkDescriptor; import org.jbpm.bpel.deploy.ScopeDescriptor; import org.jbpm.bpel.graph.def.AbstractBpelVisitor; import org.jbpm.bpel.graph.def.BpelProcessDefinition; import org.jbpm.bpel.graph.def.ImportDefinition; import org.jbpm.bpel.graph.scope.Scope; import org.jbpm.bpel.integration.catalog.CentralCatalog; import org.jbpm.bpel.integration.catalog.ServiceCatalog; import org.jbpm.bpel.integration.def.PartnerLinkDefinition; import org.jbpm.bpel.integration.soap.SoapBindConstants; import org.jbpm.bpel.wsdl.PartnerLinkType.Role; import org.jbpm.bpel.wsdl.xml.WsdlUtil; import org.jbpm.bpel.xml.BpelConstants; import org.jbpm.bpel.xml.DeploymentDescriptorWriter; import org.jbpm.bpel.xml.ProblemCounter; import org.jbpm.bpel.xml.ProblemHandler; import org.jbpm.bpel.xml.util.XmlUtil; import org.jbpm.jpdl.xml.Problem; /** * Generates WSDL binding and service definitions. * @author Alejandro Guizar * @author Juan Cantu * @version $Revision$ $Date: 2008/02/05 05:37:34 $ */ public class WsdlServiceTool { private File wsdlDirectory = DEFAULT_WSDL_DIRECTORY; private String bindingFilesPrefix = DEFAULT_BINDING_FILES_PREFIX; private String bindingFilesSuffix = DEFAULT_BINDING_FILES_SUFFIX; private String serviceFileName = DEFAULT_SERVICE_FILE_NAME; private File deploymentDescriptorFile = DEFAULT_DEPLOYMENT_DESCRIPTOR_FILE; private ProblemHandler problemHandler = new ProblemCounter(); static final File DEFAULT_WSDL_DIRECTORY = FileUtil.CURRENT_DIRECTORY; static final String DEFAULT_BINDING_FILES_PREFIX = "binding"; static final String DEFAULT_BINDING_FILES_SUFFIX = ".wsdl"; static final String DEFAULT_SERVICE_FILE_NAME = "service.wsdl"; static final File DEFAULT_DEPLOYMENT_DESCRIPTOR_FILE = new File(DeploymentDescriptor.FILE_NAME); private static final String ADDRESS_LOCATION_URI = "REPLACE_WITH_ACTUAL_URI"; private static final Log log = LogFactory.getLog(WsdlServiceTool.class); /** * Returns where to place generated WSDL files. * @return the WSDL directory */ public File getWsdlDirectory() { return wsdlDirectory; } /** * Specifies where to place generated WSDL files. * @param wsdlDirectory the directory for generated WSDL files * @throws IllegalArgumentException if the argument is <code>null</code> */ public void setWsdlDirectory(File wsdlDirectory) { if (wsdlDirectory == null) throw new IllegalArgumentException("wsdl directory cannot be null"); this.wsdlDirectory = wsdlDirectory; } /** * Returns the prefix used to construct the name of WSDL binding files. * @return the WSDL binding files prefix */ public String getBindingFilesPrefix() { return bindingFilesPrefix; } /** * Sets the prefix used to construct the name of WSDL binding files. * @param bindingFilePrefix the WSDL binding files prefix * @throws IllegalArgumentException if the argument is <code>null</code> */ public void setBindingFilesPrefix(String bindingFilePrefix) { if (bindingFilePrefix == null) throw new IllegalArgumentException("binding files prefix cannot be null"); this.bindingFilesPrefix = bindingFilePrefix; } /** * Returns the suffix used to generate the name of WSDL binding files. * @return the WSDL binding files suffix */ public String getBindingFilesSuffix() { return bindingFilesSuffix; } /** * Sets the suffix used to generate the name of WSDL binding files. * @param bindingFileSuffix the WSDL binding files suffix * @throws IllegalArgumentException if the argument is <code>null</code> */ public void setBindingFilesSuffix(String bindingFileSuffix) { if (bindingFileSuffix == null) throw new IllegalArgumentException("binding files suffix cannot be null"); this.bindingFilesSuffix = bindingFileSuffix; } /** * Returns the name of the generated WSDL service file. * @return the WSDL service file name */ public String getServiceFileName() { return serviceFileName; } /** * Sets the name of the generated WSDL service file. * @param serviceFileName the WSDL service file name * @throws IllegalArgumentException if the argument is <code>null</code> */ public void setServiceFileName(String serviceFileName) { if (serviceFileName == null) throw new IllegalArgumentException("service file name cannot be null"); this.serviceFileName = serviceFileName; } /** * Returns where to write the application descriptor. * @return the application descriptor file */ public File getDeploymentDescriptorFile() { return deploymentDescriptorFile; } /** * Specifies where to write the application descriptor. * @param deploymentDescriptorFile the application descriptor file */ public void setDeploymentDescriptorFile(File deploymentDescriptorFile) { this.deploymentDescriptorFile = deploymentDescriptorFile; } public ProblemHandler getProblemHandler() { return problemHandler; } public void setProblemHandler(ProblemHandler problemHandler) { if (problemHandler == null) throw new IllegalArgumentException("problem handler cannot be null"); this.problemHandler = problemHandler; } public void generateWsdlService(BpelProcessDefinition process) { // generate the binding and service documents ServiceDefinitionBuilder serviceDefinitionBuilder = new ServiceDefinitionBuilder(); serviceDefinitionBuilder.visit(process); // write required interface files WSDLWriter wsdlWriter = WsdlUtil.getFactory().newWSDLWriter(); Map interfaceFiles = serviceDefinitionBuilder.getInterfaceFiles(); for (Iterator i = interfaceFiles.entrySet().iterator(); i.hasNext();) { Map.Entry interfaceEntry = (Map.Entry) i.next(); File interfaceFile = (File) interfaceEntry.getKey(); Definition interfaceDefinition = (Definition) interfaceEntry.getValue(); // write interface file try { WsdlUtil.writeFile(interfaceFile, interfaceDefinition, wsdlWriter); log.debug("wrote interface definition: " + interfaceFile.getName()); } catch (WSDLException e) { problemHandler.add(new Problem(Problem.LEVEL_ERROR, "could not write interface definition: " + interfaceFile, e)); } } // write binding files StringBuffer bindingFileNameBuffer = new StringBuffer(bindingFilesPrefix); int bindingCount = 0; Definition serviceDefinition = serviceDefinitionBuilder.getServiceDefinition(); for (Iterator i = serviceDefinition.getImports().values().iterator(); i.hasNext();) { List bindingImports = (List) i.next(); assert bindingImports.size() == 1 : bindingImports.size(); // format binding filename bindingFileNameBuffer.setLength(bindingFilesPrefix.length()); String bindingFileName = bindingFileNameBuffer.append(++bindingCount).append(bindingFilesSuffix) .toString(); // fill import location Import bindingImport = (Import) bindingImports.get(0); bindingImport.setLocationURI(bindingFileName); // write binding file File bindingFile = new File(wsdlDirectory, bindingFileName); try { WsdlUtil.writeFile(bindingFile, bindingImport.getDefinition(), wsdlWriter); log.debug("wrote binding definition: " + bindingFile.getName()); } catch (WSDLException e) { problemHandler.add( new Problem(Problem.LEVEL_ERROR, "could not write binding definition: " + bindingFile, e)); } } // write service file File serviceFile = new File(wsdlDirectory, serviceFileName); try { WsdlUtil.writeFile(serviceFile, serviceDefinition, wsdlWriter); log.debug("wrote service definition: " + serviceFile.getName()); } catch (WSDLException e) { problemHandler .add(new Problem(Problem.LEVEL_ERROR, "could not write service definition: " + serviceFile, e)); } // write deployment descriptor, if requested if (deploymentDescriptorFile != null) { DeploymentDescriptor deploymentDescriptor = serviceDefinitionBuilder.getDeploymentDescriptor(); // transform descriptor to xml format Element descriptorElem = XmlUtil.createElement(BpelConstants.NS_DEPLOYMENT_DESCRIPTOR, BpelConstants.ELEM_BPEL_DEPLOYMENT); DeploymentDescriptorWriter.getInstance().write(deploymentDescriptor, descriptorElem); // write descriptor file try { XmlUtil.writeFile(descriptorElem, deploymentDescriptorFile); log.debug("wrote deployment descriptor: " + deploymentDescriptorFile.getName()); } catch (IOException e) { problemHandler.add(new Problem(Problem.LEVEL_ERROR, "could not write deployment descriptor: " + deploymentDescriptorFile, e)); } } } protected Definition createDefinition(String targetNamespace) { Definition def = WsdlUtil.getFactory().newDefinition(); def.setTargetNamespace(targetNamespace); def.addNamespace("tns", targetNamespace); def.addNamespace("soap", SOAPConstants.NS_URI_SOAP); def.addNamespace(null, Constants.NS_URI_WSDL); return def; } protected Definition generateServiceDefinition(BpelProcessDefinition processDefinition) { return createDefinition(processDefinition.getTargetNamespace()); } protected String generateServiceLocalName(BpelProcessDefinition processDefinition, Definition serviceDefinition) { return processDefinition.getName() + "Service"; } protected DeploymentDescriptor generateDeploymentDescriptor(BpelProcessDefinition processDefinition) { DeploymentDescriptor deploymentDescriptor = new DeploymentDescriptor(); deploymentDescriptor.setName(processDefinition.getName()); deploymentDescriptor.setTargetNamespace(processDefinition.getTargetNamespace()); deploymentDescriptor.setVersion(new Integer(processDefinition.getVersion())); return deploymentDescriptor; } private static Definition getBindingDefinition(Definition serviceDefinition, String targetNamespace) { List imports = serviceDefinition.getImports(targetNamespace); if (imports == null || imports.isEmpty()) return null; Import _import = (Import) imports.get(0); return _import.getDefinition(); } protected Definition generateBindingDefinition(PartnerLinkDefinition partnerLink, Definition serviceDefinition) throws WSDLException { String targetNamespace = partnerLink.getMyRole().getPortType().getQName().getNamespaceURI(); return createDefinition(targetNamespace); } protected Import generateBindingImport(Definition serviceDefinition, Definition bindingDefinition) { // import the binding definition from the service definition Import bindingImport = serviceDefinition.createImport(); bindingImport.setNamespaceURI(bindingDefinition.getTargetNamespace()); bindingImport.setDefinition(bindingDefinition); return bindingImport; } private static Import getInterfaceImport(Definition bindingDefinition, String interfaceLocation) { List imports = bindingDefinition.getImports(bindingDefinition.getTargetNamespace()); if (imports != null) { for (int i = 0, n = imports.size(); i < n; i++) { Import _import = (Import) imports.get(i); if (_import.getLocationURI().equals(interfaceLocation)) return _import; } } return null; } protected Import generateInterfaceImport(Definition bindingDefinition, Definition interfaceDefinition) throws WSDLException { Import interfaceImport = bindingDefinition.createImport(); interfaceImport.setNamespaceURI(interfaceDefinition.getTargetNamespace()); interfaceImport.setDefinition(interfaceDefinition); return interfaceImport; } protected String generateBindingLocalName(PartnerLinkDefinition partnerLink, Definition bindingDefinition) { return partnerLink.getMyRole().getPortType().getQName().getLocalPart() + "Binding"; } protected Binding generateBinding(PortType portType, Definition bindingDefinition) throws WSDLException { // wsdl binding Binding binding = bindingDefinition.createBinding(); binding.setPortType(portType); // the binding is fully specified, mark it as defined binding.setUndefined(false); // soap binding ExtensionRegistry extRegistry = bindingDefinition.getExtensionRegistry(); SOAPBinding soapBinding = (SOAPBinding) extRegistry.createExtension(Binding.class, SOAPConstants.Q_ELEM_SOAP_BINDING); String style = determineBindingStyle(portType); soapBinding.setStyle(style); soapBinding.setTransportURI(SoapBindConstants.HTTP_TRANSPORT_URI); binding.addExtensibilityElement(soapBinding); // operations for (Iterator i = portType.getOperations().iterator(); i.hasNext();) { Operation operation = (Operation) i.next(); BindingOperation bindingOperation = generateBindingOperation(operation, bindingDefinition, style); binding.addBindingOperation(bindingOperation); } return binding; } /** * Determines the appropriate binding style for the given port type according to BP 1.2 * requirements. * @param portType the port type whose binding style is to be determined * @return "{@linkplain SoapBindConstants#RPC_STYLE rpc}" if the port type references one or * more parts that have been defined using the type attribute; "{@linkplain SoapBindConstants#DOCUMENT_STYLE document}" * otherwise */ protected String determineBindingStyle(PortType portType) { /* * BP 1.2 R2203: An rpc-literal binding MUST refer, in its soapbind:body element(s), only to * wsdl:part element(s) that have been defined using the type attribute */ for (Iterator i = portType.getOperations().iterator(); i.hasNext();) { Operation operation = (Operation) i.next(); // input message Input input = operation.getInput(); if (input != null && containsTypePart(input.getMessage())) return SoapBindConstants.RPC_STYLE; // output message Output output = operation.getOutput(); if (output != null && containsTypePart(output.getMessage())) return SoapBindConstants.RPC_STYLE; } return SoapBindConstants.DOCUMENT_STYLE; } private static boolean containsTypePart(Message message) { for (Iterator i = message.getParts().values().iterator(); i.hasNext();) { Part part = (Part) i.next(); if (part.getTypeName() != null) return true; } return false; } protected BindingOperation generateBindingOperation(Operation operation, Definition bindingDefinition, String style) throws WSDLException { // binding operation BindingOperation bindOperation = bindingDefinition.createBindingOperation(); bindOperation.setOperation(operation); bindOperation.setName(operation.getName()); // soap operation SOAPOperation soapOper = (SOAPOperation) bindingDefinition.getExtensionRegistry() .createExtension(BindingOperation.class, SOAPConstants.Q_ELEM_SOAP_OPERATION); soapOper.setSoapActionURI(generateSoapAction(operation, bindingDefinition)); bindOperation.addExtensibilityElement(soapOper); // binding input BindingInput bindInput = generateBindingInput(operation.getInput(), bindingDefinition, style); bindOperation.setBindingInput(bindInput); // request-response operations have an output and zero or more faults if (operation.getOutput() != null) { BindingOutput bindOutput = generateBindingOutput(operation.getOutput(), bindingDefinition, style); bindOperation.setBindingOutput(bindOutput); // faults for (Iterator i = operation.getFaults().values().iterator(); i.hasNext();) { Fault fault = (Fault) i.next(); BindingFault bindFault = generateBindingFault(fault, bindingDefinition); bindOperation.addBindingFault(bindFault); } } return bindOperation; } protected String generateSoapAction(Operation operation, Definition bindingDefinition) { try { // target namespace URI targetNamespaceURI = new URI(bindingDefinition.getTargetNamespace()); // set the operation name as the fragment of the target namespace URI URI soapActionURI = new URI(targetNamespaceURI.getScheme(), targetNamespaceURI.getSchemeSpecificPart(), operation.getName()); return soapActionURI.toString(); } catch (URISyntaxException e) { // target namespace is not a valid URI - generate an empty action return ""; } } protected BindingInput generateBindingInput(Input input, Definition bindingDefinition, String style) throws WSDLException { // soap body SOAPBody soapBody = (SOAPBody) bindingDefinition.getExtensionRegistry().createExtension(BindingInput.class, SOAPConstants.Q_ELEM_SOAP_BODY); soapBody.setUse(SoapBindConstants.LITERAL_USE); if (SoapBindConstants.RPC_STYLE.equals(style)) { soapBody.setNamespaceURI(generateRpcBodyNamespace(input, bindingDefinition)); soapBody.setParts(getRpcBodyPartNames(input.getMessage())); } else soapBody.setParts(getDocumentBodyPartNames(input.getMessage())); // binding input BindingInput bindInput = bindingDefinition.createBindingInput(); bindInput.addExtensibilityElement(soapBody); return bindInput; } protected String generateRpcBodyNamespace(Input input, Definition bindingDefinition) { return bindingDefinition.getTargetNamespace(); } private static List getRpcBodyPartNames(Message message) { ArrayList partNames = new ArrayList(); /* * BP 1.2 R2203: An rpc-literal binding MUST refer, in its soapbind:body element(s), only to * wsdl:part element(s) that have been defined using the type attribute */ Map parts = message.getParts(); for (Iterator i = parts.values().iterator(); i.hasNext();) { Part part = (Part) i.next(); if (part.getTypeName() != null) partNames.add(part.getName()); } /* * WSDL 1.1 section 3.5: If the parts attribute is omitted, then all parts defined by the * message are assumed to be included in the SOAP Body portion */ return partNames.size() == parts.size() ? null : partNames; } private static List getDocumentBodyPartNames(Message message) { /* * BP 1.2 R2210: If a document-literal binding does not specify the parts attribute on a * soapbind:body element, the corresponding abstract wsdl:message MUST define zero or one * wsdl:parts */ Map parts = message.getParts(); if (parts.size() <= 1) return null; /* * BP 1.2 R2204: A document-literal binding MUST refer, in each of its soapbind:body element(s), * only to wsdl:part element(s) that have been defined using the element attribute. * * BP 1.2 R2201: A document-literal binding MUST, in each of its soapbind:body element(s), have * at most one part listed in the parts attribute, if the parts attribute is specified * * Corollary: the first element part is to be listed in the parts attribute */ for (Iterator i = parts.values().iterator(); i.hasNext();) { Part part = (Part) i.next(); if (part.getElementName() != null) return Collections.singletonList(part.getName()); } return Collections.EMPTY_LIST; } protected BindingOutput generateBindingOutput(Output output, Definition bindingDefinition, String style) throws WSDLException { // soap body SOAPBody soapBody = (SOAPBody) bindingDefinition.getExtensionRegistry().createExtension(BindingOutput.class, SOAPConstants.Q_ELEM_SOAP_BODY); soapBody.setUse(SoapBindConstants.LITERAL_USE); if (SoapBindConstants.RPC_STYLE.equals(style)) { soapBody.setNamespaceURI(generateRpcBodyNamespace(output, bindingDefinition)); soapBody.setParts(getRpcBodyPartNames(output.getMessage())); } else soapBody.setParts(getDocumentBodyPartNames(output.getMessage())); // binding output BindingOutput bindOutput = bindingDefinition.createBindingOutput(); bindOutput.addExtensibilityElement(soapBody); return bindOutput; } protected String generateRpcBodyNamespace(Output output, Definition bindingDefinition) { return bindingDefinition.getTargetNamespace(); } protected BindingFault generateBindingFault(Fault fault, Definition bindingDefinition) throws WSDLException { String faultName = fault.getName(); // soap fault SOAPFault soapFault = (SOAPFault) bindingDefinition.getExtensionRegistry() .createExtension(BindingFault.class, SOAPConstants.Q_ELEM_SOAP_FAULT); soapFault.setName(faultName); soapFault.setUse(SoapBindConstants.LITERAL_USE); // binding fault BindingFault bindFault = bindingDefinition.createBindingFault(); bindFault.setName(faultName); bindFault.addExtensibilityElement(soapFault); return bindFault; } protected String generatePortName(PartnerLinkDefinition partnerLink, Service service) { String portName = partnerLink.getMyRole().getName() + "Port"; // check for a conflicting port name Map ports = service.getPorts(); if (ports.containsKey(portName)) portName = generateName(portName, ports.keySet()); return portName; } protected Port generatePort(Binding binding, Definition serviceDefinition) throws WSDLException { // port Port port = serviceDefinition.createPort(); port.setBinding(binding); // namespace declaration for binding name String bindingNamespace = binding.getQName().getNamespaceURI(); Map namespaces = serviceDefinition.getNamespaces(); if (!namespaces.containsValue(bindingNamespace)) { String prefix = generateName("bindingNS", namespaces.keySet()); serviceDefinition.addNamespace(prefix, bindingNamespace); } // soap address SOAPAddress soapAddress = (SOAPAddress) serviceDefinition.getExtensionRegistry().createExtension(Port.class, SOAPConstants.Q_ELEM_SOAP_ADDRESS); soapAddress.setLocationURI(ADDRESS_LOCATION_URI); port.addExtensibilityElement(soapAddress); return port; } private static String generateName(String base, Set existingNames) { StringBuffer nameBuffer = new StringBuffer(base); int baseLength = base.length(); for (int i = 2; i < Integer.MAX_VALUE; i++) { // append a natural number to the base text String altName = nameBuffer.append(i).toString(); // check there is no collision with existing names if (!existingNames.contains(altName)) return altName; // remove appended number nameBuffer.setLength(baseLength); } throw new Error("could not generate name from base: " + base); } protected PartnerLinkDescriptor generatePartnerLinkDescriptor(PartnerLinkDefinition partnerLink, Service service, Port port) { MyRoleDescriptor myRoleDescriptor = new MyRoleDescriptor(); myRoleDescriptor.setService(service.getQName()); myRoleDescriptor.setPort(port.getName()); PartnerLinkDescriptor partnerLinkDescriptor = new PartnerLinkDescriptor(); partnerLinkDescriptor.setName(partnerLink.getName()); partnerLinkDescriptor.setMyRole(myRoleDescriptor); return partnerLinkDescriptor; } protected ServiceCatalog generateServiceCatalog(DeploymentDescriptor deploymentDescriptor) { return CentralCatalog.getConfigurationInstance(); } public void deleteGeneratedFiles() { // recursively delete wsdl files deleteWsdlFile(new File(wsdlDirectory, serviceFileName)); // delete deployment descriptor if (FileUtil.clean(deploymentDescriptorFile)) log.info("deleted: " + deploymentDescriptorFile); } private static void deleteWsdlFile(File file) { Definition def; try { def = WsdlUtil.getFactory().newWSDLReader().readWSDL(file.getPath()); } catch (WSDLException e) { log.error("not a wsdl file: " + file, e); return; } // delete the current file first if (FileUtil.clean(file)) log.info("deleted: " + file); // deal with imported files for (Iterator l = def.getImports().values().iterator(); l.hasNext();) { List importList = (List) l.next(); for (Iterator i = importList.iterator(); i.hasNext();) { javax.wsdl.Import _import = (javax.wsdl.Import) i.next(); deleteSourceWsdlFile(_import.getDefinition()); } } } private static void deleteSourceWsdlFile(Definition def) { String baseLocation = def.getDocumentBaseURI(); try { URI baseUri = new URI(baseLocation); // easy way out: not a file if (!"file".equalsIgnoreCase(baseUri.getScheme())) return; // delete the base file first File file = new File(baseUri); if (FileUtil.clean(file)) log.info("deleted: " + file); // deal with imported files for (Iterator l = def.getImports().values().iterator(); l.hasNext();) { List importList = (List) l.next(); for (Iterator i = importList.iterator(); i.hasNext();) { javax.wsdl.Import _import = (javax.wsdl.Import) i.next(); deleteSourceWsdlFile(_import.getDefinition()); } } } catch (URISyntaxException e) { log.debug("document base is not a valid uri: " + baseLocation, e); } } class ServiceDefinitionBuilder extends AbstractBpelVisitor { private Definition serviceDefinition; private Service service; private DeploymentDescriptor deploymentDescriptor; private ScopeDescriptor topmostScopeDescriptor; private URI processLocationUri; private ImportDefinition importDefinition; private final Map interfaceFiles = new HashMap(); public void visit(BpelProcessDefinition processDefinition) { // enclosing definition serviceDefinition = generateServiceDefinition(processDefinition); // service service = serviceDefinition.createService(); QName serviceName = new QName(serviceDefinition.getTargetNamespace(), generateServiceLocalName(processDefinition, serviceDefinition)); service.setQName(serviceName); serviceDefinition.addService(service); // keep import module for later use importDefinition = processDefinition.getImportDefinition(); String processLocation = processDefinition.getLocation(); // strip filename off the location so that URI.relativize() works on import locations int slashIndex = processLocation.lastIndexOf('/'); if (slashIndex != -1) processLocation = processLocation.substring(0, slashIndex + 1); try { processLocationUri = new URI(processLocation); } catch (URISyntaxException e) { problemHandler.add( new Problem(Problem.LEVEL_WARNING, "process location is not a uri: " + processLocation, e)); processLocationUri = URI.create(""); } // app descriptor deploymentDescriptor = generateDeploymentDescriptor(processDefinition); topmostScopeDescriptor = deploymentDescriptor; // propagate visit propagate(processDefinition.getGlobalScope()); // service catalog ServiceCatalog serviceCatalog = generateServiceCatalog(deploymentDescriptor); deploymentDescriptor.setServiceCatalog(serviceCatalog); } public void visit(Scope scope) { ScopeDescriptor scopeDescriptor = new ScopeDescriptor(); scopeDescriptor.setName(scope.getName()); ScopeDescriptor parentScopeDescriptor = topmostScopeDescriptor; parentScopeDescriptor.addScope(scopeDescriptor); // push scope to stack topmostScopeDescriptor = scopeDescriptor; // propagate visit propagate(scope); // pop scope from stack topmostScopeDescriptor = parentScopeDescriptor; } private void propagate(Scope scope) { for (Iterator i = scope.getPartnerLinks().values().iterator(); i.hasNext();) { PartnerLinkDefinition partnerLink = (PartnerLinkDefinition) i.next(); try { visit(partnerLink); } catch (WSDLException e) { problemHandler.add( new Problem(Problem.LEVEL_ERROR, "could not generate port for: " + partnerLink, e)); } } // propagate visit scope.getActivity().accept(this); } Map getInterfaceFiles() { return interfaceFiles; } Definition getServiceDefinition() { return serviceDefinition; } DeploymentDescriptor getDeploymentDescriptor() { return deploymentDescriptor; } private void visit(PartnerLinkDefinition partnerLink) throws WSDLException { Role myRole = partnerLink.getMyRole(); // if the process has no role, there is nothing to generate if (myRole == null) return; PortType portType = myRole.getPortType(); // binding definition Definition bindingDefinition = getBindingDefinition(serviceDefinition, portType.getQName().getNamespaceURI()); if (bindingDefinition == null) { // binding definition does not exist yet, generate it bindingDefinition = generateBindingDefinition(partnerLink, serviceDefinition); // import binding definition from service definition Import bindingImport = generateBindingImport(serviceDefinition, bindingDefinition); serviceDefinition.addImport(bindingImport); } // check whether binding definition already imports interface definition Definition interfaceDefinition = importDefinition.getDeclaringDefinition(portType); String interfaceLocation = interfaceDefinition.getDocumentBaseURI(); try { interfaceLocation = processLocationUri.relativize(new URI(interfaceLocation)).toString(); } catch (URISyntaxException e) { problemHandler.add(new Problem(Problem.LEVEL_WARNING, "interface location is not a valid uri: " + interfaceLocation, e)); } if (getInterfaceImport(bindingDefinition, interfaceLocation) == null) { // import interface definition from binding definition Import interfaceImport = generateInterfaceImport(bindingDefinition, interfaceDefinition); interfaceImport.setLocationURI(interfaceLocation); bindingDefinition.addImport(interfaceImport); // write interface definition, if read from a relative location addInterfaceDefinition(interfaceImport, wsdlDirectory); } // binding QName bindingName = new QName(bindingDefinition.getTargetNamespace(), generateBindingLocalName(partnerLink, bindingDefinition)); Binding binding = bindingDefinition.getBinding(bindingName); if (binding == null) { binding = generateBinding(portType, bindingDefinition); binding.setQName(bindingName); bindingDefinition.addBinding(binding); } // port Port port = generatePort(binding, serviceDefinition); port.setName(generatePortName(partnerLink, service)); service.addPort(port); // partner link in app descriptor topmostScopeDescriptor.addPartnerLink(generatePartnerLinkDescriptor(partnerLink, service, port)); } private void addInterfaceDefinition(Import _import, File baseDirectory) throws WSDLException { String location = _import.getLocationURI(); try { // if location is absolute, there is no need to write a copy if (new URI(location).isAbsolute()) return; } catch (URISyntaxException e) { problemHandler.add( new Problem(Problem.LEVEL_WARNING, "import location is not a valid uri: " + location, e)); // fall through, try and write the file } // place the definition in a location relative to the base directory File importFile = new File(baseDirectory, location); // check the existing files to suppress duplicates if (!interfaceFiles.containsKey(importFile)) { Definition definition = _import.getDefinition(); interfaceFiles.put(importFile, definition); // add imported documents as well baseDirectory = importFile.getParentFile(); for (Iterator l = definition.getImports().values().iterator(); l.hasNext();) { List imports = (List) l.next(); for (int i = 0, n = imports.size(); i < n; i++) { Import recursiveImport = (Import) imports.get(i); addInterfaceDefinition(recursiveImport, baseDirectory); } } } } } }