Class ClassMap


  • final class ClassMap
    extends java.lang.Object
    A cache of introspection information for a specific class instance. Keys objects by an aggregation of the method name and the classes that make up the parameters.

    Originally taken from the Velocity tree so we can be self-sufficient.

    Since:
    1.0
    See Also:
    MethodKey
    • Field Summary

      Fields 
      Modifier and Type Field Description
      private java.util.Map<MethodKey,​java.lang.reflect.Method> byKey
      This is the cache to store and look up the method information.
      private java.util.Map<java.lang.String,​java.lang.reflect.Method[]> byName
      Keep track of all methods with the same name; this is not modified after creation.
      (package private) static java.lang.reflect.Method CACHE_MISS
      The cache miss marker method.
      private static ClassMap EMPTY
      Singleton for permissions non-allowed classes.
      private java.util.Map<java.lang.String,​java.lang.reflect.Field> fieldCache
      Cache of fields.
    • Constructor Summary

      Constructors 
      Modifier Constructor Description
      private ClassMap()
      Empty map.
      (package private) ClassMap​(java.lang.Class<?> aClass, JexlPermissions permissions, org.apache.commons.logging.Log log)
      Standard constructor.
    • Method Summary

      All Methods Static Methods Instance Methods Concrete Methods 
      Modifier and Type Method Description
      static java.lang.reflect.Method cacheMiss()
      A method that returns itself used as a marker for cache miss, allows the underlying cache map to be strongly typed.
      private static void create​(ClassMap cache, JexlPermissions permissions, java.lang.Class<?> clazz, org.apache.commons.logging.Log log)
      Populate the Map of direct hits.
      (package private) static ClassMap empty()  
      (package private) java.lang.reflect.Field getField​(java.lang.String fieldName)
      Find a Field using its name.
      (package private) java.lang.String[] getFieldNames()
      Gets the field names cached by this map.
      (package private) java.lang.reflect.Method getMethod​(MethodKey methodKey)
      Find a Method using the method name and parameter objects.
      (package private) java.lang.String[] getMethodNames()
      Gets the methods names cached by this map.
      (package private) java.lang.reflect.Method[] getMethods​(java.lang.String methodName)
      Gets all the methods with a given name from this map.
      private static void populateWithClass​(ClassMap cache, JexlPermissions permissions, java.lang.Class<?> clazz, org.apache.commons.logging.Log log)
      Recurses up class hierarchy to get all super classes.
      private static void populateWithInterface​(ClassMap cache, JexlPermissions permissions, java.lang.Class<?> iface, org.apache.commons.logging.Log log)
      Recurses up interface hierarchy to get all super interfaces.
      • Methods inherited from class java.lang.Object

        clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
    • Field Detail

      • CACHE_MISS

        static final java.lang.reflect.Method CACHE_MISS
        The cache miss marker method.
      • EMPTY

        private static final ClassMap EMPTY
        Singleton for permissions non-allowed classes.
      • byKey

        private final java.util.Map<MethodKey,​java.lang.reflect.Method> byKey
        This is the cache to store and look up the method information.

        It stores the association between: - a key made of a method name and an array of argument types. - a method.

        Since the invocation of the associated method is dynamic, there is no need (nor way) to differentiate between foo(int,int) and foo(Integer,Integer) since in practice only the latter form will be used through a call. This of course, applies to all 8 primitive types.

        Uses ConcurrentMap since 3.0, marginally faster than 2.1 under contention.
      • byName

        private final java.util.Map<java.lang.String,​java.lang.reflect.Method[]> byName
        Keep track of all methods with the same name; this is not modified after creation.
      • fieldCache

        private final java.util.Map<java.lang.String,​java.lang.reflect.Field> fieldCache
        Cache of fields.
    • Constructor Detail

      • ClassMap

        private ClassMap()
        Empty map.
      • ClassMap

        ClassMap​(java.lang.Class<?> aClass,
                 JexlPermissions permissions,
                 org.apache.commons.logging.Log log)
        Standard constructor.
        Parameters:
        aClass - the class to deconstruct.
        permissions - the permissions to apply during introspection
        log - the logger.
    • Method Detail

      • cacheMiss

        public static java.lang.reflect.Method cacheMiss()
        A method that returns itself used as a marker for cache miss, allows the underlying cache map to be strongly typed.
        Returns:
        itself as a method
      • create

        private static void create​(ClassMap cache,
                                   JexlPermissions permissions,
                                   java.lang.Class<?> clazz,
                                   org.apache.commons.logging.Log log)
        Populate the Map of direct hits. These are taken from all the public methods that our class, its parents and their implemented interfaces provide.
        Parameters:
        cache - the ClassMap instance we create
        permissions - the permissions to apply during introspection
        clazz - the class to cache
        log - the Log
      • empty

        static ClassMap empty()
        Returns:
        the empty classmap instance
      • populateWithClass

        private static void populateWithClass​(ClassMap cache,
                                              JexlPermissions permissions,
                                              java.lang.Class<?> clazz,
                                              org.apache.commons.logging.Log log)
        Recurses up class hierarchy to get all super classes.
        Parameters:
        cache - the cache to fill
        permissions - the permissions to apply during introspection
        clazz - the class to populate the cache from
        log - the Log
      • populateWithInterface

        private static void populateWithInterface​(ClassMap cache,
                                                  JexlPermissions permissions,
                                                  java.lang.Class<?> iface,
                                                  org.apache.commons.logging.Log log)
        Recurses up interface hierarchy to get all super interfaces.
        Parameters:
        cache - the cache to fill
        permissions - the permissions to apply during introspection
        iface - the interface to populate the cache from
        log - the Log
      • getField

        java.lang.reflect.Field getField​(java.lang.String fieldName)
        Find a Field using its name.
        Parameters:
        fieldName - the field name
        Returns:
        A Field object representing the field to invoke or null.
      • getFieldNames

        java.lang.String[] getFieldNames()
        Gets the field names cached by this map.
        Returns:
        the array of field names
      • getMethod

        java.lang.reflect.Method getMethod​(MethodKey methodKey)
                                    throws MethodKey.AmbiguousException
        Find a Method using the method name and parameter objects.

        Look in the methodMap for an entry. If found, it'll either be a CACHE_MISS, in which case we simply give up, or it'll be a Method, in which case, we return it.

        If nothing is found, then we must actually go and introspect the method from the MethodMap.

        Parameters:
        methodKey - the method key
        Returns:
        A Method object representing the method to invoke or null.
        Throws:
        MethodKey.AmbiguousException - When more than one method is a match for the parameters.
      • getMethodNames

        java.lang.String[] getMethodNames()
        Gets the methods names cached by this map.
        Returns:
        the array of method names
      • getMethods

        java.lang.reflect.Method[] getMethods​(java.lang.String methodName)
        Gets all the methods with a given name from this map.
        Parameters:
        methodName - the seeked methods name
        Returns:
        the array of methods (null or non-empty)