KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > jboss > ejb3 > stateless > StatelessContainer


1 /*
2 * JBoss, Home of Professional Open Source
3 * Copyright 2005, JBoss Inc., and individual contributors as indicated
4 * by the @authors tag. See the copyright.txt in the distribution for a
5 * full listing of individual contributors.
6 *
7 * This is free software; you can redistribute it and/or modify it
8 * under the terms of the GNU Lesser General Public License as
9 * published by the Free Software Foundation; either version 2.1 of
10 * the License, or (at your option) any later version.
11 *
12 * This software is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
16 *
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this software; if not, write to the Free
19 * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
20 * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
21 */

22 package org.jboss.ejb3.stateless;
23
24
25 import org.jboss.annotation.ejb.LocalBinding;
26 import org.jboss.annotation.ejb.RemoteBinding;
27 import org.jboss.annotation.ejb.RemoteBindings;
28 import org.jboss.aop.AspectManager;
29 import org.jboss.aop.MethodInfo;
30 import org.jboss.aop.advice.Interceptor;
31 import org.jboss.aop.joinpoint.Invocation;
32 import org.jboss.aop.joinpoint.InvocationResponse;
33 import org.jboss.aop.joinpoint.MethodInvocation;
34 import org.jboss.aop.util.MethodHashing;
35 import org.jboss.aspects.asynch.FutureHolder;
36 import org.jboss.ejb.AllowedOperationsAssociation;
37 import org.jboss.ejb.AllowedOperationsFlags;
38 import org.jboss.ejb3.EJBContainerInvocation;
39 import org.jboss.ejb3.Ejb3Deployment;
40 import org.jboss.ejb3.ProxyFactoryHelper;
41 import org.jboss.ejb3.ProxyUtils;
42 import org.jboss.ejb3.SessionContainer;
43 import org.jboss.ejb3.BeanContext;
44 import org.jboss.ejb3.interceptor.InterceptorInfoRepository;
45 import org.jboss.ejb3.timerservice.TimedObjectInvoker;
46 import org.jboss.ejb3.timerservice.TimerServiceFactory;
47 import org.jboss.logging.Logger;
48 import org.jboss.proxy.ejb.handle.HomeHandleImpl;
49 import org.jboss.proxy.ejb.handle.StatelessHandleImpl;
50 import org.jboss.injection.EncInjector;
51
52 import javax.ejb.EJBException JavaDoc;
53 import javax.ejb.Handle JavaDoc;
54 import javax.ejb.Timer JavaDoc;
55 import javax.ejb.TimerService JavaDoc;
56 import javax.naming.NamingException JavaDoc;
57 import java.lang.reflect.Method JavaDoc;
58 import java.util.Hashtable JavaDoc;
59 import java.util.Map JavaDoc;
60 import java.util.HashMap JavaDoc;
61
62
63 /**
64  * Comment
65  *
66  * @author <a HREF="mailto:bill@jboss.org">Bill Burke</a>
67  * @version $Revision: 57901 $
68  */

69 public class StatelessContainer extends SessionContainer implements TimedObjectInvoker
70 {
71    private static final Logger log = Logger.getLogger(StatelessContainer.class);
72
73    protected TimerService JavaDoc timerService;
74
75    public StatelessContainer(ClassLoader JavaDoc cl, String JavaDoc beanClassName, String JavaDoc ejbName, AspectManager manager,
76                              Hashtable JavaDoc ctxProperties, InterceptorInfoRepository interceptorRepository,
77                              Ejb3Deployment deployment)
78    {
79       super(cl, beanClassName, ejbName, manager, ctxProperties, interceptorRepository, deployment);
80       beanContextClass = StatelessBeanContext.class;
81    }
82
83    public Object JavaDoc createSession(Class JavaDoc initTypes[], Object JavaDoc initArgs[])
84    {
85       if((initTypes != null && initTypes.length > 0) || (initArgs != null && initArgs.length > 0))
86          throw new IllegalArgumentException JavaDoc("stateless bean create method must take no arguments (EJB3 4.5)");
87       // a stateless bean has no sessions
88
// TODO: pool stuff
89
return null;
90    }
91    
92    public void start() throws Exception JavaDoc
93    {
94       try
95       {
96          super.start();
97          //timerService = EjbTimerUtil.getTimerService(this, this);
98
timerService = TimerServiceFactory.getInstance().createTimerService(this.getObjectName(), this);
99          
100          TimerServiceFactory.getInstance().restoreTimerService(timerService);
101       }
102       catch (Exception JavaDoc e)
103       {
104          try
105          {
106             stop();
107          }
108          catch (Exception JavaDoc ignore)
109          {
110             log.debug("Failed to cleanup after start() failure", ignore);
111          }
112          throw e;
113       }
114    }
115
116    public void stop() throws Exception JavaDoc
117    {
118       //if (timerService != null) EjbTimerUtil.removeTimerService(this);
119
if (timerService != null) TimerServiceFactory.getInstance().removeTimerService(timerService);
120       super.stop();
121    }
122
123    public TimerService JavaDoc getTimerService()
124    {
125       return timerService;
126    }
127
128    public TimerService JavaDoc getTimerService(Object JavaDoc pKey)
129    {
130       assert timerService != null : "Timer Service not yet initialized";
131       return timerService;
132    }
133    
134    public void callTimeout(Timer JavaDoc timer) throws Exception JavaDoc
135    {
136       Method JavaDoc timeout = callbackHandler.getTimeoutCallback();
137       if (timeout == null) throw new EJBException JavaDoc("No method has been annotated with @Timeout");
138       Object JavaDoc[] args = {timer};
139       ClassLoader JavaDoc oldLoader = Thread.currentThread().getContextClassLoader();
140       try
141       {
142          AllowedOperationsAssociation.pushInMethodFlag(AllowedOperationsFlags.IN_EJB_TIMEOUT);
143          try
144          {
145             MethodInfo info = (MethodInfo) methodInterceptors.get(callbackHandler.getTimeoutCalllbackHash());
146             Interceptor[] aspects = info.getInterceptors();
147             EJBContainerInvocation nextInvocation = new EJBContainerInvocation(info, aspects);
148             nextInvocation.setAdvisor(this);
149             nextInvocation.setArguments(args);
150             nextInvocation.invokeNext();
151          }
152          catch (Throwable JavaDoc throwable)
153          {
154             if (throwable instanceof Exception JavaDoc) throw (Exception JavaDoc) throwable;
155             throw new RuntimeException JavaDoc(throwable);
156          }
157          finally
158          {
159             AllowedOperationsAssociation.popInMethodFlag();
160          }
161       }
162       finally
163       {
164          Thread.currentThread().setContextClassLoader(oldLoader);
165       }
166    }
167
168    /**
169     * Performs a synchronous local invocation
170     */

171    public Object JavaDoc localInvoke(Method JavaDoc method, Object JavaDoc[] args) throws Throwable JavaDoc
172    {
173       return localInvoke(method, args, null);
174    }
175
176    /**
177     * Performs a synchronous or asynchronous local invocation
178     *
179     * @param provider If null a synchronous invocation, otherwise an asynchronous
180     */

181    public Object JavaDoc localInvoke(Method JavaDoc method, Object JavaDoc[] args, FutureHolder provider) throws Throwable JavaDoc
182    {
183       long start = System.currentTimeMillis();
184       
185       ClassLoader JavaDoc oldLoader = Thread.currentThread().getContextClassLoader();
186       try
187       {
188          long hash = MethodHashing.calculateHash(method);
189          MethodInfo info = (MethodInfo) methodInterceptors.get(hash);
190          if (info == null)
191          {
192             throw new RuntimeException JavaDoc("Could not resolve beanClass method from proxy call: " + method.toString());
193          }
194
195          Method JavaDoc unadvisedMethod = info.getUnadvisedMethod();
196
197          try
198          {
199             invokeStats.callIn();
200             
201             invokedMethod.push(new InvokedMethod(true, unadvisedMethod));
202
203             if (unadvisedMethod != null && isHomeMethod(unadvisedMethod))
204             {
205                return invokeLocalHomeMethod(info, args);
206             }
207
208             Interceptor[] aspects = info.getInterceptors();
209             EJBContainerInvocation nextInvocation = new EJBContainerInvocation(info, aspects);
210             nextInvocation.setAdvisor(this);
211             nextInvocation.setArguments(args);
212
213             ProxyUtils.addLocalAsynchronousInfo(nextInvocation, provider);
214             return nextInvocation.invokeNext();
215          }
216          finally
217          {
218             if (unadvisedMethod != null)
219             {
220                long end = System.currentTimeMillis();
221                long elapsed = end - start;
222                invokeStats.updateStats(unadvisedMethod, elapsed);
223             }
224             
225             invokeStats.callOut();
226             
227             invokedMethod.pop();
228          }
229       }
230       finally
231       {
232          Thread.currentThread().setContextClassLoader(oldLoader);
233       }
234    }
235
236    public InvocationResponse dynamicInvoke(Object JavaDoc target, Invocation invocation) throws Throwable JavaDoc
237    {
238       long start = System.currentTimeMillis();
239       
240       ClassLoader JavaDoc oldLoader = Thread.currentThread().getContextClassLoader();
241       try
242       {
243          Thread.currentThread().setContextClassLoader(classloader);
244          MethodInvocation si = (MethodInvocation) invocation;
245          MethodInfo info = (MethodInfo) methodInterceptors.get(si.getMethodHash());
246          if (info == null)
247          {
248             throw new RuntimeException JavaDoc("Could not resolve beanClass method from proxy call");
249          }
250
251          Method JavaDoc unadvisedMethod = info.getUnadvisedMethod();
252          try
253          {
254             invokeStats.callIn();
255             
256             invokedMethod.push(new InvokedMethod(false, unadvisedMethod));
257             Map JavaDoc responseContext = null;
258             Object JavaDoc rtn = null;
259             if (unadvisedMethod != null && isHomeMethod(unadvisedMethod))
260             {
261                rtn = invokeHomeMethod(info, si);
262             }
263             else if (info != null && unadvisedMethod != null && isEJBObjectMethod(unadvisedMethod))
264             {
265                rtn = invokeEJBObjectMethod(info, si);
266             }
267             else
268             {
269
270                EJBContainerInvocation newSi = null;
271                Interceptor[] aspects = info.getInterceptors();
272
273                newSi = new EJBContainerInvocation(info, aspects);
274                newSi.setArguments(si.getArguments());
275                newSi.setMetaData(si.getMetaData());
276                newSi.setAdvisor(this);
277                try
278                {
279                   rtn = newSi.invokeNext();
280                   responseContext = newSi.getResponseContextInfo();
281                }
282                catch (Throwable JavaDoc throwable)
283                {
284                   responseContext = newSi.getResponseContextInfo();
285                   return marshallException(invocation, throwable, responseContext);
286                }
287             }
288
289             InvocationResponse response = marshallResponse(invocation, rtn, responseContext);
290             return response;
291          }
292          finally
293          {
294             if (unadvisedMethod != null)
295             {
296                long end = System.currentTimeMillis();
297                long elapsed = end - start;
298                invokeStats.updateStats(unadvisedMethod, elapsed);
299             }
300             
301             invokeStats.callOut();
302             
303             invokedMethod.pop();
304          }
305       }
306       finally
307       {
308          Thread.currentThread().setContextClassLoader(oldLoader);
309       }
310
311    }
312
313
314    protected Object JavaDoc invokeEJBObjectMethod(MethodInfo info, MethodInvocation invocation) throws Throwable JavaDoc
315    {
316       Method JavaDoc unadvisedMethod = info.getUnadvisedMethod();
317       if (unadvisedMethod.getName().equals("getHandle"))
318       {
319          StatelessHandleImpl handle = null;
320          RemoteBinding remoteBindingAnnotation = (RemoteBinding) resolveAnnotation(RemoteBinding.class);
321          if (remoteBindingAnnotation != null)
322             handle = new StatelessHandleImpl(remoteBindingAnnotation.jndiBinding());
323
324          return handle;
325       }
326       else if (unadvisedMethod.getName().equals("remove"))
327       {
328          return null;
329       }
330       else if (unadvisedMethod.getName().equals("getEJBHome"))
331       {
332          HomeHandleImpl homeHandle = null;
333
334          RemoteBinding remoteBindingAnnotation = (RemoteBinding) resolveAnnotation(RemoteBinding.class);
335          if (remoteBindingAnnotation != null)
336             homeHandle = new HomeHandleImpl(remoteBindingAnnotation.jndiBinding() + "Home");
337
338          return homeHandle.getEJBHome();
339       }
340       else if (unadvisedMethod.getName().equals("getPrimaryKey"))
341       {
342          return null;
343       }
344       else if (unadvisedMethod.getName().equals("isIdentical"))
345       {
346          return false;
347       }
348       else
349       {
350          return null;
351       }
352    }
353
354    private Object JavaDoc invokeLocalHomeMethod(MethodInfo info, Object JavaDoc[] args) throws Exception JavaDoc
355    {
356       Method JavaDoc unadvisedMethod = info.getUnadvisedMethod();
357       if (unadvisedMethod.getName().equals("create"))
358       {
359          LocalBinding binding = (LocalBinding) resolveAnnotation(LocalBinding.class);
360
361          StatelessLocalProxyFactory factory = new StatelessLocalProxyFactory();
362          factory.setContainer(this);
363          factory.init();
364
365          Object JavaDoc proxy = factory.createProxy();
366
367          return proxy;
368       }
369       else // remove
370
{
371          return null;
372       }
373    }
374
375    protected Object JavaDoc invokeHomeMethod(MethodInfo info, MethodInvocation invocation) throws Throwable JavaDoc
376    {
377       Method JavaDoc unadvisedMethod = info.getUnadvisedMethod();
378       if (unadvisedMethod.getName().equals("create"))
379       {
380          RemoteBinding binding = null;
381
382          RemoteBindings bindings = (RemoteBindings) resolveAnnotation(RemoteBindings.class);
383          if (bindings != null)
384             binding = bindings.value()[0];
385          else
386             binding = (RemoteBinding) resolveAnnotation(RemoteBinding.class);
387
388          StatelessRemoteProxyFactory factory = new StatelessRemoteProxyFactory();
389          factory.setContainer(this);
390          factory.setRemoteBinding(binding);
391          factory.init();
392
393          return factory.createProxy();
394       }
395       else // remove
396
{
397          return null;
398       }
399    }
400
401    @Override JavaDoc
402    public Object JavaDoc getBusinessObject(BeanContext ctx, Class JavaDoc intf)
403    {
404       try
405       {
406          String JavaDoc jndiName = ProxyFactoryHelper.getJndiName(this, intf);
407          if (jndiName == null) throw new IllegalStateException JavaDoc("Cannot find BusinessObject for interface: " + intf.getName());
408          return getInitialContext().lookup(ProxyFactoryHelper.getJndiName(this, intf));
409       }
410       catch (NamingException JavaDoc e)
411       {
412          throw new RuntimeException JavaDoc("failed to invoke getBusinessObject", e);
413       }
414    }
415
416    protected void removeHandle(Handle JavaDoc handle)
417    {
418       throw new RuntimeException JavaDoc("NYI");
419    }
420 }
421
Popular Tags