Fri, 24 Sep 2010 22:42:14 -0700
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 | } |