Class Dispatcher

java.lang.Object
org.apache.sis.metadata.sql.Dispatcher
All Implemented Interfaces:
InvocationHandler

final class Dispatcher extends Object implements InvocationHandler
The handler for metadata proxy that implement (indirectly) metadata interfaces like Metadata, Citation, etc. Any call to a method in a metadata interface is redirected toward the invoke(java.lang.Object, java.lang.reflect.Method, java.lang.Object[]) method. This method uses reflection in order to find the caller's method and class name. The class name is translated into a table name, and the method name is translated into a column name. Then the information is fetched in the underlying metadata database.

There is usually a one-to-one correspondence between invoked methods and the columns to be read, but not always. Some method invocations may actually trig a computation using the values of other columns. This happen for example when invoking a deprecated method which computes its value from non-deprecated methods. Such situations happen in the transition from ISO 19115:2003 to ISO 19115:2014 and may happen again in the future as standards are revised. The algorithms are encoded in implementation classes like the ones in org.apache.sis.metadata.iso packages, and access to those implementation classes is enabled by the cache field (which, consequently, is more than only a cache).

Instance of this class shall be thread-safe.

Since:
0.8
Version:
1.2
  • Field Summary

    Fields
    Modifier and Type
    Field
    Description
    private Object
    The metadata instance where to store the property (column) values, or null if not yet created.
    (package private) final String
    The identifier used in order to locate the record for this metadata entity in the database.
    private long
    A bitmask of properties having null values.
    (package private) int
    Index in the CachedStatement cache array where to search first.
    private final MetadataSource
    The connection to the database.
  • Constructor Summary

    Constructors
    Constructor
    Description
    Dispatcher(String identifier, MetadataSource source)
    Creates a new metadata handler.
  • Method Summary

    Modifier and Type
    Method
    Description
    (package private) final String
    error(Method method)
    Returns the error message for a failure to query the database for the property identified by the given method.
    private Object
    fetchValue(LookupInfo info, Method method)
    Gets, computes or read from the database a metadata property value.
    invoke(Object proxy, Method method, Object[] args)
    Invoked when any method from a metadata interface is invoked.
    private static Method
    supercede(Method method)
    If the given method is superceded by a new method, the new method.
    Returns a string representation of this handler.
    private String
    toString(Class<?> type)
    Returns a string representation of a metadata of the given type.

    Methods inherited from class java.lang.Object

    clone, equals, finalize, getClass, hashCode, notify, notifyAll, wait, wait, wait
  • Field Details

    • identifier

      final String identifier
      The identifier used in order to locate the record for this metadata entity in the database. This is usually the primary key in the table which contains this entity.
    • source

      private final MetadataSource source
      The connection to the database. All metadata handlers created from a single database should share the same source.
    • preferredIndex

      int preferredIndex
      Index in the CachedStatement cache array where to search first. This is only a hint for increasing the chances to find quickly a CachedStatement instance for the right type and identifier.
      Design note: this field is declared in this Dispatcher class instead of CachedStatement because we need it before a CachedStatement instance can be found. Furthermore, two Dispatcher instances may have different preferredIndex values even if their CachedStatement.type value is the same, since their identifier values are different.
    • cache

      private transient volatile Object cache
      The metadata instance where to store the property (column) values, or null if not yet created. For ISO 19115, this is an instance of one of the classes defined in org.apache.sis.metadata.iso package or sub-packages. The intent is not only to cache the property values, but also to leverage implementations that compute automatically some property values from other properties. The main usage is computing the value of a deprecated property from the values of non-deprecated ones, e.g. for transition from ISO 19115:2003 to ISO 19115:2014.
    • nullValues

      private transient long nullValues
      A bitmask of properties having null values. Cached for avoiding to query the database many times. Bit indices are given by LookupInfo.asIndexMap(MetadataStandard). If a metadata contains more than 64 properties, no "null value" information will be stored for the extra properties. No damage will happen except more database accesses than needed.

      We do not need to synchronize this field because it is only an optimization. It is okay if a bit is wrongly zero; the only consequence is that it will cause one more database access than needed.

  • Constructor Details

    • Dispatcher

      public Dispatcher(String identifier, MetadataSource source)
      Creates a new metadata handler.
      Parameters:
      identifier - the identifier used in order to locate the record for this metadata entity in the database. This is usually the primary key in the table which contains this entity.
      source - the connection to the table which contains this entity.
  • Method Details

    • invoke

      public Object invoke(Object proxy, Method method, Object[] args)
      Invoked when any method from a metadata interface is invoked.
      Specified by:
      invoke in interface InvocationHandler
      Parameters:
      proxy - the object on which the method is invoked.
      method - the method invoked.
      args - the argument given to the method.
      Returns:
      the value to be returned from the public method invoked by the method.
    • fetchValue

      Gets, computes or read from the database a metadata property value. This method returns the first non-null value in the following choices:
      1. If the property value is present in the cache, the cached value.
      2. If the "cache" can compute the value from other property values, the result of that computation. This case happen mostly for deprecated properties that are replaced by one or more newer properties.
      3. The value stored in the database. The database is queried only once for the requested property and the result is cached for future reuse.
      Parameters:
      info - information related to the interface of the metadata object for which a property value is requested. This is used for fetching information from the MetadataStandard.
      method - the method to be invoked. The class given by Method.getDeclaringClass() is usually the same than the one given by LookupInfo.getMetadataType(), but not necessarily. The two classes may differ if the method is declared only in the implementation class.
      Returns:
      the property value, or null if none.
      Throws:
      ReflectiveOperationException - if an error occurred while querying the cache.
      SQLException - if an error occurred while querying the database.
      MetadataStoreException - if a value was not found or cannot be converted to the expected type.
    • error

      final String error(Method method)
      Returns the error message for a failure to query the database for the property identified by the given method.
    • toString

      private String toString(Class<?> type)
      Returns a string representation of a metadata of the given type.
    • toString

      public String toString()
      Returns a string representation of this handler. This is mostly for debugging purpose.
      Overrides:
      toString in class Object
    • supercede

      private static Method supercede(Method method) throws NoSuchMethodException
      If the given method is superceded by a new method, the new method. This is a hack for transition from legacy ISO type to newer type: ResponsibleParty.getRole() overriding Responsibility.getRole() confuses this Dispatcher class. We need the method in the base interface.
      Throws:
      NoSuchMethodException