KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > gcc > rmi > iiop > ObjectOutputStream


1 /*
2  * Copyright 2004 The Apache Software Foundation or its licensors, as
3  * applicable.
4  *
5  * Licensed under the Apache License, Version 2.0 (the "License");
6  * you may not use this file except in compliance with the License.
7  * You may obtain a copy of the License at
8  *
9  * http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
14  * implied.
15  *
16  * See the License for the specific language governing permissions and
17  * limitations under the License.
18  */

19 package gcc.rmi.iiop;
20
21 import gcc.*;
22 import gcc.rmi.*;
23 import gcc.util.*;
24 import java.io.*;
25 import java.lang.reflect.*;
26 import java.util.*;
27
28 public class ObjectOutputStream extends java.io.ObjectOutputStream
29 {
30     public static ObjectOutputStream getInstance()
31     {
32         return getInstance(CdrOutputStream.getInstance());
33     }
34
35     public static ObjectOutputStream getInstance(CdrOutputStream cdrOutput)
36     {
37         ObjectOutputStream output = null;
38         try
39         {
40             output = new ObjectOutputStream();
41         }
42         catch( Exception ex )
43         {
44             throw new SystemException( ex );
45         }
46
47         output.init(cdrOutput);
48         return output;
49     }
50
51     public static ObjectOutputStream getPooledInstance()
52     {
53         ObjectOutputStream output = null; //(ObjectOutputStream)_pool.get();
54
if (output == null)
55         {
56             output = getInstance();
57         }
58         return output;
59     }
60
61     // -----------------------------------------------------------------------
62
// private data
63
// -----------------------------------------------------------------------
64

65     protected static class StreamState
66     {
67         ValueType type;
68         Object value;
69         int offset;
70
71         StreamState(ValueType type, Object value, int offset)
72         {
73             this.type = type;
74             this.value = value;
75             this.offset = offset;
76         }
77     }
78
79     // -----------------------------------------------------------------------
80
// public data
81
// -----------------------------------------------------------------------
82

83     public CdrOutputStream _cdrOutput;
84
85     public boolean _hasException;
86
87     public Object[] thisAsObjectArray;
88
89     // -----------------------------------------------------------------------
90
// private data
91
// -----------------------------------------------------------------------
92

93     private static ValueType OBJECT_VALUE_TYPE = ValueType.getInstance(java.lang.Object.class);
94
95     private static boolean OBJECT_VALUE_TYPE_INIT = false;
96
97     //private static ThreadLocalInstancePool _pool = new ThreadLocalInstancePool(ObjectOutputStream.class.getName());
98

99     private ArrayList _stack = null;
100
101     private SimpleIdentityHashMap _indirection;
102
103     private int _blockSizeIndex = -1;
104
105     private int _endLevel;
106
107     private int _endTagIndex;
108
109     private boolean _inBlock = false;
110
111     private boolean _isChunked = false;
112
113     private int _booleanIndex = -1;
114
115     // -----------------------------------------------------------------------
116
// public methods
117
// -----------------------------------------------------------------------
118

119     public ObjectOutputStream() throws IOException
120     {
121         super();
122     }
123
124     public void $reset()
125     {
126         _cdrOutput.reset();
127         if (_indirection != null)
128         {
129             _indirection.clear();
130         }
131         if (_stack != null)
132         {
133             _stack.clear();
134         }
135         _blockSizeIndex = -1;
136         _endLevel = 0;
137         _endTagIndex = 0;
138         _inBlock = false;
139         _isChunked = false;
140         _booleanIndex = -1;
141     }
142
143     public void recycle()
144     {
145         $reset();
146         //_pool.put(this);
147
}
148
149     // -----------------------------------------------------------------------
150
// public methods from java.io.ObjectOutputStream
151
// -----------------------------------------------------------------------
152

153     public void writeBoolean(boolean value)
154     {
155         _cdrOutput.write_boolean(value);
156     }
157
158     public void writeChar(char value)
159     {
160         _cdrOutput.write_wchar(value);
161     }
162
163     public void writeByte(byte value)
164     {
165         _cdrOutput.write_octet(value);
166     }
167
168     public void writeShort(short value)
169     {
170         _cdrOutput.write_short(value);
171     }
172
173     public void writeInt(int value)
174     {
175         _cdrOutput.write_long(value);
176     }
177
178     public void writeLong(long value)
179     {
180         _cdrOutput.write_longlong(value);
181     }
182
183     public void writeFloat(float value)
184     {
185         _cdrOutput.write_float(value);
186     }
187
188     public void writeDouble(double value)
189     {
190         _cdrOutput.write_double(value);
191     }
192
193     public void writeObjectOverride(Object value)
194     {
195         writeObject(OBJECT_VALUE_TYPE, value);
196     }
197
198     public void defaultWriteObject() throws IOException
199     {
200         StreamState state = top();
201         // TODO: check this
202
int saveOffset = _cdrOutput._offset;
203         _cdrOutput._offset = _booleanIndex;
204         _cdrOutput.write_boolean(true);
205         _cdrOutput._offset = saveOffset;
206         writeDeclaredFields(state.type, state.value);
207     }
208
209     // -----------------------------------------------------------------------
210
// public methods used by generated and package-internal code
211
// -----------------------------------------------------------------------
212

213     public boolean hasException()
214     {
215         return _hasException;
216     }
217
218     public void writeException(ValueType type, Exception value)
219     {
220         writeObject(type, value);
221         _hasException = true;
222     }
223
224     public void writeObject(ValueType type, Object value)
225     {
226         writeObject(type, value, false);
227     }
228
229     // -----------------------------------------------------------------------
230
// protected methods
231
// -----------------------------------------------------------------------
232

233     protected void init(CdrOutputStream cdrOutput)
234     {
235         _cdrOutput = cdrOutput;
236         thisAsObjectArray = new Object[] { this };
237     }
238
239     protected void putIndirection(Object value, Integer ref)
240     {
241         if (_indirection == null)
242         {
243             _indirection = new SimpleIdentityHashMap(8);
244         }
245         _indirection.put(value, ref);
246     }
247
248     protected void writeObject(ValueType declaredType, Object value, boolean calledFromCustomSerialization)
249     {
250         ValueType actualType = declaredType;
251         if (value != null)
252         {
253             Class vc = value.getClass();
254             if (vc != declaredType._class)
255             {
256                 actualType = ValueType.getInstance(vc);
257             }
258             if (actualType.hasWriteReplace)
259             {
260                 value = actualType.writeReplace(value);
261             }
262         }
263         boolean saveIsChunked = _isChunked;
264         if (_inBlock)
265         {
266             if (actualType != null)
267             {
268                 if (! (declaredType.isAny && actualType.isObjectRef))
269                 {
270                     endBlock();
271                 }
272             }
273         }
274         if (value == null)
275         {
276             if (calledFromCustomSerialization)
277             {
278                 _cdrOutput.write_boolean(actualType.isObjectRef);
279                 if(actualType.isObjectRef)
280                 {
281                     _cdrOutput.write_Object((org.omg.CORBA.Object)value);
282                     endBlock();
283                 }
284                 else
285                 {
286                     _cdrOutput.write_long(ValueType.NULL_VALUE_TAG);
287                 }
288                 return;
289             }
290             if (declaredType.isAny)
291             {
292                 _cdrOutput.write_TypeCode(ValueType.TC_ABSTRACT_BASE);
293                 _cdrOutput.write_boolean(false);
294             }
295             if (declaredType.isObjectRef)
296             {
297                 _cdrOutput.write_Object((org.omg.CORBA.Object)value);
298             }
299             else
300             {
301                 if (declaredType.isAbstractInterface)
302                 {
303                     _cdrOutput.write_boolean(false);
304                 }
305                 _cdrOutput.write_long(ValueType.NULL_VALUE_TAG);
306             }
307             return;
308         }
309         if (declaredType.isAny && ! calledFromCustomSerialization)
310         {
311             org.omg.CORBA.TypeCode tc = actualType.tc;
312             _cdrOutput.write_TypeCode(tc);
313         }
314         else if (declaredType.isAbstractInterface || calledFromCustomSerialization)
315         {
316             _cdrOutput.write_boolean(actualType.isObjectRef);
317             if (actualType.isObjectRef)
318             {
319                 _cdrOutput.write_Object((org.omg.CORBA.Object)value);
320                 return;
321             }
322         }
323         if (actualType.isObjectRef)
324         {
325             if (value instanceof RemoteInterface)
326             {
327                 value = ((RemoteInterface)value).$getObjectRef();
328             }
329             _cdrOutput.write_Object((org.omg.CORBA.Object)value);
330             return;
331         }
332         Integer ref = _indirection == null ? null : (Integer)_indirection.get(value);
333         if (ref != null)
334         {
335             _cdrOutput.write_long(ValueType.INDIRECTION_TAG);
336             _cdrOutput.write_long(ref.intValue() - _cdrOutput._offset);
337             return;
338         }
339         else
340         {
341             _cdrOutput.write_align(4, 4); // write any necessary padding
342
ref = IntegerCache.get(_cdrOutput._offset);
343             putIndirection(value, ref);
344         }
345         if (saveIsChunked || actualType.requiresCustomSerialization)
346         {
347             _cdrOutput.write_long(ValueType.TRUNCATABLE_SINGLE_TYPE_VALUE_TAG);
348             _isChunked = true;
349         }
350         else
351         {
352             _cdrOutput.write_long(ValueType.SINGLE_TYPE_VALUE_TAG);
353             _isChunked = false;
354         }
355         writeMetaString(actualType.id);
356         startBlock();
357         switch (actualType.readWriteCase)
358         {
359             case ValueType.CASE_ARRAY:
360                 writeArray(actualType, value);
361                 break;
362             case ValueType.CASE_CLASS:
363                 writeClassDesc((java.lang.Class)value);
364                 break;
365             case ValueType.CASE_IDL_ENTITY:
366                 actualType.helper.write(this, value);
367                 break;
368             // case ValueType.IDL_OBJECT: // already handled above
369
case ValueType.CASE_STRING:
370                 _cdrOutput.write_wstring((String)value);
371                 break;
372             default:
373                 writeObjectState(actualType, value);
374         }
375         endBlock();
376         writeEndTag();
377         _isChunked = saveIsChunked;
378     }
379
380     protected void writeMetaString(String ms)
381     {
382         Integer ref = (Integer)_indirection.get(ms);
383         if (ref != null)
384         {
385             _cdrOutput.write_long(ValueType.INDIRECTION_TAG);
386             _cdrOutput.write_long(ref.intValue() - _cdrOutput._offset);
387         }
388         else
389         {
390             ref = IntegerCache.get(_cdrOutput._offset);
391             _cdrOutput.write_string(ms);
392             putIndirection(ms, ref);
393         }
394     }
395
396     protected void writeObjectState(ValueType type, Object value)
397     {
398         if (type.isExternalizable)
399         {
400             _cdrOutput.write_octet((byte)1);
401             type.writeExternal(value, this);
402             return;
403         }
404         if (type.hasParentState)
405         {
406             writeObjectState(type.parent, value);
407         }
408         if (type.hasWriteObject && type.hasReadObject)
409         {
410             push(new StreamState(type, value, _cdrOutput._offset));
411             if (type.skipCustomFlags)
412             {
413                 _booleanIndex = _cdrOutput._offset;
414             }
415             else
416             {
417                 _cdrOutput.write_octet((byte)1);
418                 _cdrOutput.write_boolean(false);
419                 _booleanIndex = _cdrOutput._offset - 1;
420             }
421             type.writeObject(value, this);
422             pop();
423         }
424         else
425         {
426             writeDeclaredFields(type, value);
427         }
428     }
429
430     protected void writeDeclaredFields(ValueType type, Object value)
431     {
432         int n = type.fields.length;
433         for (int f = 0; f < n; f++)
434         {
435             ValueTypeField field = type.fields[f];
436             int primitive = field.primitive;
437             if (primitive != 0)
438             {
439                 writePrimitive(primitive, field, value);
440             }
441             else
442             {
443                 writeObject(field.type, field.get(value), false);
444             }
445         }
446     }
447
448     protected void writeClassDesc(Class theClass)
449     {
450         writeObject(ValueType.STRING_VALUE_TYPE, null); // codebase URL
451
writeObject(ValueType.STRING_VALUE_TYPE, ValueType.getInstance(theClass).id);
452     }
453
454     protected void writeArray(ValueType arrayType, Object value)
455     {
456         int primitive = arrayType.primitiveArray;
457         if (primitive != 0)
458         {
459             arrayType.helper.write(this, value);
460         }
461         else
462         {
463             Object[] array = (Object[])value;
464             int n = array.length;
465             _cdrOutput.write_ulong(n);
466             for (int i = 0; i < n; i++)
467             {
468                 writeObject(arrayType.element, array[i], false);
469             }
470         }
471     }
472
473     protected void writePrimitive(int primitive, ValueTypeField field, Object value)
474     {
475         switch (primitive)
476         {
477             case PrimitiveType.BOOLEAN:
478                 _cdrOutput.write_boolean(field.getBoolean(value));
479                 break;
480             case PrimitiveType.BYTE:
481                 _cdrOutput.write_octet(field.getByte(value));
482                 break;
483             case PrimitiveType.CHAR:
484                 _cdrOutput.write_wchar(field.getChar(value));
485                 break;
486             case PrimitiveType.DOUBLE:
487                 _cdrOutput.write_double(field.getDouble(value));
488                 break;
489             case PrimitiveType.FLOAT:
490                 _cdrOutput.write_float(field.getFloat(value));
491                 break;
492             case PrimitiveType.INT:
493                 _cdrOutput.write_long(field.getInt(value));
494                 break;
495             case PrimitiveType.LONG:
496                 _cdrOutput.write_longlong(field.getLong(value));
497                 break;
498             case PrimitiveType.SHORT:
499                 _cdrOutput.write_short(field.getShort(value));
500                 break;
501             default:
502                 throw new IllegalStateException();
503         }
504     }
505
506     public void startBlock()
507     {
508         if (! _isChunked)
509         {
510             return;
511         }
512         _endLevel--;
513         _cdrOutput.write_long(0);
514         _inBlock = true;
515         _blockSizeIndex = _cdrOutput._offset - 4;
516     }
517
518     public void endBlock()
519     {
520         if (! _inBlock)
521         {
522             return;
523         }
524         _inBlock = false;
525         int oldSize = _cdrOutput._offset;
526         _cdrOutput._offset = _blockSizeIndex;
527         _cdrOutput.write_long(oldSize - _blockSizeIndex - 4);
528         _cdrOutput._offset = oldSize;
529         _blockSizeIndex = -1;
530     }
531
532     protected void writeEndTag()
533     {
534         if (_isChunked)
535         {
536             if (_endTagIndex == _cdrOutput._offset - 8)
537             {
538                 _cdrOutput._offset -= 8;
539             }
540             _cdrOutput.write_long(_endLevel);
541             _endTagIndex = _cdrOutput._offset - 4;
542             if (_endLevel != -1)
543             {
544                 _cdrOutput.write_long(1);
545             }
546             else // _endLevel == -1
547
{
548                 _cdrOutput._offset -=4;
549                 _cdrOutput.write_long(-1);
550                 _isChunked = false;
551             }
552             _endLevel++;
553         }
554     }
555
556     /*
557     public java.io.ObjectOutputStream.PutField putFields() throws IOException
558     {
559         StreamState state = top();
560
561         Class currentClass = state.type.getTheClass();
562         if(currentClass == null)
563         {
564             throw new IOException("putFields: class from ValueType is null");
565         }
566
567         java.io.ObjectStreamClass osc = ObjectStreamClass.lookup(currentClass);
568         if(osc == null)
569         {
570             throw new IOException("putFields: ObjectSteamClass is null");
571         }
572         state.putField = new com.sybase.CORBA.iiop.PutField(osc);
573         return state.putField;
574     }
575
576     public void writeFields() throws IOException
577     {
578
579         StreamState state = top();
580         if(state.putField == null)
581         {
582             throw new IOException("writeFields: PutField object is null");
583         }
584
585         state.putField.writeFields(this);
586     }
587     */

588
589     protected void push(StreamState state)
590     {
591         if (_stack == null)
592         {
593             _stack = new ArrayList();
594         }
595         _stack.add(state);
596     }
597
598     protected void pop()
599     {
600         int n = _stack.size();
601         if (n == 0)
602         {
603             throw new SystemException("pop: state stack empty");
604         }
605         _stack.remove(n - 1);
606     }
607
608     private StreamState top()
609     {
610         int n = _stack.size();
611         if (n == 0)
612         {
613             throw new SystemException("top: state stack empty");
614         }
615         return (StreamState)_stack.get(n - 1);
616     }
617 }
618
Popular Tags