summaryrefslogtreecommitdiffstats
path: root/sca-java-1.x/branches/sca-java-1.5/modules/binding-ws-wsdlgen/src/main/java
diff options
context:
space:
mode:
authorlresende <lresende@13f79535-47bb-0310-9956-ffa450edef68>2009-11-11 23:08:37 +0000
committerlresende <lresende@13f79535-47bb-0310-9956-ffa450edef68>2009-11-11 23:08:37 +0000
commit4ef0430519e276c2bdecea75f7a0f42f49f0cf30 (patch)
tree19dd40a9336c52160da6671d2fb3d428725733d4 /sca-java-1.x/branches/sca-java-1.5/modules/binding-ws-wsdlgen/src/main/java
parent725006d4c47e63986ac042ade23a4d193298b1fe (diff)
Moving 1.x branches
git-svn-id: http://svn.us.apache.org/repos/asf/tuscany@835132 13f79535-47bb-0310-9956-ffa450edef68
Diffstat (limited to 'sca-java-1.x/branches/sca-java-1.5/modules/binding-ws-wsdlgen/src/main/java')
-rw-r--r--sca-java-1.x/branches/sca-java-1.5/modules/binding-ws-wsdlgen/src/main/java/org/apache/tuscany/sca/binding/ws/wsdlgen/BindingWSDLGenerator.java345
-rw-r--r--sca-java-1.x/branches/sca-java-1.5/modules/binding-ws-wsdlgen/src/main/java/org/apache/tuscany/sca/binding/ws/wsdlgen/Interface2WSDLGenerator.java844
-rw-r--r--sca-java-1.x/branches/sca-java-1.5/modules/binding-ws-wsdlgen/src/main/java/org/apache/tuscany/sca/binding/ws/wsdlgen/WSDLDefinitionGenerator.java316
-rw-r--r--sca-java-1.x/branches/sca-java-1.5/modules/binding-ws-wsdlgen/src/main/java/org/apache/tuscany/sca/binding/ws/wsdlgen/WSDLGenerationException.java54
-rw-r--r--sca-java-1.x/branches/sca-java-1.5/modules/binding-ws-wsdlgen/src/main/java/org/apache/tuscany/sca/binding/ws/wsdlgen/WSDLServiceGenerator.java542
5 files changed, 2101 insertions, 0 deletions
diff --git a/sca-java-1.x/branches/sca-java-1.5/modules/binding-ws-wsdlgen/src/main/java/org/apache/tuscany/sca/binding/ws/wsdlgen/BindingWSDLGenerator.java b/sca-java-1.x/branches/sca-java-1.5/modules/binding-ws-wsdlgen/src/main/java/org/apache/tuscany/sca/binding/ws/wsdlgen/BindingWSDLGenerator.java
new file mode 100644
index 0000000000..de1cab15d8
--- /dev/null
+++ b/sca-java-1.x/branches/sca-java-1.5/modules/binding-ws-wsdlgen/src/main/java/org/apache/tuscany/sca/binding/ws/wsdlgen/BindingWSDLGenerator.java
@@ -0,0 +1,345 @@
+/*
+ * 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.util.List;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+import javax.wsdl.Definition;
+import javax.wsdl.PortType;
+import javax.wsdl.WSDLException;
+import javax.wsdl.xml.WSDLWriter;
+import javax.xml.namespace.QName;
+
+import org.apache.tuscany.sca.assembly.AbstractContract;
+import org.apache.tuscany.sca.assembly.Component;
+import org.apache.tuscany.sca.assembly.Contract;
+import org.apache.tuscany.sca.assembly.builder.BindingBuilderExtension;
+import org.apache.tuscany.sca.assembly.builder.impl.ProblemImpl;
+import org.apache.tuscany.sca.binding.ws.WebServiceBinding;
+import org.apache.tuscany.sca.contribution.ModelFactoryExtensionPoint;
+import org.apache.tuscany.sca.contribution.resolver.ModelResolver;
+import org.apache.tuscany.sca.contribution.resolver.ResolverExtension;
+import org.apache.tuscany.sca.core.ExtensionPointRegistry;
+import org.apache.tuscany.sca.databinding.DataBindingExtensionPoint;
+import org.apache.tuscany.sca.interfacedef.InterfaceContract;
+import org.apache.tuscany.sca.interfacedef.Operation;
+import org.apache.tuscany.sca.interfacedef.java.JavaInterface;
+import org.apache.tuscany.sca.interfacedef.java.JavaInterfaceContract;
+import org.apache.tuscany.sca.interfacedef.wsdl.WSDLDefinition;
+import org.apache.tuscany.sca.interfacedef.wsdl.WSDLFactory;
+import org.apache.tuscany.sca.interfacedef.wsdl.WSDLInterface;
+import org.apache.tuscany.sca.interfacedef.wsdl.WSDLInterfaceContract;
+import org.apache.tuscany.sca.interfacedef.wsdl.impl.InvalidWSDLException;
+import org.apache.tuscany.sca.interfacedef.wsdl.impl.WSDLInterfaceIntrospectorImpl;
+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.policy.Intent;
+import org.apache.tuscany.sca.policy.IntentAttachPoint;
+import org.apache.tuscany.sca.xsd.XSDFactory;
+
+/**
+ * @version $Rev$ $Date$
+ */
+public class BindingWSDLGenerator {
+ private static final Logger logger = Logger.getLogger(BindingWSDLGenerator.class.getName());
+ private static final QName SOAP12_INTENT = new QName("http://www.osoa.org/xmlns/sca/1.0", "SOAP.1_2");
+
+ public static boolean printWSDL; // external code sets this to print generated WSDL
+
+ private BindingWSDLGenerator() {
+ // this class has static methods only and cannot be instantiated
+ }
+
+ /**
+ * 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 static void warning(Monitor monitor, String message, WebServiceBinding wsBinding, String... messageParameters) {
+ Problem problem = new ProblemImpl(BindingWSDLGenerator.class.getName(), "wsdlgen-validation-messages", Severity.WARNING, wsBinding, message, (Object[])messageParameters);
+ if (monitor != null) {
+ monitor.problem(problem);
+ } else {
+ logWarning(problem);
+ }
+ }
+
+ /**
+ * Report an error.
+ * @param message
+ * @param binding
+ * @param parameters
+ */
+ private static void error(Monitor monitor, String message, WebServiceBinding wsBinding, String... messageParameters) {
+ Problem problem = new ProblemImpl(BindingWSDLGenerator.class.getName(), "wsdlgen-validation-messages", Severity.ERROR, wsBinding, message, (Object[])messageParameters);
+ if (monitor != null) {
+ monitor.problem(problem);
+ } else {
+ throw new WSDLGenerationException(problem.toString(), null, problem);
+ }
+ }
+
+ /**
+ * Report an exception error.
+ * @param message
+ * @param binding
+ * @param exception
+ */
+ private static void error(Monitor monitor, String message, WebServiceBinding wsBinding, Exception ex) {
+ Problem problem = new ProblemImpl(BindingWSDLGenerator.class.getName(), "wsdlgen-validation-messages", Severity.ERROR, wsBinding, message, ex);
+ if (monitor != null) {
+ monitor.problem(problem);
+ } else {
+ throw new WSDLGenerationException(problem.toString(), ex, problem);
+ }
+ }
+
+ /**
+ * Report a fatal error.
+ * @param message
+ * @param binding
+ * @param exception
+ */
+ private static void fatal(Monitor monitor, String message, WebServiceBinding wsBinding, String... messageParameters) {
+ Problem problem = new ProblemImpl(BindingWSDLGenerator.class.getName(), "wsdlgen-validation-messages", Severity.ERROR,wsBinding, message, (Object[])messageParameters);
+ throw new WSDLGenerationException(problem.toString(), null, problem);
+ }
+
+ /**
+ * Report a fatal exception error.
+ * @param message
+ * @param binding
+ * @param exception
+ */
+ private static void fatal(Monitor monitor, String message, WebServiceBinding wsBinding, Exception ex) {
+ Problem problem = new ProblemImpl(BindingWSDLGenerator.class.getName(), "wsdlgen-validation-messages", Severity.ERROR, wsBinding, message, ex);
+ throw new WSDLGenerationException(problem.toString(), ex, problem);
+ }
+
+ /**
+ * This method can be called from the binding builder or from the runtime.
+ * Report problems and exceptions in the most appropriate way for both
+ * of these cases.
+ */
+ public static void generateWSDL(Component component,
+ AbstractContract contract,
+ WebServiceBinding wsBinding,
+ ExtensionPointRegistry extensionPoints,
+ Monitor monitor) {
+ try {
+ createWSDLDocument(component, contract, wsBinding, extensionPoints, monitor);
+ } catch (WSDLGenerationException ex) {
+ if (ex.getProblem() != null) {
+ warning(monitor, "WsdlGenProblem", wsBinding, component.getName(), contract.getName());
+ if (monitor != null) {
+ monitor.problem(ex.getProblem());
+ } else {
+ throw ex;
+ }
+ } else if (ex.getCause() instanceof Exception) {
+ warning(monitor, "WsdlGenException", wsBinding, component.getName(), contract.getName());
+ error(monitor, "UnexpectedException", wsBinding, (Exception)ex.getCause());
+ } else { // should never happen
+ throw new IllegalStateException(ex);
+ }
+ } catch (RuntimeException ex) {
+ warning(monitor, "WsdlGenException", wsBinding, component.getName(), contract.getName());
+ error(monitor, "UnexpectedException", wsBinding, ex);
+ }
+ }
+
+ private static void createWSDLDocument(Component component,
+ AbstractContract contract,
+ WebServiceBinding wsBinding,
+ ExtensionPointRegistry extensionPoints,
+ Monitor monitor) {
+ ModelFactoryExtensionPoint modelFactories = extensionPoints.getExtensionPoint(ModelFactoryExtensionPoint.class);
+ DataBindingExtensionPoint dataBindings = extensionPoints.getExtensionPoint(DataBindingExtensionPoint.class);
+ WSDLFactory wsdlFactory = modelFactories.getFactory(WSDLFactory.class);
+ XSDFactory xsdFactory = modelFactories.getFactory(XSDFactory.class);
+
+ if (((Contract)contract).getInterfaceContract(wsBinding) == null) {
+ // can happen if incorrect component service name
+ fatal(monitor, "MissingInterfaceContract", wsBinding, component.getName(), contract.getName());
+ }
+
+ InterfaceContract icontract = wsBinding.getBindingInterfaceContract();
+ if (icontract == null) {
+ icontract = ((Contract)contract).getInterfaceContract(wsBinding).makeUnidirectional(false);
+ if (icontract instanceof JavaInterfaceContract) {
+ ModelResolver resolver = component instanceof ResolverExtension ?
+ ((ResolverExtension)component).getModelResolver() : null;
+ icontract = createWSDLInterfaceContract(
+ (JavaInterfaceContract)icontract,
+ requiresSOAP12(wsBinding),
+ resolver,
+ dataBindings,
+ wsdlFactory,
+ xsdFactory,
+ monitor);
+ } else {
+ try {
+ //TUSCANY-2316 Cloning the Interface Contract to avoid overriding data binding information
+ icontract = (InterfaceContract)icontract.clone();
+ } catch (Exception e) {
+ //ignore
+ }
+ }
+ wsBinding.setBindingInterfaceContract(icontract);
+ }
+
+ // TODO - fix up the conversational flag and operation sequences in case the contract has come from WSDL
+ // as we don't yet support requires="conversational" or sca:endConversation annotations
+ // in WSDL interface descriptions (see section 1.5.4 of the Assembly Specification V1.0)
+ if (contract.getInterfaceContract().getInterface() != null ) {
+ icontract.getInterface().setConversational(contract.getInterfaceContract().getInterface().isConversational());
+
+ for (Operation operation : icontract.getInterface().getOperations()){
+ Operation serviceOperation = null;
+
+ for (Operation tmpOp : contract.getInterfaceContract().getInterface().getOperations()){
+ if (operation.getName().equals(tmpOp.getName())) {
+ serviceOperation = tmpOp;
+ break;
+ }
+ }
+
+ if (serviceOperation != null ){
+ operation.setConversationSequence(serviceOperation.getConversationSequence());
+ }
+ }
+ }
+
+ /*
+ // Look at all the Web Service bindings of the SCA service to see if any
+ // of them have an existing generated WSDL definitions document. If found,
+ // use it for this binding as well. If not found, generate a new document.
+ Definition definition = null;
+ for (Binding binding : contract.getBindings()) {
+ if (binding instanceof WebServiceBinding) {
+ definition = ((WebServiceBinding)binding).getWSDLDocument();
+ if (definition != null) {
+ wsBinding.setWSDLDocument(definition);
+ break;
+ }
+ }
+ }
+ */
+ // The above code is currently not used. Instead, we only look
+ // for a WSDL definitions document in this binding and don't
+ // attempt to share the same document across multiple bindings.
+
+ // generate a WSDL definitions document if needed
+ Definition definition = wsBinding.getWSDLDocument();
+ if (definition == null) {
+ definition = WSDLServiceGenerator.configureWSDLDefinition(wsBinding, component, contract, monitor);
+ wsBinding.setWSDLDocument(definition);
+ }
+ }
+
+ protected static boolean requiresSOAP12(WebServiceBinding wsBinding) {
+ if (wsBinding instanceof IntentAttachPoint) {
+ List<Intent> intents = ((IntentAttachPoint)wsBinding).getRequiredIntents();
+ for (Intent intent : intents) {
+ if (SOAP12_INTENT.equals(intent.getName())) {
+ return true;
+ }
+ }
+ }
+ return false;
+ }
+
+ /**
+ * Create a WSDLInterfaceContract from a JavaInterfaceContract
+ */
+ protected static WSDLInterfaceContract createWSDLInterfaceContract(JavaInterfaceContract contract,
+ boolean requiresSOAP12,
+ ModelResolver resolver,
+ DataBindingExtensionPoint dataBindings,
+ WSDLFactory wsdlFactory,
+ XSDFactory xsdFactory,
+ Monitor monitor) {
+
+ WSDLInterfaceContract wsdlContract = wsdlFactory.createWSDLInterfaceContract();
+ WSDLInterface wsdlInterface = wsdlFactory.createWSDLInterface();
+ wsdlContract.setInterface(wsdlInterface);
+
+ WSDLDefinition wsdlDefinition = wsdlFactory.createWSDLDefinition();
+ JavaInterface iface = (JavaInterface)contract.getInterface();
+
+ Definition def = null;
+ try {
+ Interface2WSDLGenerator wsdlGenerator =
+ new Interface2WSDLGenerator(requiresSOAP12, resolver, dataBindings, xsdFactory, monitor);
+ def = wsdlGenerator.generate(iface, wsdlDefinition);
+ } catch (WSDLException e) {
+ throw new WSDLGenerationException(e);
+ }
+
+ // for debugging
+ if (printWSDL) {
+ try {
+ System.out.println("Generated WSDL for Java interface " + iface.getName() + " class " + iface.getJavaClass().getName());
+ WSDLWriter writer = javax.wsdl.factory.WSDLFactory.newInstance().newWSDLWriter();
+ writer.writeWSDL(def, System.out);
+ } catch (WSDLException e) {
+ throw new WSDLGenerationException(e);
+ }
+ }
+
+ wsdlDefinition.setDefinition(def);
+ wsdlInterface.setWsdlDefinition(wsdlDefinition);
+ wsdlInterface.setRemotable(true);
+ wsdlInterface.setConversational(contract.getInterface().isConversational());
+ wsdlInterface.setUnresolved(false);
+ wsdlInterface.setRemotable(true);
+ PortType portType = (PortType)def.getAllPortTypes().values().iterator().next();
+ wsdlInterface.setPortType(portType);
+
+ try {
+ for (Operation op : iface.getOperations()) {
+ javax.wsdl.Operation wsdlOp = portType.getOperation(op.getName(), null, null);
+ wsdlInterface.getOperations().add(WSDLInterfaceIntrospectorImpl.getOperation(
+ wsdlOp, wsdlDefinition, resolver, xsdFactory));
+ }
+ } catch (InvalidWSDLException e) {
+ throw new WSDLGenerationException(e);
+ }
+
+ return wsdlContract;
+ }
+
+}
diff --git a/sca-java-1.x/branches/sca-java-1.5/modules/binding-ws-wsdlgen/src/main/java/org/apache/tuscany/sca/binding/ws/wsdlgen/Interface2WSDLGenerator.java b/sca-java-1.x/branches/sca-java-1.5/modules/binding-ws-wsdlgen/src/main/java/org/apache/tuscany/sca/binding/ws/wsdlgen/Interface2WSDLGenerator.java
new file mode 100644
index 0000000000..7f1d07618f
--- /dev/null
+++ b/sca-java-1.x/branches/sca-java-1.5/modules/binding-ws-wsdlgen/src/main/java/org/apache/tuscany/sca/binding/ws/wsdlgen/Interface2WSDLGenerator.java
@@ -0,0 +1,844 @@
+/*
+ * 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, false);
+ 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 inputWrapper = op.getInputWrapper();
+ DataType dt1 = null;
+ boolean useInputWrapper = useWrapper & inputWrapper != null;
+ if (useInputWrapper) {
+ dt1 = inputWrapper.getWrapperType();
+ 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;
+ WrapperInfo outputWrapper = op.getOutputWrapper();
+ boolean useOutputWrapper = useWrapper & outputWrapper != null;
+ if (useOutputWrapper) {
+ dt2 = outputWrapper.getWrapperType();
+ 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.isInputWrapperStyle() && op.getInputWrapper() == 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 (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);
+ }
+ }
+ }
+ }
+
+ // 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.getInputWrapper() != 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.getOutputWrapper() != 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 inputWrapperInfo = operation.getInputWrapper();
+ WrapperInfo outputWrapperInfo = operation.getOutputWrapper();
+ if ((inputWrapperInfo != null) && (outputWrapperInfo != null)) {
+ ElementInfo elementInfo =
+ input ? inputWrapperInfo.getWrapperElement() : outputWrapperInfo.getWrapperElement();
+ List<ElementInfo> elements =
+ input ? inputWrapperInfo.getChildElements() : outputWrapperInfo.getChildElements();
+ 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;
+ }
+
+}
diff --git a/sca-java-1.x/branches/sca-java-1.5/modules/binding-ws-wsdlgen/src/main/java/org/apache/tuscany/sca/binding/ws/wsdlgen/WSDLDefinitionGenerator.java b/sca-java-1.x/branches/sca-java-1.5/modules/binding-ws-wsdlgen/src/main/java/org/apache/tuscany/sca/binding/ws/wsdlgen/WSDLDefinitionGenerator.java
new file mode 100644
index 0000000000..989a12d43c
--- /dev/null
+++ b/sca-java-1.x/branches/sca-java-1.5/modules/binding-ws-wsdlgen/src/main/java/org/apache/tuscany/sca/binding/ws/wsdlgen/WSDLDefinitionGenerator.java
@@ -0,0 +1,316 @@
+/*
+ * 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.util.Iterator;
+
+import javax.wsdl.Binding;
+import javax.wsdl.BindingFault;
+import javax.wsdl.BindingInput;
+import javax.wsdl.BindingOperation;
+import javax.wsdl.BindingOutput;
+import javax.wsdl.Definition;
+import javax.wsdl.Fault;
+import javax.wsdl.Input;
+import javax.wsdl.Operation;
+import javax.wsdl.Output;
+import javax.wsdl.Port;
+import javax.wsdl.PortType;
+import javax.wsdl.Service;
+import javax.wsdl.Types;
+import javax.wsdl.WSDLException;
+import javax.wsdl.extensions.ExtensibilityElement;
+import javax.wsdl.extensions.soap.SOAPAddress;
+import javax.wsdl.extensions.soap.SOAPBinding;
+import javax.wsdl.extensions.soap.SOAPBody;
+import javax.wsdl.extensions.soap.SOAPFault;
+import javax.wsdl.extensions.soap.SOAPOperation;
+import javax.wsdl.extensions.soap12.SOAP12Address;
+import javax.wsdl.extensions.soap12.SOAP12Binding;
+import javax.wsdl.extensions.soap12.SOAP12Body;
+import javax.wsdl.extensions.soap12.SOAP12Fault;
+import javax.wsdl.extensions.soap12.SOAP12Operation;
+import javax.wsdl.factory.WSDLFactory;
+import javax.wsdl.xml.WSDLReader;
+import javax.xml.namespace.QName;
+
+import org.w3c.dom.Element;
+
+/**
+ *
+ * @version $Rev: 668025 $ $Date: 2008-06-16 01:06:34 +0100 (Mon, 16 Jun 2008) $
+ */
+public class WSDLDefinitionGenerator {
+ private static final String SOAP_NS = "http://schemas.xmlsoap.org/wsdl/soap/";
+ public static final QName SOAP_ADDRESS = new QName(SOAP_NS, "address");
+ private static final QName SOAP_BINDING = new QName(SOAP_NS, "binding");
+ private static final QName SOAP_BODY = new QName(SOAP_NS, "body");
+ private static final QName SOAP_FAULT = new QName(SOAP_NS, "fault");
+ private static final QName SOAP_OPERATION = new QName(SOAP_NS, "operation");
+ private static final String SOAP12_NS = "http://schemas.xmlsoap.org/wsdl/soap12/";
+ public static final QName SOAP12_ADDRESS = new QName(SOAP12_NS, "address");
+ private static final QName SOAP12_BINDING = new QName(SOAP12_NS, "binding");
+ private static final QName SOAP12_BODY = new QName(SOAP12_NS, "body");
+ private static final QName SOAP12_FAULT = new QName(SOAP12_NS, "fault");
+ private static final QName SOAP12_OPERATION = new QName(SOAP12_NS, "operation");
+
+ private static final String BINDING_SUFFIX = "Binding";
+ private static final String SERVICE_SUFFIX = "Service";
+ private static final String PORT_SUFFIX = "Port";
+
+ private boolean requiresSOAP12;
+ private boolean requiresJMS;
+ private QName soapAddress;
+ private QName soapBinding;
+ private QName soapBody;
+ private QName soapFault;
+ private QName soapOperation;
+
+ public WSDLDefinitionGenerator(boolean requiresSOAP12, boolean requiresJMS) {
+ super();
+ this.requiresSOAP12 = requiresSOAP12;
+ this.requiresJMS = requiresJMS;
+ soapAddress = requiresSOAP12 ? SOAP12_ADDRESS : SOAP_ADDRESS;
+ soapBinding = requiresSOAP12 ? SOAP12_BINDING : SOAP_BINDING;
+ soapBody = requiresSOAP12 ? SOAP12_BODY : SOAP_BODY;
+ soapFault = requiresSOAP12 ? SOAP12_FAULT : SOAP_FAULT;
+ soapOperation = requiresSOAP12 ? SOAP12_OPERATION : SOAP_OPERATION;
+ }
+
+ public Definition cloneDefinition(WSDLFactory factory, Definition definition) throws WSDLException {
+ Element root = definition.getDocumentationElement();
+ root = (Element)root.cloneNode(true);
+ WSDLReader reader = factory.newWSDLReader();
+ return reader.readWSDL(definition.getDocumentBaseURI(), root);
+ }
+
+ public Types createTypes(Definition definition) {
+ Types types = definition.createTypes();
+ definition.setTypes(types);
+ return types;
+ }
+
+ public Binding createBinding(Definition definition, PortType portType) {
+ try {
+ Binding binding = definition.createBinding();
+ binding.setPortType(portType);
+ configureBinding(definition, binding, portType);
+ ExtensibilityElement bindingExtension =
+ definition.getExtensionRegistry().createExtension(Binding.class, soapBinding);
+ if (requiresSOAP12) {
+ ((SOAP12Binding)bindingExtension).setStyle("document");
+ if (requiresJMS){
+ ((SOAP12Binding)bindingExtension).setTransportURI("http://schemas.xmlsoap.org/soap/jms");
+ } else {
+ ((SOAP12Binding)bindingExtension).setTransportURI("http://schemas.xmlsoap.org/soap/http");
+ }
+ } else {
+ ((SOAPBinding)bindingExtension).setStyle("document");
+ if (requiresJMS){
+ ((SOAPBinding)bindingExtension).setTransportURI("http://schemas.xmlsoap.org/soap/jms");
+ } else {
+ ((SOAPBinding)bindingExtension).setTransportURI("http://schemas.xmlsoap.org/soap/http");
+ }
+ }
+ binding.addExtensibilityElement(bindingExtension);
+ return binding;
+ } catch (WSDLException e) {
+ throw new WSDLGenerationException(e);
+ }
+ }
+
+
+ protected void configureBinding(Definition definition, Binding binding, PortType portType) throws WSDLException {
+ QName portTypeName = portType.getQName();
+ if (portTypeName != null) {
+ // Choose <porttype>Binding if available. If this name is in use, insert
+ // separating underscores until there is no clash.
+ for (String suffix = BINDING_SUFFIX; ; suffix = "_" + suffix) {
+ QName name = new QName(definition.getTargetNamespace(), portTypeName.getLocalPart() + suffix);
+ if (definition.getBinding(name) == null) {
+ binding.setQName(name);
+ break;
+ }
+ }
+ }
+ }
+
+ @SuppressWarnings("unchecked")
+ public void createBindingOperations(Definition definition, Binding binding, PortType portType) {
+ try {
+ for (Iterator oi = portType.getOperations().iterator(); oi.hasNext();) {
+ Operation operation = (Operation)oi.next();
+ BindingOperation bindingOperation =
+ createBindingOperation(definition, operation, "urn:" + operation.getName());
+ binding.addBindingOperation(bindingOperation);
+ }
+ } catch (WSDLException e) {
+ throw new WSDLGenerationException(e);
+ }
+ }
+
+ @SuppressWarnings("unchecked")
+ public BindingOperation createBindingOperation(Definition definition, Operation operation, String action)
+ throws WSDLException {
+ BindingOperation bindingOperation = definition.createBindingOperation();
+ bindingOperation.setOperation(operation);
+ configureBindingOperation(bindingOperation, operation);
+ ExtensibilityElement operationExtension =
+ definition.getExtensionRegistry().createExtension(BindingOperation.class, soapOperation);
+ if (requiresSOAP12) {
+ ((SOAP12Operation)operationExtension).setSoapActionURI(action);
+ } else {
+ ((SOAPOperation)operationExtension).setSoapActionURI(action);
+ }
+ bindingOperation.addExtensibilityElement(operationExtension);
+ if (operation.getInput() != null) {
+ BindingInput bindingInput = definition.createBindingInput();
+ configureBindingInput(bindingInput, operation.getInput());
+ ExtensibilityElement inputExtension =
+ definition.getExtensionRegistry().createExtension(BindingInput.class, soapBody);
+ if (requiresSOAP12) {
+ ((SOAP12Body)inputExtension).setUse("literal");
+ } else {
+ ((SOAPBody)inputExtension).setUse("literal");
+ }
+ bindingInput.addExtensibilityElement(inputExtension);
+ bindingOperation.setBindingInput(bindingInput);
+ }
+ if (operation.getOutput() != null) {
+ BindingOutput bindingOutput = definition.createBindingOutput();
+ configureBindingOutput(bindingOutput, operation.getOutput());
+ ExtensibilityElement outputExtension =
+ definition.getExtensionRegistry().createExtension(BindingOutput.class, soapBody);
+ if (requiresSOAP12) {
+ ((SOAP12Body)outputExtension).setUse("literal");
+ } else {
+ ((SOAPBody)outputExtension).setUse("literal");
+ }
+ bindingOutput.addExtensibilityElement(outputExtension);
+ bindingOperation.setBindingOutput(bindingOutput);
+ }
+ for (Iterator fi = operation.getFaults().values().iterator(); fi.hasNext();) {
+ Fault fault = (Fault)fi.next();
+ BindingFault bindingFault = definition.createBindingFault();
+ ExtensibilityElement faultExtension =
+ definition.getExtensionRegistry().createExtension(BindingFault.class, soapFault);
+ configureBindingFault(bindingFault, faultExtension, fault);
+ bindingFault.addExtensibilityElement(faultExtension);
+ bindingOperation.addBindingFault(bindingFault);
+ }
+ return bindingOperation;
+ }
+
+ protected void configureBindingOperation(BindingOperation bindingOperation, Operation operation)
+ throws WSDLException {
+ bindingOperation.setName(operation.getName());
+ }
+
+ protected void configureBindingInput(BindingInput bindingInput, Input input) throws WSDLException {
+ bindingInput.setName(input.getName());
+ }
+
+ protected void configureBindingOutput(BindingOutput bindingOutput, Output output) throws WSDLException {
+ bindingOutput.setName(output.getName());
+ }
+
+ protected void configureBindingFault(BindingFault bindingFault,
+ ExtensibilityElement faultExtension,
+ Fault fault)
+ throws WSDLException {
+ String faultName = fault.getName();
+ bindingFault.setName(faultName);
+ if (requiresSOAP12) {
+ ((SOAP12Fault)faultExtension).setName(faultName);
+ ((SOAP12Fault)faultExtension).setUse("literal");
+ } else {
+ ((SOAPFault)faultExtension).setName(faultName);
+ ((SOAPFault)faultExtension).setUse("literal");
+ }
+ }
+
+ public Service createService(Definition definition, PortType portType) {
+ try {
+ Service service = definition.createService();
+ configureService(definition, service, portType);
+ // createPort(definition, binding, service);
+ definition.addService(service);
+ return service;
+ } catch (WSDLException e) {
+ throw new WSDLGenerationException(e);
+ }
+ }
+
+ public Service createService(Definition definition, Binding binding) {
+ try {
+ Service service = definition.createService();
+ configureService(definition, service, binding.getPortType());
+ // createPort(definition, binding, service);
+ definition.addService(service);
+ return service;
+ } catch (WSDLException e) {
+ throw new WSDLGenerationException(e);
+ }
+ }
+
+ protected void configureService(Definition definition, Service service, PortType portType) throws WSDLException {
+ QName portTypeName = portType.getQName();
+ if (portTypeName != null) {
+ // Choose <porttype>Service if available. If this name is in use, insert
+ // separating underscores until there is no clash.
+ for (String suffix = SERVICE_SUFFIX; ; suffix = "_" + suffix) {
+ QName name = new QName(definition.getTargetNamespace(), portTypeName.getLocalPart() + suffix);
+ if (definition.getService(name) == null) {
+ service.setQName(name);
+ break;
+ }
+ }
+ }
+ }
+
+ public Port createPort(Definition definition, Binding binding, Service service, String uri) {
+ try {
+ Port port = definition.createPort();
+ port.setBinding(binding);
+ configurePort(port, binding);
+ if (uri != null) {
+ ExtensibilityElement portExtension =
+ definition.getExtensionRegistry().createExtension(Port.class, soapAddress);
+ if (requiresSOAP12) {
+ ((SOAP12Address)portExtension).setLocationURI(uri);
+ } else {
+ ((SOAPAddress)portExtension).setLocationURI(uri);
+ }
+ port.addExtensibilityElement(portExtension);
+ }
+ service.addPort(port);
+ return port;
+ } catch (WSDLException e) {
+ throw new WSDLGenerationException(e);
+ }
+ }
+
+ protected void configurePort(Port port, Binding binding) throws WSDLException {
+ if (binding.getPortType() != null && binding.getPortType().getQName() != null) {
+ port.setName(binding.getPortType().getQName().getLocalPart() + PORT_SUFFIX);
+ }
+ }
+
+}
diff --git a/sca-java-1.x/branches/sca-java-1.5/modules/binding-ws-wsdlgen/src/main/java/org/apache/tuscany/sca/binding/ws/wsdlgen/WSDLGenerationException.java b/sca-java-1.x/branches/sca-java-1.5/modules/binding-ws-wsdlgen/src/main/java/org/apache/tuscany/sca/binding/ws/wsdlgen/WSDLGenerationException.java
new file mode 100644
index 0000000000..bf9e22f645
--- /dev/null
+++ b/sca-java-1.x/branches/sca-java-1.5/modules/binding-ws-wsdlgen/src/main/java/org/apache/tuscany/sca/binding/ws/wsdlgen/WSDLGenerationException.java
@@ -0,0 +1,54 @@
+/*
+ * 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 org.apache.tuscany.sca.monitor.Problem;
+import org.osoa.sca.ServiceRuntimeException;
+
+public class WSDLGenerationException extends ServiceRuntimeException {
+ private static final long serialVersionUID = 1L;
+ private Problem problem;
+
+ public WSDLGenerationException() {
+ super();
+ }
+
+ public WSDLGenerationException(String message, Throwable cause) {
+ super(message, cause);
+ }
+
+ public WSDLGenerationException(String message) {
+ super(message);
+ }
+
+ public WSDLGenerationException(Throwable cause) {
+ super(cause);
+ }
+
+ public WSDLGenerationException(String message, Throwable cause, Problem problem) {
+ super(message, cause);
+ this.problem = problem;
+ }
+
+ public Problem getProblem() {
+ return problem;
+ }
+
+}
diff --git a/sca-java-1.x/branches/sca-java-1.5/modules/binding-ws-wsdlgen/src/main/java/org/apache/tuscany/sca/binding/ws/wsdlgen/WSDLServiceGenerator.java b/sca-java-1.x/branches/sca-java-1.5/modules/binding-ws-wsdlgen/src/main/java/org/apache/tuscany/sca/binding/ws/wsdlgen/WSDLServiceGenerator.java
new file mode 100644
index 0000000000..1fbf834e86
--- /dev/null
+++ b/sca-java-1.x/branches/sca-java-1.5/modules/binding-ws-wsdlgen/src/main/java/org/apache/tuscany/sca/binding/ws/wsdlgen/WSDLServiceGenerator.java
@@ -0,0 +1,542 @@
+/*
+ * 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;
+
+//FIXME: trim the import list down to what's really needed
+
+
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.util.ArrayList;
+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.Definition;
+import javax.wsdl.Import;
+import javax.wsdl.Port;
+import javax.wsdl.PortType;
+import javax.wsdl.Service;
+import javax.wsdl.WSDLException;
+import javax.wsdl.extensions.ExtensibilityElement;
+import javax.wsdl.extensions.soap.SOAPAddress;
+import javax.wsdl.extensions.soap.SOAPBinding;
+import javax.wsdl.extensions.soap12.SOAP12Address;
+import javax.wsdl.extensions.soap12.SOAP12Binding;
+import javax.wsdl.factory.WSDLFactory;
+import javax.wsdl.xml.WSDLWriter;
+import javax.xml.namespace.QName;
+
+import org.apache.tuscany.sca.assembly.AbstractContract;
+import org.apache.tuscany.sca.assembly.Component;
+import org.apache.tuscany.sca.assembly.CompositeService;
+import org.apache.tuscany.sca.assembly.builder.impl.ProblemImpl;
+import org.apache.tuscany.sca.binding.ws.WebServiceBinding;
+import org.apache.tuscany.sca.interfacedef.Interface;
+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.w3c.dom.Element;
+import org.w3c.dom.Node;
+import org.w3c.dom.NodeList;
+import org.w3c.dom.Text;
+
+/**
+ * WSDLServiceGenerator generates a binding WSDL service document.
+ *
+ * @version $Rev$ $Date$
+ */
+public class WSDLServiceGenerator {
+ // the following switch is temporary for debugging
+ public static boolean printWSDL; // external code sets this to print generated WSDL
+
+ private static final Logger logger = Logger.getLogger(WSDLServiceGenerator.class.getName());
+ private static final QName TRANSPORT_JMS_QUALIFIED_INTENT =
+ new QName("http://www.osoa.org/xmlns/sca/1.0", "transport.jms");
+ private static final String DEFAULT_QUEUE_CONNECTION_FACTORY = "TuscanyQueueConnectionFactory";
+ private static final String ADDRESS = "Address";
+
+ private WSDLServiceGenerator() {
+ // this class has static methods only and cannot be instantiated
+ }
+
+ /**
+ * 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 static void warning(Monitor monitor, String message, WebServiceBinding wsBinding, String... messageParameters) {
+ Problem problem = new ProblemImpl(WSDLServiceGenerator.class.getName(), "wsdlgen-validation-messages", Severity.WARNING, wsBinding, message, (Object[])messageParameters);
+ if (monitor != null) {
+ monitor.problem(problem);
+ } else {
+ logWarning(problem);
+ }
+ }
+
+ /**
+ * Report an error.
+ * @param message
+ * @param binding
+ * @param parameters
+ */
+ private static void error(Monitor monitor, String message, WebServiceBinding wsBinding, String... messageParameters) {
+ Problem problem = new ProblemImpl(WSDLServiceGenerator.class.getName(), "wsdlgen-validation-messages", Severity.ERROR, wsBinding, message, (Object[])messageParameters);
+ if (monitor != null) {
+ monitor.problem(problem);
+ } else {
+ throw new WSDLGenerationException(problem.toString(), null, problem);
+ }
+ }
+
+ /**
+ * Generate a suitably configured WSDL definition
+ */
+ protected static Definition configureWSDLDefinition(WebServiceBinding wsBinding,
+ Component component,
+ AbstractContract contract,
+ Monitor monitor) {
+
+ //[nash] changes to the builder sequence avoid calling this for a CompositeService
+ assert !(contract instanceof CompositeService);
+ /*
+ // For every promoted composite service, the underlying component
+ // gets a copy of the service with the name prefixed by "$promoted$."
+ String contractName = (contract instanceof CompositeService ? "$promoted$." : "") + contract.getName();
+ */
+ String contractName = contract.getName();
+
+ List<Port> ports = new ArrayList<Port>();
+ WSDLDefinition wsdlDefinition = wsBinding.getWSDLDefinition();
+ if (wsdlDefinition == null) {
+ error(monitor, "NoWsdlInterface", wsBinding, component.getName(), contract.getName());
+ return null;
+ }
+ Definition def = wsdlDefinition.getDefinition();
+
+ boolean wsdlProvidedByUser = (wsdlDefinition.getBinding() == null);
+
+ if (wsdlProvidedByUser) {
+ // The WSDL document was provided by the user. Generate a new
+ // WSDL document with imports from the user-provided document.
+ WSDLFactory factory = null;
+ try {
+ factory = WSDLFactory.newInstance();
+ } catch (WSDLException e) {
+ throw new WSDLGenerationException(e);
+ }
+ Definition newDef = factory.newDefinition();
+
+ // Construct a target namespace from the base URI of the user's
+ // WSDL document (is this what we should be using?) and a path
+ // computed according to the SCA Web Service binding spec.
+ String nsName = component.getName() + "/" + contractName;
+ String namespaceURI = null;
+ try {
+ URI userTNS = new URI(def.getTargetNamespace());
+ namespaceURI = userTNS.resolve("/" + nsName).toString();
+ } catch (URISyntaxException e1) {
+ throw new WSDLGenerationException(e1);
+ } catch (IllegalArgumentException e2) {
+ throw new WSDLGenerationException(e2);
+ }
+
+ // set name and targetNamespace attributes on the definition
+ String defsName = component.getName() + "." + contractName;
+ newDef.setQName(new QName(namespaceURI, defsName));
+ newDef.setTargetNamespace(namespaceURI);
+ newDef.addNamespace("tns", namespaceURI);
+
+ // set wsdl namespace prefix on the definition
+ newDef.addNamespace("wsdl", "http://schemas.xmlsoap.org/wsdl/");
+
+ // import the service or reference interface portType
+ List<WSDLDefinition> imports = new ArrayList<WSDLDefinition>();
+ Interface interfaze = wsBinding.getBindingInterfaceContract().getInterface();
+ if (interfaze instanceof WSDLInterface) {
+ PortType portType = ((WSDLInterface)interfaze).getPortType();
+ boolean ok = importPortType(portType, wsdlDefinition, newDef, imports);
+ if (!ok) {
+ error(monitor, "PortTypeNotFound", wsBinding, portType.getQName().toString(),
+ component.getName(), contract.getName());
+ }
+ }
+
+ // import an existing binding if specified
+ Binding binding = wsBinding.getBinding();
+ if (binding != null) {
+ boolean ok = importBinding(binding, wsdlDefinition, newDef, imports);
+ if (ok) {
+ boolean ok2 = importPortType(binding.getPortType(), wsdlDefinition, newDef, imports);
+ if (!ok2) {
+ error(monitor, "PortTypeNotFound", wsBinding, binding.getPortType().getQName().toString(),
+ component.getName(), contract.getName());
+ }
+ } else {
+ error(monitor, "BindingNotFound", wsBinding, binding.getQName().toString(),
+ component.getName(), contract.getName());
+ }
+ }
+
+ // import bindings and portTypes needed by services and ports
+ QName serviceQName = wsBinding.getServiceName();
+ String portName = wsBinding.getPortName();
+ if (serviceQName != null) {
+ Service service = def.getService(serviceQName);
+ if (portName != null) {
+ Port port = service.getPort(portName);
+ Port newPort = copyPort(newDef, port, wsBinding);
+ if (newPort != null) {
+ importBinding(port.getBinding(), wsdlDefinition, newDef, imports);
+ ports.add(newPort);
+ } else {
+ error(monitor, "InvalidPort", wsBinding, serviceQName.toString(), portName,
+ component.getName(), contract.getName());
+ }
+ } else {
+ for (Object port : service.getPorts().values()) {
+ Port newPort = copyPort(newDef, (Port)port, wsBinding);
+ if (newPort != null) {
+ importBinding(((Port)port).getBinding(), wsdlDefinition, newDef, imports);
+ ports.add(newPort);
+ } else {
+ // not an error, just ignore the port
+ warning(monitor, "IgnoringPort", wsBinding, serviceQName.toString(), ((Port)port).getName(),
+ component.getName(), contract.getName());
+ }
+ }
+ if (ports.size() == 0) {
+ error(monitor, "NoValidPorts", wsBinding, serviceQName.toString(),
+ component.getName(), contract.getName());
+ }
+ }
+ }
+
+ // replace original WSDL definition by the generated definition
+ def = newDef;
+
+ } else {
+ // The WSDL definition was generated by Interface2WSDLGenerator.
+ // Reuse it instead of creating a new definition here.
+ }
+
+ // add a service and ports to the generated definition
+ WSDLDefinitionGenerator helper =
+ new WSDLDefinitionGenerator(BindingWSDLGenerator.requiresSOAP12(wsBinding),false);
+ WSDLInterface wi = (WSDLInterface)wsBinding.getBindingInterfaceContract().getInterface();
+ PortType portType = wi.getPortType();
+ Service service = helper.createService(def, portType);
+ if (wsBinding.getBinding() == null && ports.size() == 0) {
+ Binding binding = helper.createBinding(def, portType);
+ if (BindingWSDLGenerator.requiresSOAP12(wsBinding)) {
+ def.addNamespace("SOAP12", "http://schemas.xmlsoap.org/wsdl/soap12/");
+ } else {
+ def.addNamespace("SOAP11", "http://schemas.xmlsoap.org/wsdl/soap/");
+ }
+ helper.createBindingOperations(def, binding, portType);
+ binding.setUndefined(false);
+ def.addBinding(binding);
+
+ String endpointURI = computeActualURI(wsBinding, null);
+ Port port = helper.createPort(def, binding, service, endpointURI);
+ wsBinding.setService(service);
+ wsBinding.setPort(port);
+ } else {
+ if (ports.size() > 0) {
+ // there are one or more user-specified valid ports
+ for (Port port : ports) {
+ service.addPort(port);
+ }
+ if (ports.size() == 1) {
+ // only one port, so use it
+ wsBinding.setPort(ports.get(0));
+ } else {
+ // multiple ports, make them all available
+ wsBinding.setPort(null);
+ }
+ } else {
+ // no valid user-specified ports, so create a suitably configured port
+ String endpointURI = computeActualURI(wsBinding, null);
+ Port port = helper.createPort(def, wsBinding.getBinding(), service, endpointURI);
+ if (BindingWSDLGenerator.requiresSOAP12(wsBinding)) {
+ def.addNamespace("SOAP12", "http://schemas.xmlsoap.org/wsdl/soap12/");
+ } else {
+ def.addNamespace("SOAP11", "http://schemas.xmlsoap.org/wsdl/soap/");
+ }
+ wsBinding.setPort(port);
+ }
+ wsBinding.setService(service);
+ }
+
+ // TUSCANY-2900 - add jms binding and service port if required
+ // TODO - remove service/ports from any imported WSDL
+ // - find away to allow users to retrieve WSDL with JMS bindings
+ // as a jms binding on it's own provides not target for ?wsdl
+ if ((!wsdlProvidedByUser) &&
+ (wsBinding.getURI() != null) &&
+ (wsBinding.getURI().startsWith("jms"))){
+
+ // need to work out how to check if user has already specified a binding
+
+ // create jms binding
+ helper = new WSDLDefinitionGenerator(BindingWSDLGenerator.requiresSOAP12(wsBinding),true);
+ Binding binding = helper.createBinding(def, portType);
+ helper.createBindingOperations(def, binding, portType);
+ binding.setUndefined(false);
+ def.addBinding(binding);
+
+ // create a jms port
+ String endpointURI = computeActualURI(wsBinding, null);
+ Port port = helper.createPort(def, binding, service, endpointURI);
+ wsBinding.setService(service);
+ wsBinding.setPort(port);
+
+ //printWSDL = true;
+ }
+
+ // for debugging
+ if (printWSDL) {
+ try {
+ System.out.println("Generated WSDL for " + component.getName() + "/" + contractName);
+ WSDLWriter writer = javax.wsdl.factory.WSDLFactory.newInstance().newWSDLWriter();
+ writer.writeWSDL(def, System.out);
+ } catch (WSDLException e) {
+ throw new WSDLGenerationException(e);
+ }
+ }
+
+ return def;
+ }
+
+ private static boolean importPortType(PortType portType,
+ WSDLDefinition wsdlDef,
+ Definition newDef,
+ List<WSDLDefinition> imports) {
+ return addImport(portType.getQName(), PortType.class, wsdlDef, newDef, imports);
+ }
+
+ private static boolean importBinding(Binding binding,
+ WSDLDefinition wsdlDef,
+ Definition newDef,
+ List<WSDLDefinition> imports) {
+ boolean ok = addImport(binding.getQName(), Binding.class, wsdlDef, newDef, imports);
+ if (ok) {
+ List bindingExtensions = binding.getExtensibilityElements();
+ for (final Object extension : bindingExtensions) {
+ if (extension instanceof SOAPBinding) {
+ newDef.addNamespace("SOAP11", "http://schemas.xmlsoap.org/wsdl/soap/");
+ }
+ if (extension instanceof SOAP12Binding) {
+ newDef.addNamespace("SOAP12", "http://schemas.xmlsoap.org/wsdl/soap12/");
+ }
+ }
+ }
+ return ok;
+ }
+
+ private static boolean addImport(QName name,
+ Class type,
+ WSDLDefinition wsdlDef,
+ Definition newDef,
+ List<WSDLDefinition> imports) {
+ String namespace = name.getNamespaceURI();
+ if (newDef.getImports(namespace) == null) {
+ WSDLDefinition impDef = findDefinition(wsdlDef, name, type);
+ if (impDef != null) {
+ Import imp = newDef.createImport();
+ imp.setNamespaceURI(namespace);
+ imp.setLocationURI(impDef.getURI().toString());
+ imp.setDefinition(impDef.getDefinition());
+ newDef.addNamespace("ns" + imports.size(), namespace);
+ newDef.addImport(imp);
+ imports.add(impDef);
+ return true;
+ } else {
+ // import was not added because element not found
+ return false;
+ }
+ }
+ return true;
+ }
+
+ private static WSDLDefinition findDefinition(WSDLDefinition wsdlDef, QName name, Class type) {
+ if (wsdlDef == null || name == null) {
+ return wsdlDef;
+ }
+ if (wsdlDef.getURI() != null) { // not a facade
+ Definition def = wsdlDef.getDefinition();
+ Map types = type == PortType.class ? def.getPortTypes() : def.getBindings();
+ if (types.get(name) != null) {
+ return wsdlDef;
+ }
+ }
+ for (WSDLDefinition impDef : wsdlDef.getImportedDefinitions()) {
+ WSDLDefinition d = findDefinition(impDef, name, type);
+ if (d != null) {
+ return d;
+ }
+ }
+ return null;
+ }
+
+ private static Port copyPort(Definition def, Port port, WebServiceBinding wsBinding) {
+ Port newPort = def.createPort();
+ newPort.setName(port.getName());
+ newPort.setBinding(port.getBinding());
+ List portExtensions = port.getExtensibilityElements();
+ for (final Object extension : portExtensions) {
+ ExtensibilityElement newExt = null;
+ if (extension instanceof SOAPAddress) {
+ def.addNamespace("SOAP11", "http://schemas.xmlsoap.org/wsdl/soap/");
+ try {
+ newExt = def.getExtensionRegistry().createExtension(
+ Port.class, WSDLDefinitionGenerator.SOAP_ADDRESS);
+ } catch (WSDLException e) {
+ }
+ String uri = computeActualURI(wsBinding, port);
+ ((SOAPAddress)newExt).setLocationURI(uri);
+ newPort.addExtensibilityElement(newExt);
+ } else if (extension instanceof SOAP12Address) {
+ def.addNamespace("SOAP12", "http://schemas.xmlsoap.org/wsdl/soap12/");
+ try {
+ newExt = def.getExtensionRegistry().createExtension(
+ Port.class, WSDLDefinitionGenerator.SOAP12_ADDRESS);
+ } catch (WSDLException e) {
+ }
+ String uri = computeActualURI(wsBinding, port);
+ ((SOAP12Address)newExt).setLocationURI(uri);
+ newPort.addExtensibilityElement(newExt);
+ } else {
+ // we don't support ports with other extensibility elements such as HTTPAddress
+ return null;
+ }
+ }
+ return newPort;
+ }
+
+ /**
+ * Compute the endpoint URI based on section 2.1.1 of the WS binding Specification 1.
+ * The URIs in the endpoint(s) of the referenced WSDL, which may be relative
+ * 2. The URI specified by the wsa:Address element of the
+ * wsa:EndpointReference, which may be relative 3. The explicitly stated URI
+ * in the "uri" attribute of the binding.ws element, which may be relative,
+ * 4. The implicit URI as defined by in section 1.7 in the SCA Assembly Specification
+ * If the <binding.ws> has no wsdlElement but does have a uri attribute then
+ * the uri takes precedence over any implicitly used WSDL.
+ *
+ */
+ private static String computeActualURI(WebServiceBinding wsBinding, Port port) {
+
+ URI eprURI = null;
+ if (wsBinding.getEndPointReference() != null) {
+ eprURI = getEPR(wsBinding);
+ }
+
+ URI wsdlURI = null;
+ if (wsBinding.getServiceName() != null && wsBinding.getBindingName() == null) {
+ // <binding.ws> explicitly points at a WSDL port, may be a relative URI
+ wsdlURI = getEndpoint(port);
+ }
+
+ // if the WSDL port/endpoint has an absolute URI use that
+ if (wsdlURI != null && wsdlURI.isAbsolute()) {
+ return wsdlURI.toString();
+ }
+
+ // if the wsa:EndpointReference has an address element with an absolute URI use that
+ if (eprURI != null && eprURI.isAbsolute()) {
+ return eprURI.toString();
+ }
+
+ // either there is no WSDL port endpoint URI or that URI is relative
+ String actualURI = wsBinding.getURI();
+ if (eprURI != null && eprURI.toString().length() != 0) {
+ // there is a relative URI in the binding EPR
+ actualURI = actualURI + "/" + eprURI;
+ }
+
+ if (wsdlURI != null && wsdlURI.toString().length() != 0) {
+ // there is a relative URI in the WSDL port
+ actualURI = actualURI + "/" + wsdlURI;
+ }
+
+ if (actualURI != null) {
+ actualURI = URI.create(actualURI).normalize().toString();
+ }
+
+ return actualURI;
+ }
+
+ private static URI getEPR(WebServiceBinding wsBinding) {
+ NodeList nodeList = wsBinding.getEndPointReference().getChildNodes();
+ for (int i = 0; i < nodeList.getLength(); i++) {
+ Node childNode = nodeList.item(i);
+ if (childNode instanceof Element && ADDRESS.equals(childNode.getLocalName())) {
+ NodeList addrNodes = childNode.getChildNodes();
+ for (int j = 0; j < addrNodes.getLength(); j++) {
+ Node addrNode = addrNodes.item(j);
+ if (addrNode instanceof Text) {
+ return URI.create(((Text)addrNode).getWholeText());
+ }
+ }
+ }
+ }
+ return null;
+ }
+
+ /**
+ * Returns the endpoint of a given port.
+ */
+ private static URI getEndpoint(Port wsdlPort) {
+ if (wsdlPort != null) {
+ List<?> wsdlPortExtensions = wsdlPort.getExtensibilityElements();
+ for (Object extension : wsdlPortExtensions) {
+ if (extension instanceof SOAPAddress) {
+ String uri = ((SOAPAddress)extension).getLocationURI();
+ return (uri == null || "".equals(uri)) ? null : URI.create(uri);
+ }
+ if (extension instanceof SOAP12Address) {
+ SOAP12Address address = (SOAP12Address)extension;
+ String uri = address.getLocationURI();
+ return (uri == null || "".equals(uri)) ? null : URI.create(uri);
+ }
+ }
+ }
+ return null;
+ }
+
+}