[cdi-dev] [JBoss JIRA] (CDI-516) Firing events with dynamic parameterized types
Antoine Sabot-Durand (JIRA)
issues at jboss.org
Mon Nov 21 05:41:01 EST 2016
[ https://issues.jboss.org/browse/CDI-516?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel ]
Antoine Sabot-Durand updated CDI-516:
-------------------------------------
Fix Version/s: 2.1 (Discussion)
> Firing events with dynamic parameterized types
> ----------------------------------------------
>
> Key: CDI-516
> URL: https://issues.jboss.org/browse/CDI-516
> Project: CDI Specification Issues
> Issue Type: Feature Request
> Components: Events
> Affects Versions: 1.2.Final
> Reporter: Antonin Stefanutti
> Fix For: 2.1 (Discussion)
>
>
> For the time being, either by using {{Event.select(...)}}, respectively {{BeanManager.fireEvent(...)}}, it is not possible to fire an event whose runtime type is a dynamic parameterized type, as specified in [The {{Event}} interface|http://docs.jboss.org/cdi/spec/1.2/cdi-spec.html#event]:
> {quote}
> If the container is unable to resolve the parameterized type of the event object, it uses the specified type to infer the parameterized type of the event types.
> If the runtime type of the event object contains an unresolvable type variable, an {{IllegalArgumentException}} is thrown.
> {quote}
> Respectively in [Firing an event|http://docs.jboss.org/cdi/spec/1.2/cdi-spec.html#bm_fire_event]:
> {quote}
> If the runtime type of the event object contains a type variable, an {{IllegalArgumentException}} is thrown.
> {quote}
> While, it is possible to pass a {{TypeLiteral}} to the {{Event.select(...)}} method, e.g.:
> {code}
> @Inject
> Event<Object> event;
> event.select(new TypeLiteral<String>() {});
> {code}
> It is not possible to pass a type variable known at runtime as the {{TypeLiteral}} class relies on the declared type variable and does not permit to override that behavior as the {{TypeLiteral.getType()}} method is declared {{final}}.
> Yet, there are use cases where that need is valid, for example:
> {code}
> <T> CdiEventEndpoint<T> cdiEventEndpoint(InjectionPoint ip, CamelContext context, @Any Event<Object> event) throws Exception {
> // Represents the runtime type for T
> Type type = ((ParameterizedType) ip.getType()).getActualTypeArguments()[0];
> String uri = endpointUri(type, ip.getQualifiers());
> if (context.hasEndpoint(uri) == null) {
> // Work around to pass the dynamic type
> TypeLiteral<T> literal = new TypeLiteral<T>() {};
> for (Field field : TypeLiteral.class.getDeclaredFields()) {
> if (field.getType().equals(Type.class)) {
> field.setAccessible(true);
> field.set(literal, type);
> break;
> }
> }
> // Here we used the dynamic type
> Event<T> typedEvent = event.select(literal, ip.getQualifiers().toArray(new Annotation[ip.getQualifiers().size()]));
> context.addEndpoint(uri, new CdiEventEndpoint<>(typedEvent, uri, context));
> }
> return CamelContextHelper.getMandatoryEndpoint(context, uri, CdiEventEndpoint.class);
> }
> {code}
> In the example above, the {{TypeLiteral}} class could have a constructor taking the dynamic type as argument.
> Another alternative would be to enrich the {{BeanManager}} SPI with the following method:
> {code}
> public void fireEvent(Object event, Type type, Annotation... qualifiers);
> {code}
> That use case is taken from the [CDI event Camel endpoint|https://github.com/astefanutti/camel-cdi/blob/84426570bcd7815eb98f87b07739aa9ddfc44191/impl/src/main/java/org/apache/camel/cdi/CdiCamelFactory.java#L91] in the [Camel CDI extension|https://github.com/astefanutti/camel-cdi].
--
This message was sent by Atlassian JIRA
(v7.2.3#72005)
More information about the cdi-dev
mailing list