KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > sun > corba > se > impl > io > ValueHandlerImpl


1 /*
2  * @(#)ValueHandlerImpl.java 1.65 04/06/21
3  *
4  * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
5  * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
6  */

7 /*
8  * Licensed Materials - Property of IBM
9  * RMI-IIOP v1.0
10  * Copyright IBM Corp. 1998 1999 All Rights Reserved
11  *
12  * US Government Users Restricted Rights - Use, duplication or
13  * disclosure restricted by GSA ADP Schedule Contract with IBM Corp.
14  */

15
16 package com.sun.corba.se.impl.io;
17
18 import javax.rmi.CORBA.Util JavaDoc;
19 import javax.rmi.PortableRemoteObject JavaDoc;
20
21 import java.util.Hashtable JavaDoc;
22 import java.util.Stack JavaDoc;
23 import java.io.IOException JavaDoc;
24 import java.util.EmptyStackException JavaDoc;
25
26 import com.sun.corba.se.impl.util.Utility;
27 import com.sun.corba.se.impl.io.IIOPInputStream;
28 import com.sun.corba.se.impl.io.IIOPOutputStream;
29 import com.sun.corba.se.impl.util.RepositoryId;
30 import com.sun.corba.se.impl.util.Utility;
31
32 import org.omg.CORBA.TCKind JavaDoc;
33
34 import org.omg.CORBA.MARSHAL JavaDoc;
35 import org.omg.CORBA.BAD_PARAM JavaDoc;
36 import org.omg.CORBA.CompletionStatus JavaDoc;
37 import org.omg.CORBA.portable.IndirectionException JavaDoc;
38 import com.sun.org.omg.SendingContext.CodeBase;
39 import com.sun.org.omg.SendingContext.CodeBaseHelper;
40
41 import java.security.AccessController JavaDoc;
42 import java.security.PrivilegedAction JavaDoc;
43  
44 import com.sun.corba.se.impl.io.IIOPInputStream.ActiveRecursionManager;
45
46 import com.sun.corba.se.spi.logging.CORBALogDomains;
47 import com.sun.corba.se.impl.logging.OMGSystemException;
48 import com.sun.corba.se.impl.logging.UtilSystemException;
49
50 public class ValueHandlerImpl implements javax.rmi.CORBA.ValueHandlerMultiFormat JavaDoc {
51
52     // Property to override our maximum stream format version
53
public static final String JavaDoc FORMAT_VERSION_PROPERTY
54         = "com.sun.CORBA.MaxStreamFormatVersion";
55
56     private static final byte MAX_SUPPORTED_FORMAT_VERSION = (byte)2;
57     private static final byte STREAM_FORMAT_VERSION_1 = (byte)1;
58
59     // The ValueHandler's maximum stream format version to advertise,
60
// set in a static initializer.
61
private static final byte MAX_STREAM_FORMAT_VERSION;
62
63     static {
64         MAX_STREAM_FORMAT_VERSION = getMaxStreamFormatVersion();
65     }
66
67     // Looks for the FORMAT_VERSION_PROPERTY system property
68
// to allow the user to override our default stream format
69
// version. Note that this still only allows them to pick
70
// a supported version (1 through MAX_STREAM_FORMAT_VERSION).
71
private static byte getMaxStreamFormatVersion() {
72
73         try {
74
75             String JavaDoc propValue = (String JavaDoc) AccessController.doPrivileged(
76                                         new PrivilegedAction JavaDoc() {
77         public java.lang.Object JavaDoc run() {
78                 return System.getProperty(ValueHandlerImpl.FORMAT_VERSION_PROPERTY);
79             }
80             });
81
82             // The property wasn't set
83
if (propValue == null)
84                 return MAX_SUPPORTED_FORMAT_VERSION;
85
86             byte result = Byte.parseByte(propValue);
87
88             // REVISIT. Just set to MAX_SUPPORTED_FORMAT_VERSION
89
// or really let the system shutdown with this Error?
90
if (result < 1 || result > MAX_SUPPORTED_FORMAT_VERSION)
91         // XXX I18N, logging needed.
92
throw new ExceptionInInitializerError JavaDoc("Invalid stream format version: "
93                                                       + result
94                                                       + ". Valid range is 1 through "
95                                                       + MAX_SUPPORTED_FORMAT_VERSION);
96
97             return result;
98
99         } catch (Exception JavaDoc ex) {
100             // REVISIT. Swallow this or really let
101
// the system shutdown with this Error?
102

103             Error JavaDoc err = new ExceptionInInitializerError JavaDoc(ex);
104         err.initCause( ex ) ;
105         throw err ;
106         }
107     }
108
109     public static final short kRemoteType = 0;
110     public static final short kAbstractType = 1;
111     public static final short kValueType = 2;
112
113     private Hashtable JavaDoc inputStreamPairs = null;
114     private Hashtable JavaDoc outputStreamPairs = null;
115     private CodeBase codeBase = null;
116     private boolean useHashtables = true;
117     private boolean isInputStream = true;
118     private IIOPOutputStream outputStreamBridge = null;
119     private IIOPInputStream inputStreamBridge = null;
120     private OMGSystemException omgWrapper = OMGSystemException.get(
121     CORBALogDomains.RPC_ENCODING ) ;
122     private UtilSystemException utilWrapper = UtilSystemException.get(
123     CORBALogDomains.RPC_ENCODING ) ;
124
125     // See javax.rmi.CORBA.ValueHandlerMultiFormat
126
public byte getMaximumStreamFormatVersion() {
127         return MAX_STREAM_FORMAT_VERSION;
128     }
129
130     // See javax.rmi.CORBA.ValueHandlerMultiFormat
131
public void writeValue(org.omg.CORBA.portable.OutputStream JavaDoc out,
132                            java.io.Serializable JavaDoc value,
133                            byte streamFormatVersion) {
134
135         if (streamFormatVersion == 2) {
136             if (!(out instanceof org.omg.CORBA.portable.ValueOutputStream JavaDoc)) {
137         throw omgWrapper.notAValueoutputstream() ;
138             }
139         } else if (streamFormatVersion != 1) {
140         throw omgWrapper.invalidStreamFormatVersion(
141         new Integer JavaDoc(streamFormatVersion) ) ;
142         }
143
144         writeValueWithVersion(out, value, streamFormatVersion);
145     }
146
147     public ValueHandlerImpl(){}
148
149     public ValueHandlerImpl(boolean isInputStream) {
150     this();
151     useHashtables = false;
152     this.isInputStream = isInputStream;
153     }
154
155     /**
156      * Writes the value to the stream using java semantics.
157      * @param out The stream to write the value to
158      * @param value The value to be written to the stream
159      **/

160     public void writeValue(org.omg.CORBA.portable.OutputStream JavaDoc _out,
161                            java.io.Serializable JavaDoc value) {
162         writeValueWithVersion(_out, value, STREAM_FORMAT_VERSION_1);
163     }
164
165     private void writeValueWithVersion(org.omg.CORBA.portable.OutputStream JavaDoc _out,
166                                        java.io.Serializable JavaDoc value,
167                                        byte streamFormatVersion) {
168
169     org.omg.CORBA_2_3.portable.OutputStream JavaDoc out =
170         (org.omg.CORBA_2_3.portable.OutputStream JavaDoc) _out;
171
172     if (!useHashtables) {
173             if (outputStreamBridge == null) {
174                 outputStreamBridge = createOutputStream();
175                 outputStreamBridge.setOrbStream(out);
176             }
177
178             try {
179                 outputStreamBridge.increaseRecursionDepth();
180                 writeValueInternal(outputStreamBridge, out, value, streamFormatVersion);
181             } finally {
182                 outputStreamBridge.decreaseRecursionDepth();
183             }
184
185             return;
186         }
187         
188         IIOPOutputStream jdkToOrbOutputStreamBridge = null;
189
190     if (outputStreamPairs == null)
191         outputStreamPairs = new Hashtable JavaDoc();
192         
193         jdkToOrbOutputStreamBridge = (IIOPOutputStream)outputStreamPairs.get(_out);
194
195         if (jdkToOrbOutputStreamBridge == null) {
196             jdkToOrbOutputStreamBridge = createOutputStream();
197             jdkToOrbOutputStreamBridge.setOrbStream(out);
198             outputStreamPairs.put(_out, jdkToOrbOutputStreamBridge);
199         }
200
201         try {
202
203         jdkToOrbOutputStreamBridge.increaseRecursionDepth();
204         writeValueInternal(jdkToOrbOutputStreamBridge, out, value, streamFormatVersion);
205         } finally {
206             if (jdkToOrbOutputStreamBridge.decreaseRecursionDepth() == 0) {
207                 outputStreamPairs.remove(_out);
208         }
209         }
210     }
211
212     private void writeValueInternal(IIOPOutputStream bridge,
213                     org.omg.CORBA_2_3.portable.OutputStream JavaDoc out,
214                     java.io.Serializable JavaDoc value,
215                                     byte streamFormatVersion)
216     {
217     Class JavaDoc clazz = value.getClass();
218
219         if (clazz.isArray())
220             write_Array(out, value, clazz.getComponentType());
221         else
222             bridge.simpleWriteObject(value, streamFormatVersion);
223     }
224
225     /**
226      * Reads a value from the stream using java semantics.
227      * @param in The stream to read the value from
228      * @param clazz The type of the value to be read in
229      * @param sender The sending context runtime
230      **/

231     public java.io.Serializable JavaDoc readValue(org.omg.CORBA.portable.InputStream JavaDoc _in,
232                       int offset,
233                       java.lang.Class JavaDoc clazz,
234                       String JavaDoc repositoryID,
235                       org.omg.SendingContext.RunTime JavaDoc _sender)
236     {
237         // Must use narrow rather than a direct cast to a com.sun
238
// class. Fix for bug 4379539.
239
CodeBase sender = CodeBaseHelper.narrow(_sender);
240
241     org.omg.CORBA_2_3.portable.InputStream JavaDoc in =
242         (org.omg.CORBA_2_3.portable.InputStream JavaDoc) _in;
243
244     if (!useHashtables) {
245             if (inputStreamBridge == null) {
246                 inputStreamBridge = createInputStream();
247                 inputStreamBridge.setOrbStream(in);
248                 inputStreamBridge.setSender(sender); //d11638
249
// backward compatability 4365188
250
inputStreamBridge.setValueHandler(this);
251             }
252             
253             java.io.Serializable JavaDoc result = null;
254
255             try {
256
257                 inputStreamBridge.increaseRecursionDepth();
258                 result = (java.io.Serializable JavaDoc) readValueInternal(inputStreamBridge, in, offset, clazz, repositoryID, sender);
259
260             } finally {
261
262                 if (inputStreamBridge.decreaseRecursionDepth() == 0) {
263                     // Indirections are resolved immediately since
264
// the change to the active recursion manager,
265
// so this will never happen.
266
}
267             }
268
269             return result;
270         }
271             
272         IIOPInputStream jdkToOrbInputStreamBridge = null;
273         if (inputStreamPairs == null)
274             inputStreamPairs = new Hashtable JavaDoc();
275         
276         jdkToOrbInputStreamBridge = (IIOPInputStream)inputStreamPairs.get(_in);
277
278         if (jdkToOrbInputStreamBridge == null) {
279
280             jdkToOrbInputStreamBridge = createInputStream();
281             jdkToOrbInputStreamBridge.setOrbStream(in);
282             jdkToOrbInputStreamBridge.setSender(sender); //d11638
283
// backward compatability 4365188
284
jdkToOrbInputStreamBridge.setValueHandler(this);
285             inputStreamPairs.put(_in, jdkToOrbInputStreamBridge);
286         }
287
288     java.io.Serializable JavaDoc result = null;
289         
290         try {
291             
292         jdkToOrbInputStreamBridge.increaseRecursionDepth();
293         result = (java.io.Serializable JavaDoc) readValueInternal(jdkToOrbInputStreamBridge, in, offset, clazz, repositoryID, sender);
294
295         } finally {
296
297             if (jdkToOrbInputStreamBridge.decreaseRecursionDepth() == 0) {
298                 inputStreamPairs.remove(_in);
299             }
300         }
301
302         return result;
303     }
304
305     private java.io.Serializable JavaDoc readValueInternal(IIOPInputStream bridge,
306                           org.omg.CORBA_2_3.portable.InputStream JavaDoc in,
307                           int offset,
308                           java.lang.Class JavaDoc clazz,
309                           String JavaDoc repositoryID,
310                           com.sun.org.omg.SendingContext.CodeBase sender)
311     {
312     java.io.Serializable JavaDoc result = null;
313         
314     if (clazz == null) {
315         // clazz == null indicates an FVD situation for a nonexistant class
316
if (isArray(repositoryID)){
317         read_Array(bridge, in, null, sender, offset);
318         } else {
319         bridge.simpleSkipObject(repositoryID, sender);
320         }
321         return result;
322     }
323         
324         if (clazz.isArray()) {
325             result = (java.io.Serializable JavaDoc)read_Array(bridge, in, clazz, sender, offset);
326         } else {
327             result = (java.io.Serializable JavaDoc)bridge.simpleReadObject(clazz, repositoryID, sender, offset);
328         }
329
330     return result;
331     }
332
333     /**
334      * Returns the repository ID for the given RMI value Class.
335      * @param clz The class to return a repository ID for.
336      * @return the repository ID of the Class.
337      **/

338     public java.lang.String JavaDoc getRMIRepositoryID(java.lang.Class JavaDoc clz) {
339     return RepositoryId.createForJavaType(clz);
340     }
341
342     /**
343      * Indicates whether the given Class performs custom or
344      * default marshaling.
345      * @param clz The class to test for custom marshaling.
346      * @return True if the class performs custom marshaling, false
347      * if it does not.
348      **/

349     public boolean isCustomMarshaled(java.lang.Class JavaDoc clz) {
350     return ObjectStreamClass.lookup(clz).isCustomMarshaled();
351     }
352
353     /**
354      * Returns the CodeBase for this ValueHandler. This is used by
355      * the ORB runtime. The server sends the service context containing
356      * the IOR for this CodeBase on the first GIOP reply. The clients
357      * do the same on the first GIOP request.
358      * @return the SendingContext.CodeBase of this ValueHandler.
359      **/

360     public org.omg.SendingContext.RunTime JavaDoc getRunTimeCodeBase() {
361     if (codeBase != null)
362         return codeBase;
363     else {
364         codeBase = new FVDCodeBaseImpl();
365
366         // backward compatability 4365188
367
// set the valueHandler so that correct/incorrect RepositoryID
368
// calculations can be done based on the ORB version
369
FVDCodeBaseImpl fvdImpl = (FVDCodeBaseImpl) codeBase;
370             fvdImpl.setValueHandler(this);
371         return codeBase;
372     }
373     }
374
375
376     // methods supported for backward compatability so that the appropriate
377
// Rep-id calculations take place based on the ORB version
378

379     /**
380      * Returns a boolean of whether or not RepositoryId indicates
381      * FullValueDescriptor.
382      * used for backward compatability
383      */

384
385      public boolean useFullValueDescription(Class JavaDoc clazz, String JavaDoc repositoryID)
386     throws IOException JavaDoc
387      {
388     return RepositoryId.useFullValueDescription(clazz, repositoryID);
389      }
390
391      public String JavaDoc getClassName(String JavaDoc id)
392      {
393         RepositoryId repID = RepositoryId.cache.getId(id);
394         return repID.getClassName();
395      }
396
397      public Class JavaDoc getClassFromType(String JavaDoc id)
398         throws ClassNotFoundException JavaDoc
399      {
400         RepositoryId repId = RepositoryId.cache.getId(id);
401         return repId.getClassFromType();
402      }
403
404      public Class JavaDoc getAnyClassFromType(String JavaDoc id)
405         throws ClassNotFoundException JavaDoc
406      {
407         RepositoryId repId = RepositoryId.cache.getId(id);
408         return repId.getAnyClassFromType();
409      }
410
411      public String JavaDoc createForAnyType(Class JavaDoc cl)
412      {
413         return RepositoryId.createForAnyType(cl);
414      }
415
416      public String JavaDoc getDefinedInId(String JavaDoc id)
417      {
418         RepositoryId repId = RepositoryId.cache.getId(id);
419         return repId.getDefinedInId();
420      }
421
422      public String JavaDoc getUnqualifiedName(String JavaDoc id)
423      {
424         RepositoryId repId = RepositoryId.cache.getId(id);
425         return repId.getUnqualifiedName();
426      }
427
428      public String JavaDoc getSerialVersionUID(String JavaDoc id)
429      {
430         RepositoryId repId = RepositoryId.cache.getId(id);
431         return repId.getSerialVersionUID();
432      }
433
434
435      public boolean isAbstractBase(Class JavaDoc clazz)
436      {
437         return RepositoryId.isAbstractBase(clazz);
438      }
439
440      public boolean isSequence(String JavaDoc id)
441      {
442         RepositoryId repId = RepositoryId.cache.getId(id);
443         return repId.isSequence();
444      }
445
446     /**
447      * If the value contains a writeReplace method then the result
448      * is returned. Otherwise, the value itself is returned.
449      * @return the true value to marshal on the wire.
450      **/

451     public java.io.Serializable JavaDoc writeReplace(java.io.Serializable JavaDoc value) {
452     return ObjectStreamClass.lookup(value.getClass()).writeReplace(value);
453     }
454
455     /**
456      * Encapsulates writing of Java char arrays so that the 1.3 subclass
457      * can override it without exposing internals across packages. This
458      * is a fix for bug 4367783.
459      */

460     protected void writeCharArray(org.omg.CORBA_2_3.portable.OutputStream JavaDoc out,
461                                 char[] array,
462                                 int offset,
463                                 int length)
464     {
465         out.write_wchar_array(array, offset, length);
466     }
467
468     private void write_Array(org.omg.CORBA_2_3.portable.OutputStream JavaDoc out, java.io.Serializable JavaDoc obj, Class JavaDoc type) {
469
470         int i, length;
471
472         if (type.isPrimitive()) {
473             if (type == Integer.TYPE) {
474         int[] array = (int[])((Object JavaDoc)obj);
475         length = array.length;
476         out.write_ulong(length);
477         out.write_long_array(array, 0, length);
478             } else if (type == Byte.TYPE) {
479         byte[] array = (byte[])((Object JavaDoc)obj);
480         length = array.length;
481         out.write_ulong(length);
482         out.write_octet_array(array, 0, length);
483             } else if (type == Long.TYPE) {
484         long[] array = (long[])((Object JavaDoc)obj);
485         length = array.length;
486         out.write_ulong(length);
487         out.write_longlong_array(array, 0, length);
488             } else if (type == Float.TYPE) {
489         float[] array = (float[])((Object JavaDoc)obj);
490         length = array.length;
491         out.write_ulong(length);
492         out.write_float_array(array, 0, length);
493             } else if (type == Double.TYPE) {
494         double[] array = (double[])((Object JavaDoc)obj);
495         length = array.length;
496         out.write_ulong(length);
497         out.write_double_array(array, 0, length);
498             } else if (type == Short.TYPE) {
499         short[] array = (short[])((Object JavaDoc)obj);
500         length = array.length;
501         out.write_ulong(length);
502         out.write_short_array(array, 0, length);
503             } else if (type == Character.TYPE) {
504         char[] array = (char[])((Object JavaDoc)obj);
505         length = array.length;
506         out.write_ulong(length);
507         writeCharArray(out, array, 0, length);
508             } else if (type == Boolean.TYPE) {
509         boolean[] array = (boolean[])((Object JavaDoc)obj);
510         length = array.length;
511         out.write_ulong(length);
512         out.write_boolean_array(array, 0, length);
513             } else {
514         // XXX I18N, logging needed.
515
throw new Error JavaDoc("Invalid primitive type : " +
516             obj.getClass().getName());
517             }
518         } else if (type == java.lang.Object JavaDoc.class) {
519             Object JavaDoc[] array = (Object JavaDoc[])((Object JavaDoc)obj);
520             length = array.length;
521             out.write_ulong(length);
522             for (i = 0; i < length; i++) {
523         Util.writeAny(out, array[i]);
524         }
525         } else {
526             Object JavaDoc[] array = (Object JavaDoc[])((Object JavaDoc)obj);
527             length = array.length;
528             out.write_ulong(length);
529         int callType = kValueType;
530             
531         if (type.isInterface()) {
532         String JavaDoc className = type.getName();
533                 
534         if (java.rmi.Remote JavaDoc.class.isAssignableFrom(type)) {
535             // RMI Object reference...
536
callType = kRemoteType;
537         } else if (org.omg.CORBA.Object JavaDoc.class.isAssignableFrom(type)){
538             // IDL Object reference...
539
callType = kRemoteType;
540         } else if (RepositoryId.isAbstractBase(type)) {
541             // IDL Abstract Object reference...
542
callType = kAbstractType;
543         } else if (ObjectStreamClassCorbaExt.isAbstractInterface(type)) {
544             callType = kAbstractType;
545             }
546         }
547             
548         for (i = 0; i < length; i++) {
549         switch (callType) {
550         case kRemoteType:
551             Util.writeRemoteObject(out, array[i]);
552             break;
553         case kAbstractType:
554             Util.writeAbstractObject(out,array[i]);
555             break;
556         case kValueType:
557             try{
558             out.write_value((java.io.Serializable JavaDoc)array[i]);
559             } catch(ClassCastException JavaDoc cce){
560             if (array[i] instanceof java.io.Serializable JavaDoc)
561                 throw cce;
562             else {
563                 Utility.throwNotSerializableForCorba(
564                 array[i].getClass().getName());
565             }
566             }
567             break;
568         }
569         }
570         }
571     }
572
573     /**
574      * Encapsulates reading of Java char arrays so that the 1.3 subclass
575      * can override it without exposing internals across packages. This
576      * is a fix for bug 4367783.
577      */

578     protected void readCharArray(org.omg.CORBA_2_3.portable.InputStream JavaDoc in,
579                                  char[] array,
580                                  int offset,
581                                  int length)
582     {
583         in.read_wchar_array(array, offset, length);
584     }
585
586     private java.lang.Object JavaDoc read_Array(IIOPInputStream bridge,
587                                         org.omg.CORBA_2_3.portable.InputStream JavaDoc in,
588                     Class JavaDoc sequence,
589                                         com.sun.org.omg.SendingContext.CodeBase sender,
590                                         int offset)
591     {
592         try {
593         // Read length of coming array
594
int length = in.read_ulong();
595             int i;
596
597         if (sequence == null) {
598         for (i = 0; i < length; i++)
599             in.read_value();
600
601         return null;
602         }
603             
604         Class JavaDoc componentType = sequence.getComponentType();
605         Class JavaDoc actualType = componentType;
606
607
608             if (componentType.isPrimitive()) {
609                 if (componentType == Integer.TYPE) {
610             int[] array = new int[length];
611             in.read_long_array(array, 0, length);
612             return ((java.io.Serializable JavaDoc)((Object JavaDoc)array));
613                 } else if (componentType == Byte.TYPE) {
614             byte[] array = new byte[length];
615             in.read_octet_array(array, 0, length);
616             return ((java.io.Serializable JavaDoc)((Object JavaDoc)array));
617                 } else if (componentType == Long.TYPE) {
618             long[] array = new long[length];
619             in.read_longlong_array(array, 0, length);
620             return ((java.io.Serializable JavaDoc)((Object JavaDoc)array));
621                 } else if (componentType == Float.TYPE) {
622             float[] array = new float[length];
623             in.read_float_array(array, 0, length);
624             return ((java.io.Serializable JavaDoc)((Object JavaDoc)array));
625                 } else if (componentType == Double.TYPE) {
626             double[] array = new double[length];
627             in.read_double_array(array, 0, length);
628             return ((java.io.Serializable JavaDoc)((Object JavaDoc)array));
629                 } else if (componentType == Short.TYPE) {
630             short[] array = new short[length];
631             in.read_short_array(array, 0, length);
632             return ((java.io.Serializable JavaDoc)((Object JavaDoc)array));
633                 } else if (componentType == Character.TYPE) {
634             char[] array = new char[length];
635             readCharArray(in, array, 0, length);
636             return ((java.io.Serializable JavaDoc)((Object JavaDoc)array));
637                 } else if (componentType == Boolean.TYPE) {
638             boolean[] array = new boolean[length];
639             in.read_boolean_array(array, 0, length);
640             return ((java.io.Serializable JavaDoc)((Object JavaDoc)array));
641                 } else {
642             // XXX I18N, logging needed.
643
throw new Error JavaDoc("Invalid primitive componentType : " + sequence.getName());
644                 }
645             } else if (componentType == java.lang.Object JavaDoc.class) {
646         Object JavaDoc[] array = (Object JavaDoc[])java.lang.reflect.Array.newInstance(
647             componentType, length);
648
649                 // Store this object and its beginning position
650
// since there might be indirections to it while
651
// it's been unmarshalled.
652
bridge.activeRecursionMgr.addObject(offset, array);
653
654                 for (i = 0; i < length; i++) {
655                     Object JavaDoc objectValue = null;
656                     try {
657                         objectValue = Util.readAny(in);
658                     } catch(IndirectionException JavaDoc cdrie) {
659                         try {
660                             // The CDR stream had never seen the given offset
661
// before, so check the recursion manager (it will
662
// throw an IOException if it doesn't have a
663
// reference, either).
664
objectValue = bridge.activeRecursionMgr.getObject(
665                 cdrie.offset);
666                         } catch (IOException JavaDoc ie) {
667                             // Translate to a MARSHAL exception since
668
// ValueHandlers aren't allowed to throw
669
// IOExceptions
670
throw utilWrapper.invalidIndirection( ie,
671                 new Integer JavaDoc( cdrie.offset ) ) ;
672                         }
673                     }
674                     
675                     array[i] = objectValue;
676                 }
677                 return ((java.io.Serializable JavaDoc)((Object JavaDoc)array));
678             } else {
679         Object JavaDoc[] array = (Object JavaDoc[])java.lang.reflect.Array.newInstance(
680             componentType, length);
681                 // Store this object and its beginning position
682
// since there might be indirections to it while
683
// it's been unmarshalled.
684
bridge.activeRecursionMgr.addObject(offset, array);
685
686         // Decide what method call to make based on the componentType.
687
// If it is a componentType for which we need to load a stub,
688
// convert the componentType to the correct stub type.
689

690                 int callType = kValueType;
691                 boolean narrow = false;
692                 
693                 if (componentType.isInterface()) {
694                     boolean loadStubClass = false;
695                     // String className = componentType.getName();
696

697                     if (java.rmi.Remote JavaDoc.class.isAssignableFrom(componentType)) {
698                         
699                         // RMI Object reference...
700
callType = kRemoteType;
701                         
702                         // for better performance, load the stub class once
703
// instead of for each element of the array
704
loadStubClass = true;
705                     } else if (org.omg.CORBA.Object JavaDoc.class.isAssignableFrom(componentType)){
706                         // IDL Object reference...
707
callType = kRemoteType;
708                         loadStubClass = true;
709                     } else if (RepositoryId.isAbstractBase(componentType)) {
710                         // IDL Abstract Object reference...
711
callType = kAbstractType;
712                         loadStubClass = true;
713                     } else if (ObjectStreamClassCorbaExt.isAbstractInterface(componentType)) {
714                         
715                         // RMI Abstract Object reference...
716

717                         // componentType = null;
718
callType = kAbstractType;
719                     }
720
721                     if (loadStubClass) {
722                         try {
723                             String JavaDoc codebase = Util.getCodebase(componentType);
724                             String JavaDoc repID = RepositoryId.createForAnyType(componentType);
725                             Class JavaDoc stubType =
726                 Utility.loadStubClass(repID, codebase, componentType);
727                 actualType = stubType;
728                         } catch (ClassNotFoundException JavaDoc e) {
729                             narrow = true;
730                         }
731                     } else {
732                         narrow = true;
733                     }
734                 }
735
736                 for (i = 0; i < length; i++) {
737                     
738                     try {
739                         switch (callType) {
740                         case kRemoteType:
741                             if (!narrow)
742                                 array[i] = (Object JavaDoc)in.read_Object(actualType);
743                             else {
744                                 array[i] = Utility.readObjectAndNarrow(in, actualType);
745                                 
746                             }
747                             break;
748                         case kAbstractType:
749                             if (!narrow)
750                                 array[i] = (Object JavaDoc)in.read_abstract_interface(actualType);
751                             else {
752                                 array[i] = Utility.readAbstractAndNarrow(in, actualType);
753                             }
754                             break;
755                         case kValueType:
756                             array[i] = (Object JavaDoc)in.read_value(actualType);
757                             break;
758                         }
759                     } catch(IndirectionException JavaDoc cdrie) {
760                         // The CDR stream had never seen the given offset before,
761
// so check the recursion manager (it will throw an
762
// IOException if it doesn't have a reference, either).
763
try {
764                             array[i] = bridge.activeRecursionMgr.getObject(
765                 cdrie.offset);
766                         } catch (IOException JavaDoc ioe) {
767                             // Translate to a MARSHAL exception since
768
// ValueHandlers aren't allowed to throw
769
// IOExceptions
770
throw utilWrapper.invalidIndirection( ioe,
771                 new Integer JavaDoc( cdrie.offset ) ) ;
772                         }
773                     }
774                     
775                 }
776                 
777                 return ((java.io.Serializable JavaDoc)((Object JavaDoc)array));
778         }
779         } finally {
780             // We've completed deserializing this object. Any
781
// future indirections will be handled correctly at the
782
// CDR level. The ActiveRecursionManager only deals with
783
// objects currently being deserialized.
784
bridge.activeRecursionMgr.removeObject(offset);
785         }
786     }
787
788     private boolean isArray(String JavaDoc repId){
789     return RepositoryId.cache.getId(repId).isSequence();
790     }
791
792     protected String JavaDoc getOutputStreamClassName() {
793         return "com.sun.corba.se.impl.io.IIOPOutputStream";
794     }
795
796     private com.sun.corba.se.impl.io.IIOPOutputStream createOutputStream() {
797         return (com.sun.corba.se.impl.io.IIOPOutputStream)AccessController.doPrivileged(
798         new StreamFactory(getOutputStreamClassName()));
799     }
800
801     protected String JavaDoc getInputStreamClassName() {
802         return "com.sun.corba.se.impl.io.IIOPInputStream";
803     }
804
805     private com.sun.corba.se.impl.io.IIOPInputStream createInputStream() {
806         return (com.sun.corba.se.impl.io.IIOPInputStream)AccessController.doPrivileged(
807         new StreamFactory(getInputStreamClassName()));
808     }
809
810     /**
811      * Instantiates a class of the given name using the system ClassLoader
812      * as part of a PrivilegedAction.
813      *
814      * It's private final so hopefully people can't grab it outside of
815      * this class.
816      *
817      * If you're worried that someone could subclass ValueHandlerImpl,
818      * install his own streams, and snoop what's on the wire:
819      * Someone can do that only if he's allowed to use the feature
820      * of installing his own javax.rmi.CORBA.Util delegate (via a
821      * JVM property or orb.properties file, read the first time the
822      * Util class is used). If he can do that, he can snoop
823      * anything on the wire, anyway, without abusing the
824      * StreamFactory class.
825      */

826     private static final class StreamFactory implements PrivilegedAction JavaDoc {
827         private String JavaDoc className;
828
829         public StreamFactory (String JavaDoc _className) {
830             className = _className;
831         }
832
833         public Object JavaDoc run() {
834             try {
835                 // Note: We must use the system ClassLoader here
836
// since we want to load classes outside of the
837
// core JDK when running J2EE Pure ORB and
838
// talking to Kestrel.
839
ClassLoader JavaDoc cl = Thread.currentThread().getContextClassLoader();
840                 if (cl == null)
841                     cl = ClassLoader.getSystemClassLoader();
842
843                 Class JavaDoc streamClass = cl.loadClass(className);
844
845                 // Since the ClassLoader should cache the class, this isn't
846
// as expensive as it looks.
847
return streamClass.newInstance();
848
849             } catch(Throwable JavaDoc t) {
850                 InternalError JavaDoc ie = new InternalError JavaDoc( "Error loading " + className ) ;
851         ie.initCause( t ) ;
852         throw ie ;
853             }
854         }
855     }
856
857     /**
858      * Our JDK 1.3 and JDK 1.3.1 behavior subclasses override this.
859      * The correct behavior is for a Java char to map to a CORBA wchar,
860      * but our older code mapped it to a CORBA char.
861      */

862     protected TCKind JavaDoc getJavaCharTCKind() {
863         return TCKind.tk_wchar;
864     }
865 }
866
867
Popular Tags