src/share/classes/com/sun/corba/se/impl/orbutil/RepositoryId_1_3_1.java

Wed, 28 Mar 2012 02:50:50 -0700

author
mbankal
date
Wed, 28 Mar 2012 02:50:50 -0700
changeset 371
e324dfb90c9e
parent 158
91006f157c46
permissions
-rw-r--r--

7079902: Refine CORBA data models
Reviewed-by: coffeys

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

mercurial