001: /*
002: * Copyright (c) 1998-2000 Caucho Technology -- all rights reserved
003: *
004: * This file is part of Resin(R) Open Source
005: *
006: * Each copy or derived work must preserve the copyright notice and this
007: * notice unmodified.
008: *
009: * Resin Open Source is free software; you can redistribute it and/or modify
010: * it under the terms of the GNU General Public License as published by
011: * the Free Software Foundation; either version 2 of the License, or
012: * (at your option) any later version.
013: *
014: * Resin Open Source is distributed in the hope that it will be useful,
015: * but WITHOUT ANY WARRANTY; without even the implied warranty of
016: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, or any warranty
017: * of NON-INFRINGEMENT. See the GNU General Public License for more
018: * details.
019: *
020: * You should have received a copy of the GNU General Public License
021: * along with Resin Open Source; if not, write to the
022: *
023: * Free Software Foundation, Inc.
024: * 59 Temple Place, Suite 330
025: * Boston, MA 02111-1307 USA
026: *
027: * @author Scott Ferguson
028: */
029:
030: package com.caucho.iiop;
031:
032: import com.caucho.ejb.AbstractEJBObject;
033: import com.caucho.ejb.AbstractServer;
034: import com.caucho.log.Log;
035: import com.caucho.server.util.CauchoSystem;
036: import com.caucho.iiop.marshal.Marshal;
037:
038: import javax.rmi.CORBA.Util;
039: import java.io.Serializable;
040: import java.lang.reflect.Array;
041: import java.lang.reflect.Method;
042: import java.util.logging.Logger;
043: import org.omg.CORBA.portable.Streamable;
044:
045: public class MarshallObject {
046: private static final Logger log = Log.open(MarshallObject.class);
047:
048: public final static int VOID = -1;
049:
050: public final static int BOOLEAN = 0;
051: public final static int BYTE = 1;
052: public final static int SHORT = 2;
053: public final static int CHAR = 3;
054: public final static int INT = 4;
055: public final static int LONG = 5;
056: public final static int FLOAT = 6;
057: public final static int DOUBLE = 7;
058:
059: public final static int STRING = 8;
060:
061: public final static int BOOLEAN_ARRAY = 9;
062: public final static int BYTE_ARRAY = 10;
063: public final static int SHORT_ARRAY = 11;
064: public final static int CHAR_ARRAY = 12;
065: public final static int INT_ARRAY = 13;
066: public final static int LONG_ARRAY = 14;
067: public final static int FLOAT_ARRAY = 15;
068: public final static int DOUBLE_ARRAY = 16;
069: public final static int STRING_ARRAY = 17;
070:
071: public final static int OBJECT = 20;
072:
073: public final static int CORBA_OBJECT = 21;
074: public final static int REMOTE = 22;
075: public final static int EJB_HOME = 23;
076: public final static int EJB_OBJECT = 24;
077:
078: public final static int OBJECT_ARRAY = 25;
079:
080: public final static int OBJECT_HELPER = 26;
081: public final static int STREAMABLE = 27;
082:
083: private int _code;
084: private Class _objClass;
085: private MarshallObject _subObj;
086: private Method _readHelper;
087: private Method _writeHelper;
088:
089: private MarshallObject() {
090: }
091:
092: private MarshallObject(int code) {
093: _code = code;
094: }
095:
096: private MarshallObject(int code, Class cl) {
097: _code = code;
098: _objClass = cl;
099: }
100:
101: private MarshallObject(int code, Class cl, Method readHelper,
102: Method writeHelper) {
103: _code = code;
104: _objClass = cl;
105: _readHelper = readHelper;
106: _writeHelper = writeHelper;
107: }
108:
109: static MarshallObject create(Class cl, boolean isJava) {
110: if (void.class.equals(cl))
111: return new MarshallObject(VOID);
112: else if (boolean.class.equals(cl))
113: return new MarshallObject(BOOLEAN);
114: else if (byte.class.equals(cl))
115: return new MarshallObject(BYTE);
116: else if (short.class.equals(cl))
117: return MARSHALL_SHORT;
118: else if (char.class.equals(cl))
119: return MARSHALL_CHAR;
120: else if (int.class.equals(cl))
121: return new MarshallObject(INT);
122: else if (long.class.equals(cl))
123: return MARSHALL_LONG;
124: else if (float.class.equals(cl))
125: return new MarshallObject(FLOAT);
126: else if (double.class.equals(cl))
127: return new MarshallObject(DOUBLE);
128: else if (String.class.equals(cl))
129: return new MarshallObject(STRING);
130: else if (String[].class.equals(cl) && !isJava)
131: return new MarshallObject(STRING_ARRAY);
132: else if (javax.ejb.EJBHome.class.isAssignableFrom(cl))
133: return new MarshallObject(EJB_HOME, cl);
134: else if (javax.ejb.EJBObject.class.isAssignableFrom(cl))
135: return new MarshallObject(EJB_OBJECT, cl);
136: else if (java.rmi.Remote.class.isAssignableFrom(cl))
137: return new MarshallObject(REMOTE, cl);
138: else if (org.omg.CORBA.Object.class.isAssignableFrom(cl))
139: return new MarshallObject(CORBA_OBJECT, cl);
140: else if (cl.isArray() && !isJava) {
141: Class compType = cl.getComponentType();
142: MarshallObject subObj = MarshallObject.create(compType,
143: isJava);
144: MarshallObject obj = new MarshallObject(OBJECT_ARRAY,
145: compType);
146: obj._subObj = subObj;
147:
148: return obj;
149: } else if (Streamable.class.isAssignableFrom(cl)) {
150: return new MarshallObject(STREAMABLE, cl);
151: } else {
152: Class helperClass = null;
153: Method readHelper = null;
154: Method writeHelper = null;
155: try {
156: helperClass = CauchoSystem.loadClass(cl.getName()
157: + "Helper");
158:
159: readHelper = helperClass
160: .getMethod(
161: "read",
162: new Class[] { org.omg.CORBA.portable.InputStream.class });
163:
164: writeHelper = helperClass
165: .getMethod(
166: "write",
167: new Class[] {
168: org.omg.CORBA.portable.OutputStream.class,
169: cl });
170: } catch (Exception e) {
171: }
172:
173: if (readHelper != null)
174: return new MarshallObject(OBJECT_HELPER, cl,
175: readHelper, writeHelper);
176: else
177: return new MarshallObject(OBJECT, cl);
178: }
179: }
180:
181: public Object unmarshall(IiopReader reader) throws Exception {
182: switch (_code) {
183: case BOOLEAN:
184: return new Boolean(reader.read_boolean());
185: case BYTE:
186: return new Byte(reader.read_octet());
187: case SHORT:
188: return new Short(reader.read_short());
189: case CHAR:
190: return new Character(reader.read_wchar());
191: case INT:
192: return new Integer(reader.read_long());
193: case LONG:
194: return new Long(reader.read_longlong());
195: case FLOAT:
196: return new Float(reader.read_float());
197: case DOUBLE:
198: return new Double(reader.read_double());
199: case STRING:
200: return (String) reader.read_value(String.class);
201: case BOOLEAN_ARRAY: {
202: boolean[] array = new boolean[reader.read_sequence_length()];
203: reader.read_boolean_array(array, 0, array.length);
204: return array;
205: }
206: case BYTE_ARRAY: {
207: byte[] array = new byte[reader.read_sequence_length()];
208: reader.read_octet_array(array, 0, array.length);
209: return array;
210: }
211: case CHAR_ARRAY: {
212: char[] array = new char[reader.read_sequence_length()];
213: reader.read_wchar_array(array, 0, array.length);
214: return array;
215: }
216: case SHORT_ARRAY: {
217: short[] array = new short[reader.read_sequence_length()];
218: reader.read_short_array(array, 0, array.length);
219: return array;
220: }
221: case INT_ARRAY: {
222: int[] array = new int[reader.read_sequence_length()];
223: reader.read_long_array(array, 0, array.length);
224: return array;
225: }
226: case LONG_ARRAY: {
227: long[] array = new long[reader.read_sequence_length()];
228: reader.read_longlong_array(array, 0, array.length);
229: return array;
230: }
231: case FLOAT_ARRAY: {
232: float[] array = new float[reader.read_sequence_length()];
233: reader.read_float_array(array, 0, array.length);
234: return array;
235: }
236: case DOUBLE_ARRAY: {
237: double[] array = new double[reader.read_sequence_length()];
238: reader.read_double_array(array, 0, array.length);
239: return array;
240: }
241: /*
242: case STRING_ARRAY:
243: {
244: String []array = new String[reader.read_sequence_length()];
245: for (int i = 0; i < array.length; i++) {
246: array[i] = reader.read_wstring();
247: System.out.println(array[i]);
248: }
249:
250: return array;
251: }
252: */
253:
254: case REMOTE:
255: return reader.readObject(_objClass);
256:
257: case CORBA_OBJECT:
258: return reader.read_Object();
259:
260: case OBJECT_ARRAY: {
261: int len = reader.read_sequence_length();
262: Object[] obj = (Object[]) Array.newInstance(_objClass, len);
263:
264: for (int i = 0; i < len; i++)
265: obj[i] = _subObj.unmarshall(reader);
266:
267: return obj;
268: }
269:
270: case OBJECT_HELPER: {
271: return _readHelper.invoke(null, new Object[] { reader });
272: }
273:
274: default:
275: try {
276: log.info("Class: " + _objClass);
277:
278: return reader.read_value(_objClass);
279: } catch (Exception e) {
280: e.printStackTrace();
281: return null;
282: }
283: }
284: }
285:
286: public void marshall(Object obj, IiopWriter writer)
287: throws Exception {
288: switch (_code) {
289: case BOOLEAN:
290: writer.write_boolean(((Boolean) obj).booleanValue());
291: break;
292: case BYTE:
293: writer.write_octet(((Byte) obj).byteValue());
294: break;
295: case SHORT:
296: writer.write_short(((Short) obj).shortValue());
297: break;
298: case INT:
299: writer.write_long(((Integer) obj).intValue());
300: break;
301: case LONG:
302: writer.write_longlong(((Long) obj).longValue());
303: break;
304: case FLOAT:
305: writer.write_float(((Float) obj).floatValue());
306: break;
307: case DOUBLE:
308: writer.write_double(((Double) obj).doubleValue());
309: break;
310: case CHAR:
311: writer.write_wchar(((Character) obj).charValue());
312: break;
313: case STRING:
314: writer.write_value((String) obj, String.class);
315: break;
316: case EJB_OBJECT:
317: case REMOTE:
318: if (obj instanceof AbstractEJBObject) {
319: AbstractEJBObject absObj = (AbstractEJBObject) obj;
320:
321: AbstractServer server = absObj.__caucho_getServer();
322: String local = absObj.__caucho_getId();
323:
324: String url = server.getProtocolId() + "?" + local;
325: String typeName = "RMI:" + _objClass.getName() + ":0";
326:
327: IOR ior = new IOR(typeName, writer.getHost(), writer
328: .getPort(), url);
329: //writer.write_boolean(true);
330: writer.write_Object(new DummyObjectImpl(ior));
331: } else {
332: //writer.write_boolean(false);
333: writer.write_value((Serializable) obj);
334: }
335:
336: break;
337: /*
338: if (obj instanceof AbstractEJBObject) {
339: AbstractEJBObject absObj = (AbstractEJBObject) obj;
340:
341: AbstractServer server = absObj.__caucho_getServer();
342: String local = absObj.__caucho_getId();
343:
344: String url = server.getEJBName() + "?" + local;
345: String typeName = "RMI:" + objClass.getName() + ":0";
346:
347: IOR ior = new IOR(typeName, writer.getHost(), writer.getPort(), url);
348: writer.write_Object(new DummyObjectImpl(ior));
349: System.out.println("REMOTE: " + writer.getHost() + ":" + writer.getPort());
350: }
351: else {
352: Util.writeRemoteObject(writer, obj);
353: }
354:
355: break;
356: */
357: case EJB_HOME:
358: Util.writeRemoteObject(writer, obj);
359: break;
360: case CORBA_OBJECT:
361: writer.write_Object((org.omg.CORBA.Object) obj);
362: break;
363: case OBJECT_HELPER: {
364: _writeHelper.invoke(null, new Object[] { writer, obj });
365: break;
366: }
367: default:
368: writer.write_value((Serializable) obj);
369: break;
370: }
371: }
372:
373: private static final MarshallObject MARSHALL_SHORT = new MarshallObject() {
374: public Object unmarshall(IiopReader reader) throws Exception {
375: short v = reader.read_short();
376:
377: return new Short(v);
378: }
379:
380: public void marshall(Object obj, IiopWriter writer)
381: throws Exception {
382: writer.write_short(((Number) obj).shortValue());
383: }
384: };
385:
386: private static final MarshallObject MARSHALL_CHAR = new MarshallObject() {
387: public Object unmarshall(IiopReader reader) throws Exception {
388: char v = reader.read_wchar();
389:
390: return new Character(v);
391: }
392:
393: public void marshall(Object obj, IiopWriter writer)
394: throws Exception {
395: writer.write_wchar(((Character) obj).charValue());
396: }
397: };
398:
399: private static final MarshallObject MARSHALL_LONG = new MarshallObject() {
400: public Object unmarshall(IiopReader reader) throws Exception {
401: return new Long(reader.read_longlong());
402: }
403:
404: public void marshall(Object obj, IiopWriter writer)
405: throws Exception {
406: writer.write_longlong(((Long) obj).longValue());
407: }
408: };
409: }
|