001: /**
002: * EasyBeans
003: * Copyright (C) 2006-2007 Bull S.A.S.
004: * Contact: easybeans@ow2.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: StatelessSessionFactory.java 1970 2007-10-16 11:49:25Z benoitf $
023: * --------------------------------------------------------------------------
024: */package org.ow2.easybeans.container.session.stateless;
025:
026: import java.lang.reflect.InvocationTargetException;
027: import java.lang.reflect.Method;
028:
029: import javax.ejb.ApplicationException;
030: import javax.ejb.EJBException;
031: import javax.ejb.NoSuchEJBException;
032: import javax.ejb.Timer;
033:
034: import org.ow2.easybeans.api.EZBContainer;
035: import org.ow2.easybeans.api.FactoryException;
036: import org.ow2.easybeans.api.bean.EasyBeansSLSB;
037: import org.ow2.easybeans.api.pool.PoolException;
038: import org.ow2.easybeans.container.session.SessionFactory;
039: import org.ow2.easybeans.pool.JPool;
040: import org.ow2.easybeans.pool.PoolEntryStatistics;
041: import org.ow2.easybeans.pool.PoolFactory;
042: import org.ow2.easybeans.rpc.JEJBResponse;
043: import org.ow2.easybeans.rpc.api.EJBResponse;
044: import org.ow2.easybeans.rpc.api.RPCException;
045:
046: /**
047: * This class manages the stateless session bean and its creation/lifecycle.
048: * @author Florent Benoit
049: */
050: public class StatelessSessionFactory extends
051: SessionFactory<EasyBeansSLSB> implements
052: PoolFactory<EasyBeansSLSB, Long> {
053:
054: /**
055: * Builds a new factory with a given name and its container.
056: * @param className name of this factory (name of class that is managed)
057: * @param container the root component of this factory.
058: * @throws FactoryException if class can't be loaded.
059: */
060: public StatelessSessionFactory(final String className,
061: final EZBContainer container) throws FactoryException {
062: super (className, container);
063: setPool(new JPool<EasyBeansSLSB, Long>(this ));
064: }
065:
066: /**
067: * Checks if the given object with the given clue is matching.
068: * @param object given object against which the check should be done.
069: * @param clue the object used as clue to check the matching.
070: * @return true if it is matching, else false.
071: */
072: public boolean isMatching(final EasyBeansSLSB object,
073: final Long clue) {
074: // all instances are matching.
075: // But we shouldn't go here
076: return true;
077: }
078:
079: /**
080: * Validate an instance by giving some statistics.
081: * @param object the instance to validate
082: * @param stats some statistics to help in the validating process.
083: * @return true if the element is valid, else false.
084: */
085: public boolean validate(final EasyBeansSLSB object,
086: final PoolEntryStatistics stats) {
087: return true;
088: }
089:
090: /**
091: * Gets a new ID or a null value.
092: * @param beanId given id.
093: * @return new id
094: */
095: @Override
096: protected Long getId(final Long beanId) {
097: return null;
098: }
099:
100: /**
101: * Gets a bean for the given id.
102: * @param beanId id of the expected bean.
103: * @return a Stateless bean.
104: * @throws IllegalArgumentException if bean is not found.
105: */
106: @Override
107: protected EasyBeansSLSB getBean(final Long beanId)
108: throws IllegalArgumentException {
109: try {
110: return getPool().get();
111: } catch (PoolException e) {
112: throw new IllegalArgumentException(
113: "Cannot get element in the pool", e);
114: }
115: }
116:
117: /**
118: * Do a local call on a method of this factory.
119: * @param hash the hash of the method to execute.
120: * @param methodArgs the arguments of the method
121: * @param beanId the id of the bean that we want (stateful).
122: * @return response container new id (if any) and value.
123: */
124: @Override
125: public EJBResponse localCall(final long hash,
126: final Object[] methodArgs, final Long beanId) {
127:
128: // build EJB Response and set the id
129: EJBResponse ejbResponse = new JEJBResponse();
130:
131: EasyBeansSLSB bean = null;
132: try {
133: bean = getBean(null);
134: } catch (IllegalArgumentException e) {
135: ejbResponse.setRPCException(new RPCException(
136: "Cannot get element in the pool", e));
137: return ejbResponse;
138: } catch (NoSuchEJBException e) {
139: ejbResponse.setRPCException(new RPCException(
140: "Bean has been removed", e));
141: return ejbResponse;
142: }
143:
144: Method m = getHashes().get(Long.valueOf(hash));
145:
146: if (m == null) {
147: ejbResponse.setRPCException(new RPCException(
148: "Cannot find method called on the bean '"
149: + getClassName() + "'."));
150: return ejbResponse;
151: }
152:
153: Object value = null;
154:
155: // set ClassLoader
156: ClassLoader oldClassLoader = Thread.currentThread()
157: .getContextClassLoader();
158: Thread.currentThread().setContextClassLoader(
159: getContainer().getClassLoader());
160:
161: try {
162: value = m.invoke(bean, methodArgs);
163: } catch (IllegalArgumentException e) {
164: ejbResponse.setRPCException(new RPCException(e));
165: } catch (IllegalAccessException e) {
166: ejbResponse.setRPCException(new RPCException(e));
167: } catch (InvocationTargetException e) {
168: Throwable cause = e.getCause();
169: RPCException rpcException = new RPCException(cause);
170: // ApplicationException ?
171: ApplicationException applicationException = getBeanInfo()
172: .getApplicationExceptions().get(
173: cause.getClass().getName());
174: if (applicationException != null) {
175: rpcException.setApplicationException();
176: }
177: ejbResponse.setRPCException(rpcException);
178: } finally {
179: Thread.currentThread()
180: .setContextClassLoader(oldClassLoader);
181: // push back into the pool
182: try {
183: getPool().release(bean);
184: } catch (PoolException e) {
185: ejbResponse.setRPCException(new RPCException(
186: "cannot release bean", e));
187: }
188:
189: }
190: ejbResponse.setValue(value);
191: return ejbResponse;
192:
193: }
194:
195: /**
196: * Callback called when object is gonna be removed.
197: * @param instance that is being removed from the pool.
198: */
199: @Override
200: public void remove(final EasyBeansSLSB instance) {
201: super .remove(instance);
202: instance.setEasyBeansRemoved(true);
203: }
204:
205: /**
206: * Notified when the timer service send a Timer object.
207: * It has to call the Timed method.
208: * @param timer the given timer object that will be given to the timer method.
209: */
210: public void notifyTimeout(final Timer timer) {
211: // Call the EasyBeans timer method on a given bean instance
212: EasyBeansSLSB bean = null;
213: bean = getBean(null);
214:
215: //set ClassLoader
216: ClassLoader oldClassLoader = Thread.currentThread()
217: .getContextClassLoader();
218: Thread.currentThread().setContextClassLoader(
219: getContainer().getClassLoader());
220:
221: // Call the timer method on the bean
222: try {
223: bean.timeoutCallByEasyBeans(timer);
224: } finally {
225: // Reset classloader
226: Thread.currentThread()
227: .setContextClassLoader(oldClassLoader);
228:
229: // push back into the pool
230: try {
231: getPool().release(bean);
232: } catch (PoolException e) {
233: throw new EJBException("cannot release bean", e);
234: }
235: }
236: }
237:
238: }
|