src/share/classes/sun/rmi/rmic/iiop/IDLNames.java

Tue, 25 May 2010 15:52:11 -0700

author
ohair
date
Tue, 25 May 2010 15:52:11 -0700
changeset 158
91006f157c46
parent 1
55540e827aef
child 371
e324dfb90c9e
permissions
-rw-r--r--

6943119: Rebrand source copyright notices
Reviewed-by: darcy

     1 /*
     2  * Copyright (c) 1998, 2007, 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  * Licensed Materials - Property of IBM
    28  * RMI-IIOP v1.0
    29  * Copyright IBM Corp. 1998 1999  All Rights Reserved
    30  *
    31  */
    33 package sun.rmi.rmic.iiop;
    35 import java.util.Hashtable;
    36 import java.util.Locale;
    37 import sun.tools.java.Identifier;
    38 import sun.tools.java.CompilerError;
    39 import sun.tools.java.ClassDefinition;
    40 import sun.tools.java.ClassNotFound;
    41 import com.sun.corba.se.impl.util.RepositoryId;
    43 /**
    44  * IDLNames provides static utility methods to perform the IDL
    45  * name mappings specified in Chapter 5 of the Java Language
    46  * to IDL specification.
    47  *
    48  * @author      Bryan Atsatt
    49  */
    50 public class IDLNames implements sun.rmi.rmic.iiop.Constants {
    52     /**
    53      * Used to convert ascii to hex.
    54      */
    55     public static final byte ASCII_HEX[] =      {
    56         (byte)'0',
    57         (byte)'1',
    58         (byte)'2',
    59         (byte)'3',
    60         (byte)'4',
    61         (byte)'5',
    62         (byte)'6',
    63         (byte)'7',
    64         (byte)'8',
    65         (byte)'9',
    66         (byte)'A',
    67         (byte)'B',
    68         (byte)'C',
    69         (byte)'D',
    70         (byte)'E',
    71         (byte)'F',
    72     };
    74     //_____________________________________________________________________
    75     // Public Interfaces
    76     //_____________________________________________________________________
    78     /**
    79      * Convert a name. The nameContext argument MUST be pre-filled with
    80      * all names from the appropriate context (e.g. all the method names
    81      * in a given class). The names must not have had any IDL conversions
    82      * applied.
    83      * <p>
    84      * Section 28.3.2.2
    85      * Section 28.3.2.3
    86      * Section 28.3.2.4
    87      * Section 28.3.2.7 (member and method names only)
    88      */
    89     public static String getMemberOrMethodName (NameContext nameContext,
    90                                                 String name,
    91                                                 BatchEnvironment env) {
    93         // Check namesCache...
    95         String result = (String) env.namesCache.get(name);
    97         if (result == null) {
    99             // 28.3.2.7 Case sensitive member names.
   101             // Note:    This must be done before any of
   102             //          the other conversions!
   104             result = nameContext.get(name);
   106             // 28.3.2.3 Leading underscores...
   108             result = convertLeadingUnderscores(result);
   110             // 28.3.2.2 IDL keywords (NOTE: must be done
   111             // after leading underscore conversion because
   112             // the mangling for IDL keywords creates a
   113             // leading underscore!)...
   115             result = convertIDLKeywords(result);
   117             // 28.3.2.4 Illegal IDL identifier characters...
   119             result = convertToISOLatin1(result);
   121             // Add to namesCache...
   123             env.namesCache.put(name,result);
   124         }
   126         return result;
   127     }
   129     /**
   130      * Convert names with illegal IDL identifier characters.
   131      * <p>
   132      * Section 28.3.2.4
   133      */
   134     public static String convertToISOLatin1 (String name) {
   136         // First, replace any escape sequences...
   138         String result = replace(name,"x\\u","U");
   139         result = replace(result,"x\\U","U");
   141         // Now see if we have any remaining illegal characters (see
   142         // RepositoryId.IDL_IDENTIFIER_CHARS array)...
   144         int length = result.length();
   145         StringBuffer buffer = null;
   147         for (int i = 0; i < length; i++) {
   149             char c = result.charAt(i);
   151             if (c > 255 || RepositoryId.IDL_IDENTIFIER_CHARS[c] == 0) {
   153                 // We gotta convert. Have we already started?
   155                 if (buffer == null) {
   157                     // No, so get set up...
   159                     buffer = new StringBuffer(result.substring(0,i));
   160                 }
   162                 // Convert the character into the IDL escape syntax...
   164                 buffer.append("U");
   165                 buffer.append((char)ASCII_HEX[(c & 0xF000) >>> 12]);
   166                 buffer.append((char)ASCII_HEX[(c & 0x0F00) >>> 8]);
   167                 buffer.append((char)ASCII_HEX[(c & 0x00F0) >>> 4]);
   168                 buffer.append((char)ASCII_HEX[(c & 0x000F)]);
   170             } else {
   171                 if (buffer != null) {
   172                     buffer.append(c);
   173                 }
   174             }
   175         }
   177         if (buffer != null) {
   178             result = buffer.toString();
   179         }
   181         return result;
   182     }
   184     /**
   185      * Convert names which collide with IDL keywords.
   186      * <p>
   187      * Section 28.3.2.5
   188      */
   189     public static String convertIDLKeywords (String name) {
   191         for (int i = 0; i < IDL_KEYWORDS.length; i++) {
   192             if (name.equalsIgnoreCase(IDL_KEYWORDS[i])) {
   193                 return "_" + name;
   194             }
   195         }
   197         return name;
   198     }
   200     /**
   201      * Convert names which have leading underscores
   202      * <p>
   203      * Section 28.3.2.3
   204      */
   205     public static String convertLeadingUnderscores (String name) {
   207         if (name.startsWith("_")) {
   208             return "J" + name;
   209         }
   211         return name;
   212     }
   214     /**
   215      * Convert a type name.
   216      * <p>
   217      * Section 28.3.2.5
   218      * Section 28.3.2.7 (class or interface names only)
   219      * Throws exception if fails 28.3.2.7.
   220      */
   221     public static String getClassOrInterfaceName (Identifier id,
   222                                                   BatchEnvironment env) throws Exception {
   224         // Get the type and package name...
   226         String typeName = id.getName().toString();
   227         String packageName = null;
   229         if (id.isQualified()) {
   230             packageName = id.getQualifier().toString();
   231         }
   233         // Check namesCache...
   235         String result = (String) env.namesCache.get(typeName);
   237         if (result == null) {
   239             // 28.3.2.5 Inner classes...
   241             result = replace(typeName,". ","__");
   243             // 28.3.2.4 Illegal identifier characters...
   245             result = convertToISOLatin1(result);
   247             // 28.3.2.7 Case sensitive class or interface names...
   249             NameContext context = NameContext.forName(packageName,false,env);
   250             context.assertPut(result);
   252             // Run it through the name checks...
   254             result = getTypeOrModuleName(result);
   256             // Add it to the namesCache...
   258             env.namesCache.put(typeName,result);
   259         }
   261         return result;
   262     }
   264     /**
   265      * Convert an Exception name.
   266      * <p>
   267      * Section 28.3.7.2    (see ValueType)
   268      */
   269     public static String getExceptionName (String idlName) {
   271         String result = idlName;
   272 // d.11315 Incorrectly mangled exception names
   273         if (idlName.endsWith(EXCEPTION_SUFFIX)) {
   275             // Remove "Exception" and append "Ex". Strip leading underscore
   276             // in case the idlName is exactly "_Exception"...
   278             result = stripLeadingUnderscore(idlName.substring(0,idlName.lastIndexOf(EXCEPTION_SUFFIX)) + EX_SUFFIX);
   279         } else {
   280             result = idlName + EX_SUFFIX;
   281         }
   283         return result;
   284     }
   286     /**
   287      * Convert a qualified Identifier into an array of IDL names.
   288      * <p>
   289      * Section 28.3.2.1    (see CompoundType)
   290      * Throws exception if fails 28.3.2.7.
   291      */
   292     public static String[] getModuleNames (Identifier theID,
   293                                            boolean boxIt,
   294                                            BatchEnvironment env) throws Exception {
   296         String[] result = null;
   298         if (theID.isQualified()) {
   300             // Extract the qualifier...
   302             Identifier id = theID.getQualifier();
   304             // 28.3.2.7 Case sensitive module names.
   306             env.modulesContext.assertPut(id.toString());
   308             // Count them...
   310             int count = 1;
   311             Identifier current = id;
   312             while (current.isQualified()) {
   313                 current = current.getQualifier();
   314                 count++;
   315             }
   317             result = new String[count];
   318             int index = count-1;
   319             current = id;
   321             // Now walk them and fill our array (backwards)...
   323             for (int i = 0; i < count; i++) {
   325                 String item = current.getName().toString();
   327                 // Check namesCache...
   329                 String cachedItem = (String) env.namesCache.get(item);
   331                 if (cachedItem == null) {
   333                     // 28.3.2.4 Illegal identifier characters...
   335                     cachedItem = convertToISOLatin1(item);
   337                     // Run it through the name checks...
   339                     cachedItem = getTypeOrModuleName(cachedItem);
   341                     // Add it to the namesCache...
   343                     env.namesCache.put(item,cachedItem);
   344                 }
   346                 result[index--] = cachedItem;
   347                 current = current.getQualifier();
   348             }
   349         }
   352         // If it is supposed to be "boxed", prepend
   353         // IDL_BOXEDIDL_MODULE...
   355         if (boxIt) {
   356             if (result == null) {
   357                 result = IDL_BOXEDIDL_MODULE;
   358             } else {
   359             String[] boxed = new String[result.length+IDL_BOXEDIDL_MODULE.length];
   360             System.arraycopy(IDL_BOXEDIDL_MODULE,0,boxed,0,IDL_BOXEDIDL_MODULE.length);
   361             System.arraycopy(result,0,boxed,IDL_BOXEDIDL_MODULE.length,result.length);
   362             result = boxed;
   363         }
   364         }
   366         return result;
   367     }
   369     /**
   370      * Get an array name with the specified dimensions.
   371      * <p>
   372      * Section 28.3.6  (see ArrayType)
   373      */
   374     public static String getArrayName (Type theType, int arrayDimension) {
   376         StringBuffer idlName = new StringBuffer(64);
   378         // Prefix with seq<n>_...
   380         idlName.append(IDL_SEQUENCE);
   381         idlName.append(Integer.toString(arrayDimension));
   382         idlName.append("_");
   384         // Add the type name. We need to map any spaces in the
   385         // name to "_"...
   387         idlName.append(replace(stripLeadingUnderscore(theType.getIDLName())," ","_"));
   389         // And we're done...
   391         return idlName.toString();
   392     }
   394     /**
   395      * Get an array module names.
   396      */
   397     public static String[] getArrayModuleNames (Type theType) {
   399         String[] moduleName;
   400         String[] typeModule = theType.getIDLModuleNames();
   401         int typeModuleLength = typeModule.length;
   403         // Does the type have a module?
   405         if (typeModuleLength == 0) {
   407             // Nope, so just use the sequence module...
   409             moduleName = IDL_SEQUENCE_MODULE;
   410         } else {
   412             // Yes, so gotta concatenate...
   414             moduleName = new String[typeModuleLength + IDL_SEQUENCE_MODULE.length];
   415             System.arraycopy(IDL_SEQUENCE_MODULE,0,moduleName,0,IDL_SEQUENCE_MODULE.length);
   416             System.arraycopy(typeModule,0,moduleName,IDL_SEQUENCE_MODULE.length,typeModuleLength);
   417         }
   419         return moduleName;
   420     }
   422     private static int getInitialAttributeKind (CompoundType.Method method,
   423                                                 BatchEnvironment env) throws ClassNotFound {
   425         int result = ATTRIBUTE_NONE;
   427         // First make sure it is not a constructor...
   429         if (!method.isConstructor()) {
   431             // Now check exceptions. It may not throw any checked
   432             // exception other than RemoteException or one of its
   433             // subclasses...
   435             boolean validExceptions = true;
   436             ClassType[] exceptions = method.getExceptions();
   438             if (exceptions.length > 0) {
   439                 for (int i = 0; i < exceptions.length; i++) {
   440                     if (exceptions[i].isCheckedException() &&
   441                         !exceptions[i].isRemoteExceptionOrSubclass()) {
   442                         validExceptions = false;
   443                         break;
   444                     }
   445                 }
   446             } else {
   448                 // If this is a ValueType, it is ok to not have any exceptions,
   449                 // otherwise this method does not qualify...
   451                 validExceptions = method.getEnclosing().isType(TYPE_VALUE);
   452             }
   454             if (validExceptions) {
   455                 String name = method.getName();
   456                 int nameLength = name.length();
   457                 int argCount = method.getArguments().length;
   458                 Type returnType = method.getReturnType();
   459                 boolean voidReturn = returnType.isType(TYPE_VOID);
   460                 boolean booleanReturn = returnType.isType(TYPE_BOOLEAN);
   462                 // It's a getter if name starts with "get" and it has no arguments
   463                 // and a return type that is not void...
   465                 if (name.startsWith("get") && nameLength > 3 && argCount == 0 && !voidReturn) {
   466                     result = ATTRIBUTE_GET;
   467                 } else {
   469                     // It's a getter if name starts with "is" and it has no arguments
   470                     // and a boolean return type...
   472                     if (name.startsWith("is") && nameLength > 2 && argCount == 0 && booleanReturn) {
   473                         result = ATTRIBUTE_IS;
   474                     } else {
   476                         // It's a setter if name starts with "set" and it has 1 argument
   477                         // and a void return type...
   479                         if (name.startsWith("set") && nameLength > 3 && argCount == 1 && voidReturn) {
   480                             result = ATTRIBUTE_SET;
   481                         }
   482                     }
   483                 }
   484             }
   485         }
   487         return result;
   488     }
   490     private static void setAttributeKinds (CompoundType.Method[] methods,
   491                                            int[] kinds,
   492                                            String[] names) {
   494         int count = methods.length;
   496         // Strip the prefixes off of the attribute names...
   498         for (int i = 0; i < count; i++) {
   499             switch (kinds[i]) {
   500                 case ATTRIBUTE_GET: names[i] = names[i].substring(3); break;
   501                 case ATTRIBUTE_IS: names[i] = names[i].substring(2); break;
   502                 case ATTRIBUTE_SET: names[i] = names[i].substring(3); break;
   503             }
   504         }
   506         // Now, we need to look at all the IS attributes to see
   507         // if there is a corresponding getter or setter which has
   508         // a different return type. If so, mark it as not an
   509         // attribute. Do this before checking for invalid setters...
   511         for (int i = 0; i < count; i++) {
   512             if (kinds[i] == ATTRIBUTE_IS) {
   513                 for (int j = 0; j < count; j++) {
   514                     if (j != i &&
   515                         (kinds[j] == ATTRIBUTE_GET || kinds[j] == ATTRIBUTE_SET) &&
   516                         names[i].equals(names[j])) {
   518                         // We have matching getter or setter. Do the types match?
   520                         Type isType = methods[i].getReturnType();
   521                         Type targetType;
   523                         if (kinds[j] == ATTRIBUTE_GET) {
   524                             targetType = methods[j].getReturnType();
   525                         } else {
   526                             targetType = methods[j].getArguments()[0];
   527                         }
   529                         if (!isType.equals(targetType)) {
   531                             // No, so forget this guy as an attribute...
   533                             kinds[i] = ATTRIBUTE_NONE;
   534                             names[i] = methods[i].getName();
   535                             break;
   536                         }
   537                     }
   538                 }
   539             }
   540         }
   542         // Now, we need to look at all the setters to see if there
   543         // is a corresponding getter. If not, it is not a setter.
   544         // If there is, change the getter type to _RW and set the
   545         // pair index...
   547         for (int i = 0; i < count; i++) {
   548             if (kinds[i] == ATTRIBUTE_SET) {
   549                 int getterIndex = -1;
   550                 int isGetterIndex = -1;
   551                 // First look for is-getters, then for getters.
   552                 // This is preferred for boolean attributes.
   553                 for (int j = 0; j < count; j++) {
   554                     if (j != i && names[i].equals(names[j])) {
   555                         // Yep, is the return type of the getter the same
   556                         // as the argument type of the setter?
   558                         Type getterReturn = methods[j].getReturnType();
   559                         Type setterArg = methods[i].getArguments()[0];
   561                         if (getterReturn.equals(setterArg)) {
   562                             if (kinds[j] == ATTRIBUTE_IS) {
   563                                 isGetterIndex = j;
   564                                 // continue looking for another getter
   565                             } else if (kinds[j] == ATTRIBUTE_GET) {
   566                                 getterIndex = j;
   567                                 // continue looking for an is-getter
   568                             }
   569                         }
   570                     }
   571                 }
   573                 if (getterIndex > -1) {
   574                     if (isGetterIndex > -1) {
   575                         // We have both, a boolean is-getter and a boolean getter.
   576                         // Use the is-getter and drop the getter.
   578                         // We have a matching getter. Change it to a read-write type...
   579                         kinds[isGetterIndex] = ATTRIBUTE_IS_RW;
   581                         // Now set the pair index for both the getter and the setter...
   582                         methods[isGetterIndex].setAttributePairIndex(i);
   583                         methods[i].setAttributePairIndex(isGetterIndex);
   585                         // We found a better matching is-getter.
   586                         // Forget this other getter as an attribute.
   587                         kinds[getterIndex] = ATTRIBUTE_NONE;
   588                         names[getterIndex] = methods[getterIndex].getName();
   589                     } else {
   590                         // We only have one getter.
   592                         // We have a matching getter. Change it to a read-write type...
   593                         kinds[getterIndex] = ATTRIBUTE_GET_RW;
   595                         // Now set the pair index for both the getter and the setter...
   596                         methods[getterIndex].setAttributePairIndex(i);
   597                         methods[i].setAttributePairIndex(getterIndex);
   598                     }
   599                 } else {
   600                     if (isGetterIndex > -1) {
   601                         // We only have one is-getter.
   603                         // We have a matching getter. Change it to a read-write type...
   604                         kinds[isGetterIndex] = ATTRIBUTE_IS_RW;
   606                         // Now set the pair index for both the getter and the setter...
   607                         methods[isGetterIndex].setAttributePairIndex(i);
   608                         methods[i].setAttributePairIndex(isGetterIndex);
   609                     } else {
   610                         // We did not find a matching getter.
   611                         // Forget this setter as an attribute.
   612                         kinds[i] = ATTRIBUTE_NONE;
   613                         names[i] = methods[i].getName();
   614                     }
   615                 }
   616             }
   617         }
   619         // Finally, do the case conversion and set the
   620         // attribute kinds for each method...
   622         for (int i = 0; i < count; i++) {
   624             if (kinds[i] != ATTRIBUTE_NONE) {
   626                 String name = names[i];
   628                 // Is the first character upper case?
   630                 if (Character.isUpperCase(name.charAt(0))) {
   632                     // Yes, is the second?
   634                     if (name.length() == 1 || Character.isLowerCase(name.charAt(1))) {
   636                         // No, so convert the first character to lower case...
   638                         StringBuffer buffer = new StringBuffer(name);
   639                         buffer.setCharAt(0,Character.toLowerCase(name.charAt(0)));
   640                         names[i] = buffer.toString();
   641                     }
   642                 }
   643             }
   645             methods[i].setAttributeKind(kinds[i]);
   646         }
   647     }
   649     /**
   650      * Set all the method names in a given class.
   651      * <p>
   652      * Section 28.3.2.7    (see CompoundType)
   653      * Section 28.3.2.7
   654      * Section 28.3.4.3 (RemoteType/AbstractType only).
   655      */
   656     public static void setMethodNames (CompoundType container,
   657                                        CompoundType.Method[] allMethods,
   658                                        BatchEnvironment env)
   659         throws Exception {
   661         // This method implements the following name mangling sequence:
   662         //
   663         //   1. If methods belong to a Remote interface, identify
   664         //      those which qualify as an attribute under 28.3.4.3.
   665         //      Those that do are referred to as 'attributes' below;
   666         //      those that do not are referred to as 'methods'.
   667         //
   668         //   2. Apply the 28.3.4.3 manglings, except "__", to all
   669         //      attribute names.
   670         //
   671         //   3. Apply all 28.3 manglings, except 28.3.2.7, to all names.
   672         //
   673         //   4. Apply 28.3.2.7 manglings to all method names.
   674         //
   675         //   5. Compare each attribute name to each method name. For
   676         //      any which compare equal, append "__" to the attribute
   677         //      name.
   678         //
   679         //   6. Compare each name (attribute and method) to all others.
   680         //      If any compare equal, throw an Exception with the
   681         //      conflicting name as the message.
   683         int count = allMethods.length;
   685         if (count == 0) return;
   687         // Make an array of all the method names...
   689         String[] names = new String[count];
   690         for (int i = 0; i < count; i++) {
   691             names[i] = allMethods[i].getName();
   692         }
   694         // Are we dealing with a RemoteType, AbstractType, or ValueType?
   696         CompoundType enclosing = allMethods[0].getEnclosing();
   697         if (enclosing.isType(TYPE_REMOTE) ||
   698             enclosing.isType(TYPE_ABSTRACT) ||
   699             enclosing.isType(TYPE_VALUE)) {
   701             // Yes, so we must do the 28.3.4.3 attribute mapping. First, get
   702             // the initial attribute kind of each method...
   704             int[] kinds = new int[count];
   706             for (int i = 0; i < count; i++) {
   707                 kinds[i] = getInitialAttributeKind(allMethods[i],env);
   708             }
   710             // Now set the attribute kind for each method and do the
   711             // 28.3.4.3 name mangling...
   713             setAttributeKinds(allMethods,kinds,names);
   714         }
   716         // Make and populate a new context from our names array...
   718         NameContext context = new NameContext(true);
   720         for (int i = 0; i < count; i++) {
   721             context.put(names[i]);
   722         }
   724         // Apply the appropriate 28.3 manglings to all the names...
   726         boolean haveConstructor = false;
   727         for (int i = 0; i < count; i++) {
   728             if (!allMethods[i].isConstructor()) {
   729                 names[i] = getMemberOrMethodName(context,names[i],env);
   730             } else {
   731                 names[i] = IDL_CONSTRUCTOR;
   732                 haveConstructor = true;
   733             }
   734         }
   736         // Now do the 28.3.2.7 mangling for method name collisions...
   737         // Do this in two passes so that we don't change one during
   738         // the detection of collisions and then miss a real one...
   740         boolean overloaded[] = new boolean[count];
   741         for (int i = 0; i < count; i++) {
   742             overloaded[i] = (!allMethods[i].isAttribute() &&
   743                              !allMethods[i].isConstructor() &&
   744                          doesMethodCollide(names[i],allMethods[i],allMethods,names,true));
   745         }
   746         convertOverloadedMethods(allMethods,names,overloaded);
   748         // Now do the same mangling for constructor name collisions...
   750         for (int i = 0; i < count; i++) {
   751             overloaded[i] = (!allMethods[i].isAttribute() &&
   752                              allMethods[i].isConstructor() &&
   753                              doesConstructorCollide(names[i],allMethods[i],allMethods,names,true));
   754         }
   755         convertOverloadedMethods(allMethods,names,overloaded);
   757         // Now do the 28.3.4.3 mangling for attribute name collisions...
   759         for (int i = 0; i < count; i++) {
   761                 CompoundType.Method method = allMethods[i];
   763             // If this is an attribute name, does it collide with a method?
   765             if (method.isAttribute() &&
   766                 doesMethodCollide(names[i],method,allMethods,names,true)) {
   768                 // Yes, so add double underscore...
   770                     names[i] += "__";
   771                 }
   772             }
   774         // Do the same mangling for any constructors which collide with
   775         // methods...
   777         if (haveConstructor) {
   778         for (int i = 0; i < count; i++) {
   779             CompoundType.Method method = allMethods[i];
   781                 // Is this a constructor which collides with a method?
   783                 if (method.isConstructor() &&
   784                     doesConstructorCollide(names[i],method,allMethods,names,false)) {
   786                 // Yes, so add double underscore...
   788                 names[i] += "__";
   789             }
   790         }
   791         }
   793         // Now see if we have a collision with the container name (28.3.2.9).
   795         String containerName = container.getIDLName();
   796         for (int i = 0; i < count; i++) {
   797             if (names[i].equalsIgnoreCase(containerName)) {
   798                 // Do not add underscore to attributes.
   799                 // Otherwise getFoo will turn into _get_foo_.
   800                 if (! allMethods[i].isAttribute()) {
   801                     names[i] += "_";
   802                 }
   803             }
   804         }
   806         // Now see if we have any collisions (28.3.2.9). If we do,
   807         // it's an error.  Note: a get/set pair does not collide.
   809         for (int i = 0; i < count; i++) {
   811             // Does it collide with any other name?
   813             if (doesMethodCollide(names[i],allMethods[i],allMethods,names,false)) {
   815                 // Yes, so bail...
   817                 throw new Exception(allMethods[i].toString());
   818             }
   819         }
   821         // Ok. We have unique names. Create the appropriate 'wire' name
   822         // for each and set as the 'idl' name. If it is an attribute, also
   823         // set the attribute name...
   825         for (int i = 0; i < count; i++) {
   827             CompoundType.Method method = allMethods[i];
   828             String wireName = names[i];
   830             if (method.isAttribute()) {
   831                 wireName = ATTRIBUTE_WIRE_PREFIX[method.getAttributeKind()] +
   832                     stripLeadingUnderscore(wireName);
   833                 String attributeName = names[i];
   834                 method.setAttributeName(attributeName);
   835             }
   836             method.setIDLName(wireName);
   837         }
   838     }
   840     private static String stripLeadingUnderscore (String name) {
   841         if (name != null && name.length() > 1
   842             && name.charAt(0) == '_')
   843         {
   844             return name.substring(1);
   845         }
   846         return name;
   847     }
   850     private static String stripTrailingUnderscore (String name) {
   851         if (name != null && name.length() > 1 &&
   852             name.charAt(name.length() - 1) == '_')
   853         {
   854             return name.substring(0, name.length() - 1);
   855         }
   856         return name;
   857     }
   860     private static void convertOverloadedMethods(CompoundType.Method[] allMethods,
   861                                                  String[] names,
   862                                                  boolean[] overloaded) {
   864         for (int i = 0; i < names.length; i++) {
   866             // Do we need to mangle it?
   868             if (overloaded[i]) {
   870                 // Yes, so add arguments...
   872                 CompoundType.Method method = allMethods[i];
   873                 Type[] args = method.getArguments();
   875                 for (int k = 0; k < args.length; k++) {
   877                                 // Add the separator...
   879                     names[i] += "__";
   881                                 // Get the fully qualified IDL name, without the "::"
   882                                 // prefix...
   884                     String argIDLName = args[k].getQualifiedIDLName(false);
   886                                 // Replace any occurances of "::_" with "_" to
   887                                 // undo any IDL keyword mangling and do next step
   888                                 // at the same time...
   890                     argIDLName = replace(argIDLName,"::_","_");
   892                                 // Replace any occurances of "::" with "_"...
   894                     argIDLName = replace(argIDLName,"::","_");
   896                                 // Replace any occurances of " " with "_"...
   898                     argIDLName = replace(argIDLName," ","_");
   900                                 // Add the argument type name...
   902                     names[i] += argIDLName;
   903                 }
   905                 if (args.length == 0) {
   906                     names[i] += "__";
   907                 }
   909                 // Remove any IDL keyword mangling...
   911                 names[i] = stripLeadingUnderscore(names[i]);
   912             }
   913         }
   914     }
   916     private static boolean doesMethodCollide (String name,
   917                                               CompoundType.Method method,
   918                                               CompoundType.Method[] allMethods,
   919                                               String[] allNames,
   920                                               boolean ignoreAttributes) {
   922         // Scan all methods looking for a match...
   924         for (int i = 0; i < allMethods.length; i++) {
   926             CompoundType.Method target = allMethods[i];
   928             if (method != target &&                                 // Not same instance
   929                 !target.isConstructor() &&                      // Not a constructor
   930                 (!ignoreAttributes || !target.isAttribute()) && // Correct kind
   931                 name.equals(allNames[i])) {                         // Same names
   933                 // Are we looking at a get/set pair?
   935                 int kind1 = method.getAttributeKind();
   936                 int kind2 = target.getAttributeKind();
   938                 if ((kind1 != ATTRIBUTE_NONE && kind2 != ATTRIBUTE_NONE) &&
   939                     ((kind1 == ATTRIBUTE_SET && kind2 != ATTRIBUTE_SET) ||
   940                      (kind1 != ATTRIBUTE_SET && kind2 == ATTRIBUTE_SET) ||
   941                      // one is a is-getter/setter pair and the other is just a getter
   942                      (kind1 == ATTRIBUTE_IS_RW && kind2 == ATTRIBUTE_GET) ||
   943                      (kind1 == ATTRIBUTE_GET && kind2 == ATTRIBUTE_IS_RW))) {
   945                     // Yes, so ignore it...
   947                 } else {
   949                     // No, so we have a collision...
   951                     return true;
   952                 }
   953             }
   954         }
   956         return false;
   957     }
   959     private static boolean doesConstructorCollide (String name,
   960                                                    CompoundType.Method method,
   961                                                    CompoundType.Method[] allMethods,
   962                                                    String[] allNames,
   963                                                    boolean compareConstructors) {
   965         // Scan all methods looking for a match...
   967         for (int i = 0; i < allMethods.length; i++) {
   969             CompoundType.Method target = allMethods[i];
   971             if (method != target &&                                     // Not same instance
   972                 (target.isConstructor() == compareConstructors) &&  // Correct kind
   973                 name.equals(allNames[i])) {                             // Same names
   975                 // We have a collision...
   977                 return true;
   978             }
   979         }
   981         return false;
   982     }
   985     /**
   986      * Set all the member names in a given class.
   987      * <p>
   988      * Section 28.3.2.7    (see CompoundType)
   989      * Section 28.3.2.7
   990      */
   991     public static void setMemberNames (CompoundType container,
   992                                        CompoundType.Member[] allMembers,
   993                                        CompoundType.Method[] allMethods,
   994                                        BatchEnvironment env)
   995         throws Exception {
   997         // Make and populate a new context...
   999         NameContext context = new NameContext(true);
  1001         for (int i = 0; i < allMembers.length; i++) {
  1002             context.put(allMembers[i].getName());
  1005         // Now set all the idl names...
  1007         for (int i = 0; i < allMembers.length; i++) {
  1009             CompoundType.Member member = allMembers[i];
  1010             String idlName = getMemberOrMethodName(context,member.getName(),env);
  1011             member.setIDLName(idlName);
  1014         // First see if we have a collision with the container name (28.3.2.9).
  1016         String containerName = container.getIDLName();
  1017         for (int i = 0; i < allMembers.length; i++) {
  1018             String name = allMembers[i].getIDLName();
  1019             if (name.equalsIgnoreCase(containerName)) {
  1020                 // REVISIT - How is this different than line 788
  1021                 allMembers[i].setIDLName(name+"_");
  1025         // Check for collisions between member names...
  1027         for (int i = 0; i < allMembers.length; i++) {
  1028             String name = allMembers[i].getIDLName();
  1029             for (int j = 0; j < allMembers.length; j++) {
  1030                 if (i != j && allMembers[j].getIDLName().equals(name)) {
  1032                     // Collision...
  1034                     throw new Exception(name);
  1039         // Now check for collisions between member names and
  1040         // method names...
  1042         boolean changed;
  1043         do {
  1044             changed = false;
  1045             for (int i = 0; i < allMembers.length; i++) {
  1046                 String name = allMembers[i].getIDLName();
  1047                 for (int j = 0; j < allMethods.length; j++) {
  1048                     if (allMethods[j].getIDLName().equals(name)) {
  1050                         // Collision, so append "_" to member name...
  1052                         allMembers[i].setIDLName(name+"_");
  1053                         changed = true;
  1054                         break;
  1058         } while (changed);
  1061     /**
  1062      * Get the name for the specified type code.
  1063      * <p>
  1064      * Section 28.3..3     (see PrimitiveType)
  1065      * Section 28.3.5.10   (see SpecialClassType)
  1066      * Section 28.3.4.1    (see SpecialInterfaceType)
  1067      * Section 28.3.10.1   (see SpecialInterfaceType)
  1068      * Section 28.3.10.2   (see SpecialClassType)
  1069      */
  1070     public static String getTypeName(int typeCode, boolean isConstant) {
  1072         String idlName = null;
  1074         switch (typeCode) {
  1075         case TYPE_VOID:             idlName = IDL_VOID; break;
  1076         case TYPE_BOOLEAN:          idlName = IDL_BOOLEAN; break;
  1077         case TYPE_BYTE:             idlName = IDL_BYTE; break;
  1078         case TYPE_CHAR:             idlName = IDL_CHAR; break;
  1079         case TYPE_SHORT:            idlName = IDL_SHORT; break;
  1080         case TYPE_INT:              idlName = IDL_INT; break;
  1081         case TYPE_LONG:             idlName = IDL_LONG; break;
  1082         case TYPE_FLOAT:            idlName = IDL_FLOAT; break;
  1083         case TYPE_DOUBLE:           idlName = IDL_DOUBLE; break;
  1084         case TYPE_ANY:                  idlName = IDL_ANY; break;
  1085         case TYPE_CORBA_OBJECT: idlName = IDL_CORBA_OBJECT; break;
  1086         case TYPE_STRING:
  1088                 if (isConstant) {
  1089                     idlName = IDL_CONSTANT_STRING;
  1090                 } else {
  1091                     idlName = IDL_STRING;
  1094                 break;
  1098         return idlName;
  1101     /**
  1102      * Create a qualified name.
  1103      */
  1104     public static String getQualifiedName (String[] idlModuleNames, String idlName) {
  1105         String result = null;
  1106         if (idlModuleNames != null && idlModuleNames.length > 0) {
  1107             for (int i = 0; i < idlModuleNames.length;i++) {
  1108                 if (i == 0) {
  1109                     result = idlModuleNames[0];
  1110                 } else {
  1111                     result += IDL_NAME_SEPARATOR;
  1112                     result += idlModuleNames[i];
  1115             result += IDL_NAME_SEPARATOR;
  1116             result += idlName;
  1117         } else {
  1118             result = idlName;
  1120         return result;
  1123     /**
  1124      * Replace substrings
  1125      * @param source The source string.
  1126      * @param match The string to search for within the source string.
  1127      * @param replace The replacement for any matching components.
  1128      * @return
  1129      */
  1130     public static String replace (String source, String match, String replace) {
  1132         int index = source.indexOf(match,0);
  1134         if (index >=0) {
  1136             // We have at least one match, so gotta do the
  1137             // work...
  1139             StringBuffer result = new StringBuffer(source.length() + 16);
  1140             int matchLength = match.length();
  1141             int startIndex = 0;
  1143             while (index >= 0) {
  1144                 result.append(source.substring(startIndex,index));
  1145                 result.append(replace);
  1146                 startIndex = index + matchLength;
  1147                 index = source.indexOf(match,startIndex);
  1150             // Grab the last piece, if any...
  1152             if (startIndex < source.length()) {
  1153                 result.append(source.substring(startIndex));
  1156             return result.toString();
  1158         } else {
  1160             // No matches, just return the source...
  1162             return source;
  1166     /**
  1167      * Get an IDL style repository id for
  1168      */
  1169     public static String getIDLRepositoryID (String idlName) {
  1170         return  IDL_REPOSITORY_ID_PREFIX +
  1171             replace(idlName,"::", "/") +
  1172             IDL_REPOSITORY_ID_VERSION;
  1175     //_____________________________________________________________________
  1176     // Internal Interfaces
  1177     //_____________________________________________________________________
  1180     /**
  1181      * Convert a type or module name.
  1182      * <p>
  1183      * Section 28.3.2.2
  1184      * Section 28.3.2.3
  1185      */
  1186     private static String getTypeOrModuleName (String name) {
  1188         // 28.3.2.3 Leading underscores...
  1190         String result = convertLeadingUnderscores(name);
  1192         // 28.3.2.2 IDL keywords (NOTE: must be done
  1193         // after leading underscore conversion because
  1194         // the mangling for IDL keywords creates a
  1195         // leading underscore!)...
  1197         return convertIDLKeywords(result);

mercurial