protected static Definition configureWSDLDefinition()

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;
    }