KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > geronimo > interop > rmi > iiop > ObjectInputStream


1 /**
2  *
3  * Copyright 2004-2005 The Apache Software Foundation
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 implied.
14  *
15  * See the License for the specific language governing permissions and
16  * limitations under the License.
17  */

18 package org.apache.geronimo.interop.rmi.iiop;
19
20 import org.omg.CORBA.TCKind JavaDoc;
21 import org.apache.geronimo.interop.util.IntegerCache;
22 import org.apache.geronimo.interop.util.ArrayUtil;
23 import org.apache.geronimo.interop.SystemException;
24
25 import java.io.IOException JavaDoc;
26 import java.io.NotActiveException JavaDoc;
27 import java.io.ObjectStreamClass JavaDoc;
28 import java.util.HashMap JavaDoc;
29 import java.util.ArrayList JavaDoc;
30 import java.lang.reflect.Array JavaDoc;
31
32 /**
33  ** TODO: package-private methods???
34  **/

35 public class ObjectInputStream extends java.io.ObjectInputStream JavaDoc
36 {
37
38     public static ObjectInputStream getInstance()
39     {
40         ObjectInputStream ois = null;
41         try {
42             ois = new ObjectInputStream();
43         } catch (IOException JavaDoc e) {
44             e.printStackTrace(); //To change body of catch statement use File | Settings | File Templates.
45
ois = null;
46         }
47         return ois;
48     }
49
50     public static ObjectInputStream getInstance(org.apache.geronimo.interop.rmi.iiop.CdrInputStream cdrInput)
51     {
52         ObjectInputStream input = getInstance();
53         input.init(cdrInput);
54         return input;
55     }
56
57     public static ObjectInputStream getPooledInstance()
58     {
59         ObjectInputStream input = null;
60         if (input == null)
61         {
62             input = getInstance();
63         }
64         return input;
65     }
66
67     // -----------------------------------------------------------------------
68
// inner classes
69
// -----------------------------------------------------------------------
70

71     protected static class StreamState
72     {
73         ValueType type;
74         Object JavaDoc value;
75         int offset;
76
77         StreamState(ValueType type, Object JavaDoc value, int offset)
78         {
79             this.type = type;
80             this.value = value;
81             this.offset = offset;
82         }
83     }
84
85     // -----------------------------------------------------------------------
86
// public data
87
// -----------------------------------------------------------------------
88

89     public static final int MAXIMUM_BLOCK_LENGTH = 0x7fffff00;
90
91     public CdrInputStream _cdrInput;
92
93     public Object JavaDoc[] thisAsObjectArray;
94
95     // -----------------------------------------------------------------------
96
// private data
97
// -----------------------------------------------------------------------
98

99     private int _blockLength = MAXIMUM_BLOCK_LENGTH;
100
101     private int _endLevel = 0;
102
103     private HashMap JavaDoc _indirection;
104
105     private boolean _isChunked = false;
106
107     private ArrayList JavaDoc _stack;
108
109     // -----------------------------------------------------------------------
110
// public methods
111
// -----------------------------------------------------------------------
112

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

140     public boolean readBoolean()
141     {
142         return _cdrInput.read_boolean();
143     }
144
145     public char readChar()
146     {
147         return _cdrInput.read_wchar();
148     }
149
150     public byte readByte()
151     {
152         return _cdrInput.read_octet();
153     }
154
155     public short readShort()
156     {
157         return _cdrInput.read_short();
158     }
159
160     public int readInt()
161     {
162         return _cdrInput.read_long();
163     }
164
165     public long readLong()
166     {
167         return _cdrInput.read_longlong();
168     }
169
170     public float readFloat()
171     {
172         return _cdrInput.read_float();
173     }
174
175     public double readDouble()
176     {
177         return _cdrInput.read_double();
178     }
179
180     public Object JavaDoc readObjectOverride()
181     {
182         return readObject(ValueType.OBJECT_VALUE_TYPE, true);
183     }
184
185     public void defaultReadObject() throws IOException JavaDoc, ClassNotFoundException JavaDoc, NotActiveException JavaDoc
186     {
187         StreamState state = top();
188         readDeclaredFields(state.type, state.value);
189     }
190
191     public java.io.ObjectInputStream.GetField readFields()
192         throws IOException JavaDoc, ClassNotFoundException JavaDoc
193     {
194         StreamState state = top();
195
196         Class JavaDoc currentClass = state.type.getTheClass();
197         if(currentClass == null)
198         {
199             throw new IOException JavaDoc("readFields: class from ValueType is null");
200         }
201
202         java.io.ObjectStreamClass JavaDoc osc = ObjectStreamClass.lookup(currentClass);
203         if(osc == null)
204         {
205             throw new IOException JavaDoc("readFields: ObjectSteamClass is null");
206         }
207
208         org.apache.geronimo.interop.rmi.iiop.GetField gf = new org.apache.geronimo.interop.rmi.iiop.GetField(osc);
209         gf.readFields(this);
210         return gf;
211     }
212
213     // -----------------------------------------------------------------------
214
// public methods used by generated and package-internal code
215
// -----------------------------------------------------------------------
216

217     public Exception JavaDoc readException(ValueType type)
218     {
219         return (Exception JavaDoc)readObject(type, false);
220     }
221
222     public Object JavaDoc readObject(ValueType type)
223     {
224         return readObject(type, false);
225     }
226
227     // -----------------------------------------------------------------------
228
// protected methods
229
// -----------------------------------------------------------------------
230

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

555             {
556                valueType.readObject(value, this);
557             }
558             pop();
559         }
560         else
561         {
562             readDeclaredFields(valueType, value);
563         }
564         while (value != null && valueType.hasReadResolve)
565         {
566             value = valueType.readResolve(value);
567             if(value != null)
568             {
569                 Class JavaDoc vc = value.getClass();
570                 valueType = ValueType.getInstance(vc);
571             }
572         }
573         return value;
574     }
575
576     protected void readDeclaredFields(ValueType valueType, Object JavaDoc value)
577     {
578         int n = valueType.fields.length;
579         for (int f = 0; f < n; f++)
580         {
581             ValueTypeField field = valueType.fields[f];
582             int primitive = field.primitive;
583             if (primitive != 0)
584             {
585                 readPrimitive(primitive, field, value);
586             }
587             else
588             {
589                 field.set(value, readObject(field.type, false));
590             }
591         }
592     }
593
594     protected Object JavaDoc readClassDesc()
595     {
596         String JavaDoc codebase = (String JavaDoc)readObject(ValueType.STRING_VALUE_TYPE);
597         String JavaDoc id = (String JavaDoc)readObject(ValueType.STRING_VALUE_TYPE);
598         return ValueType.getInstanceByID(id)._class;
599     }
600
601     protected Object JavaDoc readArray(ValueType arrayType, Integer JavaDoc key)
602     {
603         Object JavaDoc value = null;
604         int primitive = arrayType.primitiveArray;
605         if (primitive != 0)
606         {
607             value = arrayType.helper.read(this);
608             putIndirection(key, value);
609         }
610         else
611         {
612             int n = _cdrInput.read_ulong();
613             Object JavaDoc[] array;
614             try
615             {
616                 array = n == 0 ? ArrayUtil.EMPTY_OBJECT_ARRAY : (Object JavaDoc[])Array.newInstance(arrayType.element._class, n);
617             }
618             catch (Exception JavaDoc ex)
619             {
620                 throw new SystemException(ex);
621             }
622             putIndirection(key, array);
623             for (int i = 0; i < n; i++)
624             {
625                 array[i] = readObject(arrayType.element, false);
626             }
627             value = array;
628         }
629         return value;
630     }
631
632     private void readPrimitive(int primitive, ValueTypeField field, Object JavaDoc value)
633     {
634         switch (primitive)
635         {
636             case PrimitiveType.BOOLEAN:
637                 field.setBoolean(value, _cdrInput.read_boolean());
638                 break;
639             case PrimitiveType.BYTE:
640                 field.setByte(value, _cdrInput.read_octet());
641                 break;
642             case PrimitiveType.CHAR:
643                 field.setChar(value, _cdrInput.read_wchar());
644                 break;
645             case PrimitiveType.DOUBLE:
646                 field.setDouble(value, _cdrInput.read_double());
647                 break;
648             case PrimitiveType.FLOAT:
649                 field.setFloat(value, _cdrInput.read_float());
650                 break;
651             case PrimitiveType.INT:
652                 field.setInt(value, _cdrInput.read_long());
653                 break;
654             case PrimitiveType.LONG:
655                 field.setLong(value, _cdrInput.read_longlong());
656                 break;
657             case PrimitiveType.SHORT:
658                 field.setShort(value, _cdrInput.read_short());
659                 break;
660             default:
661                 throw new IllegalStateException JavaDoc();
662         }
663     }
664
665     /**
666      ** This method handle end tag compaction. Note that it is lazy in the
667      ** sense that it always assumes a tag has been compacted if the end tag
668      ** is not what it expected.
669      **/

670     protected void readEndTag()
671     {
672         if (_isChunked)
673         {
674             int anEndTag = _cdrInput.read_long();
675             if (anEndTag != _endLevel)
676             {
677                 _cdrInput._offset -= 4;
678             }
679             _endLevel++;
680         }
681     }
682
683     protected void startBlock()
684     {
685         if (! _isChunked)
686         {
687             return;
688         }
689         _blockLength = _cdrInput.read_long();
690         if (_blockLength >= 0
691             && _blockLength < MAXIMUM_BLOCK_LENGTH)
692         {
693             _blockLength += _cdrInput._offset;
694         }
695         else
696         {
697             // Not a chunk length field.
698
_blockLength = MAXIMUM_BLOCK_LENGTH;
699             _cdrInput._offset -= 4;
700         }
701     }
702
703     protected void endBlock()
704     {
705         // If in a chunk, check for underflow or overflow.
706
if (_blockLength != MAXIMUM_BLOCK_LENGTH)
707         {
708             if (_blockLength == _cdrInput._offset)
709             {
710                 // Chunk ended correctly.
711
_blockLength = MAXIMUM_BLOCK_LENGTH;
712             }
713         }
714     }
715
716     protected void push(StreamState state)
717     {
718         if (_stack == null)
719         {
720             _stack = new ArrayList JavaDoc();
721         }
722         _stack.add(state);
723     }
724
725     protected void pop()
726     {
727         int n = _stack.size();
728         if (n == 0)
729         {
730             throw new SystemException("pop: state stack empty");
731         }
732         _stack.remove(n - 1);
733     }
734
735     protected StreamState top()
736     {
737         int n = _stack.size();
738         if (n == 0)
739         {
740             throw new SystemException("top: state stack empty");
741         }
742         return (StreamState)_stack.get(n - 1);
743     }
744 }
745
Popular Tags