Class Registry<K,V>

java.lang.Object
name.martingeisse.grumpyjson.registry.Sealable
name.martingeisse.grumpyjson.registry.Registry<K,V>
Type Parameters:
K - the key type
V - the type of registrable stored in this registry
Direct Known Subclasses:
JsonDeserializerRegistry, JsonSerializerRegistry

public abstract class Registry<K,V> extends Sealable
Base class for a registry which acts somewhat like a Map, but with the following differences:
  • For each registrable ("value" in Map terminology), the registry can determine the keys which that registrable supports, i.e. the keys that can be used to obtain that registrable from the registry. Registrables can be added without specifying a key, and a registrable will be available using any of the keys it supports.
  • Depending on the subclass, the registry may support auto-generation of a registrable for a key for which no registrable was registered manually.
  • The only allowed ways to manipulate the registry are adding registrables manually, auto-generation, and clearing the registry. In particular, removing individual registrables is not supported.
  • The only possible way to query the registry is to ask whether a key is supported, and to get the registrable for a key. In particular, iteration is not supported.
  • The registry operates in two phases, configuration phase and run-time phase. In the configuration phase, only registering objects and clearing the registry are allowed. Querying the registry is not allowed. In the run-time phase, only querying is allowed, no manipulation. The transition from configuration phase to run-time phase is called "sealing" the registry. The separation into two phases allows internal optimization.

The method to determine the supported keys for a registrable is located in the registry, not in the registrable, because in the case of JSON converters, the two methods to get supported keys for the serialization and deserialization case would collide if they were both located in the registrable.

  • Constructor Summary

    Constructors
    Constructor
    Description
    Constructor.
  • Method Summary

    Modifier and Type
    Method
    Description
    final void
    Removes all registered objects from this registry.
    protected abstract V
    Auto-generates a registrable in a subclass-specific way.
    final V
    get(K key)
    Returns a registered object for the specified key, auto-generating it if necessary and possible.
    protected abstract String
    Produces an error message that gets used in an exception for an unknown key.
    protected void
    Subclasses may perform seal-time operations here, e.g. optimize their internal data structures to prepare for run-time.
    final void
    register(V registrable)
    Registers a registrable with this registry.
    protected abstract boolean
    registrableSupports(V registrable, K key)
    Checks whether the specified registrable supports the specified key.
    final boolean
    supports(K key)
    Checks whether the specified key is supported by any registrable that is registered with this registry or can be auto-generated on the fly.

    Methods inherited from class name.martingeisse.grumpyjson.registry.Sealable

    ensureConfigurationPhase, ensureRunTimePhase, seal

    Methods inherited from class java.lang.Object

    clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
  • Constructor Details

    • Registry

      public Registry()
      Constructor.
  • Method Details

    • clear

      public final void clear()
      Removes all registered objects from this registry. This is useful because the registries used by grumpyjson contain default registrables, and the code using it might not want to use them.
    • register

      public final void register(V registrable)
      Registers a registrable with this registry.
      Parameters:
      registrable - the registrable to add
    • onSeal

      protected void onSeal()
      Description copied from class: Sealable
      Subclasses may perform seal-time operations here, e.g. optimize their internal data structures to prepare for run-time.
      Overrides:
      onSeal in class Sealable
    • supports

      public final boolean supports(K key)
      Checks whether the specified key is supported by any registrable that is registered with this registry or can be auto-generated on the fly.

      Note that there are some reasons why a registered object may claim to support a key, but fail at run-time when it actually encounters that key. Such a key will still be "supported" by that registrable from the point-of-view of the registry. Refer to the documentation of the individual registrables for details.

      Parameters:
      key - the key to check
      Returns:
      true if supported, false if not
    • get

      public final V get(K key) throws NotRegisteredException
      Returns a registered object for the specified key, auto-generating it if necessary and possible. This method will throw an exception if no registrable was registered manually that supports the key and no registrable can be auto-generated. If multiple registrables have been registered that can handle the specified key, the one registered later will take precedence.
      Parameters:
      key - the key to return a registrable for
      Returns:
      the registered object, possibly auto-generated
      Throws:
      NotRegisteredException - if the key is not known to this registry
    • registrableSupports

      protected abstract boolean registrableSupports(V registrable, K key)
      Checks whether the specified registrable supports the specified key.

      This method must always return the same result for the same registrable and key.

      Parameters:
      registrable - the registrable which is checked for the key
      key - the key to check
      Returns:
      true if the registrable supports the key, false if not
    • generateRegistrable

      protected abstract V generateRegistrable(K key)
      Auto-generates a registrable in a subclass-specific way. This method does not have to check the key for null, nor whether this registry is in the run-time phase.

      The returned registrable will only be used for the specified key, not for other keys that it might support as well. To re-use a single auto-generated registrable that supports multiple keys for all the keys it supports, the auto-generation itself must return the same registrable for all those keys.

      This method must not cause calls to the registry while in progress. In particular, generating a registrable must not query the registry for other registrables to use as dependencies. There are two reasons for this: First, doing so may corrupt the state of this registry or cause deadlock -- the registry is not built to handle that case, simply because it is not needed by any known registrable. Second, doing so may easily cause infinite recursion when requesting the registrable that is already being built.

      It is, however, allowed to build a registrable that refers to this registry when being used. Such a registrable can take the registry as a constructor parameter and store it internally -- and not access the registry inside its constructor to comply with the above rule -- and then access the registry at run-time. This is how various registrables act in practice. This turned out to be a more practical solution anyway because these registrables do not have all the required information available in the constructor, but only at run-time.

      Parameters:
      key - the key (never null)
      Returns:
      the auto-generated registrable, or null if auto-generation is not supported for that key
    • getErrorMessageForUnknownKey

      protected abstract String getErrorMessageForUnknownKey(K key)
      Produces an error message that gets used in an exception for an unknown key. The error message is one of the most frequent points of contact between the registry and application code, so it should be as developer-friendly as possible.
      Parameters:
      key - the unknown key
      Returns:
      the error message