FileDocCategorySizeDatePackage
BSFProvider.javaAPI DocApache Axis 1.47798Sat Apr 22 18:57:28 BST 2006org.apache.axis.providers

BSFProvider

public class BSFProvider extends BasicProvider

Fields Summary
protected static Log
log
public static final String
OPTION_LANGUAGE
public static final String
OPTION_SRC
public static final String
OPTION_SCRIPT
Constructors Summary
Methods Summary
public voidinitServiceDesc(org.apache.axis.handlers.soap.SOAPService service, org.apache.axis.MessageContext msgContext)

    
public voidinvoke(org.apache.axis.MessageContext msgContext)


          
        try {
            SOAPService service = msgContext.getService();
            String language = (String) service.getOption(OPTION_LANGUAGE);
            String scriptStr = (String) service.getOption(OPTION_SRC);

            if (log.isDebugEnabled()) {
                log.debug("Enter: BSFProvider.processMessage()");
            }

            OperationDesc operation = msgContext.getOperation();

            Vector bodies = msgContext.getRequestMessage().getSOAPEnvelope().getBodyElements();
            if (log.isDebugEnabled()) {
                log.debug(Messages.getMessage("bodyElems00", "" + bodies.size()));
                log.debug(Messages.getMessage("bodyIs00", "" + bodies.get(0)));
            }

            RPCElement body = null;
            
            // Find the first "root" body element, which is the RPC call.
            for (int bNum = 0; body == null && bNum < bodies.size(); bNum++) {
                // If this is a regular old SOAPBodyElement, and it's a root,
                // we're probably a non-wrapped doc/lit service.  In this case,
                // we deserialize the element, and create an RPCElement "wrapper"
                // around it which points to the correct method.
                // FIXME : There should be a cleaner way to do this...
                if (!(bodies.get(bNum) instanceof RPCElement)) {
                    SOAPBodyElement bodyEl = (SOAPBodyElement) bodies.get(bNum);
                    // igors: better check if bodyEl.getID() != null
                    // to make sure this loop does not step on SOAP-ENC objects
                    // that follow the parameters! FIXME?
                    if (bodyEl.isRoot() && operation != null && bodyEl.getID() == null) {
                        ParameterDesc param = operation.getParameter(bNum);
                        // at least do not step on non-existent parameters!
                        if (param != null) {
                            Object val = bodyEl.getValueAsType(param.getTypeQName());
                            body = new RPCElement("",
                                    operation.getName(),
                                    new Object[]{val});
                        }
                    }
                } else {
                    body = (RPCElement) bodies.get(bNum);
                }
            }

            String methodName = body.getMethodName();
            Vector args = body.getParams();
            int numArgs = args.size();

            Object[] argValues = new Object[numArgs];
            
            // Put the values contained in the RPCParams into an array
            // suitable for passing to java.lang.reflect.Method.invoke()
            // Make sure we respect parameter ordering if we know about it
            // from metadata, and handle whatever conversions are necessary
            // (values -> Holders, etc)
            for (int i = 0; i < numArgs; i++) {
                RPCParam rpcParam = (RPCParam) args.get(i);
                Object value = rpcParam.getObjectValue();

                // first check the type on the paramter
                ParameterDesc paramDesc = rpcParam.getParamDesc();

                // if we found some type info try to make sure the value type is
                // correct.  For instance, if we deserialized a xsd:dateTime in
                // to a Calendar and the service takes a Date, we need to convert
                if (paramDesc != null && paramDesc.getJavaType() != null) {

                    // Get the type in the signature (java type or its holder)
                    Class sigType = paramDesc.getJavaType();

                    // Convert the value into the expected type in the signature
                    value = JavaUtils.convert(value,
                            sigType);

                    rpcParam.setObjectValue(value);
                }
                argValues[i] = value;
            }

            Script script = ScriptFactory.getScript();
            Object result = script.run(language, service.getName(), scriptStr, methodName, argValues);

            RPCElement resBody = new RPCElement(methodName + "Response");
            resBody.setPrefix(body.getPrefix());
            resBody.setNamespaceURI(body.getNamespaceURI());
            resBody.setEncodingStyle(msgContext.getEncodingStyle());

            Message resMsg = msgContext.getResponseMessage();
            SOAPEnvelope resEnv;

            // If we didn't have a response message, make sure we set one up
            if (resMsg == null) {
                resEnv = new SOAPEnvelope(msgContext.getSOAPConstants());

                resMsg = new Message(resEnv);
                msgContext.setResponseMessage(resMsg);
            } else {
                resEnv = resMsg.getSOAPEnvelope();
            }

            QName returnQName = operation.getReturnQName();
            if (returnQName == null) {
                returnQName = new QName("", methodName + "Return");
            }

            // For SOAP 1.2, add a result
            if (msgContext.getSOAPConstants() ==
                    SOAPConstants.SOAP12_CONSTANTS) {
                returnQName = Constants.QNAME_RPC_RESULT;
            }

            RPCParam param = new RPCParam(returnQName, result);
            param.setParamDesc(operation.getReturnParamDesc());
            if (!operation.isReturnHeader()) {
                resBody.addParam(param);
            } else {
                resEnv.addHeader(new RPCHeaderParam(param));
            }

            resEnv.addBodyElement(resBody);

        } catch (Exception e) {
            entLog.debug(Messages.getMessage("toAxisFault00"), e);
            throw AxisFault.makeFault(e);
        }