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

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

/**
* 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.util.ArrayList;
import java.util.Arrays;
import java.util.List;

import javax.ejb.EJB;
import javax.ejb.EJBHome;
import javax.ejb.EJBLocalHome;
import javax.ejb.EJBs;
import javax.ejb.Local;
import javax.ejb.Remote;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.apache.geronimo.xbeans.javaee.DescriptionType;
import org.apache.geronimo.xbeans.javaee.EjbLinkType;
import org.apache.geronimo.xbeans.javaee.EjbLocalRefType;
import org.apache.geronimo.xbeans.javaee.EjbRefNameType;
import org.apache.geronimo.xbeans.javaee.EjbRefType;
import org.apache.geronimo.xbeans.javaee.InjectionTargetType;
import org.apache.geronimo.xbeans.javaee.LocalType;
import org.apache.geronimo.xbeans.javaee.RemoteType;
import org.apache.geronimo.xbeans.javaee.XsdStringType;
import org.apache.xbean.finder.ClassFinder;

/**
* Static helper class used to encapsulate all the functions related to the translation of
* <strong>@EJB</strong> and <strong>@EJBs</strong> annotations to deployment descriptor tags. The
* EJBAnnotationHelper 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>
*
* <p><strong>Remaining ToDo(s):</strong>
* <ul>
*      <li>Usage of mappedName
* </ul>
*
* @version $Rev: 699352 $ $Date: 2008-09-26 23:00:10 +0800 (Fri, 26 Sep 2008) $
* @since 02-2007
*/

public final class EJBAnnotationHelper extends AnnotationHelper {

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

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


    /**
     * Determine if there are any annotations present
     *
     * @return true or false
     */
    public static boolean annotationsPresent(ClassFinder classFinder) {
        if (classFinder.isAnnotationPresent(EJB.class)) return true;
        if (classFinder.isAnnotationPresent(EJBs.class)) return true;
        return false;
    }


    /**
     * Process the annotations
     *
     * @return Updated deployment descriptor
     * @throws Exception if parsing or validation error
     */
    public static void processAnnotations(AnnotatedApp annotatedApp, ClassFinder classFinder) throws Exception {
        if (annotatedApp != null) {
            processEJBs(annotatedApp, classFinder);
            processEJB(annotatedApp, classFinder);
        }
    }


    /**
     * Process annotations
     *
     * @param annotatedApp
     * @param classFinder
     * @throws Exception
     */
    private static void processEJB(AnnotatedApp annotatedApp, ClassFinder classFinder) throws Exception {
        log.debug("processEJB(): Entry: AnnotatedApp: " + annotatedApp.toString());

        List<Class> classesWithEJB = classFinder.findAnnotatedClasses(EJB.class);
        List<Method> methodsWithEJB = classFinder.findAnnotatedMethods(EJB.class);
        List<Field> fieldsWithEJB = classFinder.findAnnotatedFields(EJB.class);

        // Class-level annotation
        for (Class cls : classesWithEJB) {
            EJB ejb = (EJB) cls.getAnnotation(EJB.class);
            if (ejb != null) {
                addEJB(annotatedApp, ejb, cls, null, null);
            }
        }

        // Method-level annotation
        for (Method method : methodsWithEJB) {
            EJB ejb = (EJB) method.getAnnotation(EJB.class);
            if (ejb != null) {
                addEJB(annotatedApp, ejb, null, method, null);
            }
        }

        // Field-level annotation
        for (Field field : fieldsWithEJB) {
            EJB ejb = (EJB) field.getAnnotation(EJB.class);
            if (ejb != null) {
                addEJB(annotatedApp, ejb, null, null, field);
            }
        }

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

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


    /**
     * Process multiple annotations
     *
     * @param annotatedApp
     * @param classFinder
     * @throws Exception
     */
    private static void processEJBs(AnnotatedApp annotatedApp, ClassFinder classFinder) throws Exception {
        log.debug("processEJBs(): Entry");

        List<Class> classesWithEJBs = classFinder.findAnnotatedClasses(EJBs.class);

        // Class-level annotation(s)
        List<EJB> ejbList = new ArrayList<EJB>();
        for (Class cls : classesWithEJBs) {
            EJBs ejbs = (EJBs) cls.getAnnotation(EJBs.class);
            if (ejbs != null) {
                ejbList.addAll(Arrays.asList(ejbs.value()));
            }
            for (EJB ejb : ejbList) {
                addEJB(annotatedApp, ejb, cls, null, null);
            }
            ejbList.clear();
        }

        log.debug("processEJBs(): Exit");
    }


    /**
     * Add @EJB and @EJBs annotations to the deployment descriptor. XMLBeans are used to read and
     * manipulate the deployment descriptor as necessary. The EJB annotation(s) will be converted to
     * one of the following deployment descriptors if possible. Otherwise they will be listed as
     * ambiguous and resolved in OpenEJB.
     * <p/>
     * <ol>
     * <li><ejb-ref>
     * <li><ejb-local-ref>
     * </ol>
     * <p/>
     * <p><strong>Note(s):</strong>
     * <ul>
     * <li>The deployment descriptor is the authoritative source so this method ensures that
     * existing elements in it are not overwritten by annoations
     * </ul>
     *
     * @param annotatedApp
     * @param annotation   @EJB annotation
     * @param cls          Class name with the @EJB annoation
     * @param method       Method name with the @EJB annoation
     * @param field        Field name with the @EJB annoation
     */
    private static void addEJB(AnnotatedApp annotatedApp, EJB annotation, Class cls, Method method, Field field) {
        log.debug("addEJB( [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");

        // First determine if the interface is "Local" or "Remote" (if we can--we may not be able to)
        boolean localFlag = false;
        boolean remoteFlag = false;
        Class interfce = annotation.beanInterface();
        if (interfce.equals(Object.class)) {
            if (method != null) {
                interfce = method.getParameterTypes()[0];
            } else if (field != null) {
                interfce = field.getType();
            } else {
                interfce = null;
            }
        }
        log.debug("addEJB(): interfce: " + interfce);

        // Just in case local and/or remote homes are still being implemented (even though
        // they are optional in EJB 3.0)
        if (interfce != null && !interfce.equals(Object.class)) {
            if (EJBHome.class.isAssignableFrom(interfce)) {
                for (Method m : interfce.getMethods()) {
                    if (m.getName().startsWith("create")) {
                        interfce = m.getReturnType();
                        break;
                    }
                }
                remoteFlag = true;
            } else if (EJBLocalHome.class.isAssignableFrom(interfce)) {
                for (Method m : interfce.getMethods()) {
                    if (m.getName().startsWith("create")) {
                        interfce = m.getReturnType();
                        break;
                    }
                }
                localFlag = true;
            } else {
                if (interfce.getAnnotation(Local.class) != null) {
                    localFlag = true;
                } else if (interfce.getAnnotation(Remote.class) != null) {
                    remoteFlag = true;
                }
            }
        }
        log.debug("addEJB(): localFlag: " + localFlag);
        log.debug("addEJB(): remoteFlag: " + remoteFlag);

        //------------------------------------------------------------------------------------------
        // 1. <ejb-local-ref>
        //------------------------------------------------------------------------------------------
        if (localFlag) {

            log.debug("addEJB(): <ejb-local-ref> found");

            String localRefName = getName(annotation.name(), method, field);

            EjbLocalRefType ejbLocalRef = null;
           
            EjbLocalRefType[] ejbLocalRefEntries = annotatedApp.getEjbLocalRefArray();
            for (EjbLocalRefType ejbLocalRefEntry : ejbLocalRefEntries) {
                if (ejbLocalRefEntry.getEjbRefName().getStringValue().trim().equals(localRefName)) {
                    ejbLocalRef = ejbLocalRefEntry;
                    break;
                }
            }
            if (ejbLocalRef == null) {
                try {

                    log.debug("addEJB(): Does not exist in DD: " + localRefName);

                    // Doesn't exist in deployment descriptor -- add new
                    ejbLocalRef = annotatedApp.addNewEjbLocalRef();

                    //------------------------------------------------------------------------------
                    // <ejb-local-ref> required elements:
                    //------------------------------------------------------------------------------

                    // ejb-ref-name
                    EjbRefNameType ejbRefName = ejbLocalRef.addNewEjbRefName();
                    ejbRefName.setStringValue(localRefName);
                    ejbLocalRef.setEjbRefName(ejbRefName);

                    //------------------------------------------------------------------------------
                    // <ejb-local-ref> optional elements:
                    //------------------------------------------------------------------------------

                    // local
                    if (interfce != null) {
                        String localAnnotation = interfce.getName();
                        if (!localAnnotation.equals("")) {
                            LocalType local = ejbLocalRef.addNewLocal();
                            local.setStringValue(localAnnotation);
                            ejbLocalRef.setLocal(local);
                        }
                    }

                    // ejb-link
                    String beanName = annotation.beanName();
                    if (!beanName.equals("")) {
                        EjbLinkType ejbLink = ejbLocalRef.addNewEjbLink();
                        ejbLink.setStringValue(beanName);
                        ejbLocalRef.setEjbLink(ejbLink);
                    }

                    // mappedName
                    String mappdedNameAnnotation = annotation.mappedName();
                    if (!mappdedNameAnnotation.equals("")) {
                        XsdStringType mappedName = ejbLocalRef.addNewMappedName();
                        mappedName.setStringValue(mappdedNameAnnotation);
                        ejbLocalRef.setMappedName(mappedName);
                    }

                    // description
                    String descriptionAnnotation = annotation.description();
                    if (!descriptionAnnotation.equals("")) {
                        DescriptionType description = ejbLocalRef.addNewDescription();
                        description.setStringValue(descriptionAnnotation);
                    }
                }
                catch (Exception e) {
                    log.debug("EJBAnnotationHelper: Exception caught while processing <ejb-local-ref>", e);
                }
            }
           
            // injectionTarget
            if (method != null || field != null) {
                InjectionTargetType[] targets = ejbLocalRef.getInjectionTargetArray();
                if (!hasTarget(method, field, targets)) {
                    configureInjectionTarget(ejbLocalRef.addNewInjectionTarget(), method, field);
                }
            }
        }                                                                           // end if local
        else if (remoteFlag) {                                                      // remote

            //--------------------------------------------------------------------------------------
            // 2. <ejb-ref>
            //--------------------------------------------------------------------------------------

            log.debug("addEJB(): <ejb-ref> found");

            String remoteRefName = getName(annotation.name(), method, field);

            EjbRefType ejbRef = null;

            EjbRefType[] ejbRefEntries = annotatedApp.getEjbRefArray();
            for (EjbRefType ejbRefEntry : ejbRefEntries) {
                if (ejbRefEntry.getEjbRefName().getStringValue().trim().equals(remoteRefName)) {
                    ejbRef = ejbRefEntry;
                    break;
                }
            }
            if (ejbRef == null) {
                try {

                    log.debug("addEJB(): Does not exist in DD: " + remoteRefName);

                    // Doesn't exist in deployment descriptor -- add new
                    ejbRef = annotatedApp.addNewEjbRef();

                    //------------------------------------------------------------------------------
                    // <ejb-ref> required elements:
                    //------------------------------------------------------------------------------

                    // ejb-ref-name
                    EjbRefNameType ejbRefName = ejbRef.addNewEjbRefName();
                    ejbRefName.setStringValue(remoteRefName);
                    ejbRef.setEjbRefName(ejbRefName);

                    //------------------------------------------------------------------------------
                    // <ejb-ref> optional elements:
                    //------------------------------------------------------------------------------

                    // remote
                    if (interfce != null) {
                        String remoteAnnotation = interfce.getName();
                        if (!remoteAnnotation.equals("")) {
                            RemoteType remote = ejbRef.addNewRemote();
                            remote.setStringValue(remoteAnnotation);
                            ejbRef.setRemote(remote);
                        }
                    }

                    // ejb-link
                    String beanName = annotation.beanName();
                    if (!beanName.equals("")) {
                        EjbLinkType ejbLink = ejbRef.addNewEjbLink();
                        ejbLink.setStringValue(beanName);
                        ejbRef.setEjbLink(ejbLink);
                    }

                    // mappedName
                    String mappdedNameAnnotation = annotation.mappedName();
                    if (!mappdedNameAnnotation.equals("")) {
                        XsdStringType mappedName = ejbRef.addNewMappedName();
                        mappedName.setStringValue(mappdedNameAnnotation);
                        ejbRef.setMappedName(mappedName);
                    }

                    // description
                    String descriptionAnnotation = annotation.description();
                    if (!descriptionAnnotation.equals("")) {
                        DescriptionType description = ejbRef.addNewDescription();
                        description.setStringValue(descriptionAnnotation);
                    }
                }
                catch (Exception e) {
                    log.debug("EJBAnnotationHelper: Exception caught while processing <ejb-ref>", e);
                }
            }
           
            // injectionTarget
            if (method != null || field != null) {
                InjectionTargetType[] targets = ejbRef.getInjectionTargetArray();
                if (!hasTarget(method, field, targets)) {
                    configureInjectionTarget(ejbRef.addNewInjectionTarget(), method, field);
                }
            }
        }                                                                           // end if remote
        else {                                                                      // ambiguous

            //--------------------------------------------------------------------------------------
            // 3. <UNKNOWN>
            //--------------------------------------------------------------------------------------
            log.debug("addEJB(): <UNKNOWN> found");

            String remoteRefName = getName(annotation.name(), method, field);

            EjbRefType ejbRef = null;

            EjbRefType[] ejbRefEntries = annotatedApp.getEjbRefArray();
            for (EjbRefType ejbRefEntry : ejbRefEntries) {
                if (ejbRefEntry.getEjbRefName().getStringValue().trim().equals(remoteRefName)) {
                    ejbRef = ejbRefEntry;
                    break;
                }
            }
            if (ejbRef == null) {
                try {

                    log.debug("addEJB(): Does not exist in DD: " + remoteRefName);

                    // Doesn't exist in deployment descriptor -- add as an <ejb-ref> to the
                    // ambiguous list so that it can be resolved later
                    ejbRef = EjbRefType.Factory.newInstance();
                    annotatedApp.getAmbiguousEjbRefs().add(ejbRef);

                    //------------------------------------------------------------------------------
                    // <ejb-ref> required elements:
                    //------------------------------------------------------------------------------

                    // ejb-ref-name
                    EjbRefNameType ejbRefName = ejbRef.addNewEjbRefName();
                    ejbRefName.setStringValue(remoteRefName);
                    ejbRef.setEjbRefName(ejbRefName);

                    //------------------------------------------------------------------------------
                    // <ejb-ref> optional elements:
                    //------------------------------------------------------------------------------

                    // remote
                    if (interfce != null) {
                        String remoteAnnotation = interfce.getName();
                        if (!remoteAnnotation.equals("")) {
                            RemoteType remote = ejbRef.addNewRemote();
                            remote.setStringValue(remoteAnnotation);
                            ejbRef.setRemote(remote);
                        }
                    }

                    // ejb-link
                    String beanName = annotation.beanName();
                    if (!beanName.equals("")) {
                        EjbLinkType ejbLink = ejbRef.addNewEjbLink();
                        ejbLink.setStringValue(beanName);
                        ejbRef.setEjbLink(ejbLink);
                    }

                    // mappedName
                    String mappdedNameAnnotation = annotation.mappedName();
                    if (!mappdedNameAnnotation.equals("")) {
                        XsdStringType mappedName = ejbRef.addNewMappedName();
                        mappedName.setStringValue(mappdedNameAnnotation);
                        ejbRef.setMappedName(mappedName);
                    }

                    // description
                    String descriptionAnnotation = annotation.description();
                    if (!descriptionAnnotation.equals("")) {
                        DescriptionType description = ejbRef.addNewDescription();
                        description.setStringValue(descriptionAnnotation);
                    }
                }
                catch (Exception e) {
                    log.debug("EJBAnnotationHelper: Exception caught while processing <UNKNOWN>", e);
                }               
            }
           
            // injectionTarget
            if (method != null || field != null) {
                InjectionTargetType[] targets = ejbRef.getInjectionTargetArray();
                if (!hasTarget(method, field, targets)) {
                    configureInjectionTarget(ejbRef.addNewInjectionTarget(), method, field);
                }
            }

        }
        log.debug("addEJB(): Exit");
    }

}
TOP

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

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.