diff --git a/independent-projects/arc/processor/src/main/java/io/quarkus/arc/processor/DecoratorGenerator.java b/independent-projects/arc/processor/src/main/java/io/quarkus/arc/processor/DecoratorGenerator.java index 1f19752bede5b..2b3183d63d645 100644 --- a/independent-projects/arc/processor/src/main/java/io/quarkus/arc/processor/DecoratorGenerator.java +++ b/independent-projects/arc/processor/src/main/java/io/quarkus/arc/processor/DecoratorGenerator.java @@ -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)); diff --git a/independent-projects/arc/tests/src/test/java/io/quarkus/arc/test/decorators/DecoratorWithConstructorInjectionTest.java b/independent-projects/arc/tests/src/test/java/io/quarkus/arc/test/decorators/DecoratorWithConstructorInjectionTest.java new file mode 100644 index 0000000000000..e1e8b03b3941e --- /dev/null +++ b/independent-projects/arc/tests/src/test/java/io/quarkus/arc/test/decorators/DecoratorWithConstructorInjectionTest.java @@ -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 convert(T value); + } + + @ApplicationScoped + static class ToUpperCaseConverter implements Converter { + @Override + public String convert(String value) { + return value.toUpperCase(); + } + } + + @Dependent + @Priority(1) + @Decorator + static class TrimConverterDecorator implements Converter { + @Inject + @Delegate + Converter 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(); + } + } +} diff --git a/independent-projects/arc/tests/src/test/java/io/quarkus/arc/test/decorators/DecoratorWithFieldInjectionTest.java b/independent-projects/arc/tests/src/test/java/io/quarkus/arc/test/decorators/DecoratorWithFieldInjectionTest.java new file mode 100644 index 0000000000000..c3b4c4ab4d5a5 --- /dev/null +++ b/independent-projects/arc/tests/src/test/java/io/quarkus/arc/test/decorators/DecoratorWithFieldInjectionTest.java @@ -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 convert(T value); + } + + @ApplicationScoped + static class ToUpperCaseConverter implements Converter { + @Override + public String convert(String value) { + return value.toUpperCase(); + } + } + + @Dependent + @Priority(1) + @Decorator + static class TrimConverterDecorator implements Converter { + @Inject + @Delegate + Converter 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(); + } + } +} diff --git a/independent-projects/arc/tests/src/test/java/io/quarkus/arc/test/decorators/DecoratorWithSetterInjectionTest.java b/independent-projects/arc/tests/src/test/java/io/quarkus/arc/test/decorators/DecoratorWithSetterInjectionTest.java new file mode 100644 index 0000000000000..d0a84befefe21 --- /dev/null +++ b/independent-projects/arc/tests/src/test/java/io/quarkus/arc/test/decorators/DecoratorWithSetterInjectionTest.java @@ -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 convert(T value); + } + + @ApplicationScoped + static class ToUpperCaseConverter implements Converter { + @Override + public String convert(String value) { + return value.toUpperCase(); + } + } + + @Dependent + @Priority(1) + @Decorator + static class TrimConverterDecorator implements Converter { + @Inject + @Delegate + Converter 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(); + } + } +} diff --git a/independent-projects/arc/tests/src/test/java/io/quarkus/arc/test/decorators/abstractimpl/AbstractDecoratorWithConstructorInjectionTest.java b/independent-projects/arc/tests/src/test/java/io/quarkus/arc/test/decorators/abstractimpl/AbstractDecoratorWithConstructorInjectionTest.java new file mode 100644 index 0000000000000..9e713328a2eb6 --- /dev/null +++ b/independent-projects/arc/tests/src/test/java/io/quarkus/arc/test/decorators/abstractimpl/AbstractDecoratorWithConstructorInjectionTest.java @@ -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 convert(T value); + + U getId(); + } + + @ApplicationScoped + static class ToUpperCaseConverter implements Converter { + @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 { + @Inject + @Delegate + Converter 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(); + } + } +} diff --git a/independent-projects/arc/tests/src/test/java/io/quarkus/arc/test/decorators/abstractimpl/AbstractDecoratorWithFieldInjectionTest.java b/independent-projects/arc/tests/src/test/java/io/quarkus/arc/test/decorators/abstractimpl/AbstractDecoratorWithFieldInjectionTest.java new file mode 100644 index 0000000000000..1285906088248 --- /dev/null +++ b/independent-projects/arc/tests/src/test/java/io/quarkus/arc/test/decorators/abstractimpl/AbstractDecoratorWithFieldInjectionTest.java @@ -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 convert(T value); + + U getId(); + } + + @ApplicationScoped + static class ToUpperCaseConverter implements Converter { + @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 { + @Inject + @Delegate + Converter 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(); + } + } +} diff --git a/independent-projects/arc/tests/src/test/java/io/quarkus/arc/test/decorators/abstractimpl/AbstractDecoratorWithSetterInjectionTest.java b/independent-projects/arc/tests/src/test/java/io/quarkus/arc/test/decorators/abstractimpl/AbstractDecoratorWithSetterInjectionTest.java new file mode 100644 index 0000000000000..6ed7f33b4bc1f --- /dev/null +++ b/independent-projects/arc/tests/src/test/java/io/quarkus/arc/test/decorators/abstractimpl/AbstractDecoratorWithSetterInjectionTest.java @@ -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 AbstractDecoratorWithSetterInjectionTest { + @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 convert(T value); + + U getId(); + } + + @ApplicationScoped + static class ToUpperCaseConverter implements Converter { + @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 { + @Inject + @Delegate + Converter 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 value) { + return value.trim(); + } + } +}