You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@openwebbeans.apache.org by ar...@apache.org on 2020/09/13 09:22:10 UTC
[openwebbeans] branch master updated: OWB-1349: Use annotated type
to check qualifier validation rules
This is an automated email from the ASF dual-hosted git repository.
arne pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/openwebbeans.git
The following commit(s) were added to refs/heads/master by this push:
new 4885d0a OWB-1349: Use annotated type to check qualifier validation rules
4885d0a is described below
commit 4885d0a52b03e5a4c099c102036ff556ab8fa4bc
Author: arne <ar...@apache.org>
AuthorDate: Fri Sep 11 21:16:14 2020 +0200
OWB-1349: Use annotated type to check qualifier validation rules
---
.../webbeans/annotation/AnnotationManager.java | 48 ++++-
.../component/creation/BeanAttributesBuilder.java | 18 +-
.../apache/webbeans/container/BeanManagerImpl.java | 6 +-
.../org/apache/webbeans/util/AnnotationUtil.java | 5 +
.../qualifier/CacheUsesQualifierOverridesTest.java | 205 ++++++++++++++++++++-
5 files changed, 254 insertions(+), 28 deletions(-)
diff --git a/webbeans-impl/src/main/java/org/apache/webbeans/annotation/AnnotationManager.java b/webbeans-impl/src/main/java/org/apache/webbeans/annotation/AnnotationManager.java
index b5442c4..b934ea9 100644
--- a/webbeans-impl/src/main/java/org/apache/webbeans/annotation/AnnotationManager.java
+++ b/webbeans-impl/src/main/java/org/apache/webbeans/annotation/AnnotationManager.java
@@ -28,6 +28,7 @@ import org.apache.webbeans.exception.WebBeansConfigurationException;
import org.apache.webbeans.util.AnnotationUtil;
import org.apache.webbeans.util.ArrayUtil;
import org.apache.webbeans.util.Asserts;
+import org.apache.webbeans.util.ClassUtil;
import javax.enterprise.context.NormalScope;
import javax.enterprise.inject.Any;
@@ -57,6 +58,7 @@ import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
+import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Optional;
@@ -459,7 +461,7 @@ public final class AnnotationManager
}
}
- private void checkQualifierConditions(Annotation ann)
+ public void checkQualifierConditions(Annotation ann)
{
if (ann == DefaultLiteral.INSTANCE || ann == AnyLiteral.INSTANCE ||
ann.annotationType().equals(Default.class) || ann.annotationType().equals(Any.class) ||
@@ -469,17 +471,49 @@ public final class AnnotationManager
return;
}
- Method[] methods = webBeansContext.getSecurityService().doPrivilegedGetDeclaredMethods(ann.annotationType());
+ AnnotatedType annotatedType = webBeansContext.getBeanManagerImpl().getAdditionalAnnotatedTypeQualifiers().get(ann.annotationType());
+ if (annotatedType == null)
+ {
+ Iterator<AnnotatedType> annotatedTypes = (Iterator)webBeansContext.getBeanManagerImpl().getAnnotatedTypes(ann.annotationType()).iterator();
+ if (annotatedTypes.hasNext())
+ {
+ annotatedType = annotatedTypes.next();
+ // TODO what to do here, if we have more than one?
+ }
+ }
+ if (annotatedType != null)
+ {
+ Set<AnnotatedMethod> methods = annotatedType.getMethods();
- for (Method method : methods)
+ for (AnnotatedMethod method : methods)
+ {
+ Type baseType = method.getBaseType();
+ Class<?> clazz = ClassUtil.getClass(baseType);
+ if (clazz.isArray() || clazz.isAnnotation())
+ {
+ if (!AnnotationUtil.hasAnnotation(method.getAnnotations(), Nonbinding.class))
+ {
+ throw new WebBeansConfigurationException("WebBeans definition class : " + method.getJavaMember().getDeclaringClass().getName() + " @Qualifier : "
+ + ann.annotationType().getName()
+ + " must have @NonBinding valued members for its array-valued and annotation valued members");
+ }
+ }
+ }
+ }
+ else
{
- Class<?> clazz = method.getReturnType();
- if (clazz.isArray() || clazz.isAnnotation())
+ Method[] methods = webBeansContext.getSecurityService().doPrivilegedGetDeclaredMethods(ann.annotationType());
+
+ for (Method method : methods)
{
- if (!AnnotationUtil.hasAnnotation(method.getDeclaredAnnotations(), Nonbinding.class))
+ Class<?> clazz = method.getReturnType();
+ if (clazz.isArray() || clazz.isAnnotation())
{
- throw new WebBeansConfigurationException("@Qualifier : " + ann.annotationType().getName()
+ if (!AnnotationUtil.hasAnnotation(method.getDeclaredAnnotations(), Nonbinding.class))
+ {
+ throw new WebBeansConfigurationException("@Qualifier : " + ann.annotationType().getName()
+ " must have @NonBinding valued members for its array-valued and annotation valued members");
+ }
}
}
}
diff --git a/webbeans-impl/src/main/java/org/apache/webbeans/component/creation/BeanAttributesBuilder.java b/webbeans-impl/src/main/java/org/apache/webbeans/component/creation/BeanAttributesBuilder.java
index db00d22..eb6693f 100644
--- a/webbeans-impl/src/main/java/org/apache/webbeans/component/creation/BeanAttributesBuilder.java
+++ b/webbeans-impl/src/main/java/org/apache/webbeans/component/creation/BeanAttributesBuilder.java
@@ -20,7 +20,6 @@ package org.apache.webbeans.component.creation;
import java.lang.annotation.Annotation;
import java.lang.reflect.Constructor;
-import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.lang.reflect.Type;
import java.util.Collections;
@@ -42,7 +41,6 @@ import javax.enterprise.inject.spi.AnnotatedMember;
import javax.enterprise.inject.spi.AnnotatedMethod;
import javax.enterprise.inject.spi.AnnotatedParameter;
import javax.enterprise.inject.spi.AnnotatedType;
-import javax.enterprise.util.Nonbinding;
import javax.inject.Named;
import javax.inject.Scope;
import javax.interceptor.Interceptor;
@@ -217,21 +215,7 @@ public abstract class BeanAttributesBuilder<T, A extends Annotated>
if (annotationManager.isQualifierAnnotation(type))
{
- Method[] methods = webBeansContext.getSecurityService().doPrivilegedGetDeclaredMethods(type);
-
- for (Method method : methods)
- {
- Class<?> clazz = method.getReturnType();
- if (clazz.isArray() || clazz.isAnnotation())
- {
- if (!AnnotationUtil.hasAnnotation(method.getDeclaredAnnotations(), Nonbinding.class))
- {
- throw new WebBeansConfigurationException("WebBeans definition class : " + method.getDeclaringClass().getName() + " @Qualifier : "
- + annotation.annotationType().getName()
- + " must have @NonBinding valued members for its array-valued and annotation valued members");
- }
- }
- }
+ annotationManager.checkQualifierConditions(annotation);
if (qualifiedTypes.contains(annotation.annotationType()) && !isRepetable(annotated, annotation))
{
diff --git a/webbeans-impl/src/main/java/org/apache/webbeans/container/BeanManagerImpl.java b/webbeans-impl/src/main/java/org/apache/webbeans/container/BeanManagerImpl.java
index 082409b..4091b57 100644
--- a/webbeans-impl/src/main/java/org/apache/webbeans/container/BeanManagerImpl.java
+++ b/webbeans-impl/src/main/java/org/apache/webbeans/container/BeanManagerImpl.java
@@ -1442,7 +1442,11 @@ public class BeanManagerImpl implements BeanManager, Referenceable
public <T> Iterable<AnnotatedType<T>> getAnnotatedTypes(Class<T> type)
{
final Collection<AnnotatedType<T>> types = new ArrayList<>(2);
- types.add(annotatedElementFactory.getAnnotatedType(type));
+ AnnotatedType<T> annotatedType = annotatedElementFactory.getAnnotatedType(type);
+ if (annotatedType != null)
+ {
+ types.add(annotatedType);
+ }
final Collection<AnnotatedType<T>> userAnnotatedTypes = getUserAnnotatedTypes(type);
if (userAnnotatedTypes != null)
{
diff --git a/webbeans-impl/src/main/java/org/apache/webbeans/util/AnnotationUtil.java b/webbeans-impl/src/main/java/org/apache/webbeans/util/AnnotationUtil.java
index 589344b..fba8093 100644
--- a/webbeans-impl/src/main/java/org/apache/webbeans/util/AnnotationUtil.java
+++ b/webbeans-impl/src/main/java/org/apache/webbeans/util/AnnotationUtil.java
@@ -479,6 +479,11 @@ public final class AnnotationUtil
return getAnnotation(anns, annotation) != null;
}
+ public static boolean hasAnnotation(Set<Annotation> anns, Class<? extends Annotation> annotation)
+ {
+ return getAnnotation(anns, annotation) != null;
+ }
+
/**
* get the annotation of the given type from the array.
* @param anns
diff --git a/webbeans-impl/src/test/java/org/apache/webbeans/test/qualifier/CacheUsesQualifierOverridesTest.java b/webbeans-impl/src/test/java/org/apache/webbeans/test/qualifier/CacheUsesQualifierOverridesTest.java
index c26ec46..5710794 100644
--- a/webbeans-impl/src/test/java/org/apache/webbeans/test/qualifier/CacheUsesQualifierOverridesTest.java
+++ b/webbeans-impl/src/test/java/org/apache/webbeans/test/qualifier/CacheUsesQualifierOverridesTest.java
@@ -24,12 +24,25 @@ import static java.lang.annotation.RetentionPolicy.RUNTIME;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotEquals;
+import java.lang.annotation.Annotation;
import java.lang.annotation.Retention;
import java.lang.annotation.Target;
+import java.lang.reflect.Method;
+import java.lang.reflect.Type;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
import java.util.function.Supplier;
import javax.enterprise.context.Dependent;
import javax.enterprise.event.Observes;
+import javax.enterprise.inject.spi.AnnotatedConstructor;
+import javax.enterprise.inject.spi.AnnotatedField;
+import javax.enterprise.inject.spi.AnnotatedMethod;
+import javax.enterprise.inject.spi.AnnotatedParameter;
+import javax.enterprise.inject.spi.AnnotatedType;
import javax.enterprise.inject.spi.BeforeBeanDiscovery;
import javax.enterprise.inject.spi.Extension;
import javax.enterprise.util.AnnotationLiteral;
@@ -38,15 +51,18 @@ import javax.inject.Qualifier;
import org.apache.webbeans.config.OwbParametrizedTypeImpl;
import org.apache.webbeans.test.AbstractUnitTest;
+import org.apache.webbeans.util.GenericsUtil;
import org.junit.Test;
public class CacheUsesQualifierOverridesTest extends AbstractUnitTest
{
@Test
- public void run()
+ public void configureExistingQualifier()
{
- addExtension(new Extension() {
- void changeQualifier(@Observes final BeforeBeanDiscovery beforeBeanDiscovery) {
+ addExtension(new Extension()
+ {
+ void changeQualifier(@Observes final BeforeBeanDiscovery beforeBeanDiscovery)
+ {
beforeBeanDiscovery.configureQualifier(TheQualifier.class)
.methods().forEach(m -> m.remove(it -> it.annotationType() == Nonbinding.class));
}
@@ -61,8 +77,42 @@ public class CacheUsesQualifierOverridesTest extends AbstractUnitTest
assertNotEquals(uno.getClass(), due.getClass());
}
+ @Test
+ public void addQualifierWithNonBinding()
+ {
+ addExtension(new Extension()
+ {
+ void changeQualifier(@Observes final BeforeBeanDiscovery beforeBeanDiscovery)
+ {
+ beforeBeanDiscovery.configureQualifier(QualifierWithoutMarker.class)
+ .methods().forEach(m -> m.add(new Nonbinding.Literal()));
+ }
+ });
+ startContainer(Impl1.class, Impl2.class);
+ final OwbParametrizedTypeImpl type = new OwbParametrizedTypeImpl(null, Supplier.class, String.class);
+ final Supplier<String> uno = getInstance(type, new QualifierWithoutMarker.Literal("non-binding attribute"));
+ assertEquals("1", uno.get());
+ }
+
+ @Test
+ public void addQualifier()
+ {
+ addExtension(new Extension()
+ {
+ void addQualifier(@Observes final BeforeBeanDiscovery beforeBeanDiscovery)
+ {
+ beforeBeanDiscovery.addQualifier(new QualifierWithArrayAttributeType());
+ }
+ });
+ startContainer(Impl1.class, Impl2.class);
+ final OwbParametrizedTypeImpl type = new OwbParametrizedTypeImpl(null, Supplier.class, String.class);
+ final Supplier<String> uno = getInstance(type, new QualifierWithoutMarker.Literal("non-binding attribute"));
+ assertEquals("1", uno.get());
+ }
+
@Dependent
@TheQualifier("uno")
+ @QualifierWithoutMarker
public static class Impl1 implements Supplier<String>
{
@Override
@@ -107,4 +157,153 @@ public class CacheUsesQualifierOverridesTest extends AbstractUnitTest
}
}
}
+
+ @Target({FIELD, TYPE})
+ @Retention(RUNTIME)
+ public @interface QualifierWithoutMarker
+ {
+ String[] value() default {};
+
+ class Literal extends AnnotationLiteral<QualifierWithoutMarker> implements QualifierWithoutMarker
+ {
+ private final String[] value;
+
+ public Literal(final String... value)
+ {
+ this.value = value;
+ }
+
+ @Override
+ public String[] value()
+ {
+ return value;
+ }
+ }
+ }
+
+ class QualifierWithArrayAttributeType implements AnnotatedType<QualifierWithoutMarker>
+ {
+
+ @Override
+ public Type getBaseType()
+ {
+ return QualifierWithoutMarker.class;
+ }
+
+ @Override
+ public Set<Type> getTypeClosure()
+ {
+ return GenericsUtil.getTypeClosure(QualifierWithoutMarker.class);
+ }
+
+ @Override
+ public <T extends Annotation> T getAnnotation(Class<T> annotationType)
+ {
+ return QualifierWithoutMarker.class.getAnnotation(annotationType);
+ }
+
+ @Override
+ public Set<Annotation> getAnnotations()
+ {
+ return new HashSet<>(Arrays.asList(QualifierWithoutMarker.class.getAnnotations()));
+ }
+
+ @Override
+ public boolean isAnnotationPresent(Class<? extends Annotation> annotationType)
+ {
+ return QualifierWithoutMarker.class.isAnnotationPresent(annotationType);
+ }
+
+ @Override
+ public Class<QualifierWithoutMarker> getJavaClass()
+ {
+ return QualifierWithoutMarker.class;
+ }
+
+ @Override
+ public Set<AnnotatedConstructor<QualifierWithoutMarker>> getConstructors()
+ {
+ return Collections.emptySet();
+ }
+
+ @Override
+ public Set<AnnotatedMethod<? super QualifierWithoutMarker>> getMethods()
+ {
+ AnnotatedType<QualifierWithoutMarker> declaringType = this;
+ return Collections.singleton(new AnnotatedMethod<QualifierWithoutMarker>()
+ {
+
+ @Override
+ public List<AnnotatedParameter<QualifierWithoutMarker>> getParameters()
+ {
+ return Collections.emptyList();
+ }
+
+ @Override
+ public boolean isStatic()
+ {
+ return false;
+ }
+
+ @Override
+ public AnnotatedType<QualifierWithoutMarker> getDeclaringType()
+ {
+ return declaringType;
+ }
+
+ @Override
+ public Type getBaseType()
+ {
+ return String[].class;
+ }
+
+ @Override
+ public Set<Type> getTypeClosure()
+ {
+ return GenericsUtil.getTypeClosure(String[].class);
+ }
+
+ @Override
+ public <T extends Annotation> T getAnnotation(Class<T> annotationType)
+ {
+ if (Nonbinding.class.equals(annotationType))
+ {
+ return (T)new Nonbinding.Literal();
+ }
+ else
+ {
+ return null;
+ }
+ }
+
+ @Override
+ public Set<Annotation> getAnnotations()
+ {
+ return Collections.singleton(new Nonbinding.Literal());
+ }
+
+ @Override
+ public boolean isAnnotationPresent(Class<? extends Annotation> annotationType)
+ {
+ return Nonbinding.class.equals(annotationType);
+ }
+
+ @Override
+ public Method getJavaMember() {
+ try {
+ return QualifierWithoutMarker.class.getMethod("value");
+ } catch (NoSuchMethodException e) {
+ throw new IllegalStateException(e);
+ }
+ }
+
+ });
+ }
+
+ @Override
+ public Set<AnnotatedField<? super QualifierWithoutMarker>> getFields() {
+ return Collections.emptySet();
+ }
+
+ }
}