src/share/classes/com/sun/corba/se/impl/presentation/rmi/IDLTypesUtil_save.sjava

Fri, 09 Aug 2013 14:24:17 +0100

author
chegar
date
Fri, 09 Aug 2013 14:24:17 +0100
changeset 518
0717fc6f2960
parent 355
9cdcc0152526
permissions
-rw-r--r--

Merge

     1 /*
     2  * Copyright (c) 2004, 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 package com.sun.corba.se.impl.presentation.rmi ;
    28 import java.lang.reflect.Method;
    29 import java.lang.reflect.Field;
    30 import java.util.Set;
    31 import java.util.HashSet;
    32 import java.util.Iterator;
    34 /**
    35  * Utility class for testing RMI/IDL Types as defined in
    36  * Section 1.2 of The Java Language to IDL Mapping.  Note that
    37  * these are static checks only.  Runtime checks, such as those
    38  * described in Section 1.2.3, #3, are not covered.
    39  */
    40 public class IDLTypesUtil {
    42     public static final String JAVA_GET_PROPERTY_PREFIX = "get";
    43     public static final String JAVA_SET_PROPERTY_PREFIX = "set";
    44     public static final String JAVA_IS_PROPERTY_PREFIX  = "is";
    46     public static final int VALID_TYPE   = 0;
    47     public static final int INVALID_TYPE = 1;
    49     /**
    50      * Validate a class to ensure it conforms to the rules for a
    51      * Java RMI/IIOP interface.
    52      *
    53      * @throws IDLTypeException if not a valid RMI/IIOP interface.
    54      */
    55     public void validateRemoteInterface(Class c) throws IDLTypeException
    56     {
    57         if( c == null ) {
    58             throw new IllegalArgumentException();
    59         } 
    61         if( !c.isInterface() ) {
    62             String msg = "Class " + c + " must be a java interface.";
    63             throw new IDLTypeException(msg);
    64         }
    66         if( !java.rmi.Remote.class.isAssignableFrom(c) ) {
    67             String msg = "Class " + c + " must extend java.rmi.Remote, " +
    68                 "either directly or indirectly.";
    69             throw new IDLTypeException(msg);
    70         }
    72         // Get all methods, including super-interface methods.
    73         Method[] methods = c.getMethods();
    75         for(int i = 0; i < methods.length; i++) {
    76             Method next = methods[i];
    77             validateExceptions(next);
    78         }
    80 	// Removed because of bug 4989053
    81         // validateDirectInterfaces(c);
    82         validateConstants(c);
    84         return;
    85     }
    87     public boolean isRemoteInterface(Class c)     
    88     {
    89         boolean remoteInterface = true;
    90         try {
    91             validateRemoteInterface(c);
    92         } catch(IDLTypeException ite) {
    93             remoteInterface = false;
    94         }
    96         return remoteInterface;
    97     }
    99     /**
   100      * Section 1.2.2 Primitive Types
   101      */ 
   102     public boolean isPrimitive(Class c) 
   103     {
   104         if( c == null ) {
   105             throw new IllegalArgumentException();
   106         } 
   108         return c.isPrimitive();
   109     }
   111     /**
   112      * Section 1.2.4
   113      */
   114     public boolean isValue(Class c) 
   115     {
   116         if( c == null ) {
   117             throw new IllegalArgumentException();
   118         } 
   120         return 
   121             (!c.isInterface() &&
   122              java.io.Serializable.class.isAssignableFrom(c) &&
   123              !java.rmi.Remote.class.isAssignableFrom(c));
   124     }
   126     /**
   127      * Section 1.2.5
   128      */
   129     public boolean isArray(Class c) 
   130     {
   131         boolean arrayType = false;
   133         if( c == null ) {
   134             throw new IllegalArgumentException();
   135         } 
   137         if( c.isArray() ) {
   138             Class componentType = c.getComponentType();
   139             arrayType =
   140                 (isPrimitive(componentType) || isRemoteInterface(componentType) ||
   141                  isEntity(componentType) || isException(componentType) || 
   142 		 isValue(componentType) || isObjectReference(componentType) );
   143         }
   145         return arrayType;
   146     }
   148     /**
   149      * Section 1.2.6
   150      */
   151     public boolean isException(Class c) 
   152     {
   153         if( c == null ) {
   154             throw new IllegalArgumentException();
   155         } 
   157         // Must be a checked exception, not including RemoteException or
   158         // its subclasses.
   159         return isCheckedException(c) && !isRemoteException(c) && isValue(c);
   160     }
   162     public boolean isRemoteException(Class c)
   163     {
   164         if( c == null ) {
   165             throw new IllegalArgumentException();
   166         } 
   168 	return java.rmi.RemoteException.class.isAssignableFrom(c) ;
   169     }
   171     public boolean isCheckedException(Class c) 
   172     {
   173         if( c == null ) {
   174             throw new IllegalArgumentException();
   175         } 
   177         return Throwable.class.isAssignableFrom(c) &&
   178             !RuntimeException.class.isAssignableFrom(c) &&
   179             !Error.class.isAssignableFrom(c) ;
   180     }
   182     /**
   183      * Section 1.2.7
   184      */ 
   185     public boolean isObjectReference(Class c) 
   186     {
   187         if( c == null ) {
   188             throw new IllegalArgumentException();
   189         } 
   191         return (c.isInterface() && 
   192                 org.omg.CORBA.Object.class.isAssignableFrom(c));
   193     }
   195     /**
   196      * Section 1.2.8
   197      */ 
   198     public boolean isEntity(Class c)
   199     {
   200         if( c == null ) {
   201             throw new IllegalArgumentException();
   202         } 
   204         Class superClass = c.getSuperclass();
   205         return (!c.isInterface() &&
   206                 (superClass != null) && 
   207                 (org.omg.CORBA.portable.IDLEntity.class.isAssignableFrom(c)));
   208     }
   210     public String javaPropertyPrefixToIDL( String javaPrefix )
   211     {
   212 	return "_" + javaPrefix + "_" ;
   213     }
   215     /**
   216      * Return the property type if given method is legal property accessor as defined in 
   217      * Section 1.3.4.3 of Java2IDL spec.  Result is one of: JAVA_GET_PROPERTY_PREFIX,
   218      * JAVA_SET_PROPERTY_PREFIX, JAVA_IS_PROPERTY_PREFIX.
   219      */
   220     public String propertyAccessorMethodType(Method m, Class c) {
   222         String methodName = m.getName();
   223         Class returnType  = m.getReturnType();
   224         Class[] parameters = m.getParameterTypes();
   225         Class[] exceptionTypes = m.getExceptionTypes();
   226         String propertyType = null;
   228         if( methodName.startsWith(JAVA_GET_PROPERTY_PREFIX) ) {
   230             if((parameters.length == 0) && (returnType != Void.TYPE) &&
   231 		!hasCorrespondingReadProperty(m, c, JAVA_IS_PROPERTY_PREFIX) {
   232                 propertyType = JAVA_GET_PROPERTY_PREFIX;
   233             }
   235         } else if( methodName.startsWith(JAVA_SET_PROPERTY_PREFIX) ) {
   237             if((returnType == Void.TYPE) && (parameters.length == 1)) {
   238                 if (hasCorrespondingReadProperty(m, c, JAVA_GET_PROPERTY_PREFIX) ||
   239                     hasCorrespondingReadProperty(m, c, JAVA_IS_PROPERTY_PREFIX)) {
   240                     propertyType = JAVA_SET_PROPERTY_PREFIX;
   241                 }
   242             }
   244         } else if( methodName.startsWith(JAVA_IS_PROPERTY_PREFIX) ) {
   245             if((parameters.length == 0) && (returnType == Boolean.TYPE)) {
   246                 propertyType = JAVA_IS_PROPERTY_PREFIX;             
   247             }
   248         }
   250         // Some final checks that apply to all properties.  
   251         if( propertyType != null ) {
   252             if(!validPropertyExceptions(m) || 
   253                (methodName.length() <= propertyType.length())) {
   254                 propertyType = null;
   255             }                                       
   256         }
   258         return propertyType ;
   259     }
   261     private boolean hasCorrespondingReadProperty
   262         (Method writeProperty, Class c, String readPropertyPrefix) {
   264         String writePropertyMethodName = writeProperty.getName();
   265         Class[] writePropertyParameters = writeProperty.getParameterTypes();
   266         boolean foundReadProperty = false;
   268         try {            
   269             // Look for a valid corresponding Read property
   270             String readPropertyMethodName = 
   271                 writePropertyMethodName.replaceFirst
   272                     (JAVA_SET_PROPERTY_PREFIX, readPropertyPrefix);
   273             Method readPropertyMethod = c.getMethod(readPropertyMethodName, 
   274                                                     new Class[] {});
   275             foundReadProperty = 
   276                 ((propertyAccessorMethodType(readPropertyMethod, c) != null) &&
   277                  (readPropertyMethod.getReturnType() == 
   278                    writePropertyParameters[0]));
   279         } catch(Exception e) {
   280             // ignore. this means we didn't find a corresponding get property.
   281         }
   283         return foundReadProperty;
   284     }
   286     public String getAttributeNameForProperty(String propertyName) {
   287         String attributeName = null;
   288         String prefix = null;
   290         if( propertyName.startsWith(JAVA_GET_PROPERTY_PREFIX) ) {
   291             prefix = JAVA_GET_PROPERTY_PREFIX;           
   292         } else if( propertyName.startsWith(JAVA_SET_PROPERTY_PREFIX) ) {
   293             prefix = JAVA_SET_PROPERTY_PREFIX;
   294         } else if( propertyName.startsWith(JAVA_IS_PROPERTY_PREFIX) ) {
   295             prefix = JAVA_IS_PROPERTY_PREFIX;
   296         }
   298         if( (prefix != null) && (prefix.length() < propertyName.length()) ) {
   299             String remainder = propertyName.substring(prefix.length());
   300             if( (remainder.length() >= 2) && 
   301                 Character.isUpperCase(remainder.charAt(0)) &&
   302                 Character.isUpperCase(remainder.charAt(1)) ) {
   303                 // don't set the first letter to lower-case if the 
   304                 // first two are upper-case
   305                 attributeName = remainder;
   306             } else {
   307                 attributeName = Character.toLowerCase(remainder.charAt(0)) +
   308                     remainder.substring(1);
   309             }
   310         }
   312         return attributeName;
   313     }
   315     /**
   316      * Return IDL Type name for primitive types as defined in 
   317      * Section 1.3.3 of Java2IDL spec or null if not a primitive type.
   318      */ 
   319     public IDLType getPrimitiveIDLTypeMapping(Class c) {
   321         if( c == null ) {
   322             throw new IllegalArgumentException();
   323         } 
   325         if( c.isPrimitive() ) {            
   326             if( c == Void.TYPE ) {
   327 		return new IDLType( c, "void" ) ;
   328             } else if( c == Boolean.TYPE ) {
   329 		return new IDLType( c, "boolean" ) ;
   330             } else if( c == Character.TYPE ) {
   331 		return new IDLType( c, "wchar" ) ;
   332             } else if( c == Byte.TYPE ) {
   333 		return new IDLType( c, "octet" ) ;
   334             } else if( c == Short.TYPE ) {
   335 		return new IDLType( c, "short" ) ;
   336             } else if( c == Integer.TYPE ) {
   337 		return new IDLType( c, "long" ) ;
   338             } else if( c == Long.TYPE ) {
   339 		return new IDLType( c, "long_long" ) ;
   340             } else if( c == Float.TYPE ) {
   341 		return new IDLType( c, "float" ) ;
   342             } else if( c == Double.TYPE ) {
   343 		return new IDLType( c, "double" ) ;
   344             }
   345         }
   347         return null;
   348     }
   350     /**
   351      * Return IDL Type name for special case type mappings as defined in
   352      * Table 1-1 of Java2IDL spec or null if given class is not a special
   353      * type.
   354      */
   355     public IDLType getSpecialCaseIDLTypeMapping(Class c) {
   357         if( c == null ) {
   358             throw new IllegalArgumentException();
   359         } 
   361         if( c == java.lang.Object.class ) {
   362 	    return new IDLType( c, new String[] { "java", "lang" },
   363 		"Object" ) ;
   364         } else if( c == java.lang.String.class ) {
   365 	    return new IDLType( c, new String[] { "CORBA" },
   366 		"WStringValue" ) ;
   367         } else if( c == java.lang.Class.class ) {
   368 	    return new IDLType( c, new String[] { "javax", "rmi", "CORBA" },
   369 		"ClassDesc" ) ;
   370         } else if( c == java.io.Serializable.class ) {
   371 	    return new IDLType( c, new String[] { "java", "io" },
   372 		"Serializable" ) ;
   373         } else if( c == java.io.Externalizable.class ) {
   374 	    return new IDLType( c, new String[] { "java", "io" },
   375 		"Externalizable" ) ;
   376         } else if( c == java.rmi.Remote.class ) {
   377 	    return new IDLType( c, new String[] { "java", "rmi" },
   378 		"Remote" ) ;
   379         } else if( c == org.omg.CORBA.Object.class ) {
   380 	    return new IDLType( c, "Object" ) ;
   381         } else {
   382             return null;
   383         }
   384     }
   386     /**
   387      * Implements 1.2.3 #2 and #4
   388      */
   389     private void validateExceptions(Method method) throws IDLTypeException {
   391         Class[] exceptions = method.getExceptionTypes();
   393         boolean declaresRemoteExceptionOrSuperClass = false;
   395         // Section 1.2.3, #2
   396         for(int eIndex = 0; eIndex < exceptions.length; eIndex++) {
   397             Class exception = exceptions[eIndex];
   398             if( isRemoteExceptionOrSuperClass(exception) ) {
   399                 declaresRemoteExceptionOrSuperClass = true;
   400                 break;
   401             }
   402         }
   404         if( !declaresRemoteExceptionOrSuperClass ) {
   405             String msg = "Method '" + method + "' must throw at least one " +
   406                 "exception of type java.rmi.RemoteException or one of its " +
   407                 "super-classes";
   408             throw new IDLTypeException(msg);
   409         } 
   411         // Section 1.2.3, #4
   412 	// See also bug 4972402
   413 	// For all exceptions E in exceptions, 
   414 	// (isCheckedException(E) => (isValue(E) || RemoteException.isAssignableFrom( E ) )
   415         for(int eIndex = 0; eIndex < exceptions.length; eIndex++) {
   416             Class exception = exceptions[eIndex];
   418 	    if (isCheckedException(exception) && !isValue(exception) && 
   419 		!isRemoteException(exception)) 
   420 	    {
   421 		String msg = "Exception '" + exception + "' on method '" +
   422 		    method + "' is not a allowed RMI/IIOP exception type";
   423 		throw new IDLTypeException(msg);
   424             }
   425         }
   427         return;
   428     }
   430     /**
   431      * Returns true if the method's throw clause conforms to the exception 
   432      * restrictions for properties as defined in Section 1.3.4.3 of 
   433      * Java2IDL spec.  This means that for all exceptions E declared on the
   434      * method, E isChecked => RemoteException.isAssignableFrom( E ). 
   435      */
   436     private boolean validPropertyExceptions(Method method) 
   437     {
   438         Class[] exceptions = method.getExceptionTypes();
   440         for(int eIndex = 0; eIndex < exceptions.length; eIndex++) {
   441             Class exception = exceptions[eIndex];
   443 	    if (isCheckedException(exception) && !isRemoteException(exception)) 
   444 		return false ;
   445         }
   447         return true;
   448     }
   450     /**
   451      * Implements Section 1.2.3, #2.  
   452      */
   453     private boolean isRemoteExceptionOrSuperClass(Class c) {
   454         return 
   455             ((c == java.rmi.RemoteException.class) ||
   456              (c == java.io.IOException.class) ||
   457              (c == java.lang.Exception.class) ||
   458              (c == java.lang.Throwable.class));
   459     }
   461     /**
   462      * Implements Section 1.2.3, #5.
   463      */ 
   464     private void validateDirectInterfaces(Class c) throws IDLTypeException {
   466         Class[] directInterfaces = c.getInterfaces();
   468         if( directInterfaces.length < 2 ) {
   469             return;
   470         }
   472         Set allMethodNames = new HashSet();
   473         Set currentMethodNames = new HashSet();
   475         for(int i = 0; i < directInterfaces.length; i++) {
   476             Class next = directInterfaces[i];
   477             Method[] methods = next.getMethods();
   479             // Comparison is based on method names only.  First collect
   480             // all methods from current interface, eliminating duplicate
   481             // names.
   482             currentMethodNames.clear();
   483             for(int m = 0; m < methods.length; m++) {
   484                 currentMethodNames.add(methods[m].getName());
   485             }
   487             // Now check each method against list of all unique method
   488             // names processed so far.
   489             for(Iterator iter=currentMethodNames.iterator(); iter.hasNext();) {
   490                 String methodName = (String) iter.next();
   491                 if( allMethodNames.contains(methodName) ) {
   492                     String msg = "Class " + c + " inherits method " + 
   493                         methodName + " from multiple direct interfaces.";
   494                     throw new IDLTypeException(msg);
   495                 } else {
   496                     allMethodNames.add(methodName);
   497                 }
   498             }
   499         }
   501         return;
   502     }
   504     /**
   505      * Implements 1.2.3 #6
   506      */
   507     private void validateConstants(final Class c) 
   508         throws IDLTypeException {
   510         Field[] fields = null;
   512         try {
   513             fields = (Field[])
   514                 java.security.AccessController.doPrivileged
   515                 (new java.security.PrivilegedExceptionAction() {
   516                         public java.lang.Object run() throws Exception {
   517                             return c.getFields();
   518                         }
   519                     });
   520         } catch(java.security.PrivilegedActionException pae) {
   521             IDLTypeException ite = new IDLTypeException();
   522             ite.initCause(pae);
   523             throw ite;
   524         }
   526         for(int i = 0; i < fields.length; i++) {
   527             Field next = fields[i];
   528             Class fieldType = next.getType();
   529             if( (fieldType != java.lang.String.class) &&
   530                 !isPrimitive(fieldType) ) {
   531                 String msg = "Constant field '" + next.getName() + 
   532                     "' in class '" + next.getDeclaringClass().getName() + 
   533                     "' has invalid type' " + next.getType() + "'. Constants" +
   534                     " in RMI/IIOP interfaces can only have primitive" + 
   535                     " types and java.lang.String types.";
   536                 throw new IDLTypeException(msg);
   537             }
   538         }
   541         return;
   542     }
   544 }

mercurial