001: /**
002: * EasyBeans
003: * Copyright (C) 2006 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: EJBHomeRPCInvocationHandler.java 2010 2007-10-26 13:19:08Z benoitf $
023: * --------------------------------------------------------------------------
024: */package org.ow2.easybeans.proxy.client;
025:
026: import java.lang.reflect.Method;
027: import java.lang.reflect.Proxy;
028: import java.rmi.RemoteException;
029:
030: import javax.ejb.EJBHome;
031: import javax.ejb.EJBMetaData;
032: import javax.ejb.EJBObject;
033: import javax.ejb.Handle;
034: import javax.ejb.HomeHandle;
035: import javax.ejb.RemoveException;
036:
037: import org.ow2.easybeans.container.svc.EasyBeansMetaData;
038:
039: /**
040: * This class sends an EJB request to the server and send back to the client the
041: * response. It handles the EJBHome calls.
042: * @author Florent Benoit
043: */
044: public class EJBHomeRPCInvocationHandler extends
045: ClientRPCInvocationHandler {
046:
047: /**
048: * Id for serializable class.
049: */
050: private static final long serialVersionUID = -5766859656696754086L;
051:
052: /**
053: * Remote interface.
054: */
055: private String remoteInterface = null;
056:
057: /**
058: * Build a new Invocation handler.
059: * @param containerId the id of the container that will be called on the
060: * remote side.
061: * @param factoryName the name of the remote factory.
062: * @param useID true if all instance build with this ref are unique
063: * (stateful), false if it references the same object (stateless)
064: * @param remoteInterface the name of the remote interface used by the home interface.
065: */
066: public EJBHomeRPCInvocationHandler(final String containerId,
067: final String factoryName, final boolean useID,
068: final String remoteInterface) {
069: super (containerId, factoryName, useID);
070: this .remoteInterface = remoteInterface;
071: }
072:
073: /**
074: * Processes a method invocation on a proxy instance and returns the result.
075: * This method will be invoked on an invocation handler when a method is
076: * invoked on a proxy instance that it is associated with.
077: * @param proxy the proxy instance that the method was invoked on
078: * @param method the <code>Method</code> instance corresponding to the
079: * interface method invoked on the proxy instance. The declaring
080: * class of the <code>Method</code> object will be the interface
081: * that the method was declared in, which may be a superinterface of
082: * the proxy interface that the proxy class inherits the method
083: * through.
084: * @param args an array of objects containing the values of the arguments
085: * passed in the method invocation on the proxy instance, or
086: * <code>null</code> if interface method takes no arguments.
087: * Arguments of primitive types are wrapped in instances of the
088: * appropriate primitive wrapper class, such as
089: * <code>java.lang.Integer</code> or <code>java.lang.Boolean</code>.
090: * @return the value to return from the method invocation on the proxy
091: * instance.
092: * @throws Exception the exception to throw from the method invocation on
093: * the proxy instance.
094: */
095: @Override
096: public Object invoke(final Object proxy, final Method method,
097: final Object[] args) throws Exception {
098:
099: // Create ?
100: if (method != null) {
101: if (method.getName().startsWith("create")) {
102: // Return class (interface)
103: Class<?> itfClass = method.getReturnType();
104:
105: // Build handler
106: ClientRPCInvocationHandler handler = new ClientRPCInvocationHandler(
107: getContainerId(), getFactoryName(), isUsingID());
108: handler.setRMIEnv(getRMIEnv());
109: // set the interface class
110: handler.setInterfaceClass(itfClass);
111:
112: // Get current classloader
113: ClassLoader classLoader = Thread.currentThread()
114: .getContextClassLoader();
115:
116: // Return proxy
117: Object beanProxy = Proxy.newProxyInstance(classLoader,
118: new Class[] { itfClass }, handler);
119:
120: // create the id for stateful bean
121: beanProxy.toString();
122:
123: // return the proxy built
124: return beanProxy;
125:
126: }
127: if (method.getName().equals("remove")) {
128: handleRemoveMethod(args);
129: // void method
130: return null;
131: }
132:
133: // getEJBMetaData
134: if (method.getName().equals("getEJBMetaData")) {
135: return handleGetEJBMetadata(proxy);
136: }
137:
138: // getHomeHandle
139: if (method.getName().equals("getHomeHandle")) {
140: return handleGetHomeHandle();
141: }
142:
143: }
144:
145: return super .invoke(proxy, method, args);
146: }
147:
148: /**
149: * Handle the remove method for this EJB Home object. If the remove method
150: * is not applied with an Handle, it means that it is for the primary key
151: * and this is not supported (Only handle session bean Home).
152: * @param args the arguments of the remove method. For primary key, it will
153: * throw an error.
154: * @throws RemoveException when applying remove method on a primary key.
155: * @throws RemoteException if the ejbObject cannot be retrieved from the
156: * handle or if the remove method is failing.
157: */
158: private void handleRemoveMethod(final Object[] args)
159: throws RemoteException, RemoveException {
160: // check if it is an incorrect method (primary key) ?
161: // args has a parameter as it uses the Home interface (so no need to
162: // check the length of args)
163: if (!(args[0] instanceof Handle)) {
164: throw new RemoveException(
165: "The remove method is not allowed with an object which is not an handle."
166: + "Primary key is only used for entity 2.1x bean.");
167: }
168:
169: // Ok, now the given arg is an Handle, get it.
170: Handle handle = (Handle) args[0];
171:
172: // Get the EJBObject from this handle and call the remove method.
173: EJBObject ejbObject = handle.getEJBObject();
174:
175: // removing
176: ejbObject.remove();
177: }
178:
179: /**
180: * Build a metadata object.
181: * @param proxy the object on which the method is currently invoked (it's the home proxy).
182: * @return an EJB metadata object.
183: * @throws RemoteException if metadata object cannot be built.
184: */
185: private EJBMetaData handleGetEJBMetadata(final Object proxy)
186: throws RemoteException {
187: // EJBHome is the proxy object
188: EJBHome ejbHome = (EJBHome) proxy;
189:
190: // Classloader
191: ClassLoader classLoader = Thread.currentThread()
192: .getContextClassLoader();
193:
194: // Home interface
195: Class<?> homeInterfaceClass = null;
196: try {
197: homeInterfaceClass = classLoader
198: .loadClass(getInterfaceClassName());
199: } catch (ClassNotFoundException e) {
200: throw new RemoteException("Cannot load the class '"
201: + getInterfaceClassName() + "'.", e);
202: }
203:
204: // Remote interface
205: Class<?> remoteInterfaceClass = null;
206: if (remoteInterface != null) {
207: try {
208: remoteInterfaceClass = classLoader
209: .loadClass(remoteInterface);
210: } catch (ClassNotFoundException e) {
211: throw new RemoteException("Cannot load the class '"
212: + remoteInterface + "'.", e);
213: }
214: }
215:
216: // stateless ? (using id = stateful)
217: boolean isStateless = !isUsingID();
218:
219: // build the metadata
220: EasyBeansMetaData metadata = new EasyBeansMetaData(ejbHome,
221: homeInterfaceClass, remoteInterfaceClass, isStateless);
222:
223: // return it
224: return metadata;
225: }
226:
227: /**
228: * Gets an Home handle from this EJB Home.
229: * @return an instance of an HomeHandle object.
230: */
231: private HomeHandle handleGetHomeHandle() {
232: return null;
233: }
234:
235: }
|