rmannibucau edited a comment on pull request #28:
URL: https://github.com/apache/openwebbeans/pull/28#issuecomment-643798023
@philippkunz no issue with that since it drops some code and additional
overhead is ok IMHO.
edit: to illustrate what I have in mind:
public class CdiParametersResolverExtension implements
ParameterResolver, AfterEachCallback
{
private Map<Parameter, Instance> instances;
@Override
public boolean supportsParameter(final ParameterContext
parameterContext, final ExtensionContext extensionContext)
throws ParameterResolutionException {
try
{
final Parameter parameter = parameterContext.getParameter();
final BeanManager bm = CDI.current().getBeanManager();
final Bean<?> bean =
bm.resolve(bm.getBeans(parameter.getType(),
Stream.of(parameter.getAnnotations())
.filter(it -> bm.isQualifier(it.annotationType()))
.toArray(Annotation[]::new)));
if (bean == null)
{
return false;
}
final CreationalContext<Object> creationalContext =
bm.createCreationalContext(null);
final Object instance = bm.getReference(bean,
parameter.getType(), creationalContext);
if (instances == null)
{
instances = new HashMap<>();
}
instances.put(parameter, new Instance(instance,
creationalContext));
return true;
}
catch (final IllegalStateException ise) // no cdi container
{
return false;
}
}
@Override
public void afterEach(final ExtensionContext context)
{
if (instances != null) {
instances.values().stream().map(i ->
i.creationalContext).forEach(CreationalContext::release);
instances.clear();
instances = null;
}
}
@Override
public Object resolveParameter(final ParameterContext
parameterContext, final ExtensionContext extensionContext)
throws ParameterResolutionException
{
return instances.get(parameterContext.getParameter()).instance;
}
private static class Instance
{
private final Object instance;
private final CreationalContext<?> creationalContext;
private Instance(final Object instance, final
CreationalContext<?> creationalContext)
{
this.instance = instance;
this.creationalContext = creationalContext;
}
}
}
With as "api":
@Target({TYPE, METHOD})
@Retention(RUNTIME)
@ExtendWith(CdiParametersResolverExtension.class)
public @interface CdiMethodParameters
{
@Qualifier
@Target(PARAMETER)
@Retention(RUNTIME)
@interface Skip
{
}
}
And a test (indeed CdiMethodParameters can be put on the class too, does not
change anything there):
@Cdi(classes = CdiParameterResolversTest.SomeBean.class,
disableDiscovery = true)
class CdiParameterResolversTest
{
@Test
void noParam()
{
assertNotNull(CDI.current().getBeanManager());
}
@Test
@CdiMethodParameters
void cdiParam(final SomeBean someBean)
{
assertNotNull(someBean);
assertEquals("yes", someBean.ok());
assertTrue(someBean.getClass().getName().contains("$$Owb")); //
it is cdi proxy
}
@Test
@CdiMethodParameters
@ExtendWith(CustomParamResolver.class)
void mixedParams(final SomeBean cdi, @CdiMethodParameters.Skip final
SomeBean notCdi)
{
assertNotNull(cdi);
assertEquals("yes", cdi.ok());
assertEquals("custom", notCdi.ok());
}
@ApplicationScoped
public static class SomeBean
{
public String ok()
{
return "yes";
}
}
public static class CustomParamResolver implements ParameterResolver
{
@Override
public boolean supportsParameter(final ParameterContext
parameterContext,
final ExtensionContext
extensionContext) throws ParameterResolutionException
{
return parameterContext.getIndex() == 1;
}
@Override
public Object resolveParameter(final ParameterContext
parameterContext, final ExtensionContext extensionContext)
throws ParameterResolutionException
{
return new SomeBean()
{
@Override
public String ok()
{
return "custom";
}
};
}
}
}
Hope code is clearer than words ;)
----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
For queries about this service, please contact Infrastructure at:
[email protected]