0N/A/*
396N/A * Copyright (c) 1998, 2012, Oracle and/or its affiliates. All rights reserved.
0N/A * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
0N/A *
0N/A * This code is free software; you can redistribute it and/or modify it
0N/A * under the terms of the GNU General Public License version 2 only, as
157N/A * published by the Free Software Foundation. Oracle designates this
0N/A * particular file as subject to the "Classpath" exception as provided
157N/A * by Oracle in the LICENSE file that accompanied this code.
0N/A *
0N/A * This code is distributed in the hope that it will be useful, but WITHOUT
0N/A * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
0N/A * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
0N/A * version 2 for more details (a copy is included in the LICENSE file that
0N/A * accompanied this code).
0N/A *
0N/A * You should have received a copy of the GNU General Public License version
0N/A * 2 along with this work; if not, write to the Free Software Foundation,
0N/A * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
0N/A *
157N/A * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
157N/A * or visit www.oracle.com if you need additional information or have any
157N/A * questions.
0N/A */
0N/A
0N/A/*
0N/A * Licensed Materials - Property of IBM
0N/A * RMI-IIOP v1.0
0N/A * Copyright IBM Corp. 1998 1999 All Rights Reserved
0N/A *
0N/A */
0N/A
0N/Apackage sun.rmi.rmic.iiop;
0N/A
0N/Aimport java.util.Hashtable;
0N/Aimport java.util.Locale;
0N/Aimport sun.tools.java.Identifier;
0N/Aimport sun.tools.java.CompilerError;
0N/Aimport sun.tools.java.ClassDefinition;
0N/Aimport sun.tools.java.ClassNotFound;
0N/Aimport com.sun.corba.se.impl.util.RepositoryId;
0N/A
0N/A/**
0N/A * IDLNames provides static utility methods to perform the IDL
0N/A * name mappings specified in Chapter 5 of the Java Language
0N/A * to IDL specification.
0N/A *
0N/A * @author Bryan Atsatt
0N/A */
0N/Apublic class IDLNames implements sun.rmi.rmic.iiop.Constants {
0N/A
0N/A /**
0N/A * Used to convert ascii to hex.
0N/A */
0N/A public static final byte ASCII_HEX[] = {
0N/A (byte)'0',
0N/A (byte)'1',
0N/A (byte)'2',
0N/A (byte)'3',
0N/A (byte)'4',
0N/A (byte)'5',
0N/A (byte)'6',
0N/A (byte)'7',
0N/A (byte)'8',
0N/A (byte)'9',
0N/A (byte)'A',
0N/A (byte)'B',
0N/A (byte)'C',
0N/A (byte)'D',
0N/A (byte)'E',
0N/A (byte)'F',
0N/A };
0N/A
396N/A // Legal IDL Identifier characters (1 = legal). Note
396N/A // that '.' (2E) is marked as legal even though it is
396N/A // not legal in IDL. This allows us to treat a fully
396N/A // qualified Java name with '.' package separators
396N/A // uniformly, and is safe because that is the only
396N/A // legal use of '.' in a Java name.
396N/A
396N/A private static final byte[] IDL_IDENTIFIER_CHARS = {
396N/A
396N/A // 0 1 2 3 4 5 6 7 8 9 a b c d e f
396N/A 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, // 00-0f
396N/A 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, // 10-1f
396N/A 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,1,0, // 20-2f
396N/A 1,1,1,1, 1,1,1,1, 1,1,0,0, 0,0,0,0, // 30-3f
396N/A 0,1,1,1, 1,1,1,1, 1,1,1,1, 1,1,1,1, // 40-4f
396N/A 1,1,1,1, 1,1,1,1, 1,1,1,0, 0,0,0,1, // 50-5f
396N/A 0,1,1,1, 1,1,1,1, 1,1,1,1, 1,1,1,1, // 60-6f
396N/A 1,1,1,1, 1,1,1,1, 1,1,1,0, 0,0,0,0, // 70-7f
396N/A 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, // 80-8f
396N/A 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, // 90-9f
396N/A 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, // a0-af
396N/A 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, // b0-bf
396N/A 1,1,1,1, 1,1,1,1, 1,1,1,1, 1,1,1,1, // c0-cf
396N/A 0,1,1,1, 1,1,1,0, 1,1,1,1, 1,0,0,1, // d0-df
396N/A 1,1,1,1, 1,1,1,1, 1,1,1,1, 1,1,1,1, // e0-ef
396N/A 0,1,1,1, 1,1,1,0, 1,1,1,1, 1,0,0,1, // f0-ff
396N/A };
396N/A
0N/A //_____________________________________________________________________
0N/A // Public Interfaces
0N/A //_____________________________________________________________________
0N/A
0N/A /**
0N/A * Convert a name. The nameContext argument MUST be pre-filled with
0N/A * all names from the appropriate context (e.g. all the method names
0N/A * in a given class). The names must not have had any IDL conversions
0N/A * applied.
0N/A * <p>
0N/A * Section 28.3.2.2
0N/A * Section 28.3.2.3
0N/A * Section 28.3.2.4
0N/A * Section 28.3.2.7 (member and method names only)
0N/A */
0N/A public static String getMemberOrMethodName (NameContext nameContext,
0N/A String name,
0N/A BatchEnvironment env) {
0N/A
0N/A // Check namesCache...
0N/A
0N/A String result = (String) env.namesCache.get(name);
0N/A
0N/A if (result == null) {
0N/A
0N/A // 28.3.2.7 Case sensitive member names.
0N/A
0N/A // Note: This must be done before any of
0N/A // the other conversions!
0N/A
0N/A result = nameContext.get(name);
0N/A
0N/A // 28.3.2.3 Leading underscores...
0N/A
0N/A result = convertLeadingUnderscores(result);
0N/A
0N/A // 28.3.2.2 IDL keywords (NOTE: must be done
0N/A // after leading underscore conversion because
0N/A // the mangling for IDL keywords creates a
0N/A // leading underscore!)...
0N/A
0N/A result = convertIDLKeywords(result);
0N/A
0N/A // 28.3.2.4 Illegal IDL identifier characters...
0N/A
0N/A result = convertToISOLatin1(result);
0N/A
0N/A // Add to namesCache...
0N/A
0N/A env.namesCache.put(name,result);
0N/A }
0N/A
0N/A return result;
0N/A }
0N/A
0N/A /**
0N/A * Convert names with illegal IDL identifier characters.
0N/A * <p>
0N/A * Section 28.3.2.4
0N/A */
0N/A public static String convertToISOLatin1 (String name) {
0N/A
0N/A // First, replace any escape sequences...
0N/A
0N/A String result = replace(name,"x\\u","U");
0N/A result = replace(result,"x\\U","U");
0N/A
0N/A // Now see if we have any remaining illegal characters (see
396N/A // IDL_IDENTIFIER_CHARS array)...
0N/A
0N/A int length = result.length();
0N/A StringBuffer buffer = null;
0N/A
0N/A for (int i = 0; i < length; i++) {
0N/A
0N/A char c = result.charAt(i);
0N/A
396N/A if (c > 255 || IDL_IDENTIFIER_CHARS[c] == 0) {
0N/A
0N/A // We gotta convert. Have we already started?
0N/A
0N/A if (buffer == null) {
0N/A
0N/A // No, so get set up...
0N/A
0N/A buffer = new StringBuffer(result.substring(0,i));
0N/A }
0N/A
0N/A // Convert the character into the IDL escape syntax...
0N/A
0N/A buffer.append("U");
0N/A buffer.append((char)ASCII_HEX[(c & 0xF000) >>> 12]);
0N/A buffer.append((char)ASCII_HEX[(c & 0x0F00) >>> 8]);
0N/A buffer.append((char)ASCII_HEX[(c & 0x00F0) >>> 4]);
0N/A buffer.append((char)ASCII_HEX[(c & 0x000F)]);
0N/A
0N/A } else {
0N/A if (buffer != null) {
0N/A buffer.append(c);
0N/A }
0N/A }
0N/A }
0N/A
0N/A if (buffer != null) {
0N/A result = buffer.toString();
0N/A }
0N/A
0N/A return result;
0N/A }
0N/A
0N/A /**
0N/A * Convert names which collide with IDL keywords.
0N/A * <p>
0N/A * Section 28.3.2.5
0N/A */
0N/A public static String convertIDLKeywords (String name) {
0N/A
0N/A for (int i = 0; i < IDL_KEYWORDS.length; i++) {
0N/A if (name.equalsIgnoreCase(IDL_KEYWORDS[i])) {
0N/A return "_" + name;
0N/A }
0N/A }
0N/A
0N/A return name;
0N/A }
0N/A
0N/A /**
0N/A * Convert names which have leading underscores
0N/A * <p>
0N/A * Section 28.3.2.3
0N/A */
0N/A public static String convertLeadingUnderscores (String name) {
0N/A
0N/A if (name.startsWith("_")) {
0N/A return "J" + name;
0N/A }
0N/A
0N/A return name;
0N/A }
0N/A
0N/A /**
0N/A * Convert a type name.
0N/A * <p>
0N/A * Section 28.3.2.5
0N/A * Section 28.3.2.7 (class or interface names only)
0N/A * Throws exception if fails 28.3.2.7.
0N/A */
0N/A public static String getClassOrInterfaceName (Identifier id,
0N/A BatchEnvironment env) throws Exception {
0N/A
0N/A // Get the type and package name...
0N/A
0N/A String typeName = id.getName().toString();
0N/A String packageName = null;
0N/A
0N/A if (id.isQualified()) {
0N/A packageName = id.getQualifier().toString();
0N/A }
0N/A
0N/A // Check namesCache...
0N/A
0N/A String result = (String) env.namesCache.get(typeName);
0N/A
0N/A if (result == null) {
0N/A
0N/A // 28.3.2.5 Inner classes...
0N/A
0N/A result = replace(typeName,". ","__");
0N/A
0N/A // 28.3.2.4 Illegal identifier characters...
0N/A
0N/A result = convertToISOLatin1(result);
0N/A
0N/A // 28.3.2.7 Case sensitive class or interface names...
0N/A
0N/A NameContext context = NameContext.forName(packageName,false,env);
0N/A context.assertPut(result);
0N/A
0N/A // Run it through the name checks...
0N/A
0N/A result = getTypeOrModuleName(result);
0N/A
0N/A // Add it to the namesCache...
0N/A
0N/A env.namesCache.put(typeName,result);
0N/A }
0N/A
0N/A return result;
0N/A }
0N/A
0N/A /**
0N/A * Convert an Exception name.
0N/A * <p>
0N/A * Section 28.3.7.2 (see ValueType)
0N/A */
0N/A public static String getExceptionName (String idlName) {
0N/A
0N/A String result = idlName;
0N/A// d.11315 Incorrectly mangled exception names
0N/A if (idlName.endsWith(EXCEPTION_SUFFIX)) {
0N/A
0N/A // Remove "Exception" and append "Ex". Strip leading underscore
0N/A // in case the idlName is exactly "_Exception"...
0N/A
0N/A result = stripLeadingUnderscore(idlName.substring(0,idlName.lastIndexOf(EXCEPTION_SUFFIX)) + EX_SUFFIX);
0N/A } else {
0N/A result = idlName + EX_SUFFIX;
0N/A }
0N/A
0N/A return result;
0N/A }
0N/A
0N/A /**
0N/A * Convert a qualified Identifier into an array of IDL names.
0N/A * <p>
0N/A * Section 28.3.2.1 (see CompoundType)
0N/A * Throws exception if fails 28.3.2.7.
0N/A */
0N/A public static String[] getModuleNames (Identifier theID,
0N/A boolean boxIt,
0N/A BatchEnvironment env) throws Exception {
0N/A
0N/A String[] result = null;
0N/A
0N/A if (theID.isQualified()) {
0N/A
0N/A // Extract the qualifier...
0N/A
0N/A Identifier id = theID.getQualifier();
0N/A
0N/A // 28.3.2.7 Case sensitive module names.
0N/A
0N/A env.modulesContext.assertPut(id.toString());
0N/A
0N/A // Count them...
0N/A
0N/A int count = 1;
0N/A Identifier current = id;
0N/A while (current.isQualified()) {
0N/A current = current.getQualifier();
0N/A count++;
0N/A }
0N/A
0N/A result = new String[count];
0N/A int index = count-1;
0N/A current = id;
0N/A
0N/A // Now walk them and fill our array (backwards)...
0N/A
0N/A for (int i = 0; i < count; i++) {
0N/A
0N/A String item = current.getName().toString();
0N/A
0N/A // Check namesCache...
0N/A
0N/A String cachedItem = (String) env.namesCache.get(item);
0N/A
0N/A if (cachedItem == null) {
0N/A
0N/A // 28.3.2.4 Illegal identifier characters...
0N/A
0N/A cachedItem = convertToISOLatin1(item);
0N/A
0N/A // Run it through the name checks...
0N/A
0N/A cachedItem = getTypeOrModuleName(cachedItem);
0N/A
0N/A // Add it to the namesCache...
0N/A
0N/A env.namesCache.put(item,cachedItem);
0N/A }
0N/A
0N/A result[index--] = cachedItem;
0N/A current = current.getQualifier();
0N/A }
0N/A }
0N/A
0N/A
0N/A // If it is supposed to be "boxed", prepend
0N/A // IDL_BOXEDIDL_MODULE...
0N/A
0N/A if (boxIt) {
0N/A if (result == null) {
0N/A result = IDL_BOXEDIDL_MODULE;
0N/A } else {
0N/A String[] boxed = new String[result.length+IDL_BOXEDIDL_MODULE.length];
0N/A System.arraycopy(IDL_BOXEDIDL_MODULE,0,boxed,0,IDL_BOXEDIDL_MODULE.length);
0N/A System.arraycopy(result,0,boxed,IDL_BOXEDIDL_MODULE.length,result.length);
0N/A result = boxed;
0N/A }
0N/A }
0N/A
0N/A return result;
0N/A }
0N/A
0N/A /**
0N/A * Get an array name with the specified dimensions.
0N/A * <p>
0N/A * Section 28.3.6 (see ArrayType)
0N/A */
0N/A public static String getArrayName (Type theType, int arrayDimension) {
0N/A
0N/A StringBuffer idlName = new StringBuffer(64);
0N/A
0N/A // Prefix with seq<n>_...
0N/A
0N/A idlName.append(IDL_SEQUENCE);
0N/A idlName.append(Integer.toString(arrayDimension));
0N/A idlName.append("_");
0N/A
0N/A // Add the type name. We need to map any spaces in the
0N/A // name to "_"...
0N/A
0N/A idlName.append(replace(stripLeadingUnderscore(theType.getIDLName())," ","_"));
0N/A
0N/A // And we're done...
0N/A
0N/A return idlName.toString();
0N/A }
0N/A
0N/A /**
0N/A * Get an array module names.
0N/A */
0N/A public static String[] getArrayModuleNames (Type theType) {
0N/A
0N/A String[] moduleName;
0N/A String[] typeModule = theType.getIDLModuleNames();
0N/A int typeModuleLength = typeModule.length;
0N/A
0N/A // Does the type have a module?
0N/A
0N/A if (typeModuleLength == 0) {
0N/A
0N/A // Nope, so just use the sequence module...
0N/A
0N/A moduleName = IDL_SEQUENCE_MODULE;
0N/A } else {
0N/A
0N/A // Yes, so gotta concatenate...
0N/A
0N/A moduleName = new String[typeModuleLength + IDL_SEQUENCE_MODULE.length];
0N/A System.arraycopy(IDL_SEQUENCE_MODULE,0,moduleName,0,IDL_SEQUENCE_MODULE.length);
0N/A System.arraycopy(typeModule,0,moduleName,IDL_SEQUENCE_MODULE.length,typeModuleLength);
0N/A }
0N/A
0N/A return moduleName;
0N/A }
0N/A
0N/A private static int getInitialAttributeKind (CompoundType.Method method,
0N/A BatchEnvironment env) throws ClassNotFound {
0N/A
0N/A int result = ATTRIBUTE_NONE;
0N/A
0N/A // First make sure it is not a constructor...
0N/A
0N/A if (!method.isConstructor()) {
0N/A
0N/A // Now check exceptions. It may not throw any checked
0N/A // exception other than RemoteException or one of its
0N/A // subclasses...
0N/A
0N/A boolean validExceptions = true;
0N/A ClassType[] exceptions = method.getExceptions();
0N/A
0N/A if (exceptions.length > 0) {
0N/A for (int i = 0; i < exceptions.length; i++) {
0N/A if (exceptions[i].isCheckedException() &&
0N/A !exceptions[i].isRemoteExceptionOrSubclass()) {
0N/A validExceptions = false;
0N/A break;
0N/A }
0N/A }
0N/A } else {
0N/A
0N/A // If this is a ValueType, it is ok to not have any exceptions,
0N/A // otherwise this method does not qualify...
0N/A
0N/A validExceptions = method.getEnclosing().isType(TYPE_VALUE);
0N/A }
0N/A
0N/A if (validExceptions) {
0N/A String name = method.getName();
0N/A int nameLength = name.length();
0N/A int argCount = method.getArguments().length;
0N/A Type returnType = method.getReturnType();
0N/A boolean voidReturn = returnType.isType(TYPE_VOID);
0N/A boolean booleanReturn = returnType.isType(TYPE_BOOLEAN);
0N/A
0N/A // It's a getter if name starts with "get" and it has no arguments
0N/A // and a return type that is not void...
0N/A
0N/A if (name.startsWith("get") && nameLength > 3 && argCount == 0 && !voidReturn) {
0N/A result = ATTRIBUTE_GET;
0N/A } else {
0N/A
0N/A // It's a getter if name starts with "is" and it has no arguments
0N/A // and a boolean return type...
0N/A
0N/A if (name.startsWith("is") && nameLength > 2 && argCount == 0 && booleanReturn) {
0N/A result = ATTRIBUTE_IS;
0N/A } else {
0N/A
0N/A // It's a setter if name starts with "set" and it has 1 argument
0N/A // and a void return type...
0N/A
0N/A if (name.startsWith("set") && nameLength > 3 && argCount == 1 && voidReturn) {
0N/A result = ATTRIBUTE_SET;
0N/A }
0N/A }
0N/A }
0N/A }
0N/A }
0N/A
0N/A return result;
0N/A }
0N/A
0N/A private static void setAttributeKinds (CompoundType.Method[] methods,
0N/A int[] kinds,
0N/A String[] names) {
0N/A
0N/A int count = methods.length;
0N/A
0N/A // Strip the prefixes off of the attribute names...
0N/A
0N/A for (int i = 0; i < count; i++) {
0N/A switch (kinds[i]) {
0N/A case ATTRIBUTE_GET: names[i] = names[i].substring(3); break;
0N/A case ATTRIBUTE_IS: names[i] = names[i].substring(2); break;
0N/A case ATTRIBUTE_SET: names[i] = names[i].substring(3); break;
0N/A }
0N/A }
0N/A
0N/A // Now, we need to look at all the IS attributes to see
0N/A // if there is a corresponding getter or setter which has
0N/A // a different return type. If so, mark it as not an
0N/A // attribute. Do this before checking for invalid setters...
0N/A
0N/A for (int i = 0; i < count; i++) {
0N/A if (kinds[i] == ATTRIBUTE_IS) {
0N/A for (int j = 0; j < count; j++) {
0N/A if (j != i &&
0N/A (kinds[j] == ATTRIBUTE_GET || kinds[j] == ATTRIBUTE_SET) &&
0N/A names[i].equals(names[j])) {
0N/A
0N/A // We have matching getter or setter. Do the types match?
0N/A
0N/A Type isType = methods[i].getReturnType();
0N/A Type targetType;
0N/A
0N/A if (kinds[j] == ATTRIBUTE_GET) {
0N/A targetType = methods[j].getReturnType();
0N/A } else {
0N/A targetType = methods[j].getArguments()[0];
0N/A }
0N/A
0N/A if (!isType.equals(targetType)) {
0N/A
0N/A // No, so forget this guy as an attribute...
0N/A
0N/A kinds[i] = ATTRIBUTE_NONE;
0N/A names[i] = methods[i].getName();
0N/A break;
0N/A }
0N/A }
0N/A }
0N/A }
0N/A }
0N/A
0N/A // Now, we need to look at all the setters to see if there
0N/A // is a corresponding getter. If not, it is not a setter.
0N/A // If there is, change the getter type to _RW and set the
0N/A // pair index...
0N/A
0N/A for (int i = 0; i < count; i++) {
0N/A if (kinds[i] == ATTRIBUTE_SET) {
0N/A int getterIndex = -1;
0N/A int isGetterIndex = -1;
0N/A // First look for is-getters, then for getters.
0N/A // This is preferred for boolean attributes.
0N/A for (int j = 0; j < count; j++) {
0N/A if (j != i && names[i].equals(names[j])) {
0N/A // Yep, is the return type of the getter the same
0N/A // as the argument type of the setter?
0N/A
0N/A Type getterReturn = methods[j].getReturnType();
0N/A Type setterArg = methods[i].getArguments()[0];
0N/A
0N/A if (getterReturn.equals(setterArg)) {
0N/A if (kinds[j] == ATTRIBUTE_IS) {
0N/A isGetterIndex = j;
0N/A // continue looking for another getter
0N/A } else if (kinds[j] == ATTRIBUTE_GET) {
0N/A getterIndex = j;
0N/A // continue looking for an is-getter
0N/A }
0N/A }
0N/A }
0N/A }
0N/A
0N/A if (getterIndex > -1) {
0N/A if (isGetterIndex > -1) {
0N/A // We have both, a boolean is-getter and a boolean getter.
0N/A // Use the is-getter and drop the getter.
0N/A
0N/A // We have a matching getter. Change it to a read-write type...
0N/A kinds[isGetterIndex] = ATTRIBUTE_IS_RW;
0N/A
0N/A // Now set the pair index for both the getter and the setter...
0N/A methods[isGetterIndex].setAttributePairIndex(i);
0N/A methods[i].setAttributePairIndex(isGetterIndex);
0N/A
0N/A // We found a better matching is-getter.
0N/A // Forget this other getter as an attribute.
0N/A kinds[getterIndex] = ATTRIBUTE_NONE;
0N/A names[getterIndex] = methods[getterIndex].getName();
0N/A } else {
0N/A // We only have one getter.
0N/A
0N/A // We have a matching getter. Change it to a read-write type...
0N/A kinds[getterIndex] = ATTRIBUTE_GET_RW;
0N/A
0N/A // Now set the pair index for both the getter and the setter...
0N/A methods[getterIndex].setAttributePairIndex(i);
0N/A methods[i].setAttributePairIndex(getterIndex);
0N/A }
0N/A } else {
0N/A if (isGetterIndex > -1) {
0N/A // We only have one is-getter.
0N/A
0N/A // We have a matching getter. Change it to a read-write type...
0N/A kinds[isGetterIndex] = ATTRIBUTE_IS_RW;
0N/A
0N/A // Now set the pair index for both the getter and the setter...
0N/A methods[isGetterIndex].setAttributePairIndex(i);
0N/A methods[i].setAttributePairIndex(isGetterIndex);
0N/A } else {
0N/A // We did not find a matching getter.
0N/A // Forget this setter as an attribute.
0N/A kinds[i] = ATTRIBUTE_NONE;
0N/A names[i] = methods[i].getName();
0N/A }
0N/A }
0N/A }
0N/A }
0N/A
0N/A // Finally, do the case conversion and set the
0N/A // attribute kinds for each method...
0N/A
0N/A for (int i = 0; i < count; i++) {
0N/A
0N/A if (kinds[i] != ATTRIBUTE_NONE) {
0N/A
0N/A String name = names[i];
0N/A
0N/A // Is the first character upper case?
0N/A
0N/A if (Character.isUpperCase(name.charAt(0))) {
0N/A
0N/A // Yes, is the second?
0N/A
0N/A if (name.length() == 1 || Character.isLowerCase(name.charAt(1))) {
0N/A
0N/A // No, so convert the first character to lower case...
0N/A
0N/A StringBuffer buffer = new StringBuffer(name);
0N/A buffer.setCharAt(0,Character.toLowerCase(name.charAt(0)));
0N/A names[i] = buffer.toString();
0N/A }
0N/A }
0N/A }
0N/A
0N/A methods[i].setAttributeKind(kinds[i]);
0N/A }
0N/A }
0N/A
0N/A /**
0N/A * Set all the method names in a given class.
0N/A * <p>
0N/A * Section 28.3.2.7 (see CompoundType)
0N/A * Section 28.3.2.7
0N/A * Section 28.3.4.3 (RemoteType/AbstractType only).
0N/A */
0N/A public static void setMethodNames (CompoundType container,
0N/A CompoundType.Method[] allMethods,
0N/A BatchEnvironment env)
0N/A throws Exception {
0N/A
0N/A // This method implements the following name mangling sequence:
0N/A //
0N/A // 1. If methods belong to a Remote interface, identify
0N/A // those which qualify as an attribute under 28.3.4.3.
0N/A // Those that do are referred to as 'attributes' below;
0N/A // those that do not are referred to as 'methods'.
0N/A //
0N/A // 2. Apply the 28.3.4.3 manglings, except "__", to all
0N/A // attribute names.
0N/A //
0N/A // 3. Apply all 28.3 manglings, except 28.3.2.7, to all names.
0N/A //
0N/A // 4. Apply 28.3.2.7 manglings to all method names.
0N/A //
0N/A // 5. Compare each attribute name to each method name. For
0N/A // any which compare equal, append "__" to the attribute
0N/A // name.
0N/A //
0N/A // 6. Compare each name (attribute and method) to all others.
0N/A // If any compare equal, throw an Exception with the
0N/A // conflicting name as the message.
0N/A
0N/A int count = allMethods.length;
0N/A
0N/A if (count == 0) return;
0N/A
0N/A // Make an array of all the method names...
0N/A
0N/A String[] names = new String[count];
0N/A for (int i = 0; i < count; i++) {
0N/A names[i] = allMethods[i].getName();
0N/A }
0N/A
0N/A // Are we dealing with a RemoteType, AbstractType, or ValueType?
0N/A
0N/A CompoundType enclosing = allMethods[0].getEnclosing();
0N/A if (enclosing.isType(TYPE_REMOTE) ||
0N/A enclosing.isType(TYPE_ABSTRACT) ||
0N/A enclosing.isType(TYPE_VALUE)) {
0N/A
0N/A // Yes, so we must do the 28.3.4.3 attribute mapping. First, get
0N/A // the initial attribute kind of each method...
0N/A
0N/A int[] kinds = new int[count];
0N/A
0N/A for (int i = 0; i < count; i++) {
0N/A kinds[i] = getInitialAttributeKind(allMethods[i],env);
0N/A }
0N/A
0N/A // Now set the attribute kind for each method and do the
0N/A // 28.3.4.3 name mangling...
0N/A
0N/A setAttributeKinds(allMethods,kinds,names);
0N/A }
0N/A
0N/A // Make and populate a new context from our names array...
0N/A
0N/A NameContext context = new NameContext(true);
0N/A
0N/A for (int i = 0; i < count; i++) {
0N/A context.put(names[i]);
0N/A }
0N/A
0N/A // Apply the appropriate 28.3 manglings to all the names...
0N/A
0N/A boolean haveConstructor = false;
0N/A for (int i = 0; i < count; i++) {
0N/A if (!allMethods[i].isConstructor()) {
0N/A names[i] = getMemberOrMethodName(context,names[i],env);
0N/A } else {
0N/A names[i] = IDL_CONSTRUCTOR;
0N/A haveConstructor = true;
0N/A }
0N/A }
0N/A
0N/A // Now do the 28.3.2.7 mangling for method name collisions...
0N/A // Do this in two passes so that we don't change one during
0N/A // the detection of collisions and then miss a real one...
0N/A
0N/A boolean overloaded[] = new boolean[count];
0N/A for (int i = 0; i < count; i++) {
0N/A overloaded[i] = (!allMethods[i].isAttribute() &&
0N/A !allMethods[i].isConstructor() &&
0N/A doesMethodCollide(names[i],allMethods[i],allMethods,names,true));
0N/A }
0N/A convertOverloadedMethods(allMethods,names,overloaded);
0N/A
0N/A // Now do the same mangling for constructor name collisions...
0N/A
0N/A for (int i = 0; i < count; i++) {
0N/A overloaded[i] = (!allMethods[i].isAttribute() &&
0N/A allMethods[i].isConstructor() &&
0N/A doesConstructorCollide(names[i],allMethods[i],allMethods,names,true));
0N/A }
0N/A convertOverloadedMethods(allMethods,names,overloaded);
0N/A
0N/A // Now do the 28.3.4.3 mangling for attribute name collisions...
0N/A
0N/A for (int i = 0; i < count; i++) {
0N/A
0N/A CompoundType.Method method = allMethods[i];
0N/A
0N/A // If this is an attribute name, does it collide with a method?
0N/A
0N/A if (method.isAttribute() &&
0N/A doesMethodCollide(names[i],method,allMethods,names,true)) {
0N/A
0N/A // Yes, so add double underscore...
0N/A
0N/A names[i] += "__";
0N/A }
0N/A }
0N/A
0N/A // Do the same mangling for any constructors which collide with
0N/A // methods...
0N/A
0N/A if (haveConstructor) {
0N/A for (int i = 0; i < count; i++) {
0N/A CompoundType.Method method = allMethods[i];
0N/A
0N/A // Is this a constructor which collides with a method?
0N/A
0N/A if (method.isConstructor() &&
0N/A doesConstructorCollide(names[i],method,allMethods,names,false)) {
0N/A
0N/A // Yes, so add double underscore...
0N/A
0N/A names[i] += "__";
0N/A }
0N/A }
0N/A }
0N/A
0N/A // Now see if we have a collision with the container name (28.3.2.9).
0N/A
0N/A String containerName = container.getIDLName();
0N/A for (int i = 0; i < count; i++) {
0N/A if (names[i].equalsIgnoreCase(containerName)) {
0N/A // Do not add underscore to attributes.
0N/A // Otherwise getFoo will turn into _get_foo_.
0N/A if (! allMethods[i].isAttribute()) {
0N/A names[i] += "_";
0N/A }
0N/A }
0N/A }
0N/A
0N/A // Now see if we have any collisions (28.3.2.9). If we do,
0N/A // it's an error. Note: a get/set pair does not collide.
0N/A
0N/A for (int i = 0; i < count; i++) {
0N/A
0N/A // Does it collide with any other name?
0N/A
0N/A if (doesMethodCollide(names[i],allMethods[i],allMethods,names,false)) {
0N/A
0N/A // Yes, so bail...
0N/A
0N/A throw new Exception(allMethods[i].toString());
0N/A }
0N/A }
0N/A
0N/A // Ok. We have unique names. Create the appropriate 'wire' name
0N/A // for each and set as the 'idl' name. If it is an attribute, also
0N/A // set the attribute name...
0N/A
0N/A for (int i = 0; i < count; i++) {
0N/A
0N/A CompoundType.Method method = allMethods[i];
0N/A String wireName = names[i];
0N/A
0N/A if (method.isAttribute()) {
0N/A wireName = ATTRIBUTE_WIRE_PREFIX[method.getAttributeKind()] +
0N/A stripLeadingUnderscore(wireName);
0N/A String attributeName = names[i];
0N/A method.setAttributeName(attributeName);
0N/A }
0N/A method.setIDLName(wireName);
0N/A }
0N/A }
0N/A
0N/A private static String stripLeadingUnderscore (String name) {
0N/A if (name != null && name.length() > 1
0N/A && name.charAt(0) == '_')
0N/A {
0N/A return name.substring(1);
0N/A }
0N/A return name;
0N/A }
0N/A
0N/A
0N/A private static String stripTrailingUnderscore (String name) {
0N/A if (name != null && name.length() > 1 &&
0N/A name.charAt(name.length() - 1) == '_')
0N/A {
0N/A return name.substring(0, name.length() - 1);
0N/A }
0N/A return name;
0N/A }
0N/A
0N/A
0N/A private static void convertOverloadedMethods(CompoundType.Method[] allMethods,
0N/A String[] names,
0N/A boolean[] overloaded) {
0N/A
0N/A for (int i = 0; i < names.length; i++) {
0N/A
0N/A // Do we need to mangle it?
0N/A
0N/A if (overloaded[i]) {
0N/A
0N/A // Yes, so add arguments...
0N/A
0N/A CompoundType.Method method = allMethods[i];
0N/A Type[] args = method.getArguments();
0N/A
0N/A for (int k = 0; k < args.length; k++) {
0N/A
0N/A // Add the separator...
0N/A
0N/A names[i] += "__";
0N/A
0N/A // Get the fully qualified IDL name, without the "::"
0N/A // prefix...
0N/A
0N/A String argIDLName = args[k].getQualifiedIDLName(false);
0N/A
0N/A // Replace any occurances of "::_" with "_" to
0N/A // undo any IDL keyword mangling and do next step
0N/A // at the same time...
0N/A
0N/A argIDLName = replace(argIDLName,"::_","_");
0N/A
0N/A // Replace any occurances of "::" with "_"...
0N/A
0N/A argIDLName = replace(argIDLName,"::","_");
0N/A
0N/A // Replace any occurances of " " with "_"...
0N/A
0N/A argIDLName = replace(argIDLName," ","_");
0N/A
0N/A // Add the argument type name...
0N/A
0N/A names[i] += argIDLName;
0N/A }
0N/A
0N/A if (args.length == 0) {
0N/A names[i] += "__";
0N/A }
0N/A
0N/A // Remove any IDL keyword mangling...
0N/A
0N/A names[i] = stripLeadingUnderscore(names[i]);
0N/A }
0N/A }
0N/A }
0N/A
0N/A private static boolean doesMethodCollide (String name,
0N/A CompoundType.Method method,
0N/A CompoundType.Method[] allMethods,
0N/A String[] allNames,
0N/A boolean ignoreAttributes) {
0N/A
0N/A // Scan all methods looking for a match...
0N/A
0N/A for (int i = 0; i < allMethods.length; i++) {
0N/A
0N/A CompoundType.Method target = allMethods[i];
0N/A
0N/A if (method != target && // Not same instance
0N/A !target.isConstructor() && // Not a constructor
0N/A (!ignoreAttributes || !target.isAttribute()) && // Correct kind
0N/A name.equals(allNames[i])) { // Same names
0N/A
0N/A // Are we looking at a get/set pair?
0N/A
0N/A int kind1 = method.getAttributeKind();
0N/A int kind2 = target.getAttributeKind();
0N/A
0N/A if ((kind1 != ATTRIBUTE_NONE && kind2 != ATTRIBUTE_NONE) &&
0N/A ((kind1 == ATTRIBUTE_SET && kind2 != ATTRIBUTE_SET) ||
0N/A (kind1 != ATTRIBUTE_SET && kind2 == ATTRIBUTE_SET) ||
0N/A // one is a is-getter/setter pair and the other is just a getter
0N/A (kind1 == ATTRIBUTE_IS_RW && kind2 == ATTRIBUTE_GET) ||
0N/A (kind1 == ATTRIBUTE_GET && kind2 == ATTRIBUTE_IS_RW))) {
0N/A
0N/A // Yes, so ignore it...
0N/A
0N/A } else {
0N/A
0N/A // No, so we have a collision...
0N/A
0N/A return true;
0N/A }
0N/A }
0N/A }
0N/A
0N/A return false;
0N/A }
0N/A
0N/A private static boolean doesConstructorCollide (String name,
0N/A CompoundType.Method method,
0N/A CompoundType.Method[] allMethods,
0N/A String[] allNames,
0N/A boolean compareConstructors) {
0N/A
0N/A // Scan all methods looking for a match...
0N/A
0N/A for (int i = 0; i < allMethods.length; i++) {
0N/A
0N/A CompoundType.Method target = allMethods[i];
0N/A
0N/A if (method != target && // Not same instance
0N/A (target.isConstructor() == compareConstructors) && // Correct kind
0N/A name.equals(allNames[i])) { // Same names
0N/A
0N/A // We have a collision...
0N/A
0N/A return true;
0N/A }
0N/A }
0N/A
0N/A return false;
0N/A }
0N/A
0N/A
0N/A /**
0N/A * Set all the member names in a given class.
0N/A * <p>
0N/A * Section 28.3.2.7 (see CompoundType)
0N/A * Section 28.3.2.7
0N/A */
0N/A public static void setMemberNames (CompoundType container,
0N/A CompoundType.Member[] allMembers,
0N/A CompoundType.Method[] allMethods,
0N/A BatchEnvironment env)
0N/A throws Exception {
0N/A
0N/A // Make and populate a new context...
0N/A
0N/A NameContext context = new NameContext(true);
0N/A
0N/A for (int i = 0; i < allMembers.length; i++) {
0N/A context.put(allMembers[i].getName());
0N/A }
0N/A
0N/A // Now set all the idl names...
0N/A
0N/A for (int i = 0; i < allMembers.length; i++) {
0N/A
0N/A CompoundType.Member member = allMembers[i];
0N/A String idlName = getMemberOrMethodName(context,member.getName(),env);
0N/A member.setIDLName(idlName);
0N/A }
0N/A
0N/A // First see if we have a collision with the container name (28.3.2.9).
0N/A
0N/A String containerName = container.getIDLName();
0N/A for (int i = 0; i < allMembers.length; i++) {
0N/A String name = allMembers[i].getIDLName();
0N/A if (name.equalsIgnoreCase(containerName)) {
0N/A // REVISIT - How is this different than line 788
0N/A allMembers[i].setIDLName(name+"_");
0N/A }
0N/A }
0N/A
0N/A // Check for collisions between member names...
0N/A
0N/A for (int i = 0; i < allMembers.length; i++) {
0N/A String name = allMembers[i].getIDLName();
0N/A for (int j = 0; j < allMembers.length; j++) {
0N/A if (i != j && allMembers[j].getIDLName().equals(name)) {
0N/A
0N/A // Collision...
0N/A
0N/A throw new Exception(name);
0N/A }
0N/A }
0N/A }
0N/A
0N/A // Now check for collisions between member names and
0N/A // method names...
0N/A
0N/A boolean changed;
0N/A do {
0N/A changed = false;
0N/A for (int i = 0; i < allMembers.length; i++) {
0N/A String name = allMembers[i].getIDLName();
0N/A for (int j = 0; j < allMethods.length; j++) {
0N/A if (allMethods[j].getIDLName().equals(name)) {
0N/A
0N/A // Collision, so append "_" to member name...
0N/A
0N/A allMembers[i].setIDLName(name+"_");
0N/A changed = true;
0N/A break;
0N/A }
0N/A }
0N/A }
0N/A } while (changed);
0N/A }
0N/A
0N/A /**
0N/A * Get the name for the specified type code.
0N/A * <p>
0N/A * Section 28.3..3 (see PrimitiveType)
0N/A * Section 28.3.5.10 (see SpecialClassType)
0N/A * Section 28.3.4.1 (see SpecialInterfaceType)
0N/A * Section 28.3.10.1 (see SpecialInterfaceType)
0N/A * Section 28.3.10.2 (see SpecialClassType)
0N/A */
0N/A public static String getTypeName(int typeCode, boolean isConstant) {
0N/A
0N/A String idlName = null;
0N/A
0N/A switch (typeCode) {
0N/A case TYPE_VOID: idlName = IDL_VOID; break;
0N/A case TYPE_BOOLEAN: idlName = IDL_BOOLEAN; break;
0N/A case TYPE_BYTE: idlName = IDL_BYTE; break;
0N/A case TYPE_CHAR: idlName = IDL_CHAR; break;
0N/A case TYPE_SHORT: idlName = IDL_SHORT; break;
0N/A case TYPE_INT: idlName = IDL_INT; break;
0N/A case TYPE_LONG: idlName = IDL_LONG; break;
0N/A case TYPE_FLOAT: idlName = IDL_FLOAT; break;
0N/A case TYPE_DOUBLE: idlName = IDL_DOUBLE; break;
0N/A case TYPE_ANY: idlName = IDL_ANY; break;
0N/A case TYPE_CORBA_OBJECT: idlName = IDL_CORBA_OBJECT; break;
0N/A case TYPE_STRING:
0N/A {
0N/A if (isConstant) {
0N/A idlName = IDL_CONSTANT_STRING;
0N/A } else {
0N/A idlName = IDL_STRING;
0N/A }
0N/A
0N/A break;
0N/A }
0N/A }
0N/A
0N/A return idlName;
0N/A }
0N/A
0N/A /**
0N/A * Create a qualified name.
0N/A */
0N/A public static String getQualifiedName (String[] idlModuleNames, String idlName) {
0N/A String result = null;
0N/A if (idlModuleNames != null && idlModuleNames.length > 0) {
0N/A for (int i = 0; i < idlModuleNames.length;i++) {
0N/A if (i == 0) {
0N/A result = idlModuleNames[0];
0N/A } else {
0N/A result += IDL_NAME_SEPARATOR;
0N/A result += idlModuleNames[i];
0N/A }
0N/A }
0N/A result += IDL_NAME_SEPARATOR;
0N/A result += idlName;
0N/A } else {
0N/A result = idlName;
0N/A }
0N/A return result;
0N/A }
0N/A
0N/A /**
0N/A * Replace substrings
0N/A * @param source The source string.
0N/A * @param match The string to search for within the source string.
0N/A * @param replace The replacement for any matching components.
0N/A * @return
0N/A */
0N/A public static String replace (String source, String match, String replace) {
0N/A
0N/A int index = source.indexOf(match,0);
0N/A
0N/A if (index >=0) {
0N/A
0N/A // We have at least one match, so gotta do the
0N/A // work...
0N/A
0N/A StringBuffer result = new StringBuffer(source.length() + 16);
0N/A int matchLength = match.length();
0N/A int startIndex = 0;
0N/A
0N/A while (index >= 0) {
0N/A result.append(source.substring(startIndex,index));
0N/A result.append(replace);
0N/A startIndex = index + matchLength;
0N/A index = source.indexOf(match,startIndex);
0N/A }
0N/A
0N/A // Grab the last piece, if any...
0N/A
0N/A if (startIndex < source.length()) {
0N/A result.append(source.substring(startIndex));
0N/A }
0N/A
0N/A return result.toString();
0N/A
0N/A } else {
0N/A
0N/A // No matches, just return the source...
0N/A
0N/A return source;
0N/A }
0N/A }
0N/A
0N/A /**
0N/A * Get an IDL style repository id for
0N/A */
0N/A public static String getIDLRepositoryID (String idlName) {
0N/A return IDL_REPOSITORY_ID_PREFIX +
0N/A replace(idlName,"::", "/") +
0N/A IDL_REPOSITORY_ID_VERSION;
0N/A }
0N/A
0N/A //_____________________________________________________________________
0N/A // Internal Interfaces
0N/A //_____________________________________________________________________
0N/A
0N/A
0N/A /**
0N/A * Convert a type or module name.
0N/A * <p>
0N/A * Section 28.3.2.2
0N/A * Section 28.3.2.3
0N/A */
0N/A private static String getTypeOrModuleName (String name) {
0N/A
0N/A // 28.3.2.3 Leading underscores...
0N/A
0N/A String result = convertLeadingUnderscores(name);
0N/A
0N/A // 28.3.2.2 IDL keywords (NOTE: must be done
0N/A // after leading underscore conversion because
0N/A // the mangling for IDL keywords creates a
0N/A // leading underscore!)...
0N/A
0N/A return convertIDLKeywords(result);
0N/A }
0N/A}