KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > sun > enterprise > deployment > annotation > handlers > EJBHandler


1 /*
2  * The contents of this file are subject to the terms
3  * of the Common Development and Distribution License
4  * (the License). You may not use this file except in
5  * compliance with the License.
6  *
7  * You can obtain a copy of the license at
8  * https://glassfish.dev.java.net/public/CDDLv1.0.html or
9  * glassfish/bootstrap/legal/CDDLv1.0.txt.
10  * See the License for the specific language governing
11  * permissions and limitations under the License.
12  *
13  * When distributing Covered Code, include this CDDL
14  * Header Notice in each file and include the License file
15  * at glassfish/bootstrap/legal/CDDLv1.0.txt.
16  * If applicable, add the following below the CDDL Header,
17  * with the fields enclosed by brackets [] replaced by
18  * you own identifying information:
19  * "Portions Copyrighted [year] [name of copyright owner]"
20  *
21  * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
22  */

23 package com.sun.enterprise.deployment.annotation.handlers;
24
25 import java.lang.annotation.Annotation JavaDoc;
26 import java.lang.annotation.ElementType JavaDoc;
27 import java.lang.reflect.AnnotatedElement JavaDoc;
28 import java.lang.reflect.Field JavaDoc;
29 import java.lang.reflect.Method JavaDoc;
30
31 import java.util.logging.Level JavaDoc;
32
33 import javax.ejb.EJB JavaDoc;
34 import javax.ejb.EJBHome JavaDoc;
35 import javax.ejb.EJBLocalHome JavaDoc;
36 import javax.ejb.EJBObject JavaDoc;
37 import javax.ejb.Local JavaDoc;
38 import javax.ejb.Remote JavaDoc;
39
40 import com.sun.enterprise.deployment.EjbDescriptor;
41 import com.sun.enterprise.deployment.EjbEntityDescriptor;
42 import com.sun.enterprise.deployment.EjbReferenceDescriptor;
43 import com.sun.enterprise.deployment.EjbSessionDescriptor;
44 import com.sun.enterprise.deployment.MethodDescriptor;
45 import com.sun.enterprise.deployment.InjectionTarget;
46 import com.sun.enterprise.deployment.types.EjbReferenceContainer;
47 import com.sun.enterprise.deployment.annotation.AnnotatedElementHandler;
48 import com.sun.enterprise.deployment.annotation.AnnotationInfo;
49 import com.sun.enterprise.deployment.annotation.AnnotationProcessorException;
50 import com.sun.enterprise.deployment.annotation.HandlerProcessingResult;
51 import com.sun.enterprise.deployment.annotation.context.ResourceContainerContext;
52
53 /**
54  * This handler is responsible for handling the javax.ejb.EJB
55  *
56  * @author Shing Wai Chan
57  */

58 public class EJBHandler extends AbstractResourceHandler {
59     
60     public EJBHandler() {
61     }
62
63     /**
64      * @return the annoation type this annotation handler is handling
65      */

66     public Class JavaDoc<? extends Annotation JavaDoc> getAnnotationType() {
67         return EJB JavaDoc.class;
68     }
69
70     /**
71      * Process a particular annotation which type is the same as the
72      * one returned by @see getAnnotationType(). All information
73      * pertinent to the annotation and its context is encapsulated
74      * in the passed AnnotationInfo instance.
75      *
76      * @param ainfo the annotation information
77      * @param rcContexts an array of ResourceContainerContext
78      * @return HandlerProcessingResult
79      */

80     protected HandlerProcessingResult processAnnotation(AnnotationInfo ainfo,
81             ResourceContainerContext[] rcContexts)
82             throws AnnotationProcessorException {
83
84         EJB JavaDoc ejbAn = (EJB JavaDoc)ainfo.getAnnotation();
85         return processEJB(ainfo, rcContexts, ejbAn);
86     }
87
88
89     /**
90      * Process a particular annotation which type is the same as the
91      * one returned by @see getAnnotationType(). All information
92      * pertinent to the annotation and its context is encapsulated
93      * in the passed AnnotationInfo instance.
94      *
95      * @param ainfo the annotation information
96      * @param rcContexts an array of ResourceContainerContext
97      * @param ejbAn
98      * @return HandlerProcessingResult
99      */

100     protected HandlerProcessingResult processEJB(AnnotationInfo ainfo,
101             ResourceContainerContext[] rcContexts, EJB JavaDoc ejbAn)
102             throws AnnotationProcessorException {
103         EjbReferenceDescriptor ejbRefs[] = null;
104
105         if (ElementType.FIELD.equals(ainfo.getElementType())) {
106             Field JavaDoc f = (Field JavaDoc)ainfo.getAnnotatedElement();
107             String JavaDoc targetClassName = f.getDeclaringClass().getName();
108
109             String JavaDoc logicalName = ejbAn.name();
110
111             // applying with default
112
if (logicalName.equals("")) {
113                 logicalName = targetClassName + "/" + f.getName();
114             }
115
116             // If specified, beanInterface() overrides field type
117
// NOTE that defaultValue is Object.class, not null
118
Class JavaDoc beanInterface = (ejbAn.beanInterface() == Object JavaDoc.class) ?
119                     f.getType() : ejbAn.beanInterface();
120
121             InjectionTarget target = new InjectionTarget();
122             target.setClassName(targetClassName);
123             target.setFieldName(f.getName());
124             
125             ejbRefs = getEjbReferenceDescriptors(logicalName, rcContexts);
126             for (EjbReferenceDescriptor ejbRef : ejbRefs) {
127                 ejbRef.addInjectionTarget(target);
128
129                 if (ejbRef.getName().length() == 0) { // a new one
130
processNewEJBAnnotation(ejbRef, beanInterface,
131                                             logicalName, ejbAn);
132                 }
133             }
134         } else if (ElementType.METHOD.equals(ainfo.getElementType())) {
135
136             Method JavaDoc m = (Method JavaDoc)ainfo.getAnnotatedElement();
137             String JavaDoc targetClassName = m.getDeclaringClass().getName();
138
139             String JavaDoc logicalName = ejbAn.name();
140             if( logicalName.equals("") ) {
141                 // Derive javabean property name.
142
String JavaDoc propertyName =
143                         getInjectionMethodPropertyName(m, ainfo);
144
145                 // prefixing with fully qualified type name
146
logicalName = targetClassName + "/" + propertyName;
147             }
148
149             validateInjectionMethod(m, ainfo);
150
151             Class JavaDoc[] params = m.getParameterTypes();
152             // If specified, beanInterface() overrides parameter type
153
// NOTE that default value is Object.class, not null
154
Class JavaDoc beanInterface = (ejbAn.beanInterface() == Object JavaDoc.class) ?
155                     params[0] : ejbAn.beanInterface();
156
157             InjectionTarget target = new InjectionTarget();
158             target.setClassName(targetClassName);
159             target.setMethodName(m.getName());
160             
161             ejbRefs = getEjbReferenceDescriptors(logicalName, rcContexts);
162             for (EjbReferenceDescriptor ejbRef : ejbRefs) {
163
164                 ejbRef.addInjectionTarget(target);
165
166                 if (ejbRef.getName().length() == 0) { // a new one
167

168                     processNewEJBAnnotation(ejbRef, beanInterface,
169                                             logicalName, ejbAn);
170                 }
171             }
172         } else if( ElementType.TYPE.equals(ainfo.getElementType()) ) {
173             // name() and beanInterface() are required elements for
174
// TYPE-level usage
175
String JavaDoc logicalName = ejbAn.name();
176             Class JavaDoc beanInterface = ejbAn.beanInterface();
177
178             if( "".equals(logicalName) || beanInterface == Object JavaDoc.class ) {
179                 Class JavaDoc c = (Class JavaDoc) ainfo.getAnnotatedElement();
180                 log(Level.SEVERE, ainfo,
181                     localStrings.getLocalString(
182                     "enterprise.deployment.annotation.handlers.invalidtypelevelejb",
183                     "Invalid TYPE-level @EJB with name() = [{0}] and beanInterface = [{1}] in {2}. Each TYPE-level @EJB must specify both name() and beanInterface().",
184                 new Object JavaDoc[] { logicalName, beanInterface, c }));
185                 return getDefaultFailedResult();
186             }
187                                
188             ejbRefs = getEjbReferenceDescriptors(logicalName, rcContexts);
189             for (EjbReferenceDescriptor ejbRef : ejbRefs) {
190                 if (ejbRef.getName().length() == 0) { // a new one
191

192                     processNewEJBAnnotation(ejbRef, beanInterface,
193                                             logicalName, ejbAn);
194                 }
195             }
196         }
197
198         return getDefaultProcessedResult();
199     }
200
201     /**
202      * Return EjbReferenceDescriptors with given name if exists or a new
203      * one without name being set.
204      * @param logicalName
205      * @param rcContexts
206      * @return an array of EjbReferenceDescriptor
207      */

208     private EjbReferenceDescriptor[] getEjbReferenceDescriptors(
209             String JavaDoc logicalName, ResourceContainerContext[] rcContexts) {
210         EjbReferenceDescriptor ejbRefs[] =
211                 new EjbReferenceDescriptor[rcContexts.length];
212         for (int i = 0; i < rcContexts.length; i++) {
213             EjbReferenceDescriptor ejbRef =
214                 (EjbReferenceDescriptor)rcContexts[i].getEjbReference(logicalName);
215             if (ejbRef == null) {
216                 ejbRef = new EjbReferenceDescriptor();
217                 rcContexts[i].addEjbReferenceDescriptor(ejbRef);
218             }
219             ejbRefs[i] = ejbRef;
220         }
221
222         return ejbRefs;
223     }
224
225     private void processNewEJBAnnotation(EjbReferenceDescriptor ejbRef,
226                                          Class JavaDoc beanInterface,
227                                          String JavaDoc logicalName, EJB JavaDoc annotation) {
228         
229         ejbRef.setName(logicalName);
230         
231         String JavaDoc targetBeanType = EjbSessionDescriptor.TYPE;
232         if (EJBHome JavaDoc.class.isAssignableFrom(beanInterface) ||
233             EJBLocalHome JavaDoc.class.isAssignableFrom(beanInterface)) {
234             targetBeanType = processForHomeInterface(ejbRef, beanInterface);
235         } else {
236             // EJB 3.0 style Business Interface
237
ejbRef.setEjbInterface(beanInterface.getName());
238             
239             if( beanInterface.getAnnotation(Local JavaDoc.class) != null ) {
240                 ejbRef.setLocal(true);
241             } else if( beanInterface.getAnnotation(Remote JavaDoc.class)
242                        != null ) {
243                 ejbRef.setLocal(false);
244             } else {
245                 // Assume remote for now. We can't know for sure until the
246
// post-validation stage. Even though local business will
247
// probably be more common than remote business, defaulting
248
// to remote business simplies the post-application
249
// validation logic considerably. See
250
// EjbBundleValidator.accept(EjbReferenceDescriptor)
251
// for more details.
252
ejbRef.setLocal(false);
253             }
254         }
255         
256         String JavaDoc ejbAnBeanName = annotation.beanName();
257         if (ejbAnBeanName != null && ejbAnBeanName.length() > 0) {
258             ejbRef.setLinkName(ejbAnBeanName);
259         }
260         
261         ejbRef.setType(targetBeanType);
262         ejbRef.setMappedName(annotation.mappedName());
263
264     }
265
266     /**
267      * @return targetBeanType
268      */

269     private String JavaDoc processForHomeInterface(EjbReferenceDescriptor ejbRef,
270             Class JavaDoc beanInterface) {
271
272         //XXX assume session bean
273
String JavaDoc targetBeanType = EjbSessionDescriptor.TYPE;
274         ejbRef.setHomeClassName(beanInterface.getName());
275
276         try {
277             // Set bean Interface as well so we have all
278
// the info that would have been in an ejb-ref/
279
// ejb-local-ref
280
Method JavaDoc[] methods = beanInterface.getMethods();
281             for (Method JavaDoc m : methods) {
282                 if (m.getName().equals("create")) {
283                     ejbRef.setEjbInterface(m.getReturnType().getName());
284                     break;
285                 }
286             }
287             // Use existence of findByPrimaryKey method on Home to
288
// determine target bean type
289
for (Method JavaDoc m : methods) {
290                 if (m.getName().equals("findByPrimaryKey")) {
291                     targetBeanType = EjbEntityDescriptor.TYPE;
292                     break;
293                 }
294             }
295         } catch(Exception JavaDoc e) {
296             if (logger.isLoggable(Level.FINE)) {
297                 logger.log(Level.FINE,
298                 "component intf / ejb type annotation processing error", e);
299             }
300         }
301
302         ejbRef.setLocal(EJBLocalHome JavaDoc.class.isAssignableFrom(beanInterface));
303         return targetBeanType;
304     }
305 }
306
Popular Tags