FileDocCategorySizeDatePackage
EJBHandler.javaAPI DocGlassfish v2 API13198Fri May 04 22:31:34 BST 2007com.sun.enterprise.deployment.annotation.handlers

EJBHandler

public class EJBHandler extends AbstractResourceHandler
This handler is responsible for handling the javax.ejb.EJB
author
Shing Wai Chan

Fields Summary
Constructors Summary
public EJBHandler()

    
Methods Summary
public java.lang.ClassgetAnnotationType()

return
the annoation type this annotation handler is handling

        return EJB.class;
    
private com.sun.enterprise.deployment.EjbReferenceDescriptor[]getEjbReferenceDescriptors(java.lang.String logicalName, com.sun.enterprise.deployment.annotation.context.ResourceContainerContext[] rcContexts)
Return EjbReferenceDescriptors with given name if exists or a new one without name being set.

param
logicalName
param
rcContexts
return
an array of EjbReferenceDescriptor

        EjbReferenceDescriptor ejbRefs[] =
                new EjbReferenceDescriptor[rcContexts.length];
        for (int i = 0; i < rcContexts.length; i++) {
            EjbReferenceDescriptor ejbRef =
                (EjbReferenceDescriptor)rcContexts[i].getEjbReference(logicalName);
            if (ejbRef == null) {
                ejbRef = new EjbReferenceDescriptor();
                rcContexts[i].addEjbReferenceDescriptor(ejbRef);
            }
            ejbRefs[i] = ejbRef;
        }

        return ejbRefs;
    
protected com.sun.enterprise.deployment.annotation.HandlerProcessingResultprocessAnnotation(com.sun.enterprise.deployment.annotation.AnnotationInfo ainfo, com.sun.enterprise.deployment.annotation.context.ResourceContainerContext[] rcContexts)
Process a particular annotation which type is the same as the one returned by @see getAnnotationType(). All information pertinent to the annotation and its context is encapsulated in the passed AnnotationInfo instance.

param
ainfo the annotation information
param
rcContexts an array of ResourceContainerContext
return
HandlerProcessingResult


        EJB ejbAn = (EJB)ainfo.getAnnotation();
        return processEJB(ainfo, rcContexts, ejbAn);
    
protected com.sun.enterprise.deployment.annotation.HandlerProcessingResultprocessEJB(com.sun.enterprise.deployment.annotation.AnnotationInfo ainfo, com.sun.enterprise.deployment.annotation.context.ResourceContainerContext[] rcContexts, javax.ejb.EJB ejbAn)
Process a particular annotation which type is the same as the one returned by @see getAnnotationType(). All information pertinent to the annotation and its context is encapsulated in the passed AnnotationInfo instance.

param
ainfo the annotation information
param
rcContexts an array of ResourceContainerContext
param
ejbAn
return
HandlerProcessingResult

        EjbReferenceDescriptor ejbRefs[] = null;

        if (ElementType.FIELD.equals(ainfo.getElementType())) {
            Field f = (Field)ainfo.getAnnotatedElement();
            String targetClassName = f.getDeclaringClass().getName();

            String logicalName = ejbAn.name();

            // applying with default
            if (logicalName.equals("")) {
                logicalName = targetClassName + "/" + f.getName();
            }

            // If specified, beanInterface() overrides field type
            // NOTE that defaultValue is Object.class, not null
            Class beanInterface = (ejbAn.beanInterface() == Object.class) ?
                    f.getType() : ejbAn.beanInterface();

            InjectionTarget target = new InjectionTarget();
            target.setClassName(targetClassName);
            target.setFieldName(f.getName());
            
            ejbRefs = getEjbReferenceDescriptors(logicalName, rcContexts);
            for (EjbReferenceDescriptor ejbRef : ejbRefs) {
                ejbRef.addInjectionTarget(target);

                if (ejbRef.getName().length() == 0) { // a new one
                    processNewEJBAnnotation(ejbRef, beanInterface,
                                            logicalName, ejbAn);
                }
            }
        } else if (ElementType.METHOD.equals(ainfo.getElementType())) {

            Method m = (Method)ainfo.getAnnotatedElement();
            String targetClassName = m.getDeclaringClass().getName();

            String logicalName = ejbAn.name();
            if( logicalName.equals("") ) {
                // Derive javabean property name.
                String propertyName = 
                        getInjectionMethodPropertyName(m, ainfo);

                // prefixing with fully qualified type name
                logicalName = targetClassName + "/" + propertyName;
            }

            validateInjectionMethod(m, ainfo);

            Class[] params = m.getParameterTypes();
            // If specified, beanInterface() overrides parameter type
            // NOTE that default value is Object.class, not null
            Class beanInterface = (ejbAn.beanInterface() == Object.class) ?
                    params[0] : ejbAn.beanInterface();

            InjectionTarget target = new InjectionTarget();
            target.setClassName(targetClassName);
            target.setMethodName(m.getName());
            
            ejbRefs = getEjbReferenceDescriptors(logicalName, rcContexts);
            for (EjbReferenceDescriptor ejbRef : ejbRefs) {

                ejbRef.addInjectionTarget(target);

                if (ejbRef.getName().length() == 0) { // a new one

                    processNewEJBAnnotation(ejbRef, beanInterface,
                                            logicalName, ejbAn);
                }
            }
        } else if( ElementType.TYPE.equals(ainfo.getElementType()) ) {
            // name() and beanInterface() are required elements for 
            // TYPE-level usage
            String logicalName = ejbAn.name();
            Class beanInterface = ejbAn.beanInterface();

            if( "".equals(logicalName) || beanInterface == Object.class ) {
                Class c = (Class) ainfo.getAnnotatedElement();
                log(Level.SEVERE, ainfo,
                    localStrings.getLocalString(
                    "enterprise.deployment.annotation.handlers.invalidtypelevelejb",
                    "Invalid TYPE-level @EJB with name() = [{0}] and beanInterface = [{1}] in {2}.  Each TYPE-level @EJB must specify both name() and beanInterface().",
                new Object[] { logicalName, beanInterface, c }));
                return getDefaultFailedResult();
            }
                               
            ejbRefs = getEjbReferenceDescriptors(logicalName, rcContexts);
            for (EjbReferenceDescriptor ejbRef : ejbRefs) {
                if (ejbRef.getName().length() == 0) { // a new one

                    processNewEJBAnnotation(ejbRef, beanInterface,
                                            logicalName, ejbAn);
                }
            }
        } 

        return getDefaultProcessedResult();
    
private java.lang.StringprocessForHomeInterface(com.sun.enterprise.deployment.EjbReferenceDescriptor ejbRef, java.lang.Class beanInterface)

return
targetBeanType


        //XXX assume session bean
        String targetBeanType = EjbSessionDescriptor.TYPE;
        ejbRef.setHomeClassName(beanInterface.getName());

        try {
            // Set bean Interface as well so we have all
            // the info that would have been in an ejb-ref/
            // ejb-local-ref
            Method[] methods = beanInterface.getMethods();
            for (Method m : methods) {
                if (m.getName().equals("create")) {
                    ejbRef.setEjbInterface(m.getReturnType().getName());
                    break;
                }
            }
            // Use existence of findByPrimaryKey method on Home to
            // determine target bean type
            for (Method m : methods) {
                if (m.getName().equals("findByPrimaryKey")) {
                    targetBeanType = EjbEntityDescriptor.TYPE;
                    break;
                }
            }
        } catch(Exception e) {
            if (logger.isLoggable(Level.FINE)) {
                logger.log(Level.FINE, 
                "component intf / ejb type annotation processing error", e);
            }
        }

        ejbRef.setLocal(EJBLocalHome.class.isAssignableFrom(beanInterface));
        return targetBeanType;
    
private voidprocessNewEJBAnnotation(com.sun.enterprise.deployment.EjbReferenceDescriptor ejbRef, java.lang.Class beanInterface, java.lang.String logicalName, javax.ejb.EJB annotation)

        
        ejbRef.setName(logicalName);
        
        String targetBeanType = EjbSessionDescriptor.TYPE;
        if (EJBHome.class.isAssignableFrom(beanInterface) ||
            EJBLocalHome.class.isAssignableFrom(beanInterface)) {
            targetBeanType = processForHomeInterface(ejbRef, beanInterface);
        } else {
            // EJB 3.0 style Business Interface
            ejbRef.setEjbInterface(beanInterface.getName());
            
            if( beanInterface.getAnnotation(Local.class) != null ) {
                ejbRef.setLocal(true);
            } else if( beanInterface.getAnnotation(Remote.class) 
                       != null ) {
                ejbRef.setLocal(false);
            } else {
                // Assume remote for now. We can't know for sure until the
                // post-validation stage.  Even though local business will 
                // probably be more common than remote business, defaulting 
                // to remote business simplies the post-application 
                // validation logic considerably.  See 
                // EjbBundleValidator.accept(EjbReferenceDescriptor) 
                // for more details.
                ejbRef.setLocal(false);
            }
        }
        
        String ejbAnBeanName = annotation.beanName();
        if (ejbAnBeanName != null && ejbAnBeanName.length() > 0) {
            ejbRef.setLinkName(ejbAnBeanName);
        }
        
        ejbRef.setType(targetBeanType);
        ejbRef.setMappedName(annotation.mappedName());
        ejbRef.setDescription(annotation.description());