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.IOException;
019: import java.io.ObjectInput;
020: import java.io.ObjectOutput;
021: import java.lang.reflect.Method;
022:
023: import java.rmi.Remote;
024: import javax.naming.Context;
025: import javax.naming.InitialContext;
026: import javax.rmi.PortableRemoteObject;
027: import javax.rmi.CORBA.Tie;
028: import javax.rmi.CORBA.Stub;
029:
030: import org.omg.CORBA.ORB;
031:
032: public class EJBRequest implements ClusterableRequest {
033:
034: private transient int requestMethod;
035: private transient int deploymentCode = 0;
036: private transient Object clientIdentity;
037: private transient String deploymentId;
038: private transient int serverHash;
039:
040: private transient Body body;
041:
042: public static final int SESSION_BEAN_STATELESS = 6;
043: public static final int SESSION_BEAN_STATEFUL = 7;
044: public static final int ENTITY_BM_PERSISTENCE = 8;
045: public static final int ENTITY_CM_PERSISTENCE = 9;
046:
047: public EJBRequest() {
048: body = new Body(null);
049: }
050:
051: public EJBRequest(int requestMethod, EJBMetaDataImpl ejb,
052: Method method, Object[] args, Object primaryKey) {
053: body = new Body(ejb);
054:
055: this .requestMethod = requestMethod;
056: setDeploymentCode(ejb.deploymentCode);
057: setDeploymentId(ejb.deploymentID);
058: setMethodInstance(method);
059: setMethodParameters(args);
060: setPrimaryKey(primaryKey);
061: }
062:
063: public Class getInterfaceClass() {
064: return body.getInterfaceClass();
065: }
066:
067: public Method getMethodInstance() {
068: return body.getMethodInstance();
069: }
070:
071: public String getMethodName() {
072: return body.getMethodName();
073: }
074:
075: public Object[] getMethodParameters() {
076: return body.getMethodParameters();
077: }
078:
079: public Class[] getMethodParamTypes() {
080: return body.getMethodParamTypes();
081: }
082:
083: public Object getPrimaryKey() {
084: return body.getPrimaryKey();
085: }
086:
087: public void setMethodInstance(Method methodInstance) {
088: body.setMethodInstance(methodInstance);
089: }
090:
091: public void setMethodParameters(Object[] methodParameters) {
092: body.setMethodParameters(methodParameters);
093: }
094:
095: public void setPrimaryKey(Object primaryKey) {
096: body.setPrimaryKey(primaryKey);
097: }
098:
099: public Body getBody() {
100: return body;
101: }
102:
103: public void setBody(Body body) {
104: this .body = body;
105: }
106:
107: public static class Body implements java.io.Externalizable {
108: private transient EJBMetaDataImpl ejb;
109: private transient ORB orb;
110: private transient Method methodInstance;
111: private transient Class interfaceClass;
112: // private transient Class methodClass;
113: private transient String methodName;
114: private transient Class[] methodParamTypes;
115: private transient Object[] methodParameters;
116: private transient Object primaryKey;
117:
118: public Body(EJBMetaDataImpl ejb) {
119: this .ejb = ejb;
120: }
121:
122: public Method getMethodInstance() {
123: return methodInstance;
124: }
125:
126: public Object[] getMethodParameters() {
127: return methodParameters;
128: }
129:
130: public Object getPrimaryKey() {
131: return primaryKey;
132: }
133:
134: public Class getInterfaceClass() {
135: return interfaceClass;
136: }
137:
138: public String getMethodName() {
139: return methodName;
140: }
141:
142: public Class[] getMethodParamTypes() {
143: return methodParamTypes;
144: }
145:
146: public void setMethodInstance(Method methodInstance) {
147: this .methodInstance = methodInstance;
148: this .methodName = methodInstance.getName();
149: this .methodParamTypes = methodInstance.getParameterTypes();
150: Class methodClass = methodInstance.getDeclaringClass();
151:
152: if (ejb.homeClass != null) {
153: if (methodClass.isAssignableFrom(ejb.homeClass)) {
154: this .interfaceClass = ejb.homeClass;
155: return;
156: }
157: }
158:
159: if (ejb.remoteClass != null) {
160: if (methodClass.isAssignableFrom(ejb.remoteClass)) {
161: this .interfaceClass = ejb.remoteClass;
162: return;
163: }
164: }
165:
166: for (Class businessClass : ejb.businessClasses) {
167: if (methodClass.isAssignableFrom(businessClass)) {
168: this .interfaceClass = businessClass;
169: return;
170: }
171: }
172: }
173:
174: public void setMethodParameters(Object[] methodParameters) {
175: this .methodParameters = methodParameters;
176: }
177:
178: public void setPrimaryKey(Object primaryKey) {
179: this .primaryKey = primaryKey;
180: }
181:
182: public void readExternal(ObjectInput in) throws IOException,
183: ClassNotFoundException {
184: byte version = in.readByte(); // future use
185:
186: ClassNotFoundException result = null;
187: primaryKey = null;
188: // methodClass = null;
189: methodName = null;
190: methodInstance = null;
191: try {
192: primaryKey = in.readObject();
193: interfaceClass = (Class) in.readObject();
194: // methodClass = (Class) in.readObject();
195: } catch (ClassNotFoundException cnfe) {
196: if (result == null)
197: result = cnfe;
198: }
199: methodName = in.readUTF();
200:
201: try {
202: readMethodParameters(in);
203: } catch (ClassNotFoundException cnfe) {
204: if (result == null)
205: result = cnfe;
206: }
207:
208: if (interfaceClass != null) {
209: try {
210: methodInstance = interfaceClass.getMethod(
211: methodName, methodParamTypes);
212: } catch (NoSuchMethodException nsme) {
213: //if (result == null) result = nsme;
214: }
215: }
216: if (result != null)
217: throw result;
218: }
219:
220: public void writeExternal(ObjectOutput out) throws IOException {
221: // write out the version of the serialized data for future use
222: out.writeByte(1);
223:
224: out.writeObject(primaryKey);
225:
226: out.writeObject(interfaceClass);
227: // out.writeObject(methodClass);
228: out.writeUTF(methodName);
229:
230: writeMethodParameters(out, methodParamTypes,
231: methodParameters);
232: }
233:
234: protected void writeMethodParameters(ObjectOutput out,
235: Class[] types, Object[] args) throws IOException {
236:
237: out.writeByte(types.length);
238:
239: for (int i = 0; i < types.length; i++) {
240: Class type = types[i];
241: Object obj = args[i];
242:
243: if (type.isPrimitive()) {
244: if (type == Byte.TYPE) {
245: out.write(B);
246: byte bytevalue = ((Byte) obj).byteValue();
247: out.writeByte(bytevalue);
248:
249: } else if (type == Character.TYPE) {
250: out.write(C);
251: char charvalue = ((Character) obj).charValue();
252: out.writeChar(charvalue);
253:
254: } else if (type == Integer.TYPE) {
255: out.write(I);
256: int intvalue = ((Integer) obj).intValue();
257: out.writeInt(intvalue);
258:
259: } else if (type == Boolean.TYPE) {
260: out.write(Z);
261: boolean booleanvalue = ((Boolean) obj)
262: .booleanValue();
263: out.writeBoolean(booleanvalue);
264:
265: } else if (type == Long.TYPE) {
266: out.write(J);
267: long longvalue = ((Long) obj).longValue();
268: out.writeLong(longvalue);
269:
270: } else if (type == Float.TYPE) {
271: out.write(F);
272: float fvalue = ((Float) obj).floatValue();
273: out.writeFloat(fvalue);
274:
275: } else if (type == Double.TYPE) {
276: out.write(D);
277: double dvalue = ((Double) obj).doubleValue();
278: out.writeDouble(dvalue);
279:
280: } else if (type == Short.TYPE) {
281: out.write(S);
282: short shortvalue = ((Short) obj).shortValue();
283: out.writeShort(shortvalue);
284:
285: } else {
286: throw new IOException("Unkown primitive type: "
287: + type);
288: }
289: } else {
290: if (obj instanceof PortableRemoteObject
291: && obj instanceof Remote) {
292: Tie tie = javax.rmi.CORBA.Util
293: .getTie((Remote) obj);
294: if (tie == null) {
295: throw new IOException(
296: "Unable to serialize PortableRemoteObject; object has not been exported: "
297: + obj);
298: }
299: ORB orb = getORB();
300: tie.orb(orb);
301: obj = PortableRemoteObject.toStub((Remote) obj);
302: }
303: out.write(L);
304: out.writeObject(type);
305: out.writeObject(obj);
306: }
307: }
308: }
309:
310: static final Class[] noArgsC = new Class[0];
311: static final Object[] noArgsO = new Object[0];
312:
313: /**
314: * Obtain an ORB instance for this request to activate remote
315: * arguments and return results.
316: *
317: * @return An ORB instance.
318: */
319: protected ORB getORB() throws IOException {
320: // first ORB request? Check our various sources
321: if (orb == null) {
322: try {
323: Context initialContext = new InitialContext();
324: orb = (ORB) initialContext.lookup("java:comp/ORB");
325: } catch (Throwable e) {
326: try {
327: // any orb will do if we can't get a context one.
328: orb = ORB.init();
329: } catch (Throwable ex) {
330: throw new IOException(
331: "Unable to connect PortableRemoteObject stub to an ORB, no ORB bound to java:comp/ORB");
332: }
333: }
334: }
335: return orb;
336: }
337:
338: protected void readMethodParameters(ObjectInput in)
339: throws IOException, ClassNotFoundException {
340: int length = in.read();
341:
342: if (length < 1) {
343: methodParamTypes = noArgsC;
344: methodParameters = noArgsO;
345: return;
346: }
347:
348: Class[] types = new Class[length];
349: Object[] args = new Object[length];
350:
351: for (int i = 0; i < types.length; i++) {
352: Class clazz = null;
353: Object obj = null;
354:
355: int type = in.read();
356:
357: switch (type) {
358: case B:
359: clazz = Byte.TYPE;
360: obj = new Byte(in.readByte());
361: break;
362:
363: case C:
364: clazz = Character.TYPE;
365: obj = new Character(in.readChar());
366: break;
367:
368: case I:
369: clazz = Integer.TYPE;
370: obj = new Integer(in.readInt());
371: break;
372:
373: case Z:
374: clazz = Boolean.TYPE;
375: obj = new Boolean(in.readBoolean());
376: break;
377:
378: case J:
379: clazz = Long.TYPE;
380: obj = new Long(in.readLong());
381: break;
382:
383: case F:
384: clazz = Float.TYPE;
385: obj = new Float(in.readFloat());
386: break;
387:
388: case D:
389: clazz = Double.TYPE;
390: obj = new Double(in.readDouble());
391: break;
392:
393: case S:
394: clazz = Short.TYPE;
395: obj = new Short(in.readShort());
396: break;
397:
398: case L:
399: clazz = (Class) in.readObject();
400: obj = in.readObject();
401: if (obj instanceof Stub) {
402: Stub stub = (Stub) obj;
403: ORB orb = getORB();
404: stub.connect(orb);
405: }
406: break;
407: default:
408: throw new IOException("Unkown data type: " + type);
409: }
410:
411: types[i] = clazz;
412: args[i] = obj;
413: }
414:
415: methodParamTypes = types;
416: methodParameters = args;
417: }
418:
419: private static final int I = 0;
420: private static final int B = 1;
421: private static final int J = 2;
422: private static final int F = 3;
423: private static final int D = 4;
424: private static final int S = 5;
425: private static final int C = 6;
426: private static final int Z = 7;
427: private static final int L = 8;
428: private static final int A = 9;
429: }
430:
431: public byte getRequestType() {
432: return RequestMethodConstants.EJB_REQUEST;
433: }
434:
435: public int getRequestMethod() {
436: return requestMethod;
437: }
438:
439: public Object getClientIdentity() {
440: return clientIdentity;
441: }
442:
443: public String getDeploymentId() {
444: return deploymentId;
445: }
446:
447: public int getDeploymentCode() {
448: return deploymentCode;
449: }
450:
451: public void setRequestMethod(int requestMethod) {
452: this .requestMethod = requestMethod;
453: }
454:
455: public void setClientIdentity(Object clientIdentity) {
456: this .clientIdentity = clientIdentity;
457: }
458:
459: public void setDeploymentId(String deploymentId) {
460: this .deploymentId = deploymentId;
461: }
462:
463: public void setDeploymentCode(int deploymentCode) {
464: this .deploymentCode = deploymentCode;
465: }
466:
467: public void setServerHash(int serverHash) {
468: this .serverHash = serverHash;
469: }
470:
471: public int getServerHash() {
472: return serverHash;
473: }
474:
475: public String toString() {
476: StringBuffer s = null;
477: switch (requestMethod) {
478: case RequestMethodConstants.EJB_HOME_GET_EJB_META_DATA:
479: s = new StringBuffer("EJB_HOME.GET_EJB_META_DATA");
480: break;
481: case RequestMethodConstants.EJB_HOME_GET_HOME_HANDLE:
482: s = new StringBuffer("EJB_HOME.GET_HOME_HANDLE");
483: break;
484: case RequestMethodConstants.EJB_HOME_REMOVE_BY_HANDLE:
485: s = new StringBuffer("EJB_HOME.REMOVE_BY_HANDLE");
486: break;
487: case RequestMethodConstants.EJB_HOME_REMOVE_BY_PKEY:
488: s = new StringBuffer("EJB_HOME.REMOVE_BY_PKEY");
489: break;
490: case RequestMethodConstants.EJB_HOME_FIND:
491: s = new StringBuffer("EJB_HOME.FIND");
492: break;
493: case RequestMethodConstants.EJB_HOME_CREATE:
494: s = new StringBuffer("EJB_HOME.CREATE");
495: break;
496: case RequestMethodConstants.EJB_OBJECT_GET_EJB_HOME:
497: s = new StringBuffer("EJB_OBJECT.GET_EJB_HOME");
498: break;
499: case RequestMethodConstants.EJB_OBJECT_GET_HANDLE:
500: s = new StringBuffer("EJB_OBJECT.GET_HANDLE");
501: break;
502: case RequestMethodConstants.EJB_OBJECT_GET_PRIMARY_KEY:
503: s = new StringBuffer("EJB_OBJECT.GET_PRIMARY_KEY");
504: break;
505: case RequestMethodConstants.EJB_OBJECT_IS_IDENTICAL:
506: s = new StringBuffer("EJB_OBJECT.IS_IDENTICAL");
507: break;
508: case RequestMethodConstants.EJB_OBJECT_REMOVE:
509: s = new StringBuffer("EJB_OBJECT.REMOVE");
510: break;
511: case RequestMethodConstants.EJB_OBJECT_BUSINESS_METHOD:
512: s = new StringBuffer("EJB_OBJECT.BUSINESS_METHOD");
513: break;
514: }
515: s.append(':').append(deploymentId);
516: if (body != null) {
517: s.append(':').append(body.getMethodName());
518: s.append(':').append(body.getPrimaryKey());
519: }
520: return s.toString();
521: }
522:
523: /*
524: When the Request externalizes itself, it will reset
525: the appropriate values so that this instance can be used
526: again.
527:
528: There will be one request instance for each handler
529: */
530:
531: public void readExternal(ObjectInput in) throws IOException,
532: ClassNotFoundException {
533: ClassNotFoundException result = null;
534:
535: requestMethod = -1;
536: deploymentId = null;
537: deploymentCode = -1;
538: clientIdentity = null;
539:
540: requestMethod = in.readByte();
541: try {
542: deploymentId = (String) in.readObject();
543: } catch (ClassNotFoundException cnfe) {
544: result = cnfe;
545: }
546: deploymentCode = in.readShort();
547: try {
548: clientIdentity = in.readObject();
549: } catch (ClassNotFoundException cnfe) {
550: if (result == null)
551: result = cnfe;
552: }
553: serverHash = in.readInt();
554: if (result != null)
555: throw result;
556: }
557:
558: public void writeExternal(ObjectOutput out) throws IOException {
559: out.writeByte(requestMethod);
560:
561: if (deploymentCode > 0) {
562: out.writeObject(null);
563: } else {
564: out.writeObject(deploymentId);
565: }
566:
567: out.writeShort(deploymentCode);
568: out.writeObject(clientIdentity);
569: out.writeInt(serverHash);
570: body.writeExternal(out);
571: }
572:
573: }
|