diff --git a/api/src/main/java/jakarta/enterprise/inject/build/compatible/spi/BeanInfo.java b/api/src/main/java/jakarta/enterprise/inject/build/compatible/spi/BeanInfo.java index 58e85147..86e9231e 100644 --- a/api/src/main/java/jakarta/enterprise/inject/build/compatible/spi/BeanInfo.java +++ b/api/src/main/java/jakarta/enterprise/inject/build/compatible/spi/BeanInfo.java @@ -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; @@ -163,15 +164,31 @@ public interface BeanInfo { Collection 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. *

- * 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 invokableMethods(); + Collection 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. + *

+ * 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 registerInvoker(MethodInfo method); // --- diff --git a/api/src/main/java/jakarta/enterprise/inject/build/compatible/spi/InvokableMethodInfo.java b/api/src/main/java/jakarta/enterprise/inject/build/compatible/spi/InvokableMethodInfo.java deleted file mode 100644 index f50ba8d9..00000000 --- a/api/src/main/java/jakarta/enterprise/inject/build/compatible/spi/InvokableMethodInfo.java +++ /dev/null @@ -1,81 +0,0 @@ -/* - * Copyright (c) 2022 Red Hat and others - * - * This program and the accompanying materials are made available under the - * Apache Software License 2.0 which is available at: - * https://www.apache.org/licenses/LICENSE-2.0. - * - * SPDX-License-Identifier: Apache-2.0 - */ - -package jakarta.enterprise.inject.build.compatible.spi; - -import jakarta.enterprise.invoke.InvokerBuilder; -import jakarta.enterprise.lang.model.declarations.ClassInfo; -import jakarta.enterprise.lang.model.declarations.MethodInfo; - -/** - * Invokable method that belongs to some managed bean. Allows obtaining the direct invoker, - * registered invokers, the bean class and method metadata. Also allows - * {@linkplain #registerInvoker(Class) registering} a new invoker. - *

- * Note that multiple managed beans may inherit an invokable method from a common - * supertype. In that case, each bean has its own invokable method, as can be observed - * from {@link #beanClass()}. - *

- * The invokers are returned as {@link InvokerInfo}, so they cannot be used directly. - * - * @since 5.0 - */ -public interface InvokableMethodInfo { - /** - * Returns the bean class of the managed bean to which this invokable method belongs. - * Note that this is not necessarily the same as {@code method().declaringClass()}, - * because invokable methods may also be declared in supertypes of the bean class. - * - * @return the bean class of the managed bean to which this invokable method belongs, never {@code null} - */ - ClassInfo beanClass(); - - /** - * Returns the {@linkplain MethodInfo declaration} of this invokable method. - * - * @return declaration of this invokable method, never {@code null} - */ - MethodInfo method(); - - /** - * Returns the direct invoker for this invokable method. Direct invoker always exists - * and invokes this invokable method as is, without changing the inputs or outputs - * of the method in any way. - * - * @return an {@linkplain InvokerInfo opaque token} for the direct invoker, never {@code null} - */ - InvokerInfo directInvoker(); - - /** - * Returns an invoker for this invokable method that was previously registered under - * given {@code registrationKey}. Such invoker may transform inputs and outputs - * of the method. - * - * @param registrationKey the key under which the invoker was previously registered, - * must not be {@code null} - * @return an {@linkplain InvokerInfo opaque token} for the registered invoker, - * or {@code null} if no invoker was registered under given key - */ - // TODO maybe we shouldn't expose this method -- if someone registers an invoker, - // they get an instance from the builder, so they shouldn't need to obtain it again, - // and they likely don't want anyone else to obtain it - // TODO the method name here is dangerously close to `registerInvoker` - InvokerInfo registeredInvoker(Class registrationKey); - - /** - * Registers a new invoker for this 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. - * - * @param registrationKey the key under which the invoker is to be registered, must not be {@code null} - * @return the invoker builder, never {@code null} - */ - InvokerBuilder registerInvoker(Class registrationKey); -} diff --git a/api/src/main/java/jakarta/enterprise/inject/build/compatible/spi/InvokerInfo.java b/api/src/main/java/jakarta/enterprise/inject/build/compatible/spi/InvokerInfo.java index 58e4a653..abab7e4c 100644 --- a/api/src/main/java/jakarta/enterprise/inject/build/compatible/spi/InvokerInfo.java +++ b/api/src/main/java/jakarta/enterprise/inject/build/compatible/spi/InvokerInfo.java @@ -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}. - *

+ * 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}. diff --git a/api/src/main/java/jakarta/enterprise/inject/spi/Bean.java b/api/src/main/java/jakarta/enterprise/inject/spi/Bean.java index e6fdea24..34859e83 100644 --- a/api/src/main/java/jakarta/enterprise/inject/spi/Bean.java +++ b/api/src/main/java/jakarta/enterprise/inject/spi/Bean.java @@ -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; /** *

@@ -51,35 +49,4 @@ public interface Bean extends Contextual, BeanAttributes { */ public Set getInjectionPoints(); - /** - * Returns all {@linkplain InvokableMethod invokable methods} that belong to this bean. - *

- * 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> 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. - *

- * 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 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 InvokableMethod getInvokableMethod(String name, Class 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? } diff --git a/api/src/main/java/jakarta/enterprise/inject/spi/ProcessManagedBean.java b/api/src/main/java/jakarta/enterprise/inject/spi/ProcessManagedBean.java index 470d5f8c..1142fb97 100644 --- a/api/src/main/java/jakarta/enterprise/inject/spi/ProcessManagedBean.java +++ b/api/src/main/java/jakarta/enterprise/inject/spi/ProcessManagedBean.java @@ -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; + /** *

* The container fires an event of this type for each enabled managed bean, before registering the @@ -44,6 +45,29 @@ public interface ProcessManagedBean extends ProcessBean { */ public AnnotatedType getAnnotatedBeanClass(); + /** + * Returns all {@linkplain jakarta.enterprise.invoke.Invokable invokable} methods that belong to this bean. + *

+ * 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> 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. + *

+ * 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> registerInvoker(InvokableMethod invokableMethod, Class registrationKey); + public InvokerBuilder> registerInvoker(AnnotatedMethod method); } diff --git a/api/src/main/java/jakarta/enterprise/invoke/InvokableMethod.java b/api/src/main/java/jakarta/enterprise/invoke/InvokableMethod.java deleted file mode 100644 index 521864dc..00000000 --- a/api/src/main/java/jakarta/enterprise/invoke/InvokableMethod.java +++ /dev/null @@ -1,69 +0,0 @@ -/* - * Copyright (c) 2022 Red Hat and others - * - * This program and the accompanying materials are made available under the - * Apache Software License 2.0 which is available at: - * https://www.apache.org/licenses/LICENSE-2.0. - * - * SPDX-License-Identifier: Apache-2.0 - */ - -package jakarta.enterprise.invoke; - -/** - * Invokable method that belongs to some managed bean. Allows obtaining the direct invoker, - * previously registered invokers, the bean class and method metadata. - *

- * Note that multiple managed beans may inherit an invokable method from a common - * supertype. In that case, each bean has its own invokable method, as can be observed - * from {@link #getBeanClass()}. - * - * @param type of the target instance - * @param return type of the invokable method - * @since 5.0 - */ -public interface InvokableMethod { - /** - * Returns the bean class of the managed bean to which this invokable method belongs. - * Note that this is not necessarily the same as {@code getMethod().getDeclaringClass()}, - * because invokable methods may also be declared in supertypes of the bean class. - * - * @return the bean class of the managed bean to which this invokable method belongs, never {@code null} - */ - Class getBeanClass(); - - /** - * Returns metadata about this invokable method. - * - * @return metadata about this invokable method, never {@code null} - */ - MethodMetadata getMethod(); - - /** - * Returns the direct invoker for this invokable method. Direct invoker always exists - * and invokes this invokable method as is, without changing the inputs or outputs - * of the method in any way. - * - * @return the direct invoker, never {@code null} - */ - Invoker getDirectInvoker(); - - /** - * Returns an invoker for this invokable method that was previously registered under - * given {@code registrationKey}. Such invoker may transform inputs and outputs - * of the method. - * - * @param registrationKey the key under which the invoker was previously registered, - * must not be {@code null} - * @return the registered invoker for this invokable method, or {@code null} if - * no invoker was registered under given key - * @param target instance type of the invoker; may be different from the bean class - * of this invokable method if the invoker applies a target instance transformation - * @param return type of the invoker; may be different from the return type of this - * invokable method if the invoker applies a return value transformation - */ - // TODO maybe we shouldn't expose this method -- if someone registers an invoker, - // they get an instance from the builder, so they shouldn't need to obtain it again, - // and they likely don't want anyone else to obtain it - Invoker getRegisteredInvoker(Class registrationKey); -}