001: /**
002: * EasyBeans
003: * Copyright (C) 2006 Bull S.A.S.
004: * Contact: easybeans@objectweb.org
005: *
006: * This library is free software; you can redistribute it and/or
007: * modify it under the terms of the GNU Lesser General Public
008: * License as published by the Free Software Foundation; either
009: * version 2.1 of the License, or any later version.
010: *
011: * This library is distributed in the hope that it will be useful,
012: * but WITHOUT ANY WARRANTY; without even the implied warranty of
013: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
014: * Lesser General Public License for more details.
015: *
016: * You should have received a copy of the GNU Lesser General Public
017: * License along with this library; if not, write to the Free Software
018: * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
019: * USA
020: *
021: * --------------------------------------------------------------------------
022: * $Id: SessionBeanInterface.java 847 2006-07-12 09:51:27Z benoitf $
023: * --------------------------------------------------------------------------
024: */package com.bm.ejb3metadata.annotations.helper.bean.session;
025:
026: import static com.bm.ejb3metadata.annotations.helper.bean.InheritanceInterfacesHelper.JAVA_LANG_OBJECT;
027: import static org.ejb3unit.asm.Opcodes.ACC_PUBLIC;
028:
029: import java.util.ArrayList;
030: import java.util.List;
031:
032: import com.bm.ejb3metadata.annotations.JMethod;
033: import com.bm.ejb3metadata.annotations.impl.JAnnotationResource;
034: import com.bm.ejb3metadata.annotations.metadata.ClassAnnotationMetadata;
035: import com.bm.ejb3metadata.annotations.metadata.MethodAnnotationMetadata;
036:
037: /**
038: * This class analyze interfaces of the session bean. If the session bean
039: * implements javax.ejb.SessionBean interface, add lifecycle callbacks and add
040: * resource injection for setSessionContext method.
041: *
042: * @author Florent Benoit
043: */
044: public final class SessionBeanInterface {
045:
046: /**
047: * SessionBean interface.
048: */
049: private static final String SESSION_BEAN_INTERFACE = "javax/ejb/SessionBean";
050:
051: /**
052: * setSessionContext() method.
053: */
054: private static final JMethod SETSESSIONCONTEXT_METHOD = new JMethod(
055: ACC_PUBLIC, "setSessionContext",
056: "(Ljavax/ejb/SessionContext;)V", null, new String[] {
057: "javax/ejb/EJBException",
058: "java/rmi/RemoteException" });
059:
060: /**
061: * ejbRemove() method.
062: */
063: private static final JMethod EJBREMOVE_METHOD = new JMethod(
064: ACC_PUBLIC, "ejbRemove", "()V", null, new String[] {
065: "javax/ejb/EJBException",
066: "java/rmi/RemoteException" });
067:
068: /**
069: * ejbActivate() method.
070: */
071: private static final JMethod EJBACTIVATE_METHOD = new JMethod(
072: ACC_PUBLIC, "ejbActivate", "()V", null, new String[] {
073: "javax/ejb/EJBException",
074: "java/rmi/RemoteException" });
075:
076: /**
077: * ejbPassivate() method.
078: */
079: private static final JMethod EJBPASSIVATE_METHOD = new JMethod(
080: ACC_PUBLIC, "ejbPassivate", "()V", null, new String[] {
081: "javax/ejb/EJBException",
082: "java/rmi/RemoteException" });
083:
084: /**
085: * Helper class, no public constructor.
086: */
087: private SessionBeanInterface() {
088: }
089:
090: /**
091: * Try to see if bean implements javax.ejb.SessionBean interface.
092: *
093: * @param sessionBean
094: * Session bean to analyze
095: */
096: public static void resolve(final ClassAnnotationMetadata sessionBean) {
097: // Make a list of interfaces
098: List<String> allInterfaces = getAllInterfacesFromClass(sessionBean);
099:
100: // if SESSION_BEAN_INTERFACE is contained in the list, add some metadata
101: if (allInterfaces.contains(SESSION_BEAN_INTERFACE)) {
102: // first add dependency injection for setSessionContext method.
103: JAnnotationResource jAnnotationResource = new JAnnotationResource();
104:
105: // add resource on setSessionContext method
106: MethodAnnotationMetadata setCtxMethod = getMethod(
107: sessionBean, SETSESSIONCONTEXT_METHOD, false);
108: setCtxMethod.setJAnnotationResource(jAnnotationResource);
109:
110: // ejbRemove() method
111: MethodAnnotationMetadata ejbRemoveMethod = getMethod(
112: sessionBean, EJBREMOVE_METHOD, true);
113: ejbRemoveMethod.setPreDestroy(true);
114: if (!sessionBean.getPreDestroyMethodsMetadata().contains(
115: ejbRemoveMethod)) {
116: sessionBean
117: .addPreDestroyMethodMetadata(ejbRemoveMethod);
118: }
119:
120: // ejbActivate() method
121: MethodAnnotationMetadata ejbActivateMethod = getMethod(
122: sessionBean, EJBACTIVATE_METHOD, true);
123: ejbRemoveMethod.setPostActivate(true);
124: if (!sessionBean.getPostActivateMethodsMetadata().contains(
125: ejbActivateMethod)) {
126: sessionBean
127: .addPostActivateMethodMetadata(ejbActivateMethod);
128: }
129:
130: // ejbPassivate() method
131: MethodAnnotationMetadata ejbPassivateMethod = getMethod(
132: sessionBean, EJBPASSIVATE_METHOD, true);
133: ejbRemoveMethod.setPrePassivate(true);
134: if (!sessionBean.getPrePassivateMethodsMetadata().contains(
135: ejbPassivateMethod)) {
136: sessionBean
137: .addPrePassivateMethodMetadata(ejbPassivateMethod);
138: }
139:
140: }
141:
142: }
143:
144: /**
145: * Gets method metadata on the given class metadata for the given method.
146: *
147: * @param sessionBean
148: * the class metadata on which retrieve the method
149: * @param jMethod
150: * the method to get
151: * @param inherited
152: * get the correct method in super class, not inherited
153: * @return the method metadata, else exception
154: */
155: private static MethodAnnotationMetadata getMethod(
156: final ClassAnnotationMetadata sessionBean,
157: final JMethod jMethod, final boolean inherited) {
158: MethodAnnotationMetadata method = sessionBean
159: .getMethodAnnotationMetadata(jMethod);
160: if (method == null) {
161: throw new IllegalStateException("Bean '" + sessionBean
162: + "' implements " + SESSION_BEAN_INTERFACE
163: + " but no " + jMethod
164: + " method found in metadata");
165: }
166: // gets the correct method on the correct level. (not the inherited
167: // method) if we don't want the inherited method.
168: if (method.isInherited() && !inherited) {
169: String super ClassName = sessionBean.getSuperName();
170: // loop while class is not java.lang.Object
171: while (!JAVA_LANG_OBJECT.equals(super ClassName)) {
172: ClassAnnotationMetadata super MetaData = sessionBean
173: .getEjbJarAnnotationMetadata()
174: .getClassAnnotationMetadata(super ClassName);
175: // If the method is found in the super class and is not
176: // inherited, use this one
177: if (super MetaData != null) {
178: MethodAnnotationMetadata super Method = super MetaData
179: .getMethodAnnotationMetadata(jMethod);
180: if (super Method != null
181: && !super Method.isInherited()) {
182: return super Method;
183: }
184: super ClassName = super MetaData.getSuperName();
185: } else {
186: // break the loop
187: super ClassName = JAVA_LANG_OBJECT;
188: }
189: }
190:
191: }
192:
193: return method;
194: }
195:
196: /**
197: * Gets all interfaces used by a class.
198: *
199: * @param sessionBean
200: * the metadata to analyze.
201: * @return the list of interfaces from a given class.
202: */
203: public static List<String> getAllInterfacesFromClass(
204: final ClassAnnotationMetadata sessionBean) {
205: // build list
206: List<String> allInterfaces = new ArrayList<String>();
207:
208: // Class to analyze
209: String className = sessionBean.getClassName();
210:
211: // loop while class is not java.lang.Object
212: while (!JAVA_LANG_OBJECT.equals(className)) {
213: ClassAnnotationMetadata metaData = sessionBean
214: .getEjbJarAnnotationMetadata()
215: .getClassAnnotationMetadata(className);
216: // find metadata, all interfaces found
217: if (metaData != null) {
218: String[] interfaces = metaData.getInterfaces();
219: if (interfaces != null) {
220: for (String itf : interfaces) {
221: allInterfaces.add(itf);
222: }
223: }
224: className = metaData.getSuperName();
225: } else {
226: // break the loop
227: className = JAVA_LANG_OBJECT;
228: }
229: }
230: return allInterfaces;
231: }
232: }
|