001: /**
002: * Licensed to the Apache Software Foundation (ASF) under one or more
003: * contributor license agreements. See the NOTICE file distributed with
004: * this work for additional information regarding copyright ownership.
005: * The ASF licenses this file to You under the Apache License, Version 2.0
006: * (the "License"); you may not use this file except in compliance with
007: * the License. You may obtain a copy of the License at
008: *
009: * http://www.apache.org/licenses/LICENSE-2.0
010: *
011: * Unless required by applicable law or agreed to in writing, software
012: * distributed under the License is distributed on an "AS IS" BASIS,
013: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014: * See the License for the specific language governing permissions and
015: * limitations under the License.
016: */package org.apache.openejb.client;
017:
018: import java.io.Externalizable;
019: import java.io.IOException;
020: import java.io.ObjectInput;
021: import java.io.ObjectOutput;
022: import java.lang.reflect.Method;
023: import java.rmi.RemoteException;
024:
025: import javax.ejb.EJBHome;
026: import javax.ejb.Handle;
027: import javax.ejb.EJBException;
028:
029: import org.apache.openejb.client.proxy.ProxyManager;
030:
031: public abstract class EJBHomeHandler extends EJBInvocationHandler
032: implements Externalizable {
033:
034: protected static final Method GETEJBMETADATA = getMethod(
035: EJBHome.class, "getEJBMetaData", null);
036: protected static final Method GETHOMEHANDLE = getMethod(
037: EJBHome.class, "getHomeHandle", null);
038: protected static final Method REMOVE_W_KEY = getMethod(
039: EJBHome.class, "remove", new Class[] { Object.class });
040: protected static final Method REMOVE_W_HAND = getMethod(
041: EJBHome.class, "remove", new Class[] { Handle.class });
042: protected static final Method GETHANDLER = getMethod(
043: EJBHomeProxy.class, "getEJBHomeHandler", null);
044:
045: public EJBHomeHandler() {
046: }
047:
048: public EJBHomeHandler(EJBMetaDataImpl ejb, ServerMetaData server,
049: ClientMetaData client) {
050: super (ejb, server, client);
051: }
052:
053: public static EJBHomeHandler createEJBHomeHandler(
054: EJBMetaDataImpl ejb, ServerMetaData server,
055: ClientMetaData client) {
056:
057: switch (ejb.type) {
058: case EJBMetaDataImpl.BMP_ENTITY:
059: case EJBMetaDataImpl.CMP_ENTITY:
060:
061: return new EntityEJBHomeHandler(ejb, server, client);
062:
063: case EJBMetaDataImpl.STATEFUL:
064:
065: return new StatefulEJBHomeHandler(ejb, server, client);
066:
067: case EJBMetaDataImpl.STATELESS:
068:
069: return new StatelessEJBHomeHandler(ejb, server, client);
070: }
071: return null;
072:
073: }
074:
075: // protected abstract EJBObjectHandler newEJBObjectHandler();
076:
077: public EJBHomeProxy createEJBHomeProxy() {
078: try {
079: // Interface class must be listed first otherwise the proxy code will select
080: // the openejb system class loader for proxy creation instead of the
081: // application class loader
082: Class[] interfaces = new Class[] { ejb.homeClass,
083: EJBHomeProxy.class };
084: return (EJBHomeProxy) ProxyManager.newProxyInstance(
085: interfaces, this );
086: } catch (IllegalAccessException e) {
087:
088: e.printStackTrace();
089: }
090: return null;
091: }
092:
093: protected Object _invoke(Object proxy, Method method, Object[] args)
094: throws Throwable {
095:
096: String methodName = method.getName();
097:
098: try {
099:
100: if (method.getDeclaringClass() == Object.class) {
101: if (method.equals(TOSTRING)) {
102: return "proxy=" + this ;
103: } else if (method.equals(EQUALS)) {
104:
105: return Boolean.FALSE;
106:
107: } else if (method.equals(HASHCODE)) {
108: return new Integer(this .hashCode());
109:
110: } else {
111: throw new UnsupportedOperationException(
112: "Unkown method: " + method);
113: }
114: } else if (method.getDeclaringClass() == EJBHomeProxy.class) {
115: if (method.equals(GETHANDLER)) {
116: return this ;
117: } else if (methodName.equals("writeReplace")) {
118: return new EJBHomeProxyHandle(this );
119: } else if (methodName.equals("readResolve")) {
120:
121: throw new UnsupportedOperationException(
122: "Unkown method: " + method);
123:
124: } else {
125: throw new UnsupportedOperationException(
126: "Unkown method: " + method);
127: }
128: }
129: /*-------------------------------------------------------*/
130:
131: /*-- CREATE ------------- <HomeInterface>.create(<x>) ---*/
132: if (methodName.startsWith("create")) {
133: return create(method, args, proxy);
134:
135: /*-- FIND X --------------- <HomeInterface>.find<x>() ---*/
136: } else if (methodName.startsWith("find")) {
137: return findX(method, args, proxy);
138:
139: /*-- GET EJB METADATA ------ EJBHome.getEJBMetaData() ---*/
140:
141: } else if (method.equals(GETEJBMETADATA)) {
142: return getEJBMetaData(method, args, proxy);
143:
144: /*-- GET HOME HANDLE -------- EJBHome.getHomeHandle() ---*/
145:
146: } else if (method.equals(GETHOMEHANDLE)) {
147: return getHomeHandle(method, args, proxy);
148:
149: /*-- REMOVE ------------------------ EJBHome.remove() ---*/
150:
151: } else if (method.equals(REMOVE_W_HAND)) {
152: return removeWithHandle(method, args, proxy);
153:
154: } else if (method.equals(REMOVE_W_KEY)) {
155: return removeByPrimaryKey(method, args, proxy);
156:
157: /*-- UNKOWN ---------------------------------------------*/
158: } else {
159: return homeMethod(method, args, proxy);
160: }
161:
162: } catch (SystemException e) {
163: invalidateReference();
164: throw convertException(e.getCause(), method);
165: /*
166: * Application exceptions must be reported dirctly to the client. They
167: * do not impact the viability of the proxy.
168: */
169: } catch (ApplicationException ae) {
170: throw convertException(ae.getCause(), method);
171: /*
172: * A system exception would be highly unusual and would indicate a sever
173: * problem with the container system.
174: */
175: } catch (SystemError se) {
176: invalidateReference();
177: if (remote) {
178: throw new RemoteException(
179: "Container has suffered a SystemException", se
180: .getCause());
181: } else {
182: throw new EJBException(
183: "Container has suffered a SystemException")
184: .initCause(se.getCause());
185: }
186: } catch (Throwable oe) {
187: if (remote) {
188: throw new RemoteException("Unknown Client Exception",
189: oe);
190: } else {
191: throw new EJBException("Unknown Client Exception")
192: .initCause(oe);
193: }
194: }
195:
196: }
197:
198: public Object homeMethod(Method method, Object[] args, Object proxy)
199: throws Throwable {
200: EJBRequest req = new EJBRequest(
201: RequestMethodConstants.EJB_HOME_METHOD, ejb, method,
202: args, null);
203:
204: EJBResponse res = request(req);
205:
206: switch (res.getResponseCode()) {
207: case ResponseCodes.EJB_ERROR:
208: throw new SystemError((ThrowableArtifact) res.getResult());
209: case ResponseCodes.EJB_SYS_EXCEPTION:
210: throw new SystemException((ThrowableArtifact) res
211: .getResult());
212: case ResponseCodes.EJB_APP_EXCEPTION:
213: throw new ApplicationException((ThrowableArtifact) res
214: .getResult());
215: case ResponseCodes.EJB_OK:
216:
217: return res.getResult();
218: default:
219: throw new RemoteException(
220: "Received invalid response code from server: "
221: + res.getResponseCode());
222: }
223: }
224:
225: /*-------------------------------------------------*/
226: /* Home interface methods */
227: /*-------------------------------------------------*/
228:
229: protected Object create(Method method, Object[] args, Object proxy)
230: throws Throwable {
231: EJBRequest req = new EJBRequest(
232: RequestMethodConstants.EJB_HOME_CREATE, ejb, method,
233: args, null);
234:
235: EJBResponse res = request(req);
236:
237: switch (res.getResponseCode()) {
238: case ResponseCodes.EJB_ERROR:
239: throw new SystemError((ThrowableArtifact) res.getResult());
240: case ResponseCodes.EJB_SYS_EXCEPTION:
241: throw new SystemException((ThrowableArtifact) res
242: .getResult());
243: case ResponseCodes.EJB_APP_EXCEPTION:
244: throw new ApplicationException((ThrowableArtifact) res
245: .getResult());
246: case ResponseCodes.EJB_OK:
247:
248: Object primKey = res.getResult();
249: EJBObjectHandler handler = EJBObjectHandler
250: .createEJBObjectHandler(ejb, server, client,
251: primKey);
252: handler.setEJBHomeProxy((EJBHomeProxy) proxy);
253:
254: return handler.createEJBObjectProxy();
255: default:
256: throw new RemoteException(
257: "Received invalid response code from server: "
258: + res.getResponseCode());
259: }
260: }
261:
262: protected abstract Object findX(Method method, Object[] args,
263: Object proxy) throws Throwable;
264:
265: /*-------------------------------------------------*/
266: /* EJBHome methods */
267: /*-------------------------------------------------*/
268:
269: protected Object getEJBMetaData(Method method, Object[] args,
270: Object proxy) throws Throwable {
271: return ejb;
272: }
273:
274: protected Object getHomeHandle(Method method, Object[] args,
275: Object proxy) throws Throwable {
276:
277: return new EJBHomeHandle((EJBHomeProxy) proxy);
278: }
279:
280: protected abstract Object removeWithHandle(Method method,
281: Object[] args, Object proxy) throws Throwable;
282:
283: protected abstract Object removeByPrimaryKey(Method method,
284: Object[] args, Object proxy) throws Throwable;
285:
286: public void readExternal(ObjectInput in) throws IOException,
287: ClassNotFoundException {
288: }
289:
290: public void writeExternal(ObjectOutput out) throws IOException {
291: }
292:
293: }
|