KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > jboss > ejb3 > stateful > StatefulContainer


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.stateful;
23
24 import org.jboss.annotation.ejb.LocalBinding;
25 import org.jboss.annotation.ejb.RemoteBinding;
26 import org.jboss.annotation.ejb.RemoteBindings;
27 import org.jboss.annotation.ejb.cache.Cache;
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.util.MethodHashing;
34 import org.jboss.aspects.asynch.FutureHolder;
35 import org.jboss.ejb3.BeanContext;
36 import org.jboss.ejb3.EJBContainerInvocation;
37 import org.jboss.ejb3.Ejb3Deployment;
38 import org.jboss.ejb3.ProxyFactory;
39 import org.jboss.ejb3.ProxyFactoryHelper;
40 import org.jboss.ejb3.ProxyUtils;
41 import org.jboss.ejb3.SessionContainer;
42 import org.jboss.ejb3.ThreadLocalENCFactory;
43 import org.jboss.ejb3.cache.StatefulCache;
44 import org.jboss.injection.Injector;
45 import org.jboss.injection.JndiFieldInjector;
46 import org.jboss.ejb3.interceptor.InterceptorInfoRepository;
47 import org.jboss.ejb3.proxy.EJBMetaDataImpl;
48 import org.jboss.ejb3.proxy.handle.HomeHandleImpl;
49 import org.jboss.logging.Logger;
50
51 import javax.annotation.PostConstruct;
52 import javax.annotation.PreDestroy;
53 import javax.ejb.EJBHome JavaDoc;
54 import javax.ejb.EJBObject JavaDoc;
55 import javax.ejb.Handle JavaDoc;
56 import javax.ejb.Init JavaDoc;
57 import javax.ejb.PostActivate JavaDoc;
58 import javax.ejb.PrePassivate JavaDoc;
59 import javax.ejb.Remote JavaDoc;
60 import javax.ejb.RemoteHome JavaDoc;
61 import javax.ejb.TimerService JavaDoc;
62 import java.lang.reflect.Field JavaDoc;
63 import java.lang.reflect.Method JavaDoc;
64 import java.util.Hashtable JavaDoc;
65 import java.util.Map JavaDoc;
66
67 /**
68  * Comment
69  *
70  * @author <a HREF="mailto:bill@jboss.org">Bill Burke</a>
71  * @version $Revision: 58057 $
72  */

73 public class StatefulContainer extends SessionContainer
74 {
75    private static final Logger log = Logger.getLogger(StatefulContainer.class);
76
77    protected StatefulCache cache;
78
79    public StatefulContainer(ClassLoader JavaDoc cl, String JavaDoc beanClassName, String JavaDoc ejbName, AspectManager manager,
80                             Hashtable JavaDoc ctxProperties, InterceptorInfoRepository interceptorRepository,
81                             Ejb3Deployment deployment)
82    {
83       super(cl, beanClassName, ejbName, manager, ctxProperties, interceptorRepository, deployment);
84       beanContextClass = StatefulBeanContext.class;
85    }
86
87    public void start() throws Exception JavaDoc
88    {
89       try
90       {
91          super.start();
92          Cache cacheConfig = (Cache) resolveAnnotation(Cache.class);
93          cache = (StatefulCache) cacheConfig.value().newInstance();
94          cache.initialize(this);
95          cache.start();
96       }
97       catch (Exception JavaDoc e)
98       {
99          try
100          {
101             stop();
102          }
103          catch (Exception JavaDoc ignore)
104          {
105             log.debug("Failed to cleanup after start() failure", ignore);
106          }
107          throw e;
108       }
109
110    }
111
112    public void stop() throws Exception JavaDoc
113    {
114       super.stop();
115       if (cache != null) cache.stop();
116    }
117
118    public StatefulCache getCache()
119    {
120       return cache;
121    }
122
123    /**
124     * Performs a synchronous local invocation
125     */

126    public Object JavaDoc localInvoke(Object JavaDoc id, Method JavaDoc method, Object JavaDoc[] args)
127            throws Throwable JavaDoc
128    {
129       return localInvoke(id, method, args, null);
130    }
131
132    /**
133     * Performs a synchronous or asynchronous local invocation
134     *
135     */

136    public Object JavaDoc localHomeInvoke(Method JavaDoc method, Object JavaDoc[] args) throws Throwable JavaDoc
137    {
138       ClassLoader JavaDoc oldLoader = Thread.currentThread().getContextClassLoader();
139       ThreadLocalENCFactory.push(enc);
140       try
141       {
142          long hash = MethodHashing.calculateHash(method);
143          MethodInfo info = (MethodInfo) methodInterceptors.get(hash);
144          if (info == null)
145          {
146             throw new RuntimeException JavaDoc(
147                     "Could not resolve beanClass method from proxy call: "
148                             + method.toString());
149          }
150          return invokeLocalHomeMethod(info, args);
151       }
152       finally
153       {
154          Thread.currentThread().setContextClassLoader(oldLoader);
155          ThreadLocalENCFactory.pop();
156       }
157    }
158
159    /**
160     * Performs a synchronous or asynchronous local invocation
161     *
162     * @param provider If null a synchronous invocation, otherwise an asynchronous
163     */

164    public Object JavaDoc localInvoke(Object JavaDoc id, Method JavaDoc method, Object JavaDoc[] args,
165          FutureHolder provider) throws Throwable JavaDoc
166    {
167       long start = System.currentTimeMillis();
168
169       ClassLoader JavaDoc oldLoader = Thread.currentThread().getContextClassLoader();
170       ThreadLocalENCFactory.push(enc);
171       try
172       {
173          long hash = MethodHashing.calculateHash(method);
174          MethodInfo info = (MethodInfo) methodInterceptors.get(hash);
175          if (info == null)
176          {
177             throw new RuntimeException JavaDoc(
178                   "Could not resolve beanClass method from proxy call: "
179                   + method.toString());
180          }
181       
182          Method JavaDoc unadvisedMethod = info.getUnadvisedMethod();
183       
184          try
185          {
186             invokeStats.callIn();
187       
188             if (unadvisedMethod != null && isHomeMethod(unadvisedMethod))
189             {
190                return invokeLocalHomeMethod(info, args);
191             }
192             else if (unadvisedMethod != null
193                   && isEJBObjectMethod(unadvisedMethod))
194             {
195                return invokeEJBLocalObjectMethod(id, info, args);
196             }
197             
198             Interceptor[] aspects = info.getInterceptors();
199             StatefulContainerInvocation nextInvocation = new StatefulContainerInvocation(
200             info, aspects, id);
201             nextInvocation.setAdvisor(this);
202             nextInvocation.setArguments(args);
203             
204             ProxyUtils.addLocalAsynchronousInfo(nextInvocation, provider);
205             
206             invokedMethod.push(new InvokedMethod(true, method));
207             return nextInvocation.invokeNext();
208          }
209          finally
210          {
211             if (unadvisedMethod != null)
212             {
213                long end = System.currentTimeMillis();
214                long elapsed = end - start;
215                invokeStats.updateStats(unadvisedMethod, elapsed);
216             }
217          
218             invokeStats.callOut();
219             
220             invokedMethod.pop();
221          }
222       }
223       finally
224       {
225          Thread.currentThread().setContextClassLoader(oldLoader);
226          ThreadLocalENCFactory.pop();
227       }
228    }
229
230    /**
231     * Create a stateful bean and return its oid.
232     *
233     * @return
234     */

235    public Object JavaDoc createSession()
236    {
237       ClassLoader JavaDoc oldLoader = Thread.currentThread().getContextClassLoader();
238       ThreadLocalENCFactory.push(enc);
239       try
240       {
241          Thread.currentThread().setContextClassLoader(classloader);
242          return getCache().create().getId();
243       }
244       finally
245       {
246          Thread.currentThread().setContextClassLoader(oldLoader);
247          ThreadLocalENCFactory.pop();
248       }
249    }
250
251    /**
252     * Create a stateful bean and return its oid.
253     *
254     * @return
255     */

256    public Object JavaDoc createSession(Class JavaDoc[] initTypes, Object JavaDoc[] initValues)
257    {
258       ClassLoader JavaDoc oldLoader = Thread.currentThread().getContextClassLoader();
259       ThreadLocalENCFactory.push(enc);
260       try
261       {
262          Thread.currentThread().setContextClassLoader(classloader);
263          return getCache().create(initTypes, initValues).getId();
264       }
265       finally
266       {
267          Thread.currentThread().setContextClassLoader(oldLoader);
268          ThreadLocalENCFactory.pop();
269       }
270    }
271
272    protected void destroySession(Object JavaDoc id)
273    {
274       getCache().remove(id);
275    }
276
277    /**
278     * This should be a remote invocation call
279     *
280     * @param invocation
281     * @return
282     * @throws Throwable
283     */

284    public InvocationResponse dynamicInvoke(Object JavaDoc target, Invocation invocation) throws Throwable JavaDoc
285    {
286       long start = System.currentTimeMillis();
287       
288       ClassLoader JavaDoc oldLoader = Thread.currentThread().getContextClassLoader();
289       EJBContainerInvocation newSi = null;
290       ThreadLocalENCFactory.push(enc);
291       try
292       {
293          Thread.currentThread().setContextClassLoader(classloader);
294          StatefulRemoteInvocation si = (StatefulRemoteInvocation) invocation;
295          MethodInfo info = (MethodInfo) methodInterceptors.get(si.getMethodHash());
296          if (info == null)
297          {
298             throw new RuntimeException JavaDoc("Could not resolve beanClass method from proxy call");
299          }
300
301          InvocationResponse response = null;
302          Method JavaDoc unadvisedMethod = info.getUnadvisedMethod();
303          Object JavaDoc newId = null;
304          
305          try
306          {
307             invokeStats.callIn();
308             
309             if (info != null && unadvisedMethod != null && isHomeMethod(unadvisedMethod))
310             {
311                response = invokeHomeMethod(info, si);
312             }
313             else if (info != null && unadvisedMethod != null && isEJBObjectMethod(unadvisedMethod))
314             {
315                response = invokeEJBObjectMethod(info, si);
316             }
317             else
318             {
319                Interceptor[] aspects = info.getInterceptors();
320                
321                if (si.getId() == null)
322                {
323                   StatefulBeanContext ctx = getCache().create();
324                   newId = ctx.getId();
325                }
326                else
327                {
328                   newId = si.getId();
329                }
330                newSi = new StatefulContainerInvocation(info, aspects, newId);
331                newSi.setArguments(si.getArguments());
332                newSi.setMetaData(si.getMetaData());
333                newSi.setAdvisor(this);
334    
335                Object JavaDoc rtn = null;
336                
337                invokedMethod.push(new InvokedMethod(false, unadvisedMethod));
338                rtn = newSi.invokeNext();
339
340                response = marshallResponse(invocation, rtn, newSi.getResponseContextInfo());
341                if (newId != null) response.addAttachment(StatefulConstants.NEW_ID, newId);
342             }
343          }
344          catch (Throwable JavaDoc throwable)
345          {
346             Throwable JavaDoc exception = throwable;
347             if (newId != null)
348             {
349                exception = new ForwardId(throwable, newId);
350             }
351             Map JavaDoc responseContext = null;
352             if (newSi != null) newSi.getResponseContextInfo();
353             response = marshallException(invocation, exception, responseContext);
354             return response;
355          }
356          finally
357          {
358             if (unadvisedMethod != null)
359             {
360                long end = System.currentTimeMillis();
361                long elapsed = end - start;
362                invokeStats.updateStats(unadvisedMethod, elapsed);
363             }
364             
365             invokeStats.callOut();
366             
367             invokedMethod.pop();
368          }
369
370          return response;
371       }
372       finally
373       {
374          Thread.currentThread().setContextClassLoader(oldLoader);
375          ThreadLocalENCFactory.pop();
376       }
377    }
378
379
380    public TimerService JavaDoc getTimerService()
381    {
382       throw new UnsupportedOperationException JavaDoc("stateful bean doesn't support TimerService (EJB3 18.2#2)");
383    }
384
385    public TimerService JavaDoc getTimerService(Object JavaDoc pKey)
386    {
387       return getTimerService();
388    }
389    
390    @Override JavaDoc
391    public void invokePostActivate(BeanContext beanContext)
392    {
393       for (Injector injector : injectors)
394       {
395          if (injector instanceof JndiFieldInjector)
396          {
397             Field JavaDoc field = ((JndiFieldInjector) injector).getField();
398             if (field.isAnnotationPresent(javax.ejb.EJB JavaDoc.class))
399             {
400                continue; // skip nested EJB injection since the local proxy will be (de)serialized correctly
401
}
402             injector.inject(beanContext);
403          }
404       }
405       callbackHandler.postActivate(beanContext);
406    }
407
408    @Override JavaDoc
409    public void invokePrePassivate(BeanContext beanContext)
410    {
411       callbackHandler.prePassivate(beanContext);
412    }
413
414    @Override JavaDoc
415    protected Class JavaDoc[] getHandledCallbacks()
416    {
417       return new Class JavaDoc[]
418               {PostConstruct.class, PreDestroy.class, PostActivate JavaDoc.class,
419                       PrePassivate JavaDoc.class};
420    }
421
422    public void invokeInit(Object JavaDoc bean)
423    {
424       try
425       {
426          Method JavaDoc[] methods = bean.getClass().getDeclaredMethods();
427
428          for (int i = 0; i < methods.length; i++)
429          {
430             if (methods[i].getParameterTypes().length == 0)
431             {
432                if ((methods[i].getAnnotation(Init JavaDoc.class) != null)
433                        || (resolveAnnotation(methods[i], Init JavaDoc.class) != null))
434                {
435                   methods[i].invoke(bean, new Object JavaDoc[0]);
436                }
437             }
438          }
439       }
440       catch (Exception JavaDoc e)
441       {
442          throw new RuntimeException JavaDoc(e);
443       }
444    }
445
446    public void invokeInit(Object JavaDoc bean, Class JavaDoc[] initParameterTypes,
447                           Object JavaDoc[] initParameterValues)
448    {
449       try
450       {
451          Method JavaDoc[] methods = bean.getClass().getDeclaredMethods();
452
453          for (int i = 0; i < methods.length; i++)
454          {
455             if ((methods[i].getAnnotation(Init JavaDoc.class) != null)
456                     || (resolveAnnotation(methods[i], Init JavaDoc.class) != null))
457             {
458                Object JavaDoc[] parameters = getInitParameters(methods[i],
459                        initParameterTypes, initParameterValues);
460
461                if (parameters != null)
462                   methods[i].invoke(bean, parameters);
463             }
464          }
465       }
466       catch (Exception JavaDoc e)
467       {
468          throw new RuntimeException JavaDoc(e);
469       }
470    }
471
472    protected Object JavaDoc[] getInitParameters(Method JavaDoc method,
473                                         Class JavaDoc[] initParameterTypes, Object JavaDoc[] initParameterValues)
474    {
475       if (method.getParameterTypes().length == initParameterTypes.length)
476       {
477          for (int i = 0; i < initParameterTypes.length; ++i)
478          {
479             Class JavaDoc formal = method.getParameterTypes()[i];
480             Class JavaDoc actual = initParameterTypes[i];
481             if (!isMethodInvocationConvertible(formal, actual == null ? null
482                     : actual))
483                return null;
484          }
485          return initParameterValues;
486       }
487       return null;
488    }
489
490    /**
491     * Determines whether a type represented by a class object is convertible to
492     * another type represented by a class object using a method invocation
493     * conversion, treating object types of primitive types as if they were
494     * primitive types (that is, a Boolean actual parameter type matches boolean
495     * primitive formal type). This behavior is because this method is used to
496     * determine applicable methods for an actual parameter list, and primitive
497     * types are represented by their object duals in reflective method calls.
498     *
499     * @param formal the formal parameter type to which the actual parameter type
500     * should be convertible
501     * @param actual the actual parameter type.
502     * @return true if either formal type is assignable from actual type, or
503     * formal is a primitive type and actual is its corresponding object
504     * type or an object type of a primitive type that can be converted
505     * to the formal type.
506     */

507    private static boolean isMethodInvocationConvertible(Class JavaDoc formal,
508                                                         Class JavaDoc actual)
509    {
510       /*
511        * if it's a null, it means the arg was null
512        */

513       if (actual == null && !formal.isPrimitive())
514       {
515          return true;
516       }
517       /*
518        * Check for identity or widening reference conversion
519        */

520       if (actual != null && formal.isAssignableFrom(actual))
521       {
522          return true;
523       }
524       /*
525        * Check for boxing with widening primitive conversion. Note that actual
526        * parameters are never primitives.
527        */

528       if (formal.isPrimitive())
529       {
530          if (formal == Boolean.TYPE && actual == Boolean JavaDoc.class)
531             return true;
532          if (formal == Character.TYPE && actual == Character JavaDoc.class)
533             return true;
534          if (formal == Byte.TYPE && actual == Byte JavaDoc.class)
535             return true;
536          if (formal == Short.TYPE
537                  && (actual == Short JavaDoc.class || actual == Byte JavaDoc.class))
538             return true;
539          if (formal == Integer.TYPE
540                  && (actual == Integer JavaDoc.class || actual == Short JavaDoc.class || actual == Byte JavaDoc.class))
541             return true;
542          if (formal == Long.TYPE
543                  && (actual == Long JavaDoc.class || actual == Integer JavaDoc.class
544                  || actual == Short JavaDoc.class || actual == Byte JavaDoc.class))
545             return true;
546          if (formal == Float.TYPE
547                  && (actual == Float JavaDoc.class || actual == Long JavaDoc.class
548                  || actual == Integer JavaDoc.class || actual == Short JavaDoc.class || actual == Byte JavaDoc.class))
549             return true;
550          if (formal == Double.TYPE
551                  && (actual == Double JavaDoc.class || actual == Float JavaDoc.class
552                  || actual == Long JavaDoc.class || actual == Integer JavaDoc.class
553                  || actual == Short JavaDoc.class || actual == Byte JavaDoc.class))
554             return true;
555       }
556       return false;
557    }
558
559    private Object JavaDoc invokeEJBLocalObjectMethod(Object JavaDoc id, MethodInfo info,
560                                              Object JavaDoc[] args) throws Exception JavaDoc
561    {
562       Method JavaDoc unadvisedMethod = info.getUnadvisedMethod();
563       if (unadvisedMethod.getName().equals("remove"))
564       {
565          destroySession(id);
566
567          return null;
568       }
569       else if (unadvisedMethod.getName().equals("getEJBLocalHome"))
570       {
571          Object JavaDoc bean = getCache().get(id).getInstance();
572
573          return bean;
574       }
575       else if (unadvisedMethod.getName().equals("getPrimaryKey"))
576       {
577          return id;
578       }
579       else if (unadvisedMethod.getName().equals("isIdentical"))
580       {
581          EJBObject JavaDoc bean = (EJBObject JavaDoc) args[0];
582
583          Object JavaDoc primaryKey = bean.getPrimaryKey();
584
585          boolean isIdentical = id.equals(primaryKey);
586
587          return isIdentical;
588       }
589       else
590       {
591          return null;
592       }
593    }
594
595    private Object JavaDoc invokeLocalHomeMethod(MethodInfo info, Object JavaDoc[] args)
596            throws Exception JavaDoc
597    {
598       Method JavaDoc unadvisedMethod = info.getUnadvisedMethod();
599       if (unadvisedMethod.getName().equals("create"))
600       {
601          Class JavaDoc[] initParameterTypes =
602                  {};
603          Object JavaDoc[] initParameterValues =
604                  {};
605          if (unadvisedMethod.getParameterTypes().length > 0)
606          {
607             initParameterTypes = unadvisedMethod.getParameterTypes();
608             initParameterValues = args;
609          }
610
611          LocalBinding binding = (LocalBinding) resolveAnnotation(LocalBinding.class);
612          ;
613
614          StatefulLocalProxyFactory factory = new StatefulLocalProxyFactory();
615          factory.setContainer(this);
616          factory.init();
617
618          Object JavaDoc proxy = factory.createProxy(initParameterTypes,
619                  initParameterValues);
620
621          return proxy;
622       }
623       else if (unadvisedMethod.getName().equals("remove"))
624       {
625          StatefulHandleImpl handle = (StatefulHandleImpl) args[0];
626
627          destroySession(handle.id);
628
629          return null;
630       }
631       else
632       {
633          return null;
634       }
635    }
636
637    protected InvocationResponse invokeHomeMethod(MethodInfo info,
638                                                  StatefulRemoteInvocation statefulInvocation) throws Throwable JavaDoc
639    {
640       Method JavaDoc unadvisedMethod = info.getUnadvisedMethod();
641       if (unadvisedMethod.getName().equals("create"))
642       {
643          Class JavaDoc[] initParameterTypes =
644                  {};
645          Object JavaDoc[] initParameterValues =
646                  {};
647          if (unadvisedMethod.getParameterTypes().length > 0)
648          {
649             initParameterTypes = unadvisedMethod.getParameterTypes();
650             initParameterValues = statefulInvocation.getArguments();
651          }
652
653          RemoteBinding binding = null;
654          RemoteBindings bindings = (RemoteBindings) resolveAnnotation(RemoteBindings.class);
655          if (bindings != null)
656             binding = bindings.value()[0];
657          else
658             binding = (RemoteBinding) resolveAnnotation(RemoteBinding.class);
659
660          StatefulContainerInvocation newStatefulInvocation = buildNewInvocation(
661                  info, statefulInvocation, initParameterTypes,
662                  initParameterValues);
663
664          StatefulRemoteProxyFactory factory = new StatefulRemoteProxyFactory();
665          factory.setContainer(this);
666          factory.setRemoteBinding(binding);
667          factory.init();
668
669          Object JavaDoc proxy = null;
670          if (newStatefulInvocation.getId() != null)
671             proxy = factory.createProxy(newStatefulInvocation.getId());
672          else
673             proxy = factory.createProxy();
674
675          InvocationResponse response = marshallResponse(statefulInvocation, proxy, newStatefulInvocation.getResponseContextInfo());
676          if (newStatefulInvocation.getId() != null)
677             response.addAttachment(StatefulConstants.NEW_ID,
678                     newStatefulInvocation.getId());
679          return response;
680       }
681       else if (unadvisedMethod.getName().equals("remove"))
682       {
683          StatefulHandleImpl handle = (StatefulHandleImpl) statefulInvocation
684                  .getArguments()[0];
685
686          destroySession(handle.id);
687
688          InvocationResponse response = new InvocationResponse(null);
689          response.setContextInfo(statefulInvocation.getResponseContextInfo());
690          return response;
691       }
692       else if (unadvisedMethod.getName().equals("getEJBMetaData"))
693       {
694          Class JavaDoc remote = null;
695          Class JavaDoc home = null;
696          Class JavaDoc pkClass = Object JavaDoc.class;
697          HomeHandleImpl homeHandle = null;
698
699          Remote JavaDoc remoteAnnotation = (Remote JavaDoc) resolveAnnotation(Remote JavaDoc.class);
700          if (remoteAnnotation != null)
701             remote = remoteAnnotation.value()[0];
702          RemoteHome JavaDoc homeAnnotation = (RemoteHome JavaDoc) resolveAnnotation(RemoteHome JavaDoc.class);
703          if (homeAnnotation != null)
704             home = homeAnnotation.value();
705          RemoteBinding remoteBindingAnnotation = (RemoteBinding) resolveAnnotation(RemoteBinding.class);
706          if (remoteBindingAnnotation != null)
707             homeHandle = new HomeHandleImpl(remoteBindingAnnotation
708                     .jndiBinding());
709
710          EJBMetaDataImpl metadata = new EJBMetaDataImpl(remote, home, pkClass,
711                  true, false, homeHandle);
712
713          InvocationResponse response = marshallResponse(statefulInvocation, metadata, null);
714          return response;
715       }
716       else if (unadvisedMethod.getName().equals("getHomeHandle"))
717       {
718          HomeHandleImpl homeHandle = null;
719
720          RemoteBinding remoteBindingAnnotation = (RemoteBinding) resolveAnnotation(RemoteBinding.class);
721          if (remoteBindingAnnotation != null)
722             homeHandle = new HomeHandleImpl(remoteBindingAnnotation
723                     .jndiBinding());
724
725
726          InvocationResponse response = marshallResponse(statefulInvocation, homeHandle, null);
727          return response;
728       }
729       else
730       {
731          return null;
732       }
733    }
734
735    protected InvocationResponse invokeEJBObjectMethod(MethodInfo info,
736                                                       StatefulRemoteInvocation statefulInvocation) throws Throwable JavaDoc
737    {
738       Method JavaDoc unadvisedMethod = info.getUnadvisedMethod();
739       if (unadvisedMethod.getName().equals("getHandle"))
740       {
741          StatefulContainerInvocation newStatefulInvocation = buildInvocation(
742                  info, statefulInvocation);
743
744          StatefulHandleImpl handle = new StatefulHandleImpl();
745          handle.id = newStatefulInvocation.getId();
746          RemoteBinding remoteBinding = (RemoteBinding) resolveAnnotation(RemoteBinding.class);
747          if (remoteBinding != null)
748             handle.jndiName = remoteBinding.jndiBinding();
749          InvocationResponse response = marshallResponse(statefulInvocation, handle, null);
750          return response;
751       }
752       else if (unadvisedMethod.getName().equals("remove"))
753       {
754          destroySession(statefulInvocation.getId());
755
756          InvocationResponse response = new InvocationResponse(null);
757          return response;
758       }
759       else if (unadvisedMethod.getName().equals("getEJBHome"))
760       {
761          HomeHandleImpl homeHandle = null;
762
763          RemoteBinding remoteBindingAnnotation = (RemoteBinding) resolveAnnotation(RemoteBinding.class);
764          if (remoteBindingAnnotation != null)
765             homeHandle = new HomeHandleImpl(remoteBindingAnnotation
766                     .jndiBinding() + "Home");
767
768          EJBHome JavaDoc ejbHome = homeHandle.getEJBHome();
769
770          InvocationResponse response = marshallResponse(statefulInvocation, ejbHome, null);
771          return response;
772       }
773       else if (unadvisedMethod.getName().equals("getPrimaryKey"))
774       {
775          Object JavaDoc id = statefulInvocation.getId();
776
777          InvocationResponse response = marshallResponse(statefulInvocation, id, null);
778          return response;
779       }
780       else if (unadvisedMethod.getName().equals("isIdentical"))
781       {
782          Object JavaDoc id = statefulInvocation.getId();
783          EJBObject JavaDoc bean = (EJBObject JavaDoc) statefulInvocation.getArguments()[0];
784
785          Object JavaDoc primaryKey = bean.getPrimaryKey();
786
787          boolean isIdentical = id.equals(primaryKey);
788
789          InvocationResponse response = marshallResponse(statefulInvocation, isIdentical, null);
790          return response;
791       }
792       else
793       {
794          return null;
795       }
796    }
797
798    private StatefulContainerInvocation buildNewInvocation(MethodInfo info,
799                                                           StatefulRemoteInvocation statefulInvocation,
800                                                           Class JavaDoc[] initParameterTypes, Object JavaDoc[] initParameterValues)
801    {
802       StatefulContainerInvocation newStatefulInvocation = null;
803       Interceptor[] aspects = info.getInterceptors();
804       Object JavaDoc newId = null;
805
806       StatefulBeanContext ctx = null;
807       if (initParameterTypes.length > 0)
808          ctx = getCache().create(initParameterTypes, initParameterValues);
809       else
810          ctx = getCache().create();
811
812       newId = ctx.getId();
813       newStatefulInvocation = new StatefulContainerInvocation(info, aspects,
814               newId);
815
816       newStatefulInvocation.setArguments(statefulInvocation.getArguments());
817       newStatefulInvocation.setMetaData(statefulInvocation.getMetaData());
818       newStatefulInvocation.setAdvisor(this);
819
820       return newStatefulInvocation;
821    }
822
823    private StatefulContainerInvocation buildInvocation(MethodInfo info,
824                                                        StatefulRemoteInvocation statefulInvocation)
825    {
826       StatefulContainerInvocation newStatefulInvocation = null;
827       Interceptor[] aspects = info.getInterceptors();
828       Object JavaDoc newId = null;
829       if (statefulInvocation.getId() == null)
830       {
831          StatefulBeanContext ctx = getCache().create();
832          newId = ctx.getId();
833          newStatefulInvocation = new StatefulContainerInvocation(info, aspects,
834                  newId);
835       }
836       else
837       {
838          newStatefulInvocation = new StatefulContainerInvocation(info, aspects,
839                  statefulInvocation.getId());
840       }
841
842       newStatefulInvocation.setArguments(statefulInvocation.getArguments());
843       newStatefulInvocation.setMetaData(statefulInvocation.getMetaData());
844       newStatefulInvocation.setAdvisor(this);
845
846       return newStatefulInvocation;
847    }
848
849    @Override JavaDoc
850    public Object JavaDoc getBusinessObject(BeanContext beanContext, Class JavaDoc businessInterface) throws IllegalStateException JavaDoc
851    {
852       StatefulBeanContext ctx = (StatefulBeanContext) beanContext;
853
854       boolean isRemote = false;
855       boolean found = false;
856       Class JavaDoc[] remoteInterfaces = ProxyFactoryHelper.getRemoteInterfaces(this);
857       if (remoteInterfaces != null)
858       {
859          for (Class JavaDoc intf : remoteInterfaces)
860          {
861             if (intf.getName().equals(businessInterface.getName()))
862             {
863                isRemote = true;
864                found = true;
865                break;
866             }
867          }
868       }
869       if (found == false)
870       {
871          Class JavaDoc[] localInterfaces = ProxyFactoryHelper.getLocalInterfaces(this);
872          if (localInterfaces != null)
873          {
874             for (Class JavaDoc intf : remoteInterfaces)
875             {
876                if (intf.getName().equals(businessInterface.getName()))
877                {
878                   found = true;
879                   break;
880                }
881             }
882
883          }
884       }
885       if (found == false) throw new IllegalStateException JavaDoc(businessInterface.getName() + " is not a business interface");
886
887       for (ProxyFactory factory : proxyDeployer.getProxyFactories())
888       {
889          if (isRemote && factory instanceof StatefulRemoteProxyFactory)
890          {
891             return ((StatefulRemoteProxyFactory) factory).createProxy(ctx.getId());
892          }
893          else if (!isRemote && factory instanceof StatefulLocalProxyFactory)
894          {
895             return ((StatefulLocalProxyFactory) factory).createProxy(ctx.getId());
896          }
897       }
898       throw new IllegalStateException JavaDoc("Unable to create proxy for getBusinessObject as a proxy factory was not found");
899    }
900
901    protected void removeHandle(Handle JavaDoc arg) throws Exception JavaDoc
902    {
903       /*
904       StatefulHandleImpl handle = (StatefulHandleImpl) arg;
905
906       destroySession(handle.id);
907       */

908       arg.getEJBObject().remove();
909    }
910 }
911
Popular Tags