Package org.apache.ws.resource.handler

Source Code of org.apache.ws.resource.handler.ResourceHandler

/*=============================================================================*
*  Copyright 2004 The Apache Software Foundation
*
*  Licensed under the Apache License, Version 2.0 (the "License");
*  you may not use this file except in compliance with the License.
*  You may obtain a copy of the License at
*
*      http://www.apache.org/licenses/LICENSE-2.0
*
*  Unless required by applicable law or agreed to in writing, software
*  distributed under the License is distributed on an "AS IS" BASIS,
*  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*  See the License for the specific language governing permissions and
*  limitations under the License.
*=============================================================================*/
package org.apache.ws.resource.handler;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.ws.resource.ResourceContext;
import org.apache.ws.resource.ResourceContextException;
import org.apache.ws.resource.i18n.Keys;
import org.apache.ws.resource.i18n.MessagesImpl;
import org.apache.ws.util.XmlBeanUtils;
import org.apache.ws.util.i18n.Messages;
import org.apache.xmlbeans.XmlObject;
import org.apache.xmlbeans.XmlOptions;
import org.xmlsoap.schemas.soap.envelope.Body;
import org.xmlsoap.schemas.soap.envelope.Envelope;
import org.xmlsoap.schemas.soap.envelope.EnvelopeDocument;

import javax.xml.namespace.QName;
import javax.xml.rpc.JAXRPCException;
import javax.xml.rpc.handler.GenericHandler;
import javax.xml.rpc.handler.MessageContext;
import javax.xml.rpc.handler.soap.SOAPMessageContext;
import javax.xml.rpc.soap.SOAPFaultException;
import javax.xml.soap.MessageFactory;
import javax.xml.soap.SOAPBody;
import javax.xml.soap.SOAPBodyElement;
import javax.xml.soap.SOAPEnvelope;
import javax.xml.soap.SOAPException;
import javax.xml.soap.SOAPMessage;
import javax.xml.soap.SOAPPart;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.List;

/**
* LOG-DONE Base class for platform-specific providers; also is a JAX-RPC Handler for more flexibility.
*
* @author Ian P. Springer
* @author Sal Campana
*/
public abstract class ResourceHandler
        extends GenericHandler
{
    private static final Log LOG = LogFactory.getLog( ResourceHandler.class );

    /**
     * DOCUMENT_ME
     */
    public static final Messages MSG = MessagesImpl.getInstance();

    /**
     * DOCUMENT_ME
     */
    private static final String WSRF_RESPONSE_XMLOBJECT_LIST = "WSRF_RESPONSE_XMLOBJECT_LIST";

    /**
     * DOCUMENT_ME
     */
    public static final String SERVICE_OPT_WSDL_TARGET_NAMESPACE = "wsdlTargetNamespace";

    /**
     * DOCUMENT_ME
     */
    public static final String SERVICE_OPT_SERVICE_CLASS_NAME = "serviceClassName";

    /**
     * DOCUMENT_ME
     */
    public static final String SERVICE_OPT_RESOURCE_KEY_QNAME = "resourceKeyQname";

    /**
     * DOCUMENT_ME
     */
    public static final String SERVICE_OPT_RESOURCE_KEY_CLASS_NAME = "resourceKeyClass";

    /**
     * DOCUMENT_ME
     */
    public static final String SERVICE_OPT_RESOURCE_HOME_CLASS_NAME = "resourceHomeClass";

    /**
     * DOCUMENT_ME
     */
    public static final String SOAP_ENVELOPE_XMLBEAN = "apollo.soapEnvelopeXmlBean";

    /**
     * DOCUMENT_ME
     *
     * @return DOCUMENT_ME
     */
    public QName[] getHeaders()
    {
        return new QName[0];
    }

    /**
     * DOCUMENT_ME
     *
     * @param msgContext DOCUMENT_ME
     *
     * @return DOCUMENT_ME
     */
    public boolean handleRequest( MessageContext msgContext )
    {
        try
        {
            LOG.debug( MSG.getMessage( Keys.RECEIVED_REQUEST ) );
            SOAPMessageContext soapMsgContext = (SOAPMessageContext) msgContext;
            SOAPEnvelope envelope = soapMsgContext.getMessage().getSOAPPart().getEnvelope();
            EnvelopeDocument envelopeDocXmlBean = EnvelopeDocument.Factory.parse( envelope.toString() );
            Envelope envelopeXmlBean = envelopeDocXmlBean.getEnvelope();
            Body body = envelopeXmlBean.getBody();

            ResourceContext resourceContext = createResourceContext( soapMsgContext );
            resourceContext.setProperty( SOAP_ENVELOPE_XMLBEAN, envelopeXmlBean );
            List responseBodyElems = new ArrayList();

            XmlObject[] childElements = XmlBeanUtils.getChildElements( body );

            for ( int i = 0; i < childElements.length; i++ )
            {
                XmlObject requestXBean = childElements[i];

                //todo probably need to change method signatures to take types instead of documents to avoid this,
                requestXBean = XmlObject.Factory.parse( requestXBean.xmlText( new XmlOptions().setSaveOuter() ) );
                if ( requestXBean != null )
                {
                    Class serviceClass = getServiceClassName( resourceContext );
                    WsrfService service = createService( serviceClass, resourceContext );
                    Method serviceMethod = getServiceMethod( service, requestXBean );
                    LOG.debug( MSG.getMessage( Keys.INVOKE_RESOURCE_METHOD,
                            serviceMethod.getName() ) );
                    XmlObject responseXBean = null;
                    try
                    {
                        responseXBean = (XmlObject) serviceMethod.invoke( service,
                                new Object[]
                                {
                                    requestXBean
                                } );
                    }
                    catch ( InvocationTargetException ite )
                    {
                        LOG.error( MSG.getMessage( Keys.ERROR_INVOKING_METHOD_ON_SERVICE,
                                serviceMethod.getName(),
                                serviceClass.getName(),
                                ite ) );
                        throw ite.getCause();
                    }
                    if ( responseXBean != null )
                    {
                        responseBodyElems.add( responseXBean );
                    }
                }
            }
            if ( ! responseBodyElems.isEmpty() )
            {
                msgContext.setProperty( WSRF_RESPONSE_XMLOBJECT_LIST, responseBodyElems );
            }
        }
        catch ( Throwable t )
        {
            if ( t instanceof SOAPFaultException )
            {
                throw (SOAPFaultException) t;
            }
            else
            {
                t.printStackTrace();
                throw new JAXRPCException( MSG.getMessage( Keys.UNEXPECTED_ERROR_WITH_EXCEPTION, t ) );
            }
        }

        return false;
    }

    /**
     * DOCUMENT_ME
     *
     * @param messageContext DOCUMENT_ME
     *
     * @return DOCUMENT_ME
     */
    public boolean handleResponse( MessageContext messageContext )
    {
        LOG.debug( MSG.getMessage( Keys.HANDLING_RESPONSE ) );
        SOAPEnvelope responseEnvelope = getResponseEnvelope( (SOAPMessageContext) messageContext );
        List responseBodyElems = (List) messageContext.getProperty( WSRF_RESPONSE_XMLOBJECT_LIST );
        LOG.debug( MSG.getMessage( Keys.FOUND_RESP_ELEMS,
                Integer.toString( responseBodyElems.size() ) ) );

        if ( responseBodyElems != null )
        {
            try
            {
                SOAPBody body = responseEnvelope.getBody();
                for ( int i = 0; i < responseBodyElems.size(); i++ )
                {
                    XmlObject responseBodyElem = (XmlObject) responseBodyElems.get( i );
                    body.addChildElement( createSOAPBodyElement( responseBodyElem ) );
                }
            }
            catch ( Exception e )
            {
                if ( e instanceof SOAPFaultException )
                {
                    throw (SOAPFaultException) e;
                }
                else
                {
                    e.printStackTrace();
                    throw new JAXRPCException( MSG.getMessage( Keys.UNEXPECTED_ERROR_WITH_EXCEPTION, e ) );
                }
            }
        }

        return true;
    }

    /**
     * Creates a {@link ResourceContext} for this request.
     *
     * @param soapMsgContext the JAX-RPC SOAP message context for this request
     *
     * @return a ResourceContext for this request
     */
    protected abstract ResourceContext createResourceContext( SOAPMessageContext soapMsgContext );

    /**
     * DOCUMENT_ME
     *
     * @param responseBodyElem DOCUMENT_ME
     *
     * @return DOCUMENT_ME
     */
    protected abstract SOAPBodyElement createSOAPBodyElement( XmlObject responseBodyElem );

    /**
     * DOCUMENT_ME
     *
     * @param resourceContext DOCUMENT_ME
     *
     * @return DOCUMENT_ME
     */
    protected Class getServiceClassName( ResourceContext resourceContext )
            throws ResourceContextException,
            ClassNotFoundException
    {
        String serviceClassName = resourceContext.getResourceHome().getServiceClassName();
        LOG.debug( MSG.getMessage( Keys.RETRIEVED_SERVICE_CLASSNAME, serviceClassName ) );
        if ( serviceClassName == null )
        {
            throw new JAXRPCException( MSG.getMessage( Keys.SERVICE_OPT_UNDEFINED_IN_HOME,
                    SERVICE_OPT_SERVICE_CLASS_NAME ) );
        }

        Class serviceClass = Class.forName( serviceClassName );
        return serviceClass;
    }

    /**
     * @param resourceContext
     * @param key
     *
     * @return
     */
    protected final String getServiceOption( ResourceContext resourceContext,
                                             String key )
    {
        return (String) resourceContext.getProperty( key );
    }

    /**
     * DOCUMENT_ME
     *
     * @param soapMsgContext DOCUMENT_ME
     *
     * @return DOCUMENT_ME
     */
    protected SOAPEnvelope getResponseEnvelope( SOAPMessageContext soapMsgContext )
    {
        return ( getEnvelope( getResponseMessage( soapMsgContext ) ) );
    }

    /**
     * @param soapMsgContext the response's JAX-RPC message context
     *
     * @return response JAX-RPC SOAP message
     */
    protected SOAPMessage getResponseMessage( SOAPMessageContext soapMsgContext )
    {
        SOAPMessage soapMsg = soapMsgContext.getMessage();
        if ( soapMsg == null )
        {
            soapMsg = createSOAPMessage();
            soapMsgContext.setMessage( soapMsg );
        }

        return ( soapMsg );
    }

    /**
     * @param soap_msg a SAAJ SOAP message
     *
     * @return
     */
    private SOAPEnvelope getEnvelope( SOAPMessage soap_msg )
    {
        SOAPEnvelope soap_envelope = null;

        try
        {
            SOAPPart soap_part = soap_msg.getSOAPPart();

            soap_envelope = soap_part.getEnvelope();
        }
        catch ( SOAPException soape )
        {
        }

        return ( soap_envelope );
    }

    private Method getServiceMethod( WsrfService service,
                                     XmlObject requestXBean )
    {
        if ( LOG.isDebugEnabled() )
        {
            LOG.debug( MSG.getMessage( Keys.DERIVE_SERVICE_NAME_FROM_REQ,
                    requestXBean.toString() ) );
        }

        Method serviceMethod = null;
        String serviceMethodName =
                service.getMethodNameMap().getMethodName( XmlBeanUtils.getName( requestXBean ) );

        Method[] methods = service.getClass().getMethods();
        for ( int i = 0; i < methods.length; i++ )
        {
            Method method = methods[i];
            if ( method.getName().equals( serviceMethodName )
                    && ( method.getParameterTypes().length == 1 )
                    && method.getParameterTypes()[0].isInstance( requestXBean ) )
            {
                serviceMethod = method;
                break;
            }
        }

        if ( serviceMethod == null )
        {
            throw new JAXRPCException( MSG.getMessage( Keys.UNABLE_TO_FIND_METHOD_IN_SERVICE,
                    serviceMethodName,
                    service.getClass().getName() ) );
        }

        LOG.debug( MSG.getMessage( Keys.FOUND_SERVICE_METHOD,
                serviceMethod.getName() ) );
        return serviceMethod;
    }

    private SOAPMessage createSOAPMessage()
    {
        try
        {
            return MessageFactory.newInstance().createMessage();
        }
        catch ( SOAPException soape )
        {
            throw new JAXRPCException( MSG.getMessage( Keys.FAILED_TO_CREATE_SOAP_MSG ) );
        }
    }

    private WsrfService createService( Class serviceClass,
                                       ResourceContext resourceContext )
            throws NoSuchMethodException,
            InstantiationException,
            IllegalAccessException,
            InvocationTargetException
    {
        LOG.debug( MSG.getMessage( Keys.CREATING_INSTANCE_OF_SERVICE, serviceClass ) );
        Constructor serviceCtor = serviceClass.getConstructor( new Class[]
        {
            ResourceContext.class
        } );
        WsrfService service = (WsrfService) serviceCtor.newInstance( new Object[]
        {
            resourceContext
        } );
        return service;
    }
}
TOP

Related Classes of org.apache.ws.resource.handler.ResourceHandler

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.