FileDocCategorySizeDatePackage
IDLTypesUtil.javaAPI DocJava SE 5 API18827Fri Aug 26 14:54:30 BST 2005com.sun.corba.se.impl.presentation.rmi

IDLTypesUtil

public class IDLTypesUtil extends Object
Utility class for testing RMI/IDL Types as defined in Section 1.2 of The Java Language to IDL Mapping. Note that these are static checks only. Runtime checks, such as those described in Section 1.2.3, #3, are not covered.

Fields Summary
private static final String
GET_PROPERTY_PREFIX
private static final String
SET_PROPERTY_PREFIX
private static final String
IS_PROPERTY_PREFIX
public static final int
VALID_TYPE
public static final int
INVALID_TYPE
public static final boolean
FOLLOW_RMIC
Constructors Summary
Methods Summary
public java.lang.StringgetAttributeNameForProperty(java.lang.String propertyName)

        String attributeName = null;
        String prefix = null;

        if( propertyName.startsWith(GET_PROPERTY_PREFIX) ) {
            prefix = GET_PROPERTY_PREFIX;           
        } else if( propertyName.startsWith(SET_PROPERTY_PREFIX) ) {
            prefix = SET_PROPERTY_PREFIX;
        } else if( propertyName.startsWith(IS_PROPERTY_PREFIX) ) {
            prefix = IS_PROPERTY_PREFIX;
        }

        if( (prefix != null) && (prefix.length() < propertyName.length()) ) {
            String remainder = propertyName.substring(prefix.length());
            if( (remainder.length() >= 2) && 
                Character.isUpperCase(remainder.charAt(0)) &&
                Character.isUpperCase(remainder.charAt(1)) ) {
                // don't set the first letter to lower-case if the 
                // first two are upper-case
                attributeName = remainder;
            } else {
                attributeName = Character.toLowerCase(remainder.charAt(0)) +
                    remainder.substring(1);
            }
        }

        return attributeName;
    
public IDLTypegetPrimitiveIDLTypeMapping(java.lang.Class c)
Return IDL Type name for primitive types as defined in Section 1.3.3 of Java2IDL spec or null if not a primitive type.

               
        if( c == null ) {
            throw new IllegalArgumentException();
        } 

        if( c.isPrimitive() ) {            
            if( c == Void.TYPE ) {
		return new IDLType( c, "void" ) ;
            } else if( c == Boolean.TYPE ) {
		return new IDLType( c, "boolean" ) ;
            } else if( c == Character.TYPE ) {
		return new IDLType( c, "wchar" ) ;
            } else if( c == Byte.TYPE ) {
		return new IDLType( c, "octet" ) ;
            } else if( c == Short.TYPE ) {
		return new IDLType( c, "short" ) ;
            } else if( c == Integer.TYPE ) {
		return new IDLType( c, "long" ) ;
            } else if( c == Long.TYPE ) {
		return new IDLType( c, "long_long" ) ;
            } else if( c == Float.TYPE ) {
		return new IDLType( c, "float" ) ;
            } else if( c == Double.TYPE ) {
		return new IDLType( c, "double" ) ;
            }
        }
        
        return null;
    
public IDLTypegetSpecialCaseIDLTypeMapping(java.lang.Class c)
Return IDL Type name for special case type mappings as defined in Table 1-1 of Java2IDL spec or null if given class is not a special type.


        if( c == null ) {
            throw new IllegalArgumentException();
        } 

        if( c == java.lang.Object.class ) {
	    return new IDLType( c, new String[] { "java", "lang" },
		"Object" ) ;
        } else if( c == java.lang.String.class ) {
	    return new IDLType( c, new String[] { "CORBA" },
		"WStringValue" ) ;
        } else if( c == java.lang.Class.class ) {
	    return new IDLType( c, new String[] { "javax", "rmi", "CORBA" },
		"ClassDesc" ) ;
        } else if( c == java.io.Serializable.class ) {
	    return new IDLType( c, new String[] { "java", "io" },
		"Serializable" ) ;
        } else if( c == java.io.Externalizable.class ) {
	    return new IDLType( c, new String[] { "java", "io" },
		"Externalizable" ) ;
        } else if( c == java.rmi.Remote.class ) {
	    return new IDLType( c, new String[] { "java", "rmi" },
		"Remote" ) ;
        } else if( c == org.omg.CORBA.Object.class ) {
	    return new IDLType( c, "Object" ) ;
        } else {
            return null;
        }
    
private booleanhasCorrespondingReadProperty(java.lang.reflect.Method writeProperty, java.lang.Class c, java.lang.String readPropertyPrefix)

        String writePropertyMethodName = writeProperty.getName();
        Class[] writePropertyParameters = writeProperty.getParameterTypes();
        boolean foundReadProperty = false;

        try {            
            // Look for a valid corresponding Read property
            String readPropertyMethodName = 
                writePropertyMethodName.replaceFirst
                    (SET_PROPERTY_PREFIX, readPropertyPrefix);
            Method readPropertyMethod = c.getMethod(readPropertyMethodName, 
                                                    new Class[] {});
            foundReadProperty = 
                ( isPropertyAccessorMethod(readPropertyMethod, c) &&
                  (readPropertyMethod.getReturnType() == 
                   writePropertyParameters[0]) );
        } catch(Exception e) {
            // ignore. this means we didn't find a corresponding get property.
        }

        return foundReadProperty;
    
public booleanisArray(java.lang.Class c)
Section 1.2.5

        boolean arrayType = false;

        if( c == null ) {
            throw new IllegalArgumentException();
        } 

        if( c.isArray() ) {
            Class componentType = c.getComponentType();
            arrayType =
                (isPrimitive(componentType) || isRemoteInterface(componentType) ||
                 isEntity(componentType) || isException(componentType) || 
		 isValue(componentType) || isObjectReference(componentType) );
        }

        return arrayType;
    
public booleanisCheckedException(java.lang.Class c)

        if( c == null ) {
            throw new IllegalArgumentException();
        } 

        return Throwable.class.isAssignableFrom(c) &&
            !RuntimeException.class.isAssignableFrom(c) &&
            !Error.class.isAssignableFrom(c) ;
    
public booleanisEntity(java.lang.Class c)
Section 1.2.8

        if( c == null ) {
            throw new IllegalArgumentException();
        } 

        Class superClass = c.getSuperclass();
        return (!c.isInterface() &&
                (superClass != null) && 
                (org.omg.CORBA.portable.IDLEntity.class.isAssignableFrom(c)));
    
public booleanisException(java.lang.Class c)
Section 1.2.6

        if( c == null ) {
            throw new IllegalArgumentException();
        } 

        // Must be a checked exception, not including RemoteException or
        // its subclasses.
        return isCheckedException(c) && !isRemoteException(c) && isValue(c);
    
private booleanisHasCorrespondingReadProperty(java.lang.reflect.Method readProperty, java.lang.Class c)

	if (!FOLLOW_RMIC)
	    return false ;

        String readPropertyMethodName = readProperty.getName();
        boolean foundIsProperty = false;

        try {            
            // Look for a valid corresponding Read property
            String isPropertyMethodName = 
                readPropertyMethodName.replaceFirst(IS_PROPERTY_PREFIX, 
		    GET_PROPERTY_PREFIX);
            Method isPropertyMethod = c.getMethod( isPropertyMethodName, 
                                                    new Class[] {});
            foundIsProperty = isPropertyAccessorMethod(isPropertyMethod, 
		c) ; 
        } catch(Exception e) {
            // ignore. this means we didn't find a corresponding read property.
        }

        return foundIsProperty;
    
public booleanisObjectReference(java.lang.Class c)
Section 1.2.7

        if( c == null ) {
            throw new IllegalArgumentException();
        } 

        return (c.isInterface() && 
                org.omg.CORBA.Object.class.isAssignableFrom(c));
    
public booleanisPrimitive(java.lang.Class c)
Section 1.2.2 Primitive Types

        if( c == null ) {
            throw new IllegalArgumentException();
        } 

        return c.isPrimitive();
    
public booleanisPropertyAccessorMethod(java.lang.reflect.Method m, java.lang.Class c)
Return true if given method is legal property accessor as defined in Section 1.3.4.3 of Java2IDL spec.

        
        String methodName = m.getName();
        Class returnType  = m.getReturnType();
        Class[] parameters = m.getParameterTypes();
        Class[] exceptionTypes = m.getExceptionTypes();
        String propertyType = null;

        if( methodName.startsWith(GET_PROPERTY_PREFIX) ) {

            if((parameters.length == 0) && (returnType != Void.TYPE) &&
		!readHasCorrespondingIsProperty(m, c)) {
                propertyType = GET_PROPERTY_PREFIX;
            }
           
        } else if( methodName.startsWith(SET_PROPERTY_PREFIX) ) {
            
            if((returnType == Void.TYPE) && (parameters.length == 1)) {
                if (hasCorrespondingReadProperty(m, c, GET_PROPERTY_PREFIX) ||
                    hasCorrespondingReadProperty(m, c, IS_PROPERTY_PREFIX)) {
                    propertyType = SET_PROPERTY_PREFIX;
                }
            }

        } else if( methodName.startsWith(IS_PROPERTY_PREFIX) ) {
            if((parameters.length == 0) && (returnType == Boolean.TYPE) &&
		!isHasCorrespondingReadProperty(m, c)) {
                propertyType = IS_PROPERTY_PREFIX;             
            }
        }

        // Some final checks that apply to all properties.  
        if( propertyType != null ) {
            if(!validPropertyExceptions(m) || 
               (methodName.length() <= propertyType.length())) {
                propertyType = null;
            }                                       
        }

        return (propertyType != null);
    
public booleanisRemoteException(java.lang.Class c)

        if( c == null ) {
            throw new IllegalArgumentException();
        } 

	return java.rmi.RemoteException.class.isAssignableFrom(c) ;
    
private booleanisRemoteExceptionOrSuperClass(java.lang.Class c)
Implements Section 1.2.3, #2.

        return 
            ((c == java.rmi.RemoteException.class) ||
             (c == java.io.IOException.class) ||
             (c == java.lang.Exception.class) ||
             (c == java.lang.Throwable.class));
    
public booleanisRemoteInterface(java.lang.Class c)

        boolean remoteInterface = true;
        try {
            validateRemoteInterface(c);
        } catch(IDLTypeException ite) {
            remoteInterface = false;
        }

        return remoteInterface;
    
public booleanisValue(java.lang.Class c)
Section 1.2.4

        if( c == null ) {
            throw new IllegalArgumentException();
        } 

        return 
            (!c.isInterface() &&
             java.io.Serializable.class.isAssignableFrom(c) &&
             !java.rmi.Remote.class.isAssignableFrom(c));
    
private booleanreadHasCorrespondingIsProperty(java.lang.reflect.Method readProperty, java.lang.Class c)

	if (FOLLOW_RMIC)
	    return false ;

        String readPropertyMethodName = readProperty.getName();
        boolean foundIsProperty = false;

        try {            
            // Look for a valid corresponding Is property
            String isPropertyMethodName = 
                readPropertyMethodName.replaceFirst(GET_PROPERTY_PREFIX, 
		    IS_PROPERTY_PREFIX);
            Method isPropertyMethod = c.getMethod( isPropertyMethodName, 
                                                    new Class[] {});
            foundIsProperty = isPropertyAccessorMethod(isPropertyMethod, 
		c) ; 
        } catch(Exception e) {
            // ignore. this means we didn't find a corresponding Is property.
        }

        return foundIsProperty;
    
private booleanvalidPropertyExceptions(java.lang.reflect.Method method)
Returns true if the method's throw clause conforms to the exception restrictions for properties as defined in Section 1.3.4.3 of Java2IDL spec. This means that for all exceptions E declared on the method, E isChecked => RemoteException.isAssignableFrom( E ).

        Class[] exceptions = method.getExceptionTypes();
         
        for(int eIndex = 0; eIndex < exceptions.length; eIndex++) {
            Class exception = exceptions[eIndex];

	    if (isCheckedException(exception) && !isRemoteException(exception)) 
		return false ;
        }

        return true;
    
private voidvalidateConstants(java.lang.Class c)
Implements 1.2.3 #6


        Field[] fields = null;

        try {
            fields = (Field[])
                java.security.AccessController.doPrivileged
                (new java.security.PrivilegedExceptionAction() {
                        public java.lang.Object run() throws Exception {
                            return c.getFields();
                        }
                    });
        } catch(java.security.PrivilegedActionException pae) {
            IDLTypeException ite = new IDLTypeException();
            ite.initCause(pae);
            throw ite;
        }
   
        for(int i = 0; i < fields.length; i++) {
            Field next = fields[i];
            Class fieldType = next.getType();
            if( (fieldType != java.lang.String.class) &&
                !isPrimitive(fieldType) ) {
                String msg = "Constant field '" + next.getName() + 
                    "' in class '" + next.getDeclaringClass().getName() + 
                    "' has invalid type' " + next.getType() + "'. Constants" +
                    " in RMI/IIOP interfaces can only have primitive" + 
                    " types and java.lang.String types.";
                throw new IDLTypeException(msg);
            }
        }


        return;
    
private voidvalidateDirectInterfaces(java.lang.Class c)
Implements Section 1.2.3, #5.


        Class[] directInterfaces = c.getInterfaces();

        if( directInterfaces.length < 2 ) {
            return;
        }

        Set allMethodNames = new HashSet();
        Set currentMethodNames = new HashSet();

        for(int i = 0; i < directInterfaces.length; i++) {
            Class next = directInterfaces[i];
            Method[] methods = next.getMethods();

            // Comparison is based on method names only.  First collect
            // all methods from current interface, eliminating duplicate
            // names.
            currentMethodNames.clear();
            for(int m = 0; m < methods.length; m++) {
                currentMethodNames.add(methods[m].getName());
            }

            // Now check each method against list of all unique method
            // names processed so far.
            for(Iterator iter=currentMethodNames.iterator(); iter.hasNext();) {
                String methodName = (String) iter.next();
                if( allMethodNames.contains(methodName) ) {
                    String msg = "Class " + c + " inherits method " + 
                        methodName + " from multiple direct interfaces.";
                    throw new IDLTypeException(msg);
                } else {
                    allMethodNames.add(methodName);
                }
            }
        }

        return;
    
private voidvalidateExceptions(java.lang.reflect.Method method)
Implements 1.2.3 #2 and #4

        
        Class[] exceptions = method.getExceptionTypes();

        boolean declaresRemoteExceptionOrSuperClass = false;

        // Section 1.2.3, #2
        for(int eIndex = 0; eIndex < exceptions.length; eIndex++) {
            Class exception = exceptions[eIndex];
            if( isRemoteExceptionOrSuperClass(exception) ) {
                declaresRemoteExceptionOrSuperClass = true;
                break;
            }
        }

        if( !declaresRemoteExceptionOrSuperClass ) {
            String msg = "Method '" + method + "' must throw at least one " +
                "exception of type java.rmi.RemoteException or one of its " +
                "super-classes";
            throw new IDLTypeException(msg);
        } 

        // Section 1.2.3, #4
	// See also bug 4972402
	// For all exceptions E in exceptions, 
	// (isCheckedException(E) => (isValue(E) || RemoteException.isAssignableFrom( E ) )
        for(int eIndex = 0; eIndex < exceptions.length; eIndex++) {
            Class exception = exceptions[eIndex];

	    if (isCheckedException(exception) && !isValue(exception) && 
		!isRemoteException(exception)) 
	    {
		String msg = "Exception '" + exception + "' on method '" +
		    method + "' is not a allowed RMI/IIOP exception type";
		throw new IDLTypeException(msg);
            }
        }

        return;
    
public voidvalidateRemoteInterface(java.lang.Class c)
Validate a class to ensure it conforms to the rules for a Java RMI/IIOP interface.

throws
IDLTypeException if not a valid RMI/IIOP interface.


                                
         
    
        if( c == null ) {
            throw new IllegalArgumentException();
        } 

        if( !c.isInterface() ) {
            String msg = "Class " + c + " must be a java interface.";
            throw new IDLTypeException(msg);
        }

        if( !java.rmi.Remote.class.isAssignableFrom(c) ) {
            String msg = "Class " + c + " must extend java.rmi.Remote, " +
                "either directly or indirectly.";
            throw new IDLTypeException(msg);
        }

        // Get all methods, including super-interface methods.
        Method[] methods = c.getMethods();
        
        for(int i = 0; i < methods.length; i++) {
            Method next = methods[i];
            validateExceptions(next);
        }
        
	// Removed because of bug 4989053
        // validateDirectInterfaces(c);
        validateConstants(c);

        return;