KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > springframework > ejb > access > AbstractSlsbInvokerInterceptor


1 /*
2  * Copyright 2002-2006 the original author or authors.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */

16
17 package org.springframework.ejb.access;
18
19 import java.lang.reflect.InvocationTargetException JavaDoc;
20 import java.lang.reflect.Method JavaDoc;
21
22 import javax.naming.NamingException JavaDoc;
23
24 import org.aopalliance.intercept.MethodInterceptor;
25
26 import org.springframework.jndi.JndiObjectLocator;
27
28 /**
29  * Superclass for AOP interceptors invoking local or remote Stateless Session Beans.
30  *
31  * <p>Such an interceptor must be the last interceptor in the advice chain.
32  * In this case, there is no direct target object: The call is handled in a
33  * special way, getting executed on an EJB instance retrieved via an EJB home.
34  *
35  * @author Rod Johnson
36  * @author Juergen Hoeller
37  */

38 public abstract class AbstractSlsbInvokerInterceptor extends JndiObjectLocator
39         implements MethodInterceptor {
40
41     private boolean lookupHomeOnStartup = true;
42
43     private boolean cacheHome = true;
44
45     /**
46      * The EJB's home object, potentially cached.
47      * The type must be Object as it could be either EJBHome or EJBLocalHome.
48      */

49     private Object JavaDoc cachedHome;
50
51     /**
52      * The no-arg create() method required on EJB homes, potentially cached.
53      */

54     private Method JavaDoc createMethod;
55
56     private final Object JavaDoc homeMonitor = new Object JavaDoc();
57
58
59     /**
60      * Set whether to look up the EJB home object on startup.
61      * Default is "true".
62      * <p>Can be turned off to allow for late start of the EJB server.
63      * In this case, the EJB home object will be fetched on first access.
64      * @see #setCacheHome
65      */

66     public void setLookupHomeOnStartup(boolean lookupHomeOnStartup) {
67         this.lookupHomeOnStartup = lookupHomeOnStartup;
68     }
69
70     /**
71      * Set whether to cache the EJB home object once it has been located.
72      * Default is "true".
73      * <p>Can be turned off to allow for hot restart of the EJB server.
74      * In this case, the EJB home object will be fetched for each invocation.
75      * @see #setLookupHomeOnStartup
76      */

77     public void setCacheHome(boolean cacheHome) {
78         this.cacheHome = cacheHome;
79     }
80
81
82     /**
83      * Fetches EJB home on startup, if necessary.
84      * @see #setLookupHomeOnStartup
85      * @see #refreshHome
86      */

87     public void afterPropertiesSet() throws NamingException JavaDoc {
88         super.afterPropertiesSet();
89         if (this.lookupHomeOnStartup) {
90             // look up EJB home and create method
91
refreshHome();
92         }
93     }
94
95     /**
96      * Refresh the cached home object, if applicable.
97      * Also caches the create method on the home object.
98      * @throws NamingException if thrown by the JNDI lookup
99      * @see #lookup
100      * @see #getCreateMethod
101      */

102     protected void refreshHome() throws NamingException JavaDoc {
103         synchronized (this.homeMonitor) {
104             Object JavaDoc home = lookup();
105             if (this.cacheHome) {
106                 this.cachedHome = home;
107                 this.createMethod = getCreateMethod(home);
108             }
109         }
110     }
111
112     /**
113      * Determine the create method of the given EJB home object.
114      * @param home the EJB home object
115      * @return the create method
116      * @throws EjbAccessException if the method couldn't be retrieved
117      */

118     protected Method JavaDoc getCreateMethod(Object JavaDoc home) throws EjbAccessException {
119         try {
120             // Cache the EJB create() method that must be declared on the home interface.
121
return home.getClass().getMethod("create", (Class JavaDoc[]) null);
122         }
123         catch (NoSuchMethodException JavaDoc ex) {
124             throw new EjbAccessException("EJB home [" + home + "] has no no-arg create() method");
125         }
126     }
127
128     /**
129      * Return the EJB home object to use. Called for each invocation.
130      * <p>Default implementation returns the home created on initialization,
131      * if any; else, it invokes lookup to get a new proxy for each invocation.
132      * <p>Can be overridden in subclasses, for example to cache a home object
133      * for a given amount of time before recreating it, or to test the home
134      * object whether it is still alive.
135      * @return the EJB home object to use for an invocation
136      * @throws NamingException if proxy creation failed
137      * @see #lookup
138      * @see #getCreateMethod
139      */

140     protected Object JavaDoc getHome() throws NamingException JavaDoc {
141         if (!this.cacheHome || (this.lookupHomeOnStartup && !isHomeRefreshable())) {
142             return (this.cachedHome != null ? this.cachedHome : lookup());
143         }
144         else {
145             synchronized (this.homeMonitor) {
146                 if (this.cachedHome == null) {
147                     this.cachedHome = lookup();
148                     this.createMethod = getCreateMethod(this.cachedHome);
149                 }
150                 return this.cachedHome;
151             }
152         }
153     }
154
155     /**
156      * Return whether the cached EJB home object is potentially
157      * subject to on-demand refreshing. Default is "false".
158      */

159     protected boolean isHomeRefreshable() {
160         return false;
161     }
162
163     /**
164      * Invoke the create() method on the cached EJB home object.
165      * @return a new EJBObject or EJBLocalObject
166      * @throws NamingException if thrown by JNDI
167      * @throws InvocationTargetException if thrown by the create method
168      */

169     protected Object JavaDoc create() throws NamingException JavaDoc, InvocationTargetException JavaDoc {
170         try {
171             Object JavaDoc home = getHome();
172             Method JavaDoc createMethodToUse = this.createMethod;
173             if (createMethodToUse == null) {
174                 createMethodToUse = getCreateMethod(home);
175             }
176             // Invoke create() method on EJB home object.
177
return createMethodToUse.invoke(home, (Object JavaDoc[]) null);
178         }
179         catch (IllegalAccessException JavaDoc ex) {
180             throw new EjbAccessException("Could not access EJB home create() method", ex);
181         }
182     }
183
184 }
185
Popular Tags