src/share/classes/com/sun/corba/se/impl/orbutil/RepositoryId_1_3_1.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 371
e324dfb90c9e
permissions
-rw-r--r--

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

duke@1 1 /*
ohair@158 2 * Copyright (c) 2001, 2002, 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 /*
duke@1 27 */
duke@1 28 package com.sun.corba.se.impl.orbutil;
duke@1 29
duke@1 30 import java.util.StringTokenizer;
duke@1 31 import java.util.Hashtable;
duke@1 32 import java.io.IOException;
duke@1 33 import java.lang.reflect.Method;
duke@1 34 import java.net.MalformedURLException;
duke@1 35 import org.omg.CORBA.portable.ValueBase;
duke@1 36 import org.omg.CORBA.portable.IDLEntity;
duke@1 37
duke@1 38 //d11638 files in the same package, therefore remove their reference
duke@1 39 //import com.sun.corba.se.impl.util.JDKBridge;
duke@1 40 //import com.sun.corba.se.impl.util.IdentityHashtable;
duke@1 41 import com.sun.corba.se.impl.util.JDKBridge;
duke@1 42 import com.sun.corba.se.impl.util.Utility;
duke@1 43 import com.sun.corba.se.impl.util.PackagePrefixChecker;
duke@1 44 import com.sun.corba.se.impl.util.IdentityHashtable;
duke@1 45
duke@1 46 import javax.rmi.CORBA.Util;
duke@1 47
duke@1 48 /**
duke@1 49 * Because all methods in RepositoryId are static, we have
duke@1 50 * to duplicate all of this code, freezing it in its 1.3.1
duke@1 51 * form for backwards compatibility.
duke@1 52 *
duke@1 53 * For security reasons, we can't expose enough of
duke@1 54 * io/ObjectStreamClass, so it has to be duplicated in
duke@1 55 * orbutil.
duke@1 56 */
duke@1 57 public class RepositoryId_1_3_1 {
duke@1 58
duke@1 59 // Legal IDL Identifier characters (1 = legal). Note
duke@1 60 // that '.' (2E) is marked as legal even though it is
duke@1 61 // not legal in IDL. This allows us to treat a fully
duke@1 62 // qualified Java name with '.' package separators
duke@1 63 // uniformly, and is safe because that is the only
duke@1 64 // legal use of '.' in a Java name.
duke@1 65
duke@1 66 public static final byte[] IDL_IDENTIFIER_CHARS = {
duke@1 67
duke@1 68 // 0 1 2 3 4 5 6 7 8 9 a b c d e f
duke@1 69 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, // 00-0f
duke@1 70 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, // 10-1f
duke@1 71 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,1,0, // 20-2f
duke@1 72 1,1,1,1, 1,1,1,1, 1,1,0,0, 0,0,0,0, // 30-3f
duke@1 73 0,1,1,1, 1,1,1,1, 1,1,1,1, 1,1,1,1, // 40-4f
duke@1 74 1,1,1,1, 1,1,1,1, 1,1,1,0, 0,0,0,1, // 50-5f
duke@1 75 0,1,1,1, 1,1,1,1, 1,1,1,1, 1,1,1,1, // 60-6f
duke@1 76 1,1,1,1, 1,1,1,1, 1,1,1,0, 0,0,0,0, // 70-7f
duke@1 77 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, // 80-8f
duke@1 78 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, // 90-9f
duke@1 79 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, // a0-af
duke@1 80 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, // b0-bf
duke@1 81 1,1,1,1, 1,1,1,1, 1,1,1,1, 1,1,1,1, // c0-cf
duke@1 82 0,1,1,1, 1,1,1,0, 1,1,1,1, 1,0,0,1, // d0-df
duke@1 83 1,1,1,1, 1,1,1,1, 1,1,1,1, 1,1,1,1, // e0-ef
duke@1 84 0,1,1,1, 1,1,1,0, 1,1,1,1, 1,0,0,1, // f0-ff
duke@1 85 };
duke@1 86
duke@1 87
duke@1 88 private static final long serialVersionUID = 123456789L;
duke@1 89
duke@1 90 private static String defaultServerURL = null;
duke@1 91 private static boolean useCodebaseOnly = false;
duke@1 92
duke@1 93 static {
duke@1 94 if (defaultServerURL == null)
duke@1 95 defaultServerURL = (String)JDKBridge.getLocalCodebase();
duke@1 96 useCodebaseOnly = JDKBridge.useCodebaseOnly();
duke@1 97
duke@1 98 }
duke@1 99
duke@1 100 private static IdentityHashtable classToRepStr = new IdentityHashtable();
duke@1 101 private static IdentityHashtable classIDLToRepStr = new IdentityHashtable();
duke@1 102 private static IdentityHashtable classSeqToRepStr = new IdentityHashtable();
duke@1 103
duke@1 104 private static IdentityHashtable repStrToByteArray = new IdentityHashtable();
duke@1 105 private static Hashtable repStrToClass = new Hashtable();
duke@1 106
duke@1 107 private String repId = null;
duke@1 108 private boolean isSupportedFormat = true;
duke@1 109 private String typeString = null;
duke@1 110 private String versionString = null;
duke@1 111 private boolean isSequence = false;
duke@1 112 private boolean isRMIValueType = false;
duke@1 113 private boolean isIDLType = false;
duke@1 114 private String completeClassName = null;
duke@1 115 private String unqualifiedName = null;
duke@1 116 private String definedInId = null;
duke@1 117 private Class clazz = null;
duke@1 118 private String suid = null, actualSuid = null;
duke@1 119 private long suidLong = ObjectStreamClass_1_3_1.kDefaultUID, actualSuidLong = ObjectStreamClass_1_3_1.kDefaultUID;
duke@1 120
duke@1 121 // Repository ID fragments
duke@1 122 private static final String kSequenceKeyword = "seq";
duke@1 123 private static final String kValuePrefix = "RMI:";
duke@1 124 private static final String kIDLPrefix = "IDL:";
duke@1 125 private static final String kIDLNamePrefix = "omg.org/";
duke@1 126 private static final String kIDLClassnamePrefix = "org.omg.";
duke@1 127 private static final String kSequencePrefix = "[";
duke@1 128 private static final String kCORBAPrefix = "CORBA/";
duke@1 129 private static final String kArrayPrefix = kValuePrefix + kSequencePrefix + kCORBAPrefix;
duke@1 130 private static final int kValuePrefixLength = kValuePrefix.length();
duke@1 131 private static final int kIDLPrefixLength = kIDLPrefix.length();
duke@1 132 private static final int kSequencePrefixLength = kSequencePrefix.length();
duke@1 133 private static final String kInterfaceHashCode = ":0000000000000000";
duke@1 134 private static final String kInterfaceOnlyHashStr = "0000000000000000";
duke@1 135 private static final String kExternalizableHashStr = "0000000000000001";
duke@1 136
duke@1 137 // Value tag utility methods and constants
duke@1 138 public static final int kInitialValueTag= 0x7fffff00;
duke@1 139 public static final int kNoTypeInfo = 0;
duke@1 140 public static final int kSingleRepTypeInfo = 0x02;
duke@1 141 public static final int kPartialListTypeInfo = 0x06;
duke@1 142 public static final int kChunkedMask = 0x08;
duke@1 143 public static final int kPreComputed_StandardRMIUnchunked = RepositoryId_1_3_1.computeValueTag(false, RepositoryId_1_3_1.kSingleRepTypeInfo, false);
duke@1 144 public static final int kPreComputed_CodeBaseRMIUnchunked = RepositoryId_1_3_1.computeValueTag(true, RepositoryId_1_3_1.kSingleRepTypeInfo, false);
duke@1 145 public static final int kPreComputed_StandardRMIChunked = RepositoryId_1_3_1.computeValueTag(false, RepositoryId_1_3_1.kSingleRepTypeInfo, true);
duke@1 146 public static final int kPreComputed_CodeBaseRMIChunked = RepositoryId_1_3_1.computeValueTag(true, RepositoryId_1_3_1.kSingleRepTypeInfo, true);
duke@1 147
duke@1 148 public static final int kPreComputed_StandardRMIUnchunked_NoRep = RepositoryId_1_3_1.computeValueTag(false, RepositoryId_1_3_1.kNoTypeInfo, false);
duke@1 149 public static final int kPreComputed_CodeBaseRMIUnchunked_NoRep = RepositoryId_1_3_1.computeValueTag(true, RepositoryId_1_3_1.kNoTypeInfo, false);
duke@1 150 public static final int kPreComputed_StandardRMIChunked_NoRep = RepositoryId_1_3_1.computeValueTag(false, RepositoryId_1_3_1.kNoTypeInfo, true);
duke@1 151 public static final int kPreComputed_CodeBaseRMIChunked_NoRep = RepositoryId_1_3_1.computeValueTag(true, RepositoryId_1_3_1.kNoTypeInfo, true);
duke@1 152
duke@1 153 // Public, well known repository IDs
duke@1 154
duke@1 155 // _REVISIT_ : A table structure with a good search routine for all of this
duke@1 156 // would be more efficient and easier to maintain...
duke@1 157
duke@1 158 // String
duke@1 159 public static final String kWStringValueVersion = "1.0";
duke@1 160 public static final String kWStringValueHash = ":"+kWStringValueVersion;
duke@1 161 public static final String kWStringStubValue = "WStringValue";
duke@1 162 public static final String kWStringTypeStr = "omg.org/CORBA/"+kWStringStubValue;
duke@1 163 public static final String kWStringValueRepID = kIDLPrefix + kWStringTypeStr + kWStringValueHash;
duke@1 164
duke@1 165 // Any
duke@1 166 public static final String kAnyRepID = kIDLPrefix + "omg.org/CORBA/Any";
duke@1 167
duke@1 168 // Class
duke@1 169 // Anita4: convert to uppercase
duke@1 170 public static final String kClassDescValueHash = ":" +
duke@1 171 Long.toHexString(
duke@1 172 ObjectStreamClass_1_3_1.getActualSerialVersionUID(javax.rmi.CORBA.ClassDesc.class)).toUpperCase() + ":" +
duke@1 173 Long.toHexString(
duke@1 174 ObjectStreamClass_1_3_1.getSerialVersionUID(javax.rmi.CORBA.ClassDesc.class)).toUpperCase();
duke@1 175 public static final String kClassDescStubValue = "ClassDesc";
duke@1 176 public static final String kClassDescTypeStr = "javax.rmi.CORBA."+kClassDescStubValue;
duke@1 177 public static final String kClassDescValueRepID = kValuePrefix + kClassDescTypeStr + kClassDescValueHash;
duke@1 178
duke@1 179 // Object
duke@1 180 public static final String kObjectValueHash = ":1.0";
duke@1 181 public static final String kObjectStubValue = "Object";
duke@1 182
duke@1 183 // Sequence
duke@1 184 public static final String kSequenceValueHash = ":1.0";
duke@1 185 public static final String kPrimitiveSequenceValueHash = ":0000000000000000";
duke@1 186
duke@1 187 // Serializable
duke@1 188 public static final String kSerializableValueHash = ":1.0";
duke@1 189 public static final String kSerializableStubValue = "Serializable";
duke@1 190
duke@1 191 // Externalizable
duke@1 192 public static final String kExternalizableValueHash = ":1.0";
duke@1 193 public static final String kExternalizableStubValue = "Externalizable";
duke@1 194
duke@1 195 // Remote (The empty string is used for java.rmi.Remote)
duke@1 196 public static final String kRemoteValueHash = "";
duke@1 197 public static final String kRemoteStubValue = "";
duke@1 198 public static final String kRemoteTypeStr = "";
duke@1 199 public static final String kRemoteValueRepID = "";
duke@1 200
duke@1 201 public static final Hashtable kSpecialArrayTypeStrings = new Hashtable();
duke@1 202
duke@1 203 static {
duke@1 204 kSpecialArrayTypeStrings.put("CORBA.WStringValue", new StringBuffer(java.lang.String.class.getName()));
duke@1 205 kSpecialArrayTypeStrings.put("javax.rmi.CORBA.ClassDesc", new StringBuffer(java.lang.Class.class.getName()));
duke@1 206 kSpecialArrayTypeStrings.put("CORBA.Object", new StringBuffer(java.rmi.Remote.class.getName()));
duke@1 207
duke@1 208 }
duke@1 209
duke@1 210 public static final Hashtable kSpecialCasesRepIDs = new Hashtable();
duke@1 211
duke@1 212 static {
duke@1 213 kSpecialCasesRepIDs.put(java.lang.String.class, kWStringValueRepID);
duke@1 214 kSpecialCasesRepIDs.put(java.lang.Class.class, kClassDescValueRepID);
duke@1 215 kSpecialCasesRepIDs.put(java.rmi.Remote.class, kRemoteValueRepID);
duke@1 216 }
duke@1 217
duke@1 218 public static final Hashtable kSpecialCasesStubValues = new Hashtable();
duke@1 219
duke@1 220 static {
duke@1 221 kSpecialCasesStubValues.put(java.lang.String.class, kWStringStubValue);
duke@1 222 kSpecialCasesStubValues.put(java.lang.Class.class, kClassDescStubValue);
duke@1 223 kSpecialCasesStubValues.put(java.lang.Object.class, kObjectStubValue);
duke@1 224 kSpecialCasesStubValues.put(java.io.Serializable.class, kSerializableStubValue);
duke@1 225 kSpecialCasesStubValues.put(java.io.Externalizable.class, kExternalizableStubValue);
duke@1 226 kSpecialCasesStubValues.put(java.rmi.Remote.class, kRemoteStubValue);
duke@1 227 }
duke@1 228
duke@1 229
duke@1 230 public static final Hashtable kSpecialCasesVersions = new Hashtable();
duke@1 231
duke@1 232 static {
duke@1 233 kSpecialCasesVersions.put(java.lang.String.class, kWStringValueHash);
duke@1 234 kSpecialCasesVersions.put(java.lang.Class.class, kClassDescValueHash);
duke@1 235 kSpecialCasesVersions.put(java.lang.Object.class, kObjectValueHash);
duke@1 236 kSpecialCasesVersions.put(java.io.Serializable.class, kSerializableValueHash);
duke@1 237 kSpecialCasesVersions.put(java.io.Externalizable.class, kExternalizableValueHash);
duke@1 238 kSpecialCasesVersions.put(java.rmi.Remote.class, kRemoteValueHash);
duke@1 239 }
duke@1 240
duke@1 241 public static final Hashtable kSpecialCasesClasses = new Hashtable();
duke@1 242
duke@1 243 static {
duke@1 244 kSpecialCasesClasses.put(kWStringTypeStr, java.lang.String.class);
duke@1 245 kSpecialCasesClasses.put(kClassDescTypeStr, java.lang.Class.class);
duke@1 246 kSpecialCasesClasses.put(kRemoteTypeStr, java.rmi.Remote.class);
duke@1 247
duke@1 248 kSpecialCasesClasses.put("org.omg.CORBA.WStringValue", java.lang.String.class);
duke@1 249 kSpecialCasesClasses.put("javax.rmi.CORBA.ClassDesc", java.lang.Class.class);
duke@1 250 //kSpecialCasesClasses.put(kRemoteTypeStr, java.rmi.Remote.class);
duke@1 251 }
duke@1 252
duke@1 253 public static final Hashtable kSpecialCasesArrayPrefix = new Hashtable();
duke@1 254
duke@1 255 static {
duke@1 256 kSpecialCasesArrayPrefix.put(java.lang.String.class, kValuePrefix + kSequencePrefix + kCORBAPrefix);
duke@1 257 kSpecialCasesArrayPrefix.put(java.lang.Class.class, kValuePrefix + kSequencePrefix + "javax/rmi/CORBA/");
duke@1 258 kSpecialCasesArrayPrefix.put(java.lang.Object.class, kValuePrefix + kSequencePrefix + "java/lang/");
duke@1 259 kSpecialCasesArrayPrefix.put(java.io.Serializable.class, kValuePrefix + kSequencePrefix + "java/io/");
duke@1 260 kSpecialCasesArrayPrefix.put(java.io.Externalizable.class, kValuePrefix + kSequencePrefix + "java/io/");
duke@1 261 kSpecialCasesArrayPrefix.put(java.rmi.Remote.class, kValuePrefix + kSequencePrefix + kCORBAPrefix);
duke@1 262 }
duke@1 263
duke@1 264 public static final Hashtable kSpecialPrimitives = new Hashtable();
duke@1 265
duke@1 266 static {
duke@1 267 kSpecialPrimitives.put("int","long");
duke@1 268 kSpecialPrimitives.put("long","longlong");
duke@1 269 kSpecialPrimitives.put("byte","octet");
duke@1 270 }
duke@1 271
duke@1 272 /**
duke@1 273 * Used to convert ascii to hex.
duke@1 274 */
duke@1 275 private static final byte ASCII_HEX[] = {
duke@1 276 (byte)'0',
duke@1 277 (byte)'1',
duke@1 278 (byte)'2',
duke@1 279 (byte)'3',
duke@1 280 (byte)'4',
duke@1 281 (byte)'5',
duke@1 282 (byte)'6',
duke@1 283 (byte)'7',
duke@1 284 (byte)'8',
duke@1 285 (byte)'9',
duke@1 286 (byte)'A',
duke@1 287 (byte)'B',
duke@1 288 (byte)'C',
duke@1 289 (byte)'D',
duke@1 290 (byte)'E',
duke@1 291 (byte)'F',
duke@1 292 };
duke@1 293
duke@1 294
duke@1 295 // bug fix for 4328952; to eliminate possibility of overriding this
duke@1 296 // in a subclass.
duke@1 297 public static final RepositoryIdCache_1_3_1 cache = new RepositoryIdCache_1_3_1();
duke@1 298
duke@1 299 // Interface Rep ID Strings
duke@1 300 public static final String kjava_rmi_Remote = createForAnyType(java.rmi.Remote.class);
duke@1 301 public static final String korg_omg_CORBA_Object = createForAnyType(org.omg.CORBA.Object.class);
duke@1 302
duke@1 303 // Dummy arguments for getIdFromHelper method
duke@1 304 public static final Class kNoParamTypes[] ={};
duke@1 305 public static final Object kNoArgs[] = {};
duke@1 306
duke@1 307
duke@1 308 // To create a RepositoryID, use code similar to the following:
duke@1 309 // RepositoryId.cache.getId( id );
duke@1 310
duke@1 311 RepositoryId_1_3_1(){}
duke@1 312
duke@1 313 RepositoryId_1_3_1(String aRepId){
duke@1 314 init(aRepId);
duke@1 315 }
duke@1 316
duke@1 317 RepositoryId_1_3_1 init(String aRepId){
duke@1 318
duke@1 319 this.repId = aRepId;
duke@1 320
duke@1 321 // Special case for remote
duke@1 322 if (aRepId.length() == 0) {
duke@1 323 clazz = java.rmi.Remote.class;
duke@1 324 typeString = "";
duke@1 325 isRMIValueType = true;
duke@1 326 suid = kInterfaceOnlyHashStr;
duke@1 327 return this;
duke@1 328 }
duke@1 329 else if (aRepId.equals(kWStringValueRepID)) {
duke@1 330 clazz = java.lang.String.class;
duke@1 331 typeString = kWStringTypeStr;
duke@1 332 isIDLType = true;
duke@1 333 // fix where Attempting to obtain a FullValueDescription
duke@1 334 // for an RMI value type with a String field causes an exception.
duke@1 335 completeClassName = "java.lang.String";
duke@1 336 versionString = kWStringValueVersion;
duke@1 337 return this;
duke@1 338 }
duke@1 339 else {
duke@1 340
duke@1 341 String repId = convertFromISOLatin1(aRepId);
duke@1 342
duke@1 343 versionString = repId.substring(repId.indexOf(':', repId.indexOf(':')+1));
duke@1 344 if (repId.startsWith(kIDLPrefix)) {
duke@1 345 typeString =
duke@1 346 repId.substring(kIDLPrefixLength, repId.indexOf(':', kIDLPrefixLength));
duke@1 347 isIDLType = true;
duke@1 348 if (typeString.startsWith(kIDLNamePrefix))
duke@1 349 completeClassName = kIDLClassnamePrefix +
duke@1 350 typeString.substring(kIDLNamePrefix.length()).replace('/','.');
duke@1 351 else completeClassName = typeString.replace('/','.');
duke@1 352
duke@1 353 }
duke@1 354 else if (repId.startsWith(kValuePrefix)) {
duke@1 355 typeString =
duke@1 356 repId.substring(kValuePrefixLength, repId.indexOf(':', kValuePrefixLength));
duke@1 357 isRMIValueType = true;
duke@1 358
duke@1 359 if (versionString.indexOf('.') == -1) {
duke@1 360 actualSuid = versionString.substring(1);
duke@1 361 suid = actualSuid; // default if not explicitly specified
duke@1 362
duke@1 363 if (actualSuid.indexOf(':') != -1){
duke@1 364 // we have a declared hash also
duke@1 365 int pos = actualSuid.indexOf(':')+1;
duke@1 366 // actualSuid = suid.substring(pos);
duke@1 367 // suid = suid.substring(0, pos-1);
duke@1 368 suid = actualSuid.substring(pos);
duke@1 369 actualSuid = actualSuid.substring(0, pos-1);
duke@1 370 }
duke@1 371
duke@1 372 }
duke@1 373 else {
duke@1 374 // _REVISIT_ : Special case version failure ?
duke@1 375 }
duke@1 376 }
duke@1 377 else isSupportedFormat = false;
duke@1 378
duke@1 379 if (typeString.startsWith(kSequencePrefix)) {
duke@1 380 isSequence = true;
duke@1 381 }
duke@1 382
duke@1 383
duke@1 384 return this;
duke@1 385 }
duke@1 386 }
duke@1 387
duke@1 388 public final String getUnqualifiedName() {
duke@1 389 if (unqualifiedName == null){
duke@1 390 String className = getClassName();
duke@1 391 int index = className.lastIndexOf('.');
duke@1 392 if (index == -1){
duke@1 393 unqualifiedName = className;
duke@1 394 definedInId = "IDL::1.0";
duke@1 395 }
duke@1 396 else {
duke@1 397 unqualifiedName = className.substring(index);
duke@1 398 definedInId = "IDL:" + className.substring(0, index).replace('.','/') + ":1.0";
duke@1 399 }
duke@1 400 }
duke@1 401
duke@1 402 return unqualifiedName;
duke@1 403 }
duke@1 404
duke@1 405 public final String getDefinedInId() {
duke@1 406 if (definedInId == null){
duke@1 407 getUnqualifiedName();
duke@1 408 }
duke@1 409
duke@1 410 return definedInId;
duke@1 411 }
duke@1 412
duke@1 413 public final String getTypeString() {
duke@1 414 return typeString;
duke@1 415 }
duke@1 416
duke@1 417 public final String getVersionString() {
duke@1 418 return versionString;
duke@1 419 }
duke@1 420
duke@1 421 public final String getSerialVersionUID() {
duke@1 422 return suid;
duke@1 423 }
duke@1 424
duke@1 425 public final String getActualSerialVersionUID() {
duke@1 426 return actualSuid;
duke@1 427 }
duke@1 428 public final long getSerialVersionUIDAsLong() {
duke@1 429 return suidLong;
duke@1 430 }
duke@1 431
duke@1 432 public final long getActualSerialVersionUIDAsLong() {
duke@1 433 return actualSuidLong;
duke@1 434 }
duke@1 435
duke@1 436 public final boolean isRMIValueType() {
duke@1 437 return isRMIValueType;
duke@1 438 }
duke@1 439
duke@1 440 public final boolean isIDLType() {
duke@1 441 return isIDLType;
duke@1 442 }
duke@1 443
duke@1 444 public final String getRepositoryId() {
duke@1 445 return repId;
duke@1 446 }
duke@1 447
duke@1 448 public static byte[] getByteArray(String repStr) {
duke@1 449 synchronized (repStrToByteArray){
duke@1 450 return (byte[]) repStrToByteArray.get(repStr);
duke@1 451 }
duke@1 452 }
duke@1 453
duke@1 454 public static void setByteArray(String repStr, byte[] repStrBytes) {
duke@1 455 synchronized (repStrToByteArray){
duke@1 456 repStrToByteArray.put(repStr, repStrBytes);
duke@1 457 }
duke@1 458 }
duke@1 459
duke@1 460 public final boolean isSequence() {
duke@1 461 return isSequence;
duke@1 462 }
duke@1 463
duke@1 464 public final boolean isSupportedFormat() {
duke@1 465 return isSupportedFormat;
duke@1 466 }
duke@1 467
duke@1 468
duke@1 469 // This method will return the classname from the typestring OR if the classname turns out to be
duke@1 470 // a special class "pseudo" name, then the matching real classname is returned.
duke@1 471 public final String getClassName() {
duke@1 472
duke@1 473 if (isRMIValueType)
duke@1 474 return typeString;
duke@1 475 else if (isIDLType)
duke@1 476 return completeClassName;
duke@1 477 else return null;
duke@1 478
duke@1 479 }
duke@1 480
duke@1 481 // This method calls getClazzFromType() and falls back to the repStrToClass
duke@1 482 // cache if no class was found. It's used where any class matching the
duke@1 483 // given repid is an acceptable result.
duke@1 484 public final Class getAnyClassFromType() throws ClassNotFoundException {
duke@1 485 try {
duke@1 486 return getClassFromType();
duke@1 487 } catch (ClassNotFoundException cnfe) {
duke@1 488 Class clz = (Class)repStrToClass.get(repId);
duke@1 489 if (clz != null)
duke@1 490 return clz;
duke@1 491 else
duke@1 492 throw cnfe;
duke@1 493 }
duke@1 494 }
duke@1 495
duke@1 496 public final Class getClassFromType()
duke@1 497 throws ClassNotFoundException {
duke@1 498 if (clazz != null)
duke@1 499 return clazz;
duke@1 500
duke@1 501 Class specialCase = (Class)kSpecialCasesClasses.get(getClassName());
duke@1 502
duke@1 503 if (specialCase != null){
duke@1 504 clazz = specialCase;
duke@1 505 return specialCase;
duke@1 506 }
duke@1 507 else
duke@1 508 {
duke@1 509 try{
duke@1 510 return Util.loadClass(getClassName(), null, null);
duke@1 511 }
duke@1 512 catch(ClassNotFoundException cnfe){
duke@1 513 if (defaultServerURL != null) {
duke@1 514 try{
duke@1 515 return getClassFromType(defaultServerURL);
duke@1 516 }
duke@1 517 catch(MalformedURLException mue){
duke@1 518 throw cnfe;
duke@1 519 }
duke@1 520 }
duke@1 521 else throw cnfe;
duke@1 522 }
duke@1 523 }
duke@1 524
duke@1 525 }
duke@1 526
duke@1 527 public final Class getClassFromType(Class expectedType, String codebase)
duke@1 528 throws ClassNotFoundException {
duke@1 529 if (clazz != null)
duke@1 530 return clazz;
duke@1 531
duke@1 532 Class specialCase = (Class)kSpecialCasesClasses.get(getClassName());
duke@1 533
duke@1 534 if (specialCase != null){
duke@1 535 clazz = specialCase;
duke@1 536 return specialCase;
duke@1 537 } else {
duke@1 538 ClassLoader expectedTypeClassLoader = (expectedType == null ? null : expectedType.getClassLoader());
duke@1 539 return loadClassOfType(getClassName(),
duke@1 540 codebase,
duke@1 541 expectedTypeClassLoader,
duke@1 542 expectedType,
duke@1 543 expectedTypeClassLoader);
duke@1 544 }
duke@1 545
duke@1 546 }
duke@1 547
duke@1 548 public final Class getClassFromType(String url)
duke@1 549 throws ClassNotFoundException, MalformedURLException {
duke@1 550 return Util.loadClass(getClassName(), url, null);
duke@1 551 }
duke@1 552
duke@1 553 public final String toString() {
duke@1 554 return repId;
duke@1 555 }
duke@1 556
duke@1 557 /**
duke@1 558 * Checks to see if the FullValueDescription should be retrieved.
duke@1 559 * @exception Throws IOException if suids do not match or if the repositoryID
duke@1 560 * is not an RMIValueType
duke@1 561 */
duke@1 562 public static boolean useFullValueDescription(Class clazz, String repositoryID)
duke@1 563 throws IOException{
duke@1 564
duke@1 565 String clazzRepIDStr = createForAnyType(clazz);
duke@1 566
duke@1 567 if (clazzRepIDStr.equals(repositoryID))
duke@1 568 return false;
duke@1 569
duke@1 570 RepositoryId_1_3_1 targetRepid;
duke@1 571 RepositoryId_1_3_1 clazzRepid;
duke@1 572
duke@1 573 synchronized(cache) {
duke@1 574 // to avoid race condition where multiple threads could be
duke@1 575 // accessing this method, and their access to the cache may
duke@1 576 // be interleaved giving unexpected results
duke@1 577
duke@1 578 targetRepid = cache.getId(repositoryID);
duke@1 579 clazzRepid = cache.getId(clazzRepIDStr);
duke@1 580 }
duke@1 581 //ObjectStreamClass osc = ObjectStreamClass.lookup(clazz);
duke@1 582
duke@1 583 if ((targetRepid.isRMIValueType()) && (clazzRepid.isRMIValueType())){
duke@1 584 if (!targetRepid.getSerialVersionUID().equals(clazzRepid.getSerialVersionUID())) {
duke@1 585
duke@1 586 String mssg = "Mismatched serialization UIDs : Source (Rep. ID" +
duke@1 587 clazzRepid + ") = " +
duke@1 588 clazzRepid.getSerialVersionUID() + " whereas Target (Rep. ID " + repositoryID +
duke@1 589 ") = " + targetRepid.getSerialVersionUID();
duke@1 590 //com.sun.corba.se.impl.io.ValueUtility.log("RepositoryId",mssg);
duke@1 591 throw new IOException(mssg);
duke@1 592 }
duke@1 593 else {
duke@1 594 return true;
duke@1 595 }
duke@1 596 }
duke@1 597 else {
duke@1 598
duke@1 599 throw new IOException("The repository ID is not of an RMI value type (Expected ID = " + clazzRepIDStr + "; Received ID = " + repositoryID +")");
duke@1 600 }
duke@1 601 }
duke@1 602
duke@1 603 private static String createHashString(java.io.Serializable ser) {
duke@1 604
duke@1 605 return createHashString(ser.getClass());
duke@1 606 }
duke@1 607
duke@1 608 private static String createHashString(java.lang.Class clazz) {
duke@1 609
duke@1 610 if (clazz.isInterface() || !java.io.Serializable.class.isAssignableFrom(clazz))
duke@1 611 return kInterfaceHashCode;
duke@1 612
duke@1 613 //ObjectStreamClass osc = ObjectStreamClass.lookup(clazz);
duke@1 614
duke@1 615 long actualLong = ObjectStreamClass_1_3_1.getActualSerialVersionUID(clazz);
duke@1 616 String hash = null;
duke@1 617 if (actualLong == 0)
duke@1 618 hash = kInterfaceOnlyHashStr;
duke@1 619 else if (actualLong == 1)
duke@1 620 hash = kExternalizableHashStr;
duke@1 621 else
duke@1 622 hash = Long.toHexString(actualLong).toUpperCase();
duke@1 623 while(hash.length() < 16){
duke@1 624 hash = "0" + hash;
duke@1 625 }
duke@1 626
duke@1 627 long declaredLong = ObjectStreamClass_1_3_1.getSerialVersionUID(clazz);
duke@1 628 String declared = null;
duke@1 629 if (declaredLong == 0)
duke@1 630 declared = kInterfaceOnlyHashStr;
duke@1 631 else if (declaredLong == 1)
duke@1 632 declared = kExternalizableHashStr;
duke@1 633 else
duke@1 634 declared = Long.toHexString(declaredLong).toUpperCase();
duke@1 635 while (declared.length() < 16){
duke@1 636 declared = "0" + declared;
duke@1 637 }
duke@1 638 hash = hash + ":" + declared;
duke@1 639
duke@1 640 return ":" + hash;
duke@1 641 }
duke@1 642
duke@1 643 /**
duke@1 644 * Creates a repository ID for a sequence. This is for expert users only as
duke@1 645 * this method assumes the object passed is an array. If passed an object
duke@1 646 * that is not an array, it will produce a rep id for a sequence of zero
duke@1 647 * length. This would be an error.
duke@1 648 * @param ser The Java object to create a repository ID for
duke@1 649 **/
duke@1 650 public static String createSequenceRepID(java.lang.Object ser){
duke@1 651 return createSequenceRepID(ser.getClass());
duke@1 652 }
duke@1 653
duke@1 654 /**
duke@1 655 * Creates a repository ID for a sequence. This is for expert users only as
duke@1 656 * this method assumes the object passed is an array. If passed an object
duke@1 657 * that is not an array, it will produce a malformed rep id.
duke@1 658 * @param clazz The Java class to create a repository ID for
duke@1 659 **/
duke@1 660 public static String createSequenceRepID(java.lang.Class clazz){
duke@1 661 synchronized (classSeqToRepStr){
duke@1 662
duke@1 663 String repid = (String)classSeqToRepStr.get(clazz);
duke@1 664 if (repid != null)
duke@1 665 return repid;
duke@1 666
duke@1 667 Class originalClazz = clazz;
duke@1 668
duke@1 669 Class type = null;
duke@1 670 int numOfDims = 0;
duke@1 671
duke@1 672 while ((type = clazz.getComponentType()) != null) {
duke@1 673 numOfDims++;
duke@1 674 clazz = type;
duke@1 675 }
duke@1 676
duke@1 677 if (clazz.isPrimitive())
duke@1 678 repid = kValuePrefix + originalClazz.getName() + kPrimitiveSequenceValueHash;
duke@1 679 else {
duke@1 680 StringBuffer buf = new StringBuffer();
duke@1 681 buf.append(kValuePrefix);
duke@1 682 while(numOfDims-- > 0) {
duke@1 683 buf.append("[");
duke@1 684 }
duke@1 685 buf.append("L");
duke@1 686 buf.append(convertToISOLatin1(clazz.getName()));
duke@1 687 buf.append(";");
duke@1 688 buf.append(createHashString(clazz));
duke@1 689 repid = buf.toString();
duke@1 690 }
duke@1 691 classSeqToRepStr.put(originalClazz,repid);
duke@1 692 return repid;
duke@1 693 }
duke@1 694
duke@1 695 }
duke@1 696
duke@1 697
duke@1 698 public static String createForSpecialCase(java.lang.Class clazz){
duke@1 699 if (clazz.isArray()){
duke@1 700 return createSequenceRepID(clazz);
duke@1 701 }
duke@1 702 else {
duke@1 703 return (String)kSpecialCasesRepIDs.get(clazz);
duke@1 704 }
duke@1 705 }
duke@1 706
duke@1 707 public static String createForSpecialCase(java.io.Serializable ser){
duke@1 708 Class clazz = ser.getClass();
duke@1 709 if (clazz.isArray()){
duke@1 710 return createSequenceRepID(ser);
duke@1 711 }
duke@1 712 else
duke@1 713 return createForSpecialCase(clazz);
duke@1 714 }
duke@1 715
duke@1 716 /**
duke@1 717 * Creates a repository ID for a normal Java Type.
duke@1 718 * @param ser The Java object to create a repository ID for
duke@1 719 * @exception com.sun.corba.se.impl.io.TypeMismatchException if ser implements the
duke@1 720 * org.omg.CORBA.portable.IDLEntity interface which indicates it is an IDL Value type.
duke@1 721 **/
duke@1 722 public static String createForJavaType(java.io.Serializable ser)
duke@1 723 throws com.sun.corba.se.impl.io.TypeMismatchException
duke@1 724 {
duke@1 725 synchronized (classToRepStr) {
duke@1 726 String repid = createForSpecialCase(ser);
duke@1 727 if (repid != null)
duke@1 728 return repid;
duke@1 729 Class clazz = ser.getClass();
duke@1 730 repid = (String)classToRepStr.get(clazz);
duke@1 731
duke@1 732 if (repid != null)
duke@1 733 return repid;
duke@1 734
duke@1 735 repid = kValuePrefix + convertToISOLatin1(clazz.getName()) +
duke@1 736 createHashString(clazz);
duke@1 737
duke@1 738 classToRepStr.put(clazz, repid);
duke@1 739 repStrToClass.put(repid, clazz);
duke@1 740 return repid;
duke@1 741 }
duke@1 742 }
duke@1 743
duke@1 744 /**
duke@1 745 * Creates a repository ID for a normal Java Type.
duke@1 746 * @param clz The Java class to create a repository ID for
duke@1 747 * @exception com.sun.corba.se.impl.io.TypeMismatchException if ser implements the
duke@1 748 * org.omg.CORBA.portable.IDLEntity interface which indicates it is an IDL Value type.
duke@1 749 **/
duke@1 750 public static String createForJavaType(Class clz)
duke@1 751 throws com.sun.corba.se.impl.io.TypeMismatchException
duke@1 752 {
duke@1 753 synchronized (classToRepStr){
duke@1 754 String repid = createForSpecialCase(clz);
duke@1 755 if (repid != null)
duke@1 756 return repid;
duke@1 757
duke@1 758 repid = (String)classToRepStr.get(clz);
duke@1 759 if (repid != null)
duke@1 760 return repid;
duke@1 761
duke@1 762 repid = kValuePrefix + convertToISOLatin1(clz.getName()) +
duke@1 763 createHashString(clz);
duke@1 764
duke@1 765 classToRepStr.put(clz, repid);
duke@1 766 repStrToClass.put(repid, clz);
duke@1 767 return repid;
duke@1 768 }
duke@1 769 }
duke@1 770
duke@1 771 /**
duke@1 772 * Creates a repository ID for an IDL Java Type.
duke@1 773 * @param ser The IDL Value object to create a repository ID for
duke@1 774 * @param major The major version number
duke@1 775 * @param minor The minor version number
duke@1 776 * @exception com.sun.corba.se.impl.io.TypeMismatchException if ser does not implement the
duke@1 777 * org.omg.CORBA.portable.IDLEntity interface which indicates it is an IDL Value type.
duke@1 778 **/
duke@1 779 public static String createForIDLType(Class ser, int major, int minor)
duke@1 780 throws com.sun.corba.se.impl.io.TypeMismatchException
duke@1 781 {
duke@1 782 synchronized (classIDLToRepStr){
duke@1 783 String repid = (String)classIDLToRepStr.get(ser);
duke@1 784 if (repid != null)
duke@1 785 return repid;
duke@1 786
duke@1 787 repid = kIDLPrefix + convertToISOLatin1(ser.getName()).replace('.','/') +
duke@1 788 ":" + major + "." + minor;
duke@1 789 classIDLToRepStr.put(ser, repid);
duke@1 790 return repid;
duke@1 791 }
duke@1 792 }
duke@1 793
duke@1 794 private static String getIdFromHelper(Class clazz){
duke@1 795 try {
duke@1 796 Class helperClazz = Utility.loadClassForClass(clazz.getName()+"Helper", null,
duke@1 797 clazz.getClassLoader(), clazz, clazz.getClassLoader());
duke@1 798 Method idMethod = helperClazz.getDeclaredMethod("id", kNoParamTypes);
duke@1 799 return (String)idMethod.invoke(null, kNoArgs);
duke@1 800 }
duke@1 801 catch(java.lang.ClassNotFoundException cnfe)
duke@1 802 {
duke@1 803 throw new org.omg.CORBA.MARSHAL(cnfe.toString());
duke@1 804 }
duke@1 805 catch(java.lang.NoSuchMethodException nsme)
duke@1 806 {
duke@1 807 throw new org.omg.CORBA.MARSHAL(nsme.toString());
duke@1 808 }
duke@1 809 catch(java.lang.reflect.InvocationTargetException ite)
duke@1 810 {
duke@1 811 throw new org.omg.CORBA.MARSHAL(ite.toString());
duke@1 812 }
duke@1 813 catch(java.lang.IllegalAccessException iae)
duke@1 814 {
duke@1 815 throw new org.omg.CORBA.MARSHAL(iae.toString());
duke@1 816 }
duke@1 817 }
duke@1 818
duke@1 819 /**
duke@1 820 * Createa a repository ID for the type if it is either a java type
duke@1 821 * or an IDL type.
duke@1 822 * @param type The type to create rep. id for
duke@1 823 * @return The rep. id.
duke@1 824 **/
duke@1 825 public static String createForAnyType(Class type) {
duke@1 826 try{
duke@1 827 if (type.isArray())
duke@1 828 return createSequenceRepID(type);
duke@1 829 else if (IDLEntity.class.isAssignableFrom(type))
duke@1 830 {
duke@1 831 try{
duke@1 832 return getIdFromHelper(type);
duke@1 833 }
duke@1 834 catch(Throwable t) {
duke@1 835 return createForIDLType(type, 1, 0);
duke@1 836 }
duke@1 837 }
duke@1 838 else return createForJavaType(type);
duke@1 839 }
duke@1 840 catch(com.sun.corba.se.impl.io.TypeMismatchException e){
duke@1 841 return null;
duke@1 842 }
duke@1 843
duke@1 844 }
duke@1 845
duke@1 846 public static boolean isAbstractBase(Class clazz) {
duke@1 847 return (clazz.isInterface() &&
duke@1 848 IDLEntity.class.isAssignableFrom(clazz) &&
duke@1 849 (!ValueBase.class.isAssignableFrom(clazz)) &&
duke@1 850 (!org.omg.CORBA.Object.class.isAssignableFrom(clazz)));
duke@1 851
duke@1 852 }
duke@1 853
duke@1 854 public static boolean isAnyRequired(Class clazz) {
duke@1 855 return ((clazz == java.lang.Object.class) ||
duke@1 856 (clazz == java.io.Serializable.class) ||
duke@1 857 (clazz == java.io.Externalizable.class));
duke@1 858 }
duke@1 859
duke@1 860 public static long fromHex(String hexNumber) {
duke@1 861 if (hexNumber.startsWith("0x"))
duke@1 862 return Long.valueOf(hexNumber.substring(2), 16).longValue();
duke@1 863 else return Long.valueOf(hexNumber, 16).longValue();
duke@1 864 }
duke@1 865
duke@1 866 /**
duke@1 867 * Convert strings with illegal IDL identifier characters.
duke@1 868 * <p>
duke@1 869 * Section 5.5.7 of OBV spec.
duke@1 870 */
duke@1 871 private static String convertToISOLatin1 (String name) {
duke@1 872
duke@1 873 int length = name.length();
duke@1 874 if (length == 0) {
duke@1 875 return name;
duke@1 876 }
duke@1 877 StringBuffer buffer = null;
duke@1 878
duke@1 879 for (int i = 0; i < length; i++) {
duke@1 880
duke@1 881 char c = name.charAt(i);
duke@1 882
duke@1 883 if (c > 255 || IDL_IDENTIFIER_CHARS[c] == 0) {
duke@1 884
duke@1 885 // We gotta convert. Have we already started?
duke@1 886
duke@1 887 if (buffer == null) {
duke@1 888
duke@1 889 // No, so get set up...
duke@1 890
duke@1 891 buffer = new StringBuffer(name.substring(0,i));
duke@1 892 }
duke@1 893
duke@1 894 // Convert the character into the IDL escape syntax...
duke@1 895 buffer.append(
duke@1 896 "\\U" +
duke@1 897 (char)ASCII_HEX[(c & 0xF000) >>> 12] +
duke@1 898 (char)ASCII_HEX[(c & 0x0F00) >>> 8] +
duke@1 899 (char)ASCII_HEX[(c & 0x00F0) >>> 4] +
duke@1 900 (char)ASCII_HEX[(c & 0x000F)]);
duke@1 901
duke@1 902 } else {
duke@1 903 if (buffer != null) {
duke@1 904 buffer.append(c);
duke@1 905 }
duke@1 906 }
duke@1 907 }
duke@1 908
duke@1 909 if (buffer != null) {
duke@1 910 name = buffer.toString();
duke@1 911 }
duke@1 912
duke@1 913 return name;
duke@1 914 }
duke@1 915
duke@1 916 /**
duke@1 917 * Convert strings with ISO Latin 1 escape sequences back to original strings.
duke@1 918 * <p>
duke@1 919 * Section 5.5.7 of OBV spec.
duke@1 920 */
duke@1 921 private static String convertFromISOLatin1 (String name) {
duke@1 922
duke@1 923 int index = -1;
duke@1 924 StringBuffer buf = new StringBuffer(name);
duke@1 925
duke@1 926 while ((index = buf.toString().indexOf("\\U")) != -1){
duke@1 927 String str = "0000" + buf.toString().substring(index+2, index+6);
duke@1 928
duke@1 929 // Convert Hexadecimal
duke@1 930 byte[] buffer = new byte[(str.length() - 4) / 2];
duke@1 931 for (int i=4, j=0; i < str.length(); i +=2, j++) {
duke@1 932 buffer[j] = (byte)((ORBUtility.hexOf(str.charAt(i)) << 4) & 0xF0);
duke@1 933 buffer[j] |= (byte)((ORBUtility.hexOf(str.charAt(i+1)) << 0) & 0x0F);
duke@1 934 }
duke@1 935 buf = new StringBuffer(delete(buf.toString(), index, index+6));
duke@1 936 buf.insert(index, (char)buffer[1]);
duke@1 937 }
duke@1 938
duke@1 939 return buf.toString();
duke@1 940
duke@1 941
duke@1 942 }
duke@1 943
duke@1 944 private static String delete(String str, int from, int to)
duke@1 945 {
duke@1 946 return str.substring(0, from) + str.substring(to, str.length());
duke@1 947 }
duke@1 948
duke@1 949 private static String replace(String target, String arg, String source)
duke@1 950 {
duke@1 951 int i = 0;
duke@1 952 i = target.indexOf(arg);
duke@1 953
duke@1 954 while(i != -1)
duke@1 955 {
duke@1 956 String left = target.substring(0, i);
duke@1 957 String right = target.substring(i+arg.length());
duke@1 958 target = new String(left+source+right);
duke@1 959 i = target.indexOf(arg);
duke@1 960 }
duke@1 961 return target;
duke@1 962 }
duke@1 963
duke@1 964 public static int computeValueTag(boolean codeBasePresent, int typeInfo, boolean chunkedEncoding){
duke@1 965 int value_tag = kInitialValueTag;
duke@1 966
duke@1 967 if (codeBasePresent)
duke@1 968 value_tag = value_tag | 0x00000001;
duke@1 969
duke@1 970 value_tag = value_tag | typeInfo;
duke@1 971
duke@1 972 if (chunkedEncoding)
duke@1 973 value_tag = value_tag | kChunkedMask;
duke@1 974
duke@1 975 return value_tag;
duke@1 976 }
duke@1 977
duke@1 978 public static boolean isCodeBasePresent(int value_tag){
duke@1 979 return ((value_tag & 0x00000001) == 1);
duke@1 980 }
duke@1 981
duke@1 982 public static int getTypeInfo(int value_tag){
duke@1 983 return (value_tag & 0x00000006);
duke@1 984 }
duke@1 985
duke@1 986 public static boolean isChunkedEncoding(int value_tag){
duke@1 987 return ((value_tag & kChunkedMask) != 0);
duke@1 988 }
duke@1 989
duke@1 990 public static String getServerURL(){
duke@1 991 return defaultServerURL;
duke@1 992 }
duke@1 993
duke@1 994 /*
duke@1 995 * Load a class and check that it is assignable to a given type.
duke@1 996 * @param className the class name.
duke@1 997 * @param remoteCodebase the codebase to use. May be null.
duke@1 998 * @param loader the class loader of last resort. May be null.
duke@1 999 * @param expectedType the expected type. May be null.
duke@1 1000 * @return the loaded class.
duke@1 1001 */
duke@1 1002 private Class loadClassOfType (String className,
duke@1 1003 String remoteCodebase,
duke@1 1004 ClassLoader loader,
duke@1 1005 Class expectedType,
duke@1 1006 ClassLoader expectedTypeClassLoader)
duke@1 1007 throws ClassNotFoundException {
duke@1 1008
duke@1 1009 Class loadedClass = null;
duke@1 1010
duke@1 1011 try {
duke@1 1012 //Sequence finding of the stubs according to spec
duke@1 1013 try{
duke@1 1014 //If-else is put here for speed up of J2EE.
duke@1 1015 //According to the OMG spec, the if clause is not dead code.
duke@1 1016 //It can occur if some compiler has allowed generation
duke@1 1017 //into org.omg.stub hierarchy for non-offending
duke@1 1018 //classes. This will encourage people to
duke@1 1019 //produce non-offending class stubs in their own hierarchy.
duke@1 1020 if(!PackagePrefixChecker
duke@1 1021 .hasOffendingPrefix(PackagePrefixChecker
duke@1 1022 .withoutPackagePrefix(className))){
duke@1 1023 loadedClass = Util.loadClass
duke@1 1024 (PackagePrefixChecker.withoutPackagePrefix(className),
duke@1 1025 remoteCodebase,
duke@1 1026 loader);
duke@1 1027 } else {
duke@1 1028 loadedClass = Util.loadClass
duke@1 1029 (className,
duke@1 1030 remoteCodebase,
duke@1 1031 loader);
duke@1 1032 }
duke@1 1033 } catch (ClassNotFoundException cnfe) {
duke@1 1034 loadedClass = Util.loadClass
duke@1 1035 (className,
duke@1 1036 remoteCodebase,
duke@1 1037 loader);
duke@1 1038 }
duke@1 1039 if (expectedType == null)
duke@1 1040 return loadedClass;
duke@1 1041 } catch (ClassNotFoundException cnfe) {
duke@1 1042 if (expectedType == null)
duke@1 1043 throw cnfe;
duke@1 1044 }
duke@1 1045
duke@1 1046 // If no class was not loaded, or if the loaded class is not of the
duke@1 1047 // correct type, make a further attempt to load the correct class
duke@1 1048 // using the classloader of the expected type.
duke@1 1049 // _REVISIT_ Is this step necessary, or should the Util,loadClass
duke@1 1050 // algorithm always produce a valid class if the setup is correct?
duke@1 1051 // Does the OMG standard algorithm need to be changed to include
duke@1 1052 // this step?
duke@1 1053 if (loadedClass == null || !expectedType.isAssignableFrom(loadedClass)) {
duke@1 1054 if (expectedType.getClassLoader() != expectedTypeClassLoader)
duke@1 1055 throw new IllegalArgumentException("expectedTypeClassLoader not class loader of expectedType.");
duke@1 1056
duke@1 1057 if (expectedTypeClassLoader != null)
duke@1 1058 loadedClass = expectedTypeClassLoader.loadClass(className);
duke@1 1059 else
duke@1 1060 loadedClass = Class.forName(className);
duke@1 1061 }
duke@1 1062
duke@1 1063 return loadedClass;
duke@1 1064 }
duke@1 1065 }

mercurial