summaryrefslogtreecommitdiffstats
path: root/branches/sca-java-integration/sca/extensions/axis2/binding/src/main
diff options
context:
space:
mode:
authordims <dims@13f79535-47bb-0310-9956-ffa450edef68>2008-06-17 00:23:01 +0000
committerdims <dims@13f79535-47bb-0310-9956-ffa450edef68>2008-06-17 00:23:01 +0000
commitbdd0a41aed7edf21ec2a65cfa17a86af2ef8c48a (patch)
tree38a92061c0793434c4be189f1d70c3458b6bc41d /branches/sca-java-integration/sca/extensions/axis2/binding/src/main
Move Tuscany from Incubator to top level.
git-svn-id: http://svn.us.apache.org/repos/asf/tuscany@668359 13f79535-47bb-0310-9956-ffa450edef68
Diffstat (limited to 'branches/sca-java-integration/sca/extensions/axis2/binding/src/main')
-rw-r--r--branches/sca-java-integration/sca/extensions/axis2/binding/src/main/assembly/axis2.xml38
-rw-r--r--branches/sca-java-integration/sca/extensions/axis2/binding/src/main/java/org/apache/tuscany/binding/axis2/Axis2AsyncTargetInvoker.java94
-rwxr-xr-xbranches/sca-java-integration/sca/extensions/axis2/binding/src/main/java/org/apache/tuscany/binding/axis2/Axis2BindingBuilder.java331
-rw-r--r--branches/sca-java-integration/sca/extensions/axis2/binding/src/main/java/org/apache/tuscany/binding/axis2/Axis2BindingBuilderRuntimeException.java65
-rw-r--r--branches/sca-java-integration/sca/extensions/axis2/binding/src/main/java/org/apache/tuscany/binding/axis2/Axis2BindingRunTimeException.java48
-rw-r--r--branches/sca-java-integration/sca/extensions/axis2/binding/src/main/java/org/apache/tuscany/binding/axis2/Axis2CallbackInvocationHandler.java50
-rw-r--r--branches/sca-java-integration/sca/extensions/axis2/binding/src/main/java/org/apache/tuscany/binding/axis2/Axis2OneWayTargetInvoker.java72
-rwxr-xr-xbranches/sca-java-integration/sca/extensions/axis2/binding/src/main/java/org/apache/tuscany/binding/axis2/Axis2ReferenceBinding.java194
-rw-r--r--branches/sca-java-integration/sca/extensions/axis2/binding/src/main/java/org/apache/tuscany/binding/axis2/Axis2ReferenceCallback.java56
-rw-r--r--branches/sca-java-integration/sca/extensions/axis2/binding/src/main/java/org/apache/tuscany/binding/axis2/Axis2ReferenceCallbackTargetInvoker.java114
-rwxr-xr-xbranches/sca-java-integration/sca/extensions/axis2/binding/src/main/java/org/apache/tuscany/binding/axis2/Axis2ServiceBinding.java390
-rw-r--r--branches/sca-java-integration/sca/extensions/axis2/binding/src/main/java/org/apache/tuscany/binding/axis2/Axis2ServiceCallbackTargetInvoker.java120
-rw-r--r--branches/sca-java-integration/sca/extensions/axis2/binding/src/main/java/org/apache/tuscany/binding/axis2/Axis2ServiceInMessageReceiver.java68
-rw-r--r--branches/sca-java-integration/sca/extensions/axis2/binding/src/main/java/org/apache/tuscany/binding/axis2/Axis2ServiceInOutAsyncMessageReceiver.java91
-rw-r--r--branches/sca-java-integration/sca/extensions/axis2/binding/src/main/java/org/apache/tuscany/binding/axis2/Axis2ServiceInOutSyncMessageReceiver.java117
-rw-r--r--branches/sca-java-integration/sca/extensions/axis2/binding/src/main/java/org/apache/tuscany/binding/axis2/Axis2ServiceServlet.java211
-rwxr-xr-xbranches/sca-java-integration/sca/extensions/axis2/binding/src/main/java/org/apache/tuscany/binding/axis2/Axis2TargetInvoker.java186
-rw-r--r--branches/sca-java-integration/sca/extensions/axis2/binding/src/main/java/org/apache/tuscany/binding/axis2/TuscanyDispatcher.java79
-rwxr-xr-xbranches/sca-java-integration/sca/extensions/axis2/binding/src/main/java/org/apache/tuscany/binding/axis2/WebServiceBindingDefinition.java210
-rwxr-xr-xbranches/sca-java-integration/sca/extensions/axis2/binding/src/main/java/org/apache/tuscany/binding/axis2/WebServiceBindingLoader.java244
-rwxr-xr-xbranches/sca-java-integration/sca/extensions/axis2/binding/src/main/java/org/apache/tuscany/binding/axis2/util/TuscanyAxisConfigurator.java44
-rwxr-xr-xbranches/sca-java-integration/sca/extensions/axis2/binding/src/main/java/org/apache/tuscany/binding/axis2/util/WebServiceOperationMetaData.java491
-rwxr-xr-xbranches/sca-java-integration/sca/extensions/axis2/binding/src/main/java/org/apache/tuscany/binding/axis2/util/WebServicePortMetaData.java377
-rw-r--r--branches/sca-java-integration/sca/extensions/axis2/binding/src/main/resources/META-INF/sca/binding.axis2.scdl48
-rw-r--r--branches/sca-java-integration/sca/extensions/axis2/binding/src/main/resources/META-INF/sca/default.scdl49
-rw-r--r--branches/sca-java-integration/sca/extensions/axis2/binding/src/main/resources/META-INF/sca/extension.composite22
-rwxr-xr-xbranches/sca-java-integration/sca/extensions/axis2/binding/src/main/resources/org/apache/tuscany/binding/axis2/engine/config/axis2.xml306
27 files changed, 4115 insertions, 0 deletions
diff --git a/branches/sca-java-integration/sca/extensions/axis2/binding/src/main/assembly/axis2.xml b/branches/sca-java-integration/sca/extensions/axis2/binding/src/main/assembly/axis2.xml
new file mode 100644
index 0000000000..7c835caa5c
--- /dev/null
+++ b/branches/sca-java-integration/sca/extensions/axis2/binding/src/main/assembly/axis2.xml
@@ -0,0 +1,38 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ * 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.
+-->
+<assembly>
+ <id>bin</id>
+ <includeBaseDirectory>false</includeBaseDirectory>
+ <formats>
+ <format>zip</format>
+ <format>tar.gz</format>
+ </formats>
+
+ <dependencySets>
+ <dependencySet>
+ <outputDirectory>extension</outputDirectory>
+ <includes>
+ <include>org.apache.tuscany.bindings:axis2</include>
+ </includes>
+ <fileMode>644</fileMode>
+ </dependencySet>
+ </dependencySets>
+</assembly>
+
diff --git a/branches/sca-java-integration/sca/extensions/axis2/binding/src/main/java/org/apache/tuscany/binding/axis2/Axis2AsyncTargetInvoker.java b/branches/sca-java-integration/sca/extensions/axis2/binding/src/main/java/org/apache/tuscany/binding/axis2/Axis2AsyncTargetInvoker.java
new file mode 100644
index 0000000000..90f37ba5fa
--- /dev/null
+++ b/branches/sca-java-integration/sca/extensions/axis2/binding/src/main/java/org/apache/tuscany/binding/axis2/Axis2AsyncTargetInvoker.java
@@ -0,0 +1,94 @@
+/*
+ * 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.binding.axis2;
+
+import java.lang.reflect.InvocationTargetException;
+import java.util.LinkedList;
+import java.util.concurrent.CountDownLatch;
+
+import javax.xml.namespace.QName;
+
+import org.apache.tuscany.spi.component.WorkContext;
+import org.apache.tuscany.spi.wire.InvocationRuntimeException;
+import org.apache.tuscany.spi.wire.Message;
+
+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.client.ServiceClient;
+
+public class Axis2AsyncTargetInvoker extends Axis2TargetInvoker {
+
+ private Axis2ReferenceCallbackTargetInvoker callbackInvoker;
+
+ public Axis2AsyncTargetInvoker(ServiceClient serviceClient,
+ QName wsdlOperationName,
+ Options options,
+ SOAPFactory soapFactory, WorkContext workContext) {
+ super(serviceClient, wsdlOperationName, options, soapFactory, workContext);
+ }
+
+ public Object invokeTarget(final Object payload, final short sequence) throws InvocationTargetException {
+ throw new InvocationTargetException(new InvocationRuntimeException("Operation not supported"));
+ }
+
+ private Object invokeTarget(final Object payload, LinkedList<Object> callbackRoutingChain)
+ throws InvocationTargetException {
+ try {
+ Object[] args = (Object[]) payload;
+ OperationClient operationClient = createOperationClient(args);
+ callbackInvoker.setCallbackRoutingChain(callbackRoutingChain);
+ Axis2ReferenceCallback callback = new Axis2ReferenceCallback(callbackInvoker);
+ operationClient.setCallback(callback);
+
+ // FIXME Synchronize with callback thread to get return value
+ CountDownLatch doneSignal = new CountDownLatch(1);
+ callbackInvoker.setSignal(doneSignal);
+
+ operationClient.execute(false);
+
+ try {
+ doneSignal.await();
+ } catch(InterruptedException e) {
+ e.printStackTrace();
+ }
+
+ // FIXME returning value from callback thread
+ Object response = callbackInvoker.getReturnPayload();
+ return response;
+ } catch (AxisFault e) {
+ throw new InvocationTargetException(e);
+ }
+ }
+
+ public Message invoke(Message msg) throws InvocationRuntimeException {
+ try {
+ Object resp = invokeTarget(msg.getBody(), msg.getCallbackRoutingChain());
+ msg.setBody(resp);
+ } catch (Throwable e) {
+ msg.setBodyWithFault(e);
+ }
+ return msg;
+ }
+
+ public void setCallbackTargetInvoker(Axis2ReferenceCallbackTargetInvoker callbackInvoker) {
+ this.callbackInvoker = callbackInvoker;
+ }
+}
diff --git a/branches/sca-java-integration/sca/extensions/axis2/binding/src/main/java/org/apache/tuscany/binding/axis2/Axis2BindingBuilder.java b/branches/sca-java-integration/sca/extensions/axis2/binding/src/main/java/org/apache/tuscany/binding/axis2/Axis2BindingBuilder.java
new file mode 100755
index 0000000000..56725fdf3e
--- /dev/null
+++ b/branches/sca-java-integration/sca/extensions/axis2/binding/src/main/java/org/apache/tuscany/binding/axis2/Axis2BindingBuilder.java
@@ -0,0 +1,331 @@
+/*
+ * 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.binding.axis2;
+
+import java.net.URI;
+
+import javax.wsdl.Port;
+import javax.wsdl.PortType;
+
+import org.apache.axiom.om.OMElement;
+import org.apache.axis2.AxisFault;
+import org.apache.axis2.context.ConfigurationContext;
+import org.apache.tuscany.binding.axis2.util.TuscanyAxisConfigurator;
+import org.apache.tuscany.idl.wsdl.InterfaceWSDLIntrospector;
+import org.apache.tuscany.idl.wsdl.WSDLDefinitionRegistry;
+import org.apache.tuscany.idl.wsdl.WSDLServiceContract;
+import org.apache.tuscany.spi.annotation.Autowire;
+import org.apache.tuscany.spi.builder.BuilderConfigException;
+import org.apache.tuscany.spi.component.CompositeComponent;
+import org.apache.tuscany.spi.component.ReferenceBinding;
+import org.apache.tuscany.spi.component.ServiceBinding;
+import org.apache.tuscany.spi.component.WorkContext;
+import org.apache.tuscany.spi.deployer.DeploymentContext;
+import org.apache.tuscany.spi.extension.BindingBuilderExtension;
+import org.apache.tuscany.spi.host.ServletHost;
+import org.apache.tuscany.spi.idl.InvalidServiceContractException;
+import org.apache.tuscany.spi.model.AbstractReferenceDefinition;
+import org.apache.tuscany.spi.model.ServiceContract;
+import org.apache.tuscany.spi.model.ServiceDefinition;
+import org.apache.tuscany.spi.wire.IncompatibleServiceContractException;
+
+/**
+ * Builds a {@link org.osoa.sca.annotations.Service} or {@link org.apache.tuscany.spi.component.ReferenceBinding} configured
+ * with the Axis2 binding
+ *
+ * @version $Rev$ $Date$
+ */
+@SuppressWarnings("deprecation")
+public class Axis2BindingBuilder extends BindingBuilderExtension<WebServiceBindingDefinition> {
+ private static final String OM_DATA_BINDING = OMElement.class.getName();
+
+ // TODO: what to do about the base URI?
+ private static final String BASE_URI = "http://localhost:8080/";
+
+ private ServletHost servletHost;
+
+ private ConfigurationContext configContext;
+
+ private InterfaceWSDLIntrospector introspector;
+
+ private WorkContext workContext;
+
+ private WSDLDefinitionRegistry wsdlReg;
+
+ public Axis2BindingBuilder() throws BuilderConfigException {
+ initAxis();
+ }
+
+ @Autowire(required = false)
+ public void setServletHost(ServletHost servletHost) {
+ this.servletHost = servletHost;
+ }
+
+ /**
+ * @param introspector the introspector to set
+ */
+ @Autowire
+ public void setIntrospector(InterfaceWSDLIntrospector introspector) {
+ this.introspector = introspector;
+ }
+
+ @Autowire
+ public void setWorkContext(WorkContext workContext) {
+ this.workContext = workContext;
+ }
+
+ @Autowire
+ public void setWSDLDefinitionRegistry(WSDLDefinitionRegistry wsdlReg) {
+ this.wsdlReg = wsdlReg;
+ }
+
+ @SuppressWarnings("unchecked")
+ public ServiceBinding build(
+ CompositeComponent parent,
+ ServiceDefinition serviceDefinition,
+ WebServiceBindingDefinition wsBinding, DeploymentContext deploymentContext) {
+
+ try {
+ // Set the default databinding
+ ServiceContract outboundContract = serviceDefinition.getServiceContract();
+ if (outboundContract instanceof WSDLServiceContract) {
+ outboundContract.setDataBinding(OM_DATA_BINDING);
+ }
+
+ // TODO: TUSCANY-1148, <binding.ws> with no wsdl only works with <interface.wsdl>
+ if (wsBinding.getWSDLDefinition() == null) {
+ if (outboundContract instanceof WSDLServiceContract) {
+ String ns = ((WSDLServiceContract)outboundContract).getPortType().getQName().getNamespaceURI();
+ wsBinding.setWSDLDefinition(wsdlReg.getDefinition(ns));
+ } else {
+ throw new IllegalStateException("<binding.ws> with no WSDL requires using <interface.wsdl>");
+ }
+ }
+
+ // FIXME: We need to define how the WSDL PortType is honored in the case that
+ // both the service.ws and interface.wsdl are in place.
+ // The WSDL portType from the WSDL Port decides the incoming SOAP message format
+ // There are also cases that interface.java is used.
+
+ ServiceContract<?> inboundContract;
+ Port port = wsBinding.getWSDLPort();
+ if (port == null) {
+ // FIXME: [rfeng] No WSDL is referenced by service.ws, we need to create one from
+ // the outbound service contract if it's JavaServiceContract
+ inboundContract = outboundContract;
+ }
+
+ PortType portType = wsBinding.getWSDLPort().getBinding().getPortType();
+ inboundContract = introspector.introspect(portType);
+
+ // FIXME:
+ inboundContract.setInterfaceClass(serviceDefinition.getServiceContract().getInterfaceClass());
+ inboundContract.setDataBinding(OM_DATA_BINDING);
+ inboundContract.setCallbackName(serviceDefinition.getServiceContract().getCallbackName());
+ inboundContract.setInteractionScope(serviceDefinition.getServiceContract().getInteractionScope());
+ try {
+ wireService.checkCompatibility(inboundContract, outboundContract, true);
+ } catch (IncompatibleServiceContractException e) {
+ throw new Axis2BindingBuilderRuntimeException(e);
+ }
+
+ String axisServiceName;
+ if (wsBinding.isSpec10Compliant()) {
+ wsBinding.setActualURI(computeActualURI(wsBinding, BASE_URI, serviceDefinition.getTarget(), serviceDefinition.getName(), parent));
+ axisServiceName = wsBinding.getActualURI().getPath();
+ if (axisServiceName != null && axisServiceName.length() > 1 && axisServiceName.startsWith("/")) {
+ axisServiceName = axisServiceName.substring(1);
+ }
+ } else {
+ axisServiceName = serviceDefinition.getName();
+ }
+
+ ServiceBinding serviceBinding =
+ new Axis2ServiceBinding(axisServiceName, outboundContract, inboundContract, parent, wsBinding,
+ servletHost, configContext, workContext);
+ return serviceBinding;
+
+ } catch (InvalidServiceContractException e) {
+ throw new Axis2BindingBuilderRuntimeException(e);
+ }
+ }
+
+ @SuppressWarnings("unchecked")
+ public ReferenceBinding build(
+ CompositeComponent parent,
+ AbstractReferenceDefinition boundReferenceDefinition,
+ WebServiceBindingDefinition wsBinding,
+ DeploymentContext deploymentContext) {
+
+ // Set the default binding
+ ServiceContract inboundContract = boundReferenceDefinition.getServiceContract();
+ if (inboundContract instanceof WSDLServiceContract) {
+ inboundContract.setDataBinding(OM_DATA_BINDING);
+ }
+
+ // TODO: TUSCANY-1148, <binding.ws> with no wsdl only works with <interface.wsdl>
+ if (wsBinding.getWSDLDefinition() == null) {
+ if (inboundContract instanceof WSDLServiceContract) {
+ String ns = ((WSDLServiceContract)inboundContract).getPortType().getQName().getNamespaceURI();
+ wsBinding.setWSDLDefinition(wsdlReg.getDefinition(ns));
+ } else {
+ throw new IllegalStateException("<binding.ws> with no WSDL requires using <interface.wsdl>");
+ }
+ }
+
+ // FIXME: We need to define how the WSDL PortType is honored in the case that
+ // both the binding.ws and interface.wsdl are in place
+ // The WSDL portType from the WSDL Port decides the incoming SOAP message format
+
+ ServiceContract<?> outboundContract = inboundContract;
+ Port port = wsBinding.getWSDLPort();
+ if (port == null) {
+ // FIXME: [rfeng] No WSDL is referenced by binding.ws, we need to create one from
+ // the inbound service contract if it's JavaServiceContract
+ outboundContract = inboundContract;
+ }
+ PortType portType = port.getBinding().getPortType();
+ try {
+ outboundContract = introspector.introspect(portType);
+ } catch (InvalidServiceContractException e) {
+ new Axis2BindingBuilderRuntimeException(e);
+ }
+
+ // Set the default databinding
+ outboundContract.setDataBinding(OM_DATA_BINDING);
+ //FIXME ... need to figure out how to specify scope on wsdl.
+ outboundContract.setInteractionScope(inboundContract.getInteractionScope());
+
+ try {
+ wireService.checkCompatibility(inboundContract, outboundContract, true);
+ } catch (IncompatibleServiceContractException e) {
+ throw new Axis2BindingBuilderRuntimeException(e);
+ }
+
+ if (wsBinding.isSpec10Compliant()) {
+ wsBinding.setActualURI(computeActualURI(wsBinding, BASE_URI, null, boundReferenceDefinition.getName(), null));
+ }
+
+ return new Axis2ReferenceBinding(boundReferenceDefinition.getName(), parent, wsBinding,
+ inboundContract, outboundContract, workContext);
+
+ }
+
+ protected Class<WebServiceBindingDefinition> getBindingType() {
+ return WebServiceBindingDefinition.class;
+ }
+
+ protected void initAxis() throws BuilderConfigException {
+ // TODO: consider having a system component wrapping the Axis2 ConfigContext
+ try {
+ this.configContext = new TuscanyAxisConfigurator().getConfigurationContext();
+ } catch (AxisFault e) {
+ throw new BuilderConfigException(e);
+ }
+ }
+
+ /**
+ * Compute the endpoint URI based on section 2.1.1 of the WS binding spec
+ * 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 spec
+ * If the <binding.ws> has no wsdlElement but does have a uri attribute then the uri takes precidence
+ * over any implicitly used WSDL.
+ * @param parent
+ */
+ protected URI computeActualURI(WebServiceBindingDefinition wsBinding, String baseURI, URI componentURI, String bindingName, CompositeComponent parent) {
+ URI wsdlURI = null;
+ if (wsBinding.getServiceName() != null && wsBinding.getBindingName() == null) {
+ // <binding.ws> explicitly points at a wsdl port, may be a relative URI
+ wsdlURI = wsBinding.getPortURI();
+ }
+ if (wsdlURI != null && wsdlURI.isAbsolute()) {
+ if (wsBinding.getURI() != null && (wsBinding.getServiceName() != null && wsBinding.getBindingName() == null)) {
+ throw new IllegalArgumentException("binding URI cannot be used with absolute WSDL endpoint URI");
+ }
+ return URI.create(wsdlURI.toString());
+ }
+
+ // there is no wsdl port endpoint URI or that URI is relative
+
+ URI bindingURI = null;
+ if (wsBinding.getURI() != null) {
+ bindingURI = URI.create(wsBinding.getURI());
+ }
+
+ if (bindingURI != null && bindingURI.isAbsolute()) {
+ if (wsdlURI != null) {
+ return URI.create(bindingURI + "/" + wsdlURI).normalize();
+ } else {
+ return bindingURI;
+ }
+ }
+
+ if (componentURI == null) { // null for references
+ wsdlURI = wsBinding.getPortURI();
+ if (bindingURI != null) {
+ return URI.create(wsdlURI + "/" + bindingURI).normalize();
+ } else {
+ return wsdlURI;
+ }
+ }
+
+
+ // TODO: TUSCANY-xxx, how to tell if component has multiple services using <binding.ws>?
+ // boolean singleService = (parent != null) && (((Component)parent.getChild(componentURI.toString())).getInboundWires().size() == 1);
+ // if (bindingURI == null && !singleService) {
+
+ if (bindingURI == null) {
+ bindingURI = URI.create(bindingName);
+ }
+
+ if (componentURI.isAbsolute()) {
+ if (bindingURI == null && wsdlURI == null) {
+ return componentURI;
+ } else if (wsdlURI == null) {
+ return URI.create(componentURI + "/" + bindingURI).normalize();
+ } else if (bindingURI == null) {
+ return URI.create(componentURI + "/" + wsdlURI).normalize();
+ } else {
+ return URI.create(componentURI + "/" + bindingURI + "/" + wsdlURI).normalize();
+ }
+ }
+
+ String actualURI = "";
+
+ if (bindingURI == null) {
+ actualURI = baseURI + "/" + componentURI + "/";
+ } else {
+ actualURI = baseURI + "/" + componentURI + "/" + bindingURI + "/";
+ }
+
+ if (wsdlURI != null) {
+ actualURI = actualURI + wsdlURI.toString();
+ }
+
+ if (actualURI.endsWith("/")) {
+ actualURI = actualURI.substring(0, actualURI.length() -1);
+ }
+
+ // normalize to handle any . or .. occurances
+ return URI.create(actualURI).normalize();
+ }
+
+}
diff --git a/branches/sca-java-integration/sca/extensions/axis2/binding/src/main/java/org/apache/tuscany/binding/axis2/Axis2BindingBuilderRuntimeException.java b/branches/sca-java-integration/sca/extensions/axis2/binding/src/main/java/org/apache/tuscany/binding/axis2/Axis2BindingBuilderRuntimeException.java
new file mode 100644
index 0000000000..a5743668a4
--- /dev/null
+++ b/branches/sca-java-integration/sca/extensions/axis2/binding/src/main/java/org/apache/tuscany/binding/axis2/Axis2BindingBuilderRuntimeException.java
@@ -0,0 +1,65 @@
+/*
+ * 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.binding.axis2;
+
+
+/**
+ * Base class for Exceptions raised during the loading process. Loader implementations should throw a subclass of this
+ * to indicate the actual problem.
+ *
+ * @version $Rev$ $Date$
+ */
+public class Axis2BindingBuilderRuntimeException extends Axis2BindingRunTimeException {
+ private static final long serialVersionUID = -7459051598906813461L;
+ private String resourceURI;
+
+ public Axis2BindingBuilderRuntimeException() {
+ }
+
+ public Axis2BindingBuilderRuntimeException(String message) {
+ super(message);
+ }
+
+ public Axis2BindingBuilderRuntimeException(String message, Throwable cause) {
+ super(message, cause);
+ }
+
+ public Axis2BindingBuilderRuntimeException(Throwable cause) {
+ super(cause);
+ }
+
+ /**
+ * Returns the location of the resource that was being loaded.
+ *
+ * @return the location of the resource that was being loaded
+ */
+ public String getResourceURI() {
+ return resourceURI;
+ }
+
+ /**
+ * Sets the location of the resource that was being loaded.
+ *
+ * @param resourceURI the location of the resource that was being loaded
+ */
+ public void setResourceURI(String resourceURI) {
+ this.resourceURI = resourceURI;
+ }
+
+}
diff --git a/branches/sca-java-integration/sca/extensions/axis2/binding/src/main/java/org/apache/tuscany/binding/axis2/Axis2BindingRunTimeException.java b/branches/sca-java-integration/sca/extensions/axis2/binding/src/main/java/org/apache/tuscany/binding/axis2/Axis2BindingRunTimeException.java
new file mode 100644
index 0000000000..cd957c2ec6
--- /dev/null
+++ b/branches/sca-java-integration/sca/extensions/axis2/binding/src/main/java/org/apache/tuscany/binding/axis2/Axis2BindingRunTimeException.java
@@ -0,0 +1,48 @@
+/*
+ * 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.binding.axis2;
+
+import org.apache.tuscany.api.TuscanyRuntimeException;
+
+/**
+ * Denotes an error creating a new object instance
+ *
+ * @version $Rev$ $Date$
+ */
+public class Axis2BindingRunTimeException extends TuscanyRuntimeException {
+ private static final long serialVersionUID = -6423113430265944499L;
+
+ public Axis2BindingRunTimeException() {
+ super();
+ }
+
+ public Axis2BindingRunTimeException(String message) {
+ super(message);
+ }
+
+ public Axis2BindingRunTimeException(String message, Throwable cause) {
+ super(message, cause);
+ }
+
+ public Axis2BindingRunTimeException(Throwable cause) {
+ super(cause);
+ }
+
+}
+
diff --git a/branches/sca-java-integration/sca/extensions/axis2/binding/src/main/java/org/apache/tuscany/binding/axis2/Axis2CallbackInvocationHandler.java b/branches/sca-java-integration/sca/extensions/axis2/binding/src/main/java/org/apache/tuscany/binding/axis2/Axis2CallbackInvocationHandler.java
new file mode 100644
index 0000000000..e9aefa7320
--- /dev/null
+++ b/branches/sca-java-integration/sca/extensions/axis2/binding/src/main/java/org/apache/tuscany/binding/axis2/Axis2CallbackInvocationHandler.java
@@ -0,0 +1,50 @@
+/*
+ * 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.binding.axis2;
+
+import java.util.LinkedList;
+import java.util.Map;
+
+import org.apache.tuscany.spi.model.Operation;
+import org.apache.tuscany.spi.wire.AbstractOutboundInvocationHandler;
+import org.apache.tuscany.spi.wire.InboundWire;
+import org.apache.tuscany.spi.wire.OutboundInvocationChain;
+import org.apache.tuscany.spi.wire.TargetInvoker;
+
+public class Axis2CallbackInvocationHandler extends AbstractOutboundInvocationHandler {
+
+ private InboundWire inboundWire;
+
+ public Axis2CallbackInvocationHandler(InboundWire inboundWire) {
+ this.inboundWire = inboundWire;
+ }
+
+ public Object invoke(Operation operation, Object[] args, LinkedList<Object> callbackRoutingChain) throws Throwable {
+ Object targetAddress = callbackRoutingChain.removeFirst();
+ if (targetAddress == null) {
+ throw new AssertionError("Popped a null from address from stack");
+ }
+ //TODO optimize as this is slow in local invocations
+ Map<Operation<?>, OutboundInvocationChain> sourceCallbackInvocationChains =
+ inboundWire.getSourceCallbackInvocationChains(targetAddress);
+ OutboundInvocationChain chain = sourceCallbackInvocationChains.get(operation);
+ TargetInvoker invoker = chain.getTargetInvoker();
+ return invoke(chain, invoker, args, null, callbackRoutingChain);
+ }
+}
diff --git a/branches/sca-java-integration/sca/extensions/axis2/binding/src/main/java/org/apache/tuscany/binding/axis2/Axis2OneWayTargetInvoker.java b/branches/sca-java-integration/sca/extensions/axis2/binding/src/main/java/org/apache/tuscany/binding/axis2/Axis2OneWayTargetInvoker.java
new file mode 100644
index 0000000000..23d0fa56de
--- /dev/null
+++ b/branches/sca-java-integration/sca/extensions/axis2/binding/src/main/java/org/apache/tuscany/binding/axis2/Axis2OneWayTargetInvoker.java
@@ -0,0 +1,72 @@
+/*
+ * 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.binding.axis2;
+
+import java.lang.reflect.InvocationTargetException;
+import javax.xml.namespace.QName;
+
+import org.apache.tuscany.spi.component.WorkContext;
+import org.apache.tuscany.spi.wire.InvocationRuntimeException;
+import org.apache.tuscany.spi.wire.Message;
+
+import org.apache.axiom.om.OMElement;
+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.client.ServiceClient;
+
+public class Axis2OneWayTargetInvoker extends Axis2TargetInvoker {
+
+ protected static final OMElement RESPONSE = null;
+
+ public Axis2OneWayTargetInvoker(ServiceClient serviceClient,
+ QName wsdlOperationName,
+ Options options,
+ SOAPFactory soapFactory, WorkContext workContext) {
+
+ super(serviceClient, wsdlOperationName, options, soapFactory, workContext);
+ }
+
+ public Object invokeTarget(final Object payload, final short sequence) throws InvocationTargetException {
+ try {
+ Object[] args = (Object[]) payload;
+ OperationClient operationClient = createOperationClient(args);
+
+ operationClient.execute(false);
+
+ // REVIEW it seems ok to return null
+ return RESPONSE;
+ } catch (AxisFault e) {
+ throw new InvocationTargetException(e);
+ } catch (Throwable t) {
+ throw new Axis2BindingRunTimeException(t);
+ }
+ }
+
+ public Message invoke(Message msg) throws InvocationRuntimeException {
+ try {
+ Object resp = invokeTarget(msg.getBody(), NONE);
+ msg.setBody(resp);
+ } catch (Throwable e) {
+ msg.setBodyWithFault(e);
+ }
+ return msg;
+ }
+}
diff --git a/branches/sca-java-integration/sca/extensions/axis2/binding/src/main/java/org/apache/tuscany/binding/axis2/Axis2ReferenceBinding.java b/branches/sca-java-integration/sca/extensions/axis2/binding/src/main/java/org/apache/tuscany/binding/axis2/Axis2ReferenceBinding.java
new file mode 100755
index 0000000000..b0ee16ba3a
--- /dev/null
+++ b/branches/sca-java-integration/sca/extensions/axis2/binding/src/main/java/org/apache/tuscany/binding/axis2/Axis2ReferenceBinding.java
@@ -0,0 +1,194 @@
+/*
+ * 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.binding.axis2;
+
+import java.util.Collection;
+import javax.wsdl.Definition;
+import javax.xml.namespace.QName;
+
+import static org.osoa.sca.Constants.SCA_NS;
+
+import org.apache.tuscany.spi.component.CompositeComponent;
+import org.apache.tuscany.spi.component.WorkContext;
+import org.apache.tuscany.spi.extension.ReferenceBindingExtension;
+import org.apache.tuscany.spi.model.Operation;
+import org.apache.tuscany.spi.model.ServiceContract;
+import org.apache.tuscany.spi.wire.TargetInvoker;
+
+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.description.AxisService;
+import org.apache.axis2.transport.http.HTTPConstants;
+import org.apache.tuscany.binding.axis2.util.TuscanyAxisConfigurator;
+import org.apache.tuscany.binding.axis2.util.WebServiceOperationMetaData;
+import org.apache.tuscany.binding.axis2.util.WebServicePortMetaData;
+
+/**
+ * Axis2Reference uses Axis2 to invoke a remote web service
+ */
+public class Axis2ReferenceBinding<T> extends ReferenceBindingExtension {
+ private static final QName BINDING_WS = new QName(SCA_NS, "binding.ws");
+
+ private WebServicePortMetaData wsPortMetaData;
+ private ServiceClient serviceClient;
+ private WorkContext workContext;
+
+ @SuppressWarnings("unchecked")
+ public Axis2ReferenceBinding(String theName,
+ CompositeComponent parent,
+ WebServiceBindingDefinition wsBinding,
+ ServiceContract contract,
+ ServiceContract<?> bindingServiceContract,
+ WorkContext workContext) {
+ super(theName, parent);
+ this.bindingServiceContract = bindingServiceContract;
+ this.workContext = workContext;
+ try {
+ Definition wsdlDefinition = wsBinding.getWSDLDefinition();
+ if (wsBinding.isSpec10Compliant()) {
+ wsPortMetaData =
+ new WebServicePortMetaData(wsdlDefinition, wsBinding.getWSDLPort(), wsBinding.getActualURI().toString(), false);
+ } else {
+ wsPortMetaData =
+ new WebServicePortMetaData(wsdlDefinition, wsBinding.getWSDLPort(), wsBinding.getURI(), false);
+ }
+ serviceClient = createServiceClient(wsdlDefinition, wsPortMetaData);
+ } catch (AxisFault e) {
+ throw new Axis2BindingRunTimeException(e);
+ }
+ }
+
+ public QName getBindingType() {
+ return BINDING_WS;
+ }
+
+ public TargetInvoker createTargetInvoker(ServiceContract contract, Operation operation) {
+ Axis2TargetInvoker invoker;
+ try {
+ boolean operationHasCallback = contract.getCallbackName() != null;
+ if (operationHasCallback) {
+ // FIXME: SDODataBinding needs to pass in TypeHelper and classLoader
+ // as parameters.
+ Axis2AsyncTargetInvoker asyncInvoker =
+ (Axis2AsyncTargetInvoker) createOperationInvoker(serviceClient,
+ operation,
+ wsPortMetaData,
+ true,
+ false);
+ // FIXME: This makes the (BIG) assumption that there is only one
+ // callback method
+ // Relaxing this assumption, however, does not seem to be trivial,
+ // it may depend on knowledge
+ // of what actual callback method was invoked by the service at the
+ // other end
+ Operation callbackOperation = findCallbackOperation();
+ Axis2CallbackInvocationHandler invocationHandler =
+ new Axis2CallbackInvocationHandler(inboundWire);
+ Axis2ReferenceCallbackTargetInvoker callbackInvoker =
+ new Axis2ReferenceCallbackTargetInvoker(callbackOperation, inboundWire, invocationHandler);
+ asyncInvoker.setCallbackTargetInvoker(callbackInvoker);
+
+ invoker = asyncInvoker;
+ } else {
+ boolean isOneWay = operation.isNonBlocking();
+ invoker = createOperationInvoker(serviceClient, operation, wsPortMetaData, false, isOneWay);
+ }
+ } catch (AxisFault e) {
+ throw new Axis2BindingRunTimeException(e);
+ }
+ return invoker;
+ }
+
+ private Operation findCallbackOperation() {
+ ServiceContract contract = inboundWire.getServiceContract();
+ Operation callbackOperation = null;
+ Collection callbackOperations = contract.getCallbackOperations().values();
+ if (callbackOperations.size() != 1) {
+ throw new Axis2BindingRunTimeException("Can only handle one callback operation");
+ } else {
+ callbackOperation = (Operation) callbackOperations.iterator().next();
+ }
+ return callbackOperation;
+ }
+
+ /**
+ * Create an Axis2 ServiceClient
+ */
+ private ServiceClient createServiceClient(Definition wsdlDefinition, WebServicePortMetaData wsPortMetaData)
+ throws AxisFault {
+
+ TuscanyAxisConfigurator tuscanyAxisConfigurator = new TuscanyAxisConfigurator();
+ ConfigurationContext configurationContext = tuscanyAxisConfigurator.getConfigurationContext();
+ QName serviceQName = wsPortMetaData.getServiceName();
+ String portName = wsPortMetaData.getPortName().getLocalPart();
+ AxisService axisService =
+ AxisService.createClientSideAxisService(wsdlDefinition, serviceQName, portName, new Options());
+ return new ServiceClient(configurationContext, axisService);
+ }
+
+ /**
+ * Create and configure an Axis2TargetInvoker for each operations
+ */
+ private Axis2TargetInvoker createOperationInvoker(ServiceClient serviceClient,
+ Operation m,
+ WebServicePortMetaData wsPortMetaData,
+ boolean hasCallback,
+ boolean isOneWay) throws AxisFault {
+ SOAPFactory soapFactory = OMAbstractFactory.getSOAP11Factory();
+ String portTypeNS = wsPortMetaData.getPortTypeName().getNamespaceURI();
+
+ String methodName = m.getName();
+
+ WebServiceOperationMetaData operationMetaData = wsPortMetaData.getOperationMetaData(methodName);
+
+ Options options = new Options();
+ options.setTo(new EndpointReference(wsPortMetaData.getEndpoint()));
+ options.setProperty(HTTPConstants.CHUNKED, Boolean.FALSE);
+
+ String wsdlOperationName = operationMetaData.getBindingOperation().getOperation().getName();
+
+ String soapAction = wsPortMetaData.getOperationMetaData(wsdlOperationName).getSOAPAction();
+ if (soapAction != null && soapAction.length() > 1) {
+ options.setAction(soapAction);
+ }
+
+ options.setTimeOutInMilliSeconds(5 * 60 * 1000);
+
+ QName wsdlOperationQName = new QName(portTypeNS, wsdlOperationName);
+
+ Axis2TargetInvoker invoker;
+ if (hasCallback) {
+ invoker =
+ new Axis2AsyncTargetInvoker(serviceClient, wsdlOperationQName, options, soapFactory, workContext);
+ } else if (isOneWay) {
+ invoker =
+ new Axis2OneWayTargetInvoker(serviceClient, wsdlOperationQName, options, soapFactory, workContext);
+ } else {
+ invoker = new Axis2TargetInvoker(serviceClient, wsdlOperationQName, options, soapFactory, workContext);
+ }
+
+ return invoker;
+ }
+
+}
diff --git a/branches/sca-java-integration/sca/extensions/axis2/binding/src/main/java/org/apache/tuscany/binding/axis2/Axis2ReferenceCallback.java b/branches/sca-java-integration/sca/extensions/axis2/binding/src/main/java/org/apache/tuscany/binding/axis2/Axis2ReferenceCallback.java
new file mode 100644
index 0000000000..ca129ca1cc
--- /dev/null
+++ b/branches/sca-java-integration/sca/extensions/axis2/binding/src/main/java/org/apache/tuscany/binding/axis2/Axis2ReferenceCallback.java
@@ -0,0 +1,56 @@
+/*
+ * 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.binding.axis2;
+
+import java.lang.reflect.InvocationTargetException;
+
+import org.apache.axiom.om.OMElement;
+import org.apache.axis2.client.async.AsyncResult;
+import org.apache.axis2.client.async.Callback;
+import org.apache.axis2.context.MessageContext;
+import org.apache.tuscany.spi.wire.InvocationRuntimeException;
+import org.apache.tuscany.spi.wire.TargetInvoker;
+
+public class Axis2ReferenceCallback extends Callback {
+
+ private Axis2ReferenceCallbackTargetInvoker targetInvoker;
+
+ public Axis2ReferenceCallback(Axis2ReferenceCallbackTargetInvoker targetInvoker) {
+ this.targetInvoker = targetInvoker;
+ }
+
+ public void onComplete(AsyncResult result) {
+ MessageContext responseMC = result.getResponseMessageContext();
+ OMElement responseOM = responseMC.getEnvelope().getBody().getFirstElement();
+ try {
+ targetInvoker.invokeTarget(new Object[] {responseOM}, TargetInvoker.NONE);
+ } catch (InvocationTargetException e) {
+ // FIXME what is the appropriate exception here?
+ throw new InvocationRuntimeException(e);
+ }
+ }
+
+ public void setComplete(boolean complete) {
+ super.setComplete(complete);
+ }
+
+ public void onError(Exception e) {
+ throw new InvocationRuntimeException(e);
+ }
+}
diff --git a/branches/sca-java-integration/sca/extensions/axis2/binding/src/main/java/org/apache/tuscany/binding/axis2/Axis2ReferenceCallbackTargetInvoker.java b/branches/sca-java-integration/sca/extensions/axis2/binding/src/main/java/org/apache/tuscany/binding/axis2/Axis2ReferenceCallbackTargetInvoker.java
new file mode 100644
index 0000000000..cdc975b54e
--- /dev/null
+++ b/branches/sca-java-integration/sca/extensions/axis2/binding/src/main/java/org/apache/tuscany/binding/axis2/Axis2ReferenceCallbackTargetInvoker.java
@@ -0,0 +1,114 @@
+/*
+ * 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.binding.axis2;
+
+import java.lang.reflect.InvocationTargetException;
+import java.util.LinkedList;
+import java.util.concurrent.CountDownLatch;
+
+import org.apache.tuscany.spi.model.Operation;
+import org.apache.tuscany.spi.wire.InboundWire;
+import org.apache.tuscany.spi.wire.InvocationRuntimeException;
+import org.apache.tuscany.spi.wire.Message;
+import org.apache.tuscany.spi.wire.TargetInvoker;
+
+public class Axis2ReferenceCallbackTargetInvoker implements TargetInvoker {
+
+ private Operation operation;
+ private InboundWire inboundWire;
+ private LinkedList<Object> callbackRoutingChain;
+ private boolean cacheable;
+ Axis2CallbackInvocationHandler invocationHandler;
+ private CountDownLatch signal;
+ private Object returnPayload;
+
+ public Axis2ReferenceCallbackTargetInvoker(Operation operation,
+ InboundWire inboundWire,
+ Axis2CallbackInvocationHandler invocationHandler) {
+
+ this.operation = operation;
+ this.inboundWire = inboundWire;
+ this.invocationHandler = invocationHandler;
+ }
+
+ public Object invokeTarget(final Object payload, final short sequence) throws InvocationTargetException {
+ Object[] args;
+ if (payload != null && !payload.getClass().isArray()) {
+ args = new Object[]{payload};
+ returnPayload = payload;
+ } else {
+ args = (Object[]) payload;
+ returnPayload = args[0];
+ }
+ // FIXME synchronize with forward thread to return value
+ signal.countDown();
+ try {
+ return invocationHandler.invoke(operation, args, callbackRoutingChain);
+ } catch (Throwable t) {
+ t.printStackTrace();
+ throw new InvocationTargetException(t);
+ }
+ }
+
+ public Message invoke(Message msg) throws InvocationRuntimeException {
+ try {
+ Object resp = invokeTarget(msg.getBody(), NONE);
+ msg.setBody(resp);
+ } catch (InvocationTargetException e) {
+ msg.setBodyWithFault(e.getCause());
+ } catch (Throwable e) {
+ msg.setBodyWithFault(e);
+ }
+ return msg;
+ }
+
+ public boolean isCacheable() {
+ return cacheable;
+ }
+
+ public void setCacheable(boolean cacheable) {
+ this.cacheable = cacheable;
+ }
+
+ public boolean isOptimizable() {
+ return isCacheable(); // we only need to check if the scopes are correct
+ }
+
+ public Axis2ReferenceCallbackTargetInvoker clone() throws CloneNotSupportedException {
+ Axis2ReferenceCallbackTargetInvoker invoker = (Axis2ReferenceCallbackTargetInvoker) super.clone();
+ invoker.operation = this.operation;
+ invoker.inboundWire = this.inboundWire;
+ invoker.callbackRoutingChain = this.callbackRoutingChain;
+ invoker.cacheable = this.cacheable;
+ invoker.invocationHandler = this.invocationHandler;
+ return invoker;
+ }
+
+ public void setCallbackRoutingChain(LinkedList<Object> callbackRoutingChain) {
+ this.callbackRoutingChain = callbackRoutingChain;
+ }
+
+ public void setSignal(CountDownLatch signal) {
+ this.signal = signal;
+ }
+
+ public Object getReturnPayload() {
+ return returnPayload;
+ }
+}
diff --git a/branches/sca-java-integration/sca/extensions/axis2/binding/src/main/java/org/apache/tuscany/binding/axis2/Axis2ServiceBinding.java b/branches/sca-java-integration/sca/extensions/axis2/binding/src/main/java/org/apache/tuscany/binding/axis2/Axis2ServiceBinding.java
new file mode 100755
index 0000000000..d7e04ca917
--- /dev/null
+++ b/branches/sca-java-integration/sca/extensions/axis2/binding/src/main/java/org/apache/tuscany/binding/axis2/Axis2ServiceBinding.java
@@ -0,0 +1,390 @@
+/*
+ * 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.binding.axis2;
+
+import static org.osoa.sca.Constants.SCA_NS;
+
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.Set;
+import java.util.concurrent.CountDownLatch;
+
+import javax.wsdl.Definition;
+import javax.wsdl.Operation;
+import javax.wsdl.PortType;
+import javax.xml.namespace.QName;
+
+import org.apache.axiom.om.OMElement;
+import org.apache.axiom.soap.SOAPFactory;
+import org.apache.axis2.AxisFault;
+import org.apache.axis2.context.ConfigurationContext;
+import org.apache.axis2.context.MessageContext;
+import org.apache.axis2.description.AxisOperation;
+import org.apache.axis2.description.AxisService;
+import org.apache.axis2.description.Parameter;
+import org.apache.axis2.description.WSDL11ToAxisServiceBuilder;
+import org.apache.axis2.description.WSDLToAxisServiceBuilder;
+import org.apache.axis2.engine.MessageReceiver;
+import org.apache.axis2.wsdl.WSDLConstants;
+import org.apache.axis2.wsdl.WSDLConstants.WSDL20_2004Constants;
+import org.apache.tuscany.binding.axis2.util.WebServicePortMetaData;
+import org.apache.tuscany.spi.builder.BuilderConfigException;
+import org.apache.tuscany.spi.component.CompositeComponent;
+import org.apache.tuscany.spi.component.TargetInvokerCreationException;
+import org.apache.tuscany.spi.component.WorkContext;
+import org.apache.tuscany.spi.extension.ServiceBindingExtension;
+import org.apache.tuscany.spi.host.ServletHost;
+import org.apache.tuscany.spi.model.InteractionScope;
+import org.apache.tuscany.spi.model.Scope;
+import org.apache.tuscany.spi.model.ServiceContract;
+import org.apache.tuscany.spi.wire.Interceptor;
+import org.apache.tuscany.spi.wire.InvocationChain;
+import org.apache.tuscany.spi.wire.Message;
+import org.apache.tuscany.spi.wire.MessageImpl;
+import org.apache.tuscany.spi.wire.TargetInvoker;
+import org.osoa.sca.annotations.Destroy;
+
+// org.apache.tuscany.spi.model
+/**
+ * An implementation of a {@link ServiceBindingExtension} configured with the Axis2 binding
+ *
+ * @version $Rev$ $Date$
+ */
+public class Axis2ServiceBinding extends ServiceBindingExtension {
+ private static final QName BINDING_WS = new QName(SCA_NS, "binding.ws");
+
+ private ServiceContract<?> serviceContract;
+
+ private ServletHost servletHost;
+
+ private ConfigurationContext configContext;
+
+ private WebServiceBindingDefinition binding;
+
+ private Map<Object, InvocationContext> invCtxMap = new HashMap<Object, InvocationContext>();
+
+ private String serviceName;
+
+ private WorkContext workContext;
+
+ private Boolean conversational = null;
+
+ private Set<String> seenConversations = Collections.synchronizedSet(new HashSet<String>());
+
+ public Axis2ServiceBinding(String theName,
+ ServiceContract<?> serviceContract,
+ ServiceContract<?> serviceBindingContract,
+ CompositeComponent parent,
+ WebServiceBindingDefinition binding,
+ ServletHost servletHost,
+ ConfigurationContext configContext,
+ WorkContext workContext) {
+
+ super(theName, parent);
+
+ this.serviceContract = serviceContract;
+ this.bindingServiceContract = serviceBindingContract;
+ this.binding = binding;
+ this.servletHost = servletHost;
+ this.configContext = configContext;
+ this.serviceName = theName;
+ this.workContext = workContext;
+ }
+
+ public void start() {
+ super.start();
+
+ try {
+ configContext.getAxisConfiguration().addService(createAxisService(binding));
+ } catch (AxisFault e) {
+ throw new Axis2BindingRunTimeException(e);
+ }
+
+ Axis2ServiceServlet servlet = new Axis2ServiceServlet();
+ servlet.init(configContext);
+ configContext.setContextRoot(getName());
+ if (binding.isSpec10Compliant()) {
+ // TODO: TUSCANY-xxx, sort out what to do with system base URI etc
+ servletHost.registerMapping(binding.getActualURI().getPath(), servlet);
+ } else {
+ servletHost.registerMapping("/services/" + getName(), servlet);
+ }
+ }
+
+ @Destroy
+ public void stop() {
+ if (binding.isSpec10Compliant()) {
+ servletHost.unregisterMapping(binding.getActualURI().getPath());
+ } else {
+ servletHost.unregisterMapping("/services/" + getName());
+ }
+ try {
+ configContext.getAxisConfiguration().removeService(getName());
+ } catch (AxisFault e) {
+ throw new Axis2BindingRunTimeException(e);
+ }
+ super.stop();
+ }
+
+ private AxisService createAxisService(WebServiceBindingDefinition wsBinding) throws AxisFault {
+ Definition definition = wsBinding.getWSDLDefinition();
+ WebServicePortMetaData wsdlPortInfo =
+ new WebServicePortMetaData(definition, wsBinding.getWSDLPort(), null, false);
+
+ // TODO investigate if this is 20 wsdl what todo?
+ WSDLToAxisServiceBuilder builder =
+ new WSDL11ToAxisServiceBuilder(definition, wsdlPortInfo.getServiceName(), wsdlPortInfo.getPort()
+ .getName());
+ builder.setServerSide(true);
+ AxisService axisService = builder.populateService();
+
+ axisService.setName(this.getName());
+ axisService.setServiceDescription("Tuscany configured AxisService for service: '" + this.getName()
+ + "'");
+
+ // Use the existing WSDL
+ Parameter wsdlParam = new Parameter(WSDLConstants.WSDL_4_J_DEFINITION, null);
+ wsdlParam.setValue(definition);
+ axisService.addParameter(wsdlParam);
+ Parameter userWSDL = new Parameter("useOriginalwsdl", "true");
+ axisService.addParameter(userWSDL);
+
+ PortType wsdlPortType = wsdlPortInfo.getPortType();
+ for (Object o : wsdlPortType.getOperations()) {
+ Operation wsdlOperation = (Operation) o;
+ String operationName = wsdlOperation.getName();
+ QName operationQN = new QName(definition.getTargetNamespace(), operationName);
+
+ org.apache.tuscany.spi.model.Operation<?> op = serviceContract.getOperations().get(operationName);
+
+ MessageReceiver msgrec = null;
+ boolean opIsNonBlocking = op.isNonBlocking();
+ if (serviceContract.getCallbackName() != null) {
+ msgrec = new Axis2ServiceInOutAsyncMessageReceiver(this, op);
+ } else if (opIsNonBlocking) {
+ msgrec = new Axis2ServiceInMessageReceiver(this, op);
+ } else {
+ msgrec = new Axis2ServiceInOutSyncMessageReceiver(this, op);
+ }
+
+ AxisOperation axisOp = axisService.getOperation(operationQN);
+ if (opIsNonBlocking) {
+ axisOp.setMessageExchangePattern(WSDL20_2004Constants.MEP_URI_IN_ONLY);
+ } else {
+ axisOp.setMessageExchangePattern(WSDL20_2004Constants.MEP_URI_IN_OUT);
+ }
+ axisOp.setMessageReceiver(msgrec);
+ }
+
+ return axisService;
+ }
+
+ public Object invokeTarget(org.apache.tuscany.spi.model.Operation<?> op, Object[] args, Object messageId,
+ String conversationID)
+ throws InvocationTargetException {
+ InvocationChain chain = inboundWire.getInvocationChains().get(op);
+ Interceptor headInterceptor = chain.getHeadInterceptor();
+ String oldConversationID = (String) workContext.getIdentifier(Scope.CONVERSATION);
+ if (isConversational() && conversationID != null) {
+ workContext.setIdentifier(Scope.CONVERSATION, conversationID);
+ } else {
+ workContext.clearIdentifier(Scope.CONVERSATION);
+ }
+ try {
+ if (headInterceptor == null) {
+ // short-circuit the dispatch and invoke the target directly
+ TargetInvoker targetInvoker = chain.getTargetInvoker();
+ if (targetInvoker == null) {
+ throw new AssertionError("No target invoker [" + chain.getOperation().getName() + "]");
+ }
+ return targetInvoker.invokeTarget(args, TargetInvoker.NONE);
+ } else {
+
+ Message msg = new MessageImpl();
+ msg.setTargetInvoker(chain.getTargetInvoker());
+ msg.pushFromAddress(getFromAddress());
+ if (messageId != null) {
+ msg.setMessageId(messageId);
+ }
+ msg.setBody(args);
+ Message resp;
+
+ if (isConversational()) {
+
+
+ int opSeq = op.getConversationSequence();
+ if (opSeq == org.apache.tuscany.spi.model.Operation.CONVERSATION_END) {
+ assert seenConversations
+ .contains(conversationID) : "End of conversation called when no conversation existed";
+ msg.setConversationSequence(TargetInvoker.END);
+ seenConversations.remove(conversationID); //if a fault occurs does the conversation end?
+ //how do I know if a component called locally another opeation that ended this conversation?
+
+ } else {
+ boolean ec = seenConversations.contains(conversationID);
+ if (ec) {
+
+ msg.setConversationSequence(TargetInvoker.CONTINUE);
+ } else {
+ seenConversations.add(conversationID);
+ msg.setConversationSequence(TargetInvoker.START);
+ }
+ }
+
+ }
+ // dispatch the wire down the chain and get the response
+ resp = headInterceptor.invoke(msg);
+ Object body = resp.getBody();
+ if (resp.isFault()) {
+ throw new InvocationTargetException((Throwable) body);
+ }
+ return body;
+ }
+ } finally {
+ if (null != oldConversationID) {
+ workContext.setIdentifier(Scope.CONVERSATION, conversationID);
+ } else {
+ workContext.clearIdentifier(Scope.CONVERSATION);
+ }
+ }
+ }
+
+ protected Object getFromAddress() {
+ return this.serviceName;
+ }
+
+ /**
+ * Get the Method from an interface matching the WSDL operation name
+ */
+ protected Method getMethod(Class<?> serviceInterface, String operationName) throws BuilderConfigException {
+ // 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());
+ }
+
+ public QName getBindingType() {
+ return BINDING_WS;
+ }
+
+ public TargetInvoker createTargetInvoker(ServiceContract contract, org.apache.tuscany.spi.model.Operation operation)
+ throws TargetInvokerCreationException {
+ if (!operation.isCallback()) {
+ throw new UnsupportedOperationException();
+ } else {
+ return new Axis2ServiceCallbackTargetInvoker(this);
+ }
+ }
+
+ public void addMapping(Object msgId, InvocationContext invCtx) {
+ this.invCtxMap.put(msgId, invCtx);
+ }
+
+ public InvocationContext retrieveMapping(Object msgId) {
+ return this.invCtxMap.get(msgId);
+ }
+
+ public void removeMapping(Object msgId) {
+ this.invCtxMap.remove(msgId);
+ }
+
+ /**
+ * @param inMC
+ * @return
+ */
+ protected static String getConversationID(MessageContext inMC) {
+ String conversationID = null;
+ Iterator i = inMC.getEnvelope().getHeader()
+ .getChildrenWithName(new QName("http://www.w3.org/2005/08/addressing", "From"));
+ for (; i.hasNext();) {
+ Object a = i.next();
+ if (a instanceof OMElement) {
+ OMElement ao = (OMElement) a;
+ for (Iterator rpI =
+ ao.getChildrenWithName(new QName("http://www.w3.org/2005/08/addressing", "ReferenceParameters"));
+ rpI.hasNext();) {
+ OMElement rpE = (OMElement) rpI.next();
+ for (
+ Iterator cidI = rpE.getChildrenWithName(WebServiceBindingDefinition.CONVERSATION_ID_REFPARM_QN);
+ cidI.hasNext();) {
+ OMElement cidE = (OMElement) cidI.next();
+ conversationID = cidE.getText();
+ }
+ }
+
+ }
+
+ }
+ return conversationID;
+ }
+
+ protected class InvocationContext {
+ public MessageContext inMessageContext;
+
+ public org.apache.tuscany.spi.model.Operation<?> operation;
+
+ public SOAPFactory soapFactory;
+
+ public CountDownLatch doneSignal;
+
+ public InvocationContext(MessageContext messageCtx,
+ org.apache.tuscany.spi.model.Operation<?> operation,
+ SOAPFactory soapFactory,
+ CountDownLatch doneSignal) {
+ this.inMessageContext = messageCtx;
+ this.operation = operation;
+ this.soapFactory = soapFactory;
+ this.doneSignal = doneSignal;
+ }
+ }
+
+ WorkContext getWorkContext() {
+ return workContext;
+ }
+
+ boolean isConversational() {
+ if (conversational == null) {
+ conversational = serviceContract.getInteractionScope() == InteractionScope.CONVERSATIONAL;
+
+ }
+ return conversational;
+ }
+
+ @Override
+ public boolean allowsPassByReference() {
+ return true;
+ }
+}
diff --git a/branches/sca-java-integration/sca/extensions/axis2/binding/src/main/java/org/apache/tuscany/binding/axis2/Axis2ServiceCallbackTargetInvoker.java b/branches/sca-java-integration/sca/extensions/axis2/binding/src/main/java/org/apache/tuscany/binding/axis2/Axis2ServiceCallbackTargetInvoker.java
new file mode 100644
index 0000000000..7ec4a13669
--- /dev/null
+++ b/branches/sca-java-integration/sca/extensions/axis2/binding/src/main/java/org/apache/tuscany/binding/axis2/Axis2ServiceCallbackTargetInvoker.java
@@ -0,0 +1,120 @@
+/*
+ * 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.binding.axis2;
+
+import java.lang.reflect.InvocationTargetException;
+
+import org.apache.tuscany.spi.wire.InvocationRuntimeException;
+import org.apache.tuscany.spi.wire.Message;
+import org.apache.tuscany.spi.wire.TargetInvoker;
+
+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.engine.AxisEngine;
+import org.apache.axis2.util.Utils;
+import org.apache.tuscany.binding.axis2.Axis2ServiceBinding.InvocationContext;
+
+public class Axis2ServiceCallbackTargetInvoker implements TargetInvoker {
+
+ private Axis2ServiceBinding service;
+
+ protected static final OMElement RESPONSE = null;
+
+ public Axis2ServiceCallbackTargetInvoker(Axis2ServiceBinding service) {
+ this.service = service;
+ }
+
+ public Object invokeTarget(final Object payload, final short sequence) throws InvocationTargetException {
+ throw new InvocationTargetException(new InvocationRuntimeException("Operation not supported"));
+ }
+
+ private Object invokeTarget(final Object payload, Object correlationId) throws InvocationTargetException {
+ try {
+ // Use current correlation id as index to retrieve inv context
+ InvocationContext invCtx = service.retrieveMapping(correlationId);
+
+ MessageContext outMC = Utils.createOutMessageContext(invCtx.inMessageContext);
+ outMC.getOperationContext().addMessageContext(outMC);
+
+ OMElement responseOM;
+ if (payload != null && !payload.getClass().isArray()) {
+ responseOM = (OMElement) payload;
+ } else {
+ responseOM = (OMElement) ((Object[]) payload)[0];
+ }
+ SOAPEnvelope soapEnvelope = invCtx.soapFactory.getDefaultEnvelope();
+ soapEnvelope.getBody().addChild(responseOM);
+ outMC.setEnvelope(soapEnvelope);
+ outMC.getOperationContext().setProperty(Constants.RESPONSE_WRITTEN, Constants.VALUE_TRUE);
+
+ AxisEngine engine =
+ new AxisEngine(
+ invCtx.inMessageContext.getOperationContext().getServiceContext().getConfigurationContext());
+ engine.send(outMC);
+
+ invCtx.doneSignal.countDown();
+
+ service.removeMapping(correlationId);
+ } catch (AxisFault e) {
+ throw new InvocationTargetException(e);
+ } catch (Throwable t) {
+ throw new Axis2BindingRunTimeException(t);
+ }
+
+ return RESPONSE;
+ }
+
+ public Message invoke(Message msg) throws InvocationRuntimeException {
+ try {
+ Object correlationId = msg.getCorrelationId();
+ if (correlationId == null) {
+ throw new InvocationRuntimeException("Missing correlation id");
+ }
+ Object resp = invokeTarget(msg.getBody(), correlationId);
+ msg.setBody(resp);
+ } catch (Throwable e) {
+ msg.setBodyWithFault(e);
+ }
+ return msg;
+ }
+
+ public Axis2ServiceCallbackTargetInvoker clone() throws CloneNotSupportedException {
+ try {
+ return (Axis2ServiceCallbackTargetInvoker) super.clone();
+ } catch (CloneNotSupportedException e) {
+ // will not happen
+ return null;
+ }
+ }
+
+ public boolean isCacheable() {
+ return true;
+ }
+
+ public void setCacheable(boolean cacheable) {
+
+ }
+
+ public boolean isOptimizable() {
+ return false;
+ }
+}
diff --git a/branches/sca-java-integration/sca/extensions/axis2/binding/src/main/java/org/apache/tuscany/binding/axis2/Axis2ServiceInMessageReceiver.java b/branches/sca-java-integration/sca/extensions/axis2/binding/src/main/java/org/apache/tuscany/binding/axis2/Axis2ServiceInMessageReceiver.java
new file mode 100644
index 0000000000..53b85ea887
--- /dev/null
+++ b/branches/sca-java-integration/sca/extensions/axis2/binding/src/main/java/org/apache/tuscany/binding/axis2/Axis2ServiceInMessageReceiver.java
@@ -0,0 +1,68 @@
+/*
+ * 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.binding.axis2;
+
+import java.lang.reflect.InvocationTargetException;
+
+import org.apache.axiom.om.OMElement;
+import org.apache.axis2.AxisFault;
+import org.apache.axis2.context.MessageContext;
+import org.apache.axis2.receivers.AbstractInMessageReceiver;
+import org.apache.tuscany.spi.model.Operation;
+import org.apache.tuscany.spi.wire.InvocationRuntimeException;
+
+public class Axis2ServiceInMessageReceiver extends AbstractInMessageReceiver {
+
+ protected Operation<?> operation;
+
+ private Axis2ServiceBinding axis2Service;
+
+ public Axis2ServiceInMessageReceiver(Axis2ServiceBinding service, Operation<?> operation) {
+ this.axis2Service = service;
+ this.operation = operation;
+ }
+
+ public Axis2ServiceInMessageReceiver() {
+
+ }
+
+ @Override
+ public void invokeBusinessLogic(MessageContext inMC) throws AxisFault {
+ try {
+ OMElement requestOM = inMC.getEnvelope().getBody().getFirstElement();
+ Object[] args = new Object[] {requestOM};
+ String conversationID = axis2Service.isConversational() ? Axis2ServiceBinding.getConversationID(inMC) : null;
+
+ axis2Service.invokeTarget(operation, args, null, conversationID);
+
+ } catch (InvocationTargetException e) {
+ Throwable t = e.getCause();
+ if (t instanceof Exception) {
+ throw AxisFault.makeFault((Exception)t);
+ }
+ throw new InvocationRuntimeException(e);
+ } catch (Throwable t) {
+ if (t instanceof Exception) {
+ throw AxisFault.makeFault((Exception)t);
+ }
+ throw new Axis2BindingRunTimeException(t);
+ }
+
+ }
+}
diff --git a/branches/sca-java-integration/sca/extensions/axis2/binding/src/main/java/org/apache/tuscany/binding/axis2/Axis2ServiceInOutAsyncMessageReceiver.java b/branches/sca-java-integration/sca/extensions/axis2/binding/src/main/java/org/apache/tuscany/binding/axis2/Axis2ServiceInOutAsyncMessageReceiver.java
new file mode 100644
index 0000000000..9d7b711701
--- /dev/null
+++ b/branches/sca-java-integration/sca/extensions/axis2/binding/src/main/java/org/apache/tuscany/binding/axis2/Axis2ServiceInOutAsyncMessageReceiver.java
@@ -0,0 +1,91 @@
+/*
+ * 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.binding.axis2;
+
+import java.lang.reflect.InvocationTargetException;
+import java.util.concurrent.CountDownLatch;
+
+import org.apache.axiom.om.OMElement;
+import org.apache.axis2.AxisFault;
+import org.apache.axis2.context.MessageContext;
+import org.apache.axis2.receivers.AbstractMessageReceiver;
+import org.apache.tuscany.binding.axis2.Axis2ServiceBinding.InvocationContext;
+import org.apache.tuscany.spi.model.Operation;
+import org.apache.tuscany.spi.wire.InvocationRuntimeException;
+import org.apache.tuscany.spi.wire.MessageId;
+
+public class Axis2ServiceInOutAsyncMessageReceiver extends AbstractMessageReceiver {
+
+ private Operation<?> operation;
+
+ private Axis2ServiceBinding service;
+
+ public Axis2ServiceInOutAsyncMessageReceiver(Axis2ServiceBinding service,
+ Operation operation) {
+ this.operation = operation;
+ this.service = service;
+ }
+
+ public Axis2ServiceInOutAsyncMessageReceiver() {
+ }
+
+ public final void receive(final MessageContext messageCtx) {
+ try {
+ Object messageId = messageCtx.getMessageID();
+ if (messageId == null) {
+ messageId = new MessageId();
+ }
+
+ // Now use message id as index to context to be used by callback
+ // target invoker
+ CountDownLatch doneSignal = new CountDownLatch(1);
+ InvocationContext invCtx =
+ service.new InvocationContext(messageCtx, operation, getSOAPFactory(messageCtx), doneSignal);
+ service.addMapping(messageId, invCtx);
+
+ invokeBusinessLogic(messageCtx, messageId);
+
+ try {
+ doneSignal.await();
+ } catch(InterruptedException e) {
+ e.printStackTrace();
+ }
+ } catch (AxisFault e) {
+ // log.error(e);
+ }
+ }
+
+ private void invokeBusinessLogic(MessageContext inMC, Object messageId) throws AxisFault {
+ try {
+ OMElement requestOM = inMC.getEnvelope().getBody().getFirstElement();
+ Object[] args = new Object[] {requestOM};
+ String conversationID = service.isConversational() ? Axis2ServiceBinding.getConversationID(inMC) : null;
+ service.invokeTarget(operation, args, messageId, conversationID);
+ } catch (InvocationTargetException e) {
+ Throwable t = e.getCause();
+ if (t instanceof Exception) {
+ throw AxisFault.makeFault((Exception)t);
+ }
+ throw new InvocationRuntimeException(e);
+ } catch (Exception e) {
+ throw AxisFault.makeFault(e);
+ }
+
+ }
+}
diff --git a/branches/sca-java-integration/sca/extensions/axis2/binding/src/main/java/org/apache/tuscany/binding/axis2/Axis2ServiceInOutSyncMessageReceiver.java b/branches/sca-java-integration/sca/extensions/axis2/binding/src/main/java/org/apache/tuscany/binding/axis2/Axis2ServiceInOutSyncMessageReceiver.java
new file mode 100644
index 0000000000..8af613450d
--- /dev/null
+++ b/branches/sca-java-integration/sca/extensions/axis2/binding/src/main/java/org/apache/tuscany/binding/axis2/Axis2ServiceInOutSyncMessageReceiver.java
@@ -0,0 +1,117 @@
+/*
+ * 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.binding.axis2;
+
+import java.lang.reflect.InvocationTargetException;
+
+import javax.xml.namespace.QName;
+
+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.spi.idl.ServiceFaultException;
+import org.apache.tuscany.spi.model.Operation;
+import org.apache.tuscany.spi.wire.InvocationRuntimeException;
+
+public class Axis2ServiceInOutSyncMessageReceiver extends AbstractInOutSyncMessageReceiver {
+
+ protected Operation<?> operation;
+
+ private Axis2ServiceBinding axis2Service;
+
+ public Axis2ServiceInOutSyncMessageReceiver(Axis2ServiceBinding service, Operation<?> operation) {
+ this.axis2Service = service;
+ this.operation = operation;
+ }
+
+ public Axis2ServiceInOutSyncMessageReceiver() {
+
+ }
+
+ @Override
+ public void invokeBusinessLogic(MessageContext inMC, MessageContext outMC) throws AxisFault {
+ QName envQName = null;
+ try {
+ envQName= inMC.getEnvelope().getQName();
+ OMElement requestOM = inMC.getEnvelope().getBody().getFirstElement();
+ Object[] args = new Object[] {requestOM};
+
+ String conversationID = axis2Service.isConversational() ? Axis2ServiceBinding.getConversationID(inMC) : null;
+
+ OMElement responseOM = (OMElement)axis2Service.invokeTarget(operation, args, null, conversationID);
+
+
+ SOAPEnvelope soapEnvelope = getSOAPFactory(inMC).getDefaultEnvelope();
+ if(null != responseOM ){
+ soapEnvelope.getBody().addChild(responseOM);
+ }
+ outMC.setEnvelope(soapEnvelope);
+ outMC.getOperationContext().setProperty(Constants.RESPONSE_WRITTEN, Constants.VALUE_TRUE);
+
+ } catch (InvocationTargetException e) {
+ // e.printStackTrace();
+ throw processMessageFault(envQName.getNamespaceURI(), e.getCause());
+ } catch(InvocationRuntimeException e){
+ // e.printStackTrace();
+ throw processMessageFault(envQName.getNamespaceURI(), e.getCause());
+ } catch (AxisFault e) {
+ // e.printStackTrace();
+ throw e;
+ } catch (Exception e) {
+ // e.printStackTrace();
+ throw AxisFault.makeFault(e);
+ }
+ }
+
+ /**
+ * @param envQName
+ * @param e
+ * @throws AxisFault
+ */
+ private AxisFault processMessageFault(String nsURI, Throwable t) {
+
+ if (t instanceof ServiceFaultException) { //Business fault.
+ OMElement faultdetail = null;
+ String reason = "";
+
+ ServiceFaultException sfe = (ServiceFaultException)t;
+ reason= sfe.getMessage();
+ reason = reason == null ? "" : reason;
+ Object finfo = sfe.getFaultInfo();
+
+ if (finfo instanceof OMElement) {
+ faultdetail = (OMElement)finfo;
+
+ }
+ QName faultCode= new QName(nsURI ,
+ org.apache.axiom.soap.SOAP12Constants.SOAP_FAULT_VALUE_SENDER);
+ return new AxisFault(faultCode, reason, null, null, faultdetail);
+
+
+ } else if ( t instanceof Exception) {
+ return AxisFault.makeFault((Exception) t);
+ }
+
+
+ return new AxisFault(t);
+ }
+}
diff --git a/branches/sca-java-integration/sca/extensions/axis2/binding/src/main/java/org/apache/tuscany/binding/axis2/Axis2ServiceServlet.java b/branches/sca-java-integration/sca/extensions/axis2/binding/src/main/java/org/apache/tuscany/binding/axis2/Axis2ServiceServlet.java
new file mode 100644
index 0000000000..74b79de3ed
--- /dev/null
+++ b/branches/sca-java-integration/sca/extensions/axis2/binding/src/main/java/org/apache/tuscany/binding/axis2/Axis2ServiceServlet.java
@@ -0,0 +1,211 @@
+/*
+ * 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.binding.axis2;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.util.Collections;
+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.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.apache.axis2.context.ConfigurationContext;
+import org.apache.axis2.transport.http.AxisServlet;
+
+/**
+ * This overrides the servlet init of the AxisServlet so Tuscany can use
+ * a single Axis2 ConfigurationContext instance shared between AxisServlet
+ * instances for each SCA service with a ws binding.
+ * TODO: need to review if thats really what we want to be doing
+ */
+public class Axis2ServiceServlet extends AxisServlet {
+
+ private static final long serialVersionUID = 1L;
+
+ private static final ServletConfig DUMMY_CONFIG = createDummyServletConfig();
+
+ private boolean inited;
+
+ public void init(ConfigurationContext configContext) {
+ this.configContext = configContext;
+ try {
+ super.init(DUMMY_CONFIG);
+ } catch (ServletException e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+ /**
+ * We've setup the Servlet by passing in a ConfigurationContext on our init method
+ * override this method to just return that
+ */
+ @Override
+ protected ConfigurationContext initConfigContext(ServletConfig config) throws ServletException {
+ return this.configContext;
+ }
+
+ /**
+ * The AxisServlet gets NPE during init without a ServletConfig so this is a mocked up one to prevent that.
+ */
+ private static ServletConfig createDummyServletConfig() {
+ ServletConfig sc = new ServletConfig() {
+
+ public String getServletName() {
+ return "TuscanyAxis2DummyServlet";
+ }
+
+ public ServletContext getServletContext() {
+ return new ServletContext() {
+
+ public ServletContext getContext(String uripath) {
+ return null;
+ }
+
+ public String getContextPath() {
+ return null;
+ }
+
+ public int getMajorVersion() {
+ return 0;
+ }
+
+ public int getMinorVersion() {
+ return 0;
+ }
+
+ public String getMimeType(String file) {
+ return null;
+ }
+
+ public Set getResourcePaths(String path) {
+ return Collections.emptySet();
+ }
+
+ public URL getResource(String path) throws MalformedURLException {
+ if("/".equals(path)) {
+ // HACK: To avoid NPE
+ return new URL("/axis2");
+ }
+ return null;
+ }
+
+ public InputStream getResourceAsStream(String path) {
+ return null;
+ }
+
+ public RequestDispatcher getRequestDispatcher(String path) {
+ 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;
+ }
+
+ @Override
+ protected void service(HttpServletRequest request, HttpServletResponse response)
+ throws ServletException, IOException {
+ // HACK: Get the correct context root which is not available during init() call
+ if (!inited) {
+ synchronized (configContext) {
+ configContext.setContextRoot(request.getContextPath());
+ inited = true;
+ }
+ }
+ super.service(request, response);
+ }
+
+}
diff --git a/branches/sca-java-integration/sca/extensions/axis2/binding/src/main/java/org/apache/tuscany/binding/axis2/Axis2TargetInvoker.java b/branches/sca-java-integration/sca/extensions/axis2/binding/src/main/java/org/apache/tuscany/binding/axis2/Axis2TargetInvoker.java
new file mode 100755
index 0000000000..52768b973c
--- /dev/null
+++ b/branches/sca-java-integration/sca/extensions/axis2/binding/src/main/java/org/apache/tuscany/binding/axis2/Axis2TargetInvoker.java
@@ -0,0 +1,186 @@
+/*
+ * 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.binding.axis2;
+
+import java.lang.reflect.InvocationTargetException;
+import javax.xml.namespace.QName;
+
+import org.apache.tuscany.spi.component.WorkContext;
+import org.apache.tuscany.spi.idl.ServiceFaultException;
+import org.apache.tuscany.spi.model.Scope;
+import org.apache.tuscany.spi.wire.InvocationRuntimeException;
+import org.apache.tuscany.spi.wire.Message;
+import org.apache.tuscany.spi.wire.TargetInvoker;
+
+import org.apache.axiom.om.OMElement;
+import org.apache.axiom.soap.SOAPBody;
+import org.apache.axiom.soap.SOAPEnvelope;
+import org.apache.axiom.soap.SOAPFactory;
+import org.apache.axiom.soap.SOAPHeader;
+import org.apache.axis2.AxisFault;
+import org.apache.axis2.addressing.AddressingConstants;
+import org.apache.axis2.addressing.EndpointReference;
+import org.apache.axis2.client.OperationClient;
+import org.apache.axis2.client.Options;
+import org.apache.axis2.client.ServiceClient;
+import org.apache.axis2.context.MessageContext;
+import org.apache.axis2.wsdl.WSDLConstants;
+
+/**
+ * Axis2TargetInvoker uses an Axis2 OperationClient to invoke a remote web
+ * service
+ */
+public class Axis2TargetInvoker implements TargetInvoker {
+
+ private QName wsdlOperationName;
+
+ private Options options;
+
+ private SOAPFactory soapFactory;
+
+ private ServiceClient serviceClient;
+
+ private WorkContext workContext;
+
+ public Axis2TargetInvoker(ServiceClient serviceClient,
+ QName wsdlOperationName,
+ Options options,
+ SOAPFactory soapFactory,
+ WorkContext workContext) {
+ this.wsdlOperationName = wsdlOperationName;
+ this.options = options;
+ this.soapFactory = soapFactory;
+ this.serviceClient = serviceClient;
+ this.workContext = workContext;
+ }
+
+ /**
+ * Invoke a WS operation
+ *
+ * @param payload
+ * @param sequence
+ * @return
+ * @throws InvocationTargetException
+ */
+ public Object invokeTarget(final Object payload, final short sequence) throws InvocationTargetException {
+ try {
+ Object[] args = (Object[])payload;
+ OperationClient operationClient = createOperationClient(args);
+
+ operationClient.execute(true);
+
+ MessageContext responseMC = operationClient.getMessageContext(WSDLConstants.MESSAGE_LABEL_IN_VALUE);
+
+ return responseMC.getEnvelope().getBody().getFirstElement();
+
+ } catch (AxisFault e) {
+ // convert exception to an exception independent on Axis runtime.
+ Throwable cause = e.getCause();
+ cause = cause == null ? e : cause;
+ ServiceFaultException serviceFaultException =
+ new ServiceFaultException(e.getMessage(), e.getDetail(), cause);
+ OMElement detail = e.getDetail();
+ if (null != detail) {
+ detail.getQName();
+ serviceFaultException.setLogical(detail.getQName());
+ }
+ throw new InvocationTargetException(serviceFaultException);
+
+ }
+
+ }
+
+ @SuppressWarnings("deprecation")
+ protected OperationClient createOperationClient(Object[] args) throws AxisFault {
+ SOAPEnvelope env = soapFactory.getDefaultEnvelope();
+ if (args != null && args.length > 0) {
+ SOAPBody body = env.getBody();
+ for (Object bc : args) {
+ if (bc instanceof OMElement) {
+ body.addChild((OMElement)bc);
+ } else {
+ throw new IllegalArgumentException(
+ "Can't handle mixed payloads betweem OMElements and other types.");
+ }
+ }
+ }
+ MessageContext requestMC = new MessageContext();
+ requestMC.setEnvelope(env);
+ // Axis2 operationClients can not be shared so create a new one for each
+ // request
+ OperationClient operationClient = serviceClient.createClient(wsdlOperationName);
+
+ if (workContext != null) {
+ String conversationId = (String)workContext.getIdentifier(Scope.CONVERSATION);
+ if (conversationId != null && conversationId.length() != 0) {
+ EndpointReference fromEPR = new EndpointReference(AddressingConstants.Final.WSA_ANONYMOUS_URL);
+ fromEPR.addReferenceParameter(WebServiceBindingDefinition.CONVERSATION_ID_REFPARM_QN, conversationId);
+ options.setFrom(fromEPR);
+ requestMC.setFrom(fromEPR); // who knows why two ways ?
+
+ // For now do this the brute force method. Need to figure out
+ // how to do axis addressing .. configure mar in flow.
+ SOAPEnvelope sev = requestMC.getEnvelope();
+ SOAPHeader sh = sev.getHeader();
+ OMElement el =
+ fromEPR.toOM(AddressingConstants.Final.WSA_NAMESPACE,
+ AddressingConstants.WSA_FROM,
+ AddressingConstants.WSA_DEFAULT_PREFIX);
+ sh.addChild(el);
+ }
+
+ }
+
+ operationClient.setOptions(options);
+ operationClient.addMessageContext(requestMC);
+ return operationClient;
+ }
+
+ public Message invoke(Message msg) throws InvocationRuntimeException {
+ try {
+ Object resp = invokeTarget(msg.getBody(), NONE);
+ msg.setBody(resp);
+ } catch (Throwable e) {
+ msg.setBodyWithFault(e);
+ }
+ return msg;
+ }
+
+ public Axis2TargetInvoker clone() throws CloneNotSupportedException {
+ try {
+ return (Axis2TargetInvoker)super.clone();
+ } catch (CloneNotSupportedException e) {
+ // will not happen
+ return null;
+ }
+ }
+
+ public boolean isCacheable() {
+ return true;
+ }
+
+ public void setCacheable(boolean cacheable) {
+
+ }
+
+ public boolean isOptimizable() {
+ return false;
+ }
+
+}
diff --git a/branches/sca-java-integration/sca/extensions/axis2/binding/src/main/java/org/apache/tuscany/binding/axis2/TuscanyDispatcher.java b/branches/sca-java-integration/sca/extensions/axis2/binding/src/main/java/org/apache/tuscany/binding/axis2/TuscanyDispatcher.java
new file mode 100644
index 0000000000..64ccb94193
--- /dev/null
+++ b/branches/sca-java-integration/sca/extensions/axis2/binding/src/main/java/org/apache/tuscany/binding/axis2/TuscanyDispatcher.java
@@ -0,0 +1,79 @@
+/*
+ * 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.binding.axis2;
+
+import java.net.URI;
+
+import org.apache.axis2.AxisFault;
+import org.apache.axis2.addressing.EndpointReference;
+import org.apache.axis2.context.ConfigurationContext;
+import org.apache.axis2.context.MessageContext;
+import org.apache.axis2.description.AxisService;
+import org.apache.axis2.description.HandlerDescription;
+import org.apache.axis2.engine.AxisConfiguration;
+import org.apache.axis2.engine.RequestURIBasedDispatcher;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+/**
+ */
+public class TuscanyDispatcher extends RequestURIBasedDispatcher {
+
+ public static final String NAME = "TuscanyDispatcher";
+ private static final Log log = LogFactory.getLog(RequestURIBasedDispatcher.class);
+ private static final boolean isDebugEnabled = log.isDebugEnabled();
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.apache.axis2.engine.AbstractDispatcher#findService(org.apache.axis2.context.MessageContext)
+ */
+ public AxisService findService(MessageContext messageContext) throws AxisFault {
+ EndpointReference toEPR = messageContext.getTo();
+
+ if (toEPR != null) {
+ if(isDebugEnabled){
+ log.debug("Checking for Service using target endpoint address : " + toEPR.getAddress());
+ }
+
+ String path = URI.create(toEPR.getAddress()).getPath();
+
+ // remove the leading slash
+ if (path != null && path.length() > 1 && path.startsWith("/")) {
+ path = path.substring(1);
+ }
+
+ ConfigurationContext configurationContext = messageContext.getConfigurationContext();
+ AxisConfiguration registry = configurationContext.getAxisConfiguration();
+
+ return registry.getService(path);
+
+ } else {
+ if(isDebugEnabled){
+ log.debug("Attempted to check for Service using null target endpoint URI");
+ }
+ return null;
+ }
+ }
+
+ public void initDispatcher() {
+ init(new HandlerDescription(NAME));
+ }
+}
diff --git a/branches/sca-java-integration/sca/extensions/axis2/binding/src/main/java/org/apache/tuscany/binding/axis2/WebServiceBindingDefinition.java b/branches/sca-java-integration/sca/extensions/axis2/binding/src/main/java/org/apache/tuscany/binding/axis2/WebServiceBindingDefinition.java
new file mode 100755
index 0000000000..3f59ec0130
--- /dev/null
+++ b/branches/sca-java-integration/sca/extensions/axis2/binding/src/main/java/org/apache/tuscany/binding/axis2/WebServiceBindingDefinition.java
@@ -0,0 +1,210 @@
+/*
+ * 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.binding.axis2;
+
+
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.util.List;
+import java.util.Map;
+
+import javax.wsdl.Binding;
+import javax.wsdl.Definition;
+import javax.wsdl.Port;
+import javax.wsdl.Service;
+import javax.wsdl.extensions.soap.SOAPAddress;
+import javax.xml.namespace.QName;
+
+import org.apache.tuscany.spi.model.BindingDefinition;
+import org.osoa.sca.Constants;
+
+/**
+ * Represents a Celtix binding configuration in an assembly
+ *
+ * @version $Rev$ $Date$
+ */
+public class WebServiceBindingDefinition extends BindingDefinition {
+ public static final QName CONVERSATION_ID_REFPARM_QN = new QName(Constants.SCA_NS,"conversationID");
+ private Definition definition;
+ private Port port;
+ private Service service;
+ private String uri;
+ private String namespace;
+ private String serviceName;
+ private String portName;
+ private String bindingName;
+ private Binding binding;
+ private boolean spec10Compliant; // hack just to allow any existing WS scdl to still work for now
+ private URI actualURI;
+
+ /**
+ * @deprecated pre 1.0 binding.ws spec
+ */
+ @Deprecated
+ public WebServiceBindingDefinition(Definition definition, Port port, String uri, String portURI, Service service) {
+ this.definition = definition;
+ this.port = port;
+ this.uri = uri;
+ this.service = service;
+ }
+
+ public WebServiceBindingDefinition(String ns, Definition definition, String serviceName, String portName, String bindingName, String uri) {
+ this.namespace = ns;
+ this.definition = definition;
+ this.serviceName = serviceName;
+ this.portName = portName;
+ this.bindingName = bindingName;
+ this.uri = uri;
+ this.spec10Compliant = true;
+ }
+
+ public Port getWSDLPort() {
+ if (port == null) {
+ Service service = getWSDLService();
+ if (portName == null) {
+ Map ports = service.getPorts();
+ if (ports.size() != 1) {
+ throw new IllegalStateException("when portName is null WSDL service must have exactly one WSDL port");
+ }
+ port = (Port)ports.values().iterator().next();
+ } else {
+ port = service.getPort(portName);
+ }
+ }
+ return port;
+ }
+
+ public Service getWSDLService() {
+ if (service == null) {
+ if (definition == null) {
+ throw new IllegalStateException("WSDL definition is null");
+ }
+ Map services = definition.getServices();
+ if (serviceName != null) {
+ QName serviceQN = new QName(namespace, serviceName);
+ for (Object o : services.values()) {
+ Service s = (Service) o;
+ if (s.getQName().equals(serviceQN)) {
+ service = s;
+ break;
+ }
+ }
+ if (service == null) {
+ throw new IllegalStateException("no service: " + serviceQN);
+ }
+ } else {
+ service = (Service)services.values().iterator().next();
+ }
+ }
+ return service;
+ }
+
+ public void setWSDLPort(Port value) {
+ port = value;
+ }
+
+ public Definition getWSDLDefinition() {
+ return definition;
+ }
+
+ public void setWSDLDefinition(Definition def) {
+ definition = def;
+ }
+
+ public String getURI() {
+ return uri;
+ }
+
+ public URI getPortURI() {
+ URI portURI = null;
+ if (definition != null) {
+ Port port = getWSDLPort();
+ final List wsdlPortExtensions = port.getExtensibilityElements();
+ for (final Object extension : wsdlPortExtensions) {
+ if (extension instanceof SOAPAddress) {
+ try {
+ portURI = new URI(((SOAPAddress) extension).getLocationURI());
+ } catch (URISyntaxException e) {
+ throw new RuntimeException(e);
+ }
+ break;
+ }
+ }
+ }
+ return portURI;
+ }
+
+ public void setURI(String theUri) {
+ this.uri = theUri;
+ }
+
+ public Binding getBinding() {
+ if (binding == null) {
+ if (definition == null) {
+ throw new IllegalStateException("WSDL definition is null");
+ }
+ QName bindingQN = new QName(namespace, bindingName);
+ this.binding = definition.getBinding(bindingQN);
+ if (binding == null) {
+ throw new IllegalStateException("no binding: " + bindingQN);
+ }
+ }
+ return binding;
+ }
+
+ public String getWSDLNamepace() {
+ return namespace;
+ }
+
+ public String getPortName() {
+ return portName;
+ }
+
+ public String getServiceName() {
+ return serviceName;
+ }
+
+ public String getBindingName() {
+ return bindingName;
+ }
+
+ public boolean isSpec10Compliant() {
+ return spec10Compliant;
+ }
+
+ public URI getActualURI() {
+ return actualURI;
+ }
+
+ public void setActualURI(URI actualURI) {
+ this.actualURI = actualURI;
+ }
+
+ public Object clone() {
+ WebServiceBindingDefinition clone =
+ new WebServiceBindingDefinition(this.namespace,
+ this.definition,
+ this.serviceName,
+ this.portName,
+ this.bindingName,
+ this.uri);
+
+ return clone;
+ }
+}
diff --git a/branches/sca-java-integration/sca/extensions/axis2/binding/src/main/java/org/apache/tuscany/binding/axis2/WebServiceBindingLoader.java b/branches/sca-java-integration/sca/extensions/axis2/binding/src/main/java/org/apache/tuscany/binding/axis2/WebServiceBindingLoader.java
new file mode 100755
index 0000000000..15b58b4305
--- /dev/null
+++ b/branches/sca-java-integration/sca/extensions/axis2/binding/src/main/java/org/apache/tuscany/binding/axis2/WebServiceBindingLoader.java
@@ -0,0 +1,244 @@
+/*
+ * 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.binding.axis2;
+
+import static org.osoa.sca.Constants.SCA_NS;
+
+import java.io.IOException;
+import java.util.Collection;
+
+import javax.wsdl.Definition;
+import javax.wsdl.Port;
+import javax.wsdl.Service;
+import javax.wsdl.WSDLException;
+import javax.xml.namespace.QName;
+import javax.xml.stream.XMLStreamException;
+import javax.xml.stream.XMLStreamReader;
+
+import org.apache.tuscany.idl.wsdl.WSDLDefinitionRegistry;
+import org.apache.tuscany.spi.annotation.Autowire;
+import org.apache.tuscany.spi.component.CompositeComponent;
+import org.apache.tuscany.spi.deployer.DeploymentContext;
+import org.apache.tuscany.spi.extension.LoaderExtension;
+import org.apache.tuscany.spi.loader.LoaderException;
+import org.apache.tuscany.spi.loader.LoaderRegistry;
+import org.apache.tuscany.spi.loader.LoaderUtil;
+import org.apache.tuscany.spi.model.ModelObject;
+
+import org.osoa.sca.annotations.Constructor;
+import org.osoa.sca.annotations.Scope;
+
+/**
+ * Parses a <code>WebServiceBindingDefinition</code> entry in an assembly XML file
+ *
+ * TODO: TUSCANY-1153 support <wsa:EndpointReference>
+ *
+ * @version $Rev$ $Date$
+ */
+@Scope("COMPOSITE")
+@SuppressWarnings("deprecation")
+public class WebServiceBindingLoader extends LoaderExtension<WebServiceBindingDefinition> {
+ public static final QName BINDING_WS = new QName(SCA_NS, "binding.ws");
+
+ private WSDLDefinitionRegistry wsdlDefinitionRegistry;
+
+ @Constructor( { "loaderRegistry", "wsdlDefinitionRegistry" })
+ public WebServiceBindingLoader(@Autowire LoaderRegistry loaderRegistry,
+ @Autowire WSDLDefinitionRegistry wsdlDefinitionRegistry) {
+ super(loaderRegistry);
+ this.wsdlDefinitionRegistry = wsdlDefinitionRegistry;
+ }
+
+ public QName getXMLType() {
+ return BINDING_WS;
+ }
+
+ public WebServiceBindingDefinition load(CompositeComponent parent, ModelObject object, XMLStreamReader reader,
+ DeploymentContext deploymentContext)
+ throws XMLStreamException, LoaderException {
+
+ String uri = reader.getAttributeValue(null, "uri");
+ String wsdlElement = reader.getAttributeValue(null, "wsdlElement");
+ String wsdliLocation = reader.getAttributeValue(null, "wsdlLocation");
+
+ // TODO: keep these old attributes for now for backward compatability
+ String endpoint = reader.getAttributeValue(null, "endpoint");
+ String wsdlLocation = reader.getAttributeValue(null, "location");
+
+ // TODO: support wsa:endpointreference
+
+ LoaderUtil.skipToEndElement(reader);
+
+ WebServiceBindingDefinition wsBinding;
+ if (endpoint != null && endpoint.length() > 0) {
+ // TODO: support these old attributes for now for backward compatability
+ try {
+ wsBinding = createBindingOld(uri, endpoint, wsdlLocation, deploymentContext);
+ } catch (Exception e) {
+ throw new LoaderException(e);
+ }
+ } else {
+ wsBinding = createWSBinding(wsdlElement, wsdliLocation, uri, deploymentContext);
+ }
+
+ return wsBinding;
+ }
+
+ protected WebServiceBindingDefinition createWSBinding(String wsdlElement, String wsdliLocation, String uri, DeploymentContext deploymentContext) throws LoaderException {
+ String ns = null;
+ String serviceName = null;
+ String portName = null;
+ String bindingName = null;
+
+ if (wsdlElement != null && wsdlElement.length() > 0) {
+
+ ns = getWSDLNamespace(wsdlElement);
+
+ String uriValue = getWSDLElementURIValue(wsdlElement, "wsdl.service");
+ if (uriValue != null) {
+ serviceName = uriValue;
+ } else {
+ uriValue = getWSDLElementURIValue(wsdlElement, "wsdl.port");
+ if (uriValue != null) {
+ int i = uriValue.lastIndexOf('/');
+ if (i == -1) {
+ throw new IllegalArgumentException("Missing '/' seperator between service and port in wsdl.port() in wsdlElement attribute");
+ }
+ serviceName = uriValue.substring(0, i);
+ portName = uriValue.substring(i+1);
+ } else {
+ uriValue = getWSDLElementURIValue(wsdlElement, "wsdl.endpoint");
+ if (uriValue != null) {
+ throw new IllegalArgumentException("WSDL 2.0 not supported for '#wsdl.endpoint' in wsdlElement attribute");
+ }
+ uriValue = getWSDLElementURIValue(wsdlElement, "wsdl.binding");
+ if (uriValue == null) {
+ throw new IllegalArgumentException("missing '#wsdl.service' or '#wsdl.port' or '#wsdl.endpoint'or '#wsdl.binding' in wsdlElement attribute");
+ }
+ bindingName = uriValue;
+ }
+ }
+ }
+
+ Definition definition = null;
+ if (wsdliLocation != null && wsdliLocation.length() > 0) {
+ try {
+ definition = wsdlDefinitionRegistry.loadDefinition(wsdliLocation, deploymentContext.getClassLoader());
+ } catch (Exception e) {
+ throw new LoaderException("Exception loading WSDL", e);
+ }
+ } else if (ns != null ){
+ definition = wsdlDefinitionRegistry.getDefinition(ns);
+ }
+
+ WebServiceBindingDefinition wsBinding = new WebServiceBindingDefinition(ns, definition, serviceName, portName, bindingName, uri);
+
+ return wsBinding;
+ }
+
+ protected String getWSDLElementURIValue(String wsdlElement, String type) {
+ String value = null;
+ String fullType = "#" + type + "(";
+ int i = wsdlElement.indexOf(fullType);
+ if (i > -1) {
+ int j = wsdlElement.indexOf(')',i);
+ if (j < 0) {
+ throw new IllegalArgumentException("missing closing bracket ')' on " + fullType + " in wsdlElement attribute");
+ }
+ value = wsdlElement.substring(i + fullType.length(), j);
+ }
+ return value;
+ }
+
+ protected String getWSDLNamespace(String wsdlElement) {
+ String ns = null;
+ if (wsdlElement != null && wsdlElement.length() > 0) {
+ int i = wsdlElement.indexOf('#');
+ if (i < 0) {
+ throw new IllegalArgumentException("missing '#' namespace delimiter in wsdlElement attribute");
+ }
+ if (i == 0) {
+ throw new IllegalArgumentException("no namespace in wsdlElement attribute");
+ }
+ ns = wsdlElement.substring(0, i);
+ }
+ return ns;
+ }
+
+ @SuppressWarnings("unchecked")
+ private WebServiceBindingDefinition createBindingOld(String uri, String endpoint, String wsdlLocation, DeploymentContext deploymentContext)
+ throws WSDLException, IOException, LoaderException {
+ // Get the WSDL port namespace and name
+ if (endpoint != null) {
+ int h = endpoint.indexOf('#');
+ String serviceName;
+ String portName;
+
+ String namespace = endpoint.substring(0, h);
+ String fragment = endpoint.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;
+ }
+ // FIXME need to find out how to get wsdl and what context to use --- terrible hack attack!
+ if (null == wsdlLocation) {
+ throw new Axis2BindingRunTimeException(
+ "Failed to determine wsdl location on binding. Try specifying 'location' attribute on binding.");
+ }
+ Definition definition =
+ wsdlDefinitionRegistry.loadDefinition(namespace+" "+wsdlLocation, deploymentContext.getClassLoader());
+
+ Port thePort = null;
+ Service service = null;
+ // Find the port with the given name
+ for (Service serv : (Collection<Service>) definition.getServices().values()) {
+ QName sqn = serv.getQName();
+ if (serviceName != null && !serviceName.equals(sqn.getLocalPart())) {
+ continue;
+ }
+
+ Port p = serv.getPort(portName);
+ if (p != null) {
+ service = serv;
+ thePort = p;
+ break;
+ }
+ }
+ if (thePort == null) {
+ throw new IllegalArgumentException("Cannot find WSDL port " + endpoint);
+
+ }
+ return new WebServiceBindingDefinition(definition, thePort, uri, endpoint, service);
+ }
+ // FIXME: Find the first port?
+ throw new LoaderException("Web Service endpoint cannot be resolved: " + endpoint);
+
+ }
+
+} \ No newline at end of file
diff --git a/branches/sca-java-integration/sca/extensions/axis2/binding/src/main/java/org/apache/tuscany/binding/axis2/util/TuscanyAxisConfigurator.java b/branches/sca-java-integration/sca/extensions/axis2/binding/src/main/java/org/apache/tuscany/binding/axis2/util/TuscanyAxisConfigurator.java
new file mode 100755
index 0000000000..c0ef46fee3
--- /dev/null
+++ b/branches/sca-java-integration/sca/extensions/axis2/binding/src/main/java/org/apache/tuscany/binding/axis2/util/TuscanyAxisConfigurator.java
@@ -0,0 +1,44 @@
+/*
+ * 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.binding.axis2.util;
+
+import org.apache.axis2.AxisFault;
+import org.apache.axis2.context.ConfigurationContext;
+import org.apache.axis2.context.ConfigurationContextFactory;
+import org.apache.axis2.deployment.URLBasedAxisConfigurator;
+import org.apache.axis2.engine.AxisConfigurator;
+
+/**
+ * Helps configure Axis2 from a resource in binding.axis2 instead of Axis2.xml
+ * <p/> TODO: Review: should there be a single global Axis
+ * ConfigurationContext
+ */
+public class TuscanyAxisConfigurator extends URLBasedAxisConfigurator implements AxisConfigurator {
+
+ public TuscanyAxisConfigurator() throws AxisFault {
+ super(TuscanyAxisConfigurator.class.getResource("/org/apache/tuscany/binding/axis2/engine/config/axis2.xml"), null);
+ }
+
+ public ConfigurationContext getConfigurationContext() throws AxisFault {
+ if (configContext == null)
+ configContext = ConfigurationContextFactory.createConfigurationContext(this);
+ return configContext;
+ }
+
+}
diff --git a/branches/sca-java-integration/sca/extensions/axis2/binding/src/main/java/org/apache/tuscany/binding/axis2/util/WebServiceOperationMetaData.java b/branches/sca-java-integration/sca/extensions/axis2/binding/src/main/java/org/apache/tuscany/binding/axis2/util/WebServiceOperationMetaData.java
new file mode 100755
index 0000000000..c5d3733d01
--- /dev/null
+++ b/branches/sca-java-integration/sca/extensions/axis2/binding/src/main/java/org/apache/tuscany/binding/axis2/util/WebServiceOperationMetaData.java
@@ -0,0 +1,491 @@
+/*
+ * 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.binding.axis2.util;
+
+import java.io.Serializable;
+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
+ */
+@SuppressWarnings({"all"})
+public class WebServiceOperationMetaData implements Serializable {
+ private static final long serialVersionUID = 2425306250256227724L;
+
+ // WSDL BindingDefinition and BindingOperation
+ private Binding binding;
+ private BindingOperation bindingOperation;
+ // Fields to cache derived metadata
+ private transient Set<Part> inputHeaderParts;
+ private transient Set<Part> outputHeaderParts;
+ private transient String style;
+ private transient String use;
+ private transient String soapAction;
+ private transient List<Object> 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<Part> getInputHeaderParts() {
+ if (inputHeaderParts == null) {
+ // Build a set of header parts that we need to exclude
+ inputHeaderParts = new HashSet<Part>();
+ 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<Part> getOutputHeaderParts() {
+ if (outputHeaderParts == null) {
+ // Build a set of header parts that we need to exclude
+ outputHeaderParts = new HashSet<Part>();
+ 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.
+ */
+ 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<String> getSOAPBodyParts(boolean input) {
+ javax.wsdl.extensions.soap.SOAPBody soapBody = getSOAPBody(input);
+ if (soapBody != null) {
+ List parts = soapBody.getParts();
+ if (parts != null) {
+ List<String> names = new ArrayList<String>();
+ 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
+ */
+ 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<String> styles = (List<String>) 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
+ */
+ public List<?> getOperationSignature() {
+ if (signature == null) {
+ signature = new ArrayList<Object>();
+
+ 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, 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<String> 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
+ */
+ public List<Integer> getBodyPartIndexes(boolean isInput) {
+ List<Integer> indexes = new ArrayList<Integer>();
+
+ Message message = getMessage(isInput);
+ if (message == null) {
+ return indexes;
+ }
+
+ List<String> 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
+ */
+ 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;
+ }
+
+}
diff --git a/branches/sca-java-integration/sca/extensions/axis2/binding/src/main/java/org/apache/tuscany/binding/axis2/util/WebServicePortMetaData.java b/branches/sca-java-integration/sca/extensions/axis2/binding/src/main/java/org/apache/tuscany/binding/axis2/util/WebServicePortMetaData.java
new file mode 100755
index 0000000000..a8d4f0f581
--- /dev/null
+++ b/branches/sca-java-integration/sca/extensions/axis2/binding/src/main/java/org/apache/tuscany/binding/axis2/util/WebServicePortMetaData.java
@@ -0,0 +1,377 @@
+/*
+ * 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.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.idl.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<WebServiceOperationMetaData> allOperationMetaData;
+ private WSDLServiceContract interfaceType;
+
+ /**
+ * Constructor
+ *
+ * @param wsdlDefinition
+ */
+ 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 portTypeName
+ * @param endpoint
+ */
+ 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.
+ */
+ 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 (final Object extension : wsdlPortExtensions) {
+ if (extension instanceof SOAPAddress) {
+ return ((SOAPAddress) extension).getLocationURI();
+ }
+ }
+ }
+
+ return null;
+ }
+
+ /**
+ * Returns the SOAP binding style.
+ */
+ 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
+ */
+ public String getUse() {
+ List<WebServiceOperationMetaData> list = getAllOperationMetaData();
+ return list.get(0).getUse();
+ }
+
+ /**
+ * Returns the encoding attribute
+ */
+ public String getEncoding() {
+ List<WebServiceOperationMetaData> 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
+ */
+ public static <T> T getExtensibilityElement(List elements, Class<T> type) {
+ for (Object element : elements) {
+ if (type.isInstance(element)) {
+ return type.cast(element);
+ }
+ }
+ return null;
+ }
+
+ /**
+ * Returns the extensibility elements of the given type.
+ *
+ * @param elements
+ * @param type
+ * @return List
+ */
+ public static <T> List<T> getExtensibilityElements(List elements, Class<T> type) {
+ List<T> result = new ArrayList<T>();
+ for (Object element : elements) {
+ if (type.isInstance(element)) {
+ result.add(type.cast(element));
+ }
+ }
+ return result;
+ }
+
+ /**
+ * Get the operation signature from the SOAP 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<WebServiceOperationMetaData> getAllOperationMetaData() {
+ if (allOperationMetaData == null) {
+ allOperationMetaData = new ArrayList<WebServiceOperationMetaData>();
+ 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 (WebServiceOperationMetaData webServiceOperationMetaData : getAllOperationMetaData()) {
+ WebServiceOperationMetaData descriptor = (WebServiceOperationMetaData) webServiceOperationMetaData;
+ String opName = descriptor.getBindingOperation().getOperation().getName();
+
+ if (opName.equals(operationName) || opName.equals(capatalizedOpName)) {
+ return descriptor;
+ }
+ }
+ return null;
+ }
+
+ /**
+ * Returns the WSDL service contract
+ *
+ * @return WSDLServiceContract
+ */
+ 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;
+ }
+
+}
diff --git a/branches/sca-java-integration/sca/extensions/axis2/binding/src/main/resources/META-INF/sca/binding.axis2.scdl b/branches/sca-java-integration/sca/extensions/axis2/binding/src/main/resources/META-INF/sca/binding.axis2.scdl
new file mode 100644
index 0000000000..ee1b8d9e81
--- /dev/null
+++ b/branches/sca-java-integration/sca/extensions/axis2/binding/src/main/resources/META-INF/sca/binding.axis2.scdl
@@ -0,0 +1,48 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ * 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.
+-->
+<!-- Axis2 based WebService binding extension -->
+<composite xmlns="http://www.osoa.org/xmlns/sca/1.0" xmlns:system="http://tuscany.apache.org/xmlns/system/1.0-SNAPSHOT"
+ name="org.apache.tuscany.binding.axis2.include">
+
+ <dependency xmlns="http://tuscany.apache.org/xmlns/1.0-SNAPSHOT">
+ <group>org.apache.tuscany.sca.extensions.axis2</group>
+ <name>tuscany-axis2</name>
+ <version>0.1-integration-incubating-SNAPSHOT</version>
+ </dependency>
+
+ <dependency xmlns="http://tuscany.apache.org/xmlns/1.0-SNAPSHOT">
+ <group>org.apache.tuscany.sca.extensions.axis2</group>
+ <name>databinding-axiom</name>
+ <version>0.1-integration-incubating-SNAPSHOT</version>
+ </dependency>
+
+ <component name="webservice.bindingLoader">
+ <system:implementation.system class="org.apache.tuscany.binding.axis2.WebServiceBindingLoader" />
+ </component>
+
+ <component name="webservice.axis2.bindingBuilder">
+ <system:implementation.system class="org.apache.tuscany.binding.axis2.Axis2BindingBuilder" />
+ </component>
+
+ <!-- A workaround to handle inter-extension dependencies -->
+ <include name="idl.wsdl" scdlResource="META-INF/sca/idl.wsdl.scdl" />
+ <include name="databinding.axiom" scdlResource="META-INF/sca/databinding.axiom.scdl" />
+
+</composite>
diff --git a/branches/sca-java-integration/sca/extensions/axis2/binding/src/main/resources/META-INF/sca/default.scdl b/branches/sca-java-integration/sca/extensions/axis2/binding/src/main/resources/META-INF/sca/default.scdl
new file mode 100644
index 0000000000..fd5c2f5baa
--- /dev/null
+++ b/branches/sca-java-integration/sca/extensions/axis2/binding/src/main/resources/META-INF/sca/default.scdl
@@ -0,0 +1,49 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ * 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.
+-->
+<!-- Axis2 based WebService binding extension -->
+<composite xmlns="http://www.osoa.org/xmlns/sca/1.0"
+ xmlns:system="http://tuscany.apache.org/xmlns/system/1.0-SNAPSHOT"
+ name="org.apache.tuscany.binding.axis2.WebServiceBinding">
+
+ <dependency xmlns="http://tuscany.apache.org/xmlns/1.0-SNAPSHOT">
+ <group>org.apache.tuscany.sca.extensions.axis2</group>
+ <name>tuscany-axis2</name>
+ <version>0.1-integration-incubating-SNAPSHOT</version>
+ </dependency>
+
+ <dependency xmlns="http://tuscany.apache.org/xmlns/1.0-SNAPSHOT">
+ <group>org.apache.tuscany.sca.extensions.axis2</group>
+ <name>databinding-axiom</name>
+ <version>0.1-integration-incubating-SNAPSHOT</version>
+ </dependency>
+
+ <component name="webservice.bindingLoader">
+ <system:implementation.system class="org.apache.tuscany.binding.axis2.WebServiceBindingLoader"/>
+ </component>
+
+ <component name="webservice.axis2.bindingBuilder">
+ <system:implementation.system class="org.apache.tuscany.binding.axis2.Axis2BindingBuilder"/>
+ </component>
+
+ <!-- A workaround to handle inter-extension dependencies -->
+ <include name="idl.wsdl" scdlResource="META-INF/sca/idl.wsdl.scdl"/>
+ <include name="databinding.axiom" scdlResource="META-INF/sca/databinding.axiom.scdl"/>
+
+</composite>
diff --git a/branches/sca-java-integration/sca/extensions/axis2/binding/src/main/resources/META-INF/sca/extension.composite b/branches/sca-java-integration/sca/extensions/axis2/binding/src/main/resources/META-INF/sca/extension.composite
new file mode 100644
index 0000000000..10306d8968
--- /dev/null
+++ b/branches/sca-java-integration/sca/extensions/axis2/binding/src/main/resources/META-INF/sca/extension.composite
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ * 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 peaxis2ssions and limitations
+ * under the License.
+-->
+<composite xmlns="http://www.osoa.org/xmlns/sca/1.0" name="org.apache.tuscany.binding.axis2">
+ <include name="org.apache.tuscany.binding.axis2.include" scdlLocation="binding.axis2.scdl" />
+</composite> \ No newline at end of file
diff --git a/branches/sca-java-integration/sca/extensions/axis2/binding/src/main/resources/org/apache/tuscany/binding/axis2/engine/config/axis2.xml b/branches/sca-java-integration/sca/extensions/axis2/binding/src/main/resources/org/apache/tuscany/binding/axis2/engine/config/axis2.xml
new file mode 100755
index 0000000000..e4f6d699f9
--- /dev/null
+++ b/branches/sca-java-integration/sca/extensions/axis2/binding/src/main/resources/org/apache/tuscany/binding/axis2/engine/config/axis2.xml
@@ -0,0 +1,306 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ * 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.
+-->
+<axisconfig name="AxisJava2.0">
+ <!-- ================================================= -->
+ <!-- Parameters -->
+ <!-- ================================================= -->
+ <parameter name="hotdeployment" locked="false">false</parameter>
+ <parameter name="hotupdate" locked="false">false</parameter>
+ <parameter name="enableMTOM" locked="false">false</parameter>
+ <parameter name="enableSwA" locked="false">false</parameter>
+
+ <!--Uncomment if you want to enable file caching for attachments -->
+ <!--parameter name="cacheAttachments" locked="false">true</parameter>
+ <parameter name="attachmentDIR" locked="false"></parameter>
+ <parameter name="sizeThreshold" locked="false">4000</parameter-->
+
+ <!--This will give out the timout of the configuration contexts, in seconds-->
+ <parameter name="ConfigContextTimeoutInterval" locked="false">30</parameter>
+
+ <!--During a fault, stacktrace can be sent with the fault message. The following flag will control -->
+ <!--that behaviour.-->
+ <parameter name="sendStacktraceDetailsWithFaults" locked="false">true</parameter>
+
+ <!--If there aren't any information available to find out the fault reason, we set the message of the expcetion-->
+ <!--as the faultreason/Reason. But when a fault is thrown from a service or some where, it will be -->
+ <!--wrapped by different levels. Due to this the initial exception message can be lost. If this flag-->
+ <!--is set then, Axis2 tries to get the first exception and set its message as the faultreason/Reason.-->
+ <parameter name="DrillDownToRootCauseForFaultReason" locked="false">false</parameter>
+
+ <parameter name="userName" locked="false">admin</parameter>
+ <parameter name="password" locked="false">axis2</parameter>
+
+ <!--Following params will set the proper context paths for invocations. All the endpoints will have a commons context-->
+ <!--root which can configured using the following contextRoot parameter-->
+ <!--<parameter name="contextRoot" locked="false">axis2</parameter>-->
+
+ <!--Our HTTP endpoints can handle both REST and SOAP. Following parameters can be used to distingiush those endpoints-->
+ <!--In case of a servlet, if you change this you have to manually change the settings of your servlet container to map this -->
+ <!--context path to proper Axis2 servlets-->
+ <!--<parameter name="servicePath" locked="false">services</parameter>-->
+ <!--<parameter name="restPath" locked="false">rest</parameter>-->
+
+
+ <!--Set the flag to true if you want to enable transport level session mangment-->
+ <parameter name="manageTransportSession" locked="false">false</parameter>
+
+ <!--Following two parameters will be used to handle REST in Axis2. The default settings will make Axis2 to have two-->
+ <!--different endpoints, one for REST (AxisRESTServlet) one for SOAP message handling (AxisServlet). But following-->
+ <!--parameters help to tweak the message handling of two main servlets. -->
+
+ <!-- If the enableRESTInAxis2MainServlet is true, then Axis2MainServlet will handle both SOAP and REST messages -->
+ <parameter name="enableRESTInAxis2MainServlet" locked="true">true</parameter>
+
+ <!-- Following parameter will completely disable REST handling in both the servlets-->
+ <parameter name="disableREST" locked="true">false</parameter>
+
+ <!-- This will disable the separate servlet we have for REST handling. -->
+ <parameter name="disableSeparateEndpointForREST" locked="true">false</parameter>
+
+ <!-- If you have a frontend host which exposes this webservice using a different public URL -->
+ <!-- use this parameter to override autodetected url -->
+ <!--<parameter name="httpFrontendHostUrl" locked="false">https://someotherhost/context</parameter>-->
+
+
+ <!-- The way of adding listener to the system-->
+ <!-- <listener class="org.apache.axis2.ObserverIMPL">-->
+ <!-- <parameter name="RSS_URL" locked="false">http://127.0.0.1/rss</parameter>-->
+ <!-- </listener>-->
+
+ <!-- ================================================= -->
+ <!-- Message Receivers -->
+ <!-- ================================================= -->
+ <!--This is the Deafult Message Receiver for the system , if you want to have MessageReceivers for -->
+ <!--all the other MEP implement it and add the correct entry to here , so that you can refer from-->
+ <!--any operation -->
+ <!--Note : You can ovride this for particular service by adding the same element with your requirement-->
+ <messageReceivers>
+ <messageReceiver mep="http://www.w3.org/2004/08/wsdl/in-only"
+ class="org.apache.tuscany.binding.axis2.Axis2ServiceInMessageReceiver"/>
+ <messageReceiver mep="http://www.w3.org/2004/08/wsdl/in-only"
+ class="org.apache.axis2.receivers.RawXMLINOnlyMessageReceiver"/>
+ <messageReceiver mep="http://www.w3.org/2004/08/wsdl/in-out"
+ class="org.apache.axis2.receivers.RawXMLINOutMessageReceiver"/>
+ <messageReceiver mep="http://www.w3.org/2004/08/wsdl/in-out"
+ class="org.apache.tuscany.binding.axis2.Axis2ServiceInOutAsyncMessageReceiver"/>
+ <messageReceiver mep="http://www.w3.org/2004/08/wsdl/in-out"
+ class="org.apache.tuscany.binding.axis2.Axis2ServiceInOutSyncMessageReceiver"/>
+ </messageReceivers>
+ <!-- ================================================= -->
+ <!-- Transport Ins -->
+ <!-- ================================================= -->
+ <transportReceiver name="http"
+ class="org.apache.axis2.transport.http.SimpleHTTPServer">
+ <parameter name="port" locked="false">6060</parameter>
+ <!-- Here is the complete list of supported parameters (see example settings further below):
+ port: the port to listen on (default 6060)
+ hostname: if non-null, url prefix used in reply-to endpoint references (default null)
+ originServer: value of http Server header in outgoing messages (default "Simple-Server/1.1")
+ requestTimeout: value in millis of time that requests can wait for data (default 20000)
+ requestTcpNoDelay: true to maximize performance and minimize latency (default true)
+ false to minimize bandwidth consumption by combining segments
+ requestCoreThreadPoolSize: number of threads available for request processing (unless queue fills up) (default 25)
+ requestMaxThreadPoolSize: number of threads available for request processing if queue fills us (default 150)
+ note that default queue never fills up: see HttpFactory
+ threadKeepAliveTime: time to keep threads in excess of core size alive while inactive (default 180)
+ note that no such threads can exist with default unbounded request queue
+ threadKeepAliveTimeUnit: TimeUnit of value in threadKeepAliveTime (default SECONDS) (default SECONDS)
+ -->
+ <!-- <parameter name="hostname" locked="false">http://www.myApp.com/ws</parameter> -->
+ <!-- <parameter name="originServer" locked="false">My-Server/1.1</parameter> -->
+ <!-- <parameter name="requestTimeout" locked="false">10000</parameter> -->
+ <!-- <parameter name="requestTcpNoDelay" locked="false">false</parameter> -->
+ <!-- <parameter name="requestCoreThreadPoolSize" locked="false">50</parameter> -->
+ <!-- <parameter name="RequestMaxThreadPoolSize" locked="false">100</parameter> -->
+ <!-- <parameter name="threadKeepAliveTime" locked="false">240000</parameter> -->
+ <!-- <parameter name="threadKeepAliveTimeUnit" locked="false">MILLISECONDS</parameter> -->
+ </transportReceiver>
+
+ <!--Uncomment this and configure as appropriate for JMS transport support, after setting up your JMS environment (e.g. ActiveMQ)
+ <transportReceiver name="jms" class="org.apache.axis2.transport.jms.JMSListener">
+ <parameter name="myTopicConnectionFactory" locked="false">
+ <parameter name="java.naming.factory.initial" locked="false">org.apache.activemq.jndi.ActiveMQInitialContextFactory</parameter>
+ <parameter name="java.naming.provider.url" locked="false">tcp://localhost:61616</parameter>
+ <parameter name="transport.jms.ConnectionFactoryJNDIName" locked="false">TopicConnectionFactory</parameter>
+ </parameter>
+
+ <parameter name="myQueueConnectionFactory" locked="false">
+ <parameter name="java.naming.factory.initial" locked="false">org.apache.activemq.jndi.ActiveMQInitialContextFactory</parameter>
+ <parameter name="java.naming.provider.url" locked="false">tcp://localhost:61616</parameter>
+ <parameter name="transport.jms.ConnectionFactoryJNDIName" locked="false">QueueConnectionFactory</parameter>
+ </parameter>
+
+ <parameter name="default" locked="false">
+ <parameter name="java.naming.factory.initial" locked="false">org.apache.activemq.jndi.ActiveMQInitialContextFactory</parameter>
+ <parameter name="java.naming.provider.url" locked="false">tcp://localhost:61616</parameter>
+ <parameter name="transport.jms.ConnectionFactoryJNDIName" locked="false">QueueConnectionFactory</parameter>
+ </parameter>
+ </transportReceiver>-->
+
+ <!--Uncomment if you want to have SMTP transport support-->
+ <!--<transportReceiver name="mail" class="org.apache.axis2.transport.mail.SimpleMailListener">-->
+ <!--<parameter name="transport.mail.pop3.host" locked="false">127.0.0.1</parameter>-->
+ <!--<parameter name="transport.mail.pop3.user" locked="false">axis2</parameter>-->
+ <!--<parameter name="transport.mail.pop3.password" locked="false">axis2</parameter>-->
+ <!--<parameter name="transport.mail.pop3.port" locked="false">110</parameter>-->
+ <!--<parameter name="transport.mail.replyToAddress" locked="false">axis2@127.0.0.1</parameter>-->
+ <!--</transportReceiver>-->
+
+ <transportReceiver name="tcp"
+ class="org.apache.axis2.transport.tcp.TCPServer">
+ <parameter name="port" locked="false">6060</parameter>
+ <!--If you want to give your own host address for EPR generation-->
+ <!--uncommet following paramter , and set as you required.-->
+ <!--<parameter name="hostname" locked="false">tcp://myApp.com/ws</parameter>-->
+ </transportReceiver>
+
+ <!-- ================================================= -->
+ <!-- Transport Outs -->
+ <!-- ================================================= -->
+
+ <transportSender name="tcp"
+ class="org.apache.axis2.transport.tcp.TCPTransportSender"/>
+ <transportSender name="local"
+ class="org.apache.axis2.transport.local.LocalTransportSender"/>
+ <transportSender name="http"
+ class="org.apache.axis2.transport.http.CommonsHTTPTransportSender">
+ <parameter name="PROTOCOL" locked="false">HTTP/1.1</parameter>
+ <parameter name="Transfer-Encoding" locked="false">chunked</parameter>
+ </transportSender>
+ <transportSender name="https"
+ class="org.apache.axis2.transport.http.CommonsHTTPTransportSender">
+ <parameter name="PROTOCOL" locked="false">HTTP/1.1</parameter>
+ <parameter name="Transfer-Encoding" locked="false">chunked</parameter>
+ </transportSender>
+
+ <!-- Commented out by Tuscany
+ <transportSender name="jms"
+ class="org.apache.axis2.transport.jms.JMSSender"/>
+ -->
+
+ <!-- Uncomment this one with the appropriate papameters to enable the SMTP transport Receiver
+ <transportSender name="mailto" class="org.apache.axis2.transport.mail.MailTransportSender">
+ <parameter name="transport.mail.smtp.host" locked="false">127.0.0.1</parameter>
+ <parameter name="transport.mail.smtp.user" locked="false">axis2</parameter>
+ <parameter name="transport.mail.smtp.password" locked="false">axis2</parameter>
+ <parameter name="transport.mail.smtp.port" locked="false">25</parameter>
+ </transportSender>
+ -->
+
+ <!-- ================================================= -->
+ <!-- Global Modules -->
+ <!-- ================================================= -->
+ <!-- Comment this to disable Addressing -->
+ <!-- Commented out by Tuscany
+ <module ref="addressing"/>
+ -->
+
+ <!--Configuring module , providing parameters for modules whether they refer or not-->
+ <!--<moduleConfig name="addressing">-->
+ <!--<parameter name="addressingPara" locked="false">N/A</parameter>-->
+ <!--</moduleConfig>-->
+
+ <!-- ================================================= -->
+ <!-- Phases -->
+ <!-- ================================================= -->
+ <phaseOrder type="InFlow">
+ <!-- System pre defined phases -->
+ <phase name="Transport">
+ <handler name="TuscanyDispatcher"
+ class="org.apache.tuscany.binding.axis2.TuscanyDispatcher">
+ <order phase="Transport"/>
+ </handler>
+ <handler name="RequestURIBasedDispatcher"
+ class="org.apache.axis2.engine.RequestURIBasedDispatcher">
+ <order phase="Transport"/>
+ </handler>
+ <handler name="SOAPActionBasedDispatcher"
+ class="org.apache.axis2.engine.SOAPActionBasedDispatcher">
+ <order phase="Transport"/>
+ </handler>
+ </phase>
+ <phase name="Security"/>
+ <phase name="PreDispatch"/>
+ <phase name="Dispatch" class="org.apache.axis2.engine.DispatchPhase">
+ <handler name="AddressingBasedDispatcher"
+ class="org.apache.axis2.engine.AddressingBasedDispatcher">
+ <order phase="Dispatch"/>
+ </handler>
+
+ <handler name="SOAPMessageBodyBasedDispatcher"
+ class="org.apache.axis2.engine.SOAPMessageBodyBasedDispatcher">
+ <order phase="Dispatch"/>
+ </handler>
+ <handler name="InstanceDispatcher"
+ class="org.apache.axis2.engine.InstanceDispatcher">
+ <order phase="Dispatch"/>
+ </handler>
+ </phase>
+ <!-- System pre defined phases -->
+ <!-- After Postdispatch phase module author or or service author can add any phase he want -->
+ <phase name="OperationInPhase"/>
+ </phaseOrder>
+ <phaseOrder type="OutFlow">
+ <!-- user can add his own phases to this area -->
+ <phase name="OperationOutPhase"/>
+ <!--system predefined phase-->
+ <!--these phase will run irrespective of the service-->
+ <phase name="PolicyDetermination"/>
+ <phase name="MessageOut"/>
+ <phase name="Security"/>
+ </phaseOrder>
+ <phaseOrder type="InFaultFlow">
+ <phase name="PreDispatch"/>
+ <phase name="Dispatch" class="org.apache.axis2.engine.DispatchPhase">
+ <handler name="RequestURIBasedDispatcher"
+ class="org.apache.axis2.engine.RequestURIBasedDispatcher">
+ <order phase="Dispatch"/>
+ </handler>
+
+ <handler name="SOAPActionBasedDispatcher"
+ class="org.apache.axis2.engine.SOAPActionBasedDispatcher">
+ <order phase="Dispatch"/>
+ </handler>
+
+ <handler name="AddressingBasedDispatcher"
+ class="org.apache.axis2.engine.AddressingBasedDispatcher">
+ <order phase="Dispatch"/>
+ </handler>
+
+ <handler name="SOAPMessageBodyBasedDispatcher"
+ class="org.apache.axis2.engine.SOAPMessageBodyBasedDispatcher">
+ <order phase="Dispatch"/>
+ </handler>
+ <handler name="InstanceDispatcher"
+ class="org.apache.axis2.engine.InstanceDispatcher">
+ <order phase="PostDispatch"/>
+ </handler>
+ </phase>
+ <!-- user can add his own phases to this area -->
+ <phase name="OperationInFaultPhase"/>
+ </phaseOrder>
+ <phaseOrder type="OutFaultFlow">
+ <!-- user can add his own phases to this area -->
+ <phase name="OperationOutFaultPhase"/>
+ <phase name="PolicyDetermination"/>
+ <phase name="MessageOut"/>
+ </phaseOrder>
+</axisconfig>
+