Interface Registry

  • All Known Subinterfaces:
    Context, Execution, ExecutionRef, GroovyContext, MutableRegistry, Request

    public interface Registry
    An object registry.

    Registries are primarily used for inter Handler communication in request processing. The Context object that handlers operate on implements the Registry interface.

     import ratpack.core.handling.Handler;
     import ratpack.core.handling.Context;
     import ratpack.exec.registry.Registry;
    
     import static org.junit.jupiter.api.Assertions.assertTrue;
    
     public class Thing {
       private final String name
       public Thing(String name) { this.name = name; }
       public String getName() { return name; }
     }
    
     public class UpstreamHandler implements Handler {
       public void handle(Context context) {
         context.next(Registry.single(new Thing("foo")));
       }
     }
    
     public class DownstreamHandler implements Handler {
       public void handle(Context context) {
         assertTrue(context instanceof Registry);
         Thing thing = context.get(Thing.class);
         context.render(thing.getName());
       }
     }
    
     import ratpack.test.handling.HandlingResult;
     import ratpack.test.handling.RequestFixture;
    
     import static ratpack.core.handling.Handlers.chain;
     import static ratpack.func.Action.noop;
    
     import static org.junit.jupiter.api.Assertions.assertEquals;
    
     Handler chain = chain(new UpstreamHandler(), new DownstreamHandler());
     HandlingResult result = RequestFixture.handle(chain, noop());
    
     assertEquals("foo", result.rendered(String.class));
     

    Thread safety

    Registry objects are assumed to be thread safe. No external synchronization is performed around registry access. As registry objects may be used across multiple requests, they should be thread safe.

    Registries that are created per request however do not need to be thread safe.

    Ordering

    Registry objects are returned in the reverse order that they were added (i.e. Last-In-First-Out).

    
     import com.google.common.base.Joiner;
     import ratpack.exec.registry.Registry;
    
     import static org.junit.jupiter.api.Assertions.assertEquals;
    
     public class Example {
       public static void main(String... args) throws Exception {
         Registry registry = Registry.of(r -> r
             .add("Ratpack")
             .add("foo")
             .add("bar")
         );
    
         assertEquals("bar", registry.get(String.class));
    
         String joined = Joiner.on(", ").join(registry.getAll(String.class));
         assertEquals("bar, foo, Ratpack", joined);
       }
     }
     

    While this is strictly the case for the core registry implementations in Ratpack, adapted implementations (e.g. Guice, Spring etc.) may have more nuanced ordering semantics. To the greatest extent possible, registry implementations should strive to honor LIFO ordering.

    • Method Detail

      • get

        default <O> O get​(Class<O> type)
                   throws NotInRegistryException
        Provides an object of the specified type, or throws an exception if no object of that type is available.
        Type Parameters:
        O - The type of the object to provide
        Parameters:
        type - The type of the object to provide
        Returns:
        An object of the specified type
        Throws:
        NotInRegistryException - If no object of this type can be returned
      • get

        default <O> O get​(com.google.common.reflect.TypeToken<O> type)
                   throws NotInRegistryException
        Provides an object of the specified type, or throws an exception if no object of that type is available.
        Type Parameters:
        O - The type of the object to provide
        Parameters:
        type - The type of the object to provide
        Returns:
        An object of the specified type
        Throws:
        NotInRegistryException - If no object of this type can be returned
      • maybeGet

        default <O> Optional<O> maybeGet​(Class<O> type)
        Does the same thing as get(Class), except returns null instead of throwing an exception.
        Type Parameters:
        O - The type of the object to provide
        Parameters:
        type - The type of the object to provide
        Returns:
        An object of the specified type, or null if no object of this type is available.
      • maybeGet

        <O> Optional<O> maybeGet​(com.google.common.reflect.TypeToken<O> type)
        Does the same thing as get(Class), except returns null instead of throwing an exception.
        Type Parameters:
        O - The type of the object to provide
        Parameters:
        type - The type of the object to provide
        Returns:
        An optional of an object of the specified type
      • getAll

        default <O> Iterable<? extends O> getAll​(Class<O> type)
        Returns all of the objects whose declared type is assignment compatible with the given type.
        Type Parameters:
        O - the type of objects to search for
        Parameters:
        type - the type of objects to search for
        Returns:
        All objects of the given type
      • getAll

        <O> Iterable<? extends O> getAll​(com.google.common.reflect.TypeToken<O> type)
        Returns all of the objects whose declared type is assignment compatible with the given type.
        Type Parameters:
        O - the type of objects to search for
        Parameters:
        type - the type of objects to search for
        Returns:
        All objects of the given type
      • first

        default <T,​O> Optional<O> first​(com.google.common.reflect.TypeToken<T> type,
                                              Function<? super T,​? extends O> function)
                                       throws Exception
        Find and transform an item.

        This method will apply the given function to items in the order returned by getAll(TypeToken) until the function returns a non null value. The first non null value will be returned by this method immediately (as an optional). If the function returns a null value for every item, an empty optional is returned.

        Type Parameters:
        T - the type of the object to search for
        O - the type of transformed object
        Parameters:
        type - the type of object to search for
        function - a function to apply to each item
        Returns:
        An optional of the object of the specified type that satisfied the specified predicate
        Throws:
        Exception - any thrown by the function
      • first

        default <T,​O> Optional<O> first​(Class<T> type,
                                              Function<? super T,​? extends O> function)
                                       throws Exception
        A convenience method for first(TypeToken, Function).
        Type Parameters:
        T - the type of the object to search for
        O - the type of transformed object
        Parameters:
        type - the type of object to search for
        function - a function to apply to each item
        Returns:
        An optional of the object of the specified type that satisfied the specified predicate
        Throws:
        Exception - any thrown by the function
        See Also:
        first(TypeToken, Function)
      • join

        default Registry join​(Registry child)
        Creates a new registry by joining this registry with the given registry

        The returned registry is effectively the union of the two registries, with the child registry taking precedence. This means that child entries are effectively “returned first”.

        
         import ratpack.exec.registry.Registry;
        
         import java.util.List;
         import com.google.common.collect.Lists;
        
         import static org.junit.jupiter.api.Assertions.assertEquals;
        
         public class Example {
        
           public static interface Thing {
             String getName();
           }
        
           public static class ThingImpl implements Thing {
             private final String name;
        
             public ThingImpl(String name) {
               this.name = name;
             }
        
             public String getName() {
               return name;
             }
           }
        
           public static void main(String[] args) {
             Registry child = Registry.builder().add(Thing.class, new ThingImpl("child-1")).add(Thing.class, new ThingImpl("child-2")).build();
             Registry parent = Registry.builder().add(Thing.class, new ThingImpl("parent-1")).add(Thing.class, new ThingImpl("parent-2")).build();
             Registry joined = parent.join(child);
        
             assertEquals("child-2", joined.get(Thing.class).getName());
             List<Thing> all = Lists.newArrayList(joined.getAll(Thing.class));
             assertEquals("child-2", all.get(0).getName());
             assertEquals("child-1", all.get(1).getName());
             assertEquals("parent-2", all.get(2).getName());
             assertEquals("parent-1", all.get(3).getName());
           }
         }
         
        Parameters:
        child - the child registry
        Returns:
        a registry which is the combination of the this and the given child
      • empty

        static Registry empty()
        Returns an empty registry.
        Returns:
        an empty registry
      • of

        static Registry of​(Action<? super RegistrySpec> action)
                    throws Exception
        Builds a registry from the given action.
        Parameters:
        action - the action that defines the registry
        Returns:
        a registry created by the given action
        Throws:
        Exception - any thrown by the action
      • backedBy

        static Registry backedBy​(RegistryBacking registryBacking)
        Creates a new registry instance that is backed by a RegistryBacking implementation. The registry instance caches lookups.
        Parameters:
        registryBacking - the implementation that returns instances for the registry
        Returns:
        a new registry
      • mutable

        static MutableRegistry mutable()
        Creates a new, empty, mutable registry.

        Mutable registries are not concurrent safe when being mutated. Concurrent reading is supported as long as no mutations are occurring.

        Returns:
        a new, empty, mutable registry.
        Since:
        1.4