You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@tuscany.apache.org by an...@apache.org on 2008/09/08 18:39:49 UTC

svn commit: r693154 [2/3] - in /tuscany/java/sca: modules/binding-ws-axis2/src/main/java/org/apache/tuscany/sca/binding/ws/axis2/ modules/binding-ws-axis2/src/main/resources/org/apache/tuscany/sca/binding/ws/axis2/ modules/binding-ws-axis2/src/test/jav...

Modified: tuscany/java/sca/modules/binding-ws-wsdlgen/src/main/java/org/apache/tuscany/sca/binding/ws/wsdlgen/Interface2WSDLGenerator.java
URL: http://svn.apache.org/viewvc/tuscany/java/sca/modules/binding-ws-wsdlgen/src/main/java/org/apache/tuscany/sca/binding/ws/wsdlgen/Interface2WSDLGenerator.java?rev=693154&r1=693153&r2=693154&view=diff
==============================================================================
--- tuscany/java/sca/modules/binding-ws-wsdlgen/src/main/java/org/apache/tuscany/sca/binding/ws/wsdlgen/Interface2WSDLGenerator.java (original)
+++ tuscany/java/sca/modules/binding-ws-wsdlgen/src/main/java/org/apache/tuscany/sca/binding/ws/wsdlgen/Interface2WSDLGenerator.java Mon Sep  8 09:39:47 2008
@@ -1,840 +1,840 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- * 
- *   http://www.apache.org/licenses/LICENSE-2.0
- * 
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.    
- */
-
-package org.apache.tuscany.sca.binding.ws.wsdlgen;
-
-import java.lang.reflect.Method;
-import java.net.URI;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Map;
-import java.util.logging.Level;
-import java.util.logging.Logger;
-
-import javax.wsdl.Binding;
-import javax.wsdl.BindingOperation;
-import javax.wsdl.Definition;
-import javax.wsdl.Fault;
-import javax.wsdl.Input;
-import javax.wsdl.Message;
-import javax.wsdl.OperationType;
-import javax.wsdl.Output;
-import javax.wsdl.Part;
-import javax.wsdl.PortType;
-import javax.wsdl.Types;
-import javax.wsdl.WSDLException;
-import javax.wsdl.extensions.schema.Schema;
-import javax.wsdl.factory.WSDLFactory;
-import javax.xml.namespace.QName;
-import javax.xml.parsers.DocumentBuilderFactory;
-import javax.xml.parsers.ParserConfigurationException;
-
-import org.apache.tuscany.sca.assembly.builder.impl.ProblemImpl;
-import org.apache.tuscany.sca.contribution.resolver.ModelResolver;
-import org.apache.tuscany.sca.databinding.DataBinding;
-import org.apache.tuscany.sca.databinding.DataBindingExtensionPoint;
-import org.apache.tuscany.sca.databinding.XMLTypeHelper;
-import org.apache.tuscany.sca.databinding.jaxb.JAXBDataBinding;
-import org.apache.tuscany.sca.interfacedef.DataType;
-import org.apache.tuscany.sca.interfacedef.Interface;
-import org.apache.tuscany.sca.interfacedef.Operation;
-import org.apache.tuscany.sca.interfacedef.java.JavaInterface;
-import org.apache.tuscany.sca.interfacedef.java.JavaOperation;
-import org.apache.tuscany.sca.interfacedef.util.ElementInfo;
-import org.apache.tuscany.sca.interfacedef.util.JavaXMLMapper;
-import org.apache.tuscany.sca.interfacedef.util.TypeInfo;
-import org.apache.tuscany.sca.interfacedef.util.WrapperInfo;
-import org.apache.tuscany.sca.interfacedef.util.XMLType;
-import org.apache.tuscany.sca.interfacedef.wsdl.WSDLDefinition;
-import org.apache.tuscany.sca.interfacedef.wsdl.WSDLInterface;
-import org.apache.tuscany.sca.monitor.Monitor;
-import org.apache.tuscany.sca.monitor.Problem;
-import org.apache.tuscany.sca.monitor.Problem.Severity;
-import org.apache.tuscany.sca.xsd.XSDFactory;
-import org.apache.tuscany.sca.xsd.XSDefinition;
-import org.apache.ws.commons.schema.XmlSchema;
-import org.apache.ws.commons.schema.XmlSchemaCollection;
-import org.apache.ws.commons.schema.XmlSchemaException;
-import org.apache.ws.commons.schema.utils.NamespaceMap;
-import org.w3c.dom.Document;
-import org.w3c.dom.Element;
-import org.w3c.dom.Node;
-import org.w3c.dom.NodeList;
-
-/**
- * @version $Rev: 670103 $ $Date: 2008-06-21 01:35:00 +0100 (Sat, 21 Jun 2008) $
- */
-public class Interface2WSDLGenerator {
-    private static final Logger logger = Logger.getLogger(Interface2WSDLGenerator.class.getName());
-    private static final String SCHEMA_NS = "http://www.w3.org/2001/XMLSchema";
-    private static final String SCHEMA_NAME = "schema";
-    private static final QName SCHEMA_QNAME = new QName(SCHEMA_NS, SCHEMA_NAME);
-    private static final String XMLNS_NS = "http://www.w3.org/2000/xmlns/";
-    
-    private static final String ANYTYPE_NAME = "anyType";
-    private static final QName ANYTYPE_QNAME = new QName(SCHEMA_NS, ANYTYPE_NAME);
-
-
-    private WSDLFactory factory;
-    private DataBindingExtensionPoint dataBindings;
-    private WSDLDefinitionGenerator definitionGenerator;
-    private boolean requiresSOAP12;
-    private ModelResolver resolver;
-    private XSDFactory xsdFactory;
-    private Monitor monitor;
-
-    public Interface2WSDLGenerator(boolean requiresSOAP12,
-                                   ModelResolver resolver,
-                                   DataBindingExtensionPoint dataBindings,
-                                   XSDFactory xsdFactory,
-                                   Monitor monitor) throws WSDLException {
-        super();
-        this.requiresSOAP12 = requiresSOAP12; 
-        this.resolver = resolver; 
-        definitionGenerator = new WSDLDefinitionGenerator(requiresSOAP12);
-        this.dataBindings = dataBindings;
-        this.xsdFactory = xsdFactory;
-        this.monitor = monitor;
-        this.factory = WSDLFactory.newInstance();
-    }
-
-    /**
-     * Log a warning message.
-     * @param problem
-     */
-    private static void logWarning(Problem problem) {
-        Logger problemLogger = Logger.getLogger(problem.getSourceClassName(), problem.getBundleName());
-        if (problemLogger != null){
-            problemLogger.logp(Level.WARNING, problem.getSourceClassName(), null, problem.getMessageId(), problem.getMessageParams());
-        } else {
-            logger.severe("Can't get logger " + problem.getSourceClassName()+ " with bundle " + problem.getBundleName());
-        }
-    }
-
-    /**
-     * Report a warning.
-     * @param message
-     * @param binding
-     * @param parameters
-     */
-    private void warning(String message, Interface interfaze, String... messageParameters) {
-        Problem problem = new ProblemImpl(this.getClass().getName(), "wsdlgen-validation-messages", Severity.WARNING, interfaze, message, (Object[])messageParameters);
-        if (monitor != null) {
-            monitor.problem(problem);
-        } else {
-            logWarning(problem);
-        }
-    }
-
-    /**
-     * Report a fatal error.
-     * @param message
-     * @param binding
-     * @param parameters
-     */
-    private void fatal(String message, Interface interfaze, String... messageParameters) {
-        Problem problem = new ProblemImpl(this.getClass().getName(), "wsdlgen-validation-messages", Severity.ERROR, interfaze, message, (Object[])messageParameters);
-        throw new WSDLGenerationException(problem.toString(), null, problem);
-    }
-    
-    private XMLTypeHelper getTypeHelper(DataType type, Map<String, XMLTypeHelper> helpers) {
-        if (type == null) {
-            return null;
-        }
-        String db = type.getDataBinding();
-        if (db == null) {
-            return null;
-        }
-        if ("java:array".equals(db)) {
-            DataType dt = (DataType)type.getLogical();
-            db = dt.getDataBinding();
-        }
-        return helpers.get(db);
-    }
-    
-    private boolean inputTypesCompatible(DataType wrapperType, DataType<List<DataType>> inputType, Map<String, XMLTypeHelper> helpers) {
-        XMLTypeHelper wrapperHelper = getTypeHelper(wrapperType, helpers);
-        for (DataType dt : inputType.getLogical()) {
-            if (getTypeHelper(dt, helpers) != wrapperHelper) {
-                return false;
-            }
-        }
-        return true;
-    }
-    
-    private boolean outputTypeCompatible(DataType wrapperType, DataType outputType, Map<String, XMLTypeHelper> helpers) {
-        if (getTypeHelper(outputType, helpers) != getTypeHelper(wrapperType, helpers)) {
-            return false;
-        } else {
-            return true;
-        }
-    }
-    
-    private void addDataType(Map<XMLTypeHelper, List<DataType>> map, DataType type, Map<String, XMLTypeHelper> helpers) {
-        if (type == null) {
-            return;
-        }
-        String db = type.getDataBinding();
-        if (db == null) {
-            return;
-        }
-        if ("java:array".equals(db)) {
-            DataType dt = (DataType)type.getLogical();
-            db = dt.getDataBinding();
-        }
-        XMLTypeHelper helper = helpers.get(db);
-        List<DataType> types = map.get(helper);
-        if (types == null) {
-            types = new ArrayList<DataType>();
-            map.put(helper, types);
-        }
-        types.add(type);
-    }
-    
-    private Map<XMLTypeHelper, List<DataType>> getDataTypes(Interface intf, boolean useWrapper, Map<String, XMLTypeHelper> helpers) {
-        Map<XMLTypeHelper, List<DataType>> dataTypes = new HashMap<XMLTypeHelper, List<DataType>>();
-        for (Operation op : intf.getOperations()) {
-            WrapperInfo wrapper = op.getWrapper();
-            DataType dt1 = null;
-            boolean useInputWrapper = useWrapper & wrapper != null;
-            if (useInputWrapper) {
-                dt1 = wrapper.getInputWrapperType();
-                useInputWrapper &= inputTypesCompatible(dt1, op.getInputType(), helpers);
-            }
-            if (useInputWrapper) {
-                addDataType(dataTypes, dt1, helpers);
-            } else {
-                for (DataType dt : op.getInputType().getLogical()) {
-                    addDataType(dataTypes, dt, helpers);
-                }
-            }
-            
-            DataType dt2 = null;
-            boolean useOutputWrapper = useWrapper & wrapper != null;
-            if (useOutputWrapper) {
-                dt2 = wrapper.getOutputWrapperType();
-                useOutputWrapper &= outputTypeCompatible(dt2, op.getOutputType(), helpers);
-            }
-            if (useOutputWrapper) {
-                addDataType(dataTypes, dt2, helpers);
-            } else {
-                dt2 = op.getOutputType();
-                addDataType(dataTypes, dt2, helpers);
-            }
-            
-            for (DataType<DataType> dt3 : op.getFaultTypes()) {
-                DataType dt4 = dt3.getLogical();
-                addDataType(dataTypes, dt4, helpers);
-            }
-        }
-        return dataTypes;
-    }
-
-
-    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();
-            if ((action == null || "".equals(action)) && !op.isWrapperStyle() && op.getWrapper() == null) {
-                // Bare style
-                action = "urn:" + op.getName();
-            }
-            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(); 
-
-        for (Map.Entry<XMLTypeHelper, List<DataType>> en: getDataTypes(interfaze, false, helpers).entrySet()) {
-            XMLTypeHelper helper = en.getKey();
-            if (helper == null) {
-                continue;
-            }
-            List<XSDefinition> xsDefinitions = helper.getSchemaDefinitions(xsdFactory, resolver, en.getValue());
-            for (XSDefinition xsDef: xsDefinitions) {
-                addSchemaExtension(xsDef, schemaCollection, wsdlDefinition, definition);
-            }
-        }
-
-        // 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);
-            }
-        }
-
-        // generate schema elements for wrappers that aren't defined in the schemas
-        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 {
-                    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);
-                    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);
-                }
-                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 (targetNS.equals(nsURI)) {
-                                xsElement.setAttribute("type", typeName.getLocalPart());
-                            } 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) {
-                                    prefix = "ns" + i++;
-                                    prefixMap.put(nsURI, prefix);
-                                    schema.setAttributeNS(XMLNS_NS, "xmlns:" + prefix, nsURI);
-                                    addSchemaImport(schema, nsURI, schemaDoc);
-                                }
-                                xsElement.setAttribute("type", prefix + ":" + typeName.getLocalPart());
-                            }
-                            sequence.appendChild(xsElement);
-                        }
-                    }
-                }
-            }
- 
-            // resolve XSDefinitions containing generated wrappers
-            for (XSDefinition xsDef: wrapperXSDs.values()) {
-                loadXSD(schemaCollection, xsDef);
-                wsdlDefinition.getXmlSchemas().add(xsDef);
-            }
-        }
-
-        return definition;
-    }
-
-    private static void addSchemaImport(Element schema, String nsURI, Document schemaDoc) {
-        Element imp = schemaDoc.createElementNS(SCHEMA_NS, "xs:import");
-        if (!"".equals(nsURI)) {
-            imp.setAttribute("namespace", nsURI);
-        }
-        NodeList childNodes = schema.getChildNodes();
-        for (int i = 0; i < childNodes.getLength(); i++) {
-            Node childNode = childNodes.item(i);
-            if (childNode instanceof Element) {
-                schema.insertBefore(imp, childNode);
-                imp = null;
-                break;
-            }
-        }
-        if (imp != null) {
-            schema.appendChild(imp);
-        }
-    }
-
-    private void addSchemaExtension(XSDefinition xsDef,
-                                    XmlSchemaCollection schemaCollection,
-                                    WSDLDefinition wsdlDefinition,
-                                    Definition definition) throws WSDLException {
-        if (xsDef.getAggregatedDefinitions() != null) {
-            for (XSDefinition xsd: xsDef.getAggregatedDefinitions()) {
-                addSchemaExtension(xsd, schemaCollection, wsdlDefinition, definition);
-            }
-        } else {
-            String nsURI = xsDef.getNamespace();
-            Document document = xsDef.getDocument();
-            if (document == null) {
-                try {
-                    NamespaceMap prefixMap = new NamespaceMap();
-                    prefixMap.add("xs", SCHEMA_NS);
-                    prefixMap.add("tns", nsURI);
-                    XmlSchema schemaDef = xsDef.getSchema();
-                    schemaDef.setNamespaceContext(prefixMap);
-                    Document[] docs = schemaDef.getAllSchemas();
-                    document = docs[docs.length-1];
-                    document.setDocumentURI(xsDef.getLocation().toString());
-                    xsDef.setDocument(document);
-                } catch (XmlSchemaException e) {
-                    throw new RuntimeException(e);
-                }
-            }
-            loadXSD(schemaCollection, xsDef);
-            wsdlDefinition.getXmlSchemas().add(xsDef);
-            Element schema = document.getDocumentElement();
-            Schema schemaExt = createSchemaExt(definition);
-            schemaExt.setDocumentBaseURI(document.getDocumentURI());
-            schemaExt.setElement(schema);
-        }
-    }
-
-    private static void loadXSD(XmlSchemaCollection schemaCollection, XSDefinition definition) {
-        if (definition.getSchema() != null) {
-            return;
-        }
-        if (definition.getDocument() != null) {
-            String uri = null;
-            if (definition.getLocation() != null) {
-                uri = definition.getLocation().toString();
-            }
-            XmlSchema schema = schemaCollection.read(definition.getDocument(), uri, null);
-            if (definition.getSchemaCollection() == null) {
-                definition.setSchemaCollection(schemaCollection);
-            }
-            if (definition.getSchema() == null) {
-                definition.setSchema(schema);
-            }
-        }
-    }
-
-    public Schema createSchemaExt(Definition definition) throws WSDLException {
-        Types types = definition.getTypes();
-        if (types == null) {
-            types = definition.createTypes();
-            definition.setTypes(types);
-        }
-
-        Schema schemaExt = createSchema(definition);
-        types.addExtensibilityElement(schemaExt);
-
-        return schemaExt;
-    }
-
-    public Schema createSchema(Definition definition) throws WSDLException {
-        return (Schema)definition.getExtensionRegistry().createExtension(Types.class, SCHEMA_QNAME);
-    }
-
-    private DocumentBuilderFactory documentBuilderFactory;
-
-    public Document createDocument() {
-        Document document;
-        try {
-            if (documentBuilderFactory == null) {
-                documentBuilderFactory = DocumentBuilderFactory.newInstance();
-                documentBuilderFactory.setNamespaceAware(true);
-            }
-            document = documentBuilderFactory.newDocumentBuilder().newDocument();
-        } catch (ParserConfigurationException ex) {
-            throw new WSDLGenerationException(ex);
-         }
-        // document.setDocumentURI("http://");
-        return document;
-    }
-
-    protected QName getQName(Interface interfaze) {
-        JavaInterface iface = (JavaInterface)interfaze;
-        QName qname = iface.getQName();
-        if (qname != null) {
-            return qname;
-        } else {
-            Class<?> javaClass = iface.getJavaClass();
-            return new QName(JavaXMLMapper.getNamespace(javaClass), javaClass.getSimpleName(), "tns");
-        }
-    }
-
-    public javax.wsdl.Operation generateOperation(Definition definition,
-                                                  Operation op,
-                                                  Map<String, XMLTypeHelper> helpers,
-                                                  Map<QName, List<ElementInfo>> wrappers)
-                                              throws WSDLException {
-        javax.wsdl.Operation operation = definition.createOperation();
-        operation.setName(op.getName());
-        operation.setUndefined(false);
-
-        Input input = definition.createInput();
-        Message inputMsg = definition.createMessage();
-        String namespaceURI = definition.getQName().getNamespaceURI();
-        QName inputMsgName = new QName(namespaceURI, op.getName());
-        inputMsg.setQName(inputMsgName);
-        inputMsg.setUndefined(false);
-        definition.addMessage(inputMsg);
-
-        List<ElementInfo> elements = null;
-        // FIXME: By default, java interface is mapped to doc-lit-wrapper style WSDL
-        if (op.getWrapper() != null) {
-            // Generate doc-lit-wrapper style
-            inputMsg.addPart(generateWrapperPart(definition, op, helpers, wrappers, true));
-        } else {
-            // Bare style
-            int i = 0;
-            for (DataType d : op.getInputType().getLogical()) {
-                inputMsg.addPart(generatePart(definition, d, "arg" + i));
-                elements = new ArrayList<ElementInfo>();
-                ElementInfo element = getElementInfo(d.getPhysical(), d, null, helpers);
-                elements.add(element);
-                QName elementName = ((XMLType)d.getLogical()).getElementName();
-                wrappers.put(elementName, elements);
-                i++;
-            }
-        }
-        input.setMessage(inputMsg);
-        operation.setInput(input);
-
-        if (!op.isNonBlocking()) {
-            Output output = definition.createOutput();
-            Message outputMsg = definition.createMessage();
-            QName outputMsgName = new QName(namespaceURI, op.getName() + "Response");
-            outputMsg.setQName(outputMsgName);
-            outputMsg.setUndefined(false);
-            definition.addMessage(outputMsg);
-
-            if (op.getWrapper() != null) {
-                outputMsg.addPart(generateWrapperPart(definition, op, helpers, wrappers, false));
-            } else {
-                DataType outputType = op.getOutputType();
-                outputMsg.addPart(generatePart(definition, outputType, "return"));
-                if (outputType != null) {
-                    elements = new ArrayList<ElementInfo>();
-                    ElementInfo element = getElementInfo(outputType.getPhysical(), outputType, null, helpers);
-                    elements.add(element);
-                    QName elementName = ((XMLType)outputType.getLogical()).getElementName();
-                    wrappers.put(elementName, elements);
-                }
-            }
-            output.setMessage(outputMsg);
-
-            operation.setOutput(output);
-            operation.setStyle(OperationType.REQUEST_RESPONSE);
-        } else {
-            operation.setStyle(OperationType.ONE_WAY);
-        }
-
-        for (DataType<DataType> faultType: op.getFaultTypes()) {
-            Fault fault = definition.createFault();
-            QName faultName = ((XMLType)faultType.getLogical().getLogical()).getElementName();
-            fault.setName(faultName.getLocalPart());
-            Message faultMsg = definition.getMessage(faultName);
-            if (faultMsg == null) {
-                faultMsg = definition.createMessage();
-                faultMsg.setQName(faultName);
-                faultMsg.setUndefined(false);
-                definition.addMessage(faultMsg);
-                faultMsg.addPart(generatePart(definition, faultType.getLogical(), faultName.getLocalPart()));
-            }
-            fault.setMessage(faultMsg);
-            operation.addFault(fault);
-            if (faultType.getLogical().getPhysical() != faultType.getPhysical()) {
-                // create special wrapper for type indirection to real fault bean
-                DataType logical = faultType.getLogical();
-                elements = new ArrayList<ElementInfo>();
-                elements.add(getElementInfo(logical.getPhysical(), logical, null, helpers));
-             } else {
-                // convert synthesized fault bean to a wrapper type
-                for (DataType<XMLType> propDT: op.getFaultBeans().get(faultName)) {
-                    XMLType logical = propDT.getLogical();
-                    elements = new ArrayList<ElementInfo>();
-                    elements.add(getElementInfo(propDT.getPhysical(), propDT, logical.getElementName(), helpers));
-                }
-            }
-            wrappers.put(faultName, elements);
-        }
-
-        operation.setUndefined(false);
-        return operation;
-    }
-
-    public Part generatePart(Definition definition, DataType arg, String partName) {
-        Part part = definition.createPart();
-        part.setName(partName);
-        if (arg != null && arg.getLogical() instanceof XMLType) {
-            XMLType xmlType = (XMLType)arg.getLogical();
-            QName elementName = xmlType.getElementName();
-            part.setElementName(elementName);
-            addNamespace(definition, elementName);
-            if (xmlType.getElementName() == null) {
-                QName typeName = xmlType.getTypeName();
-                part.setTypeName(typeName);
-                addNamespace(definition, typeName);
-            }
-        }
-        return part;
-    }
-
-    public Part generateWrapperPart(Definition definition,
-                                    Operation operation,
-                                    Map<String, XMLTypeHelper> helpers, 
-                                    Map<QName, List<ElementInfo>> wrappers,
-                                    boolean input) throws WSDLException {
-        Part part = definition.createPart();
-        String partName = input ? operation.getName() : (operation.getName() + "Response");
-        part.setName(partName);
-        WrapperInfo opWrapper = operation.getWrapper();
-        if (opWrapper != null) {
-            ElementInfo elementInfo =
-                input ? opWrapper.getInputWrapperElement() : opWrapper.getOutputWrapperElement();
-            List<ElementInfo> elements =
-                input ? opWrapper.getInputChildElements() : opWrapper.getOutputChildElements();
-            QName wrapperName = elementInfo.getQName();
-            part.setElementName(wrapperName);
-            addNamespace(definition, wrapperName);
-            wrappers.put(wrapperName, elements);
-
-            // FIXME: [rfeng] Ideally, we should try to register the wrappers only. But we are
-            // expriencing the problem that we cannot handle XSD imports 
-            /*
-            Class<?> wrapperClass = input ? opWrapper.getInputWrapperClass() : opWrapper.getOutputWrapperClass();
-            DataType wrapperDT = input ? opWrapper.getInputWrapperType() : opWrapper.getOutputWrapperType();
-            if (wrapperClass != null) {
-                getElementInfo(wrapperClass, wrapperDT, wrapperName, helpers);
-                return part;
-            }
-            */
-
-            Method method = ((JavaOperation)operation).getJavaMethod();
-            if (input) {
-                Class<?>[] paramTypes = method.getParameterTypes();
-                for (int i = 0; i < paramTypes.length; i++) {
-                    DataType dataType = operation.getInputType().getLogical().get(i);
-                    elements.set(i, getElementInfo(paramTypes[i], dataType, elements.get(i).getQName(), helpers));
-                }
-            } else {
-                Class<?> returnType = method.getReturnType();
-                if (returnType != Void.TYPE) {
-                    DataType dataType = operation.getOutputType();
-                    elements.set(0, getElementInfo(returnType, dataType, elements.get(0).getQName(), helpers));
-                }
-            }
-        }
-        return part;
-    }
-
-    private ElementInfo getElementInfo(Class javaType,
-                                       DataType dataType,
-                                       QName name,
-                                       Map<String, XMLTypeHelper> helpers) {
-        String db = dataType.getDataBinding();
-        while ("java:array".equals(db)) {
-            dataType = (DataType)dataType.getLogical();
-            db = dataType.getDataBinding();
-        }
-        XMLTypeHelper helper = helpers.get(db);
-        if (helper == null) {
-            DataBinding dataBinding = dataBindings.getDataBinding(db);
-            if (dataBinding == null) {
-                QName element = name;
-                if (element == null || dataType.getLogical() instanceof XMLType) {
-                    XMLType xmlType = (XMLType)dataType.getLogical();
-                    if (xmlType.getElementName() != null) {
-                        element = xmlType.getElementName();
-                    }
-                }
-                return new ElementInfo(element, new TypeInfo(ANYTYPE_QNAME, false, null));
-                // throw new ServiceRuntimeException("No data binding for " + db);
-            }
-
-            helper = dataBinding.getXMLTypeHelper();
-            if (helper == null) {
-                // Default to JAXB
-                helper = helpers.get(JAXBDataBinding.NAME);
-                if (helper == null) {
-                    helper = dataBindings.getDataBinding(JAXBDataBinding.NAME).getXMLTypeHelper();
-                    helpers.put(JAXBDataBinding.NAME, helper);
-                }
-            }
-            helpers.put(db, helper);
-        }
-        TypeInfo typeInfo = helper.getTypeInfo(javaType.isArray() ? javaType.getComponentType() : javaType,
-                                               dataType.getLogical());
-        ElementInfo element = new ElementInfo(name, typeInfo);
-        element.setMany(byte[].class != javaType && javaType.isArray());
-        element.setNillable(!javaType.isPrimitive());
-        return element;
-    }
-
-    private static void addNamespace(Definition definition, QName name) {
-        String namespace = name.getNamespaceURI();
-        if (definition.getPrefix(namespace) == null) {
-            definition.addNamespace("ns" + definition.getNamespaces().size(), namespace);
-        }
-    }
-
-    /*
-    // currently not using the next three methods
-    public XmlSchemaType getXmlSchemaType(DataType type) {
-        return null;
-    }
-
-    // FIXME: WE need to add databinding-specific Java2XSD generation
-    public Element generateXSD(DataType dataType) {
-        DataBinding dataBinding = dataBindings.getDataBinding(dataType.getDataBinding());
-        if (dataBinding != null) {
-            // return dataBinding.generateSchema(dataType);
-        }
-        return null;
-    }
-
-    public void generateWrapperElements(Operation op) {
-        XmlSchemaCollection collection = new XmlSchemaCollection();
-        String ns = getQName(op.getInterface()).getNamespaceURI();
-        XmlSchema schema = new XmlSchema(ns, collection);
-        schema.setAttributeFormDefault(new XmlSchemaForm(XmlSchemaForm.QUALIFIED));
-        schema.setElementFormDefault(new XmlSchemaForm(XmlSchemaForm.QUALIFIED));
-
-        XmlSchemaElement inputElement = new XmlSchemaElement();
-        inputElement.setQName(new QName(ns, op.getName()));
-        XmlSchemaComplexType inputType = new XmlSchemaComplexType(schema);
-        inputType.setName("");
-        XmlSchemaSequence inputSeq = new XmlSchemaSequence();
-        inputType.setParticle(inputSeq);
-        List<DataType> argTypes = op.getInputType().getLogical();
-        for (DataType argType : argTypes) {
-            XmlSchemaElement child = new XmlSchemaElement();
-            Object logical = argType.getLogical();
-            if (logical instanceof XMLType) {
-                child.setName(((XMLType)logical).getElementName().getLocalPart());
-                XmlSchemaType type = getXmlSchemaType(argType);
-                child.setType(type);
-            }
-            inputSeq.getItems().add(child);
-        }
-        inputElement.setType(inputType);
-
-        XmlSchemaElement outputElement = new XmlSchemaElement();
-        outputElement.setQName(new QName(ns, op.getName() + "Response"));
-        XmlSchemaComplexType outputType = new XmlSchemaComplexType(schema);
-        outputType.setName("");
-        XmlSchemaSequence outputSeq = new XmlSchemaSequence();
-        outputType.setParticle(outputSeq);
-        DataType returnType = op.getOutputType();
-        XmlSchemaElement child = new XmlSchemaElement();
-        Object logical = returnType.getLogical();
-        if (logical instanceof XMLType) {
-            child.setName(((XMLType)logical).getElementName().getLocalPart());
-            XmlSchemaType type = getXmlSchemaType(returnType);
-            child.setType(type);
-        }
-        outputSeq.getItems().add(child);
-        outputElement.setType(outputType);
-
-        schema.getElements().add(inputElement.getQName(), inputElement);
-        schema.getElements().add(outputElement.getQName(), outputElement);
-
-    }
-    */
-
-    public WSDLFactory getFactory() {
-        return factory;
-    }
-
-    public void setFactory(WSDLFactory factory) {
-        this.factory = factory;
-    }
-
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ * 
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+
+package org.apache.tuscany.sca.binding.ws.wsdlgen;
+
+import java.lang.reflect.Method;
+import java.net.URI;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+import javax.wsdl.Binding;
+import javax.wsdl.BindingOperation;
+import javax.wsdl.Definition;
+import javax.wsdl.Fault;
+import javax.wsdl.Input;
+import javax.wsdl.Message;
+import javax.wsdl.OperationType;
+import javax.wsdl.Output;
+import javax.wsdl.Part;
+import javax.wsdl.PortType;
+import javax.wsdl.Types;
+import javax.wsdl.WSDLException;
+import javax.wsdl.extensions.schema.Schema;
+import javax.wsdl.factory.WSDLFactory;
+import javax.xml.namespace.QName;
+import javax.xml.parsers.DocumentBuilderFactory;
+import javax.xml.parsers.ParserConfigurationException;
+
+import org.apache.tuscany.sca.assembly.builder.impl.ProblemImpl;
+import org.apache.tuscany.sca.contribution.resolver.ModelResolver;
+import org.apache.tuscany.sca.databinding.DataBinding;
+import org.apache.tuscany.sca.databinding.DataBindingExtensionPoint;
+import org.apache.tuscany.sca.databinding.XMLTypeHelper;
+import org.apache.tuscany.sca.databinding.jaxb.JAXBDataBinding;
+import org.apache.tuscany.sca.interfacedef.DataType;
+import org.apache.tuscany.sca.interfacedef.Interface;
+import org.apache.tuscany.sca.interfacedef.Operation;
+import org.apache.tuscany.sca.interfacedef.java.JavaInterface;
+import org.apache.tuscany.sca.interfacedef.java.JavaOperation;
+import org.apache.tuscany.sca.interfacedef.util.ElementInfo;
+import org.apache.tuscany.sca.interfacedef.util.JavaXMLMapper;
+import org.apache.tuscany.sca.interfacedef.util.TypeInfo;
+import org.apache.tuscany.sca.interfacedef.util.WrapperInfo;
+import org.apache.tuscany.sca.interfacedef.util.XMLType;
+import org.apache.tuscany.sca.interfacedef.wsdl.WSDLDefinition;
+import org.apache.tuscany.sca.interfacedef.wsdl.WSDLInterface;
+import org.apache.tuscany.sca.monitor.Monitor;
+import org.apache.tuscany.sca.monitor.Problem;
+import org.apache.tuscany.sca.monitor.Problem.Severity;
+import org.apache.tuscany.sca.xsd.XSDFactory;
+import org.apache.tuscany.sca.xsd.XSDefinition;
+import org.apache.ws.commons.schema.XmlSchema;
+import org.apache.ws.commons.schema.XmlSchemaCollection;
+import org.apache.ws.commons.schema.XmlSchemaException;
+import org.apache.ws.commons.schema.utils.NamespaceMap;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.w3c.dom.Node;
+import org.w3c.dom.NodeList;
+
+/**
+ * @version $Rev: 670103 $ $Date: 2008-06-21 01:35:00 +0100 (Sat, 21 Jun 2008) $
+ */
+public class Interface2WSDLGenerator {
+    private static final Logger logger = Logger.getLogger(Interface2WSDLGenerator.class.getName());
+    private static final String SCHEMA_NS = "http://www.w3.org/2001/XMLSchema";
+    private static final String SCHEMA_NAME = "schema";
+    private static final QName SCHEMA_QNAME = new QName(SCHEMA_NS, SCHEMA_NAME);
+    private static final String XMLNS_NS = "http://www.w3.org/2000/xmlns/";
+    
+    private static final String ANYTYPE_NAME = "anyType";
+    private static final QName ANYTYPE_QNAME = new QName(SCHEMA_NS, ANYTYPE_NAME);
+
+
+    private WSDLFactory factory;
+    private DataBindingExtensionPoint dataBindings;
+    private WSDLDefinitionGenerator definitionGenerator;
+    private boolean requiresSOAP12;
+    private ModelResolver resolver;
+    private XSDFactory xsdFactory;
+    private Monitor monitor;
+
+    public Interface2WSDLGenerator(boolean requiresSOAP12,
+                                   ModelResolver resolver,
+                                   DataBindingExtensionPoint dataBindings,
+                                   XSDFactory xsdFactory,
+                                   Monitor monitor) throws WSDLException {
+        super();
+        this.requiresSOAP12 = requiresSOAP12; 
+        this.resolver = resolver; 
+        definitionGenerator = new WSDLDefinitionGenerator(requiresSOAP12);
+        this.dataBindings = dataBindings;
+        this.xsdFactory = xsdFactory;
+        this.monitor = monitor;
+        this.factory = WSDLFactory.newInstance();
+    }
+
+    /**
+     * Log a warning message.
+     * @param problem
+     */
+    private static void logWarning(Problem problem) {
+        Logger problemLogger = Logger.getLogger(problem.getSourceClassName(), problem.getBundleName());
+        if (problemLogger != null){
+            problemLogger.logp(Level.WARNING, problem.getSourceClassName(), null, problem.getMessageId(), problem.getMessageParams());
+        } else {
+            logger.severe("Can't get logger " + problem.getSourceClassName()+ " with bundle " + problem.getBundleName());
+        }
+    }
+
+    /**
+     * Report a warning.
+     * @param message
+     * @param binding
+     * @param parameters
+     */
+    private void warning(String message, Interface interfaze, String... messageParameters) {
+        Problem problem = new ProblemImpl(this.getClass().getName(), "wsdlgen-validation-messages", Severity.WARNING, interfaze, message, (Object[])messageParameters);
+        if (monitor != null) {
+            monitor.problem(problem);
+        } else {
+            logWarning(problem);
+        }
+    }
+
+    /**
+     * Report a fatal error.
+     * @param message
+     * @param binding
+     * @param parameters
+     */
+    private void fatal(String message, Interface interfaze, String... messageParameters) {
+        Problem problem = new ProblemImpl(this.getClass().getName(), "wsdlgen-validation-messages", Severity.ERROR, interfaze, message, (Object[])messageParameters);
+        throw new WSDLGenerationException(problem.toString(), null, problem);
+    }
+    
+    private XMLTypeHelper getTypeHelper(DataType type, Map<String, XMLTypeHelper> helpers) {
+        if (type == null) {
+            return null;
+        }
+        String db = type.getDataBinding();
+        if (db == null) {
+            return null;
+        }
+        if ("java:array".equals(db)) {
+            DataType dt = (DataType)type.getLogical();
+            db = dt.getDataBinding();
+        }
+        return helpers.get(db);
+    }
+    
+    private boolean inputTypesCompatible(DataType wrapperType, DataType<List<DataType>> inputType, Map<String, XMLTypeHelper> helpers) {
+        XMLTypeHelper wrapperHelper = getTypeHelper(wrapperType, helpers);
+        for (DataType dt : inputType.getLogical()) {
+            if (getTypeHelper(dt, helpers) != wrapperHelper) {
+                return false;
+            }
+        }
+        return true;
+    }
+    
+    private boolean outputTypeCompatible(DataType wrapperType, DataType outputType, Map<String, XMLTypeHelper> helpers) {
+        if (getTypeHelper(outputType, helpers) != getTypeHelper(wrapperType, helpers)) {
+            return false;
+        } else {
+            return true;
+        }
+    }
+    
+    private void addDataType(Map<XMLTypeHelper, List<DataType>> map, DataType type, Map<String, XMLTypeHelper> helpers) {
+        if (type == null) {
+            return;
+        }
+        String db = type.getDataBinding();
+        if (db == null) {
+            return;
+        }
+        if ("java:array".equals(db)) {
+            DataType dt = (DataType)type.getLogical();
+            db = dt.getDataBinding();
+        }
+        XMLTypeHelper helper = helpers.get(db);
+        List<DataType> types = map.get(helper);
+        if (types == null) {
+            types = new ArrayList<DataType>();
+            map.put(helper, types);
+        }
+        types.add(type);
+    }
+    
+    private Map<XMLTypeHelper, List<DataType>> getDataTypes(Interface intf, boolean useWrapper, Map<String, XMLTypeHelper> helpers) {
+        Map<XMLTypeHelper, List<DataType>> dataTypes = new HashMap<XMLTypeHelper, List<DataType>>();
+        for (Operation op : intf.getOperations()) {
+            WrapperInfo wrapper = op.getWrapper();
+            DataType dt1 = null;
+            boolean useInputWrapper = useWrapper & wrapper != null;
+            if (useInputWrapper) {
+                dt1 = wrapper.getInputWrapperType();
+                useInputWrapper &= inputTypesCompatible(dt1, op.getInputType(), helpers);
+            }
+            if (useInputWrapper) {
+                addDataType(dataTypes, dt1, helpers);
+            } else {
+                for (DataType dt : op.getInputType().getLogical()) {
+                    addDataType(dataTypes, dt, helpers);
+                }
+            }
+            
+            DataType dt2 = null;
+            boolean useOutputWrapper = useWrapper & wrapper != null;
+            if (useOutputWrapper) {
+                dt2 = wrapper.getOutputWrapperType();
+                useOutputWrapper &= outputTypeCompatible(dt2, op.getOutputType(), helpers);
+            }
+            if (useOutputWrapper) {
+                addDataType(dataTypes, dt2, helpers);
+            } else {
+                dt2 = op.getOutputType();
+                addDataType(dataTypes, dt2, helpers);
+            }
+            
+            for (DataType<DataType> dt3 : op.getFaultTypes()) {
+                DataType dt4 = dt3.getLogical();
+                addDataType(dataTypes, dt4, helpers);
+            }
+        }
+        return dataTypes;
+    }
+
+
+    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();
+            if ((action == null || "".equals(action)) && !op.isWrapperStyle() && op.getWrapper() == null) {
+                // Bare style
+                action = "urn:" + op.getName();
+            }
+            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(); 
+
+        for (Map.Entry<XMLTypeHelper, List<DataType>> en: getDataTypes(interfaze, false, helpers).entrySet()) {
+            XMLTypeHelper helper = en.getKey();
+            if (helper == null) {
+                continue;
+            }
+            List<XSDefinition> xsDefinitions = helper.getSchemaDefinitions(xsdFactory, resolver, en.getValue());
+            for (XSDefinition xsDef: xsDefinitions) {
+                addSchemaExtension(xsDef, schemaCollection, wsdlDefinition, definition);
+            }
+        }
+
+        // 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);
+            }
+        }
+
+        // generate schema elements for wrappers that aren't defined in the schemas
+        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 {
+                    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);
+                    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);
+                }
+                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 (targetNS.equals(nsURI)) {
+                                xsElement.setAttribute("type", typeName.getLocalPart());
+                            } 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) {
+                                    prefix = "ns" + i++;
+                                    prefixMap.put(nsURI, prefix);
+                                    schema.setAttributeNS(XMLNS_NS, "xmlns:" + prefix, nsURI);
+                                    addSchemaImport(schema, nsURI, schemaDoc);
+                                }
+                                xsElement.setAttribute("type", prefix + ":" + typeName.getLocalPart());
+                            }
+                            sequence.appendChild(xsElement);
+                        }
+                    }
+                }
+            }
+ 
+            // resolve XSDefinitions containing generated wrappers
+            for (XSDefinition xsDef: wrapperXSDs.values()) {
+                loadXSD(schemaCollection, xsDef);
+                wsdlDefinition.getXmlSchemas().add(xsDef);
+            }
+        }
+
+        return definition;
+    }
+
+    private static void addSchemaImport(Element schema, String nsURI, Document schemaDoc) {
+        Element imp = schemaDoc.createElementNS(SCHEMA_NS, "xs:import");
+        if (!"".equals(nsURI)) {
+            imp.setAttribute("namespace", nsURI);
+        }
+        NodeList childNodes = schema.getChildNodes();
+        for (int i = 0; i < childNodes.getLength(); i++) {
+            Node childNode = childNodes.item(i);
+            if (childNode instanceof Element) {
+                schema.insertBefore(imp, childNode);
+                imp = null;
+                break;
+            }
+        }
+        if (imp != null) {
+            schema.appendChild(imp);
+        }
+    }
+
+    private void addSchemaExtension(XSDefinition xsDef,
+                                    XmlSchemaCollection schemaCollection,
+                                    WSDLDefinition wsdlDefinition,
+                                    Definition definition) throws WSDLException {
+        if (xsDef.getAggregatedDefinitions() != null) {
+            for (XSDefinition xsd: xsDef.getAggregatedDefinitions()) {
+                addSchemaExtension(xsd, schemaCollection, wsdlDefinition, definition);
+            }
+        } else {
+            String nsURI = xsDef.getNamespace();
+            Document document = xsDef.getDocument();
+            if (document == null) {
+                try {
+                    NamespaceMap prefixMap = new NamespaceMap();
+                    prefixMap.add("xs", SCHEMA_NS);
+                    prefixMap.add("tns", nsURI);
+                    XmlSchema schemaDef = xsDef.getSchema();
+                    schemaDef.setNamespaceContext(prefixMap);
+                    Document[] docs = schemaDef.getAllSchemas();
+                    document = docs[docs.length-1];
+                    document.setDocumentURI(xsDef.getLocation().toString());
+                    xsDef.setDocument(document);
+                } catch (XmlSchemaException e) {
+                    throw new RuntimeException(e);
+                }
+            }
+            loadXSD(schemaCollection, xsDef);
+            wsdlDefinition.getXmlSchemas().add(xsDef);
+            Element schema = document.getDocumentElement();
+            Schema schemaExt = createSchemaExt(definition);
+            schemaExt.setDocumentBaseURI(document.getDocumentURI());
+            schemaExt.setElement(schema);
+        }
+    }
+
+    private static void loadXSD(XmlSchemaCollection schemaCollection, XSDefinition definition) {
+        if (definition.getSchema() != null) {
+            return;
+        }
+        if (definition.getDocument() != null) {
+            String uri = null;
+            if (definition.getLocation() != null) {
+                uri = definition.getLocation().toString();
+            }
+            XmlSchema schema = schemaCollection.read(definition.getDocument(), uri, null);
+            if (definition.getSchemaCollection() == null) {
+                definition.setSchemaCollection(schemaCollection);
+            }
+            if (definition.getSchema() == null) {
+                definition.setSchema(schema);
+            }
+        }
+    }
+
+    public Schema createSchemaExt(Definition definition) throws WSDLException {
+        Types types = definition.getTypes();
+        if (types == null) {
+            types = definition.createTypes();
+            definition.setTypes(types);
+        }
+
+        Schema schemaExt = createSchema(definition);
+        types.addExtensibilityElement(schemaExt);
+
+        return schemaExt;
+    }
+
+    public Schema createSchema(Definition definition) throws WSDLException {
+        return (Schema)definition.getExtensionRegistry().createExtension(Types.class, SCHEMA_QNAME);
+    }
+
+    private DocumentBuilderFactory documentBuilderFactory;
+
+    public Document createDocument() {
+        Document document;
+        try {
+            if (documentBuilderFactory == null) {
+                documentBuilderFactory = DocumentBuilderFactory.newInstance();
+                documentBuilderFactory.setNamespaceAware(true);
+            }
+            document = documentBuilderFactory.newDocumentBuilder().newDocument();
+        } catch (ParserConfigurationException ex) {
+            throw new WSDLGenerationException(ex);
+         }
+        // document.setDocumentURI("http://");
+        return document;
+    }
+
+    protected QName getQName(Interface interfaze) {
+        JavaInterface iface = (JavaInterface)interfaze;
+        QName qname = iface.getQName();
+        if (qname != null) {
+            return qname;
+        } else {
+            Class<?> javaClass = iface.getJavaClass();
+            return new QName(JavaXMLMapper.getNamespace(javaClass), javaClass.getSimpleName(), "tns");
+        }
+    }
+
+    public javax.wsdl.Operation generateOperation(Definition definition,
+                                                  Operation op,
+                                                  Map<String, XMLTypeHelper> helpers,
+                                                  Map<QName, List<ElementInfo>> wrappers)
+                                              throws WSDLException {
+        javax.wsdl.Operation operation = definition.createOperation();
+        operation.setName(op.getName());
+        operation.setUndefined(false);
+
+        Input input = definition.createInput();
+        Message inputMsg = definition.createMessage();
+        String namespaceURI = definition.getQName().getNamespaceURI();
+        QName inputMsgName = new QName(namespaceURI, op.getName());
+        inputMsg.setQName(inputMsgName);
+        inputMsg.setUndefined(false);
+        definition.addMessage(inputMsg);
+
+        List<ElementInfo> elements = null;
+        // FIXME: By default, java interface is mapped to doc-lit-wrapper style WSDL
+        if (op.getWrapper() != null) {
+            // Generate doc-lit-wrapper style
+            inputMsg.addPart(generateWrapperPart(definition, op, helpers, wrappers, true));
+        } else {
+            // Bare style
+            int i = 0;
+            for (DataType d : op.getInputType().getLogical()) {
+                inputMsg.addPart(generatePart(definition, d, "arg" + i));
+                elements = new ArrayList<ElementInfo>();
+                ElementInfo element = getElementInfo(d.getPhysical(), d, null, helpers);
+                elements.add(element);
+                QName elementName = ((XMLType)d.getLogical()).getElementName();
+                wrappers.put(elementName, elements);
+                i++;
+            }
+        }
+        input.setMessage(inputMsg);
+        operation.setInput(input);
+
+        if (!op.isNonBlocking()) {
+            Output output = definition.createOutput();
+            Message outputMsg = definition.createMessage();
+            QName outputMsgName = new QName(namespaceURI, op.getName() + "Response");
+            outputMsg.setQName(outputMsgName);
+            outputMsg.setUndefined(false);
+            definition.addMessage(outputMsg);
+
+            if (op.getWrapper() != null) {
+                outputMsg.addPart(generateWrapperPart(definition, op, helpers, wrappers, false));
+            } else {
+                DataType outputType = op.getOutputType();
+                outputMsg.addPart(generatePart(definition, outputType, "return"));
+                if (outputType != null) {
+                    elements = new ArrayList<ElementInfo>();
+                    ElementInfo element = getElementInfo(outputType.getPhysical(), outputType, null, helpers);
+                    elements.add(element);
+                    QName elementName = ((XMLType)outputType.getLogical()).getElementName();
+                    wrappers.put(elementName, elements);
+                }
+            }
+            output.setMessage(outputMsg);
+
+            operation.setOutput(output);
+            operation.setStyle(OperationType.REQUEST_RESPONSE);
+        } else {
+            operation.setStyle(OperationType.ONE_WAY);
+        }
+
+        for (DataType<DataType> faultType: op.getFaultTypes()) {
+            Fault fault = definition.createFault();
+            QName faultName = ((XMLType)faultType.getLogical().getLogical()).getElementName();
+            fault.setName(faultName.getLocalPart());
+            Message faultMsg = definition.getMessage(faultName);
+            if (faultMsg == null) {
+                faultMsg = definition.createMessage();
+                faultMsg.setQName(faultName);
+                faultMsg.setUndefined(false);
+                definition.addMessage(faultMsg);
+                faultMsg.addPart(generatePart(definition, faultType.getLogical(), faultName.getLocalPart()));
+            }
+            fault.setMessage(faultMsg);
+            operation.addFault(fault);
+            if (faultType.getLogical().getPhysical() != faultType.getPhysical()) {
+                // create special wrapper for type indirection to real fault bean
+                DataType logical = faultType.getLogical();
+                elements = new ArrayList<ElementInfo>();
+                elements.add(getElementInfo(logical.getPhysical(), logical, null, helpers));
+             } else {
+                // convert synthesized fault bean to a wrapper type
+                for (DataType<XMLType> propDT: op.getFaultBeans().get(faultName)) {
+                    XMLType logical = propDT.getLogical();
+                    elements = new ArrayList<ElementInfo>();
+                    elements.add(getElementInfo(propDT.getPhysical(), propDT, logical.getElementName(), helpers));
+                }
+            }
+            wrappers.put(faultName, elements);
+        }
+
+        operation.setUndefined(false);
+        return operation;
+    }
+
+    public Part generatePart(Definition definition, DataType arg, String partName) {
+        Part part = definition.createPart();
+        part.setName(partName);
+        if (arg != null && arg.getLogical() instanceof XMLType) {
+            XMLType xmlType = (XMLType)arg.getLogical();
+            QName elementName = xmlType.getElementName();
+            part.setElementName(elementName);
+            addNamespace(definition, elementName);
+            if (xmlType.getElementName() == null) {
+                QName typeName = xmlType.getTypeName();
+                part.setTypeName(typeName);
+                addNamespace(definition, typeName);
+            }
+        }
+        return part;
+    }
+
+    public Part generateWrapperPart(Definition definition,
+                                    Operation operation,
+                                    Map<String, XMLTypeHelper> helpers, 
+                                    Map<QName, List<ElementInfo>> wrappers,
+                                    boolean input) throws WSDLException {
+        Part part = definition.createPart();
+        String partName = input ? operation.getName() : (operation.getName() + "Response");
+        part.setName(partName);
+        WrapperInfo opWrapper = operation.getWrapper();
+        if (opWrapper != null) {
+            ElementInfo elementInfo =
+                input ? opWrapper.getInputWrapperElement() : opWrapper.getOutputWrapperElement();
+            List<ElementInfo> elements =
+                input ? opWrapper.getInputChildElements() : opWrapper.getOutputChildElements();
+            QName wrapperName = elementInfo.getQName();
+            part.setElementName(wrapperName);
+            addNamespace(definition, wrapperName);
+            wrappers.put(wrapperName, elements);
+
+            // FIXME: [rfeng] Ideally, we should try to register the wrappers only. But we are
+            // expriencing the problem that we cannot handle XSD imports 
+            /*
+            Class<?> wrapperClass = input ? opWrapper.getInputWrapperClass() : opWrapper.getOutputWrapperClass();
+            DataType wrapperDT = input ? opWrapper.getInputWrapperType() : opWrapper.getOutputWrapperType();
+            if (wrapperClass != null) {
+                getElementInfo(wrapperClass, wrapperDT, wrapperName, helpers);
+                return part;
+            }
+            */
+
+            Method method = ((JavaOperation)operation).getJavaMethod();
+            if (input) {
+                Class<?>[] paramTypes = method.getParameterTypes();
+                for (int i = 0; i < paramTypes.length; i++) {
+                    DataType dataType = operation.getInputType().getLogical().get(i);
+                    elements.set(i, getElementInfo(paramTypes[i], dataType, elements.get(i).getQName(), helpers));
+                }
+            } else {
+                Class<?> returnType = method.getReturnType();
+                if (returnType != Void.TYPE) {
+                    DataType dataType = operation.getOutputType();
+                    elements.set(0, getElementInfo(returnType, dataType, elements.get(0).getQName(), helpers));
+                }
+            }
+        }
+        return part;
+    }
+
+    private ElementInfo getElementInfo(Class javaType,
+                                       DataType dataType,
+                                       QName name,
+                                       Map<String, XMLTypeHelper> helpers) {
+        String db = dataType.getDataBinding();
+        while ("java:array".equals(db)) {
+            dataType = (DataType)dataType.getLogical();
+            db = dataType.getDataBinding();
+        }
+        XMLTypeHelper helper = helpers.get(db);
+        if (helper == null) {
+            DataBinding dataBinding = dataBindings.getDataBinding(db);
+            if (dataBinding == null) {
+                QName element = name;
+                if (element == null || dataType.getLogical() instanceof XMLType) {
+                    XMLType xmlType = (XMLType)dataType.getLogical();
+                    if (xmlType.getElementName() != null) {
+                        element = xmlType.getElementName();
+                    }
+                }
+                return new ElementInfo(element, new TypeInfo(ANYTYPE_QNAME, false, null));
+                // throw new ServiceRuntimeException("No data binding for " + db);
+            }
+
+            helper = dataBinding.getXMLTypeHelper();
+            if (helper == null) {
+                // Default to JAXB
+                helper = helpers.get(JAXBDataBinding.NAME);
+                if (helper == null) {
+                    helper = dataBindings.getDataBinding(JAXBDataBinding.NAME).getXMLTypeHelper();
+                    helpers.put(JAXBDataBinding.NAME, helper);
+                }
+            }
+            helpers.put(db, helper);
+        }
+        TypeInfo typeInfo = helper.getTypeInfo(javaType.isArray() ? javaType.getComponentType() : javaType,
+                                               dataType.getLogical());
+        ElementInfo element = new ElementInfo(name, typeInfo);
+        element.setMany(byte[].class != javaType && javaType.isArray());
+        element.setNillable(!javaType.isPrimitive());
+        return element;
+    }
+
+    private static void addNamespace(Definition definition, QName name) {
+        String namespace = name.getNamespaceURI();
+        if (definition.getPrefix(namespace) == null) {
+            definition.addNamespace("ns" + definition.getNamespaces().size(), namespace);
+        }
+    }
+
+    /*
+    // currently not using the next three methods
+    public XmlSchemaType getXmlSchemaType(DataType type) {
+        return null;
+    }
+
+    // FIXME: WE need to add databinding-specific Java2XSD generation
+    public Element generateXSD(DataType dataType) {
+        DataBinding dataBinding = dataBindings.getDataBinding(dataType.getDataBinding());
+        if (dataBinding != null) {
+            // return dataBinding.generateSchema(dataType);
+        }
+        return null;
+    }
+
+    public void generateWrapperElements(Operation op) {
+        XmlSchemaCollection collection = new XmlSchemaCollection();
+        String ns = getQName(op.getInterface()).getNamespaceURI();
+        XmlSchema schema = new XmlSchema(ns, collection);
+        schema.setAttributeFormDefault(new XmlSchemaForm(XmlSchemaForm.QUALIFIED));
+        schema.setElementFormDefault(new XmlSchemaForm(XmlSchemaForm.QUALIFIED));
+
+        XmlSchemaElement inputElement = new XmlSchemaElement();
+        inputElement.setQName(new QName(ns, op.getName()));
+        XmlSchemaComplexType inputType = new XmlSchemaComplexType(schema);
+        inputType.setName("");
+        XmlSchemaSequence inputSeq = new XmlSchemaSequence();
+        inputType.setParticle(inputSeq);
+        List<DataType> argTypes = op.getInputType().getLogical();
+        for (DataType argType : argTypes) {
+            XmlSchemaElement child = new XmlSchemaElement();
+            Object logical = argType.getLogical();
+            if (logical instanceof XMLType) {
+                child.setName(((XMLType)logical).getElementName().getLocalPart());
+                XmlSchemaType type = getXmlSchemaType(argType);
+                child.setType(type);
+            }
+            inputSeq.getItems().add(child);
+        }
+        inputElement.setType(inputType);
+
+        XmlSchemaElement outputElement = new XmlSchemaElement();
+        outputElement.setQName(new QName(ns, op.getName() + "Response"));
+        XmlSchemaComplexType outputType = new XmlSchemaComplexType(schema);
+        outputType.setName("");
+        XmlSchemaSequence outputSeq = new XmlSchemaSequence();
+        outputType.setParticle(outputSeq);
+        DataType returnType = op.getOutputType();
+        XmlSchemaElement child = new XmlSchemaElement();
+        Object logical = returnType.getLogical();
+        if (logical instanceof XMLType) {
+            child.setName(((XMLType)logical).getElementName().getLocalPart());
+            XmlSchemaType type = getXmlSchemaType(returnType);
+            child.setType(type);
+        }
+        outputSeq.getItems().add(child);
+        outputElement.setType(outputType);
+
+        schema.getElements().add(inputElement.getQName(), inputElement);
+        schema.getElements().add(outputElement.getQName(), outputElement);
+
+    }
+    */
+
+    public WSDLFactory getFactory() {
+        return factory;
+    }
+
+    public void setFactory(WSDLFactory factory) {
+        this.factory = factory;
+    }
+
+}