KickJava   Java API By Example, From Geeks To Geeks.

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


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.util.*;
23 import java.io.*;
24 import java.lang.reflect.*;
25 import java.util.*;
26 import org.omg.CORBA.TCKind;
27
28 public class ObjectInputStream extends java.io.ObjectInputStream
29 {
30     public static ObjectInputStream getInstance()
31     {
32         return getInstance(CdrInputStream.getInstance());
33     }
34
35     public static ObjectInputStream getInstance(gcc.rmi.iiop.CdrInputStream cdrInput)
36     {
37         ObjectInputStream input = null;
38         try
39         {
40             input = new ObjectInputStream();
41         }
42         catch( Exception ex )
43         {
44             throw new SystemException( ex );
45         }
46
47         input.init(cdrInput);
48         return input;
49     }
50
51     public static ObjectInputStream getPooledInstance()
52     {
53         ObjectInputStream input = null; //(ObjectInputStream)_pool.get();
54
if (input == null)
55         {
56             input = getInstance();
57         }
58         return input;
59     }
60
61     // -----------------------------------------------------------------------
62
// inner classes
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 static final int MAXIMUM_BLOCK_LENGTH = 0x7fffff00;
84
85     public CdrInputStream _cdrInput;
86
87     public Object[] thisAsObjectArray;
88
89     // -----------------------------------------------------------------------
90
// private data
91
// -----------------------------------------------------------------------
92

93     //private static ThreadLocalInstancePool _pool = new ThreadLocalInstancePool(ObjectInputStream.class.getName());
94

95     private int _blockLength = MAXIMUM_BLOCK_LENGTH;
96
97     private int _endLevel = 0;
98
99     private HashMap _indirection;
100
101     private boolean _isChunked = false;
102
103     private ArrayList _stack;
104
105     // -----------------------------------------------------------------------
106
// public methods
107
// -----------------------------------------------------------------------
108

109     public ObjectInputStream() throws IOException
110     {
111     }
112
113     public void $reset()
114     {
115         _cdrInput.reset();
116         if (_indirection != null)
117         {
118             _indirection.clear();
119         }
120         if (_stack != null)
121         {
122             _stack.clear();
123         }
124         _blockLength = MAXIMUM_BLOCK_LENGTH;
125         _endLevel = 0;
126         _isChunked = false;
127     }
128
129     public void recycle()
130     {
131         $reset();
132         //_pool.put(this);
133
}
134
135     // public methods from java.io.ObjectInputStream
136

137     public boolean readBoolean()
138     {
139         return _cdrInput.read_boolean();
140     }
141
142     public char readChar()
143     {
144         return _cdrInput.read_wchar();
145     }
146
147     public byte readByte()
148     {
149         return _cdrInput.read_octet();
150     }
151
152     public short readShort()
153     {
154         return _cdrInput.read_short();
155     }
156
157     public int readInt()
158     {
159         return _cdrInput.read_long();
160     }
161
162     public long readLong()
163     {
164         return _cdrInput.read_longlong();
165     }
166
167     public float readFloat()
168     {
169         return _cdrInput.read_float();
170     }
171
172     public double readDouble()
173     {
174         return _cdrInput.read_double();
175     }
176
177     public Object readObjectOverride()
178     {
179         return readObject(ValueType.OBJECT_VALUE_TYPE, false);
180     }
181
182     public void defaultReadObject() throws IOException, ClassNotFoundException, NotActiveException
183     {
184         StreamState state = top();
185         readDeclaredFields(state.type, state.value);
186     }
187
188     // -----------------------------------------------------------------------
189
// public methods used by generated and package-internal code
190
// -----------------------------------------------------------------------
191

192     public Exception readException(ValueType type)
193     {
194         return (Exception)readObject(type, false);
195     }
196
197     public Object readObject(ValueType type)
198     {
199         return readObject(type, false);
200     }
201
202     // -----------------------------------------------------------------------
203
// protected methods
204
// -----------------------------------------------------------------------
205

206     protected void init(gcc.rmi.iiop.CdrInputStream cdrInput)
207     {
208         _cdrInput = cdrInput;
209         thisAsObjectArray = new Object[] { this };
210     }
211
212     protected void putIndirection(Integer key, Object value)
213     {
214         if (_indirection == null)
215         {
216             _indirection = new HashMap();
217         }
218         _indirection.put(key, value);
219     }
220
221     protected Object readObject(ValueType declaredType, boolean calledByCustomSerialization)
222     {
223         org.omg.CORBA.TypeCode tc = null;
224
225         int tag = _cdrInput.read_ulong();
226         int saveOffset = _cdrInput._offset - 4;
227         Object value;
228
229         if (tag == ValueType.INDIRECTION_TAG)
230         {
231             // Indirection to value already read (or cyclic value being read).
232
saveOffset = _cdrInput._offset;
233             int offset = _cdrInput.read_long();
234             Integer key = IntegerCache.get(saveOffset + offset);
235             if (_indirection != null)
236             {
237                 value = _indirection.get(key);
238                 if (value != null)
239                 {
240                     return value;
241                 }
242             }
243             throw new org.omg.CORBA.MARSHAL("invalid indirection offset = " + offset);
244         }
245         else
246         {
247             _cdrInput._offset = saveOffset;
248         }
249
250         if (calledByCustomSerialization)
251         {
252             boolean isObjectRef = _cdrInput.read_boolean();
253             if (isObjectRef)
254             {
255                 org.omg.CORBA.Object ref = _cdrInput.read_Object();
256                 endBlock();
257                 if (_blockLength == MAXIMUM_BLOCK_LENGTH)
258                 {
259                     startBlock();
260                 }
261                 return ref;
262             }
263             else
264             {
265                 _cdrInput._offset = saveOffset;
266             }
267         }
268         else if (declaredType.isAnyOrObjectRefOrAbstractInterface)
269         {
270             boolean isObjectRef = false;
271             if (declaredType.isObjectRef)
272             {
273                 return _cdrInput.read_Object();
274             }
275             else if (declaredType.isAny)
276             {
277                 tc = _cdrInput.read_TypeCode();
278                 int kind = tc.kind().value();
279                 if(kind == TCKind._tk_null)
280                 {
281                     return null;
282                 }
283                 if(kind == TCKind._tk_objref)
284                 {
285                     isObjectRef = true;
286                 }
287                 else if(kind == TCKind._tk_abstract_interface)
288                 {
289                     isObjectRef = _cdrInput.read_boolean();
290                 }
291                 if(isObjectRef)
292                 {
293                     saveOffset = _cdrInput._offset;
294                     int checkValue = _cdrInput.read_ulong();
295                     if(checkValue == 0)
296                     {
297                         return null;
298                     }
299
300                     _cdrInput._offset = saveOffset;
301                     return _cdrInput.read_Object();
302                 }
303             }
304             else if (declaredType.isAbstractInterface)
305             {
306                 isObjectRef = _cdrInput.read_boolean();
307                 if (isObjectRef)
308                 {
309                     return _cdrInput.read_Object();
310                 }
311             }
312             else
313             {
314                 throw new IllegalStateException(declaredType.toString());
315             }
316         }
317
318         saveOffset = _cdrInput._offset;
319         tag = _cdrInput.read_long();
320         if (tag == ValueType.NULL_VALUE_TAG)
321         {
322             return null;
323         }
324         if (tag == ValueType.INDIRECTION_TAG)
325         {
326             // Indirection to value already read (or cyclic value being read).
327
saveOffset = _cdrInput._offset;
328             int offset = _cdrInput.read_long();
329             Integer key = IntegerCache.get(saveOffset + offset);
330             if (_indirection != null)
331             {
332                 value = _indirection.get(key);
333                 if (value != null)
334                 {
335                     return value;
336                 }
337             }
338             throw new org.omg.CORBA.MARSHAL("invalid indirection offset = " + offset);
339         }
340         ValueType actualType;
341         boolean saveIsChunked = _isChunked;
342         _isChunked = (tag & 0x00000008) != 0;
343         String codebaseURL = null;
344         if ((tag & 0x00000001) == 1)
345         {
346             codebaseURL = readMetaString();
347         }
348         switch (tag & 0x00000006)
349         {
350             case 0: // NO_TYPE_VALUE_TAG
351
{
352                     actualType = declaredType;
353                     if (tc != null)
354                     {
355                         try
356                         {
357                             String id = tc.id();
358                             if (id != null)
359                             {
360                                 int kind = tc.kind().value();
361                                 if (kind == TCKind._tk_value_box)
362                                 {
363                                     kind = tc.content_type().kind().value();
364                                     if (kind == TCKind._tk_wstring)
365                                     {
366                                         actualType = ValueType.STRING_VALUE_TYPE;
367                                     }
368                                 }
369                             }
370                         }
371                         catch (Exception ex)
372                         {
373                             throw new SystemException(ex);
374                         }
375                     }
376                 }
377                 break;
378             case 2: // SINGLE_TYPE_VALUE_TAG
379
{
380                     String repositoryID = readMetaString();
381 // TODO requiresCustomSerialization = (Boolean)_specialCaseReposIds.get(repositoryID);
382
actualType = ValueType.getInstanceByID(repositoryID);
383                 }
384                 break;
385             case 6: // TYPE_LIST_VALUE_TAG
386
{
387                     int n = _cdrInput.read_ulong();
388                     if (n < 1)
389                     {
390                         throw new org.omg.CORBA.MARSHAL("invalid type list length = " + n);
391                     }
392                     String repositoryID = readMetaString();
393 // TODO requiresCustomSerialization = (Boolean)_specialCaseReposIds.get(repositoryID);
394
actualType = ValueType.getInstanceByID(repositoryID);
395                     for (int i = 1; i < n; i++)
396                     {
397                         String ignore = readMetaString();
398                     }
399                 }
400                 break;
401             default:
402                 throw new org.omg.CORBA.MARSHAL("invalid value tag = " + tag);
403         }
404         if (actualType.isObjectRef)
405         {
406             value = actualType.helper.read(this);
407             return value;
408         }
409         startBlock();
410         if (_isChunked)
411         {
412             _endLevel--;
413         }
414         Integer key = new Integer(saveOffset);
415         switch (actualType.readWriteCase)
416         {
417             case ValueType.CASE_ARRAY:
418                 value = readArray(actualType, key);
419                 break;
420             case ValueType.CASE_CLASS:
421                 value = readClassDesc();
422                 putIndirection(key, value);
423                 break;
424             case ValueType.CASE_IDL_ENTITY:
425                 value = actualType.helper.read(this);
426                 putIndirection(key, value);
427                 break;
428             // case ValueType.CASE_IDL_OBJECT: // already handled above
429
case ValueType.CASE_STRING:
430                 value = _cdrInput.read_wstring();
431                 putIndirection(key, value);
432                 break;
433             default:
434                 value = actualType.newInstance();
435                 putIndirection(key, value);
436                 Object newValue = readObjectState(actualType, value, false); // requiresCustomSerialization);
437
if (newValue != value)
438                 {
439                     value = newValue;
440                     putIndirection(key, value);
441                 }
442         }
443         endBlock();
444         readEndTag();
445         _isChunked = saveIsChunked;
446         startBlock();
447         return value;
448     }
449
450     protected String readMetaString()
451     {
452         String id;
453         int saveOffset = _cdrInput._offset;
454         int tag = _cdrInput.read_long();
455         if (tag == ValueType.INDIRECTION_TAG)
456         {
457             saveOffset = _cdrInput._offset;
458             int offset = _cdrInput.read_long();
459             Integer key = IntegerCache.get(saveOffset + offset);
460             id = _indirection == null ? null : (String)_indirection.get(key);
461             if (id == null)
462             {
463                 throw new org.omg.CORBA.MARSHAL("invalid indirection offset = " + offset);
464             }
465         }
466         else
467         {
468             _cdrInput._offset = saveOffset;
469             id = _cdrInput.read_string();
470             putIndirection(IntegerCache.get(saveOffset), id);
471         }
472         return id;
473     }
474
475     protected Object readObjectState(ValueType valueType, Object value, boolean requiresCustomSerialization)
476     {
477         if (valueType.isExternalizable)
478         {
479             byte format = _cdrInput.read_octet();
480             valueType.readExternal(value, this);
481             return value;
482         }
483         if (valueType.hasParentState)
484         {
485             value = readObjectState(valueType.parent, value, false);
486         }
487         if (valueType.hasReadObject)
488         {
489             push(new StreamState(valueType, value, _cdrInput._offset));
490             /* TODO
491             if (repositoryID.equals(_SUN_JDK_BIG_DECIMAL_REPOSID))
492             {
493                 // Sun's first field is an int
494                 int scale = readInt();
495                 // Sun's second field is a java.math.BigInteger
496                 java.math.BigInteger intVal = (java.math.BigInteger)readObject(java.math.BigInteger.class);
497                 // Create BigDecimal using scale and intVal
498                 value = new java.math.BigDecimal(intVal, scale);
499             }
500             else if (repositoryID.equals(_IBM_JDK_BIG_DECIMAL_REPOSID))
501             {
502                 byte format = _cdrInput.read_octet();
503                 boolean defaultWriteObjectCalled = _cdrInput.read_boolean();
504                 // IBM's first field is a long
505                 long intLong = readLong();
506                 // IBM's second field is a int
507                 int scale = readInt();
508                 // IBM's third field is a java.math.BigInteger
509                 java.math.BigInteger intVal = (java.math.BigInteger)readObject(java.math.BigInteger.class);
510                 // We can ignore the long, since IBM doesn't use it
511                 // in the writeObject, to ensure backward's compatibility
512                 // with their previous versions which don't have the long.
513                 value = new java.math.BigDecimal(intVal, scale);
514             }
515             else
516             */

517             {
518                 if (valueType.hasWriteObject || requiresCustomSerialization)
519                 {
520                     byte format = _cdrInput.read_octet();
521                     boolean defaultWriteObjectCalled = _cdrInput.read_boolean();
522                 }
523                 valueType.readObject(value, this);
524             }
525             pop();
526         }
527         else
528         {
529             readDeclaredFields(valueType, value);
530         }
531         if (valueType.hasReadResolve)
532         {
533             value = valueType.readResolve(value);
534         }
535         return value;
536     }
537
538     protected void readDeclaredFields(ValueType valueType, Object value)
539     {
540         int n = valueType.fields.length;
541         for (int f = 0; f < n; f++)
542         {
543             ValueTypeField field = valueType.fields[f];
544             int primitive = field.primitive;
545             if (primitive != 0)
546             {
547                 readPrimitive(primitive, field, value);
548             }
549             else
550             {
551                 field.set(value, readObject(field.type, false));
552             }
553         }
554     }
555
556     protected Object readClassDesc()
557     {
558         String codebase = (String)readObject(ValueType.STRING_VALUE_TYPE);
559         String id = (String)readObject(ValueType.STRING_VALUE_TYPE);
560         return ValueType.getInstanceByID(id)._class;
561     }
562
563     protected Object readArray(ValueType arrayType, Integer key)
564     {
565         Object value = null;
566         int primitive = arrayType.primitiveArray;
567         int n = _cdrInput.read_ulong();
568         if (primitive != 0)
569         {
570             value = arrayType.helper.read(this);
571             putIndirection(key, value);
572         }
573         else
574         {
575             Object[] array;
576             try
577             {
578                 array = n == 0 ? ArrayUtil.EMPTY_OBJECT_ARRAY : (Object[])Array.newInstance(arrayType.element._class, n);
579             }
580             catch (Exception ex)
581             {
582                 throw new SystemException(ex);
583             }
584             putIndirection(key, array);
585             for (int i = 0; i < n; i++)
586             {
587                 array[i] = readObject(arrayType.element, false);
588             }
589             value = array;
590         }
591         return value;
592     }
593
594     private void readPrimitive(int primitive, ValueTypeField field, Object value)
595     {
596         switch (primitive)
597         {
598             case PrimitiveType.BOOLEAN:
599                 field.setBoolean(value, _cdrInput.read_boolean());
600                 break;
601             case PrimitiveType.BYTE:
602                 field.setByte(value, _cdrInput.read_octet());
603                 break;
604             case PrimitiveType.CHAR:
605                 field.setChar(value, _cdrInput.read_wchar());
606                 break;
607             case PrimitiveType.DOUBLE:
608                 field.setDouble(value, _cdrInput.read_double());
609                 break;
610             case PrimitiveType.FLOAT:
611                 field.setFloat(value, _cdrInput.read_float());
612                 break;
613             case PrimitiveType.INT:
614                 field.setInt(value, _cdrInput.read_long());
615                 break;
616             case PrimitiveType.LONG:
617                 field.setLong(value, _cdrInput.read_longlong());
618                 break;
619             case PrimitiveType.SHORT:
620                 field.setShort(value, _cdrInput.read_short());
621                 break;
622             default:
623                 throw new IllegalStateException();
624         }
625     }
626
627     /**
628      ** This method handle end tag compaction. Note that it is lazy in the
629      ** sense that it always assumes a tag has been compacted if the end tag
630      ** is not what it expected.
631      **/

632     protected void readEndTag()
633     {
634         if (_isChunked)
635         {
636             int anEndTag = _cdrInput.read_long();
637             if (anEndTag != _endLevel)
638             {
639                 _cdrInput._offset -= 4;
640             }
641             _endLevel++;
642         }
643     }
644
645     protected void startBlock()
646     {
647         if (! _isChunked)
648         {
649             return;
650         }
651         _blockLength = _cdrInput.read_long();
652         if (_blockLength >= 0
653             && _blockLength < MAXIMUM_BLOCK_LENGTH)
654         {
655             _blockLength += _cdrInput._offset;
656         }
657         else
658         {
659             // Not a chunk length field.
660
_blockLength = MAXIMUM_BLOCK_LENGTH;
661             _cdrInput._offset -= 4;
662         }
663     }
664
665     protected void endBlock()
666     {
667         // If in a chunk, check for underflow or overflow.
668
if (_blockLength != MAXIMUM_BLOCK_LENGTH)
669         {
670             if (_blockLength == _cdrInput._offset)
671             {
672                 // Chunk ended correctly.
673
_blockLength = MAXIMUM_BLOCK_LENGTH;
674             }
675         }
676     }
677
678     protected void push(StreamState state)
679     {
680         if (_stack == null)
681         {
682             _stack = new ArrayList();
683         }
684         _stack.add(state);
685     }
686
687     protected void pop()
688     {
689         int n = _stack.size();
690         if (n == 0)
691         {
692             throw new SystemException("pop: state stack empty");
693         }
694         _stack.remove(n - 1);
695     }
696
697     protected StreamState top()
698     {
699         int n = _stack.size();
700         if (n == 0)
701         {
702             throw new SystemException("top: state stack empty");
703         }
704         return (StreamState)_stack.get(n - 1);
705     }
706 }
707
Popular Tags