Skip to content

Commit

Permalink
Simplify the invoker registration process
Browse files Browse the repository at this point in the history
This commit removes the ability to obtain an invoker without previous
registration. It also removes the concept of registration key: whenever
an invoker is registered, the extension must remember it for later use.

After that, the `InvokableMethod[Info]` interfaces are useless, hence
this commit removes them. Access to invoker registration is through
the extension API: `ProcessManagedBean` and `BeanInfo`. Both of these
places are provisional; better API for invoker registration likely exists.

This commit does not (yet) remove the `MethodMetadata` and `ParameterMetadata`
interfaces, because there is one more possible use case for them: the invoker
transformers may want to access the called method, including transformed
annotations. The API definition currently does not allow that, but it's
something that should be explored.
  • Loading branch information
Ladicek committed Jan 17, 2023
1 parent 624abfd commit 836bb87
Show file tree
Hide file tree
Showing 6 changed files with 49 additions and 191 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@

package jakarta.enterprise.inject.build.compatible.spi;

import jakarta.enterprise.invoke.InvokerBuilder;
import jakarta.enterprise.lang.model.AnnotationInfo;
import jakarta.enterprise.lang.model.declarations.ClassInfo;
import jakarta.enterprise.lang.model.declarations.FieldInfo;
Expand Down Expand Up @@ -163,15 +164,31 @@ public interface BeanInfo {
Collection<InjectionPointInfo> injectionPoints();

/**
* Returns a collection of this bean's {@linkplain InvokableMethodInfo invokable methods}.
* Returns all {@linkplain jakarta.enterprise.invoke.Invokable invokable} methods that belong to this bean.
* <p>
* Note that only managed beans, also known as class-based beans, may have invokable methods;
* calling this method on a producer-based bean or a synthetic bean results in an empty collection.
* Note that only managed beans may have invokable methods; calling this method on a producer bean
* or a synthetic bean results in an empty collection.
*
* @return immutable collection of invokable methods, never {@code null}
* @since 5.0
*/
Collection<InvokableMethodInfo> invokableMethods();
Collection<MethodInfo> invokableMethods();

/**
* Registers a new invoker for given invokable method. The returned builder should be used
* to configure transformations that the invoker should apply. The builder eventually
* produces an opaque representation of the invoker.
* <p>
* The {@code method} must be an invokable method that belongs to this bean, otherwise
* an exception is thrown.
*
* @param method invokable method belonging to this bean, must not be {@code null}
* @return the invoker builder, never {@code null}
* @since 5.0
*/
// TODO we may want to introduce another entrypoint for this operation, or at least
// specify that this method may only be called during `@Registration`
InvokerBuilder<InvokerInfo> registerInvoker(MethodInfo method);

// ---

Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,10 @@
package jakarta.enterprise.inject.build.compatible.spi;

import jakarta.enterprise.invoke.Invoker;
import jakarta.enterprise.lang.model.declarations.MethodInfo;

/**
* Opaque token that stands in for an invoker obtained from an {@linkplain InvokableMethodInfo invokable method}.
* <p>
* Opaque token that stands in for an invoker registered using {@link BeanInfo#registerInvoker(MethodInfo)}.
* It can only be used to materialize an {@link Invoker} in a synthetic component; see
* {@link SyntheticBeanBuilder#withParam(String, InvokerInfo) SyntheticBeanBuilder.withParam} or
* {@link SyntheticObserverBuilder#withParam(String, InvokerInfo) SyntheticObserverBuilder.withParam}.
Expand Down
33 changes: 0 additions & 33 deletions api/src/main/java/jakarta/enterprise/inject/spi/Bean.java
Original file line number Diff line number Diff line change
Expand Up @@ -17,11 +17,9 @@

package jakarta.enterprise.inject.spi;

import java.util.Collection;
import java.util.Set;

import jakarta.enterprise.context.spi.Contextual;
import jakarta.enterprise.invoke.InvokableMethod;

/**
* <p>
Expand Down Expand Up @@ -51,35 +49,4 @@ public interface Bean<T> extends Contextual<T>, BeanAttributes<T> {
*/
public Set<InjectionPoint> getInjectionPoints();

/**
* Returns all {@linkplain InvokableMethod invokable methods} that belong to this bean.
* <p>
* Note that only managed beans may have invokable methods; calling this method on a producer bean
* or a synthetic bean results in an empty collection.
*
* @return immutable collection of invokable methods, never {@code null}
* @since 5.0
*/
public Collection<InvokableMethod<T, ?>> getInvokableMethods();

/**
* Returns the {@linkplain InvokableMethod invokable method} that belongs to this bean and
* has given {@code name}, {@code returnType} and {@code parameterTypes}. Returns {@code null}
* if no such invokable method exists.
* <p>
* Note that only managed beans may have invokable methods; calling this method on a producer bean
* or a synthetic bean results in {@code null}.
*
* @param name name of the invokable method
* @param returnType class of return type of the invokable method
* @param parameterTypes classes of parameter types of the invokable method
* @param <R> return type of the invokable method
* @return an invokable method, or {@code null} if this bean has no such invokable method
* @since 5.0
*/
public <R> InvokableMethod<T, R> getInvokableMethod(String name, Class<R> returnType, Class<?>... parameterTypes);

// TODO there must be a better way to obtain invokers at runtime, using the methods above is too clunky...
// maybe we should require everyone to write an extension that finds all invokable method they need,
// creates the required invokers and remembers them?
}
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,11 @@
*/
package jakarta.enterprise.inject.spi;

import jakarta.enterprise.invoke.InvokableMethod;
import jakarta.enterprise.invoke.Invoker;
import jakarta.enterprise.invoke.InvokerBuilder;

import java.util.Collection;

/**
* <p>
* The container fires an event of this type for each enabled managed bean, before registering the
Expand All @@ -44,6 +45,29 @@ public interface ProcessManagedBean<X> extends ProcessBean<X> {
*/
public AnnotatedType<X> getAnnotatedBeanClass();

/**
* Returns all {@linkplain jakarta.enterprise.invoke.Invokable invokable} methods that belong to this bean.
* <p>
* Note that only managed beans may have invokable methods; calling this method on a producer bean
* or a synthetic bean results in an empty collection.
*
* @return immutable collection of invokable methods, never {@code null}
* @since 5.0
*/
public Collection<AnnotatedMethod<? super X>> getInvokableMethods();

/**
* Registers a new invoker for given invokable method. The returned builder should be used
* to configure transformations that the invoker should apply. The builder eventually
* produces the invoker.
* <p>
* The {@code method} must be an invokable method that belongs to this bean, otherwise
* an exception is thrown.
*
* @param method invokable method belonging to this bean, must not be {@code null}
* @return the invoker builder, never {@code null}
* @since 5.0
*/
// TODO if we introduce `ProcessInvokableMethod`, this method would be moved there
public InvokerBuilder<Invoker<X, ?>> registerInvoker(InvokableMethod<X, ?> invokableMethod, Class<?> registrationKey);
public InvokerBuilder<Invoker<X, ?>> registerInvoker(AnnotatedMethod<? super X> method);
}
69 changes: 0 additions & 69 deletions api/src/main/java/jakarta/enterprise/invoke/InvokableMethod.java

This file was deleted.

0 comments on commit 836bb87

Please sign in to comment.