src/share/classes/com/sun/corba/se/impl/io/ValueHandlerImpl.java

Fri, 24 Sep 2010 22:42:14 -0700

author
skoppar
date
Fri, 24 Sep 2010 22:42:14 -0700
changeset 205
b2fff4b7e8cd
parent 158
91006f157c46
child 443
3c73273667ae
permissions
-rw-r--r--

6891766: Vulnerabilities in use of reflection in CORBA
Reviewed-by: hawtin

     1 /*
     2  * Copyright (c) 1998, 2010, Oracle and/or its affiliates. All rights reserved.
     3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     4  *
     5  * This code is free software; you can redistribute it and/or modify it
     6  * under the terms of the GNU General Public License version 2 only, as
     7  * published by the Free Software Foundation.  Oracle designates this
     8  * particular file as subject to the "Classpath" exception as provided
     9  * by Oracle in the LICENSE file that accompanied this code.
    10  *
    11  * This code is distributed in the hope that it will be useful, but WITHOUT
    12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
    13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
    14  * version 2 for more details (a copy is included in the LICENSE file that
    15  * accompanied this code).
    16  *
    17  * You should have received a copy of the GNU General Public License version
    18  * 2 along with this work; if not, write to the Free Software Foundation,
    19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
    20  *
    21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
    22  * or visit www.oracle.com if you need additional information or have any
    23  * questions.
    24  */
    25 /*
    26  * Licensed Materials - Property of IBM
    27  * RMI-IIOP v1.0
    28  * Copyright IBM Corp. 1998 1999  All Rights Reserved
    29  *
    30  */
    32 package com.sun.corba.se.impl.io;
    34 import javax.rmi.CORBA.Util;
    36 import java.util.Hashtable;
    37 import java.io.IOException;
    39 import com.sun.corba.se.impl.util.RepositoryId;
    40 import com.sun.corba.se.impl.util.Utility;
    42 import org.omg.CORBA.TCKind;
    44 import org.omg.CORBA.portable.IndirectionException;
    45 import com.sun.org.omg.SendingContext.CodeBase;
    46 import com.sun.org.omg.SendingContext.CodeBaseHelper;
    48 import java.security.AccessController;
    49 import java.security.PrivilegedAction;
    50 import java.security.PrivilegedExceptionAction;
    52 import com.sun.corba.se.spi.logging.CORBALogDomains;
    53 import com.sun.corba.se.impl.logging.OMGSystemException;
    54 import com.sun.corba.se.impl.logging.UtilSystemException;
    56 public class ValueHandlerImpl implements javax.rmi.CORBA.ValueHandlerMultiFormat {
    58     // Property to override our maximum stream format version
    59     public static final String FORMAT_VERSION_PROPERTY
    60         = "com.sun.CORBA.MaxStreamFormatVersion";
    62     private static final byte MAX_SUPPORTED_FORMAT_VERSION = (byte)2;
    63     private static final byte STREAM_FORMAT_VERSION_1 = (byte)1;
    65     // The ValueHandler's maximum stream format version to advertise,
    66     // set in a static initializer.
    67     private static final byte MAX_STREAM_FORMAT_VERSION;
    69     static {
    70         MAX_STREAM_FORMAT_VERSION = getMaxStreamFormatVersion();
    71     }
    73     // Looks for the FORMAT_VERSION_PROPERTY system property
    74     // to allow the user to override our default stream format
    75     // version.  Note that this still only allows them to pick
    76     // a supported version (1 through MAX_STREAM_FORMAT_VERSION).
    77     private static byte getMaxStreamFormatVersion() {
    79         try {
    81             String propValue = (String) AccessController.doPrivileged(
    82                                         new PrivilegedAction() {
    83                 public java.lang.Object run() {
    84                     return System.getProperty(ValueHandlerImpl.FORMAT_VERSION_PROPERTY);
    85                 }
    86             });
    88             // The property wasn't set
    89             if (propValue == null)
    90                 return MAX_SUPPORTED_FORMAT_VERSION;
    92             byte result = Byte.parseByte(propValue);
    94             // REVISIT.  Just set to MAX_SUPPORTED_FORMAT_VERSION
    95             // or really let the system shutdown with this Error?
    96             if (result < 1 || result > MAX_SUPPORTED_FORMAT_VERSION)
    97                 // XXX I18N, logging needed.
    98                 throw new ExceptionInInitializerError("Invalid stream format version: "
    99                                                       + result
   100                                                       + ".  Valid range is 1 through "
   101                                                       + MAX_SUPPORTED_FORMAT_VERSION);
   103             return result;
   105         } catch (Exception ex) {
   106             // REVISIT.  Swallow this or really let
   107             // the system shutdown with this Error?
   109             Error err = new ExceptionInInitializerError(ex);
   110             err.initCause( ex ) ;
   111             throw err ;
   112         }
   113     }
   115     public static final short kRemoteType = 0;
   116     public static final short kAbstractType = 1;
   117     public static final short kValueType = 2;
   119     private Hashtable inputStreamPairs = null;
   120     private Hashtable outputStreamPairs = null;
   121     private CodeBase codeBase = null;
   122     private boolean useHashtables = true;
   123     private boolean isInputStream = true;
   124     private IIOPOutputStream outputStreamBridge = null;
   125     private IIOPInputStream inputStreamBridge = null;
   126     private OMGSystemException omgWrapper = OMGSystemException.get(
   127         CORBALogDomains.RPC_ENCODING ) ;
   128     private UtilSystemException utilWrapper = UtilSystemException.get(
   129         CORBALogDomains.RPC_ENCODING ) ;
   131     // See javax.rmi.CORBA.ValueHandlerMultiFormat
   132     public byte getMaximumStreamFormatVersion() {
   133         return MAX_STREAM_FORMAT_VERSION;
   134     }
   136     // See javax.rmi.CORBA.ValueHandlerMultiFormat
   137     public void writeValue(org.omg.CORBA.portable.OutputStream out,
   138                            java.io.Serializable value,
   139                            byte streamFormatVersion) {
   141         if (streamFormatVersion == 2) {
   142             if (!(out instanceof org.omg.CORBA.portable.ValueOutputStream)) {
   143                 throw omgWrapper.notAValueoutputstream() ;
   144             }
   145         } else if (streamFormatVersion != 1) {
   146             throw omgWrapper.invalidStreamFormatVersion(
   147                 new Integer(streamFormatVersion) ) ;
   148         }
   150         writeValueWithVersion(out, value, streamFormatVersion);
   151     }
   153     public ValueHandlerImpl(){}
   155     public ValueHandlerImpl(boolean isInputStream) {
   156         this();
   157         useHashtables = false;
   158         this.isInputStream = isInputStream;
   159     }
   161     /**
   162      * Writes the value to the stream using java semantics.
   163      * @param out The stream to write the value to
   164      * @param value The value to be written to the stream
   165      **/
   166     public void writeValue(org.omg.CORBA.portable.OutputStream _out,
   167                            java.io.Serializable value) {
   168         writeValueWithVersion(_out, value, STREAM_FORMAT_VERSION_1);
   169     }
   171     private void writeValueWithVersion(org.omg.CORBA.portable.OutputStream _out,
   172                                        java.io.Serializable value,
   173                                        byte streamFormatVersion) {
   175         org.omg.CORBA_2_3.portable.OutputStream out =
   176             (org.omg.CORBA_2_3.portable.OutputStream) _out;
   178         if (!useHashtables) {
   179             if (outputStreamBridge == null) {
   180                 outputStreamBridge = createOutputStream();
   181                 outputStreamBridge.setOrbStream(out);
   182             }
   184             try {
   185                 outputStreamBridge.increaseRecursionDepth();
   186                 writeValueInternal(outputStreamBridge, out, value, streamFormatVersion);
   187             } finally {
   188                 outputStreamBridge.decreaseRecursionDepth();
   189             }
   191             return;
   192         }
   194         IIOPOutputStream jdkToOrbOutputStreamBridge = null;
   196         if (outputStreamPairs == null)
   197             outputStreamPairs = new Hashtable();
   199         jdkToOrbOutputStreamBridge = (IIOPOutputStream)outputStreamPairs.get(_out);
   201         if (jdkToOrbOutputStreamBridge == null) {
   202             jdkToOrbOutputStreamBridge = createOutputStream();
   203             jdkToOrbOutputStreamBridge.setOrbStream(out);
   204             outputStreamPairs.put(_out, jdkToOrbOutputStreamBridge);
   205         }
   207         try {
   209             jdkToOrbOutputStreamBridge.increaseRecursionDepth();
   210             writeValueInternal(jdkToOrbOutputStreamBridge, out, value, streamFormatVersion);
   211         } finally {
   212             if (jdkToOrbOutputStreamBridge.decreaseRecursionDepth() == 0) {
   213                 outputStreamPairs.remove(_out);
   214             }
   215         }
   216     }
   218     private void writeValueInternal(IIOPOutputStream bridge,
   219                                     org.omg.CORBA_2_3.portable.OutputStream out,
   220                                     java.io.Serializable value,
   221                                     byte streamFormatVersion)
   222     {
   223         Class clazz = value.getClass();
   225         if (clazz.isArray())
   226             write_Array(out, value, clazz.getComponentType());
   227         else
   228             bridge.simpleWriteObject(value, streamFormatVersion);
   229     }
   231     /**
   232      * Reads a value from the stream using java semantics.
   233      * @param in The stream to read the value from
   234      * @param clazz The type of the value to be read in
   235      * @param sender The sending context runtime
   236      **/
   237     public java.io.Serializable readValue(org.omg.CORBA.portable.InputStream _in,
   238                                           int offset,
   239                                           java.lang.Class clazz,
   240                                           String repositoryID,
   241                                           org.omg.SendingContext.RunTime _sender)
   242     {
   243         // Must use narrow rather than a direct cast to a com.sun
   244         // class.  Fix for bug 4379539.
   245         CodeBase sender = CodeBaseHelper.narrow(_sender);
   247         org.omg.CORBA_2_3.portable.InputStream in =
   248             (org.omg.CORBA_2_3.portable.InputStream) _in;
   250         if (!useHashtables) {
   251             if (inputStreamBridge == null) {
   252                 inputStreamBridge = createInputStream();
   253                 inputStreamBridge.setOrbStream(in);
   254                 inputStreamBridge.setSender(sender); //d11638
   255                 // backward compatability 4365188
   256                 inputStreamBridge.setValueHandler(this);
   257             }
   259             java.io.Serializable result = null;
   261             try {
   263                 inputStreamBridge.increaseRecursionDepth();
   264                 result = (java.io.Serializable) readValueInternal(inputStreamBridge, in, offset, clazz, repositoryID, sender);
   266             } finally {
   268                 if (inputStreamBridge.decreaseRecursionDepth() == 0) {
   269                     // Indirections are resolved immediately since
   270                     // the change to the active recursion manager,
   271                     // so this will never happen.
   272                 }
   273             }
   275             return result;
   276         }
   278         IIOPInputStream jdkToOrbInputStreamBridge = null;
   279         if (inputStreamPairs == null)
   280             inputStreamPairs = new Hashtable();
   282         jdkToOrbInputStreamBridge = (IIOPInputStream)inputStreamPairs.get(_in);
   284         if (jdkToOrbInputStreamBridge == null) {
   286             jdkToOrbInputStreamBridge = createInputStream();
   287             jdkToOrbInputStreamBridge.setOrbStream(in);
   288             jdkToOrbInputStreamBridge.setSender(sender); //d11638
   289             // backward compatability 4365188
   290             jdkToOrbInputStreamBridge.setValueHandler(this);
   291             inputStreamPairs.put(_in, jdkToOrbInputStreamBridge);
   292         }
   294         java.io.Serializable result = null;
   296         try {
   298             jdkToOrbInputStreamBridge.increaseRecursionDepth();
   299             result = (java.io.Serializable) readValueInternal(jdkToOrbInputStreamBridge, in, offset, clazz, repositoryID, sender);
   301         } finally {
   303             if (jdkToOrbInputStreamBridge.decreaseRecursionDepth() == 0) {
   304                 inputStreamPairs.remove(_in);
   305             }
   306         }
   308         return result;
   309     }
   311     private java.io.Serializable readValueInternal(IIOPInputStream bridge,
   312                                                   org.omg.CORBA_2_3.portable.InputStream in,
   313                                                   int offset,
   314                                                   java.lang.Class clazz,
   315                                                   String repositoryID,
   316                                                   com.sun.org.omg.SendingContext.CodeBase sender)
   317     {
   318         java.io.Serializable result = null;
   320         if (clazz == null) {
   321             // clazz == null indicates an FVD situation for a nonexistant class
   322             if (isArray(repositoryID)){
   323                 read_Array(bridge, in, null, sender, offset);
   324             } else {
   325                 bridge.simpleSkipObject(repositoryID, sender);
   326             }
   327             return result;
   328         }
   330         if (clazz.isArray()) {
   331             result = (java.io.Serializable)read_Array(bridge, in, clazz, sender, offset);
   332         } else {
   333             result = (java.io.Serializable)bridge.simpleReadObject(clazz, repositoryID, sender, offset);
   334         }
   336         return result;
   337     }
   339     /**
   340      * Returns the repository ID for the given RMI value Class.
   341      * @param clz The class to return a repository ID for.
   342      * @return the repository ID of the Class.
   343      **/
   344     public java.lang.String getRMIRepositoryID(java.lang.Class clz) {
   345         return RepositoryId.createForJavaType(clz);
   346     }
   348     /**
   349      * Indicates whether the given Class performs custom or
   350      * default marshaling.
   351      * @param clz The class to test for custom marshaling.
   352      * @return True if the class performs custom marshaling, false
   353      * if it does not.
   354      **/
   355     public boolean isCustomMarshaled(java.lang.Class clz) {
   356         return ObjectStreamClass.lookup(clz).isCustomMarshaled();
   357     }
   359     /**
   360      * Returns the CodeBase for this ValueHandler.  This is used by
   361      * the ORB runtime.  The server sends the service context containing
   362      * the IOR for this CodeBase on the first GIOP reply.  The clients
   363      * do the same on the first GIOP request.
   364      * @return the SendingContext.CodeBase of this ValueHandler.
   365      **/
   366     public org.omg.SendingContext.RunTime getRunTimeCodeBase() {
   367         if (codeBase != null)
   368             return codeBase;
   369         else {
   370             codeBase = new FVDCodeBaseImpl();
   372             // backward compatability 4365188
   373             // set the valueHandler so that correct/incorrect RepositoryID
   374             // calculations can be done based on the ORB version
   375             FVDCodeBaseImpl fvdImpl = (FVDCodeBaseImpl) codeBase;
   376             fvdImpl.setValueHandler(this);
   377             return codeBase;
   378         }
   379     }
   382     // methods supported for backward compatability so that the appropriate
   383     // Rep-id calculations take place based on the ORB version
   385     /**
   386      *  Returns a boolean of whether or not RepositoryId indicates
   387      *  FullValueDescriptor.
   388      *  used for backward compatability
   389      */
   391      public boolean useFullValueDescription(Class clazz, String repositoryID)
   392         throws IOException
   393      {
   394         return RepositoryId.useFullValueDescription(clazz, repositoryID);
   395      }
   397      public String getClassName(String id)
   398      {
   399         RepositoryId repID = RepositoryId.cache.getId(id);
   400         return repID.getClassName();
   401      }
   403      public Class getClassFromType(String id)
   404         throws ClassNotFoundException
   405      {
   406         RepositoryId repId = RepositoryId.cache.getId(id);
   407         return repId.getClassFromType();
   408      }
   410      public Class getAnyClassFromType(String id)
   411         throws ClassNotFoundException
   412      {
   413         RepositoryId repId = RepositoryId.cache.getId(id);
   414         return repId.getAnyClassFromType();
   415      }
   417      public String createForAnyType(Class cl)
   418      {
   419         return RepositoryId.createForAnyType(cl);
   420      }
   422      public String getDefinedInId(String id)
   423      {
   424         RepositoryId repId = RepositoryId.cache.getId(id);
   425         return repId.getDefinedInId();
   426      }
   428      public String getUnqualifiedName(String id)
   429      {
   430         RepositoryId repId = RepositoryId.cache.getId(id);
   431         return repId.getUnqualifiedName();
   432      }
   434      public String getSerialVersionUID(String id)
   435      {
   436         RepositoryId repId = RepositoryId.cache.getId(id);
   437         return repId.getSerialVersionUID();
   438      }
   441      public boolean isAbstractBase(Class clazz)
   442      {
   443         return RepositoryId.isAbstractBase(clazz);
   444      }
   446      public boolean isSequence(String id)
   447      {
   448         RepositoryId repId = RepositoryId.cache.getId(id);
   449         return repId.isSequence();
   450      }
   452     /**
   453      * If the value contains a writeReplace method then the result
   454      * is returned.  Otherwise, the value itself is returned.
   455      * @return the true value to marshal on the wire.
   456      **/
   457     public java.io.Serializable writeReplace(java.io.Serializable value) {
   458         return ObjectStreamClass.lookup(value.getClass()).writeReplace(value);
   459     }
   461     /**
   462      * Encapsulates writing of Java char arrays so that the 1.3 subclass
   463      * can override it without exposing internals across packages.  This
   464      * is a fix for bug 4367783.
   465      */
   466     protected void writeCharArray(org.omg.CORBA_2_3.portable.OutputStream out,
   467                                 char[] array,
   468                                 int offset,
   469                                 int length)
   470     {
   471         out.write_wchar_array(array, offset, length);
   472     }
   474     private void write_Array(org.omg.CORBA_2_3.portable.OutputStream out, java.io.Serializable obj, Class type) {
   476         int i, length;
   478         if (type.isPrimitive()) {
   479             if (type == Integer.TYPE) {
   480                 int[] array = (int[])((Object)obj);
   481                 length = array.length;
   482                 out.write_ulong(length);
   483                 out.write_long_array(array, 0, length);
   484             } else if (type == Byte.TYPE) {
   485                 byte[] array = (byte[])((Object)obj);
   486                 length = array.length;
   487                 out.write_ulong(length);
   488                 out.write_octet_array(array, 0, length);
   489             } else if (type == Long.TYPE) {
   490                 long[] array = (long[])((Object)obj);
   491                 length = array.length;
   492                 out.write_ulong(length);
   493                 out.write_longlong_array(array, 0, length);
   494             } else if (type == Float.TYPE) {
   495                 float[] array = (float[])((Object)obj);
   496                 length = array.length;
   497                 out.write_ulong(length);
   498                 out.write_float_array(array, 0, length);
   499             } else if (type == Double.TYPE) {
   500                 double[] array = (double[])((Object)obj);
   501                 length = array.length;
   502                 out.write_ulong(length);
   503                 out.write_double_array(array, 0, length);
   504             } else if (type == Short.TYPE) {
   505                 short[] array = (short[])((Object)obj);
   506                 length = array.length;
   507                 out.write_ulong(length);
   508                 out.write_short_array(array, 0, length);
   509             } else if (type == Character.TYPE) {
   510                 char[] array = (char[])((Object)obj);
   511                 length = array.length;
   512                 out.write_ulong(length);
   513                 writeCharArray(out, array, 0, length);
   514             } else if (type == Boolean.TYPE) {
   515                 boolean[] array = (boolean[])((Object)obj);
   516                 length = array.length;
   517                 out.write_ulong(length);
   518                 out.write_boolean_array(array, 0, length);
   519             } else {
   520                 // XXX I18N, logging needed.
   521                 throw new Error("Invalid primitive type : " +
   522                     obj.getClass().getName());
   523             }
   524         } else if (type == java.lang.Object.class) {
   525             Object[] array = (Object[])((Object)obj);
   526             length = array.length;
   527             out.write_ulong(length);
   528             for (i = 0; i < length; i++) {
   529                 Util.writeAny(out, array[i]);
   530             }
   531         } else {
   532             Object[] array = (Object[])((Object)obj);
   533             length = array.length;
   534             out.write_ulong(length);
   535             int callType = kValueType;
   537             if (type.isInterface()) {
   538                 String className = type.getName();
   540                 if (java.rmi.Remote.class.isAssignableFrom(type)) {
   541                     // RMI Object reference...
   542                     callType = kRemoteType;
   543                 } else if (org.omg.CORBA.Object.class.isAssignableFrom(type)){
   544                     // IDL Object reference...
   545                     callType = kRemoteType;
   546                 } else if (RepositoryId.isAbstractBase(type)) {
   547                     // IDL Abstract Object reference...
   548                     callType = kAbstractType;
   549                 } else if (ObjectStreamClassCorbaExt.isAbstractInterface(type)) {
   550                     callType = kAbstractType;
   551                 }
   552             }
   554             for (i = 0; i < length; i++) {
   555                 switch (callType) {
   556                 case kRemoteType:
   557                     Util.writeRemoteObject(out, array[i]);
   558                     break;
   559                 case kAbstractType:
   560                     Util.writeAbstractObject(out,array[i]);
   561                     break;
   562                 case kValueType:
   563                     try{
   564                         out.write_value((java.io.Serializable)array[i]);
   565                     } catch(ClassCastException cce){
   566                         if (array[i] instanceof java.io.Serializable)
   567                             throw cce;
   568                         else {
   569                             Utility.throwNotSerializableForCorba(
   570                                 array[i].getClass().getName());
   571                         }
   572                     }
   573                     break;
   574                 }
   575             }
   576         }
   577     }
   579     /**
   580      * Encapsulates reading of Java char arrays so that the 1.3 subclass
   581      * can override it without exposing internals across packages.  This
   582      * is a fix for bug 4367783.
   583      */
   584     protected void readCharArray(org.omg.CORBA_2_3.portable.InputStream in,
   585                                  char[] array,
   586                                  int offset,
   587                                  int length)
   588     {
   589         in.read_wchar_array(array, offset, length);
   590     }
   592     private java.lang.Object read_Array(IIOPInputStream bridge,
   593                                         org.omg.CORBA_2_3.portable.InputStream in,
   594                                         Class sequence,
   595                                         com.sun.org.omg.SendingContext.CodeBase sender,
   596                                         int offset)
   597     {
   598         try {
   599             // Read length of coming array
   600             int length = in.read_ulong();
   601             int i;
   603             if (sequence == null) {
   604                 for (i = 0; i < length; i++)
   605                     in.read_value();
   607                 return null;
   608             }
   610             Class componentType = sequence.getComponentType();
   611             Class actualType = componentType;
   614             if (componentType.isPrimitive()) {
   615                 if (componentType == Integer.TYPE) {
   616                     int[] array = new int[length];
   617                     in.read_long_array(array, 0, length);
   618                     return ((java.io.Serializable)((Object)array));
   619                 } else if (componentType == Byte.TYPE) {
   620                     byte[] array = new byte[length];
   621                     in.read_octet_array(array, 0, length);
   622                     return ((java.io.Serializable)((Object)array));
   623                 } else if (componentType == Long.TYPE) {
   624                     long[] array = new long[length];
   625                     in.read_longlong_array(array, 0, length);
   626                     return ((java.io.Serializable)((Object)array));
   627                 } else if (componentType == Float.TYPE) {
   628                     float[] array = new float[length];
   629                     in.read_float_array(array, 0, length);
   630                     return ((java.io.Serializable)((Object)array));
   631                 } else if (componentType == Double.TYPE) {
   632                     double[] array = new double[length];
   633                     in.read_double_array(array, 0, length);
   634                     return ((java.io.Serializable)((Object)array));
   635                 } else if (componentType == Short.TYPE) {
   636                     short[] array = new short[length];
   637                     in.read_short_array(array, 0, length);
   638                     return ((java.io.Serializable)((Object)array));
   639                 } else if (componentType == Character.TYPE) {
   640                     char[] array = new char[length];
   641                     readCharArray(in, array, 0, length);
   642                     return ((java.io.Serializable)((Object)array));
   643                 } else if (componentType == Boolean.TYPE) {
   644                     boolean[] array = new boolean[length];
   645                     in.read_boolean_array(array, 0, length);
   646                     return ((java.io.Serializable)((Object)array));
   647                 } else {
   648                     // XXX I18N, logging needed.
   649                     throw new Error("Invalid primitive componentType : " + sequence.getName());
   650                 }
   651             } else if (componentType == java.lang.Object.class) {
   652                 Object[] array = (Object[])java.lang.reflect.Array.newInstance(
   653                     componentType, length);
   655                 // Store this object and its beginning position
   656                 // since there might be indirections to it while
   657                 // it's been unmarshalled.
   658                 bridge.activeRecursionMgr.addObject(offset, array);
   660                 for (i = 0; i < length; i++) {
   661                     Object objectValue = null;
   662                     try {
   663                         objectValue = Util.readAny(in);
   664                     } catch(IndirectionException cdrie) {
   665                         try {
   666                             // The CDR stream had never seen the given offset
   667                             // before, so check the recursion manager (it will
   668                             // throw an IOException if it doesn't have a
   669                             // reference, either).
   670                             objectValue = bridge.activeRecursionMgr.getObject(
   671                                 cdrie.offset);
   672                         } catch (IOException ie) {
   673                             // Translate to a MARSHAL exception since
   674                             // ValueHandlers aren't allowed to throw
   675                             // IOExceptions
   676                             throw utilWrapper.invalidIndirection( ie,
   677                                 new Integer( cdrie.offset ) ) ;
   678                         }
   679                     }
   681                     array[i] = objectValue;
   682                 }
   683                 return ((java.io.Serializable)((Object)array));
   684             } else {
   685                 Object[] array = (Object[])java.lang.reflect.Array.newInstance(
   686                     componentType, length);
   687                 // Store this object and its beginning position
   688                 // since there might be indirections to it while
   689                 // it's been unmarshalled.
   690                 bridge.activeRecursionMgr.addObject(offset, array);
   692                 // Decide what method call to make based on the componentType.
   693                 // If it is a componentType for which we need to load a stub,
   694                 // convert the componentType to the correct stub type.
   696                 int callType = kValueType;
   697                 boolean narrow = false;
   699                 if (componentType.isInterface()) {
   700                     boolean loadStubClass = false;
   701                     // String className = componentType.getName();
   703                     if (java.rmi.Remote.class.isAssignableFrom(componentType)) {
   705                         // RMI Object reference...
   706                         callType = kRemoteType;
   708                         // for better performance, load the stub class once
   709                         // instead of for each element of the array
   710                         loadStubClass = true;
   711                     } else if (org.omg.CORBA.Object.class.isAssignableFrom(componentType)){
   712                         // IDL Object reference...
   713                         callType = kRemoteType;
   714                         loadStubClass = true;
   715                     } else if (RepositoryId.isAbstractBase(componentType)) {
   716                         // IDL Abstract Object reference...
   717                         callType = kAbstractType;
   718                         loadStubClass = true;
   719                     } else if (ObjectStreamClassCorbaExt.isAbstractInterface(componentType)) {
   721                         // RMI Abstract Object reference...
   723                         // componentType = null;
   724                         callType = kAbstractType;
   725                     }
   727                     if (loadStubClass) {
   728                         try {
   729                             String codebase = Util.getCodebase(componentType);
   730                             String repID = RepositoryId.createForAnyType(componentType);
   731                             Class stubType =
   732                                 Utility.loadStubClass(repID, codebase, componentType);
   733                             actualType = stubType;
   734                         } catch (ClassNotFoundException e) {
   735                             narrow = true;
   736                         }
   737                     } else {
   738                         narrow = true;
   739                     }
   740                 }
   742                 for (i = 0; i < length; i++) {
   744                     try {
   745                         switch (callType) {
   746                         case kRemoteType:
   747                             if (!narrow)
   748                                 array[i] = (Object)in.read_Object(actualType);
   749                             else {
   750                                 array[i] = Utility.readObjectAndNarrow(in, actualType);
   752                             }
   753                             break;
   754                         case kAbstractType:
   755                             if (!narrow)
   756                                 array[i] = (Object)in.read_abstract_interface(actualType);
   757                             else {
   758                                 array[i] = Utility.readAbstractAndNarrow(in, actualType);
   759                             }
   760                             break;
   761                         case kValueType:
   762                             array[i] = (Object)in.read_value(actualType);
   763                             break;
   764                         }
   765                     } catch(IndirectionException cdrie) {
   766                         // The CDR stream had never seen the given offset before,
   767                         // so check the recursion manager (it will throw an
   768                         // IOException if it doesn't have a reference, either).
   769                         try {
   770                             array[i] = bridge.activeRecursionMgr.getObject(
   771                                 cdrie.offset);
   772                         } catch (IOException ioe) {
   773                             // Translate to a MARSHAL exception since
   774                             // ValueHandlers aren't allowed to throw
   775                             // IOExceptions
   776                             throw utilWrapper.invalidIndirection( ioe,
   777                                 new Integer( cdrie.offset ) ) ;
   778                         }
   779                     }
   781                 }
   783                 return ((java.io.Serializable)((Object)array));
   784             }
   785         } finally {
   786             // We've completed deserializing this object.  Any
   787             // future indirections will be handled correctly at the
   788             // CDR level.  The ActiveRecursionManager only deals with
   789             // objects currently being deserialized.
   790             bridge.activeRecursionMgr.removeObject(offset);
   791         }
   792     }
   794     private boolean isArray(String repId){
   795         return RepositoryId.cache.getId(repId).isSequence();
   796     }
   798     protected String getOutputStreamClassName() {
   799         return "com.sun.corba.se.impl.io.IIOPOutputStream";
   800     }
   802    private IIOPOutputStream createOutputStream() {
   803         final String name = getOutputStreamClassName();
   804         try {
   805              IIOPOutputStream stream = createOutputStreamBuiltIn(name);
   806              if (stream != null) {
   807                  return stream;
   808              }
   809              return createCustom(IIOPOutputStream.class, name);
   810         } catch (Throwable t) {
   811             // Throw exception under the carpet.
   812             InternalError ie = new InternalError(
   813                 "Error loading " + name
   814             );
   815                 ie.initCause(t);
   816                 throw ie;
   817         }
   818     }
   820     /**
   821      * Construct a built in implementation with priveleges.
   822      * Returning null indicates a non-built is specified.
   823      */
   824     private IIOPOutputStream createOutputStreamBuiltIn(
   825         final String name
   826     ) throws Throwable {
   827         try {
   828             return AccessController.doPrivileged(
   829                 new PrivilegedExceptionAction<IIOPOutputStream>() {
   830                     public IIOPOutputStream run() throws IOException {
   831                         return createOutputStreamBuiltInNoPriv(name);
   832                     }
   833                 }
   834             );
   835         } catch (java.security.PrivilegedActionException exc) {
   836             throw exc.getCause();
   837         }
   838     }
   840     /**
   841      * Returning null indicates a non-built is specified.
   842      */
   843     private IIOPOutputStream createOutputStreamBuiltInNoPriv(
   844         final String name
   845     ) throws IOException {
   846         return
   847             name.equals(
   848                 IIOPOutputStream
   849                     .class.getName()
   850             ) ?
   851             new IIOPOutputStream() :
   853             name.equals(
   854                 com.sun.corba.se.impl.orbutil.IIOPOutputStream_1_3
   855                     .class.getName()
   856             ) ?
   857             new com.sun.corba.se.impl.orbutil.IIOPOutputStream_1_3() :
   859             name.equals(
   860                 com.sun.corba.se.impl.orbutil.IIOPOutputStream_1_3_1
   861                     .class.getName()
   862             ) ?
   863             new com.sun.corba.se.impl.orbutil.IIOPOutputStream_1_3_1() :
   865             null;
   866     }
   868     protected String getInputStreamClassName() {
   869         return "com.sun.corba.se.impl.io.IIOPInputStream";
   870     }
   872     private IIOPInputStream createInputStream() {
   873         final String name = getInputStreamClassName();
   874         try {
   875              IIOPInputStream stream = createInputStreamBuiltIn(name);
   876              if (stream != null) {
   877                  return stream;
   878              }
   879              return createCustom(IIOPInputStream.class, name);
   880         } catch (Throwable t) {
   881             // Throw exception under the carpet.
   882             InternalError ie = new InternalError(
   883                 "Error loading " + name
   884             );
   885                 ie.initCause(t);
   886                 throw ie;
   887         }
   888     }
   890     /**
   891      * Construct a built in implementation with priveleges.
   892      * Returning null indicates a non-built is specified.
   893      */
   894      private IIOPInputStream createInputStreamBuiltIn(
   895          final String name
   896      ) throws Throwable {
   897          try {
   898              return AccessController.doPrivileged(
   899                  new PrivilegedExceptionAction<IIOPInputStream>() {
   900                      public IIOPInputStream run() throws IOException {
   901                          return createInputStreamBuiltInNoPriv(name);
   902                      }
   903                  }
   904              );
   905          } catch (java.security.PrivilegedActionException exc) {
   906              throw exc.getCause();
   907          }
   908      }
   910      /**
   911       * Returning null indicates a non-built is specified.
   912       */
   913      private IIOPInputStream createInputStreamBuiltInNoPriv(
   914          final String name
   915      ) throws IOException {
   916          return
   917              name.equals(
   918                  IIOPInputStream
   919                      .class.getName()
   920              ) ?
   921              new IIOPInputStream() :
   923              name.equals(
   924                  com.sun.corba.se.impl.orbutil.IIOPInputStream_1_3
   925                      .class.getName()
   926              ) ?
   927              new com.sun.corba.se.impl.orbutil.IIOPInputStream_1_3() :
   929              name.equals(
   930                  com.sun.corba.se.impl.orbutil.IIOPInputStream_1_3_1
   931                      .class.getName()
   932              ) ?
   933              new com.sun.corba.se.impl.orbutil.IIOPInputStream_1_3_1() :
   935              null;
   936      }
   938      /**
   939       * Create a custom implementation without privileges.
   940       */
   941      private <T> T createCustom(
   942          final Class<T> type, final String className
   943      ) throws Throwable {
   944            // Note: We use the thread context or system ClassLoader here
   945            // since we want to load classes outside of the
   946            // core JDK when running J2EE Pure ORB and
   947            // talking to Kestrel.
   948                 ClassLoader cl = Thread.currentThread().getContextClassLoader();
   949                 if (cl == null)
   950                     cl = ClassLoader.getSystemClassLoader();
   952                 Class<?> clazz = cl.loadClass(className);
   953                 Class<? extends T> streamClass = clazz.asSubclass(type);
   955                 // Since the ClassLoader should cache the class, this isn't
   956                 // as expensive as it looks.
   957                 return streamClass.newInstance();
   959     }
   961     /**
   962      * Our JDK 1.3 and JDK 1.3.1 behavior subclasses override this.
   963      * The correct behavior is for a Java char to map to a CORBA wchar,
   964      * but our older code mapped it to a CORBA char.
   965      */
   966     protected TCKind getJavaCharTCKind() {
   967         return TCKind.tk_wchar;
   968     }
   969 }

mercurial