Methods Summary |
---|
private void | buildNameTranslation()
// holds method info, keyed by method
Map allMethodInfo = new HashMap() ;
for (int ctr=0; ctr<interf_.length; ctr++) {
Class interf = interf_[ctr] ;
IDLTypesUtil idlTypesUtil = new IDLTypesUtil();
final Method[] methods = interf.getMethods();
// Handle the case of a non-public interface!
AccessController.doPrivileged(new PrivilegedAction() {
public Object run() {
Method.setAccessible( methods, true ) ;
return null ;
}
} ) ;
// Take an initial pass through all the methods and create some
// information that will be used to track the IDL name
// transformation.
for(int i = 0; i < methods.length; i++) {
Method nextMethod = methods[i];
IDLMethodInfo methodInfo = new IDLMethodInfo();
methodInfo.method = nextMethod;
if (idlTypesUtil.isPropertyAccessorMethod(nextMethod, interf)) {
methodInfo.isProperty = true;
String attributeName = idlTypesUtil.
getAttributeNameForProperty(nextMethod.getName());
methodInfo.originalName = attributeName;
methodInfo.mangledName = attributeName;
} else {
methodInfo.isProperty = false;
methodInfo.originalName = nextMethod.getName();
methodInfo.mangledName = nextMethod.getName();
}
allMethodInfo.put(nextMethod, methodInfo);
}
}
//
// Perform case sensitivity test first. This applies to all
// method names AND attributes. Compare each method name and
// attribute to all other method names and attributes. If names
// differ only in case, apply mangling as defined in section 1.3.2.7
// of Java2IDL spec. Note that we compare using the original names.
//
for(Iterator outerIter=allMethodInfo.values().iterator();
outerIter.hasNext();) {
IDLMethodInfo outer = (IDLMethodInfo) outerIter.next();
for(Iterator innerIter = allMethodInfo.values().iterator();
innerIter.hasNext();) {
IDLMethodInfo inner = (IDLMethodInfo) innerIter.next();
if( (outer != inner) &&
(!outer.originalName.equals(inner.originalName)) &&
outer.originalName.equalsIgnoreCase(inner.originalName) ) {
outer.mangledName =
mangleCaseSensitiveCollision(outer.originalName);
break;
}
}
}
for(Iterator iter = allMethodInfo.values().iterator();
iter.hasNext();) {
IDLMethodInfo next = (IDLMethodInfo) iter.next();
next.mangledName =
mangleIdentifier(next.mangledName, next.isProperty);
}
//
// Now check for overloaded method names and apply 1.3.2.6.
//
for(Iterator outerIter=allMethodInfo.values().iterator();
outerIter.hasNext();) {
IDLMethodInfo outer = (IDLMethodInfo) outerIter.next();
if( outer.isProperty ) {
continue;
}
for(Iterator innerIter = allMethodInfo.values().iterator();
innerIter.hasNext();) {
IDLMethodInfo inner = (IDLMethodInfo) innerIter.next();
if( (outer != inner) &&
!inner.isProperty &&
outer.originalName.equals(inner.originalName) ) {
outer.mangledName = mangleOverloadedMethod
(outer.mangledName, outer.method);
break;
}
}
}
//
// Now mangle any properties that clash with method names.
//
for(Iterator outerIter=allMethodInfo.values().iterator();
outerIter.hasNext();) {
IDLMethodInfo outer = (IDLMethodInfo) outerIter.next();
if( !outer.isProperty ) {
continue;
}
for(Iterator innerIter = allMethodInfo.values().iterator();
innerIter.hasNext();) {
IDLMethodInfo inner = (IDLMethodInfo) innerIter.next();
if( (outer != inner) &&
!inner.isProperty &&
outer.mangledName.equals(inner.mangledName) ) {
outer.mangledName = outer.mangledName +
ATTRIBUTE_METHOD_CLASH_MANGLE_CHARS;
break;
}
}
}
//
// Ensure that no mapped method names clash with mapped name
// of container(1.3.2.9). This is a case insensitive comparison.
//
for (int ctr=0; ctr<interf_.length; ctr++ ) {
Class interf = interf_[ctr] ;
String mappedContainerName = getMappedContainerName(interf);
for(Iterator iter = allMethodInfo.values().iterator();
iter.hasNext();) {
IDLMethodInfo next = (IDLMethodInfo) iter.next();
if( !next.isProperty &&
identifierClashesWithContainer(mappedContainerName,
next.mangledName)) {
next.mangledName = mangleContainerClash(next.mangledName);
}
}
}
//
// Populate name translation maps.
//
methodToIDLNameMap_ = new HashMap();
IDLNameToMethodMap_ = new HashMap();
methods_ = (Method[])allMethodInfo.keySet().toArray(
new Method[0] ) ;
for(Iterator iter = allMethodInfo.values().iterator();
iter.hasNext();) {
IDLMethodInfo next = (IDLMethodInfo) iter.next();
String idlName = next.mangledName;
if( next.isProperty ) {
String origMethodName = next.method.getName();
String prefix = "";
if( origMethodName.startsWith("get") ) {
prefix = GET_ATTRIBUTE_PREFIX;
} else if( origMethodName.startsWith("set") ) {
prefix = SET_ATTRIBUTE_PREFIX;
} else {
prefix = IS_ATTRIBUTE_PREFIX;
}
idlName = prefix + next.mangledName;
}
methodToIDLNameMap_.put(next.method, idlName);
// Final check to see if there are any clashes after all the
// manglings have been applied. If so, this is treated as an
// invalid interface. Currently, we do a CASE-SENSITIVE
// comparison since that matches the rmic behavior.
// @@@ Shouldn't this be a case-insensitive check?
if( IDLNameToMethodMap_.containsKey(idlName) ) {
// @@@ I18N
Method clash = (Method) IDLNameToMethodMap_.get(idlName);
throw new IllegalStateException("Error : methods " +
clash + " and " + next.method +
" both result in IDL name '" + idlName + "'");
} else {
IDLNameToMethodMap_.put(idlName, next.method);
}
}
return;
|
public static java.lang.String | charToUnicodeRepresentation(char c)Returns Unicode mangling as defined in Section 1.3.2.4 of
Java2IDL spec.
"For Java identifiers that contain illegal OMG IDL identifier
characters such as '$' or Unicode characters outside of ISO Latin 1,
any such illegal characters are replaced by "U" followed by the
4 hexadecimal characters(in upper case) representing the Unicode
value. So, the Java name a$b is mapped to aU0024b and
x\u03bCy is mapped to xU03BCy."
int orig = (int) c;
StringBuffer hexString = new StringBuffer();
int value = orig;
while( value > 0 ) {
int div = value / 16;
int mod = value % 16;
hexString.insert(0, HEX_DIGITS[mod]);
value = div;
}
int numZerosToAdd = 4 - hexString.length();
for(int i = 0; i < numZerosToAdd; i++) {
hexString.insert(0, "0");
}
hexString.insert(0, "U");
return hexString.toString();
|
private static com.sun.corba.se.impl.presentation.rmi.IDLType | classToIDLType(java.lang.Class c)
IDLType idlType = null;
IDLTypesUtil idlTypesUtil = new IDLTypesUtil();
if( idlTypesUtil.isPrimitive(c) ) {
idlType = idlTypesUtil.getPrimitiveIDLTypeMapping(c);
} else if( c.isArray() ) {
// Calculate array depth, as well as base element type.
Class componentType = c.getComponentType();
int numArrayDimensions = 1;
while(componentType.isArray()) {
componentType = componentType.getComponentType();
numArrayDimensions++;
}
IDLType componentIdlType = classToIDLType(componentType);
String[] modules = BASE_IDL_ARRAY_MODULE_TYPE;
if( componentIdlType.hasModule() ) {
modules = (String[])ObjectUtility.concatenateArrays( modules,
componentIdlType.getModules() ) ;
}
String memberName = BASE_IDL_ARRAY_ELEMENT_TYPE +
numArrayDimensions + UNDERSCORE +
componentIdlType.getMemberName();
idlType = new IDLType(c, modules, memberName);
} else {
idlType = idlTypesUtil.getSpecialCaseIDLTypeMapping(c);
if (idlType == null) {
// Section 1.3.2.5 of Java2IDL spec defines mangling rules for
// inner classes.
String memberName = getUnmappedContainerName(c);
// replace inner class separator with double underscore
memberName = memberName.replaceAll("\\$",
INNER_CLASS_SEPARATOR);
if( hasLeadingUnderscore(memberName) ) {
memberName = mangleLeadingUnderscore(memberName);
}
// Get raw package name. If there is a package, it
// will still have the "." separators and none of the
// mangling rules will have been applied.
String packageName = getPackageName(c);
if (packageName == null) {
idlType = new IDLType( c, memberName ) ;
} else {
// If this is a generated IDL Entity Type we need to
// prepend org_omg_boxedIDL per sections 1.3.5 and 1.3.9
if (idlTypesUtil.isEntity(c)) {
packageName = "org.omg.boxedIDL." + packageName ;
}
// Section 1.3.2.1 and 1.3.2.6 of Java2IDL spec defines
// rules for mapping java packages to IDL modules and for
// mangling module name portion of type name. NOTE that
// of the individual identifier mangling rules,
// only the leading underscore test is done here.
// The other two(IDL Keyword, Illegal Unicode chars) are
// done in mangleOverloadedMethodName.
StringTokenizer tokenizer =
new StringTokenizer(packageName, ".");
String[] modules = new String[ tokenizer.countTokens() ] ;
int index = 0 ;
while (tokenizer.hasMoreElements()) {
String next = tokenizer.nextToken();
String moreMangled = hasLeadingUnderscore( next ) ?
mangleLeadingUnderscore( next ) : next;
modules[index++] = moreMangled ;
}
idlType = new IDLType(c, modules, memberName);
}
}
}
return idlType;
|
public static com.sun.corba.se.spi.presentation.rmi.IDLNameTranslator | get(java.lang.Class interf)Return an IDLNameTranslator for the given interface.
return new IDLNameTranslatorImpl(new Class[] { interf } );
|
public static com.sun.corba.se.spi.presentation.rmi.IDLNameTranslator | get(java.lang.Class[] interfaces)Return an IDLNameTranslator for the given interfacex.
return new IDLNameTranslatorImpl(interfaces );
|
public static java.lang.String | getExceptionId(java.lang.Class cls)
// Requirements for this method:
// 1. cls must be an exception but not a RemoteException.
// 2. If cls has an IDL keyword name, an underscore is prepended (1.3.2.2).
// 3. If cls jas a leading underscore, J is prepended (1.3.2.3).
// 4. If cls has an illegal IDL ident char, it is mapped to UXXXX where
// XXXX is the unicode value in hex of the char (1.3.2.4).
// 5. double underscore for inner class (1.3.2.5).
// 6. The ID is "IDL:" + name with / separators + ":1.0".
IDLType itype = classToIDLType( cls ) ;
return itype.getExceptionName() ;
|
public java.lang.String | getIDLName(java.lang.reflect.Method method)
return (String) methodToIDLNameMap_.get(method);
|
public java.lang.Class[] | getInterfaces()
return interf_;
|
private static java.lang.String | getMappedContainerName(java.lang.Class c)
String unmappedName = getUnmappedContainerName(c);
return mangleIdentifier(unmappedName);
|
public java.lang.reflect.Method | getMethod(java.lang.String idlName)
return (Method) IDLNameToMethodMap_.get(idlName);
|
public java.lang.reflect.Method[] | getMethods()
return methods_ ;
|
private static java.lang.String | getPackageName(java.lang.Class c)Return Class' package name or null if there is no package.
Package thePackage = c.getPackage();
String packageName = null;
// Try to get package name by introspection. Some classloaders might
// not provide this information, so check for null.
if( thePackage != null ) {
packageName = thePackage.getName();
} else {
// brute force method
String fullyQualifiedClassName = c.getName();
int lastDot = fullyQualifiedClassName.indexOf('.");
packageName = (lastDot == -1) ? null :
fullyQualifiedClassName.substring(0, lastDot);
}
return packageName;
|
private static java.lang.String | getUnmappedContainerName(java.lang.Class c)Return portion of class name excluding package name.
String memberName = null;
String packageName = getPackageName(c);
String fullyQualifiedClassName = c.getName();
if( packageName != null ) {
int packageLength = packageName.length();
memberName = fullyQualifiedClassName.substring(packageLength + 1);
} else {
memberName = fullyQualifiedClassName;
}
return memberName;
|
private static boolean | hasLeadingUnderscore(java.lang.String identifier)Checks whether a java identifier starts with an underscore.
Used to implement section 1.3.2.3 of Java2IDL spec.
return identifier.startsWith(UNDERSCORE);
|
private static boolean | identifierClashesWithContainer(java.lang.String mappedContainerName, java.lang.String identifier)Implements Section 1.3.2.9 of Java2IDL Mapping. Container in this
context means the name of the java Class(excluding package) in which
the identifier is defined. Comparison is case-insensitive.
return identifier.equalsIgnoreCase(mappedContainerName);
|
private static boolean | isIDLAlphabeticChar(char c)True if character is one of 114 Alphabetic characters as
specified in Table 2 of Chapter 3 in CORBA spec.
// NOTE that we can't use the java.lang.Character
// isUpperCase, isLowerCase, etc. methods since they
// include many characters other than the Alphabetic list in
// the CORBA spec. Instead, we test for inclusion in the
// Unicode value ranges for the corresponding legal characters.
boolean alphaChar =
(
// A - Z
((c >= 0x0041) && (c <= 0x005A))
||
// a - z
((c >= 0x0061) && (c <= 0x007A))
||
// other letter uppercase, other letter lowercase, which is
// the entire upper half of C1 Controls except X and /
((c >= 0x00C0) && (c <= 0x00FF)
&& (c != 0x00D7) && (c != 0x00F7)));
return alphaChar;
|
private static boolean | isIDLDecimalDigit(char c)True if character is one of 10 Decimal Digits
specified in Table 3 of Chapter 3 in CORBA spec.
return ( (c >= 0x0030) && (c <= 0x0039) );
|
private static boolean | isIDLIdentifier(java.lang.String identifier)
boolean isIdentifier = true;
for(int i = 0; i < identifier.length(); i++) {
char nextChar = identifier.charAt(i);
// 1st char must be alphbetic.
isIdentifier = (i == 0) ?
isIDLAlphabeticChar(nextChar) :
isIDLIdentifierChar(nextChar);
if( !isIdentifier ) {
break;
}
}
return isIdentifier;
|
private static boolean | isIDLIdentifierChar(char c)
return (isIDLAlphabeticChar(c) ||
isIDLDecimalDigit(c) ||
isUnderscore(c));
|
static boolean | isIDLKeyword(java.lang.String identifier)Checks whether a java identifier clashes with an
IDL keyword. Note that this is a case-insensitive
comparison.
Used to implement section 1.3.2.2 of Java2IDL spec.
String identifierAllCaps = identifier.toUpperCase();
return idlKeywords_.contains(identifierAllCaps);
|
private static boolean | isUnderscore(char c)
return ( c == 0x005F );
|
public static void | main(java.lang.String[] args)
Class remoteInterface = java.rmi.Remote.class;
if( args.length > 0 ) {
String className = args[0];
try {
remoteInterface = Class.forName(className);
} catch(Exception e) {
e.printStackTrace();
System.exit(-1);
}
}
System.out.println("Building name translation for " + remoteInterface);
try {
IDLNameTranslator nameTranslator =
IDLNameTranslatorImpl.get(remoteInterface);
System.out.println(nameTranslator);
} catch(IllegalStateException ise) {
ise.printStackTrace();
}
|
java.lang.String | mangleCaseSensitiveCollision(java.lang.String identifier)Implements mangling portion of Section 1.3.2.7 of Java2IDL spec.
This method only deals with the actual mangling. Decision about
whether case-sensitive collision mangling is required is made
elsewhere.
"...a mangled name is generated consisting of the original name
followed by an underscore separated list of decimal indices
into the string, where the indices identify all the upper case
characters in the original string. Indices are zero based."
StringBuffer mangledIdentifier = new StringBuffer(identifier);
// There is always at least one trailing underscore, whether or
// not the identifier has uppercase letters.
mangledIdentifier.append(UNDERSCORE);
boolean needUnderscore = false;
for(int i = 0; i < identifier.length(); i++) {
char next = identifier.charAt(i);
if( Character.isUpperCase(next) ) {
// This bit of logic is needed to ensure that we have
// an underscore separated list of indices but no
// trailing underscores. Basically, after we have at least
// one uppercase letter, we always put an undercore before
// printing the next one.
if( needUnderscore ) {
mangledIdentifier.append(UNDERSCORE);
}
mangledIdentifier.append(i);
needUnderscore = true;
}
}
return mangledIdentifier.toString();
|
private static java.lang.String | mangleContainerClash(java.lang.String identifier)
return identifier + ID_CONTAINER_CLASH_CHAR;
|
static java.lang.String | mangleIDLKeywordClash(java.lang.String identifier)
return UNDERSCORE + identifier;
|
private static java.lang.String | mangleIdentifier(java.lang.String identifier)Perform all necessary stand-alone identifier mangling operations
on a java identifier that is being transformed into an IDL name.
That is, mangling operations that don't require looking at anything
else but the identifier itself. This covers sections 1.3.2.2, 1.3.2.3,
and 1.3.2.4 of the Java2IDL spec. Method overloading and
case-sensitivity checks are handled elsewhere.
return mangleIdentifier(identifier, false);
|
private static java.lang.String | mangleIdentifier(java.lang.String identifier, boolean attribute)
String mangledName = identifier;
//
// Apply leading underscore test (1.3.2.3)
// This should be done before IDL Keyword clash test, since clashing
// IDL keywords are mangled by adding a leading underscore.
//
if( hasLeadingUnderscore(mangledName) ) {
mangledName = mangleLeadingUnderscore(mangledName);
}
//
// Apply IDL keyword clash test (1.3.2.2).
// This is not needed for attributes since when the full property
// name is composed it cannot clash with an IDL keyword.
// (Also, rmic doesn't do it.)
//
if( !attribute && isIDLKeyword(mangledName) ) {
mangledName = mangleIDLKeywordClash(mangledName);
}
//
// Replace illegal IDL identifier characters (1.3.2.4)
// for all method names and attributes.
//
if( !isIDLIdentifier(mangledName) ) {
mangledName = mangleUnicodeChars(mangledName);
}
return mangledName;
|
private static java.lang.String | mangleLeadingUnderscore(java.lang.String identifier)
return LEADING_UNDERSCORE_CHAR + identifier;
|
private static java.lang.String | mangleOverloadedMethod(java.lang.String mangledName, java.lang.reflect.Method m)Mangle an overloaded method name as defined in Section 1.3.2.6 of
Java2IDL spec. Current value of method name is passed in as argument.
We can't start from original method name since the name might have
been partially mangled as a result of the other rules.
IDLTypesUtil idlTypesUtil = new IDLTypesUtil();
// Start by appending the separator string
String newMangledName = mangledName + OVERLOADED_TYPE_SEPARATOR;
Class[] parameterTypes = m.getParameterTypes();
for(int i = 0; i < parameterTypes.length; i++) {
Class nextParamType = parameterTypes[i];
if( i > 0 ) {
newMangledName = newMangledName + OVERLOADED_TYPE_SEPARATOR;
}
IDLType idlType = classToIDLType(nextParamType);
String moduleName = idlType.getModuleName();
String memberName = idlType.getMemberName();
String typeName = (moduleName.length() > 0) ?
moduleName + UNDERSCORE + memberName : memberName;
if( !idlTypesUtil.isPrimitive(nextParamType) &&
(idlTypesUtil.getSpecialCaseIDLTypeMapping(nextParamType)
== null) &&
isIDLKeyword(typeName) ) {
typeName = mangleIDLKeywordClash(typeName);
}
typeName = mangleUnicodeChars(typeName);
newMangledName = newMangledName + typeName;
}
return newMangledName;
|
static java.lang.String | mangleUnicodeChars(java.lang.String identifier)Implements Section 1.3.2.4 of Java2IDL Mapping.
All non-IDL identifier characters must be replaced
with their Unicode representation.
StringBuffer mangledIdentifier = new StringBuffer();
for(int i = 0; i < identifier.length(); i++) {
char nextChar = identifier.charAt(i);
if( isIDLIdentifierChar(nextChar) ) {
mangledIdentifier.append(nextChar);
} else {
String unicode = charToUnicodeRepresentation(nextChar);
mangledIdentifier.append(unicode);
}
}
return mangledIdentifier.toString();
|
public java.lang.String | toString()
StringBuffer contents = new StringBuffer();
contents.append("IDLNameTranslator[" );
for( int ctr=0; ctr<interf_.length; ctr++) {
if (ctr != 0)
contents.append( " " ) ;
contents.append( interf_[ctr].getName() ) ;
}
contents.append("]\n");
for(Iterator iter = methodToIDLNameMap_.keySet().iterator();
iter.hasNext();) {
Method method = (Method) iter.next();
String idlName = (String) methodToIDLNameMap_.get(method);
contents.append(idlName + ":" + method + "\n");
}
return contents.toString();
|