You are viewing a plain text version of this content. The canonical link for it is here.
Posted to axis-cvs@ws.apache.org by sa...@apache.org on 2005/12/20 13:30:15 UTC

svn commit: r357970 - in /webservices/axis2/trunk/java/modules/core/src/org/apache/axis2: client/ description/ engine/

Author: sanjiva
Date: Tue Dec 20 04:30:01 2005
New Revision: 357970

URL: http://svn.apache.org/viewcvs?rev=357970&view=rev
Log:
First commit of cleaned up lighter weight client API. When fully completed,
the simplest client will look like this:

sc = new ServiceClient ();
sc.getOptions().setTo(..); // etc.
sc.sendReceive (OMElement);
// etc.

You can also add headers to the service client:
sc.addHeader (OMElement)
sc.addStringHeader (QName, String)

If you want more power and flexibility, then do
OperationClient oc = sc.createClient (QName of axis operation);

and now you can do:
	oc.addMessageContext (mc); // as many times as needed
	oc.execute (boolean); // indicating whether to block or not

(More stuff to be refined yet.)

This is not complete so its not hooked in yet but committing so I can
get help! Yes the build does work yet (esp. because its not hooked in :)!

Added:
    webservices/axis2/trunk/java/modules/core/src/org/apache/axis2/client/OperationClient.java
    webservices/axis2/trunk/java/modules/core/src/org/apache/axis2/client/ServiceClient.java
Modified:
    webservices/axis2/trunk/java/modules/core/src/org/apache/axis2/description/AxisOperation.java
    webservices/axis2/trunk/java/modules/core/src/org/apache/axis2/description/AxisOperationFactory.java
    webservices/axis2/trunk/java/modules/core/src/org/apache/axis2/description/OutOnlyAxisOperation.java
    webservices/axis2/trunk/java/modules/core/src/org/apache/axis2/engine/AxisConfiguration.java

Added: webservices/axis2/trunk/java/modules/core/src/org/apache/axis2/client/OperationClient.java
URL: http://svn.apache.org/viewcvs/webservices/axis2/trunk/java/modules/core/src/org/apache/axis2/client/OperationClient.java?rev=357970&view=auto
==============================================================================
--- webservices/axis2/trunk/java/modules/core/src/org/apache/axis2/client/OperationClient.java (added)
+++ webservices/axis2/trunk/java/modules/core/src/org/apache/axis2/client/OperationClient.java Tue Dec 20 04:30:01 2005
@@ -0,0 +1,102 @@
+package org.apache.axis2.client;
+
+import org.apache.axis2.AxisFault;
+import org.apache.axis2.context.MessageContext;
+import org.apache.axis2.engine.MessageReceiver;
+
+/**
+ * An operation client is the way an advanced user interacts with Axis2. Actual
+ * operation clients understand a specific MEP and hence their behavior is
+ * defined by their MEP. To interact with an operation client, you first get one
+ * from a specific AxisOperation. Then you set the messages into it one by one
+ * (whatever is available). Then, when you call execute() the client will
+ * execute what it can at that point. If executing the operation client results
+ * in a new message being created, then if a message receiver is registered with
+ * the client then the message will be delivered to that client.
+ */
+public interface OperationClient {
+    /**
+     * Sets the options that should be used for this particular client. This
+     * resets the entire set of options to use the new options - so you'd lose
+     * any option cascading that may have been set up.
+     * 
+     * @param options
+     *            the options
+     */
+    public void setOptions(Options options);
+
+    /**
+     * Return the options used by this client. If you want to set a single
+     * option, then the right way is to do getOptions() and set specific
+     * options.
+     * 
+     * @return the options, which will never be null.
+     */
+    public Options getOptions();
+
+    /**
+     * Add a message context to the client for processing. This method must not
+     * process the message - it only records it in the operation client.
+     * Processing only occurs when execute() is called.
+     * 
+     * @param mc
+     *            the message context
+     * @throws AxisFault
+     *             if this is called inappropriately.
+     */
+    public void addMessageContext(MessageContext mc) throws AxisFault;
+
+    /**
+     * Return a message from the client - will return null if the requested
+     * message is not available.
+     * 
+     * @param messageLabel
+     *            the message label of the desired message context
+     * @return the desired message context or null if its not available.
+     * @throws AxisFault
+     *             if the message label is invalid
+     */
+    public MessageContext getMessageContext(String messageLabel)
+            throws AxisFault;
+
+    /**
+     * Set the message receiver to be executed when a message comes into the MEP
+     * and the operation client is executed. This is the way the operation
+     * client provides notification that a message has been received by it.
+     * Exactly when its executed and under what conditions is a function of the
+     * specific operation client.
+     * 
+     * @param mr
+     *            the message receiver
+     */
+    public void setMessageReceiver(MessageReceiver mr);
+
+    /**
+     * Execute the MEP. What this does depends on the specific operation client.
+     * The basic idea is to have the operation client execute and do something
+     * with the messages that have been added to it so far. For example, if its
+     * an Out-In MEP, then if the Out message has been set, then executing the
+     * client asks it to send the message and get the In message, possibly using
+     * a different thread.
+     * 
+     * @param block
+     *            Indicates whether execution should block or return ASAP. What
+     *            block means is of course a function of the specific operation
+     *            client.
+     * @throws AxisFault
+     *             if something goes wrong during the execution of the operation
+     *             client.
+     */
+    public void execute(boolean block) throws AxisFault;
+
+    /**
+     * Reset the operation client to a clean status after the MEP has completed.
+     * This is how you can reuse an operation client. NOTE: this does not reset
+     * the options; only the internal state so the client can be used again.
+     * 
+     * @throws AxisFault
+     *             if reset is called before the MEP client has completed an
+     *             interaction.
+     */
+    public void reset() throws AxisFault;
+}

Added: webservices/axis2/trunk/java/modules/core/src/org/apache/axis2/client/ServiceClient.java
URL: http://svn.apache.org/viewcvs/webservices/axis2/trunk/java/modules/core/src/org/apache/axis2/client/ServiceClient.java?rev=357970&view=auto
==============================================================================
--- webservices/axis2/trunk/java/modules/core/src/org/apache/axis2/client/ServiceClient.java (added)
+++ webservices/axis2/trunk/java/modules/core/src/org/apache/axis2/client/ServiceClient.java Tue Dec 20 04:30:01 2005
@@ -0,0 +1,320 @@
+package org.apache.axis2.client;
+
+import java.net.URL;
+import java.util.ArrayList;
+
+import javax.xml.namespace.QName;
+
+import org.apache.axis2.AxisFault;
+import org.apache.axis2.client.async.Callback;
+import org.apache.axis2.context.ConfigurationContext;
+import org.apache.axis2.context.ConfigurationContextFactory;
+import org.apache.axis2.context.MessageContext;
+import org.apache.axis2.context.ServiceContext;
+import org.apache.axis2.context.ServiceGroupContext;
+import org.apache.axis2.description.AxisOperation;
+import org.apache.axis2.description.AxisService;
+import org.apache.axis2.description.OutInAxisOperation;
+import org.apache.axis2.description.OutOnlyAxisOperation;
+import org.apache.axis2.description.RobustOutOnlyAxisOperation;
+import org.apache.axis2.engine.AxisConfiguration;
+import org.apache.axis2.om.OMAbstractFactory;
+import org.apache.axis2.om.OMElement;
+import org.apache.axis2.soap.SOAP12Constants;
+import org.apache.axis2.soap.SOAPEnvelope;
+import org.apache.axis2.soap.SOAPFactory;
+import org.apache.axis2.soap.SOAPHeader;
+
+/**
+ * A ServiceClient class is used to create a client for a service. More details
+ * need to be explained here.
+ */
+public class ServiceClient {
+    // service and operation names used for anonymously stuff
+    private static final String ANON_SERVICE = "__ANONYMOUS_SERVICE__";
+
+    private static final QName ANON_OUT_ONLY_OP = new QName(
+            "__OPERATION_OUT_ONLY__");
+
+    private static final QName ANON_ROBUST_OUT_ONLY_OP = new QName(
+            "__OPERATION_ROBUST_OUT_ONLY__");
+
+    private static final QName ANON_OUT_IN_OP = new QName(
+            "__OPERATION_OUT_IN__");
+
+    // the metadata for the service that I'm clienting for
+    AxisService axisService;
+
+    // the configuration context in which I live
+    ConfigurationContext configContext;
+
+    // service context for this specific service instance
+    ServiceContext serviceContext;
+
+    // client options for this service interaction
+    Options options = new Options();
+
+    // list of headers to be sent with the simple APIs
+    ArrayList headers;
+
+    /**
+     * Create a service client configured to work with a specific AxisService.
+     * If this service is already in the world that's handed in (in the form of
+     * a ConfigurationContext) then I will happily work in it. If not I will
+     * create a small little virtual world and live there.
+     * 
+     * @param configContext
+     *            The configuration context under which this service lives (may
+     *            be null, in which case a new local one will be created)
+     * @param service
+     *            The AxisService to create a client for. Must not be null; bad
+     *            things will happen if it is.
+     * @throws AxisFault
+     *             if something goes wrong while creating a config context (if
+     *             needed)
+     */
+    public ServiceClient(ConfigurationContext configContext,
+            AxisService axisService) throws AxisFault {
+        // create a config context if needed
+        this.configContext = (configContext != null) ? configContext
+                : createDefaultConfigurationContext();
+        // add the service to the config context if it isn't in there already
+        AxisConfiguration axisConfig = this.configContext
+                .getAxisConfiguration();
+        if (axisConfig.getService(axisService.getName()) != null) {
+            axisConfig.addService(axisService);
+        }
+        this.axisService = axisService;
+        this.serviceContext = createServiceContext();
+    }
+
+    /**
+     * Create a service client for WSDL service identified by the QName of the
+     * wsdl:service element in a WSDL document.
+     * 
+     * @param configContext
+     *            The configuration context under which this service lives (may
+     *            be null, in which case a new local one will be created) *
+     * @param wsdlURL
+     *            The URL of the WSDL document to read
+     * @param wsdlServiceName
+     *            The QName of the WSDL service in the WSDL document to create a
+     *            client for
+     * @param portName
+     *            The name of the WSDL 1.1 port to create a client for. May be
+     *            null (if WSDL 2.0 is used or if only one port is there). .
+     * @throws AxisFault
+     *             if something goes wrong while creating a config context (if
+     *             needed)
+     */
+    public ServiceClient(ConfigurationContext configContext, URL wsdlURL,
+            QName wsdlServiceName, String portName) throws AxisFault {
+        // TODO: Srinath to write this code :)
+        throw new UnsupportedOperationException(
+                "ServiceClient currently does not support direct WSDL construction");
+    }
+
+    /**
+     * Create a service client by assuming an anonymous service and any other
+     * necessary information.
+     */
+    public ServiceClient() throws AxisFault {
+        // since I have not been created with real service metadata, let's
+        // create an anonymous service and add myself to a newly created default
+        // (and lonely) world where I'm the only service around
+        this(null, new AxisService(ANON_SERVICE));
+        // add anonymous operations as well for use with the shortcut client
+        // API. NOTE: We only add the ones we know we'll use later; if you use
+        // this constructor then you can't expect any magic!
+        axisService.addOperation(new RobustOutOnlyAxisOperation(
+                ANON_ROBUST_OUT_ONLY_OP));
+        axisService.addOperation(new OutOnlyAxisOperation(ANON_OUT_ONLY_OP));
+        axisService.addOperation(new OutInAxisOperation(ANON_OUT_IN_OP));
+    }
+
+    /**
+     * If I have not been created with real service metadata, let's create a
+     * temporary configuration context for this (lonely) client to live in.
+     */
+    private ConfigurationContext createDefaultConfigurationContext()
+            throws AxisFault {
+        return new ConfigurationContextFactory()
+                .buildClientConfigurationContext(null);
+    }
+
+    /**
+     * Create the service context for myself
+     */
+    private ServiceContext createServiceContext() {
+        // create a new service group context and then get the service context
+        // for myself as I'll need that later for stuff that I gotta do
+        ServiceGroupContext sgc = new ServiceGroupContext(configContext,
+                axisService.getParent());
+        return sgc.getServiceContext(axisService.getName());
+    }
+
+    /**
+     * Set the client configuration related to this service interaction.
+     */
+    public void setOptions(Options options) {
+        this.options = options;
+    }
+
+    /**
+     * Get the client configuration from this service interaction.
+     * 
+     * @return set of options set earlier.
+     */
+    public Options getOptions() {
+        return options;
+    }
+
+    /**
+     * Add an XML element as a header to be sent with interactions. This allows
+     * users to go a bit beyond the dirt simple XML in/out pattern using this
+     * simplified API. A header
+     * 
+     * @param header
+     *            The header to be added for interactions. Must not be null.
+     */
+    public void addHeader(OMElement header) {
+        if (headers == null) {
+            headers = new ArrayList();
+        }
+        headers.add(header);
+    }
+
+    /**
+     * Add a simple header consisting of some text (and a header name; duh) to
+     * be sent with interactions.
+     * 
+     * @see addHeader(OMElement)
+     * @param headerName
+     * @param headerText
+     */
+    public void addStringHeader(QName headerName, String headerText) {
+        OMElement omElement = OMAbstractFactory.getOMFactory().createOMElement(
+                headerName, null);
+        omElement.setText(headerText);
+        addHeader(omElement);
+    }
+
+    /**
+     * This is a simple client API to invoke a service operation who's MEP is
+     * Robust In-Only. This API can be used to simply send a bit of XML and
+     * possibly receive a fault. If you need more control over this interaction
+     * then you need to create a client (@see createClient()) for the operation
+     * and use that instead.
+     * 
+     * @param elem
+     *            The XML to send
+     * @throws AxisFault
+     *             if something goes wrong while sending it or if a fault is
+     *             received in response (per the Robust In-Only MEP).
+     */
+    public void sendRobust(OMElement elem) throws AxisFault {
+        // look up the appropriate axisop and create the client
+        OperationClient mepClient = axisService.getOperation(
+                ANON_ROBUST_OUT_ONLY_OP).createClient(serviceContext, options);
+
+        // create a message context with elem as the payload
+        /*
+         * MessageContext mc = new MessageContext(); SOAPEnvelope se =
+         * createEmptySOAPEnvelope(); se.getBody().addChild(se);
+         * mc.setEnvelope(se); // create a client and have it do the work of
+         * sending this out InOnlyMEPClient mepClient = new
+         * InOnlyMEPClient(serviceContext); mepClient.send("foo", mc);
+         */
+        throw new UnsupportedOperationException(
+                "ServiceClient.sendRobust is not yet implemented");
+    }
+
+    /**
+     * Send a bit of XML and forget about it. This API is used to interact with
+     * a service operation who's MEP is In-Only. That is, there is no
+     * opportunity to get an error from the service via this API; one may still
+     * get client-side errors, such as host unknown etc.
+     * 
+     * @param elem
+     *            The XML element to send to the service
+     * @throws AxisFault
+     *             If something goes wrong trying to send the XML
+     */
+    public void fireAndForget(OMElement elem) throws AxisFault {
+        // create a message context and put the payload in there along with any
+        // headers
+        MessageContext mc = new MessageContext();
+        mc.setServiceContext (serviceContext);
+        SOAPFactory sf = getSOAPFactory();
+        SOAPEnvelope se = sf.getDefaultEnvelope();
+        se.getBody().addChild(elem);
+        if (headers != null) {
+            SOAPHeader sh = se.getHeader();
+            for (int i = 0; i < headers.size(); i++) {
+                OMElement headerBlock = (OMElement) headers.get(i);
+                sh.addChild(headerBlock);
+            }
+        }
+
+        // look up the appropriate axisop and create the client
+        OperationClient mepClient = axisService.getOperation(ANON_OUT_ONLY_OP)
+                .createClient(serviceContext, options);
+
+        // add the message context there and have it go
+        mepClient.addMessageContext(mc);
+        mepClient.execute(true);
+    }
+
+    public OMElement sendReceive(OMElement elem) {
+        // look up the appropriate axisop and create the client
+        OperationClient mepClient = axisService.getOperation(ANON_OUT_IN_OP)
+                .createClient(serviceContext, options);
+        // TODO
+        throw new UnsupportedOperationException(
+                "ServiceClient.sendReceive() is not yet implemented");
+    }
+
+    public void sendReceiveNonblocking(OMElement elem, Callback callback) {
+        // look up the appropriate axisop and create the client
+        OperationClient mepClient = axisService.getOperation(ANON_OUT_IN_OP)
+                .createClient(serviceContext, options);
+        // TODO
+        throw new UnsupportedOperationException(
+                "ServiceClient.sendReceiveNonblocking() is not yet implemented");
+    }
+
+    /**
+     * Create a MEP client for a specific operation. This is the way one can
+     * create a full function MEP client which can be used to exchange messages
+     * for this specific operation. If you're using this then you must know what
+     * you're doing and need the full capabilities of Axis2's client
+     * architecture. This is meant for people with deep skin and not the light
+     * user.
+     * 
+     * @param operation
+     *            The QName of the operation to create a client for.
+     * @return a MEP client configured to talk to the given operation or null if
+     *         the operation name is not found.
+     */
+    public OperationClient createClient(QName operation) {
+        AxisOperation axisOp = axisService.getOperation(operation);
+        return (axisOp == null) ? null : axisOp.createClient(serviceContext,
+                options);
+    }
+
+    /**
+     * Return the SOAP factory to use depending on what options have been set
+     * (or default to SOAP 1.1)
+     * 
+     * @return the SOAP factory
+     */
+    private SOAPFactory getSOAPFactory() {
+        String soapVersionURI = options.getSoapVersionURI();
+        if (SOAP12Constants.SOAP_ENVELOPE_NAMESPACE_URI.equals(soapVersionURI)) {
+            return OMAbstractFactory.getSOAP12Factory();
+        } else {
+            // if its not SOAP 1.2 just assume SOAP 1.1
+            return OMAbstractFactory.getSOAP11Factory();
+        }
+    }
+}

Modified: webservices/axis2/trunk/java/modules/core/src/org/apache/axis2/description/AxisOperation.java
URL: http://svn.apache.org/viewcvs/webservices/axis2/trunk/java/modules/core/src/org/apache/axis2/description/AxisOperation.java?rev=357970&r1=357969&r2=357970&view=diff
==============================================================================
--- webservices/axis2/trunk/java/modules/core/src/org/apache/axis2/description/AxisOperation.java (original)
+++ webservices/axis2/trunk/java/modules/core/src/org/apache/axis2/description/AxisOperation.java Tue Dec 20 04:30:01 2005
@@ -1,6 +1,15 @@
 package org.apache.axis2.description;
 
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.Iterator;
+
+import javax.xml.namespace.QName;
+
 import org.apache.axis2.AxisFault;
+import org.apache.axis2.client.OperationClient;
+import org.apache.axis2.client.Options;
 import org.apache.axis2.context.ConfigurationContext;
 import org.apache.axis2.context.MessageContext;
 import org.apache.axis2.context.OperationContext;
@@ -15,12 +24,6 @@
 import org.apache.commons.logging.LogFactory;
 import org.apache.wsdl.WSDLConstants;
 
-import javax.xml.namespace.QName;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.HashMap;
-import java.util.Iterator;
-
 public abstract class AxisOperation
         implements ParameterInclude, DescriptionConstants, WSDLConstants {
     public static final String STYLE_RPC = "rpc";
@@ -408,5 +411,11 @@
 
     public void setWsamappingList(ArrayList wsamappingList) {
         this.wsamappingList = wsamappingList;
+    }
+    /**
+     * 
+     */
+    public OperationClient createClient (ServiceContext sc, Options options){
+        throw new UnsupportedOperationException ("The MEP you are using (" + mepURI + ") has not implemented createClient().");
     }
 }

Modified: webservices/axis2/trunk/java/modules/core/src/org/apache/axis2/description/AxisOperationFactory.java
URL: http://svn.apache.org/viewcvs/webservices/axis2/trunk/java/modules/core/src/org/apache/axis2/description/AxisOperationFactory.java?rev=357970&r1=357969&r2=357970&view=diff
==============================================================================
--- webservices/axis2/trunk/java/modules/core/src/org/apache/axis2/description/AxisOperationFactory.java (original)
+++ webservices/axis2/trunk/java/modules/core/src/org/apache/axis2/description/AxisOperationFactory.java Tue Dec 20 04:30:01 2005
@@ -70,7 +70,7 @@
             }
 
             case MEP_CONSTANT_ROBUST_OUT_ONLY : {
-                abOpdesc = new OutInAxisOperation();
+                abOpdesc = new RobustOutOnlyAxisOperation();
 
                 break;
             }

Modified: webservices/axis2/trunk/java/modules/core/src/org/apache/axis2/description/OutOnlyAxisOperation.java
URL: http://svn.apache.org/viewcvs/webservices/axis2/trunk/java/modules/core/src/org/apache/axis2/description/OutOnlyAxisOperation.java?rev=357970&r1=357969&r2=357970&view=diff
==============================================================================
--- webservices/axis2/trunk/java/modules/core/src/org/apache/axis2/description/OutOnlyAxisOperation.java (original)
+++ webservices/axis2/trunk/java/modules/core/src/org/apache/axis2/description/OutOnlyAxisOperation.java Tue Dec 20 04:30:01 2005
@@ -1,19 +1,29 @@
 package org.apache.axis2.description;
 
+import java.util.ArrayList;
+
+import javax.xml.namespace.QName;
+
 import org.apache.axis2.AxisFault;
+import org.apache.axis2.addressing.EndpointReference;
+import org.apache.axis2.client.OperationClient;
+import org.apache.axis2.client.Options;
+import org.apache.axis2.context.ConfigurationContext;
 import org.apache.axis2.context.MessageContext;
 import org.apache.axis2.context.OperationContext;
+import org.apache.axis2.context.ServiceContext;
+import org.apache.axis2.engine.AxisEngine;
+import org.apache.axis2.engine.MessageReceiver;
 import org.apache.wsdl.WSDLConstants;
 
-import javax.xml.namespace.QName;
-import java.util.ArrayList;
-
 public class OutOnlyAxisOperation extends AxisOperation {
     private AxisMessage inFaultMessage;
 
     // just to keep the inflow , there wont be any usage
     private ArrayList inPhases;
+
     private AxisMessage outFaultMessage;
+
     private AxisMessage outMessage;
 
     public OutOnlyAxisOperation() {
@@ -34,13 +44,15 @@
         }
     }
 
-    public void addMessageContext(MessageContext msgContext, OperationContext opContext)
-            throws AxisFault {
+    public void addMessageContext(MessageContext msgContext,
+            OperationContext opContext) throws AxisFault {
         if (!opContext.isComplete()) {
-            opContext.getMessageContexts().put(MESSAGE_LABEL_OUT_VALUE, msgContext);
+            opContext.getMessageContexts().put(MESSAGE_LABEL_OUT_VALUE,
+                    msgContext);
             opContext.setComplete(true);
         } else {
-            throw new AxisFault("Invalid messge addition , operation context completed");
+            throw new AxisFault(
+                    "Invalid messge addition , operation context completed");
         }
     }
 
@@ -90,5 +102,193 @@
 
     public void setRemainingPhasesInFlow(ArrayList list) {
         inPhases = list;
+    }
+
+    /**
+     * Return a MEP client for an Out-only operation. This client can be used to
+     * interact with a server which is offering an In-only operation. To use the
+     * client, you must call addMessageContext() with a message context and then
+     * call execute() to execute the client. Note that the execute method's
+     * block parameter is ignored by this client and also the setMessageReceiver
+     * method cannot be used.
+     * 
+     * @param sc
+     *            The service context for this client to live within. Cannot be
+     *            null.
+     * @param options
+     *            Options to use as defaults for this client. If any options are
+     *            set specifically on the client then those override options
+     *            here.
+     */
+    public OperationClient createClient(ServiceContext sc, Options options) {
+        return new OutOnlyAxisOperationClient(this, sc, options);
+    }
+}
+
+/**
+ * MEP client for moi.
+ */
+class OutOnlyAxisOperationClient implements OperationClient {
+    OutOnlyAxisOperation axisOp;
+
+    ServiceContext sc;
+
+    Options options;
+
+    MessageContext mc;
+
+    /*
+     * indicates whether the MEP execution has completed (and hence ready for
+     * resetting)
+     */
+    boolean completed;
+
+    OutOnlyAxisOperationClient(OutOnlyAxisOperation axisOp, ServiceContext sc,
+            Options options) {
+        this.axisOp = axisOp;
+        this.sc = sc;
+        this.options = new Options(options);
+        this.completed = false;
+    }
+
+    /**
+     * Sets the options that should be used for this particular client. This
+     * resets the entire set of options to use the new options - so you'd lose
+     * any option cascading that may have been set up.
+     * 
+     * @param options
+     *            the options
+     */
+    public void setOptions(Options options) {
+        this.options = options;
+    }
+
+    /**
+     * Return the options used by this client. If you want to set a single
+     * option, then the right way is to do getOptions() and set specific
+     * options.
+     * 
+     * @return the options, which will never be null.
+     */
+    public Options getOptions() {
+        return options;
+    }
+
+    /**
+     * Add a message context to the client for processing. This method must not
+     * process the message - it only records it in the MEP client. Processing
+     * only occurs when execute() is called.
+     * 
+     * @param mc
+     *            the message context
+     * @throws AxisFault
+     *             if this is called inappropriately.
+     */
+    public void addMessageContext(MessageContext mc) throws AxisFault {
+        if (this.mc != null) {
+            throw new AxisFault(
+                    "Can't add message context again until client has been executed");
+        }
+        this.mc = mc;
+        this.completed = false;
+    }
+
+    /**
+     * Return a message from the client - will return null if the requested
+     * message is not available.
+     * 
+     * @param messageLabel
+     *            the message label of the desired message context
+     * @return the desired message context or null if its not available.
+     * @throws AxisFault
+     *             if the message label is invalid
+     */
+    public MessageContext getMessageContext(String messageLabel)
+            throws AxisFault {
+        if (messageLabel.equals(WSDLConstants.MESSAGE_LABEL_OUT_VALUE)) {
+            return mc;
+        }
+        throw new AxisFault("Unknown message label: '" + messageLabel + "'");
+    }
+
+    /**
+     * Set the message receiver to be executed when a message comes into the MEP
+     * and the MEP is executed. This is the way the MEP client provides
+     * notification that a message has been received by it. Exactly when its
+     * executed and under what conditions is a function of the specific MEP
+     * client.
+     * 
+     * @param mr
+     *            the message receiver
+     */
+    public void setMessageReceiver(MessageReceiver mr) {
+        throw new UnsupportedOperationException(
+                "This feature is not supported by this MEP");
+    }
+
+    /**
+     * Execute the MEP. What this does depends on the specific MEP client. The
+     * basic idea is to have the MEP client execute and do something with the
+     * messages that have been added to it so far. For example, if its an Out-In
+     * MEP, then if the Out message has been set, then executing the client asks
+     * it to send the message and get the In message, possibly using a different
+     * thread.
+     * 
+     * @param block
+     *            Indicates whether execution should block or return ASAP. What
+     *            block means is of course a function of the specific MEP
+     *            client. IGNORED BY THIS MEP CLIENT.
+     * @throws AxisFault
+     *             if something goes wrong during the execution of the MEP.
+     */
+    public void execute(boolean block) throws AxisFault {
+        if (completed) {
+            throw new AxisFault(
+                    "MEP is already completed- need to reset() before re-executing.");
+        }
+        ConfigurationContext cc = sc.getConfigurationContext();
+        
+        // copy interesting info from options to message context.
+        ClientUtils.copyInfoFromOptionsToMessageContext(options, mc);
+
+        // if the transport to use for sending is not specified, try to find it
+        // from the URL
+        TransportOutDescription senderTransport = options.getSenderTransport();
+        if (senderTransport == null) {
+            EndpointReference toEPR = (options.getTo() != null) ? options
+                    .getTo() : mc.getTo();
+            senderTransport = ClientUtils.inferOutTransport(cc
+                    .getAxisConfiguration(), toEPR);
+        }
+        mc.setTransportOut(senderTransport);
+
+        // create the operation context for myself
+        OperationContext oc = new OperationContext(axisOp, sc);
+        oc.addMessageContext(mc);
+        mc.setOperationContext(oc);
+
+        // ship it out
+        AxisEngine engine = new AxisEngine(cc);
+        engine.send(mc);
+
+        // all done
+        completed = true;
+    }
+
+    /**
+     * Reset the MEP client to a clean status after the MEP has completed. This
+     * is how you can reuse a MEP client. NOTE: this does not reset the options;
+     * only the internal state so the client can be used again.
+     * 
+     * @throws AxisFault
+     *             if reset is called before the MEP client has completed an
+     *             interaction.
+     */
+    public void reset() throws AxisFault {
+        if (!completed) {
+            throw new AxisFault("MEP is not yet complete: cannot reset");
+        }
+        mc = null;
+        completed = false;
     }
 }

Modified: webservices/axis2/trunk/java/modules/core/src/org/apache/axis2/engine/AxisConfiguration.java
URL: http://svn.apache.org/viewcvs/webservices/axis2/trunk/java/modules/core/src/org/apache/axis2/engine/AxisConfiguration.java?rev=357970&r1=357969&r2=357970&view=diff
==============================================================================
--- webservices/axis2/trunk/java/modules/core/src/org/apache/axis2/engine/AxisConfiguration.java (original)
+++ webservices/axis2/trunk/java/modules/core/src/org/apache/axis2/engine/AxisConfiguration.java Tue Dec 20 04:30:01 2005
@@ -437,7 +437,7 @@
      * @return Returns AxisService.
      * @throws AxisFault
      */
-    public AxisService getService(String name) throws AxisFault {
+    public AxisService getService(String name) {
         return (AxisService) allservices.get(name);
     }