Skip to content

Commit

Permalink
Merge pull request #34336 from Ladicek/constructor-injection-for-abst…
Browse files Browse the repository at this point in the history
…ract-decorators

ArC: fix constructor injection for abstract decorators
  • Loading branch information
Ladicek committed Jun 28, 2023
2 parents d25ebbc + f75c576 commit fd51d93
Show file tree
Hide file tree
Showing 7 changed files with 427 additions and 2 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -167,9 +167,13 @@ private String generateDecoratorImplementation(String baseName, String targetPac
// Constructor
MethodInfo decoratorConstructor = decoratorClass.firstMethod(Methods.INIT);
MethodCreator constructor = decoratorImplCreator.getMethodCreator(Methods.INIT, "V",
decoratorConstructor.parameterTypes().toArray());
decoratorConstructor.parameterTypes().stream().map(it -> it.name().toString()).toArray());
ResultHandle[] constructorArgs = new ResultHandle[decoratorConstructor.parametersCount()];
for (int i = 0; i < decoratorConstructor.parametersCount(); i++) {
constructorArgs[i] = constructor.getMethodParam(i);
}
// Invoke super()
constructor.invokeSpecialMethod(decoratorConstructor, constructor.getThis());
constructor.invokeSpecialMethod(decoratorConstructor, constructor.getThis(), constructorArgs);
// Set the delegate field
constructor.writeInstanceField(delegateField.getFieldDescriptor(), constructor.getThis(),
constructor.invokeStaticMethod(MethodDescriptors.DECORATOR_DELEGATE_PROVIDER_GET));
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
package io.quarkus.arc.test.decorators;

import static org.junit.jupiter.api.Assertions.assertEquals;

import jakarta.annotation.Priority;
import jakarta.decorator.Decorator;
import jakarta.decorator.Delegate;
import jakarta.enterprise.context.ApplicationScoped;
import jakarta.enterprise.context.Dependent;
import jakarta.inject.Inject;

import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.RegisterExtension;

import io.quarkus.arc.Arc;
import io.quarkus.arc.test.ArcTestContainer;

public class DecoratorWithConstructorInjectionTest {
@RegisterExtension
public ArcTestContainer container = new ArcTestContainer(Converter.class, ToUpperCaseConverter.class,
TrimConverterDecorator.class, Trimmer.class);

@Test
public void testDecoration() {
ToUpperCaseConverter converter = Arc.container().instance(ToUpperCaseConverter.class).get();
assertEquals("HOLA!", converter.convert(" holA! "));
}

interface Converter<T> {
T convert(T value);
}

@ApplicationScoped
static class ToUpperCaseConverter implements Converter<String> {
@Override
public String convert(String value) {
return value.toUpperCase();
}
}

@Dependent
@Priority(1)
@Decorator
static class TrimConverterDecorator implements Converter<String> {
@Inject
@Delegate
Converter<String> delegate;

private final Trimmer trimmer;

@Inject
TrimConverterDecorator(Trimmer trimmer) {
this.trimmer = trimmer;
}

@Override
public String convert(String value) {
return delegate.convert(trimmer.trim(value));
}
}

@Dependent
static class Trimmer {
public String trim(String str) {
return str.trim();
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
package io.quarkus.arc.test.decorators;

import static org.junit.jupiter.api.Assertions.assertEquals;

import jakarta.annotation.Priority;
import jakarta.decorator.Decorator;
import jakarta.decorator.Delegate;
import jakarta.enterprise.context.ApplicationScoped;
import jakarta.enterprise.context.Dependent;
import jakarta.inject.Inject;

import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.RegisterExtension;

import io.quarkus.arc.Arc;
import io.quarkus.arc.test.ArcTestContainer;

public class DecoratorWithFieldInjectionTest {
@RegisterExtension
public ArcTestContainer container = new ArcTestContainer(Converter.class, ToUpperCaseConverter.class,
TrimConverterDecorator.class, Trimmer.class);

@Test
public void testDecoration() {
ToUpperCaseConverter converter = Arc.container().instance(ToUpperCaseConverter.class).get();
assertEquals("HOLA!", converter.convert(" holA! "));
}

interface Converter<T> {
T convert(T value);
}

@ApplicationScoped
static class ToUpperCaseConverter implements Converter<String> {
@Override
public String convert(String value) {
return value.toUpperCase();
}
}

@Dependent
@Priority(1)
@Decorator
static class TrimConverterDecorator implements Converter<String> {
@Inject
@Delegate
Converter<String> delegate;

@Inject
Trimmer trimmer;

@Override
public String convert(String value) {
return delegate.convert(trimmer.trim(value));
}
}

@Dependent
static class Trimmer {
public String trim(String str) {
return str.trim();
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
package io.quarkus.arc.test.decorators;

import static org.junit.jupiter.api.Assertions.assertEquals;

import jakarta.annotation.Priority;
import jakarta.decorator.Decorator;
import jakarta.decorator.Delegate;
import jakarta.enterprise.context.ApplicationScoped;
import jakarta.enterprise.context.Dependent;
import jakarta.inject.Inject;

import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.RegisterExtension;

import io.quarkus.arc.Arc;
import io.quarkus.arc.test.ArcTestContainer;

public class DecoratorWithSetterInjectionTest {
@RegisterExtension
public ArcTestContainer container = new ArcTestContainer(Converter.class, ToUpperCaseConverter.class,
TrimConverterDecorator.class, Trimmer.class);

@Test
public void testDecoration() {
ToUpperCaseConverter converter = Arc.container().instance(ToUpperCaseConverter.class).get();
assertEquals("HOLA!", converter.convert(" holA! "));
}

interface Converter<T> {
T convert(T value);
}

@ApplicationScoped
static class ToUpperCaseConverter implements Converter<String> {
@Override
public String convert(String value) {
return value.toUpperCase();
}
}

@Dependent
@Priority(1)
@Decorator
static class TrimConverterDecorator implements Converter<String> {
@Inject
@Delegate
Converter<String> delegate;

private Trimmer trimmer;

@Inject
void init(Trimmer trimmer) {
this.trimmer = trimmer;
}

@Override
public String convert(String value) {
return delegate.convert(trimmer.trim(value));
}
}

@Dependent
static class Trimmer {
public String trim(String str) {
return str.trim();
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
package io.quarkus.arc.test.decorators.abstractimpl;

import static org.junit.jupiter.api.Assertions.assertEquals;

import jakarta.annotation.Priority;
import jakarta.decorator.Decorator;
import jakarta.decorator.Delegate;
import jakarta.enterprise.context.ApplicationScoped;
import jakarta.enterprise.context.Dependent;
import jakarta.inject.Inject;

import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.RegisterExtension;

import io.quarkus.arc.Arc;
import io.quarkus.arc.test.ArcTestContainer;

public class AbstractDecoratorWithConstructorInjectionTest {
@RegisterExtension
public ArcTestContainer container = new ArcTestContainer(Converter.class, ToUpperCaseConverter.class,
TrimConverterDecorator.class, Trimmer.class);

@Test
public void testDecoration() {
ToUpperCaseConverter converter = Arc.container().instance(ToUpperCaseConverter.class).get();
assertEquals("HELLO", converter.convert(" hello "));
assertEquals(ToUpperCaseConverter.class.getName(), converter.getId());
}

interface Converter<T, U> {
T convert(T value);

U getId();
}

@ApplicationScoped
static class ToUpperCaseConverter implements Converter<String, String> {
@Override
public String convert(String value) {
return value.toUpperCase();
}

@Override
public String getId() {
return ToUpperCaseConverter.class.getName();
}
}

@Priority(1)
@Decorator
static abstract class TrimConverterDecorator implements Converter<String, String> {
@Inject
@Delegate
Converter<String, String> delegate;

private final Trimmer trimmer;

@Inject
TrimConverterDecorator(Trimmer trimmer) {
this.trimmer = trimmer;
}

@Override
public String convert(String value) {
return delegate.convert(trimmer.trim(value));
}
}

@Dependent
static class Trimmer {
public String trim(String value) {
return value.trim();
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
package io.quarkus.arc.test.decorators.abstractimpl;

import static org.junit.jupiter.api.Assertions.assertEquals;

import jakarta.annotation.Priority;
import jakarta.decorator.Decorator;
import jakarta.decorator.Delegate;
import jakarta.enterprise.context.ApplicationScoped;
import jakarta.enterprise.context.Dependent;
import jakarta.inject.Inject;

import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.RegisterExtension;

import io.quarkus.arc.Arc;
import io.quarkus.arc.test.ArcTestContainer;

public class AbstractDecoratorWithFieldInjectionTest {
@RegisterExtension
public ArcTestContainer container = new ArcTestContainer(Converter.class, ToUpperCaseConverter.class,
TrimConverterDecorator.class, Trimmer.class);

@Test
public void testDecoration() {
ToUpperCaseConverter converter = Arc.container().instance(ToUpperCaseConverter.class).get();
assertEquals("HELLO", converter.convert(" hello "));
assertEquals(ToUpperCaseConverter.class.getName(), converter.getId());
}

interface Converter<T, U> {
T convert(T value);

U getId();
}

@ApplicationScoped
static class ToUpperCaseConverter implements Converter<String, String> {
@Override
public String convert(String value) {
return value.toUpperCase();
}

@Override
public String getId() {
return ToUpperCaseConverter.class.getName();
}
}

@Priority(1)
@Decorator
static abstract class TrimConverterDecorator implements Converter<String, String> {
@Inject
@Delegate
Converter<String, String> delegate;

@Inject
Trimmer trimmer;

@Override
public String convert(String value) {
return delegate.convert(trimmer.trim(value));
}
}

@Dependent
static class Trimmer {
public String trim(String value) {
return value.trim();
}
}
}

0 comments on commit fd51d93

Please sign in to comment.