Class ELMethodRegistry

java.lang.Object
io.micronaut.el.ELMethodRegistry

public final class ELMethodRegistry extends Object
Declares the methods, constructors and functions an ELMethodContributor makes callable from expressions parsed at runtime, and turns them into an ELMethodExecutor that dispatches them directly, without reflection.

A registration carries the declared signature next to the code that runs it. The signature is what the specification needs and what a method reference cannot supply on its own — the overload selection of the section 1.6, the coercions of the section 1.23 and the metadata of a jakarta.el.MethodExpression are all defined in terms of the declared parameter types:

registry.method(Book.class, "discounted", double.class, Integer.class, Book::discounted)
        .staticMethod(Math.class, "abs", int.class, int.class, Math::abs)
        .constructor(Book.class, String.class, Book::new);

The methods a registration produces are reusable: they hold the signature and the invocation, never the arguments they were resolved with, so the interpreter resolves a call site once and re-invokes the same method on every later evaluation. Only a name carrying several overloads is resolved again per call, since the arguments then decide which one applies.

Since:
1.1
Author:
Denis Stepanov
See Also:
  • Constructor Details

    • ELMethodRegistry

      public ELMethodRegistry()
      Creates an empty registry.
  • Method Details

    • method

      public <T,R> ELMethodRegistry method(Class<T> type, String name, Class<R> returnType, ELMethodRegistry.Call0<T,R> call)
      Registers an instance method taking no argument.
      Type Parameters:
      T - The type declaring the method
      R - The return type
      Parameters:
      type - The type declaring the method
      name - The name the expression calls it by
      returnType - The declared return type
      call - The invocation
      Returns:
      This registry
    • method

      public <T,A,R> ELMethodRegistry method(Class<T> type, String name, Class<R> returnType, Class<A> first, ELMethodRegistry.Call1<T,A,R> call)
      Registers an instance method taking one argument.
      Type Parameters:
      T - The type declaring the method
      A - The type of the argument
      R - The return type
      Parameters:
      type - The type declaring the method
      name - The name the expression calls it by
      returnType - The declared return type
      first - The declared type of the argument
      call - The invocation
      Returns:
      This registry
    • method

      public <T,A,B,R> ELMethodRegistry method(Class<T> type, String name, Class<R> returnType, Class<A> first, Class<B> second, ELMethodRegistry.Call2<T,A,B,R> call)
      Registers an instance method taking two arguments.
      Type Parameters:
      T - The type declaring the method
      A - The type of the first argument
      B - The type of the second argument
      R - The return type
      Parameters:
      type - The type declaring the method
      name - The name the expression calls it by
      returnType - The declared return type
      first - The declared type of the first argument
      second - The declared type of the second argument
      call - The invocation
      Returns:
      This registry
    • method

      public ELMethodRegistry method(Class<?> type, String name, Class<?> returnType, Class<?>[] parameterTypes, boolean varArgs, ELMethodRegistry.Invocation invocation)
      Registers an instance method of any arity, including one of variable arity.

      The arguments reach the invocation coerced to parameterTypes, the variable arity ones packed into an array of the component type of the last parameter.

      Parameters:
      type - The type declaring the method
      name - The name the expression calls it by
      returnType - The declared return type
      parameterTypes - The declared parameter types
      varArgs - Whether the last parameter is of variable arity, which requires it to be an array
      invocation - The invocation
      Returns:
      This registry
    • method

      public ELMethodRegistry method(Class<?> type, String name, Class<?> returnType, Class<?>[] parameterTypes, boolean varArgs, Annotation[] annotations, ELMethodRegistry.Invocation invocation)
      Registers an instance method carrying annotations, which a jakarta.el.MethodExpression reports through jakarta.el.MethodReference.
      Parameters:
      type - The type declaring the method
      name - The name the expression calls it by
      returnType - The declared return type
      parameterTypes - The declared parameter types
      varArgs - Whether the last parameter is of variable arity, which requires it to be an array
      annotations - The annotations declared on the method
      invocation - The invocation
      Returns:
      This registry
    • staticMethod

      public <R> ELMethodRegistry staticMethod(Class<?> type, String name, Class<R> returnType, ELMethodRegistry.Fn0<R> call)
      Registers a static method taking no argument.
      Type Parameters:
      R - The return type
      Parameters:
      type - The type declaring the method
      name - The name the expression calls it by
      returnType - The declared return type
      call - The invocation
      Returns:
      This registry
    • staticMethod

      public <A,R> ELMethodRegistry staticMethod(Class<?> type, String name, Class<R> returnType, Class<A> first, ELMethodRegistry.Fn1<A,R> call)
      Registers a static method taking one argument.
      Type Parameters:
      A - The type of the argument
      R - The return type
      Parameters:
      type - The type declaring the method
      name - The name the expression calls it by
      returnType - The declared return type
      first - The declared type of the argument
      call - The invocation
      Returns:
      This registry
    • staticMethod

      public <A,B,R> ELMethodRegistry staticMethod(Class<?> type, String name, Class<R> returnType, Class<A> first, Class<B> second, ELMethodRegistry.Fn2<A,B,R> call)
      Registers a static method taking two arguments.
      Type Parameters:
      A - The type of the first argument
      B - The type of the second argument
      R - The return type
      Parameters:
      type - The type declaring the method
      name - The name the expression calls it by
      returnType - The declared return type
      first - The declared type of the first argument
      second - The declared type of the second argument
      call - The invocation
      Returns:
      This registry
    • staticMethod

      public ELMethodRegistry staticMethod(Class<?> type, String name, Class<?> returnType, Class<?>[] parameterTypes, boolean varArgs, ELMethodRegistry.Invocation invocation)
      Registers a static method of any arity, including one of variable arity.
      Parameters:
      type - The type declaring the method
      name - The name the expression calls it by
      returnType - The declared return type
      parameterTypes - The declared parameter types
      varArgs - Whether the last parameter is of variable arity, which requires it to be an array
      invocation - The invocation, which receives a null base
      Returns:
      This registry
    • constructor

      public <A,T> ELMethodRegistry constructor(Class<T> type, Class<A> first, ELMethodRegistry.Fn1<A,T> call)
      Registers a constructor taking one argument, callable as Type(argument).
      Type Parameters:
      A - The type of the argument
      T - The type to construct
      Parameters:
      type - The type to construct
      first - The declared type of the argument
      call - The invocation
      Returns:
      This registry
    • constructor

      public ELMethodRegistry constructor(Class<?> type, Class<?>[] parameterTypes, boolean varArgs, ELMethodRegistry.Invocation invocation)
      Registers a constructor of any arity, callable as Type(arguments).
      Parameters:
      type - The type to construct
      parameterTypes - The declared parameter types
      varArgs - Whether the last parameter is of variable arity, which requires it to be an array
      invocation - The invocation, which receives a null base
      Returns:
      This registry
    • function

      public ELMethodRegistry function(String prefix, String localName, Class<?> declaringType, String methodName, Class<?> returnType, Class<?>[] parameterTypes, boolean varArgs, ELMethodRegistry.Invocation invocation)
      Registers a function, callable as prefix:localName(arguments), or as localName(arguments) when the prefix is empty.

      A function registered here replaces the jakarta.el.FunctionMapper lookup, which is defined in terms of java.lang.reflect.Method and therefore needs reflection.

      Parameters:
      prefix - The namespace prefix, empty for a function without one
      localName - The name within the namespace
      declaringType - The type declaring the method, which the identity of the expression is built from
      methodName - The name of the method, which the metadata of the expression reports
      returnType - The declared return type
      parameterTypes - The declared parameter types
      varArgs - Whether the last parameter is of variable arity, which requires it to be an array
      invocation - The invocation, which receives a null base
      Returns:
      This registry
    • function

      public <A,R> ELMethodRegistry function(String prefix, String localName, Class<?> declaringType, String methodName, Class<R> returnType, Class<A> first, ELMethodRegistry.Fn1<A,R> call)
      Registers a function taking one argument.
      Type Parameters:
      A - The type of the argument
      R - The return type
      Parameters:
      prefix - The namespace prefix, empty for a function without one
      localName - The name within the namespace
      declaringType - The type declaring the method, which the identity of the expression is built from
      methodName - The name of the method, which the metadata of the expression reports
      returnType - The declared return type
      first - The declared type of the argument
      call - The invocation
      Returns:
      This registry
    • functionalInterface

      public <T> ELMethodRegistry functionalInterface(Class<T> type, ELMethodRegistry.Lambda<T> factory)
      Registers how a lambda expression is presented as an instance of a functional interface the application declares, which is the coercion of the section 1.23.2 of the specification.

      The coercion needs the single abstract method of the target interface. Where the compiler resolves the method being called it implements the interface itself, and the functional interfaces of the platform are implemented without reflection, so neither reaches here. What does is an interface of the application reached through a method the resolver chain selects at evaluation time: nothing knows it before the call, and without a registration a java.lang.reflect.Proxy stands in for it.

      registry.functionalInterface(TextMapper.class,
              (context, lambda) -> value -> (String) lambda.invoke(context, value));
      
      Type Parameters:
      T - The functional interface
      Parameters:
      type - The functional interface
      factory - The invocation building an instance of it
      Returns:
      This registry
    • build

      public ELMethodExecutor build(int order)
      Builds the executor dispatching everything registered so far.

      The registrations are indexed by type and name, and the methods a type inherits from its supertypes and interfaces are merged into it, so a method registered on an interface is callable on every implementation. A constructor is not inherited, since it constructs the type it was registered for. The executor is immutable; later registrations do not reach it.

      Parameters:
      order - The order of the executor among the others, see Ordered
      Returns:
      The executor
    • isEmpty

      public boolean isEmpty()
      Whether nothing has been registered.
      Returns:
      Whether the registry is empty
    • functionalInterface

      @Internal public @Nullable ELMethodRegistry.Lambda<?> functionalInterface(Class<?> type)
      The registration presenting a lambda expression as the given functional interface.
      Parameters:
      type - The functional interface
      Returns:
      The registration, or null when nothing registered one