public Definition generate()

in modules/binding-ws-wsdlgen/src/main/java/org/apache/tuscany/sca/binding/ws/wsdlgen/Interface2WSDLGenerator.java [328:557]


    public Definition generate(Interface interfaze, WSDLDefinition wsdlDefinition) throws WSDLException {
        if (interfaze == null) {
            return null;
        }
        if (interfaze instanceof WSDLInterface) {
            return ((WSDLInterface)interfaze).getWsdlDefinition().getDefinition();
        }
        JavaInterface iface = (JavaInterface)interfaze;
        if (!interfaze.isRemotable()) {
            fatal("InterfaceNotRemotable", interfaze, iface.getName());
        }
        QName name = getQName(iface);
        Definition definition = factory.newDefinition();
        if (requiresSOAP12) {
            definition.addNamespace("SOAP12", "http://schemas.xmlsoap.org/wsdl/soap12/");
        } else {
            definition.addNamespace("SOAP", "http://schemas.xmlsoap.org/wsdl/soap/");
        }
        definition.addNamespace("wsdl", "http://schemas.xmlsoap.org/wsdl/");
        definition.addNamespace("xs", SCHEMA_NS);

        String namespaceURI = name.getNamespaceURI();
        definition.setTargetNamespace(namespaceURI);
        definition.setQName(new QName(namespaceURI, name.getLocalPart() + "Service", name.getPrefix()));
        definition.addNamespace(name.getPrefix(), namespaceURI);

        PortType portType = definition.createPortType();
        portType.setQName(name);
        Binding binding = definitionGenerator.createBinding(definition, portType);
        Map<String, XMLTypeHelper> helpers = new HashMap<String, XMLTypeHelper>();
        Map<QName, List<ElementInfo>> wrappers = new HashMap<QName, List<ElementInfo>>();
        for (Operation op : interfaze.getOperations()) {
            javax.wsdl.Operation operation = generateOperation(definition, op, helpers, wrappers);
            portType.addOperation(operation);
            String action = ((JavaOperation)op).getAction();
            // Removed improper defaulting of SOAP action when using doc/lit BARE.
            // The correct default is "" (empty string).
            if (action == null) {
                action = "";
            }
            BindingOperation bindingOp = definitionGenerator.createBindingOperation(definition, operation, action);
            binding.addBindingOperation(bindingOp);
        }
        portType.setUndefined(false);
        definition.addPortType(portType);
        binding.setUndefined(false);
        definition.addBinding(binding);
        wsdlDefinition.setBinding(binding);

        // call each helper in turn to populate the wsdl.types element
        XmlSchemaCollection schemaCollection = new XmlSchemaCollection();

        // TUSCANY-3283 - "true" here means also generate the wrapper types using JAXB
        Map<XMLTypeHelper, List<DataType>> dataTypes = getDataTypes(interfaze, true, helpers);
        for (Map.Entry<XMLTypeHelper, List<DataType>> en: dataTypes.entrySet()) {
            XMLTypeHelper helper = en.getKey();
            if (helper == null) {
                continue;
            }
            List<XSDefinition> xsDefinitions = helper.getSchemaDefinitions(xsdFactory, resolver, en.getValue());
            
            // TUSCANY-3283 - move the nonamespace types into the namespace of the interface
            //                as per JAXWS
            mergeNoNamespaceSchema(namespaceURI, xsDefinitions);
            
            for (XSDefinition xsDef: xsDefinitions) {
                //addSchemaExtension(xsDef, schemaCollection, wsdlDefinition, definition);
                loadXSD(schemaCollection, xsDef);
                wsdlDefinition.getXmlSchemas().add(xsDef);
            }
        }
        
        // remove global wrapper elements with schema definitions from generation list
        for (QName wrapperName: new HashSet<QName>(wrappers.keySet())) {
            if (wsdlDefinition.getXmlSchemaElement(wrapperName) != null) {
                wrappers.remove(wrapperName);
            }
        }
        
        // below we might generate wrapper schema into a DOM. If the schema are in a namespace
        // that is already been loaded then we need to throw away the schema collection and reload
        // it because you can't load a DOM into a schema collection if the schema for the namespace
        // has already been loaded
        boolean reloadSchema = false;

        // generate schema elements for wrappers that aren't defined in the schemas
        // TUSCANY-3283 - as we're generating wrappers with JAXB it won't 
        //                go through here for all wrappers. It will just have to do the ones
        //                where there is no JAXB mapping for the child types, e.g. SDO DataObject
        if (wrappers.size() > 0) {
            int i = 0;
            int index = 0;
            Map<String, XSDefinition> wrapperXSDs = new HashMap<String, XSDefinition>();
            Map<Element, Map<String, String>> prefixMaps = new HashMap<Element, Map<String, String>>();
            for (Map.Entry<QName, List<ElementInfo>> entry: wrappers.entrySet()) {
                String targetNS = entry.getKey().getNamespaceURI();
                Document schemaDoc = null;
                Element schema = null;
                XSDefinition xsDef = wrapperXSDs.get(targetNS);
                if (xsDef != null) {
                    schemaDoc = xsDef.getDocument();
                    schema = schemaDoc.getDocumentElement();
                } else {
                    // TUSCANY-3283 - if we have to generate a new schema check to see if the 
                    //                WSDL doc already has a schema in this namespace                       
                    xsDef = wsdlDefinition.getSchema(targetNS);
                    if (xsDef != null) {
                        schemaDoc = xsDef.getDocument();
                        schema = schemaDoc.getDocumentElement();
                        //wrapperXSDs.put(targetNS, xsDef);
                        Map<String, String> prefixMap = prefixMaps.get(schema);
                        if (prefixMap == null){
                            prefixMap = new HashMap<String, String>();
                            prefixMaps.put(schema, prefixMap);
                            String [] prefixes = xsDef.getSchema().getNamespaceContext().getDeclaredPrefixes();
                            for (int j = 0; j < prefixes.length; j++){
                                prefixMap.put(xsDef.getSchema().getNamespaceContext().getNamespaceURI(prefixes[j]),
                                             prefixes[j]);
                            }
                        } 
                        reloadSchema = true;
                    } else {                    
                        schemaDoc = createDocument();
                        schema = schemaDoc.createElementNS(SCHEMA_NS, "xs:schema");
                        // The elementFormDefault should be set to unqualified, see TUSCANY-2388
                        schema.setAttribute("elementFormDefault", "unqualified");
                        schema.setAttribute("attributeFormDefault", "qualified");
                        schema.setAttribute("targetNamespace", targetNS);
                        schema.setAttributeNS(XMLNS_NS, "xmlns:xs", SCHEMA_NS);
                        schemaDoc.appendChild(schema);
                        // TUSCANY-3283 - the extension is created at the bottom
                        //Schema schemaExt = createSchemaExt(definition);
                        //schemaExt.setElement(schema);
                        prefixMaps.put(schema, new HashMap<String, String>());
                        xsDef = xsdFactory.createXSDefinition();
                        xsDef.setUnresolved(true);
                        xsDef.setNamespace(targetNS);
                        xsDef.setDocument(schemaDoc);
                        // TUSCANY-2465: Set the system id to avoid schema conflict
                        xsDef.setLocation(URI.create("xsd_" + index + ".xsd"));
                        index++;
                        wrapperXSDs.put(targetNS, xsDef);
                        wsdlDefinition.getXmlSchemas().add(xsDef);
                    }
                }
                Element wrapper = schemaDoc.createElementNS(SCHEMA_NS, "xs:element");
                schema.appendChild(wrapper);
                wrapper.setAttribute("name", entry.getKey().getLocalPart());
                if (entry.getValue().size() == 1 && entry.getValue().get(0).getQName() == null) {
                    // special case for global fault element
                    QName typeName = entry.getValue().get(0).getType().getQName();
                    String nsURI = typeName.getNamespaceURI();
                    if ("".equals(nsURI)) {
                        wrapper.setAttribute("type", typeName.getLocalPart());
                        addSchemaImport(schema, "", schemaDoc);
                    } else if (targetNS.equals(nsURI)) {
                        wrapper.setAttribute("type", typeName.getLocalPart());
                    } else if (SCHEMA_NS.equals(nsURI)) {
                        wrapper.setAttribute("type", "xs:" + typeName.getLocalPart());
                    } else {
                        Map<String, String> prefixMap = prefixMaps.get(schema);
                        String prefix = prefixMap.get(nsURI);
                        if (prefix == null) {
                            prefix = "ns" + i++;
                            prefixMap.put(nsURI, prefix);
                            schema.setAttributeNS(XMLNS_NS, "xmlns:" + prefix, nsURI);
                            addSchemaImport(schema, nsURI, schemaDoc);
                        }
                        wrapper.setAttribute("type", prefix + ":" + typeName.getLocalPart());
                    }                    
                } else {
                    // normal wrapper containing type definition inline
                    Element complexType = schemaDoc.createElementNS(SCHEMA_NS, "xs:complexType");
                    wrapper.appendChild(complexType);
                    if (entry.getValue().size() > 0) {
                        Element sequence = schemaDoc.createElementNS(SCHEMA_NS, "xs:sequence");
                        complexType.appendChild(sequence);
                        for (ElementInfo element: entry.getValue()) {
                            Element xsElement = schemaDoc.createElementNS(SCHEMA_NS, "xs:element"); 
                            if (element.isMany()) {
                                xsElement.setAttribute("maxOccurs", "unbounded");
                            }
                            xsElement.setAttribute("minOccurs", "0");
                            xsElement.setAttribute("name", element.getQName().getLocalPart());
                            if (element.isNillable()) {
                                xsElement.setAttribute("nillable", "true");
                            }
                            QName typeName = element.getType().getQName();
                            String nsURI = typeName.getNamespaceURI();
                            if ("".equals(nsURI)) {
                                xsElement.setAttribute("type", typeName.getLocalPart());
                                addSchemaImport(schema, "", schemaDoc);
                            } else if (SCHEMA_NS.equals(nsURI)) {
                                xsElement.setAttribute("type", "xs:" + typeName.getLocalPart());
                            } else {
                                Map<String, String> prefixMap = prefixMaps.get(schema);
                                String prefix = prefixMap.get(nsURI);
                                if (prefix == null) {
                                    if (targetNS.equals(nsURI)) {
									    prefix = "tns";
									} else {
                                        prefix = "ns" + i++;
                                        addSchemaImport(schema, nsURI, schemaDoc);
									}
                                    prefixMap.put(nsURI, prefix);
                                    schema.setAttributeNS(XMLNS_NS, "xmlns:" + prefix, nsURI);
                                }
                                xsElement.setAttribute("type", prefix + ":" + typeName.getLocalPart());
                            }
                            sequence.appendChild(xsElement);
                        }
                    }
                }
            }
        }
        
        if (reloadSchema){
            schemaCollection = new XmlSchemaCollection();
            for (XSDefinition xsDef: wsdlDefinition.getXmlSchemas()){
                xsDef.setSchema(null);
                xsDef.setSchemaCollection(null);
            }
        }
        
        for (XSDefinition xsDef: wsdlDefinition.getXmlSchemas()){
            addSchemaExtension(xsDef, schemaCollection, wsdlDefinition, definition);
        }

        return definition;
    }