From bdd0a41aed7edf21ec2a65cfa17a86af2ef8c48a Mon Sep 17 00:00:00 2001 From: dims Date: Tue, 17 Jun 2008 00:23:01 +0000 Subject: Move Tuscany from Incubator to top level. git-svn-id: http://svn.us.apache.org/repos/asf/tuscany@668359 13f79535-47bb-0310-9956-ffa450edef68 --- .../axis2/assembly/WebServiceAssemblyFactory.java | 31 ++ .../binding/axis2/assembly/WebServiceBinding.java | 75 ++++ .../impl/WebServiceAssemblyFactoryImpl.java | 42 ++ .../axis2/assembly/impl/WebServiceBindingImpl.java | 176 ++++++++ .../axis2/builder/ExternalWebServiceBuilder.java | 146 ++++++ .../builder/ExternalWebServiceWireBuilder.java | 36 ++ .../axis2/builder/WebServiceEntryPointBuilder.java | 49 ++ .../axis2/config/WSEntryPointContextFactory.java | 276 ++++++++++++ .../config/WSExternalServiceContextFactory.java | 34 ++ ...bServiceEntryPointInOutSyncMessageReceiver.java | 101 +++++ .../entrypoint/WebServiceEntryPointServlet.java | 113 +++++ .../externalservice/Axis2OperationInvoker.java | 114 +++++ .../axis2/externalservice/Axis2ServiceInvoker.java | 60 +++ .../axis2/loader/WebServiceBindingLoader.java | 74 +++ .../tuscany/binding/axis2/util/SDODataBinding.java | 104 +++++ .../axis2/util/TuscanyAxisConfigurator.java | 88 ++++ .../axis2/util/WebServiceOperationMetaData.java | 499 +++++++++++++++++++++ .../binding/axis2/util/WebServicePortMetaData.java | 400 +++++++++++++++++ 18 files changed, 2418 insertions(+) create mode 100644 branches/java-post-M1/sca/bindings/binding.axis2/src/main/java/org/apache/tuscany/binding/axis2/assembly/WebServiceAssemblyFactory.java create mode 100644 branches/java-post-M1/sca/bindings/binding.axis2/src/main/java/org/apache/tuscany/binding/axis2/assembly/WebServiceBinding.java create mode 100644 branches/java-post-M1/sca/bindings/binding.axis2/src/main/java/org/apache/tuscany/binding/axis2/assembly/impl/WebServiceAssemblyFactoryImpl.java create mode 100644 branches/java-post-M1/sca/bindings/binding.axis2/src/main/java/org/apache/tuscany/binding/axis2/assembly/impl/WebServiceBindingImpl.java create mode 100644 branches/java-post-M1/sca/bindings/binding.axis2/src/main/java/org/apache/tuscany/binding/axis2/builder/ExternalWebServiceBuilder.java create mode 100644 branches/java-post-M1/sca/bindings/binding.axis2/src/main/java/org/apache/tuscany/binding/axis2/builder/ExternalWebServiceWireBuilder.java create mode 100644 branches/java-post-M1/sca/bindings/binding.axis2/src/main/java/org/apache/tuscany/binding/axis2/builder/WebServiceEntryPointBuilder.java create mode 100644 branches/java-post-M1/sca/bindings/binding.axis2/src/main/java/org/apache/tuscany/binding/axis2/config/WSEntryPointContextFactory.java create mode 100644 branches/java-post-M1/sca/bindings/binding.axis2/src/main/java/org/apache/tuscany/binding/axis2/config/WSExternalServiceContextFactory.java create mode 100644 branches/java-post-M1/sca/bindings/binding.axis2/src/main/java/org/apache/tuscany/binding/axis2/entrypoint/WebServiceEntryPointInOutSyncMessageReceiver.java create mode 100644 branches/java-post-M1/sca/bindings/binding.axis2/src/main/java/org/apache/tuscany/binding/axis2/entrypoint/WebServiceEntryPointServlet.java create mode 100644 branches/java-post-M1/sca/bindings/binding.axis2/src/main/java/org/apache/tuscany/binding/axis2/externalservice/Axis2OperationInvoker.java create mode 100644 branches/java-post-M1/sca/bindings/binding.axis2/src/main/java/org/apache/tuscany/binding/axis2/externalservice/Axis2ServiceInvoker.java create mode 100644 branches/java-post-M1/sca/bindings/binding.axis2/src/main/java/org/apache/tuscany/binding/axis2/loader/WebServiceBindingLoader.java create mode 100644 branches/java-post-M1/sca/bindings/binding.axis2/src/main/java/org/apache/tuscany/binding/axis2/util/SDODataBinding.java create mode 100644 branches/java-post-M1/sca/bindings/binding.axis2/src/main/java/org/apache/tuscany/binding/axis2/util/TuscanyAxisConfigurator.java create mode 100644 branches/java-post-M1/sca/bindings/binding.axis2/src/main/java/org/apache/tuscany/binding/axis2/util/WebServiceOperationMetaData.java create mode 100644 branches/java-post-M1/sca/bindings/binding.axis2/src/main/java/org/apache/tuscany/binding/axis2/util/WebServicePortMetaData.java (limited to 'branches/java-post-M1/sca/bindings/binding.axis2/src/main/java/org/apache/tuscany/binding') diff --git a/branches/java-post-M1/sca/bindings/binding.axis2/src/main/java/org/apache/tuscany/binding/axis2/assembly/WebServiceAssemblyFactory.java b/branches/java-post-M1/sca/bindings/binding.axis2/src/main/java/org/apache/tuscany/binding/axis2/assembly/WebServiceAssemblyFactory.java new file mode 100644 index 0000000000..8114b348d1 --- /dev/null +++ b/branches/java-post-M1/sca/bindings/binding.axis2/src/main/java/org/apache/tuscany/binding/axis2/assembly/WebServiceAssemblyFactory.java @@ -0,0 +1,31 @@ +/** + * + * Copyright 2005 The Apache Software Foundation or its licensors, as applicable. + * + * Licensed 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.binding.axis2.assembly; + +import org.apache.tuscany.model.assembly.AssemblyFactory; + +/** + * The Factory for the model. + */ +public interface WebServiceAssemblyFactory extends AssemblyFactory { + + /** + * Returns a new WebServiceBinding. + */ + WebServiceBinding createWebServiceBinding(); + +} diff --git a/branches/java-post-M1/sca/bindings/binding.axis2/src/main/java/org/apache/tuscany/binding/axis2/assembly/WebServiceBinding.java b/branches/java-post-M1/sca/bindings/binding.axis2/src/main/java/org/apache/tuscany/binding/axis2/assembly/WebServiceBinding.java new file mode 100644 index 0000000000..ea9f3f116f --- /dev/null +++ b/branches/java-post-M1/sca/bindings/binding.axis2/src/main/java/org/apache/tuscany/binding/axis2/assembly/WebServiceBinding.java @@ -0,0 +1,75 @@ +/** + * + * Copyright 2005 The Apache Software Foundation or its licensors, as applicable. + * + * Licensed 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.binding.axis2.assembly; + +import javax.wsdl.Definition; +import javax.wsdl.Port; + +import org.apache.tuscany.common.resource.ResourceLoader; +import org.apache.tuscany.model.assembly.Binding; + +import commonj.sdo.helper.TypeHelper; + +/** + * Represents a Web service binding. + */ +public interface WebServiceBinding extends Binding { + + /** + * Set the URI of the WSDL port for this binding. + * + * @param portURI + * the URI of the WSDL port + */ + void setPortURI(String portURI); + + /** + * Returns the WSDL port defining this binding. + */ + Port getWSDLPort(); + + /** + * Returns the WSDL definition containing the WSDL port. + * + * @return the WSDL definition containing the WSDL port + */ + Definition getWSDLDefinition(); + + /** + * Sets the WSDL port defining this binding. + */ + void setWSDLPort(Port value); + + /** + * Sets the WSDL definition containing the WSDL port. + * + * @param definition + */ + void setWSDLDefinition(Definition definition); + + TypeHelper getTypeHelper(); + + void setTypeHelper(TypeHelper typeHelper); + + ResourceLoader getResourceLoader(); + + void setResourceLoader(ResourceLoader resourceLoader); + + public void setWebAppName(String webAppName); + + public String getWebAppName(); +} diff --git a/branches/java-post-M1/sca/bindings/binding.axis2/src/main/java/org/apache/tuscany/binding/axis2/assembly/impl/WebServiceAssemblyFactoryImpl.java b/branches/java-post-M1/sca/bindings/binding.axis2/src/main/java/org/apache/tuscany/binding/axis2/assembly/impl/WebServiceAssemblyFactoryImpl.java new file mode 100644 index 0000000000..5523d8fdc0 --- /dev/null +++ b/branches/java-post-M1/sca/bindings/binding.axis2/src/main/java/org/apache/tuscany/binding/axis2/assembly/impl/WebServiceAssemblyFactoryImpl.java @@ -0,0 +1,42 @@ +/** + * + * Copyright 2005 The Apache Software Foundation or its licensors, as applicable. + * + * Licensed 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.binding.axis2.assembly.impl; + +import org.apache.tuscany.binding.axis2.assembly.WebServiceAssemblyFactory; +import org.apache.tuscany.binding.axis2.assembly.WebServiceBinding; +import org.apache.tuscany.model.assembly.impl.AssemblyFactoryImpl; + +/** + * An implementation of the model Factory. + */ +public class WebServiceAssemblyFactoryImpl extends AssemblyFactoryImpl implements WebServiceAssemblyFactory { + + /** + * Creates an instance of the factory. + */ + public WebServiceAssemblyFactoryImpl() { + super(); + } + + /** + * @see org.apache.tuscany.binding.axis2.assembly.WebServiceAssemblyFactory#createWebServiceBinding() + */ + public WebServiceBinding createWebServiceBinding() { + return new WebServiceBindingImpl(); + } + +} diff --git a/branches/java-post-M1/sca/bindings/binding.axis2/src/main/java/org/apache/tuscany/binding/axis2/assembly/impl/WebServiceBindingImpl.java b/branches/java-post-M1/sca/bindings/binding.axis2/src/main/java/org/apache/tuscany/binding/axis2/assembly/impl/WebServiceBindingImpl.java new file mode 100644 index 0000000000..5be1b87e01 --- /dev/null +++ b/branches/java-post-M1/sca/bindings/binding.axis2/src/main/java/org/apache/tuscany/binding/axis2/assembly/impl/WebServiceBindingImpl.java @@ -0,0 +1,176 @@ +/** + * + * Copyright 2005 The Apache Software Foundation or its licensors, as applicable. + * + * Licensed 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.binding.axis2.assembly.impl; + +import java.util.Collection; +import java.util.List; + +import javax.wsdl.Definition; +import javax.wsdl.Port; +import javax.wsdl.Service; + +import org.apache.tuscany.binding.axis2.assembly.WebServiceBinding; +import org.apache.tuscany.common.resource.ResourceLoader; +import org.apache.tuscany.model.assembly.AssemblyContext; +import org.apache.tuscany.model.assembly.impl.BindingImpl; + +import commonj.sdo.helper.TypeHelper; + +/** + * An implementation of WebServiceBinding. + */ +public class WebServiceBindingImpl extends BindingImpl implements WebServiceBinding { + + private Definition definition; + + private Port port; + + private String portURI; + + private TypeHelper typeHelper; + + private ResourceLoader resourceLoader; + + private String webAppName; + + /** + * Constructor + */ + protected WebServiceBindingImpl() { + } + + public TypeHelper getTypeHelper() { + return typeHelper; + } + + public void setTypeHelper(TypeHelper typeHelper) { + this.typeHelper = typeHelper; + } + + public ResourceLoader getResourceLoader() { + return resourceLoader; + } + + public void setResourceLoader(ResourceLoader resourceLoader) { + this.resourceLoader = resourceLoader; + } + + /** + * @see org.apache.tuscany.binding.axis2.assembly.WebServiceBinding#getWSDLPort() + */ + public Port getWSDLPort() { + return port; + } + + /** + * @see org.apache.tuscany.binding.axis2.assembly.WebServiceBinding#setWSDLPort(javax.wsdl.Port) + */ + public void setWSDLPort(Port value) { + checkNotFrozen(); + this.port = value; + } + + /** + * @see org.apache.tuscany.binding.axis2.assembly.WebServiceBinding#getWSDLDefinition() + */ + public Definition getWSDLDefinition() { + return definition; + } + + /** + */ + public void setWSDLDefinition(Definition pdefinition) { + checkNotFrozen(); + this.definition = pdefinition; + } + + /** + * @param portURI + * The portURI to set. + */ + public void setPortURI(String portURI) { + this.portURI = portURI; + } + + public void setWebAppName(String webAppName) { + this.webAppName = webAppName; + } + + public String getWebAppName() { + return webAppName; + } + + /** + */ + @SuppressWarnings("unchecked") + public void initialize(AssemblyContext modelContext) { + if (isInitialized()) { + return; + } + super.initialize(modelContext); + + // Get the WSDL port namespace and name + // We currently support two syntaxes for specifying a WSDL port: + // namespace#portName, this is what we supported in the initial contribution, we will + // deprecate this after M1 + // namespace#wsdl.endpoint(serviceName/portName), this is the WSDL 2.0 syntax + if (port == null && portURI != null) { + int h = portURI.indexOf('#'); + String portNamespace = portURI.substring(0, h); + String serviceName; + String portName; + + String fragment = portURI.substring(h + 1); + if (fragment.startsWith("wsdl.endpoint(") && fragment.endsWith(")")) { + fragment = fragment.substring(14, fragment.length()-1); + int slash = fragment.indexOf('/'); + if (slash != -1) { + serviceName = fragment.substring(0, slash); + portName = fragment.substring(slash+1); + } else { + serviceName = null; + portName = fragment; + } + } else { + serviceName = null; + portName = fragment; + } + + // Load the WSDL definitions for the given namespace + List definitions = modelContext.getAssemblyLoader().loadDefinitions(portNamespace); + if (definitions == null) { + throw new IllegalArgumentException("Cannot find WSDL definition for " + portNamespace); + } + for (Definition def : definitions) { + + // Find the port with the given name + for (Service service : (Collection) def.getServices().values()) { + if (serviceName != null && !serviceName.equals(service.getQName().getLocalPart())) + continue; + Port prt = service.getPort(portName); + if (prt != null) { + this.definition = def; + this.port = prt; + return; + } + } + } + throw new IllegalArgumentException("Cannot find WSDL port " + portURI); + } + } + +} diff --git a/branches/java-post-M1/sca/bindings/binding.axis2/src/main/java/org/apache/tuscany/binding/axis2/builder/ExternalWebServiceBuilder.java b/branches/java-post-M1/sca/bindings/binding.axis2/src/main/java/org/apache/tuscany/binding/axis2/builder/ExternalWebServiceBuilder.java new file mode 100644 index 0000000000..9b428f8be8 --- /dev/null +++ b/branches/java-post-M1/sca/bindings/binding.axis2/src/main/java/org/apache/tuscany/binding/axis2/builder/ExternalWebServiceBuilder.java @@ -0,0 +1,146 @@ +/** + * + * Copyright 2005 The Apache Software Foundation or its licensors, as applicable. + * + * Licensed 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.binding.axis2.builder; + +import java.lang.reflect.Method; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import javax.wsdl.Definition; +import javax.xml.namespace.QName; + +import org.apache.axiom.om.OMAbstractFactory; +import org.apache.axiom.soap.SOAPFactory; +import org.apache.axis2.AxisFault; +import org.apache.axis2.addressing.EndpointReference; +import org.apache.axis2.client.Options; +import org.apache.axis2.client.ServiceClient; +import org.apache.axis2.context.ConfigurationContext; +import org.apache.axis2.context.MessageContextConstants; +import org.apache.axis2.description.AxisService; +import org.apache.tuscany.binding.axis2.assembly.WebServiceBinding; +import org.apache.tuscany.binding.axis2.config.WSExternalServiceContextFactory; +import org.apache.tuscany.binding.axis2.externalservice.Axis2OperationInvoker; +import org.apache.tuscany.binding.axis2.externalservice.Axis2ServiceInvoker; +import org.apache.tuscany.binding.axis2.util.SDODataBinding; +import org.apache.tuscany.binding.axis2.util.TuscanyAxisConfigurator; +import org.apache.tuscany.binding.axis2.util.WebServiceOperationMetaData; +import org.apache.tuscany.binding.axis2.util.WebServicePortMetaData; +import org.apache.tuscany.core.builder.BuilderConfigException; +import org.apache.tuscany.core.extension.ExternalServiceBuilderSupport; +import org.apache.tuscany.core.extension.ExternalServiceContextFactory; +import org.apache.tuscany.core.injection.SingletonObjectFactory; +import org.apache.tuscany.model.assembly.ExternalService; +import org.osoa.sca.annotations.Scope; + +import commonj.sdo.helper.TypeHelper; + +/** + * Creates a ContextFactory for an external service configured with the {@link WebServiceBinding} + */ +@Scope("MODULE") +public class ExternalWebServiceBuilder extends ExternalServiceBuilderSupport { + + /* + * (non-Javadoc) + * + * @see org.apache.tuscany.core.extension.ExternalServiceBuilderSupport#createExternalServiceContextFactory(org.apache.tuscany.model.assembly.ExternalService) + */ + @Override + protected ExternalServiceContextFactory createExternalServiceContextFactory(ExternalService externalService) { + + WebServiceBinding wsBinding = (WebServiceBinding) externalService.getBindings().get(0); + Definition wsdlDefinition = wsBinding.getWSDLDefinition(); + WebServicePortMetaData wsPortMetaData = new WebServicePortMetaData(wsdlDefinition, wsBinding.getWSDLPort(), wsBinding.getURI(), false); + + ServiceClient serviceClient = createServiceClient(externalService.getName(), wsdlDefinition, wsPortMetaData); + + TypeHelper typeHelper = wsBinding.getTypeHelper(); + ClassLoader cl = wsBinding.getResourceLoader().getClassLoader(); + Class serviceInterface = externalService.getConfiguredService().getPort().getServiceContract().getInterface(); + Map invokers = createOperationInvokers(serviceInterface, typeHelper, cl, wsPortMetaData); + + Axis2ServiceInvoker axis2Client = new Axis2ServiceInvoker(serviceClient, invokers); + + return new WSExternalServiceContextFactory(externalService.getName(), new SingletonObjectFactory(axis2Client)); + + } + + /** + * Create an Axis2 ServiceClient configured for the externalService + */ + protected ServiceClient createServiceClient(String externalServiceName, Definition wsdlDefinition, WebServicePortMetaData wsPortMetaData) { + + TuscanyAxisConfigurator tuscanyAxisConfigurator = new TuscanyAxisConfigurator(null, null); + ConfigurationContext configurationContext = tuscanyAxisConfigurator.getConfigurationContext(); + + QName serviceQName = wsPortMetaData.getServiceName(); + String portName = wsPortMetaData.getPortName().getLocalPart(); + + ServiceClient serviceClient; + try { + + AxisService axisService = AxisService.createClientSideAxisService(wsdlDefinition, serviceQName, portName, new Options()); + serviceClient = new ServiceClient(configurationContext, axisService); + + } catch (AxisFault e) { + BuilderConfigException bce = new BuilderConfigException("AxisFault creating external service", e); + bce.addContextName(externalServiceName); + throw bce; + } + + return serviceClient; + } + + /** + * Create and configure an Axis2OperationInvoker for each operation in the externalService + */ + protected Map createOperationInvokers(Class sc, TypeHelper typeHelper, ClassLoader cl, WebServicePortMetaData wsPortMetaData) { + SOAPFactory soapFactory = OMAbstractFactory.getSOAP11Factory(); + String portTypeNS = wsPortMetaData.getPortTypeName().getNamespaceURI(); + Map invokers = new HashMap(); + + for (Method m : sc.getMethods()) { + String methodName = m.getName(); + + WebServiceOperationMetaData operationMetaData = wsPortMetaData.getOperationMetaData(methodName); + boolean isWrapped = operationMetaData.isDocLitWrapped(); + List sig = operationMetaData.getOperationSignature(); + SDODataBinding dataBinding = new SDODataBinding(cl, typeHelper, sig.size() > 0 ? (QName) sig.get(0) : null, isWrapped); + + Options options = new Options(); + options.setTo(new EndpointReference(wsPortMetaData.getEndpoint())); + options.setProperty(MessageContextConstants.CHUNKED, Boolean.FALSE); + + String wsdlOperationName = operationMetaData.getBindingOperation().getOperation().getName(); + + String soapAction = wsPortMetaData.getOperationMetaData(wsdlOperationName).getSOAPAction(); + if (soapAction != null && soapAction.length() > 1) { + options.setAction(soapAction); + } + + QName wsdlOperationQName = new QName(portTypeNS, wsdlOperationName); + Axis2OperationInvoker invoker = new Axis2OperationInvoker(wsdlOperationQName, options, dataBinding, soapFactory); + + invokers.put(methodName, invoker); + } + + return invokers; + } + +} diff --git a/branches/java-post-M1/sca/bindings/binding.axis2/src/main/java/org/apache/tuscany/binding/axis2/builder/ExternalWebServiceWireBuilder.java b/branches/java-post-M1/sca/bindings/binding.axis2/src/main/java/org/apache/tuscany/binding/axis2/builder/ExternalWebServiceWireBuilder.java new file mode 100644 index 0000000000..be526a2a9a --- /dev/null +++ b/branches/java-post-M1/sca/bindings/binding.axis2/src/main/java/org/apache/tuscany/binding/axis2/builder/ExternalWebServiceWireBuilder.java @@ -0,0 +1,36 @@ +/** + * + * Copyright 2005 The Apache Software Foundation or its licensors, as applicable. + * + * Licensed 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.binding.axis2.builder; + +import java.lang.reflect.Method; + +import org.apache.tuscany.binding.axis2.config.WSExternalServiceContextFactory; +import org.apache.tuscany.core.context.QualifiedName; +import org.apache.tuscany.core.context.ScopeContext; +import org.apache.tuscany.core.extension.ExternalServiceTargetInvoker; +import org.apache.tuscany.core.extension.WireBuilderSupport; +import org.apache.tuscany.core.wire.TargetInvoker; +import org.osoa.sca.annotations.Scope; + +@Scope("MODULE") +public class ExternalWebServiceWireBuilder extends WireBuilderSupport { + + @Override + protected TargetInvoker createInvoker(QualifiedName targetName, Method operation, ScopeContext context, boolean downScope) { + return new ExternalServiceTargetInvoker(targetName, operation, context); + } +} diff --git a/branches/java-post-M1/sca/bindings/binding.axis2/src/main/java/org/apache/tuscany/binding/axis2/builder/WebServiceEntryPointBuilder.java b/branches/java-post-M1/sca/bindings/binding.axis2/src/main/java/org/apache/tuscany/binding/axis2/builder/WebServiceEntryPointBuilder.java new file mode 100644 index 0000000000..de0d54f505 --- /dev/null +++ b/branches/java-post-M1/sca/bindings/binding.axis2/src/main/java/org/apache/tuscany/binding/axis2/builder/WebServiceEntryPointBuilder.java @@ -0,0 +1,49 @@ +/** + * + * Copyright 2005 The Apache Software Foundation or its licensors, as applicable. + * + * Licensed 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.binding.axis2.builder; + +import org.apache.tuscany.binding.axis2.assembly.WebServiceBinding; +import org.apache.tuscany.binding.axis2.config.WSEntryPointContextFactory; +import org.apache.tuscany.core.extension.EntryPointBuilderSupport; +import org.apache.tuscany.core.extension.EntryPointContextFactory; +import org.apache.tuscany.core.message.MessageFactory; +import org.apache.tuscany.core.system.annotation.Autowire; +import org.apache.tuscany.core.webapp.ServletHost; +import org.apache.tuscany.model.assembly.EntryPoint; +import org.osoa.sca.annotations.Scope; + +/** + * Creates a ContextFactory for an entry point configured with the {@link WebServiceBinding} + * + * @version $Rev$ $Date$ + */ +@Scope("MODULE") +public class WebServiceEntryPointBuilder extends EntryPointBuilderSupport { + + private ServletHost tomcatHost; + + @Autowire + public void setTomcatHost(ServletHost tomcatHost) { + this.tomcatHost = tomcatHost; + } + + protected EntryPointContextFactory createEntryPointContextFactory(EntryPoint entryPoint, MessageFactory msgFactory) { + WebServiceBinding wsBinding = (WebServiceBinding) entryPoint.getBindings().get(0); + return new WSEntryPointContextFactory(entryPoint.getName(), messageFactory, tomcatHost, wsBinding); + } + +} diff --git a/branches/java-post-M1/sca/bindings/binding.axis2/src/main/java/org/apache/tuscany/binding/axis2/config/WSEntryPointContextFactory.java b/branches/java-post-M1/sca/bindings/binding.axis2/src/main/java/org/apache/tuscany/binding/axis2/config/WSEntryPointContextFactory.java new file mode 100644 index 0000000000..9e836b43e5 --- /dev/null +++ b/branches/java-post-M1/sca/bindings/binding.axis2/src/main/java/org/apache/tuscany/binding/axis2/config/WSEntryPointContextFactory.java @@ -0,0 +1,276 @@ +/** + * + * Copyright 2005 The Apache Software Foundation or its licensors, as applicable. + * + * Licensed 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.binding.axis2.config; + +import java.io.InputStream; +import java.lang.reflect.Method; +import java.net.MalformedURLException; +import java.net.URL; +import java.util.Enumeration; +import java.util.Set; +import java.util.Vector; + +import javax.servlet.RequestDispatcher; +import javax.servlet.Servlet; +import javax.servlet.ServletConfig; +import javax.servlet.ServletContext; +import javax.servlet.ServletException; +import javax.wsdl.Definition; +import javax.wsdl.Operation; +import javax.wsdl.PortType; +import javax.xml.namespace.QName; + +import org.apache.axis2.AxisFault; +import org.apache.axis2.description.AxisOperation; +import org.apache.axis2.description.AxisService; +import org.apache.axis2.description.WSDL2AxisServiceBuilder; +import org.apache.axis2.wsdl.WSDLConstants; +import org.apache.tuscany.binding.axis2.assembly.WebServiceBinding; +import org.apache.tuscany.binding.axis2.entrypoint.WebServiceEntryPointInOutSyncMessageReceiver; +import org.apache.tuscany.binding.axis2.entrypoint.WebServiceEntryPointServlet; +import org.apache.tuscany.binding.axis2.util.SDODataBinding; +import org.apache.tuscany.binding.axis2.util.WebServiceOperationMetaData; +import org.apache.tuscany.binding.axis2.util.WebServicePortMetaData; +import org.apache.tuscany.core.builder.BuilderConfigException; +import org.apache.tuscany.core.builder.ContextCreationException; +import org.apache.tuscany.core.context.EntryPointContext; +import org.apache.tuscany.core.extension.EntryPointContextFactory; +import org.apache.tuscany.core.message.MessageFactory; +import org.apache.tuscany.core.webapp.ServletHost; + +import commonj.sdo.helper.TypeHelper; + +/** + * Creates instances of {@link org.apache.tuscany.core.context.EntryPointContext} configured with the appropriate wire chains and bindings. This + * implementation serves as a marker for + * + * @version $Rev$ $Date$ + */ +public class WSEntryPointContextFactory extends EntryPointContextFactory { + + private ServletHost tomcatHost; + + private WebServiceBinding wsBinding; + + public WSEntryPointContextFactory(String name, MessageFactory messageFactory, ServletHost tomcatHost, WebServiceBinding wsBinding) { + super(name, messageFactory); + this.tomcatHost = tomcatHost; + this.wsBinding = wsBinding; + } + + public EntryPointContext createContext() throws ContextCreationException { + EntryPointContext epc = super.createContext(); + initServlet(epc); + return epc; + } + + private void initServlet(EntryPointContext epc) { + AxisService axisService; + try { + axisService = createAxisService(epc, wsBinding); + } catch (AxisFault e) { + throw new BuilderConfigException(e); + } + WebServiceEntryPointServlet servlet = new WebServiceEntryPointServlet(axisService); + ServletConfig sc = createDummyServletConfig(); + try { + servlet.init(sc ); + } catch (ServletException e) { + throw new BuilderConfigException(e); + } + + String servletMapping = wsBinding.getWebAppName() + "/services/" + epc.getName(); + tomcatHost.registerMapping(servletMapping, servlet); + } + + private ServletConfig createDummyServletConfig() { + ServletConfig sc = new ServletConfig() { + + public String getServletName() { + return "TuscanyWSServlet"; + } + + public ServletContext getServletContext() { + return new ServletContext() { + + public ServletContext getContext(String arg0) { + return null; + } + + public int getMajorVersion() { + return 0; + } + + public int getMinorVersion() { + return 0; + } + + public String getMimeType(String arg0) { + return null; + } + + public Set getResourcePaths(String arg0) { + return null; + } + + public URL getResource(String arg0) throws MalformedURLException { + return null; + } + + public InputStream getResourceAsStream(String arg0) { + return null; + } + + public RequestDispatcher getRequestDispatcher(String arg0) { + return null; + } + + public RequestDispatcher getNamedDispatcher(String arg0) { + return null; + } + + public Servlet getServlet(String arg0) throws ServletException { + return null; + } + + public Enumeration getServlets() { + return null; + } + + public Enumeration getServletNames() { + return null; + } + + public void log(String arg0) { + } + + public void log(Exception arg0, String arg1) { + } + + public void log(String arg0, Throwable arg1) { + } + + public String getRealPath(String arg0) { + return null; + } + + public String getServerInfo() { + return null; + } + + public String getInitParameter(String arg0) { + return null; + } + + public Enumeration getInitParameterNames() { + return null; + } + + public Object getAttribute(String arg0) { + return null; + } + + public Enumeration getAttributeNames() { + return null; + } + + public void setAttribute(String arg0, Object arg1) { + } + + public void removeAttribute(String arg0) { + } + + public String getServletContextName() { + return null; + }}; + } + + public String getInitParameter(String arg0) { + return null; + } + + public Enumeration getInitParameterNames() { + return new Vector().elements(); + }}; + return sc; + } + + private AxisService createAxisService(EntryPointContext entryPointContext, WebServiceBinding wsBinding) throws AxisFault { + + String entryPointName = entryPointContext.getName(); + + Definition definition = wsBinding.getWSDLDefinition(); + WebServicePortMetaData wsdlPortInfo = new WebServicePortMetaData(definition, wsBinding.getWSDLPort(), null, false); + + // AxisServiceGroup serviceGroup = new AxisServiceGroup(axisConfig); + // serviceGroup.setServiceGroupName(wsdlPortInfo.getServiceName().getLocalPart()); + // axisConfig.addServiceGroup(serviceGroup); + + WSDL2AxisServiceBuilder builder = new WSDL2AxisServiceBuilder(definition, wsdlPortInfo.getServiceName(), wsdlPortInfo.getPort().getName()); + builder.setServerSide(true); + AxisService axisService = builder.populateService(); + + axisService.setName(entryPointName); + // axisService.setParent(serviceGroup); + axisService.setServiceDescription("Tuscany configured AxisService for EntryPoint: '" + entryPointName + '\''); + + TypeHelper typeHelper = wsBinding.getTypeHelper(); + ClassLoader cl = wsBinding.getResourceLoader().getClassLoader(); + + Class serviceInterface = entryPointContext.getServiceInterface(); + + PortType wsdlPortType = wsdlPortInfo.getPortType(); + for (Object o : wsdlPortType.getOperations()) { + Operation wsdlOperation = (Operation) o; + String operationName = wsdlOperation.getName(); + QName operationQN = new QName(definition.getTargetNamespace(), operationName); + Object entryPointProxy = entryPointContext.getInstance(null); + + WebServiceOperationMetaData omd = wsdlPortInfo.getOperationMetaData(operationName); + QName responseTypeQN = omd.getOutputPart(0).getElementName(); + + Method operationMethod = getMethod(serviceInterface, operationName); + SDODataBinding dataBinding = new SDODataBinding(cl, typeHelper, responseTypeQN, omd.isDocLitWrapped()); + WebServiceEntryPointInOutSyncMessageReceiver msgrec = new WebServiceEntryPointInOutSyncMessageReceiver(entryPointProxy, operationMethod, + dataBinding, cl); + + AxisOperation axisOp = axisService.getOperation(operationQN); + axisOp.setMessageExchangePattern(WSDLConstants.MEP_URI_IN_OUT); + axisOp.setMessageReceiver(msgrec); + } + + return axisService; + } + + protected Method getMethod(Class serviceInterface, String operationName) { + // Note: this doesn't support overloaded operations + Method[] methods = serviceInterface.getMethods(); + for (Method m : methods) { + if (m.getName().equals(operationName)) { + return m; + } + // tolerate WSDL with capatalized operation name + StringBuilder sb = new StringBuilder(operationName); + sb.setCharAt(0, Character.toLowerCase(sb.charAt(0))); + if (m.getName().equals(sb.toString())) { + return m; + } + } + throw new BuilderConfigException("no operation named " + operationName + " found on service interface: " + serviceInterface.getName()); + } + +} diff --git a/branches/java-post-M1/sca/bindings/binding.axis2/src/main/java/org/apache/tuscany/binding/axis2/config/WSExternalServiceContextFactory.java b/branches/java-post-M1/sca/bindings/binding.axis2/src/main/java/org/apache/tuscany/binding/axis2/config/WSExternalServiceContextFactory.java new file mode 100644 index 0000000000..0a2e308587 --- /dev/null +++ b/branches/java-post-M1/sca/bindings/binding.axis2/src/main/java/org/apache/tuscany/binding/axis2/config/WSExternalServiceContextFactory.java @@ -0,0 +1,34 @@ +/** + * + * Copyright 2005 The Apache Software Foundation or its licensors, as applicable. + * + * Licensed 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.binding.axis2.config; + +import org.apache.tuscany.core.builder.ObjectFactory; +import org.apache.tuscany.core.extension.ExternalServiceContextFactory; + +/** + * Creates instances of {@link org.apache.tuscany.core.context.ExternalServiceContext} configured with the appropriate wire chains and bindings. This + * implementation serves as a marker for {@link org.apache.tuscany.binding.axis2.builder.ExternalWebServiceWireBuilder} + * + * @version $Rev$ $Date$ + */ +public class WSExternalServiceContextFactory extends ExternalServiceContextFactory { + + public WSExternalServiceContextFactory(String name, ObjectFactory objectFactory) { + super(name, objectFactory); + } + +} diff --git a/branches/java-post-M1/sca/bindings/binding.axis2/src/main/java/org/apache/tuscany/binding/axis2/entrypoint/WebServiceEntryPointInOutSyncMessageReceiver.java b/branches/java-post-M1/sca/bindings/binding.axis2/src/main/java/org/apache/tuscany/binding/axis2/entrypoint/WebServiceEntryPointInOutSyncMessageReceiver.java new file mode 100644 index 0000000000..bb9f0e307a --- /dev/null +++ b/branches/java-post-M1/sca/bindings/binding.axis2/src/main/java/org/apache/tuscany/binding/axis2/entrypoint/WebServiceEntryPointInOutSyncMessageReceiver.java @@ -0,0 +1,101 @@ +/** + * + * Copyright 2005 The Apache Software Foundation or its licensors, as applicable. + * + * Licensed 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.binding.axis2.entrypoint; + +import java.lang.reflect.Method; + +import org.apache.axiom.om.OMElement; +import org.apache.axiom.soap.SOAPEnvelope; +import org.apache.axis2.AxisFault; +import org.apache.axis2.Constants; +import org.apache.axis2.context.MessageContext; +import org.apache.axis2.receivers.AbstractInOutSyncMessageReceiver; +import org.apache.tuscany.binding.axis2.util.SDODataBinding; +import org.apache.tuscany.core.wire.InvocationRuntimeException; + +public class WebServiceEntryPointInOutSyncMessageReceiver extends AbstractInOutSyncMessageReceiver { + + private Object entryPointProxy; + + protected Method operationMethod; + + protected SDODataBinding dataBinding; + + protected ClassLoader classLoader; + + public WebServiceEntryPointInOutSyncMessageReceiver(Object entryPointProxy, Method operationMethod, SDODataBinding dataBinding, ClassLoader classLoader) { + this.entryPointProxy = entryPointProxy; + this.operationMethod = operationMethod; + this.dataBinding = dataBinding; + this.classLoader = classLoader; + } + + @Override + public void invokeBusinessLogic(MessageContext inMC, MessageContext outMC) throws AxisFault { + try { + + OMElement requestOM = inMC.getEnvelope().getBody().getFirstElement(); + Object[] request; + if (requestOM != null) { + request = dataBinding.fromOMElement(requestOM); + } else { + request = new Object[0]; + } + + Object response; + ClassLoader tccl = Thread.currentThread().getContextClassLoader(); + try { + if (tccl != classLoader) { + Thread.currentThread().setContextClassLoader(classLoader); + } + + response = operationMethod.invoke(entryPointProxy, request); + + } finally { + if (tccl != classLoader) { + Thread.currentThread().setContextClassLoader(tccl); + } + } + + SOAPEnvelope soapEnvelope = getSOAPFactory(inMC).getDefaultEnvelope(); + + OMElement responseOM = null; + if (response != null) { + responseOM = dataBinding.toOMElement(new Object[] { response }); + soapEnvelope.getBody().addChild(responseOM); + } + + outMC.setEnvelope(soapEnvelope); + outMC.getOperationContext().setProperty(Constants.RESPONSE_WRITTEN, Constants.VALUE_TRUE); + + } catch (InvocationRuntimeException e) { + // throw new InvocationRuntimeException(e); + Throwable t = e.getCause(); + if(t instanceof Exception) { + + throw AxisFault.makeFault((Exception)t); + + } + throw e; + + + } catch (Exception e) { + throw AxisFault.makeFault(e); + } + + } +} diff --git a/branches/java-post-M1/sca/bindings/binding.axis2/src/main/java/org/apache/tuscany/binding/axis2/entrypoint/WebServiceEntryPointServlet.java b/branches/java-post-M1/sca/bindings/binding.axis2/src/main/java/org/apache/tuscany/binding/axis2/entrypoint/WebServiceEntryPointServlet.java new file mode 100644 index 0000000000..4e6173b671 --- /dev/null +++ b/branches/java-post-M1/sca/bindings/binding.axis2/src/main/java/org/apache/tuscany/binding/axis2/entrypoint/WebServiceEntryPointServlet.java @@ -0,0 +1,113 @@ +/** + * + * Copyright 2005 The Apache Software Foundation or its licensors, as applicable. + * + * Licensed 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.binding.axis2.entrypoint; + +import java.io.IOException; + +import javax.servlet.ServletConfig; +import javax.servlet.ServletException; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +import org.apache.axis2.description.AxisService; +import org.apache.axis2.transport.http.AxisServlet; + +/** + * @version $Rev: 383148 $ $Date: 2006-03-04 08:07:17 -0800 (Sat, 04 Mar 2006) $ + */ +public class WebServiceEntryPointServlet extends AxisServlet { + + private static final long serialVersionUID = 1L; + + private AxisService axisService; + + public WebServiceEntryPointServlet(AxisService axisService) { + this.axisService = axisService; + } + + public void init(final ServletConfig config) throws ServletException { + ClassLoader tccl = Thread.currentThread().getContextClassLoader(); + ClassLoader scl = this.getClass().getClassLoader(); + try { + if (tccl != scl) { + Thread.currentThread().setContextClassLoader(scl); + } + + try { + + super.init(config); + + configContext.getAxisConfiguration().addService(axisService); + + } catch (Exception e) { + throw new ServletException(e); + } + + } finally { + if (tccl != scl) { + Thread.currentThread().setContextClassLoader(tccl); + } + } + } + + @Override + protected void doGet(final HttpServletRequest arg0, final HttpServletResponse arg1) throws ServletException, IOException { + ClassLoader tccl = Thread.currentThread().getContextClassLoader(); + ClassLoader scl = this.getClass().getClassLoader(); + try { + if (tccl != scl) { + Thread.currentThread().setContextClassLoader(scl); + } + + try { + super.doGet(arg0, arg1); + } catch (Exception e) { + e.printStackTrace(); + throw new ServletException(e); + } + + } finally { + if (tccl != scl) { + Thread.currentThread().setContextClassLoader(tccl); + } + } + } + + @Override + protected void doPost(final HttpServletRequest arg0, final HttpServletResponse arg1) throws ServletException, IOException { + ClassLoader tccl = Thread.currentThread().getContextClassLoader(); + ClassLoader scl = this.getClass().getClassLoader(); + try { + if (tccl != scl) { + Thread.currentThread().setContextClassLoader(scl); + } + + try { + super.doPost(arg0, arg1); + } catch (Exception e) { + e.printStackTrace(); + throw new ServletException(e); + } + + } finally { + if (tccl != scl) { + Thread.currentThread().setContextClassLoader(tccl); + } + } + } +} diff --git a/branches/java-post-M1/sca/bindings/binding.axis2/src/main/java/org/apache/tuscany/binding/axis2/externalservice/Axis2OperationInvoker.java b/branches/java-post-M1/sca/bindings/binding.axis2/src/main/java/org/apache/tuscany/binding/axis2/externalservice/Axis2OperationInvoker.java new file mode 100644 index 0000000000..32767012df --- /dev/null +++ b/branches/java-post-M1/sca/bindings/binding.axis2/src/main/java/org/apache/tuscany/binding/axis2/externalservice/Axis2OperationInvoker.java @@ -0,0 +1,114 @@ +/** + * Copyright 2005 The Apache Software Foundation or its licensors, as applicable. + * + * Licensed 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.binding.axis2.externalservice; + +import javax.xml.namespace.QName; + +import org.apache.axiom.om.OMElement; +import org.apache.axiom.soap.SOAPEnvelope; +import org.apache.axiom.soap.SOAPFactory; +import org.apache.axis2.AxisFault; +import org.apache.axis2.client.OperationClient; +import org.apache.axis2.client.Options; +import org.apache.axis2.context.MessageContext; +import org.apache.axis2.wsdl.WSDLConstants; +import org.apache.tuscany.binding.axis2.util.SDODataBinding; + +/** + * Axis2OperationInvoker uses an Axis2 OperationClient to invoke a remote web service + */ +public class Axis2OperationInvoker { + + public QName wsdlOperationName; + + public Options options; + + public SDODataBinding dataBinding; + + private SOAPFactory soapFactory; + + public Axis2OperationInvoker(QName wsdlOperationName, Options options, SDODataBinding dataBinding, SOAPFactory soapFactory) { + this.wsdlOperationName = wsdlOperationName; + this.options = options; + this.dataBinding = dataBinding; + this.soapFactory = soapFactory; + } + + /** + * Invoke a WS operation + * + * @param operationClient + * @param args + * @return + * @throws AxisFault + */ + protected Object invokeOperation(OperationClient operationClient, Object[] args) throws AxisFault { + + operationClient.setOptions(options); + + SOAPEnvelope env = soapFactory.getDefaultEnvelope(); + + if (args != null && args.length > 0) { + OMElement requestOM = dataBinding.toOMElement(args); + env.getBody().addChild(requestOM); + } + + MessageContext requestMC = new MessageContext(); + requestMC.setEnvelope(env); + + operationClient.addMessageContext(requestMC); + + ClassLoader tccl = Thread.currentThread().getContextClassLoader(); + ClassLoader scl = this.getClass().getClassLoader(); + try { + if (tccl != scl) { + Thread.currentThread().setContextClassLoader(scl); + } + + operationClient.execute(true); + + } finally { + if (tccl != scl) { + Thread.currentThread().setContextClassLoader(tccl); + } + } + + MessageContext responseMC = operationClient.getMessageContext(WSDLConstants.MESSAGE_LABEL_IN_VALUE); + OMElement responseOM = responseMC.getEnvelope().getBody().getFirstElement(); + + Object[] os = null; + if (responseOM != null) { + os = dataBinding.fromOMElement(responseOM); + } + + Object response; + if (os == null || os.length < 1) { + response = null; + } else { + response = os[0]; + } + + return response; + } + + /** + * Get the WSDL operation name that this can invoke + */ + public QName getWSDLOperationName() { + return wsdlOperationName; + } + +} diff --git a/branches/java-post-M1/sca/bindings/binding.axis2/src/main/java/org/apache/tuscany/binding/axis2/externalservice/Axis2ServiceInvoker.java b/branches/java-post-M1/sca/bindings/binding.axis2/src/main/java/org/apache/tuscany/binding/axis2/externalservice/Axis2ServiceInvoker.java new file mode 100644 index 0000000000..38b9e40d2e --- /dev/null +++ b/branches/java-post-M1/sca/bindings/binding.axis2/src/main/java/org/apache/tuscany/binding/axis2/externalservice/Axis2ServiceInvoker.java @@ -0,0 +1,60 @@ +/** + * Copyright 2005 The Apache Software Foundation or its licensors, as applicable. + * + * Licensed 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.binding.axis2.externalservice; + +import java.util.Map; + +import org.apache.axis2.AxisFault; +import org.apache.axis2.client.OperationClient; +import org.apache.axis2.client.ServiceClient; +import org.apache.tuscany.core.extension.ExternalServiceInvoker; +import org.osoa.sca.ServiceRuntimeException; + +/** + * Axis2ServiceInvoker uses Axis2 to invoke a remote web service + */ +public class Axis2ServiceInvoker implements ExternalServiceInvoker { + + private ServiceClient serviceClient; + + private Map operationInvokers; + + public Axis2ServiceInvoker(ServiceClient serviceClient, Map operationInvokers) { + this.serviceClient = serviceClient; + this.operationInvokers = operationInvokers; + } + + /* + * (non-Javadoc) + * + * @see org.apache.tuscany.binding.axis2.handler.ExternalServiceInvoker#invoke(java.lang.String, java.lang.Object[]) + */ + public Object invoke(String methodName, Object[] args) { + try { + + Axis2OperationInvoker invoker = operationInvokers.get(methodName); + + // Axis2 operationClients can not be shared so create a new one for each request + OperationClient operationClient = serviceClient.createClient(invoker.getWSDLOperationName()); + + return invoker.invokeOperation(operationClient, args); + + } catch (AxisFault e) { + throw new ServiceRuntimeException(e); + } + } + +} diff --git a/branches/java-post-M1/sca/bindings/binding.axis2/src/main/java/org/apache/tuscany/binding/axis2/loader/WebServiceBindingLoader.java b/branches/java-post-M1/sca/bindings/binding.axis2/src/main/java/org/apache/tuscany/binding/axis2/loader/WebServiceBindingLoader.java new file mode 100644 index 0000000000..eb46c64219 --- /dev/null +++ b/branches/java-post-M1/sca/bindings/binding.axis2/src/main/java/org/apache/tuscany/binding/axis2/loader/WebServiceBindingLoader.java @@ -0,0 +1,74 @@ +/** + * + * Copyright 2005 The Apache Software Foundation + * + * Licensed 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.binding.axis2.loader; + +import javax.xml.namespace.QName; +import javax.xml.stream.XMLStreamException; +import javax.xml.stream.XMLStreamReader; + +import org.apache.tuscany.binding.axis2.assembly.WebServiceAssemblyFactory; +import org.apache.tuscany.binding.axis2.assembly.WebServiceBinding; +import org.apache.tuscany.binding.axis2.assembly.impl.WebServiceAssemblyFactoryImpl; +import org.apache.tuscany.core.config.ConfigurationLoadException; +import org.apache.tuscany.core.loader.LoaderContext; +import org.apache.tuscany.core.loader.StAXElementLoader; +import org.apache.tuscany.core.loader.StAXLoaderRegistry; +import org.apache.tuscany.core.system.annotation.Autowire; +import org.osoa.sca.annotations.Destroy; +import org.osoa.sca.annotations.Init; +import org.osoa.sca.annotations.Scope; + +/** + * @version $Rev$ $Date$ + */ +@Scope("MODULE") +public class WebServiceBindingLoader implements StAXElementLoader { + public static final QName BINDING_WS = new QName("http://www.osoa.org/xmlns/sca/0.9", "binding.ws"); + public static final QName BINDING_WS_RECURSIVE = new QName("http://www.osoa.org/xmlns/sca/1.0", "binding.ws"); + + private static final WebServiceAssemblyFactory WS_FACTORY = new WebServiceAssemblyFactoryImpl(); + + protected StAXLoaderRegistry registry; + + @Autowire + public void setRegistry(StAXLoaderRegistry registry) { + this.registry = registry; + } + + @Init(eager = true) + public void start() { + registry.registerLoader(BINDING_WS, this); + registry.registerLoader(BINDING_WS_RECURSIVE, this); + } + + @Destroy + public void stop() { + registry.unregisterLoader(BINDING_WS, this); + } + + @SuppressWarnings("deprecation") + public WebServiceBinding load(XMLStreamReader reader, LoaderContext loaderContext) throws XMLStreamException, ConfigurationLoadException { + + WebServiceBinding binding = WS_FACTORY.createWebServiceBinding(); + binding.setURI(reader.getAttributeValue(null, "uri")); + binding.setPortURI(reader.getAttributeValue(null, "port")); + binding.setTypeHelper(registry.getContext().getTypeHelper()); + binding.setWebAppName(registry.getContext().getWebAppName()); + binding.setResourceLoader(loaderContext.getResourceLoader()); + return binding; + } +} diff --git a/branches/java-post-M1/sca/bindings/binding.axis2/src/main/java/org/apache/tuscany/binding/axis2/util/SDODataBinding.java b/branches/java-post-M1/sca/bindings/binding.axis2/src/main/java/org/apache/tuscany/binding/axis2/util/SDODataBinding.java new file mode 100644 index 0000000000..0caf2293d6 --- /dev/null +++ b/branches/java-post-M1/sca/bindings/binding.axis2/src/main/java/org/apache/tuscany/binding/axis2/util/SDODataBinding.java @@ -0,0 +1,104 @@ +/** + * Copyright 2005 The Apache Software Foundation or its licensors, as applicable. + * + * Licensed 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.binding.axis2.util; + +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.IOException; + +import javax.xml.namespace.QName; +import javax.xml.stream.FactoryConfigurationError; +import javax.xml.stream.XMLInputFactory; +import javax.xml.stream.XMLStreamException; +import javax.xml.stream.XMLStreamReader; + +import org.apache.axiom.om.OMAbstractFactory; +import org.apache.axiom.om.OMElement; +import org.apache.axiom.om.OMXMLParserWrapper; +import org.apache.axiom.om.impl.llom.factory.OMXMLBuilderFactory; +import org.apache.tuscany.core.wire.InvocationRuntimeException; +import org.apache.tuscany.databinding.sdo.SDOXMLHelper; +import org.apache.tuscany.sdo.util.SDOUtil; +import org.osoa.sca.ServiceRuntimeException; + +import commonj.sdo.DataObject; +import commonj.sdo.helper.TypeHelper; +import commonj.sdo.helper.XMLHelper; + +/** + * DataBinding for converting between AXIOM OMElement and Java Objects + */ +public class SDODataBinding { + + private ClassLoader classLoader; + + private TypeHelper typeHelper; + + private QName elementQName; + + private boolean isWrapped; + + public SDODataBinding(ClassLoader classLoader, TypeHelper typeHelper, QName elementQName, boolean isWrapped) { + this.classLoader = classLoader; + this.typeHelper = typeHelper; + this.elementQName = elementQName; + this.isWrapped = isWrapped; + } + + public Object[] fromOMElement(OMElement omElement) { + try { + + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + + omElement.serialize(baos); + + baos.flush(); + baos.close(); + + return SDOXMLHelper.toObjects(classLoader,typeHelper, baos.toByteArray(), isWrapped); + + } catch (IOException e) { + throw new InvocationRuntimeException(e); + } catch (XMLStreamException e) { + throw new InvocationRuntimeException(e); + } + } + + public OMElement toOMElement(Object[] os) { + try { + + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + + DataObject dataObject = SDOXMLHelper.toDataObject(classLoader, typeHelper, os, elementQName, isWrapped); + XMLHelper xmlHelper = SDOUtil.createXMLHelper(typeHelper); + xmlHelper.save(dataObject, elementQName.getNamespaceURI(), elementQName.getLocalPart(), baos); + baos.close(); + + XMLStreamReader xsr = XMLInputFactory.newInstance().createXMLStreamReader(new ByteArrayInputStream(baos.toByteArray())); + OMXMLParserWrapper builder = OMXMLBuilderFactory.createStAXOMBuilder(OMAbstractFactory.getOMFactory(), xsr); + OMElement omElement = builder.getDocumentElement(); + + return omElement; + + } catch (IOException e) { + throw new ServiceRuntimeException(e); + } catch (XMLStreamException e) { + throw new ServiceRuntimeException(e); + } catch (FactoryConfigurationError e) { + throw new ServiceRuntimeException(e); + } + } +} diff --git a/branches/java-post-M1/sca/bindings/binding.axis2/src/main/java/org/apache/tuscany/binding/axis2/util/TuscanyAxisConfigurator.java b/branches/java-post-M1/sca/bindings/binding.axis2/src/main/java/org/apache/tuscany/binding/axis2/util/TuscanyAxisConfigurator.java new file mode 100644 index 0000000000..a5795d076e --- /dev/null +++ b/branches/java-post-M1/sca/bindings/binding.axis2/src/main/java/org/apache/tuscany/binding/axis2/util/TuscanyAxisConfigurator.java @@ -0,0 +1,88 @@ +/** + * + * Copyright 2005 The Apache Software Foundation or its licensors, as applicable. + * + * Licensed 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.binding.axis2.util; + +import java.io.IOException; +import java.io.InputStream; +import java.net.URL; + +import org.apache.axis2.AxisFault; +import org.apache.axis2.context.ConfigurationContext; +import org.apache.axis2.context.ConfigurationContextFactory; +import org.apache.axis2.deployment.AxisConfigBuilder; +import org.apache.axis2.deployment.DeploymentEngine; +import org.apache.axis2.engine.AxisConfiguration; +import org.apache.axis2.engine.AxisConfigurator; +import org.apache.tuscany.common.resource.ResourceLoader; +import org.apache.tuscany.common.resource.impl.ResourceLoaderImpl; +import org.osoa.sca.ServiceRuntimeException; + +/** + * Helps configure Axis2 from a resource in binding.axis2 instead of Axis2.xml + * + * TODO: Review: should there be a single global Axis ConfigurationContext + */ +public class TuscanyAxisConfigurator implements AxisConfigurator { + + protected AxisConfiguration axisConfiguration; + + protected final ResourceLoader resourceLoader; + + /** + * @param resourceLoader + * desired resource loader if null use thread context. + * @param axisConfiguration + * Starting axis configuration, null then use uninitialized configuration. + */ + public TuscanyAxisConfigurator(ResourceLoader resourceLoader, AxisConfiguration axisConfiguration) { + this.resourceLoader = resourceLoader != null ? resourceLoader : new ResourceLoaderImpl(getClass().getClassLoader()); + this.axisConfiguration = axisConfiguration == null ? new AxisConfiguration() : axisConfiguration; + } + + public AxisConfiguration getAxisConfiguration() { + + return axisConfiguration; + } + + public ConfigurationContext getConfigurationContext() throws ServiceRuntimeException { + + try { + URL url = resourceLoader.getResource("org/apache/tuscany/binding/axis2/engine/config/axis2.xml"); + + InputStream serviceInputStream = url.openStream(); + AxisConfigBuilder axisConfigBuilder = new AxisConfigBuilder(serviceInputStream, new DeploymentEngine(), axisConfiguration); + axisConfigBuilder.populateConfig(); + serviceInputStream.close(); + return ConfigurationContextFactory.createConfigurationContext(this); + } catch (IOException e) { + + throw new ServiceRuntimeException(e); + } + + } + + public void loadServices() { + // TODO Auto-generated method stub + + } + + public void engageGlobalModules() throws AxisFault { + // TODO Auto-generated method stub + + } + +} diff --git a/branches/java-post-M1/sca/bindings/binding.axis2/src/main/java/org/apache/tuscany/binding/axis2/util/WebServiceOperationMetaData.java b/branches/java-post-M1/sca/bindings/binding.axis2/src/main/java/org/apache/tuscany/binding/axis2/util/WebServiceOperationMetaData.java new file mode 100644 index 0000000000..1ebca5d3fc --- /dev/null +++ b/branches/java-post-M1/sca/bindings/binding.axis2/src/main/java/org/apache/tuscany/binding/axis2/util/WebServiceOperationMetaData.java @@ -0,0 +1,499 @@ +/** + * + * Copyright 2005 The Apache Software Foundation or its licensors, as applicable. + * + * Licensed 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.binding.axis2.util; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.HashSet; +import java.util.Iterator; +import java.util.List; +import java.util.Set; + +import javax.wsdl.Binding; +import javax.wsdl.BindingInput; +import javax.wsdl.BindingOperation; +import javax.wsdl.BindingOutput; +import javax.wsdl.Input; +import javax.wsdl.Message; +import javax.wsdl.Operation; +import javax.wsdl.Output; +import javax.wsdl.Part; +import javax.wsdl.extensions.soap.SOAPBinding; +import javax.wsdl.extensions.soap.SOAPHeader; +import javax.wsdl.extensions.soap.SOAPOperation; +import javax.xml.namespace.QName; + +/** + * Metadata for a WSDL operation + * + */ +public class WebServiceOperationMetaData { + // WSDL Binding and BindingOperation + private Binding binding; + + private BindingOperation bindingOperation; + + // Fields to cache derived metadata + private transient Set inputHeaderParts; + + private transient Set outputHeaderParts; + + private transient String style; + + private transient String use; + + private transient String soapAction; + + private transient List signature; + + private String encoding; + + private transient QName rpcOperationName; + + public WebServiceOperationMetaData(Binding binding, BindingOperation bindingOperation) { + this.binding = binding; + this.bindingOperation = bindingOperation; + } + + public WebServiceOperationMetaData(Binding binding, BindingOperation bindingOperation, String style, String use, String encoding, + String soapAction) { + this.binding = binding; + this.bindingOperation = bindingOperation; + this.style = style; + this.use = use; + this.encoding = encoding; + this.soapAction = soapAction; + } + + public Set getInputHeaderParts() { + if (inputHeaderParts == null) { + // Build a set of header parts that we need to exclude + inputHeaderParts = new HashSet(); + BindingInput bindingInput = bindingOperation.getBindingInput(); + + if (bindingInput != null) { + Operation operation = bindingOperation.getOperation(); + javax.wsdl.Message message = operation.getInput().getMessage(); + List elements = bindingInput.getExtensibilityElements(); + for (Iterator i = elements.iterator(); i.hasNext();) { + Object extensibilityElement = i.next(); + Part part = getPartFromSOAPHeader(message, extensibilityElement); + if (part != null) { + inputHeaderParts.add(part); + } + } + } + } + return inputHeaderParts; + } + + public Set getOutputHeaderParts() { + if (outputHeaderParts == null) { + // Build a set of header parts that we need to exclude + outputHeaderParts = new HashSet(); + BindingOutput bindingOutput = bindingOperation.getBindingOutput(); + + if (bindingOutput != null) { + Operation operation = bindingOperation.getOperation(); + javax.wsdl.Message message = operation.getOutput().getMessage(); + List elements = bindingOutput.getExtensibilityElements(); + for (Iterator i = elements.iterator(); i.hasNext();) { + Object extensibilityElement = i.next(); + Part part = getPartFromSOAPHeader(message, extensibilityElement); + if (part != null) { + outputHeaderParts.add(part); + } + } + } + } + return outputHeaderParts; + } + + private Part getPartFromSOAPHeader(Message message, Object extensibilityElement) { + Part part = null; + if (extensibilityElement instanceof SOAPHeader) { + SOAPHeader soapHeader = (SOAPHeader) extensibilityElement; + QName msgName = soapHeader.getMessage(); + if (message.getQName().equals(msgName)) { + part = message.getPart(soapHeader.getPart()); + } + } else if (extensibilityElement instanceof SOAPHeader) { + SOAPHeader soapHeader = (SOAPHeader) extensibilityElement; + QName msgName = soapHeader.getMessage(); + if (message.getQName().equals(msgName)) { + part = message.getPart(soapHeader.getPart()); + } + } + return part; + } + + public String getStyle() { + if (style == null) { + SOAPOperation soapOperation = (SOAPOperation) WebServicePortMetaData.getExtensibilityElement(bindingOperation.getExtensibilityElements(), + SOAPOperation.class); + if (soapOperation != null) { + style = soapOperation.getStyle(); + } + if (style == null) { + SOAPBinding soapBinding = WebServicePortMetaData.getExtensibilityElement(binding.getExtensibilityElements(), SOAPBinding.class); + if (soapBinding != null) { + style = soapBinding.getStyle(); + } + } + if (style == null) { + style = "document"; + } + } + return style; + } + + /** + * Returns the SOAP action for the given operation. + * + * @param wsdlBindingOperation + * @return + */ + public String getSOAPAction() { + if (soapAction == null) { + final List wsdlBindingOperationExtensions = bindingOperation.getExtensibilityElements(); + final SOAPOperation soapOp = WebServicePortMetaData.getExtensibilityElement(wsdlBindingOperationExtensions, SOAPOperation.class); + if (soapOp != null) { + soapAction = soapOp.getSoapActionURI(); + } + } + return soapAction; + } + + public QName getRPCOperationName() { + if (rpcOperationName == null) { + javax.wsdl.extensions.soap.SOAPBody soapBody = getSOAPBody(true); + String ns = (soapBody != null) ? soapBody.getNamespaceURI() : binding.getPortType().getQName().getNamespaceURI(); + String name = bindingOperation.getOperation().getName(); + rpcOperationName = new QName(ns, name); + } + return rpcOperationName; + } + + private List getSOAPBodyParts(boolean input) { + javax.wsdl.extensions.soap.SOAPBody soapBody = getSOAPBody(input); + if (soapBody != null) { + List parts = soapBody.getParts(); + if (parts != null) { + List names = new ArrayList(); + for (Iterator i = parts.iterator(); i.hasNext();) { + Object part = i.next(); + if (part instanceof String) { + names.add((String) part); + } else if (part instanceof Part) { + names.add(((Part) part).getName()); + } + } + return names; + } else { + return null; + } + } else { + return null; + } + } + + private javax.wsdl.extensions.soap.SOAPBody getSOAPBody(boolean input) { + List elements = null; + if (input) { + BindingInput bindingInput = bindingOperation.getBindingInput(); + if (bindingInput == null) { + return null; + } + elements = bindingInput.getExtensibilityElements(); + } else { + BindingOutput bindingOutput = bindingOperation.getBindingOutput(); + if (bindingOutput == null) { + return null; + } + elements = bindingOutput.getExtensibilityElements(); + } + javax.wsdl.extensions.soap.SOAPBody soapBody = WebServicePortMetaData.getExtensibilityElement(elements, + javax.wsdl.extensions.soap.SOAPBody.class); + return soapBody; + } + + /** + * Returns the use attribute + * + * @param wsdlOperation + * @return + */ + public String getUse() { + if (use == null) { + javax.wsdl.extensions.soap.SOAPBody soapBody = getSOAPBody(true); + if (soapBody != null) { + use = soapBody.getUse(); + } + if (use == null) { + use = "literal"; + } + } + return use; + } + + @SuppressWarnings("unchecked") + public String getEncoding() { + if (encoding == null) { + javax.wsdl.extensions.soap.SOAPBody soapBody = getSOAPBody(true); + if (soapBody != null) { + List styles = (List) soapBody.getEncodingStyles(); + if (styles != null && !styles.isEmpty()) { + encoding = styles.get(0); + } + } + if (encoding == null) { + encoding = ""; + } + } + return encoding; + } + + public boolean isDocLitWrapped() { + boolean flag = getStyle().equals("document") && getUse().equals("literal"); + if (!flag) { + return false; + } + Message msg = getMessage(true); + if (msg == null) { + return false; + } + List parts = msg.getOrderedParts(null); + if (parts.size() != 1) { + return false; + } + Part part = (Part) parts.get(0); + QName element = part.getElementName(); + if (element == null) { + return false; + } + return element.getLocalPart().equals(bindingOperation.getOperation().getName()); + } + + /* + * public SOAPMediator createMediator(boolean serverMode) throws SOAPException { // create a new mediator for each invoke for thread-safety + * boolean rpcStyle = getStyle().equals("rpc"); boolean rpcEncoded = isEncoded(); + * + * SOAPMediator mediator = null; + * + * if (!rpcStyle) { // Document mediator = new SOAPDocumentLiteralMediatorImpl(this, serverMode); } else { if (!rpcEncoded) mediator = new + * SOAPRPCLiteralMediatorImpl(this, serverMode); // RPC-literal else mediator = new SOAPRPCEncodedMediatorImpl(this, serverMode); // RPC-encoded } + * return mediator; } + */ + + /** + * Get the operation signature from the WSDL operation + * + * @param wsdlBinding + * @param bindingOperation + * @return + */ + public List getOperationSignature() { + if (signature == null) { + signature = new ArrayList(); + + Operation operation = bindingOperation.getOperation(); + if (operation == null) { + return signature; + } + + final Input input = operation.getInput(); + if (input == null) { + return signature; + } + + String sstyle = getStyle(); + + if ("rpc".equals(sstyle)) { + Collection partNames = input.getMessage().getParts().values(); + for (Iterator i = partNames.iterator(); i.hasNext();) { + Part part = (Part) i.next(); + signature.add(part.getName()); + } + } else { + /* + * WS-I Basic Profile 1.1 4.7.6 Operation Signatures Definition: operation signature + * + * The profile defines the "operation signature" to be the fully qualified name of the child element of SOAP body of the SOAP input + * message described by an operation in a WSDL binding. + * + * In the case of rpc-literal binding, the operation name is used as a wrapper for the part accessors. In the document-literal case, + * since a wrapper with the operation name is not present, the message signatures must be correctly designed so that they meet this + * requirement. + * + * An endpoint that supports multiple operations must unambiguously identify the operation being invoked based on the input message + * that it receives. This is only possible if all the operations specified in the wsdl:binding associated with an endpoint have a + * unique operation signature. + * + * R2710 The operations in a wsdl:binding in a DESCRIPTION MUST result in operation signatures that are different from one another. + */ + List bodyParts = getSOAPBodyParts(true); + + Collection parts = input.getMessage().getParts().values(); + // Exclude the parts to be transmitted in SOAP header + if (bodyParts == null) { + parts.removeAll(getInputHeaderParts()); + } + for (Iterator i = parts.iterator(); i.hasNext();) { + Part part = (Part) i.next(); + if (bodyParts == null) { + // All parts + QName elementName = part.getElementName(); + if (elementName == null) { + elementName = new QName("", part.getName()); + // TODO: [rfeng] throw new + // ServiceRuntimeException("Message part for + // document style must refer to an XSD element + // using a QName: " + part); + } + signature.add(elementName); + } else { + // "parts" in soap:body + if (bodyParts.contains(part.getName())) { + QName elementName = part.getElementName(); + if (elementName == null) { + elementName = new QName("", part.getName()); + // TODO: [rfeng] throw new + // ServiceRuntimeException("Message part for + // document style must refer to an XSD + // element using a QName: " + part); + } + signature.add(elementName); + } + + } + } + } + } + return signature; + } + + public Message getMessage(boolean isInput) { + Operation operation = bindingOperation.getOperation(); + if (operation == null) { + return null; + } + + if (isInput) { + final Input input = operation.getInput(); + return input == null ? null : input.getMessage(); + } else { + final Output output = operation.getOutput(); + return output == null ? null : output.getMessage(); + } + } + + public Part getInputPart(int index) { + Part part = null; + Message message = getMessage(true); + if (message == null) { + return part; + } + + List parts = message.getOrderedParts(null); + return (Part) parts.get(index); + + } + + public Part getOutputPart(int index) { + Part part = null; + Message message = getMessage(false); + if (message == null) { + return part; + } + + List parts = message.getOrderedParts(null); + return (Part) parts.get(index); + + } + + /** + * Get a list of indexes for each part in the SOAP body + * + * @param isInput + * TODO + * @return + */ + public List getBodyPartIndexes(boolean isInput) { + List indexes = new ArrayList(); + + Message message = getMessage(isInput); + if (message == null) { + return indexes; + } + + List bodyParts = getSOAPBodyParts(isInput); + List parts = message.getOrderedParts(null); + Set headerParts = isInput ? getInputHeaderParts() : getOutputHeaderParts(); + + int index = 0; + for (Iterator i = parts.iterator(); i.hasNext(); index++) { + Part part = (Part) i.next(); + if (headerParts.contains(part)) { + continue; + } + if (bodyParts == null) { + // All parts + indexes.add(index); + } else { + // "parts" in soap:body + if (bodyParts.contains(part.getName())) { + indexes.add(index); + } + } + } + return indexes; + } + + /** + * Get the corresponding index for a part in the SOAP header by element name + * + * @param elementName + * @param isInput + * TODO + * @return + */ + public int getHeaderPartIndex(QName elementName, boolean isInput) { + + Message message = getMessage(isInput); + if (message == null) { + return -1; + } + + List parts = message.getOrderedParts(null); + Set headerParts = isInput ? getInputHeaderParts() : getOutputHeaderParts(); + + int index = 0; + for (Iterator i = parts.iterator(); i.hasNext(); index++) { + Part part = (Part) i.next(); + // Test if the part is in header section + if (headerParts.contains(part) && elementName.equals(part.getElementName())) { + return index; + } + } + return -1; + } + + public BindingOperation getBindingOperation() { + return bindingOperation; + } + +} \ No newline at end of file diff --git a/branches/java-post-M1/sca/bindings/binding.axis2/src/main/java/org/apache/tuscany/binding/axis2/util/WebServicePortMetaData.java b/branches/java-post-M1/sca/bindings/binding.axis2/src/main/java/org/apache/tuscany/binding/axis2/util/WebServicePortMetaData.java new file mode 100644 index 0000000000..694a8fbf5f --- /dev/null +++ b/branches/java-post-M1/sca/bindings/binding.axis2/src/main/java/org/apache/tuscany/binding/axis2/util/WebServicePortMetaData.java @@ -0,0 +1,400 @@ +/** + * + * Copyright 2005 The Apache Software Foundation or its licensors, as applicable. + * + * Licensed 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.binding.axis2.util; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.Iterator; +import java.util.List; + +import javax.wsdl.Binding; +import javax.wsdl.BindingOperation; +import javax.wsdl.Definition; +import javax.wsdl.Operation; +import javax.wsdl.Port; +import javax.wsdl.PortType; +import javax.wsdl.Service; +import javax.wsdl.extensions.soap.SOAPAddress; +import javax.wsdl.extensions.soap.SOAPBinding; +import javax.xml.namespace.QName; + +import org.apache.tuscany.model.types.wsdl.WSDLServiceContract; + +/** + * Metadata for a WSDL port + * + */ +public class WebServicePortMetaData { + + private Service wsdlService; + + private QName wsdlServiceName; + + private Port wsdlPort; + + private Binding wsdlBinding; + + private QName wsdlPortName; + + private PortType wsdlPortType; + + private QName wsdlPortTypeName; + + private String endpoint; + + private boolean managed; + + private List allOperationMetaData; + + private WSDLServiceContract interfaceType; + + /** + * Constructor + * + * @param wsdlDefinition + * @param portName + */ + public WebServicePortMetaData(Definition wsdlDefinition, Port wsdlPort, String endpoint, boolean managed) { + + // Lookup the named port + this.wsdlPort = wsdlPort; + wsdlPortName = new QName(wsdlDefinition.getTargetNamespace(), wsdlPort.getName()); + + Collection services = wsdlDefinition.getServices().values(); + for (Object serviceObj : services) { + Service service = (Service) serviceObj; + if (service.getPorts().containsValue(wsdlPort)) { + wsdlService = service; + wsdlServiceName = service.getQName(); + break; + } + } + + // Save the binding + wsdlBinding = wsdlPort.getBinding(); + if (wsdlBinding == null) { + throw new IllegalArgumentException("WSDL binding cannot be found for " + wsdlPortName); + } + + // Save the portType + wsdlPortType = wsdlBinding.getPortType(); + if (wsdlPortType == null) { + throw new IllegalArgumentException("WSDL portType cannot be found for " + wsdlPortName); + } + wsdlPortTypeName = wsdlPortType.getQName(); + + // Save the endpoint + this.endpoint = endpoint; + + // Track if this endpoint is managed or not + this.managed = managed; + } + + /** + * Constructor + * + * @param serviceName + * @param portName + * @param portType + */ + public WebServicePortMetaData(QName serviceName, String portName, QName portTypeName, String endpoint) { + wsdlServiceName = serviceName; + wsdlPortName = new QName(serviceName.getNamespaceURI(), portName); + wsdlPortTypeName = portTypeName; + this.endpoint = endpoint; + } + + /** + * @return Returns the wsdlPort. + */ + public javax.wsdl.Port getPort() { + return wsdlPort; + } + + /** + * @return Returns the wsdlService. + */ + public QName getServiceName() { + return wsdlServiceName; + } + + /** + * @return Returns the wsdlService. + */ + public javax.wsdl.Service getService() { + return wsdlService; + } + + /** + * @return Returns the wsdlPortType. + */ + public PortType getPortType() { + return wsdlPortType; + } + + /** + * @return Returns the wsdlPortType. + */ + public QName getPortTypeName() { + return wsdlPortTypeName; + } + + /** + * @return Returns the wsdlBinding. + */ + public Binding getBinding() { + return wsdlBinding; + } + + /** + * @return Returns the wsdlPortName. + */ + public QName getPortName() { + return wsdlPortName; + } + + /** + * Returns the endpoint of a given port. + * + * @param wsdlPort + * @return + */ + public String getEndpoint() { + + // Return the specified endpoint + if (endpoint != null) { + return endpoint; + } + + // Find the target endpoint on the port + if (wsdlPort != null) { + final List wsdlPortExtensions = wsdlPort.getExtensibilityElements(); + for (Iterator i = wsdlPortExtensions.iterator(); i.hasNext();) { + final Object extension = i.next(); + if (extension instanceof SOAPAddress) { + return ((SOAPAddress) extension).getLocationURI(); + } + } + } + + return null; + } + + /** + * Returns the SOAP binding style. + * + * @return + */ + public String getStyle() { + + // Find the binding style + String style = null; + if (wsdlBinding != null) { + final List wsdlBindingExtensions = wsdlBinding.getExtensibilityElements(); + SOAPBinding soapBinding = getExtensibilityElement(wsdlBindingExtensions, SOAPBinding.class); + if (soapBinding != null) { + style = soapBinding.getStyle(); + } + } + + // Default to document + return (style == null) ? "document" : style; + } + + /** + * Returns the use attribute + * + * @return + */ + public String getUse() { + List list = getAllOperationMetaData(); + return list.get(0).getUse(); + } + + /** + * Returns the encoding attribute + * + * @return + */ + public String getEncoding() { + List list = getAllOperationMetaData(); + return list.get(0).getEncoding(); + } + + /** + * @return Returns true if this is a managed web service. + */ + public boolean isManaged() { + return managed; + } + + /** + * Returns the first extensibility element of the given type. + * + * @param elements + * @param type + * @return + */ + public static T getExtensibilityElement(List elements, Class type) { + for (Iterator i = elements.iterator(); i.hasNext();) { + Object element = i.next(); + if (type.isInstance(element)) { + return type.cast(element); + } + } + return null; + } + + /** + * Returns the extensibility elements of the given type. + * + * @param elements + * @param type + * @return + */ + public static List getExtensibilityElements(List elements, Class type) { + List result = new ArrayList(); + for (Iterator i = elements.iterator(); i.hasNext();) { + Object element = i.next(); + if (type.isInstance(element)) { + result.add(type.cast(element)); + } + } + return result; + } + + /** + * Get the operation signature from the SOAP Body + * + * @param body + * @return A list of QNames + */ + // public static List getOperationSignature(javax.xml.soap.SOAPBody body) { + // List signature = new ArrayList(); + // for (Iterator i = body.getChildElements(); i.hasNext();) { + // Object child = i.next(); + // if (child instanceof SOAPBodyElement) { + // Name name = ((SOAPBodyElement) child).getElementName(); + // QName qname = new QName(name.getURI(), name.getLocalName(), name.getPrefix()); + // signature.add(qname); + // } + // } + // return signature; + // } + // public static List getRPCOperationSignature(javax.xml.soap.SOAPBody body) { + // List signature = new ArrayList(); + // for (Iterator i = body.getChildElements(); i.hasNext();) { + // Object child = i.next(); + // if (child instanceof SOAPBodyElement) { + // SOAPBodyElement op = ((SOAPBodyElement) child); + // for (Iterator j = op.getChildElements(); j.hasNext();) { + // Object part = i.next(); + // if (part instanceof SOAPElement) { + // SOAPElement p = (SOAPElement) part; + // signature.add(p.getLocalName()); + // } + // } + // } + // } + // return signature; + // } + // public WebServiceOperationMetaData getOperationMetaData(javax.xml.soap.SOAPBody body) { + // List s1 = getOperationSignature(body); + // // List rpcParts = getRPCOperationSignature(body); + // for (Iterator it = getAllOperationMetaData().iterator(); it.hasNext();) { + // WebServiceOperationMetaData descriptor = (WebServiceOperationMetaData) it.next(); + // + // String style = descriptor.getStyle(); + // + // if (style.equals("document")) { + // List s2 = descriptor.getOperationSignature(); + // if (s1.equals(s2)) + // return descriptor; + // } else { + // QName op1 = (QName) s1.get(0); + // QName op2 = descriptor.getRPCOperationName(); + // if (op1.equals(op2)) { + // /* + // * // FIXME: [rfeng] We don't support method overloading + // * List partNames = getOperationSignature(binding, + // * bindingOperation); if (rpcParts.equals(partNames)) + // */ + // return descriptor; + // } + // } + // } + // return null; + // } + public List getAllOperationMetaData() { + if (allOperationMetaData == null) { + allOperationMetaData = new ArrayList(); + for (Iterator it = wsdlBinding.getBindingOperations().iterator(); it.hasNext();) { + final BindingOperation bindingOperation = (BindingOperation) it.next(); + if (bindingOperation.getOperation() != null) { + allOperationMetaData.add(new WebServiceOperationMetaData(wsdlBinding, bindingOperation)); + } + } + } + return allOperationMetaData; + } + + public WebServiceOperationMetaData getOperationMetaData(String operationName) { + StringBuilder sb = new StringBuilder(operationName); + sb.setCharAt(0, Character.toUpperCase(sb.charAt(0))); + String capatalizedOpName = sb.toString(); + + for (Iterator it = getAllOperationMetaData().iterator(); it.hasNext();) { + WebServiceOperationMetaData descriptor = (WebServiceOperationMetaData) it.next(); + String opName = descriptor.getBindingOperation().getOperation().getName(); + + if (opName.equals(operationName) || opName.equals(capatalizedOpName)) { + return descriptor; + } + } + return null; + } + + /** + * Returns the WSDL service contract + * + * @return + */ + public WSDLServiceContract getInterfaceType() { + return interfaceType; + } + + /** + * Get the WSDL operation name for a Java method name + */ + public String getWSDLOperationName(String methodName) { + StringBuilder sb = new StringBuilder(methodName); + sb.setCharAt(0, Character.toUpperCase(sb.charAt(0))); + String capatalizedOpName = sb.toString(); + for (Object o : wsdlPortType.getOperations()) { + Operation operation = (Operation) o; + String wsdlOpName = operation.getName(); + if (wsdlOpName.equals(methodName)) { + return wsdlOpName; + } + if (wsdlOpName.equals(capatalizedOpName)) { + return wsdlOpName; + } + } + return null; + } + +} \ No newline at end of file -- cgit v1.2.3