src/share/classes/sun/rmi/rmic/iiop/IDLNames.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
child 748
6845b95cba6b
permissions
-rw-r--r--

7079902: Refine CORBA data models
Reviewed-by: coffeys

     1 /*
     2  * Copyright (c) 1998, 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  * 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     // Legal IDL Identifier characters (1 = legal). Note
    75     // that '.' (2E) is marked as legal even though it is
    76     // not legal in IDL. This allows us to treat a fully
    77     // qualified Java name with '.' package separators
    78     // uniformly, and is safe because that is the only
    79     // legal use of '.' in a Java name.
    81     private static final byte[] IDL_IDENTIFIER_CHARS = {
    83         // 0 1 2 3  4 5 6 7  8 9 a b  c d e f
    84         0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, // 00-0f
    85         0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, // 10-1f
    86         0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,1,0, // 20-2f
    87         1,1,1,1, 1,1,1,1, 1,1,0,0, 0,0,0,0, // 30-3f
    88         0,1,1,1, 1,1,1,1, 1,1,1,1, 1,1,1,1, // 40-4f
    89         1,1,1,1, 1,1,1,1, 1,1,1,0, 0,0,0,1, // 50-5f
    90         0,1,1,1, 1,1,1,1, 1,1,1,1, 1,1,1,1, // 60-6f
    91         1,1,1,1, 1,1,1,1, 1,1,1,0, 0,0,0,0, // 70-7f
    92         0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, // 80-8f
    93         0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, // 90-9f
    94         0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, // a0-af
    95         0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, // b0-bf
    96         1,1,1,1, 1,1,1,1, 1,1,1,1, 1,1,1,1, // c0-cf
    97         0,1,1,1, 1,1,1,0, 1,1,1,1, 1,0,0,1, // d0-df
    98         1,1,1,1, 1,1,1,1, 1,1,1,1, 1,1,1,1, // e0-ef
    99         0,1,1,1, 1,1,1,0, 1,1,1,1, 1,0,0,1, // f0-ff
   100     };
   102     //_____________________________________________________________________
   103     // Public Interfaces
   104     //_____________________________________________________________________
   106     /**
   107      * Convert a name. The nameContext argument MUST be pre-filled with
   108      * all names from the appropriate context (e.g. all the method names
   109      * in a given class). The names must not have had any IDL conversions
   110      * applied.
   111      * <p>
   112      * Section 28.3.2.2
   113      * Section 28.3.2.3
   114      * Section 28.3.2.4
   115      * Section 28.3.2.7 (member and method names only)
   116      */
   117     public static String getMemberOrMethodName (NameContext nameContext,
   118                                                 String name,
   119                                                 BatchEnvironment env) {
   121         // Check namesCache...
   123         String result = (String) env.namesCache.get(name);
   125         if (result == null) {
   127             // 28.3.2.7 Case sensitive member names.
   129             // Note:    This must be done before any of
   130             //          the other conversions!
   132             result = nameContext.get(name);
   134             // 28.3.2.3 Leading underscores...
   136             result = convertLeadingUnderscores(result);
   138             // 28.3.2.2 IDL keywords (NOTE: must be done
   139             // after leading underscore conversion because
   140             // the mangling for IDL keywords creates a
   141             // leading underscore!)...
   143             result = convertIDLKeywords(result);
   145             // 28.3.2.4 Illegal IDL identifier characters...
   147             result = convertToISOLatin1(result);
   149             // Add to namesCache...
   151             env.namesCache.put(name,result);
   152         }
   154         return result;
   155     }
   157     /**
   158      * Convert names with illegal IDL identifier characters.
   159      * <p>
   160      * Section 28.3.2.4
   161      */
   162     public static String convertToISOLatin1 (String name) {
   164         // First, replace any escape sequences...
   166         String result = replace(name,"x\\u","U");
   167         result = replace(result,"x\\U","U");
   169         // Now see if we have any remaining illegal characters (see
   170         // IDL_IDENTIFIER_CHARS array)...
   172         int length = result.length();
   173         StringBuffer buffer = null;
   175         for (int i = 0; i < length; i++) {
   177             char c = result.charAt(i);
   179             if (c > 255 || IDL_IDENTIFIER_CHARS[c] == 0) {
   181                 // We gotta convert. Have we already started?
   183                 if (buffer == null) {
   185                     // No, so get set up...
   187                     buffer = new StringBuffer(result.substring(0,i));
   188                 }
   190                 // Convert the character into the IDL escape syntax...
   192                 buffer.append("U");
   193                 buffer.append((char)ASCII_HEX[(c & 0xF000) >>> 12]);
   194                 buffer.append((char)ASCII_HEX[(c & 0x0F00) >>> 8]);
   195                 buffer.append((char)ASCII_HEX[(c & 0x00F0) >>> 4]);
   196                 buffer.append((char)ASCII_HEX[(c & 0x000F)]);
   198             } else {
   199                 if (buffer != null) {
   200                     buffer.append(c);
   201                 }
   202             }
   203         }
   205         if (buffer != null) {
   206             result = buffer.toString();
   207         }
   209         return result;
   210     }
   212     /**
   213      * Convert names which collide with IDL keywords.
   214      * <p>
   215      * Section 28.3.2.5
   216      */
   217     public static String convertIDLKeywords (String name) {
   219         for (int i = 0; i < IDL_KEYWORDS.length; i++) {
   220             if (name.equalsIgnoreCase(IDL_KEYWORDS[i])) {
   221                 return "_" + name;
   222             }
   223         }
   225         return name;
   226     }
   228     /**
   229      * Convert names which have leading underscores
   230      * <p>
   231      * Section 28.3.2.3
   232      */
   233     public static String convertLeadingUnderscores (String name) {
   235         if (name.startsWith("_")) {
   236             return "J" + name;
   237         }
   239         return name;
   240     }
   242     /**
   243      * Convert a type name.
   244      * <p>
   245      * Section 28.3.2.5
   246      * Section 28.3.2.7 (class or interface names only)
   247      * Throws exception if fails 28.3.2.7.
   248      */
   249     public static String getClassOrInterfaceName (Identifier id,
   250                                                   BatchEnvironment env) throws Exception {
   252         // Get the type and package name...
   254         String typeName = id.getName().toString();
   255         String packageName = null;
   257         if (id.isQualified()) {
   258             packageName = id.getQualifier().toString();
   259         }
   261         // Check namesCache...
   263         String result = (String) env.namesCache.get(typeName);
   265         if (result == null) {
   267             // 28.3.2.5 Inner classes...
   269             result = replace(typeName,". ","__");
   271             // 28.3.2.4 Illegal identifier characters...
   273             result = convertToISOLatin1(result);
   275             // 28.3.2.7 Case sensitive class or interface names...
   277             NameContext context = NameContext.forName(packageName,false,env);
   278             context.assertPut(result);
   280             // Run it through the name checks...
   282             result = getTypeOrModuleName(result);
   284             // Add it to the namesCache...
   286             env.namesCache.put(typeName,result);
   287         }
   289         return result;
   290     }
   292     /**
   293      * Convert an Exception name.
   294      * <p>
   295      * Section 28.3.7.2    (see ValueType)
   296      */
   297     public static String getExceptionName (String idlName) {
   299         String result = idlName;
   300 // d.11315 Incorrectly mangled exception names
   301         if (idlName.endsWith(EXCEPTION_SUFFIX)) {
   303             // Remove "Exception" and append "Ex". Strip leading underscore
   304             // in case the idlName is exactly "_Exception"...
   306             result = stripLeadingUnderscore(idlName.substring(0,idlName.lastIndexOf(EXCEPTION_SUFFIX)) + EX_SUFFIX);
   307         } else {
   308             result = idlName + EX_SUFFIX;
   309         }
   311         return result;
   312     }
   314     /**
   315      * Convert a qualified Identifier into an array of IDL names.
   316      * <p>
   317      * Section 28.3.2.1    (see CompoundType)
   318      * Throws exception if fails 28.3.2.7.
   319      */
   320     public static String[] getModuleNames (Identifier theID,
   321                                            boolean boxIt,
   322                                            BatchEnvironment env) throws Exception {
   324         String[] result = null;
   326         if (theID.isQualified()) {
   328             // Extract the qualifier...
   330             Identifier id = theID.getQualifier();
   332             // 28.3.2.7 Case sensitive module names.
   334             env.modulesContext.assertPut(id.toString());
   336             // Count them...
   338             int count = 1;
   339             Identifier current = id;
   340             while (current.isQualified()) {
   341                 current = current.getQualifier();
   342                 count++;
   343             }
   345             result = new String[count];
   346             int index = count-1;
   347             current = id;
   349             // Now walk them and fill our array (backwards)...
   351             for (int i = 0; i < count; i++) {
   353                 String item = current.getName().toString();
   355                 // Check namesCache...
   357                 String cachedItem = (String) env.namesCache.get(item);
   359                 if (cachedItem == null) {
   361                     // 28.3.2.4 Illegal identifier characters...
   363                     cachedItem = convertToISOLatin1(item);
   365                     // Run it through the name checks...
   367                     cachedItem = getTypeOrModuleName(cachedItem);
   369                     // Add it to the namesCache...
   371                     env.namesCache.put(item,cachedItem);
   372                 }
   374                 result[index--] = cachedItem;
   375                 current = current.getQualifier();
   376             }
   377         }
   380         // If it is supposed to be "boxed", prepend
   381         // IDL_BOXEDIDL_MODULE...
   383         if (boxIt) {
   384             if (result == null) {
   385                 result = IDL_BOXEDIDL_MODULE;
   386             } else {
   387             String[] boxed = new String[result.length+IDL_BOXEDIDL_MODULE.length];
   388             System.arraycopy(IDL_BOXEDIDL_MODULE,0,boxed,0,IDL_BOXEDIDL_MODULE.length);
   389             System.arraycopy(result,0,boxed,IDL_BOXEDIDL_MODULE.length,result.length);
   390             result = boxed;
   391         }
   392         }
   394         return result;
   395     }
   397     /**
   398      * Get an array name with the specified dimensions.
   399      * <p>
   400      * Section 28.3.6  (see ArrayType)
   401      */
   402     public static String getArrayName (Type theType, int arrayDimension) {
   404         StringBuffer idlName = new StringBuffer(64);
   406         // Prefix with seq<n>_...
   408         idlName.append(IDL_SEQUENCE);
   409         idlName.append(Integer.toString(arrayDimension));
   410         idlName.append("_");
   412         // Add the type name. We need to map any spaces in the
   413         // name to "_"...
   415         idlName.append(replace(stripLeadingUnderscore(theType.getIDLName())," ","_"));
   417         // And we're done...
   419         return idlName.toString();
   420     }
   422     /**
   423      * Get an array module names.
   424      */
   425     public static String[] getArrayModuleNames (Type theType) {
   427         String[] moduleName;
   428         String[] typeModule = theType.getIDLModuleNames();
   429         int typeModuleLength = typeModule.length;
   431         // Does the type have a module?
   433         if (typeModuleLength == 0) {
   435             // Nope, so just use the sequence module...
   437             moduleName = IDL_SEQUENCE_MODULE;
   438         } else {
   440             // Yes, so gotta concatenate...
   442             moduleName = new String[typeModuleLength + IDL_SEQUENCE_MODULE.length];
   443             System.arraycopy(IDL_SEQUENCE_MODULE,0,moduleName,0,IDL_SEQUENCE_MODULE.length);
   444             System.arraycopy(typeModule,0,moduleName,IDL_SEQUENCE_MODULE.length,typeModuleLength);
   445         }
   447         return moduleName;
   448     }
   450     private static int getInitialAttributeKind (CompoundType.Method method,
   451                                                 BatchEnvironment env) throws ClassNotFound {
   453         int result = ATTRIBUTE_NONE;
   455         // First make sure it is not a constructor...
   457         if (!method.isConstructor()) {
   459             // Now check exceptions. It may not throw any checked
   460             // exception other than RemoteException or one of its
   461             // subclasses...
   463             boolean validExceptions = true;
   464             ClassType[] exceptions = method.getExceptions();
   466             if (exceptions.length > 0) {
   467                 for (int i = 0; i < exceptions.length; i++) {
   468                     if (exceptions[i].isCheckedException() &&
   469                         !exceptions[i].isRemoteExceptionOrSubclass()) {
   470                         validExceptions = false;
   471                         break;
   472                     }
   473                 }
   474             } else {
   476                 // If this is a ValueType, it is ok to not have any exceptions,
   477                 // otherwise this method does not qualify...
   479                 validExceptions = method.getEnclosing().isType(TYPE_VALUE);
   480             }
   482             if (validExceptions) {
   483                 String name = method.getName();
   484                 int nameLength = name.length();
   485                 int argCount = method.getArguments().length;
   486                 Type returnType = method.getReturnType();
   487                 boolean voidReturn = returnType.isType(TYPE_VOID);
   488                 boolean booleanReturn = returnType.isType(TYPE_BOOLEAN);
   490                 // It's a getter if name starts with "get" and it has no arguments
   491                 // and a return type that is not void...
   493                 if (name.startsWith("get") && nameLength > 3 && argCount == 0 && !voidReturn) {
   494                     result = ATTRIBUTE_GET;
   495                 } else {
   497                     // It's a getter if name starts with "is" and it has no arguments
   498                     // and a boolean return type...
   500                     if (name.startsWith("is") && nameLength > 2 && argCount == 0 && booleanReturn) {
   501                         result = ATTRIBUTE_IS;
   502                     } else {
   504                         // It's a setter if name starts with "set" and it has 1 argument
   505                         // and a void return type...
   507                         if (name.startsWith("set") && nameLength > 3 && argCount == 1 && voidReturn) {
   508                             result = ATTRIBUTE_SET;
   509                         }
   510                     }
   511                 }
   512             }
   513         }
   515         return result;
   516     }
   518     private static void setAttributeKinds (CompoundType.Method[] methods,
   519                                            int[] kinds,
   520                                            String[] names) {
   522         int count = methods.length;
   524         // Strip the prefixes off of the attribute names...
   526         for (int i = 0; i < count; i++) {
   527             switch (kinds[i]) {
   528                 case ATTRIBUTE_GET: names[i] = names[i].substring(3); break;
   529                 case ATTRIBUTE_IS: names[i] = names[i].substring(2); break;
   530                 case ATTRIBUTE_SET: names[i] = names[i].substring(3); break;
   531             }
   532         }
   534         // Now, we need to look at all the IS attributes to see
   535         // if there is a corresponding getter or setter which has
   536         // a different return type. If so, mark it as not an
   537         // attribute. Do this before checking for invalid setters...
   539         for (int i = 0; i < count; i++) {
   540             if (kinds[i] == ATTRIBUTE_IS) {
   541                 for (int j = 0; j < count; j++) {
   542                     if (j != i &&
   543                         (kinds[j] == ATTRIBUTE_GET || kinds[j] == ATTRIBUTE_SET) &&
   544                         names[i].equals(names[j])) {
   546                         // We have matching getter or setter. Do the types match?
   548                         Type isType = methods[i].getReturnType();
   549                         Type targetType;
   551                         if (kinds[j] == ATTRIBUTE_GET) {
   552                             targetType = methods[j].getReturnType();
   553                         } else {
   554                             targetType = methods[j].getArguments()[0];
   555                         }
   557                         if (!isType.equals(targetType)) {
   559                             // No, so forget this guy as an attribute...
   561                             kinds[i] = ATTRIBUTE_NONE;
   562                             names[i] = methods[i].getName();
   563                             break;
   564                         }
   565                     }
   566                 }
   567             }
   568         }
   570         // Now, we need to look at all the setters to see if there
   571         // is a corresponding getter. If not, it is not a setter.
   572         // If there is, change the getter type to _RW and set the
   573         // pair index...
   575         for (int i = 0; i < count; i++) {
   576             if (kinds[i] == ATTRIBUTE_SET) {
   577                 int getterIndex = -1;
   578                 int isGetterIndex = -1;
   579                 // First look for is-getters, then for getters.
   580                 // This is preferred for boolean attributes.
   581                 for (int j = 0; j < count; j++) {
   582                     if (j != i && names[i].equals(names[j])) {
   583                         // Yep, is the return type of the getter the same
   584                         // as the argument type of the setter?
   586                         Type getterReturn = methods[j].getReturnType();
   587                         Type setterArg = methods[i].getArguments()[0];
   589                         if (getterReturn.equals(setterArg)) {
   590                             if (kinds[j] == ATTRIBUTE_IS) {
   591                                 isGetterIndex = j;
   592                                 // continue looking for another getter
   593                             } else if (kinds[j] == ATTRIBUTE_GET) {
   594                                 getterIndex = j;
   595                                 // continue looking for an is-getter
   596                             }
   597                         }
   598                     }
   599                 }
   601                 if (getterIndex > -1) {
   602                     if (isGetterIndex > -1) {
   603                         // We have both, a boolean is-getter and a boolean getter.
   604                         // Use the is-getter and drop the getter.
   606                         // We have a matching getter. Change it to a read-write type...
   607                         kinds[isGetterIndex] = ATTRIBUTE_IS_RW;
   609                         // Now set the pair index for both the getter and the setter...
   610                         methods[isGetterIndex].setAttributePairIndex(i);
   611                         methods[i].setAttributePairIndex(isGetterIndex);
   613                         // We found a better matching is-getter.
   614                         // Forget this other getter as an attribute.
   615                         kinds[getterIndex] = ATTRIBUTE_NONE;
   616                         names[getterIndex] = methods[getterIndex].getName();
   617                     } else {
   618                         // We only have one getter.
   620                         // We have a matching getter. Change it to a read-write type...
   621                         kinds[getterIndex] = ATTRIBUTE_GET_RW;
   623                         // Now set the pair index for both the getter and the setter...
   624                         methods[getterIndex].setAttributePairIndex(i);
   625                         methods[i].setAttributePairIndex(getterIndex);
   626                     }
   627                 } else {
   628                     if (isGetterIndex > -1) {
   629                         // We only have one is-getter.
   631                         // We have a matching getter. Change it to a read-write type...
   632                         kinds[isGetterIndex] = ATTRIBUTE_IS_RW;
   634                         // Now set the pair index for both the getter and the setter...
   635                         methods[isGetterIndex].setAttributePairIndex(i);
   636                         methods[i].setAttributePairIndex(isGetterIndex);
   637                     } else {
   638                         // We did not find a matching getter.
   639                         // Forget this setter as an attribute.
   640                         kinds[i] = ATTRIBUTE_NONE;
   641                         names[i] = methods[i].getName();
   642                     }
   643                 }
   644             }
   645         }
   647         // Finally, do the case conversion and set the
   648         // attribute kinds for each method...
   650         for (int i = 0; i < count; i++) {
   652             if (kinds[i] != ATTRIBUTE_NONE) {
   654                 String name = names[i];
   656                 // Is the first character upper case?
   658                 if (Character.isUpperCase(name.charAt(0))) {
   660                     // Yes, is the second?
   662                     if (name.length() == 1 || Character.isLowerCase(name.charAt(1))) {
   664                         // No, so convert the first character to lower case...
   666                         StringBuffer buffer = new StringBuffer(name);
   667                         buffer.setCharAt(0,Character.toLowerCase(name.charAt(0)));
   668                         names[i] = buffer.toString();
   669                     }
   670                 }
   671             }
   673             methods[i].setAttributeKind(kinds[i]);
   674         }
   675     }
   677     /**
   678      * Set all the method names in a given class.
   679      * <p>
   680      * Section 28.3.2.7    (see CompoundType)
   681      * Section 28.3.2.7
   682      * Section 28.3.4.3 (RemoteType/AbstractType only).
   683      */
   684     public static void setMethodNames (CompoundType container,
   685                                        CompoundType.Method[] allMethods,
   686                                        BatchEnvironment env)
   687         throws Exception {
   689         // This method implements the following name mangling sequence:
   690         //
   691         //   1. If methods belong to a Remote interface, identify
   692         //      those which qualify as an attribute under 28.3.4.3.
   693         //      Those that do are referred to as 'attributes' below;
   694         //      those that do not are referred to as 'methods'.
   695         //
   696         //   2. Apply the 28.3.4.3 manglings, except "__", to all
   697         //      attribute names.
   698         //
   699         //   3. Apply all 28.3 manglings, except 28.3.2.7, to all names.
   700         //
   701         //   4. Apply 28.3.2.7 manglings to all method names.
   702         //
   703         //   5. Compare each attribute name to each method name. For
   704         //      any which compare equal, append "__" to the attribute
   705         //      name.
   706         //
   707         //   6. Compare each name (attribute and method) to all others.
   708         //      If any compare equal, throw an Exception with the
   709         //      conflicting name as the message.
   711         int count = allMethods.length;
   713         if (count == 0) return;
   715         // Make an array of all the method names...
   717         String[] names = new String[count];
   718         for (int i = 0; i < count; i++) {
   719             names[i] = allMethods[i].getName();
   720         }
   722         // Are we dealing with a RemoteType, AbstractType, or ValueType?
   724         CompoundType enclosing = allMethods[0].getEnclosing();
   725         if (enclosing.isType(TYPE_REMOTE) ||
   726             enclosing.isType(TYPE_ABSTRACT) ||
   727             enclosing.isType(TYPE_VALUE)) {
   729             // Yes, so we must do the 28.3.4.3 attribute mapping. First, get
   730             // the initial attribute kind of each method...
   732             int[] kinds = new int[count];
   734             for (int i = 0; i < count; i++) {
   735                 kinds[i] = getInitialAttributeKind(allMethods[i],env);
   736             }
   738             // Now set the attribute kind for each method and do the
   739             // 28.3.4.3 name mangling...
   741             setAttributeKinds(allMethods,kinds,names);
   742         }
   744         // Make and populate a new context from our names array...
   746         NameContext context = new NameContext(true);
   748         for (int i = 0; i < count; i++) {
   749             context.put(names[i]);
   750         }
   752         // Apply the appropriate 28.3 manglings to all the names...
   754         boolean haveConstructor = false;
   755         for (int i = 0; i < count; i++) {
   756             if (!allMethods[i].isConstructor()) {
   757                 names[i] = getMemberOrMethodName(context,names[i],env);
   758             } else {
   759                 names[i] = IDL_CONSTRUCTOR;
   760                 haveConstructor = true;
   761             }
   762         }
   764         // Now do the 28.3.2.7 mangling for method name collisions...
   765         // Do this in two passes so that we don't change one during
   766         // the detection of collisions and then miss a real one...
   768         boolean overloaded[] = new boolean[count];
   769         for (int i = 0; i < count; i++) {
   770             overloaded[i] = (!allMethods[i].isAttribute() &&
   771                              !allMethods[i].isConstructor() &&
   772                          doesMethodCollide(names[i],allMethods[i],allMethods,names,true));
   773         }
   774         convertOverloadedMethods(allMethods,names,overloaded);
   776         // Now do the same mangling for constructor name collisions...
   778         for (int i = 0; i < count; i++) {
   779             overloaded[i] = (!allMethods[i].isAttribute() &&
   780                              allMethods[i].isConstructor() &&
   781                              doesConstructorCollide(names[i],allMethods[i],allMethods,names,true));
   782         }
   783         convertOverloadedMethods(allMethods,names,overloaded);
   785         // Now do the 28.3.4.3 mangling for attribute name collisions...
   787         for (int i = 0; i < count; i++) {
   789                 CompoundType.Method method = allMethods[i];
   791             // If this is an attribute name, does it collide with a method?
   793             if (method.isAttribute() &&
   794                 doesMethodCollide(names[i],method,allMethods,names,true)) {
   796                 // Yes, so add double underscore...
   798                     names[i] += "__";
   799                 }
   800             }
   802         // Do the same mangling for any constructors which collide with
   803         // methods...
   805         if (haveConstructor) {
   806         for (int i = 0; i < count; i++) {
   807             CompoundType.Method method = allMethods[i];
   809                 // Is this a constructor which collides with a method?
   811                 if (method.isConstructor() &&
   812                     doesConstructorCollide(names[i],method,allMethods,names,false)) {
   814                 // Yes, so add double underscore...
   816                 names[i] += "__";
   817             }
   818         }
   819         }
   821         // Now see if we have a collision with the container name (28.3.2.9).
   823         String containerName = container.getIDLName();
   824         for (int i = 0; i < count; i++) {
   825             if (names[i].equalsIgnoreCase(containerName)) {
   826                 // Do not add underscore to attributes.
   827                 // Otherwise getFoo will turn into _get_foo_.
   828                 if (! allMethods[i].isAttribute()) {
   829                     names[i] += "_";
   830                 }
   831             }
   832         }
   834         // Now see if we have any collisions (28.3.2.9). If we do,
   835         // it's an error.  Note: a get/set pair does not collide.
   837         for (int i = 0; i < count; i++) {
   839             // Does it collide with any other name?
   841             if (doesMethodCollide(names[i],allMethods[i],allMethods,names,false)) {
   843                 // Yes, so bail...
   845                 throw new Exception(allMethods[i].toString());
   846             }
   847         }
   849         // Ok. We have unique names. Create the appropriate 'wire' name
   850         // for each and set as the 'idl' name. If it is an attribute, also
   851         // set the attribute name...
   853         for (int i = 0; i < count; i++) {
   855             CompoundType.Method method = allMethods[i];
   856             String wireName = names[i];
   858             if (method.isAttribute()) {
   859                 wireName = ATTRIBUTE_WIRE_PREFIX[method.getAttributeKind()] +
   860                     stripLeadingUnderscore(wireName);
   861                 String attributeName = names[i];
   862                 method.setAttributeName(attributeName);
   863             }
   864             method.setIDLName(wireName);
   865         }
   866     }
   868     private static String stripLeadingUnderscore (String name) {
   869         if (name != null && name.length() > 1
   870             && name.charAt(0) == '_')
   871         {
   872             return name.substring(1);
   873         }
   874         return name;
   875     }
   878     private static String stripTrailingUnderscore (String name) {
   879         if (name != null && name.length() > 1 &&
   880             name.charAt(name.length() - 1) == '_')
   881         {
   882             return name.substring(0, name.length() - 1);
   883         }
   884         return name;
   885     }
   888     private static void convertOverloadedMethods(CompoundType.Method[] allMethods,
   889                                                  String[] names,
   890                                                  boolean[] overloaded) {
   892         for (int i = 0; i < names.length; i++) {
   894             // Do we need to mangle it?
   896             if (overloaded[i]) {
   898                 // Yes, so add arguments...
   900                 CompoundType.Method method = allMethods[i];
   901                 Type[] args = method.getArguments();
   903                 for (int k = 0; k < args.length; k++) {
   905                                 // Add the separator...
   907                     names[i] += "__";
   909                                 // Get the fully qualified IDL name, without the "::"
   910                                 // prefix...
   912                     String argIDLName = args[k].getQualifiedIDLName(false);
   914                                 // Replace any occurances of "::_" with "_" to
   915                                 // undo any IDL keyword mangling and do next step
   916                                 // at the same time...
   918                     argIDLName = replace(argIDLName,"::_","_");
   920                                 // Replace any occurances of "::" with "_"...
   922                     argIDLName = replace(argIDLName,"::","_");
   924                                 // Replace any occurances of " " with "_"...
   926                     argIDLName = replace(argIDLName," ","_");
   928                                 // Add the argument type name...
   930                     names[i] += argIDLName;
   931                 }
   933                 if (args.length == 0) {
   934                     names[i] += "__";
   935                 }
   937                 // Remove any IDL keyword mangling...
   939                 names[i] = stripLeadingUnderscore(names[i]);
   940             }
   941         }
   942     }
   944     private static boolean doesMethodCollide (String name,
   945                                               CompoundType.Method method,
   946                                               CompoundType.Method[] allMethods,
   947                                               String[] allNames,
   948                                               boolean ignoreAttributes) {
   950         // Scan all methods looking for a match...
   952         for (int i = 0; i < allMethods.length; i++) {
   954             CompoundType.Method target = allMethods[i];
   956             if (method != target &&                                 // Not same instance
   957                 !target.isConstructor() &&                      // Not a constructor
   958                 (!ignoreAttributes || !target.isAttribute()) && // Correct kind
   959                 name.equals(allNames[i])) {                         // Same names
   961                 // Are we looking at a get/set pair?
   963                 int kind1 = method.getAttributeKind();
   964                 int kind2 = target.getAttributeKind();
   966                 if ((kind1 != ATTRIBUTE_NONE && kind2 != ATTRIBUTE_NONE) &&
   967                     ((kind1 == ATTRIBUTE_SET && kind2 != ATTRIBUTE_SET) ||
   968                      (kind1 != ATTRIBUTE_SET && kind2 == ATTRIBUTE_SET) ||
   969                      // one is a is-getter/setter pair and the other is just a getter
   970                      (kind1 == ATTRIBUTE_IS_RW && kind2 == ATTRIBUTE_GET) ||
   971                      (kind1 == ATTRIBUTE_GET && kind2 == ATTRIBUTE_IS_RW))) {
   973                     // Yes, so ignore it...
   975                 } else {
   977                     // No, so we have a collision...
   979                     return true;
   980                 }
   981             }
   982         }
   984         return false;
   985     }
   987     private static boolean doesConstructorCollide (String name,
   988                                                    CompoundType.Method method,
   989                                                    CompoundType.Method[] allMethods,
   990                                                    String[] allNames,
   991                                                    boolean compareConstructors) {
   993         // Scan all methods looking for a match...
   995         for (int i = 0; i < allMethods.length; i++) {
   997             CompoundType.Method target = allMethods[i];
   999             if (method != target &&                                     // Not same instance
  1000                 (target.isConstructor() == compareConstructors) &&  // Correct kind
  1001                 name.equals(allNames[i])) {                             // Same names
  1003                 // We have a collision...
  1005                 return true;
  1009         return false;
  1013     /**
  1014      * Set all the member names in a given class.
  1015      * <p>
  1016      * Section 28.3.2.7    (see CompoundType)
  1017      * Section 28.3.2.7
  1018      */
  1019     public static void setMemberNames (CompoundType container,
  1020                                        CompoundType.Member[] allMembers,
  1021                                        CompoundType.Method[] allMethods,
  1022                                        BatchEnvironment env)
  1023         throws Exception {
  1025         // Make and populate a new context...
  1027         NameContext context = new NameContext(true);
  1029         for (int i = 0; i < allMembers.length; i++) {
  1030             context.put(allMembers[i].getName());
  1033         // Now set all the idl names...
  1035         for (int i = 0; i < allMembers.length; i++) {
  1037             CompoundType.Member member = allMembers[i];
  1038             String idlName = getMemberOrMethodName(context,member.getName(),env);
  1039             member.setIDLName(idlName);
  1042         // First see if we have a collision with the container name (28.3.2.9).
  1044         String containerName = container.getIDLName();
  1045         for (int i = 0; i < allMembers.length; i++) {
  1046             String name = allMembers[i].getIDLName();
  1047             if (name.equalsIgnoreCase(containerName)) {
  1048                 // REVISIT - How is this different than line 788
  1049                 allMembers[i].setIDLName(name+"_");
  1053         // Check for collisions between member names...
  1055         for (int i = 0; i < allMembers.length; i++) {
  1056             String name = allMembers[i].getIDLName();
  1057             for (int j = 0; j < allMembers.length; j++) {
  1058                 if (i != j && allMembers[j].getIDLName().equals(name)) {
  1060                     // Collision...
  1062                     throw new Exception(name);
  1067         // Now check for collisions between member names and
  1068         // method names...
  1070         boolean changed;
  1071         do {
  1072             changed = false;
  1073             for (int i = 0; i < allMembers.length; i++) {
  1074                 String name = allMembers[i].getIDLName();
  1075                 for (int j = 0; j < allMethods.length; j++) {
  1076                     if (allMethods[j].getIDLName().equals(name)) {
  1078                         // Collision, so append "_" to member name...
  1080                         allMembers[i].setIDLName(name+"_");
  1081                         changed = true;
  1082                         break;
  1086         } while (changed);
  1089     /**
  1090      * Get the name for the specified type code.
  1091      * <p>
  1092      * Section 28.3..3     (see PrimitiveType)
  1093      * Section 28.3.5.10   (see SpecialClassType)
  1094      * Section 28.3.4.1    (see SpecialInterfaceType)
  1095      * Section 28.3.10.1   (see SpecialInterfaceType)
  1096      * Section 28.3.10.2   (see SpecialClassType)
  1097      */
  1098     public static String getTypeName(int typeCode, boolean isConstant) {
  1100         String idlName = null;
  1102         switch (typeCode) {
  1103         case TYPE_VOID:             idlName = IDL_VOID; break;
  1104         case TYPE_BOOLEAN:          idlName = IDL_BOOLEAN; break;
  1105         case TYPE_BYTE:             idlName = IDL_BYTE; break;
  1106         case TYPE_CHAR:             idlName = IDL_CHAR; break;
  1107         case TYPE_SHORT:            idlName = IDL_SHORT; break;
  1108         case TYPE_INT:              idlName = IDL_INT; break;
  1109         case TYPE_LONG:             idlName = IDL_LONG; break;
  1110         case TYPE_FLOAT:            idlName = IDL_FLOAT; break;
  1111         case TYPE_DOUBLE:           idlName = IDL_DOUBLE; break;
  1112         case TYPE_ANY:                  idlName = IDL_ANY; break;
  1113         case TYPE_CORBA_OBJECT: idlName = IDL_CORBA_OBJECT; break;
  1114         case TYPE_STRING:
  1116                 if (isConstant) {
  1117                     idlName = IDL_CONSTANT_STRING;
  1118                 } else {
  1119                     idlName = IDL_STRING;
  1122                 break;
  1126         return idlName;
  1129     /**
  1130      * Create a qualified name.
  1131      */
  1132     public static String getQualifiedName (String[] idlModuleNames, String idlName) {
  1133         String result = null;
  1134         if (idlModuleNames != null && idlModuleNames.length > 0) {
  1135             for (int i = 0; i < idlModuleNames.length;i++) {
  1136                 if (i == 0) {
  1137                     result = idlModuleNames[0];
  1138                 } else {
  1139                     result += IDL_NAME_SEPARATOR;
  1140                     result += idlModuleNames[i];
  1143             result += IDL_NAME_SEPARATOR;
  1144             result += idlName;
  1145         } else {
  1146             result = idlName;
  1148         return result;
  1151     /**
  1152      * Replace substrings
  1153      * @param source The source string.
  1154      * @param match The string to search for within the source string.
  1155      * @param replace The replacement for any matching components.
  1156      * @return
  1157      */
  1158     public static String replace (String source, String match, String replace) {
  1160         int index = source.indexOf(match,0);
  1162         if (index >=0) {
  1164             // We have at least one match, so gotta do the
  1165             // work...
  1167             StringBuffer result = new StringBuffer(source.length() + 16);
  1168             int matchLength = match.length();
  1169             int startIndex = 0;
  1171             while (index >= 0) {
  1172                 result.append(source.substring(startIndex,index));
  1173                 result.append(replace);
  1174                 startIndex = index + matchLength;
  1175                 index = source.indexOf(match,startIndex);
  1178             // Grab the last piece, if any...
  1180             if (startIndex < source.length()) {
  1181                 result.append(source.substring(startIndex));
  1184             return result.toString();
  1186         } else {
  1188             // No matches, just return the source...
  1190             return source;
  1194     /**
  1195      * Get an IDL style repository id for
  1196      */
  1197     public static String getIDLRepositoryID (String idlName) {
  1198         return  IDL_REPOSITORY_ID_PREFIX +
  1199             replace(idlName,"::", "/") +
  1200             IDL_REPOSITORY_ID_VERSION;
  1203     //_____________________________________________________________________
  1204     // Internal Interfaces
  1205     //_____________________________________________________________________
  1208     /**
  1209      * Convert a type or module name.
  1210      * <p>
  1211      * Section 28.3.2.2
  1212      * Section 28.3.2.3
  1213      */
  1214     private static String getTypeOrModuleName (String name) {
  1216         // 28.3.2.3 Leading underscores...
  1218         String result = convertLeadingUnderscores(name);
  1220         // 28.3.2.2 IDL keywords (NOTE: must be done
  1221         // after leading underscore conversion because
  1222         // the mangling for IDL keywords creates a
  1223         // leading underscore!)...
  1225         return convertIDLKeywords(result);

mercurial