KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > objectweb > easybeans > container > session > stateful > StatefulSessionFactory


1 /**
2  * EasyBeans
3  * Copyright (C) 2006 Bull S.A.S.
4  * Contact: easybeans@objectweb.org
5  *
6  * This library is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Lesser General Public
8  * License as published by the Free Software Foundation; either
9  * version 2.1 of the License, or any later version.
10  *
11  * This library is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with this library; if not, write to the Free Software
18  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
19  * USA
20  *
21  * --------------------------------------------------------------------------
22  * $Id: StatefulSessionFactory.java 1133 2006-10-04 14:30:41Z benoitf $
23  * --------------------------------------------------------------------------
24  */

25
26 package org.objectweb.easybeans.container.session.stateful;
27
28 import java.lang.reflect.InvocationTargetException JavaDoc;
29 import java.lang.reflect.Method JavaDoc;
30
31 import javax.ejb.ApplicationException JavaDoc;
32 import javax.ejb.NoSuchEJBException JavaDoc;
33
34 import org.objectweb.easybeans.api.EZBContainer;
35 import org.objectweb.easybeans.api.FactoryException;
36 import org.objectweb.easybeans.api.bean.EasyBeansSFSB;
37 import org.objectweb.easybeans.api.pool.PoolException;
38 import org.objectweb.easybeans.container.session.SessionFactory;
39 import org.objectweb.easybeans.log.JLog;
40 import org.objectweb.easybeans.log.JLogFactory;
41 import org.objectweb.easybeans.pool.JPool;
42 import org.objectweb.easybeans.pool.PoolEntryStatistics;
43 import org.objectweb.easybeans.pool.PoolFactory;
44 import org.objectweb.easybeans.rpc.JEJBResponse;
45 import org.objectweb.easybeans.rpc.api.EJBResponse;
46 import org.objectweb.easybeans.rpc.api.RPCException;
47
48 /**
49  * This class manages the stateless session bean and its creation/lifecycle.
50  * @author Florent Benoit
51  */

52 public class StatefulSessionFactory extends SessionFactory<EasyBeansSFSB> implements PoolFactory<EasyBeansSFSB, Long JavaDoc> {
53
54     /**
55      * Logger.
56      */

57     private static JLog logger = JLogFactory.getLog(StatefulSessionFactory.class);
58
59     /**
60      * Id generator.
61      */

62     private long idCount = 0L;
63
64     /**
65      * Builds a new factory with a given name and its container.
66      * @param className name of this factory (name of class that is managed)
67      * @param container the root component of this factory.
68      * @throws FactoryException if class can't be loaded.
69      */

70     public StatefulSessionFactory(final String JavaDoc className, final EZBContainer container) throws FactoryException {
71         super(className, container);
72         JPool<EasyBeansSFSB, Long JavaDoc> pool = new JPool<EasyBeansSFSB, Long JavaDoc>(this);
73         // stateful = only one client at a given time.
74
pool.setAllowSharedInstance(false);
75         setPool(pool);
76     }
77
78     /**
79      * Checks if the given object with the given clue is matching.
80      * @param bean given object against which the check should be done.
81      * @param clue the object used as clue to check the matching.
82      * @return true if it is matching, else false.
83      */

84     public boolean isMatching(final EasyBeansSFSB bean, final Long JavaDoc clue) {
85         logger.debug("Called with bean = {0} and beanId = {1}", bean, clue);
86         Long JavaDoc beanId = bean.getEasyBeansStatefulID();
87         boolean val = (beanId.equals(clue));
88         logger.debug("Found id = {0} and will return = {1}", beanId, Boolean.valueOf(val));
89         return val;
90     }
91
92     /**
93      * Validate an instance by giving some statistics.
94      * @param object the instance to validate
95      * @param stats some statistics to help in the validating process.
96      * @return true if the element is valid, else false.
97      */

98     public boolean validate(final EasyBeansSFSB object, final PoolEntryStatistics stats) {
99         return true;
100     }
101
102     /**
103      * Gets a new ID or a null value.
104      * @param beanId given id.
105      * @return new id
106      */

107     @Override JavaDoc
108     protected synchronized Long JavaDoc getId(final Long JavaDoc beanId) {
109         Long JavaDoc newId = beanId;
110         // no Id, compute a new one
111
if (newId == null) {
112             idCount++;
113             newId = Long.valueOf(idCount);
114         }
115         return newId;
116     }
117
118     /**
119      * Creates an instance with the given hint.
120      * @param clue a clue given by the Pool. Could be null.
121      * @throws PoolException if instance cannot be created.
122      * @return the created instance.
123      */

124     @Override JavaDoc
125     public synchronized EasyBeansSFSB create(final Long JavaDoc clue) throws PoolException {
126         // else, create it
127
EasyBeansSFSB bean = super.create(clue);
128
129         return bean;
130     }
131
132     /**
133      * Gets a bean for the given id.
134      * @param beanId id of the expected bean.
135      * @return a Stateless bean.
136      * @throws IllegalArgumentException if bean is not found.
137      */

138     @Override JavaDoc
139     protected synchronized EasyBeansSFSB getBean(final Long JavaDoc beanId) throws IllegalArgumentException JavaDoc {
140         EasyBeansSFSB bean = null;
141         try {
142             bean = getPool().get(beanId);
143         } catch (PoolException e) {
144             throw new IllegalArgumentException JavaDoc("Cannot get element in the pool", e);
145         }
146         logger.debug("Set for bean {0} the Id = {1}", bean, beanId);
147         bean.setEasyBeansStatefulID(beanId);
148         return bean;
149     }
150
151     /**
152      * Callback called when object is gonna be removed.
153      * @param instance that is being removed from the pool.
154      */

155     @Override JavaDoc
156     public void remove(final EasyBeansSFSB instance) {
157         super.remove(instance);
158         instance.setEasyBeansRemoved(true);
159     }
160
161     /**
162      * Do a local call on a method of this factory.
163      * @param hash the hash of the method to execute.
164      * @param methodArgs the arguments of the method
165      * @param beanId the id of the bean that we want (stateful).
166      * @return response container new id (if any) and value.
167      */

168     @Override JavaDoc
169     public EJBResponse localCall(final long hash, final Object JavaDoc[] methodArgs, final Long JavaDoc beanId) {
170         Long JavaDoc id = getId(beanId);
171
172         // build EJB Response and set the id
173
EJBResponse ejbResponse = new JEJBResponse();
174         ejbResponse.setBeanId(id);
175
176         EasyBeansSFSB bean = null;
177         try {
178             bean = getBean(id);
179         } catch (IllegalArgumentException JavaDoc e) {
180             ejbResponse.setRPCException(new RPCException("Cannot get element in the pool", e));
181             return ejbResponse;
182         } catch (NoSuchEJBException JavaDoc e) {
183             ejbResponse.setRPCException(new RPCException("Bean has been removed", e));
184             return ejbResponse;
185         }
186
187         Method JavaDoc m = getHashes().get(Long.valueOf(hash));
188
189         if (m == null) {
190             ejbResponse.setRPCException(new RPCException("Cannot find method called on the bean '" + getClassName() + "'."));
191             return ejbResponse;
192         }
193
194         Object JavaDoc value = null;
195
196         // set ClassLoader
197
ClassLoader JavaDoc oldClassLoader = Thread.currentThread().getContextClassLoader();
198         Thread.currentThread().setContextClassLoader(getContainer().getClassLoader());
199         synchronized (bean) {
200             try {
201                 value = m.invoke(bean, methodArgs);
202             } catch (IllegalArgumentException JavaDoc e) {
203                 ejbResponse.setRPCException(new RPCException(e));
204             } catch (IllegalAccessException JavaDoc e) {
205                 ejbResponse.setRPCException(new RPCException(e));
206             } catch (InvocationTargetException JavaDoc e) {
207                 Throwable JavaDoc cause = e.getCause();
208                 RPCException rpcException = new RPCException(cause);
209                 // ApplicationException ?
210
ApplicationException JavaDoc applicationException = getBeanInfo().getApplicationExceptions().get(
211                         cause.getClass().getName());
212                 if (applicationException != null) {
213                     rpcException.setApplicationException();
214                 }
215                 ejbResponse.setRPCException(rpcException);
216             } finally {
217                 Thread.currentThread().setContextClassLoader(oldClassLoader);
218                 // push back into the pool
219
try {
220                     getPool().release(bean);
221                 } catch (PoolException e) {
222                     ejbResponse.setRPCException(new RPCException("cannot release bean", e));
223                 }
224
225                 // If the bean has been removed (stateful), flag it as a removed
226
// bean, so the client won't call again any methods.
227
if (bean.getEasyBeansRemoved()) {
228                     ejbResponse.setRemoved(true);
229                 }
230
231             }
232         }
233         ejbResponse.setValue(value);
234         return ejbResponse;
235
236     }
237 }
238
Popular Tags