Package org.apache.geronimo.j2ee.deployment.annotation

Source Code of org.apache.geronimo.j2ee.deployment.annotation.HandlerChainAnnotationHelper

/**
* 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.geronimo.j2ee.deployment.annotation;

import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.List;

import javax.jws.HandlerChain;
import javax.xml.ws.WebServiceRef;

import org.apache.geronimo.common.DeploymentException;
import org.apache.geronimo.deployment.xmlbeans.XmlBeansUtil;
import org.apache.geronimo.xbeans.javaee.HandlerChainsDocument;
import org.apache.geronimo.xbeans.javaee.PortComponentHandlerType;
import org.apache.geronimo.xbeans.javaee6.DescriptionType;
import org.apache.geronimo.xbeans.javaee6.HandlerChainType;
import org.apache.geronimo.xbeans.javaee6.HandlerChainsType;
import org.apache.geronimo.xbeans.javaee6.HandlerType;
import org.apache.geronimo.xbeans.javaee6.ParamValueType;
import org.apache.geronimo.xbeans.javaee6.ServiceRefType;
import org.apache.geronimo.xbeans.javaee6.XsdQNameType;
import org.apache.xbean.finder.ClassFinder;
import org.apache.xmlbeans.XmlObject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;


/**
* Static helper class used to encapsulate all the functions related to the translation of
* <strong>@HandlerChain</strong> annotations to deployment descriptor tags. The
* HandlerChainAnnotationHelper class can be used as part of the deployment of a module into the
* Geronimo server. It performs the following major functions:
*
* <ol>
*      <li>Translates annotations into corresponding deployment descriptor elements (so that the
*      actual deployment descriptor in the module can be updated or even created if necessary)
* </ol>
*
* <p><strong>Note(s):</strong>
* <ul>
*      <li>The user is responsible for invoking change to metadata-complete
*      <li>This helper class will validate any changes it makes to the deployment descriptor. An
*      exception will be thrown if it fails to parse
* </ul>
*
* @version $Rev $Date
* @since 03-2007
*/
public final class HandlerChainAnnotationHelper extends AnnotationHelper {

    // Private instance variables
    private static final Logger log = LoggerFactory.getLogger(HandlerChainAnnotationHelper.class);

    // Private constructor to prevent instantiation
    private HandlerChainAnnotationHelper() {
    }


    /**
     * Updates the deployment descriptor with handler chain info from HandlerChain annotations
     *
     * @param annotatedApp Wrapper around spec dd
     * @param classFinder ClassFinder containing classes of interest
     * @throws DeploymentException if parsing or validation error
     */
    public static void processAnnotations(AnnotatedApp annotatedApp, ClassFinder classFinder) throws DeploymentException {
        if ( annotatedApp != null && classFinder.isAnnotationPresent(HandlerChain.class)) {
            processHandlerChain(annotatedApp, classFinder);
        }
    }


    /**
     * Updates the deployment descriptor with handler chain info from HandlerChain annotations
     *
     * @param annotatedApp Wrapper around spec dd
     * @param classFinder ClassFinder containing classes of interest
     * @throws DeploymentException if parsing or validation error
     */
    private static void processHandlerChain(AnnotatedApp annotatedApp, ClassFinder classFinder) throws DeploymentException {
        log.debug("processHandlerChain(): Entry: AnnotatedApp: " + annotatedApp.toString());

        List<Method> methodswithHandlerChain = classFinder.findAnnotatedMethods(HandlerChain.class);
        List<Field> fieldswithHandlerChain = classFinder.findAnnotatedFields(HandlerChain.class);


        // Method-level annotation
        for ( Method method : methodswithHandlerChain ) {
            HandlerChain handlerChain = method.getAnnotation(HandlerChain.class);
            if ( handlerChain != null ) {
                addHandlerChain(annotatedApp, handlerChain, null, method, null);
            }
        }

        // Field-level annotation
        for ( Field field : fieldswithHandlerChain ) {
            HandlerChain handlerChain = field.getAnnotation(HandlerChain.class);
            if ( handlerChain != null ) {
                addHandlerChain(annotatedApp, handlerChain, null, null, field);
            }
        }

        // Validate deployment descriptor to ensure it's still okay
        validateDD(annotatedApp);

        log.debug("processHandlerChain(): Exit: AnnotatedApp: " + annotatedApp.toString());
    }


    /**
     * Add to the deployment descriptor for a single @HandlerChain annotation. XMLBeans are used to read and
     * manipulate the deployment descriptor as necessary. The HandlerChain annotation(s) will be
     * converted to one of the following deployment descriptors:
     *
     * <ol>
     *      <li><handler-chain> -- Associates the Web Service with an externally defined handler
     *      chain
     * </ol>
     *
     * <p><strong>Note(s):</strong>
     * <ul>
     *      <li>If a field/method has the @HandlerChain annotation then The corresponding
     *      <service-ref> is obtained via the @WebServiceRef annotation
     * </ul>
     *
     * @param annotatedApp wrapper around spec dd
     * @param annotation @HandlerChain annotation
     * @param cls        Class name with the @HandlerChain annotation
     * @param method     Method name with the @HandlerChain annotation
     * @param field      Field name with the @HandlerChain annotation
     */
    private static void addHandlerChain(AnnotatedApp annotatedApp, final HandlerChain annotation, Class cls, Method method, Field field) {
        log.debug("addHandlerChain( [annotatedApp] " + annotatedApp.toString() + "," + '\n' +
                "[annotation] " + annotation.toString() + "," + '\n' +
                "[cls] " + (cls != null ? cls.getName() : null) + "," + '\n' +
                "[method] " + (method != null ? method.getName() : null) + "," + '\n' +
                "[field] " + (field != null ? field.getName() : null) + " ): Entry");

        //------------------------------------------------------------------------------------------
        // HandlerChain members:
        // -- name: Deprecated -- must be empty string
        // -- file: Location of handler chain file in either absolute URL format or a relative path
        //          from the class file. Cannot be emptry string.
        //------------------------------------------------------------------------------------------
        String handlerChainFile = annotation.file();
        log.debug("addHandlerChain(): handlerChainFile: " + handlerChainFile);

        // Determine ServiceRef name
        String serviceRefName;
        WebServiceRef webServiceRef = null;
        if ( method != null ) {
            webServiceRef = method.getAnnotation(WebServiceRef.class);
        }
        else if ( field != null ) {
            webServiceRef = field.getAnnotation(WebServiceRef.class);
        }
        if ( webServiceRef != null ) {
            serviceRefName = webServiceRef.name();
        }
        else {
            //TODO is this guaranteed to be ""? If so, simplify the code here
            serviceRefName = annotation.name();
        }
        if ( serviceRefName.equals("") ) {
            serviceRefName = getInjectionJavaType(method, field);
        }
        log.debug("addHandlerChain().serviceRefName : " + serviceRefName);

        if (!serviceRefName.equals("") && !handlerChainFile.equals("")) {
            try {
                // Locate the handler chain XML file
                URL url = null;
                try {
                    // Assume URL format first
                    url = new URL(handlerChainFile);
                }
                catch (MalformedURLException mfe) {
                    log.debug("addHandlerChain().MalformedURLException" );

                    // Not URL format -- see if it's relative to the annotated class
                    if (cls != null) {
                        url = getURL(cls.getClass(), handlerChainFile);
                    }
                    else if (method != null) {
                        url = getURL(method.getDeclaringClass(), handlerChainFile);
                    }
                    else if (field != null) {
                        url = getURL(field.getDeclaringClass(), handlerChainFile);
                    }
                }

                if (url != null) {
                    // Find the <service-ref> entry this handler chain belongs to and insert it
                    ServiceRefType[] serviceRefs = annotatedApp.getServiceRefArray();
                    boolean exists = false;
                    for ( ServiceRefType serviceRef : serviceRefs ) {
                        if ( serviceRef.getServiceRefName().getStringValue().trim().equals(serviceRefName) && !serviceRef.isSetHandlerChains()) {
                            insertHandlers(serviceRef, url);
                            exists = true;
                            break;
                        }
                    }
                    if (exists) {
                        log.debug("HandlerChainAnnotationHelper: <service-ref> entry found: " + serviceRefName);
                    }
                    else {
                        log.debug("HandlerChainAnnotationHelper: <service-ref> entry NOT found: " + serviceRefName);
                    }
                }
                else {
                    log.debug("HandlerChainAnnotationHelper: Handler chain file NOT found: " + handlerChainFile );
                }
            }
            catch ( Exception anyException ) {
                log.debug("HandlerChainAnnotationHelper: Exception caught while processing <handler-chain>");
            }
        }
        log.debug("addHandlerChain(): Exit");
    }


    private static URL getURL(Class clazz, String file) {
        log.debug("getURL( " + clazz.getName() + ", " + file + " ): Entry");

        URL url = clazz.getResource(file);
        if (url == null) {
            url = Thread.currentThread().getContextClassLoader().getResource(file);
        }
        if (url == null) {
            String loc= clazz.getPackage().getName().replace('.', '/') + "/" + file;
            url = Thread.currentThread().getContextClassLoader().getResource(loc);
        }

        log.debug("getURL(): Exit: url: " + (url != null ? url.toString() : null) );
        return url;
    }
   
    public static void insertHandlers(ServiceRefType serviceRef, HandlerChain annotation, Class clazz) {
        String handlerChainFile = annotation.file();
        log.debug("handlerChainFile: " + handlerChainFile);
        if (handlerChainFile == null || handlerChainFile.trim().length() == 0) {
            return;
        }
        URL url = null;
        try {
            // Assume URL format first
            url = new URL(handlerChainFile);
        } catch (MalformedURLException mfe) {
            // Not URL format -- see if it's relative to the annotated class
            url = getURL(clazz, handlerChainFile);
        }
        if (url != null) {
            try {
                insertHandlers(serviceRef, url);
            } catch (Exception e) {
                log.debug("Error while processing <handler-chain>", e);
            }
        }
    }
   
    public static void insertHandlers(ServiceRefType serviceRef, URL url) throws Exception {
        // Bind the XML handler chain file to an XMLBeans document
        XmlObject xml = XmlBeansUtil.parse(url, null);
        HandlerChainsDocument hcd = (HandlerChainsDocument) XmlBeansUtil.typedCopy(xml, HandlerChainsDocument.type);
        org.apache.geronimo.xbeans.javaee.HandlerChainsType handlerChains = hcd.getHandlerChains();

        HandlerChainsType  serviceRefHandlerChains = serviceRef.addNewHandlerChains();
        for (org.apache.geronimo.xbeans.javaee.HandlerChainType handlerChain : handlerChains.getHandlerChainArray()) {
            HandlerChainType serviceRefHandlerChain = serviceRefHandlerChains.addNewHandlerChain();
            if (handlerChain.getPortNamePattern() != null) {
                serviceRefHandlerChain.setPortNamePattern(handlerChain.getPortNamePattern());
            }
            if (handlerChain.getServiceNamePattern() != null) {
                serviceRefHandlerChain.setServiceNamePattern(handlerChain.getServiceNamePattern());
            }
            if (handlerChain.getProtocolBindings() != null) {
                serviceRefHandlerChain.setProtocolBindings(handlerChain.getProtocolBindings());
            }
            for (PortComponentHandlerType srcHandler : handlerChain.getHandlerArray()) {
                HandlerType serviceRefHandler = serviceRefHandlerChain.addNewHandler();
                serviceRefHandler.setId(srcHandler.getId());
                //Copy HandlerName
                org.apache.geronimo.xbeans.javaee.String srcHandlerName = srcHandler.getHandlerName();
                org.apache.geronimo.xbeans.javaee6.String desHandlerName = serviceRefHandler.addNewHandlerName();
                desHandlerName.setStringValue(srcHandlerName.getStringValue());
                desHandlerName.setId(srcHandlerName.getId());
                //Copy HandlerClass
                org.apache.geronimo.xbeans.javaee.String srcHandlerClass = srcHandler.getHandlerClass();
                org.apache.geronimo.xbeans.javaee6.String desHandlerClass = serviceRefHandler.addNewHandlerClass();
                desHandlerClass.setId(srcHandlerClass.getId());
                desHandlerClass.setStringValue(srcHandlerClass.getStringValue());
                //Copy DescriptionArray
                for (org.apache.geronimo.xbeans.javaee.DescriptionType srcDescription : srcHandler.getDescriptionArray()) {
                    DescriptionType desDescription = serviceRefHandler.addNewDescription();
                    desDescription.setStringValue(srcDescription.getStringValue());
                    desDescription.setId(srcDescription.getId());
                }
                //Copy InitParamArray
                for (org.apache.geronimo.xbeans.javaee.ParamValueType srcParamValue : srcHandler.getInitParamArray()) {
                    ParamValueType desParamValue = serviceRefHandler.addNewInitParam();
                    srcParamValue.setId(desParamValue.getId());
                    desParamValue.addNewParamName().setStringValue(srcParamValue.getParamName().getStringValue());
                    desParamValue.addNewParamValue().setStringValue(srcParamValue.getParamValue().getStringValue());
                    for (org.apache.geronimo.xbeans.javaee.DescriptionType srcDescription : srcParamValue.getDescriptionArray()) {
                        DescriptionType desDescription = desParamValue.addNewDescription();
                        desDescription.setId(srcDescription.getId());
                        desDescription.setStringValue(srcDescription.getStringValue());
                    }
                }
                //Copy SoapHeaderArray
                for (org.apache.geronimo.xbeans.javaee.XsdQNameType srcSOAPHeader : srcHandler.getSoapHeaderArray()) {
                    XsdQNameType desSOAPHeader = serviceRefHandler.addNewSoapHeader();
                    desSOAPHeader.setId(srcSOAPHeader.getId());
                    desSOAPHeader.setQNameValue(srcSOAPHeader.getQNameValue());
                }
                //Copy SoapRoleArray
                for (org.apache.geronimo.xbeans.javaee.String srcSOAPRole : srcHandler.getSoapRoleArray()) {
                    org.apache.geronimo.xbeans.javaee6.String desSOAPRole = serviceRefHandler.addNewSoapRole();
                    desSOAPRole.setId(srcSOAPRole.getId());
                    desSOAPRole.setStringValue(srcSOAPRole.getStringValue());
                }
            }
        }
    }

}
TOP

Related Classes of org.apache.geronimo.j2ee.deployment.annotation.HandlerChainAnnotationHelper

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.