/* * JBoss, Home of Professional Open Source. * Copyright 2008, Red Hat Middleware LLC, and individual contributors * as indicated by the @author tags. See the copyright.txt file in the * distribution for a full listing of individual contributors. * * This is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as * published by the Free Software Foundation; either version 2.1 of * the License, or (at your option) any later version. * * This software is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this software; if not, write to the Free * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA * 02110-1301 USA, or see the FSF site: http://www.fsf.org. */ package org.jboss.iiop.rmi; import java.lang.reflect.Field; import java.lang.reflect.Member; import java.lang.reflect.Method; import java.lang.reflect.Modifier; import java.util.Arrays; import java.util.Iterator; /** * This class contains a bunch of methods taken from * org.jboss.verifier.strategy.AbstractVerifier. There they are declared * as instance methods. I copied them to this class and made them static here * in order to call them as utility methods, without having to create a * verifier instance, * * @author <a href="mailto:juha.lindfors@jboss.org">Juha Lindfors</a> * @author Aaron Mulder (ammulder@alumni.princeton.edu) * @author Vinay Menon (menonv@cpw.co.uk) * @author <a href="mailto:reverbel@ime.usp.br">Francisco Reverbel</a> * @version $Revision: 81018 $ */ public class RmiIdlUtil { public static boolean hasLegalRMIIIOPArguments(Method method) { Class[] params = method.getParameterTypes(); for (int i = 0; i < params.length; ++i) if (!isRMIIIOPType(params[i])) return false; return true; } public static boolean hasLegalRMIIIOPReturnType(Method method) { return isRMIIIOPType(method.getReturnType()); } public static boolean hasLegalRMIIIOPExceptionTypes(Method method) { /* * All checked exception classes used in method declarations * (other than java.rmi.RemoteException) MUST be conforming * RMI/IDL exception types. * * Spec 28.2.3 (4) */ Iterator it = Arrays.asList(method.getExceptionTypes()).iterator(); while (it.hasNext()) { Class exception = (Class)it.next(); if (!isRMIIDLExceptionType(exception)) return false; } return true; } /* * checks if the method's throws clause includes java.rmi.RemoteException * or a superclass of it. */ public static boolean throwsRemoteException(Method method) { Class[] exception = method.getExceptionTypes(); for (int i = 0; i < exception.length; ++i) if (exception[i].isAssignableFrom(java.rmi.RemoteException.class)) return true; return false; } /* * checks if a class's member (method, constructor or field) has a 'static' * modifier. */ public static boolean isStatic(Member member) { return (Modifier.isStatic(member.getModifiers())); } /* * checks if the given class is declared as static (inner classes only) */ public static boolean isStatic(Class c) { return (Modifier.isStatic(c.getModifiers())); } /* * checks if a class's member (method, constructor or field) has a 'final' * modifier. */ public static boolean isFinal(Member member) { return (Modifier.isFinal(member.getModifiers())); } /* * checks if the given class is declared as final */ public static boolean isFinal(Class c) { return (Modifier.isFinal(c.getModifiers())); } /* * checks if a class's memeber (method, constructor or field) has a 'public' * modifier. */ public static boolean isPublic(Member member) { return (Modifier.isPublic(member.getModifiers())); } /* * checks if the given class is declared as public */ public static boolean isPublic(Class c) { return (Modifier.isPublic(c.getModifiers())); } /** * Checks whether all the fields in the class are declared as public. */ public static boolean isAllFieldsPublic(Class c) { try { Field list[] = c.getFields(); for(int i=0; i<list.length; i++) if(!Modifier.isPublic(list[i].getModifiers())) return false; } catch(Exception e) { return false; } return true; } /* * checks if the given class is declared as abstract */ public static boolean isAbstract(Class c) { return (Modifier.isAbstract(c.getModifiers())); } public static boolean isRMIIIOPType(Class type) { /* * Java Language to IDL Mapping * ftp://ftp.omg.org/pub/docs/ptc/99-03-09.pdf * * A conforming RMI/IDL type is a Java type whose values * may be transmitted across an RMI/IDL remote interface at * run-time. A Java data type is a conforming RMI/IDL type * if it is: * * - one of the Java primitive types (see Primitive Types on page 28-2). * - a conforming remote interface (as defined in RMI/IDL Remote Interfaces on page 28-2). * - a conforming value type (as defined in RMI/IDL Value Types on page 28-4). * - an array of conforming RMI/IDL types (see RMI/IDL Arrays on page 28-5). * - a conforming exception type (see RMI/IDL Exception Types on page 28-5). * - a conforming CORBA object reference type (see CORBA Object Reference Types on page 28-6). * - a conforming IDL entity type see IDL Entity Types on page 28-6). */ /* * Primitive types. * * Spec 28.2.2 */ if (type.isPrimitive()) return true; /* * Conforming array. * * Spec 28.2.5 */ if (type.isArray()) return isRMIIIOPType(type.getComponentType()); /* * Conforming CORBA reference type * * Spec 28.2.7 */ if (org.omg.CORBA.Object.class.isAssignableFrom(type)) return true; /* * Conforming IDL Entity type * * Spec 28.2.8 */ if (org.omg.CORBA.portable.IDLEntity.class.isAssignableFrom(type)) return true; /* * Conforming remote interface. * * Spec 28.2.3 */ if (isRMIIDLRemoteInterface(type)) return true; /* * Conforming exception. * * Spec 28.2.6 */ if (isRMIIDLExceptionType(type)) return true; /* * Conforming value type. * * Spec 28.2.4 */ if (isRMIIDLValueType(type)) return true; return false; } public static boolean isRMIIDLRemoteInterface(Class type) { /* * If does not implement java.rmi.Remote, cannot be valid RMI-IDL * remote interface. */ if (!java.rmi.Remote.class.isAssignableFrom(type)) return false; Iterator methodIterator = Arrays.asList(type.getMethods()).iterator(); while (methodIterator.hasNext()) { Method m = (Method)methodIterator.next(); /* * All methods in the interface MUST throw * java.rmi.RemoteException or a superclass of it. * * Spec 28.2.3 (2) */ if (!throwsRemoteException(m)) { return false; } /* * All checked exception classes used in method declarations * (other than java.rmi.RemoteException) MUST be conforming * RMI/IDL exception types. * * Spec 28.2.3 (4) */ Iterator it = Arrays.asList(m.getExceptionTypes()).iterator(); while (it.hasNext()) { Class exception = (Class)it.next(); if (!isRMIIDLExceptionType(exception)) return false; } } /* * The constant values defined in the interface MUST be * compile-time types of RMI/IDL primitive types or String. * * Spec 28.2.3 (6) */ Iterator fieldIterator = Arrays.asList(type.getFields()).iterator(); while (fieldIterator.hasNext()) { Field f = (Field)fieldIterator.next(); if (f.getType().isPrimitive()) continue; if (f.getType().equals(java.lang.String.class)) continue; return false; } return true; } public static boolean isAbstractInterface(Class type) { /* * It must be a Java interface. */ if (!type.isInterface()) return false; /* * It must not be the interface of a CORBA object. */ if (org.omg.CORBA.Object.class.isAssignableFrom(type)) return false; /* * It must not extend java.rmi.Remote directly or indirectly. */ if (java.rmi.Remote.class.isAssignableFrom(type)) return false; Iterator methodIterator = Arrays.asList(type.getMethods()).iterator(); while (methodIterator.hasNext()) { Method m = (Method)methodIterator.next(); /* * All methods MUST throw java.rmi.RemoteException * or a superclass of it. */ if (!throwsRemoteException(m)) { return false; } } return true; } public static boolean isRMIIDLExceptionType(Class type) { /* * A conforming RMI/IDL Exception class MUST be a checked * exception class and MUST be a valid RMI/IDL value type. * * Spec 28.2.6 */ if (!Throwable.class.isAssignableFrom(type)) return false; if (Error.class.isAssignableFrom(type)) return false; if (RuntimeException.class.isAssignableFrom(type)) return false; if (!isRMIIDLValueType(type)) return false; return true; } public static boolean isRMIIDLValueType(Class type) { /* * A value type MUST NOT either directly or indirectly implement the * java.rmi.Remote interface. * * Spec 28.2.4 (4) */ if (java.rmi.Remote.class.isAssignableFrom(type)) return false; /* * It cannot be a CORBA object. */ if (org.omg.CORBA.Object.class.isAssignableFrom(type)) return false; /* * If class is a non-static inner class then its containing class must * also be a conforming RMI/IDL value type. * * Spec 2.8.4 (3) */ if (type.getDeclaringClass() != null && isStatic(type)) if (!isRMIIDLValueType(type.getDeclaringClass())) return false; return true; } public static boolean isAbstractValueType(Class type) { if (!type.isInterface()) return false; if (org.omg.CORBA.Object.class.isAssignableFrom(type)) return false; boolean cannotBeRemote = false; boolean cannotBeAbstractInterface = false; if (java.rmi.Remote.class.isAssignableFrom(type)) { cannotBeAbstractInterface = true; } else { cannotBeRemote = true; } Iterator methodIterator = Arrays.asList(type.getMethods()).iterator(); while (methodIterator.hasNext()) { Method m = (Method)methodIterator.next(); if (!throwsRemoteException(m)) { cannotBeAbstractInterface = true; cannotBeRemote = true; break; } Iterator it = Arrays.asList(m.getExceptionTypes()).iterator(); while (it.hasNext()) { Class exception = (Class)it.next(); if (!isRMIIDLExceptionType(exception)) { cannotBeRemote = true; break; } } } if (!cannotBeRemote) { Iterator fieldIterator = Arrays.asList(type.getFields()).iterator(); while (fieldIterator.hasNext()) { Field f = (Field)fieldIterator.next(); if (f.getType().isPrimitive()) continue; if (f.getType().equals(java.lang.String.class)) continue; cannotBeRemote = true; break; } } return cannotBeRemote && cannotBeAbstractInterface; } public static void rethrowIfCorbaSystemException(Exception e) { if (e instanceof java.rmi.MarshalException) throw new org.omg.CORBA.MARSHAL(e.toString()); else if (e instanceof java.rmi.NoSuchObjectException) throw new org.omg.CORBA.OBJECT_NOT_EXIST(e.toString()); else if (e instanceof java.rmi.AccessException) throw new org.omg.CORBA.NO_PERMISSION(e.toString()); else if (e instanceof javax.transaction.TransactionRequiredException) throw new org.omg.CORBA.TRANSACTION_REQUIRED(e.toString()); else if (e instanceof javax.transaction.TransactionRolledbackException) throw new org.omg.CORBA.TRANSACTION_ROLLEDBACK(e.toString()); else if (e instanceof javax.transaction.InvalidTransactionException) throw new org.omg.CORBA.INVALID_TRANSACTION(e.toString()); else if (e instanceof org.omg.CORBA.SystemException) throw (org.omg.CORBA.SystemException)e; } }