Thu, 24 May 2018 16:41:12 +0800
Merge
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;
1006 }
1007 }
1009 return false;
1010 }
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());
1031 }
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);
1040 }
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+"_");
1050 }
1051 }
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);
1063 }
1064 }
1065 }
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;
1083 }
1084 }
1085 }
1086 } while (changed);
1087 }
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:
1115 {
1116 if (isConstant) {
1117 idlName = IDL_CONSTANT_STRING;
1118 } else {
1119 idlName = IDL_STRING;
1120 }
1122 break;
1123 }
1124 }
1126 return idlName;
1127 }
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];
1141 }
1142 }
1143 result += IDL_NAME_SEPARATOR;
1144 result += idlName;
1145 } else {
1146 result = idlName;
1147 }
1148 return result;
1149 }
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);
1176 }
1178 // Grab the last piece, if any...
1180 if (startIndex < source.length()) {
1181 result.append(source.substring(startIndex));
1182 }
1184 return result.toString();
1186 } else {
1188 // No matches, just return the source...
1190 return source;
1191 }
1192 }
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;
1201 }
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);
1226 }
1227 }