in modules/binding-ws-wsdlgen/src/main/java/org/apache/tuscany/sca/binding/ws/wsdlgen/WSDLServiceGenerator.java [129:340]
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);
boolean generatedWsdl = false;
String contractName = contract.getName();
List<Port> ports = new ArrayList<Port>();
WSDLDefinition wsdlDefinition = wsBinding.getUserSpecifiedWSDLDefinition();
if (wsdlDefinition == null) {
error(monitor, "NoWsdlInterface", wsBinding, component.getName(), contract.getName());
return null;
}
Definition def = wsdlDefinition.getDefinition();
if (wsdlDefinition.getBinding() == null) {
// 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 {
generatedWsdl = true;
// 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(wsBinding);
WSDLInterface wi = (WSDLInterface)wsBinding.getBindingInterfaceContract().getInterface();
PortType portType = wi.getPortType();
// If using the WSDL definition that was generated by Interface2WSDLGenerator,
// add the component name to the WSDL service name. This is done so that the
// WSDL service name doesn't clash with other components that use the same contract.
// The runtime may have a need to keep the WSDL services separate, e.g. to support
// different policy attachments on each service. It isn't necessary to add the
// component name when using user-supplied WSDL because in that case the above code
// created a new WSDL document in a namespace that is qualified by the component name.
String wsdlServiceName = contract.getName();
if (generatedWsdl) {
wsdlServiceName = component.getURI().replace('/','_') + '_' + wsdlServiceName;
}
Service service = helper.createService(def, portType, wsdlServiceName);
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);
// set binding style based on the interface specified by the
// user if one is available
// TODO - set encoding style also currently default to literal
if (wsdlDefinition != null && wsdlDefinition.getDefinition() != null){
Message firstMessage = (Message)wsdlDefinition.getDefinition().getMessages().values().iterator().next();
Part firstPart = (Part)firstMessage.getParts().values().iterator().next();
if (firstPart.getTypeName() != null){
for (Object ext : binding.getExtensibilityElements()){
if (ext instanceof SOAPBinding){
((SOAPBinding)ext).setStyle("rpc");
break;
}
}
}
}
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);
}
// 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;
}