in modules/binding-ws-wsdlgen/src/main/java/org/apache/tuscany/sca/binding/ws/wsdlgen/WSDLServiceGenerator.java [129:343]
protected static Definition configureWSDLDefinition(WebServiceBinding wsBinding,
Component component,
AbstractContract contract,
Monitor monitor) {
//[nash] changes to the builder sequence avoid calling this for a CompositeService
assert !(contract instanceof CompositeService);
/*
// For every promoted composite service, the underlying component
// gets a copy of the service with the name prefixed by "$promoted$."
String contractName = (contract instanceof CompositeService ? "$promoted$." : "") + contract.getName();
*/
String contractName = contract.getName();
List<Port> ports = new ArrayList<Port>();
WSDLDefinition wsdlDefinition = wsBinding.getWSDLDefinition();
if (wsdlDefinition == null) {
error(monitor, "NoWsdlInterface", wsBinding, component.getName(), contract.getName());
return null;
}
Definition def = wsdlDefinition.getDefinition();
boolean wsdlProvidedByUser = (wsdlDefinition.getBinding() == null);
if (wsdlProvidedByUser) {
// The WSDL document was provided by the user. Generate a new
// WSDL document with imports from the user-provided document.
WSDLFactory factory = null;
try {
factory = WSDLFactory.newInstance();
} catch (WSDLException e) {
throw new WSDLGenerationException(e);
}
Definition newDef = factory.newDefinition();
// Construct a target namespace from the base URI of the user's
// WSDL document (is this what we should be using?) and a path
// computed according to the SCA Web Service binding spec.
String nsName = component.getName() + "/" + contractName;
String namespaceURI = null;
try {
URI userTNS = new URI(def.getTargetNamespace());
namespaceURI = userTNS.resolve("/" + nsName).toString();
} catch (URISyntaxException e1) {
throw new WSDLGenerationException(e1);
} catch (IllegalArgumentException e2) {
throw new WSDLGenerationException(e2);
}
// set name and targetNamespace attributes on the definition
String defsName = component.getName() + "." + contractName;
newDef.setQName(new QName(namespaceURI, defsName));
newDef.setTargetNamespace(namespaceURI);
newDef.addNamespace("tns", namespaceURI);
// set wsdl namespace prefix on the definition
newDef.addNamespace("wsdl", "http://schemas.xmlsoap.org/wsdl/");
// import the service or reference interface portType
List<WSDLDefinition> imports = new ArrayList<WSDLDefinition>();
Interface interfaze = wsBinding.getBindingInterfaceContract().getInterface();
if (interfaze instanceof WSDLInterface) {
PortType portType = ((WSDLInterface)interfaze).getPortType();
boolean ok = importPortType(portType, wsdlDefinition, newDef, imports);
if (!ok) {
error(monitor, "PortTypeNotFound", wsBinding, portType.getQName().toString(),
component.getName(), contract.getName());
}
}
// import an existing binding if specified
Binding binding = wsBinding.getBinding();
if (binding != null) {
boolean ok = importBinding(binding, wsdlDefinition, newDef, imports);
if (ok) {
boolean ok2 = importPortType(binding.getPortType(), wsdlDefinition, newDef, imports);
if (!ok2) {
error(monitor, "PortTypeNotFound", wsBinding, binding.getPortType().getQName().toString(),
component.getName(), contract.getName());
}
} else {
error(monitor, "BindingNotFound", wsBinding, binding.getQName().toString(),
component.getName(), contract.getName());
}
}
// import bindings and portTypes needed by services and ports
QName serviceQName = wsBinding.getServiceName();
String portName = wsBinding.getPortName();
if (serviceQName != null) {
Service service = def.getService(serviceQName);
if (portName != null) {
Port port = service.getPort(portName);
Port newPort = copyPort(newDef, port, wsBinding);
if (newPort != null) {
importBinding(port.getBinding(), wsdlDefinition, newDef, imports);
ports.add(newPort);
} else {
error(monitor, "InvalidPort", wsBinding, serviceQName.toString(), portName,
component.getName(), contract.getName());
}
} else {
for (Object port : service.getPorts().values()) {
Port newPort = copyPort(newDef, (Port)port, wsBinding);
if (newPort != null) {
importBinding(((Port)port).getBinding(), wsdlDefinition, newDef, imports);
ports.add(newPort);
} else {
// not an error, just ignore the port
warning(monitor, "IgnoringPort", wsBinding, serviceQName.toString(), ((Port)port).getName(),
component.getName(), contract.getName());
}
}
if (ports.size() == 0) {
error(monitor, "NoValidPorts", wsBinding, serviceQName.toString(),
component.getName(), contract.getName());
}
}
}
// replace original WSDL definition by the generated definition
def = newDef;
} else {
// The WSDL definition was generated by Interface2WSDLGenerator.
// Reuse it instead of creating a new definition here.
}
// add a service and ports to the generated definition
WSDLDefinitionGenerator helper =
new WSDLDefinitionGenerator(BindingWSDLGenerator.requiresSOAP12(wsBinding),false);
WSDLInterface wi = (WSDLInterface)wsBinding.getBindingInterfaceContract().getInterface();
PortType portType = wi.getPortType();
Service service = helper.createService(def, portType);
if (wsBinding.getBinding() == null && ports.size() == 0) {
Binding binding = helper.createBinding(def, portType);
if (BindingWSDLGenerator.requiresSOAP12(wsBinding)) {
def.addNamespace("SOAP12", "http://schemas.xmlsoap.org/wsdl/soap12/");
} else {
def.addNamespace("SOAP11", "http://schemas.xmlsoap.org/wsdl/soap/");
}
helper.createBindingOperations(def, binding, portType);
binding.setUndefined(false);
def.addBinding(binding);
String endpointURI = computeActualURI(wsBinding, null);
Port port = helper.createPort(def, binding, service, endpointURI);
wsBinding.setService(service);
wsBinding.setPort(port);
} else {
if (ports.size() > 0) {
// there are one or more user-specified valid ports
for (Port port : ports) {
service.addPort(port);
}
if (ports.size() == 1) {
// only one port, so use it
wsBinding.setPort(ports.get(0));
} else {
// multiple ports, make them all available
wsBinding.setPort(null);
}
} else {
// no valid user-specified ports, so create a suitably configured port
String endpointURI = computeActualURI(wsBinding, null);
Port port = helper.createPort(def, wsBinding.getBinding(), service, endpointURI);
if (BindingWSDLGenerator.requiresSOAP12(wsBinding)) {
def.addNamespace("SOAP12", "http://schemas.xmlsoap.org/wsdl/soap12/");
} else {
def.addNamespace("SOAP11", "http://schemas.xmlsoap.org/wsdl/soap/");
}
wsBinding.setPort(port);
}
wsBinding.setService(service);
}
// TUSCANY-2900 - add jms binding and service port if required
// TODO - remove service/ports from any imported WSDL
// - find away to allow users to retrieve WSDL with JMS bindings
// as a jms binding on it's own provides not target for ?wsdl
if ((!wsdlProvidedByUser) &&
(wsBinding.getURI() != null) &&
(wsBinding.getURI().startsWith("jms"))){
// need to work out how to check if user has already specified a binding
// create jms binding
helper = new WSDLDefinitionGenerator(BindingWSDLGenerator.requiresSOAP12(wsBinding),true);
Binding binding = helper.createBinding(def, portType);
helper.createBindingOperations(def, binding, portType);
binding.setUndefined(false);
def.addBinding(binding);
// create a jms port
String endpointURI = computeActualURI(wsBinding, null);
Port port = helper.createPort(def, binding, service, endpointURI);
wsBinding.setService(service);
wsBinding.setPort(port);
//printWSDL = true;
}
// for debugging
if (printWSDL) {
try {
System.out.println("Generated WSDL for " + component.getName() + "/" + contractName);
WSDLWriter writer = javax.wsdl.factory.WSDLFactory.newInstance().newWSDLWriter();
writer.writeWSDL(def, System.out);
} catch (WSDLException e) {
throw new WSDLGenerationException(e);
}
}
return def;
}