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