diff --git a/webbeans-impl/src/test/java/org/apache/webbeans/test/interceptors/owb1441/CustomInterceptorTest.java b/webbeans-impl/src/test/java/org/apache/webbeans/test/interceptors/owb1441/CustomInterceptorTest.java new file mode 100644 index 000000000..0efcced3c --- /dev/null +++ b/webbeans-impl/src/test/java/org/apache/webbeans/test/interceptors/owb1441/CustomInterceptorTest.java @@ -0,0 +1,61 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.webbeans.test.interceptors.owb1441; + +import jakarta.enterprise.context.ApplicationScoped; +import org.apache.webbeans.test.AbstractUnitTest; +import org.apache.webbeans.test.interceptors.interceptorbean.BigBrotherInterceptor; +import org.apache.webbeans.test.interceptors.interceptorbean.BigBrothered; +import org.apache.webbeans.test.interceptors.interceptorbean.BigBrotheredExtension; +import org.junit.Test; + +import static org.junit.Assert.assertTrue; + +/** + * Test for programmatically added Interceptors + */ +public class CustomInterceptorTest extends AbstractUnitTest +{ + @Test + public void testCustomInterceptor() throws Exception + { + WatchExtension bbe = new WatchExtension(); + addExtension(bbe); + startContainer(LittleJohnDoe.class); + + final LittleJohnDoe joe = getInstance(LittleJohnDoe.class); + + joe.makeACoffee(); + assertTrue(WatchInterceptor.isObserved()); + + joe.watchTv(); + assertTrue(WatchInterceptor.isObserved()); + } + + @ApplicationScoped + @BigBrothered + public static class LittleJohnDoe + { + public void makeACoffee() { + System.out.println("Making a coffee"); + } + + public void watchTv() { + System.out.println("Watching TV"); + } + } +} diff --git a/webbeans-impl/src/test/java/org/apache/webbeans/test/interceptors/owb1441/WatchExtension.java b/webbeans-impl/src/test/java/org/apache/webbeans/test/interceptors/owb1441/WatchExtension.java new file mode 100644 index 000000000..7c3738908 --- /dev/null +++ b/webbeans-impl/src/test/java/org/apache/webbeans/test/interceptors/owb1441/WatchExtension.java @@ -0,0 +1,165 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.webbeans.test.interceptors.owb1441; + +import java.lang.annotation.Annotation; +import java.lang.reflect.Method; +import java.lang.reflect.Type; +import java.util.Collections; +import java.util.HashSet; +import java.util.List; +import java.util.Set; + +import jakarta.enterprise.event.Observes; +import jakarta.enterprise.inject.spi.AfterBeanDiscovery; +import jakarta.enterprise.inject.spi.AnnotatedConstructor; +import jakarta.enterprise.inject.spi.AnnotatedField; +import jakarta.enterprise.inject.spi.AnnotatedMethod; +import jakarta.enterprise.inject.spi.AnnotatedParameter; +import jakarta.enterprise.inject.spi.AnnotatedType; +import jakarta.enterprise.inject.spi.BeanManager; +import jakarta.enterprise.inject.spi.BeforeBeanDiscovery; +import jakarta.enterprise.inject.spi.Extension; +import jakarta.enterprise.util.Nonbinding; +import org.apache.webbeans.test.interceptors.interceptorbean.BigBrotherInterceptorBean; +import org.apache.webbeans.test.interceptors.interceptorbean.BigBrothered; + +public class WatchExtension implements Extension +{ + public void registerInterceptorBinding(@Observes BeforeBeanDiscovery beforeBeanDiscovery, BeanManager beanManager) { + beforeBeanDiscovery.addInterceptorBinding( + new WatchedAnnotatedType(beanManager.createAnnotatedType(Watched.class))); + + } + + public void registerInterceptor(@Observes AfterBeanDiscovery afterBeanDiscovery) { + afterBeanDiscovery.addBean(new WatchInterceptorBean(42)); + } + + // To add Nonbinding to @Watched members + @SuppressWarnings("unchecked") + static class WatchedAnnotatedType implements AnnotatedType { + private final AnnotatedType delegate; + private final Set> methods; + + WatchedAnnotatedType(final AnnotatedType delegate) { + this.delegate = delegate; + this.methods = new HashSet<>(); + + for (AnnotatedMethod method : delegate.getMethods()) { + methods.add(new AnnotatedMethod<>() { + private final AnnotatedMethod delegate = (AnnotatedMethod) method; + private final Set annotations = Collections.singleton(Nonbinding.Literal.INSTANCE); + + @Override + public Method getJavaMember() { + return delegate.getJavaMember(); + } + + @Override + public List> getParameters() { + return delegate.getParameters(); + } + + @Override + public boolean isStatic() { + return delegate.isStatic(); + } + + @Override + public AnnotatedType getDeclaringType() { + return delegate.getDeclaringType(); + } + + @Override + public Type getBaseType() { + return delegate.getBaseType(); + } + + @Override + public Set getTypeClosure() { + return delegate.getTypeClosure(); + } + + @Override + public T getAnnotation(final Class annotationType) { + if (annotationType.equals(Nonbinding.class)) { + return (T) annotations.iterator().next(); + } + return null; + } + + @Override + public Set getAnnotations() { + return annotations; + } + + @Override + public boolean isAnnotationPresent(final Class annotationType) { + return annotationType.equals(Nonbinding.class); + } + }); + } + } + + @Override + public Class getJavaClass() { + return delegate.getJavaClass(); + } + + @Override + public Set> getConstructors() { + return delegate.getConstructors(); + } + + @Override + public Set> getMethods() { + return this.methods; + } + + @Override + public Set> getFields() { + return delegate.getFields(); + } + + @Override + public Type getBaseType() { + return delegate.getBaseType(); + } + + @Override + public Set getTypeClosure() { + return delegate.getTypeClosure(); + } + + @Override + public T getAnnotation(final Class annotationType) { + return delegate.getAnnotation(annotationType); + } + + @Override + public Set getAnnotations() { + return delegate.getAnnotations(); + } + + @Override + public boolean isAnnotationPresent(final Class annotationType) { + return delegate.isAnnotationPresent(annotationType); + } + } + +} diff --git a/webbeans-impl/src/test/java/org/apache/webbeans/test/interceptors/owb1441/WatchInterceptor.java b/webbeans-impl/src/test/java/org/apache/webbeans/test/interceptors/owb1441/WatchInterceptor.java new file mode 100644 index 000000000..38512d245 --- /dev/null +++ b/webbeans-impl/src/test/java/org/apache/webbeans/test/interceptors/owb1441/WatchInterceptor.java @@ -0,0 +1,30 @@ +package org.apache.webbeans.test.interceptors.owb1441; + +import jakarta.interceptor.AroundInvoke; +import jakarta.interceptor.InvocationContext; + +public class WatchInterceptor { + + public WatchInterceptor(String totallyUselessParamJustToNotHaveADefaultCt) { + + } + + private static boolean observed = false; + + @AroundInvoke + public Object invoke(InvocationContext context) throws Exception + { + System.out.println("I am watching you " + context.getMethod()); + observed = true; + + return context.proceed(); + } + + public static boolean isObserved() + { + boolean wasObserved = observed; + observed = false; + return wasObserved; + } + +} diff --git a/webbeans-impl/src/test/java/org/apache/webbeans/test/interceptors/owb1441/WatchInterceptorBean.java b/webbeans-impl/src/test/java/org/apache/webbeans/test/interceptors/owb1441/WatchInterceptorBean.java new file mode 100644 index 000000000..bdfdcfba6 --- /dev/null +++ b/webbeans-impl/src/test/java/org/apache/webbeans/test/interceptors/owb1441/WatchInterceptorBean.java @@ -0,0 +1,124 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.webbeans.test.interceptors.owb1441; + +import java.lang.annotation.Annotation; +import java.lang.reflect.Type; +import java.util.Collections; +import java.util.Set; + +import jakarta.enterprise.context.Dependent; +import jakarta.enterprise.context.spi.CreationalContext; +import jakarta.enterprise.inject.spi.InjectionPoint; +import jakarta.enterprise.inject.spi.InterceptionType; +import jakarta.enterprise.inject.spi.Interceptor; +import jakarta.enterprise.util.AnnotationLiteral; +import jakarta.interceptor.InvocationContext; +import org.apache.webbeans.annotation.DefaultLiteral; +import org.apache.webbeans.test.interceptors.interceptorbean.BigBrotherInterceptor; +import org.apache.webbeans.test.interceptors.interceptorbean.BigBrothered; + +public class WatchInterceptorBean implements Interceptor +{ + // it's good performance practice to keep the sets static as they are requested tons of times! + public static final Set TYPES = Set.of(WatchInterceptor.class); + public static final Set QUALIFIERS = Set.of(DefaultLiteral.INSTANCE); + public static final Set INTERCEPTOR_BINDINGS = Set.of(new AnnotationLiteral() {}); + + public WatchInterceptorBean(int totallyUselessParamJustToNotHaveADefaultCt) + { + // all fine ;) + } + + @Override + public Set getInterceptorBindings() + { + return INTERCEPTOR_BINDINGS; + } + + @Override + public boolean intercepts(InterceptionType type) + { + return InterceptionType.AROUND_INVOKE.equals(type); + } + + @Override + public Object intercept(InterceptionType type, WatchInterceptor instance, InvocationContext ctx) throws Exception + { + return instance.invoke(ctx); + } + + @Override + public Class getBeanClass() + { + return WatchInterceptor.class; + } + + @Override + public Set getInjectionPoints() + { + return Collections.emptySet(); + } + + @Override + public WatchInterceptor create(CreationalContext creationalContext) + { + return new WatchInterceptor(""); + } + + @Override + public void destroy(WatchInterceptor instance, CreationalContext creationalContext) + { + // no op + } + + @Override + public Set getTypes() + { + return TYPES; + } + + @Override + public Set getQualifiers() + { + return QUALIFIERS; + } + + @Override + public Class getScope() + { + return Dependent.class; + } + + @Override + public String getName() + { + return null; + } + + @Override + public Set> getStereotypes() + { + return Collections.emptySet(); + } + + @Override + public boolean isAlternative() + { + return false; + } +} diff --git a/webbeans-impl/src/test/java/org/apache/webbeans/test/interceptors/owb1441/Watched.java b/webbeans-impl/src/test/java/org/apache/webbeans/test/interceptors/owb1441/Watched.java new file mode 100644 index 000000000..495fbc0ef --- /dev/null +++ b/webbeans-impl/src/test/java/org/apache/webbeans/test/interceptors/owb1441/Watched.java @@ -0,0 +1,35 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.webbeans.test.interceptors.owb1441; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +import org.apache.webbeans.test.interceptors.interceptorbean.BigBrotheredExtension; + +/** + * Test interceptor annotation + * + * Note that this is not an InterceptorBinding as we do register the interface via {@link WatchExtension}. + */ +@Target({ElementType.METHOD, ElementType.TYPE}) +@Retention(RetentionPolicy.RUNTIME) +public @interface Watched +{ +}