Sample Document-Style Customizations

In the following code sample a document-oriented web service passing an XML document (message-style) web service is processed by a custom provider to allow for default credentials to be set based on the operation name.

Figure 1. Example Message Style Provider Override
package webservice;

import
  curam.util.connectors.webservice.CuramMsgStyleEJBMethodProvider;
import java.util.Vector;
import javax.xml.namespace.QName;
import org.apache.axis.AxisFault;
import org.apache.axis.Handler;
import org.apache.axis.MessageContext;
import org.apache.axis.description.OperationDesc;
import org.apache.axis.description.ServiceDesc;
import org.apache.axis.handlers.soap.SOAPService;
import org.apache.axis.i18n.Messages;
import org.apache.axis.message.MessageElement;
import org.apache.axis.message.SOAPEnvelope;

/**
 * A web services hook which extends the Curam message style
 * provider to enable the developer to do custom processing for
 * properties and then pass control to the Curam handler.
 */
public class CustomMsgStyleMethodProvider
  extends CuramMsgStyleEJBMethodProvider {

  /**
   * Process the message: Ensure the interface method matches
   * the supported Curam message style signature:
   * [public Document doSomething (Document xmlMessage)].
   *
   * Parse the SOAP body XML message into a Document object,
   * strip the root wrapper element, do the actual invocation
   * and restore the root wrapper element before responding.
   *
   * @param msgContext the active MessageContext
   * @param reqEnv the request SOAPEnvelope
   * @param resEnv the response SOAPEnvelope
   * @param obj the service target object
   * @throws Exception exception
   */
  @Override
  public void processMessage(final MessageContext msgContext,
    final SOAPEnvelope reqEnv, final SOAPEnvelope resEnv,
    final Object obj)
    throws Exception {

    try {

      OperationDesc operation = msgContext.getOperation();
      final SOAPService serviceHandler = msgContext.getService();
      final ServiceDesc serviceDesc =
        serviceHandler.getServiceDescription();
      QName opQName = null;

      // If operation not in the context extract from the
      // SOAP envelope.
      if (operation == null) {
        final Vector bodyElements = reqEnv.getBodyElements();
        if (bodyElements.size() > 0) {
          final MessageElement element =
            (MessageElement) bodyElements.get(0);
          if (element != null) {
            opQName = new QName(
              element.getNamespaceURI(), element.getLocalName());
            operation =
              serviceDesc.getOperationByElementQName(opQName);
          }
        }
      }

      // Cannot proceed without an operation name.
      if (operation == null) {
        throw new
          AxisFault(Messages.getMessage("noOperationForQName",
          opQName == null ? "null" : opQName.toString()));
      }

      // If this is a "public" operation we ensure
      // default credentials are supplied.
      if ("public_operation".equals(opQName.toString())) {

        final String jndiUserName = "jndiUser";
        String jndiUser = (serviceHandler != null)
          ? (String) serviceHandler.getOption(jndiUserName)
          : (String) getOption(jndiUserName);
        if (jndiUser == null || jndiUser.length() == 0) {
          serviceHandler.setOption(jndiUserName, "default");

          final String jndiPasswordName = "jndiPassword";
          serviceHandler.setOption(jndiPasswordName, "password");
        }
      }

      msgContext.setService(serviceHandler);

      // Process the message
      super.processMessage(msgContext, reqEnv, resEnv, obj);
    } catch (Exception e) {
      e.printStackTrace();
      throw e;
    }
  }
}

A custom message-style handler could also be used to intercept the (W3C) Document in the SOAP message to inspect and modify as the following illustrates:

package webservice;

import curam.util.exception.AppException;
import curam.util.message.INFRASTRUCTURE;
import curam.util.webservices.MessageProcessor;
import java.lang.reflect.Method;
import java.util.Vector;
import javax.xml.namespace.QName;
import org.apache.axis.AxisFault;
import org.apache.axis.MessageContext;
import org.apache.axis.description.OperationDesc;
import org.apache.axis.description.ServiceDesc;
import org.apache.axis.handlers.soap.SOAPService;
import org.apache.axis.i18n.Messages;
import org.apache.axis.message.MessageElement;
import org.apache.axis.message.SOAPBodyElement;
import org.apache.axis.message.SOAPEnvelope;
import org.w3c.dom.Document;
import org.w3c.dom.Node;

/**
 *
 */
public class CustomMsgStyleMethodProvider
extends CuramMsgStyleEJBMethodProvider {
  /**
   * Process the message: Ensure the interface method matches
   * the supported Curam message style:
   * [public Document doSomething (Document xmlMessage)].
   *
   * Parse the SOAP body XML message in to a Document object,
   * strip the root wrapper element, do the actual invocation
   * and restore the root wrapper element before responding.
   *
   * @param msgContext the active MessageContext
   * @param reqEnv the request SOAPEnvelope
   * @param resEnv the response SOAPEnvelope
   * @param obj the service target object
   * @throws Exception exception
   */
  @Override
  public void processMessage(final MessageContext msgContext,
    final SOAPEnvelope reqEnv, final SOAPEnvelope resEnv,
    final Object obj)
    throws Exception {


    OperationDesc operation = msgContext.getOperation();
    final SOAPService service = msgContext.getService();
    final ServiceDesc serviceDesc =
      service.getServiceDescription();
    QName opQName = null;

    // If operation not in the context extract from the
    // SOAP envelope.
    if (operation == null) {
      final Vector bodyElements = reqEnv.getBodyElements();
      if (bodyElements.size() > 0) {
        final MessageElement element =
          (MessageElement) bodyElements.get(0);
        if (element != null) {
          opQName = new QName(
            element.getNamespaceURI(), element.getLocalName());
          operation =
            serviceDesc.getOperationByElementQName(opQName);
        }
      }
    }

    // Cannot proceed without an operation name.
    if (operation == null) {
      throw new
        AxisFault(Messages.getMessage("noOperationForQName",
        opQName == null ? "null" : opQName.toString()));
    }

    final Method method = operation.getMethod();
    final int methodType = operation.getMessageOperationStyle();

    if (methodType == OperationDesc.MSG_METHOD_DOCUMENT) {
      // Dig out the body XML and invoke method.
      final Vector bodies = reqEnv.getBodyElements();

      Document doc =
        ((SOAPBodyElement) bodies.get(0)).getAsDocument();

      // Preserve wrapper root element, and then remove it.
      final Node root = doc.getDocumentElement();
      doc = MessageProcessor.removeWrapperElement(doc);


      // ********************************
      // Custom Document processing here.
      // ********************************
      // ...


      // Add XML to arg for invocation.
      final Object[] argObjects = new Object[1];
      argObjects[0] = doc;

      // Do the actual invocation of EJB method.
      // TODO: instantiate your own provider instead
      //       of CuramEJBMethodProvider.
      final CuramEJBMethodProvider ejbMP =
        new CuramEJBMethodProvider();
      Document resultDoc =
        (Document) ejbMP.
        invokeMethod(msgContext, method, obj, argObjects);

      // Add return XML to SOAP response
      if (resultDoc != null) {
        // Restore the wrapper root element that
        // was removed above.
        resultDoc =
          MessageProcessor.
          restoreWrapperElement(root, resultDoc);

        resEnv.addBodyElement(
          new SOAPBodyElement(resultDoc.getDocumentElement()));
      }
      return;
    }
  }
}