Author: rmannibucau
Date: Sun Jun 23 09:10:31 2019
New Revision: 1861905
URL: http://svn.apache.org/viewvc?rev=1861905&view=rev
Log:
OWB-1292 exit satisfiesDependency when generics loop
Modified:
openwebbeans/trunk/webbeans-impl/src/main/java/org/apache/webbeans/component/creation/AbstractBeanBuilder.java
openwebbeans/trunk/webbeans-impl/src/main/java/org/apache/webbeans/component/creation/BaseProducerFactory.java
openwebbeans/trunk/webbeans-impl/src/main/java/org/apache/webbeans/config/BeansDeployer.java
openwebbeans/trunk/webbeans-impl/src/main/java/org/apache/webbeans/container/BeanManagerImpl.java
openwebbeans/trunk/webbeans-impl/src/main/java/org/apache/webbeans/container/InjectionResolver.java
openwebbeans/trunk/webbeans-impl/src/main/java/org/apache/webbeans/decorator/DecoratorsManager.java
openwebbeans/trunk/webbeans-impl/src/main/java/org/apache/webbeans/event/NotificationManager.java
openwebbeans/trunk/webbeans-impl/src/main/java/org/apache/webbeans/portable/EventProducer.java
openwebbeans/trunk/webbeans-impl/src/main/java/org/apache/webbeans/util/GenericsUtil.java
openwebbeans/trunk/webbeans-impl/src/main/java/org/apache/webbeans/util/WebBeansUtil.java
openwebbeans/trunk/webbeans-impl/src/test/java/org/apache/webbeans/test/unittests/inject/parametrized/GenericClassTest.java
openwebbeans/trunk/webbeans-impl/src/test/java/org/apache/webbeans/test/util/GenericsUtilTest.java
Modified:
openwebbeans/trunk/webbeans-impl/src/main/java/org/apache/webbeans/component/creation/AbstractBeanBuilder.java
URL:
http://svn.apache.org/viewvc/openwebbeans/trunk/webbeans-impl/src/main/java/org/apache/webbeans/component/creation/AbstractBeanBuilder.java?rev=1861905&r1=1861904&r2=1861905&view=diff
==============================================================================
---
openwebbeans/trunk/webbeans-impl/src/main/java/org/apache/webbeans/component/creation/AbstractBeanBuilder.java
(original)
+++
openwebbeans/trunk/webbeans-impl/src/main/java/org/apache/webbeans/component/creation/AbstractBeanBuilder.java
Sun Jun 23 09:10:31 2019
@@ -27,6 +27,7 @@ import javax.enterprise.inject.spi.Annot
import javax.enterprise.inject.spi.AnnotatedParameter;
import javax.enterprise.inject.spi.AnnotatedType;
import java.util.Collection;
+import java.util.HashMap;
import java.util.Set;
import org.apache.webbeans.component.ProducerFieldBean;
@@ -59,7 +60,7 @@ public abstract class AbstractBeanBuilde
boolean found = false;
for (ProducerMethodBean<?> producer : producerBeans)
{
- if (GenericsUtil.satisfiesDependency(false, true,
producer.getCreatorMethod().getGenericReturnType(), param.getBaseType()))
+ if (GenericsUtil.satisfiesDependency(false, true,
producer.getCreatorMethod().getGenericReturnType(), param.getBaseType(), new
HashMap<>()))
{
found = true;
break;
@@ -69,7 +70,7 @@ public abstract class AbstractBeanBuilde
{
for (ProducerFieldBean<?> field : producerFields)
{
- if (GenericsUtil.satisfiesDependency(false, true,
field.getCreatorField().getType(), param.getBaseType()))
+ if (GenericsUtil.satisfiesDependency(false, true,
field.getCreatorField().getType(), param.getBaseType(), new HashMap<>()))
{
found = true;
break;
@@ -81,7 +82,7 @@ public abstract class AbstractBeanBuilde
// see if @Disposes should just be ignored as well
- no inheritance
for (AnnotatedMethod<?> producer :
ignoredProducers)
{
- if (GenericsUtil.satisfiesDependency(false,
true, producer.getJavaMember().getGenericReturnType(), param.getBaseType()))
+ if (GenericsUtil.satisfiesDependency(false,
true, producer.getJavaMember().getGenericReturnType(), param.getBaseType(), new
HashMap<>()))
{
found = true;
break;
Modified:
openwebbeans/trunk/webbeans-impl/src/main/java/org/apache/webbeans/component/creation/BaseProducerFactory.java
URL:
http://svn.apache.org/viewvc/openwebbeans/trunk/webbeans-impl/src/main/java/org/apache/webbeans/component/creation/BaseProducerFactory.java?rev=1861905&r1=1861904&r2=1861905&view=diff
==============================================================================
---
openwebbeans/trunk/webbeans-impl/src/main/java/org/apache/webbeans/component/creation/BaseProducerFactory.java
(original)
+++
openwebbeans/trunk/webbeans-impl/src/main/java/org/apache/webbeans/component/creation/BaseProducerFactory.java
Sun Jun 23 09:10:31 2019
@@ -43,6 +43,7 @@ import javax.inject.Named;
import java.lang.annotation.Annotation;
import java.lang.reflect.Type;
import java.util.Collections;
+import java.util.HashMap;
import java.util.HashSet;
import java.util.Set;
@@ -102,7 +103,7 @@ public abstract class BaseProducerFactor
{
if (annotatedParameter.isAnnotationPresent(Disposes.class))
{
- if (!GenericsUtil.satisfiesDependency(false, true,
producerBaseType, annotatedParameter.getBaseType()))
+ if (!GenericsUtil.satisfiesDependency(false, true,
producerBaseType, annotatedParameter.getBaseType(), new HashMap<>()))
{
continue;
}
Modified:
openwebbeans/trunk/webbeans-impl/src/main/java/org/apache/webbeans/config/BeansDeployer.java
URL:
http://svn.apache.org/viewvc/openwebbeans/trunk/webbeans-impl/src/main/java/org/apache/webbeans/config/BeansDeployer.java?rev=1861905&r1=1861904&r2=1861905&view=diff
==============================================================================
---
openwebbeans/trunk/webbeans-impl/src/main/java/org/apache/webbeans/config/BeansDeployer.java
(original)
+++
openwebbeans/trunk/webbeans-impl/src/main/java/org/apache/webbeans/config/BeansDeployer.java
Sun Jun 23 09:10:31 2019
@@ -597,7 +597,7 @@ public class BeansDeployer
ParameterizedType pt2 =
ParameterizedType.class.cast(t);
if (pt1.getRawType() == pt2.getRawType() &&
- !GenericsUtil.isAssignableFrom(true, false, pt1,
pt2))
+ !GenericsUtil.isAssignableFrom(true, false, pt1,
pt2, new HashMap<>()))
{
throw new WebBeansConfigurationException("Generic
error matching " + api + " and " + t);
}
Modified:
openwebbeans/trunk/webbeans-impl/src/main/java/org/apache/webbeans/container/BeanManagerImpl.java
URL:
http://svn.apache.org/viewvc/openwebbeans/trunk/webbeans-impl/src/main/java/org/apache/webbeans/container/BeanManagerImpl.java?rev=1861905&r1=1861904&r2=1861905&view=diff
==============================================================================
---
openwebbeans/trunk/webbeans-impl/src/main/java/org/apache/webbeans/container/BeanManagerImpl.java
(original)
+++
openwebbeans/trunk/webbeans-impl/src/main/java/org/apache/webbeans/container/BeanManagerImpl.java
Sun Jun 23 09:10:31 2019
@@ -755,8 +755,8 @@ public class BeanManagerImpl implements
boolean isProducer = AbstractProducerBean.class.isInstance(bean);
if(!isProducer && // we have different rules for producers
!isBeanTypeAssignableToGivenType(bean.getTypes(), beanType,
bean instanceof NewBean, isProducer) &&
- !GenericsUtil.satisfiesDependency(false, isProducer, beanType,
bean.getBeanClass()) &&
- !GenericsUtil.satisfiesDependencyRaw(false, isProducer,
beanType, bean.getBeanClass()))
+ !GenericsUtil.satisfiesDependency(false, isProducer, beanType,
bean.getBeanClass(), new HashMap<>()) &&
+ !GenericsUtil.satisfiesDependencyRaw(false, isProducer,
beanType, bean.getBeanClass(), new HashMap<>()))
{
throw new IllegalArgumentException("Given bean type : " +
beanType + " is not applicable for the bean instance : " + bean);
}
@@ -934,7 +934,7 @@ public class BeanManagerImpl implements
{
for (Type beanApiType : beanTypes)
{
- if (GenericsUtil.satisfiesDependency(false, producer, givenType,
beanApiType))
+ if (GenericsUtil.satisfiesDependency(false, producer, givenType,
beanApiType, new HashMap<>()))
{
return true;
}
Modified:
openwebbeans/trunk/webbeans-impl/src/main/java/org/apache/webbeans/container/InjectionResolver.java
URL:
http://svn.apache.org/viewvc/openwebbeans/trunk/webbeans-impl/src/main/java/org/apache/webbeans/container/InjectionResolver.java?rev=1861905&r1=1861904&r2=1861905&view=diff
==============================================================================
---
openwebbeans/trunk/webbeans-impl/src/main/java/org/apache/webbeans/container/InjectionResolver.java
(original)
+++
openwebbeans/trunk/webbeans-impl/src/main/java/org/apache/webbeans/container/InjectionResolver.java
Sun Jun 23 09:10:31 2019
@@ -54,6 +54,7 @@ import java.lang.reflect.Type;
import java.lang.reflect.TypeVariable;
import java.lang.reflect.WildcardType;
import java.util.Collections;
+import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
@@ -514,7 +515,7 @@ public class InjectionResolver
if (GenericsUtil.satisfiesDependency(
isDelegate,
AbstractProducerBean.class.isInstance(component),
- injectionPointType, componentApiType))
+ injectionPointType, componentApiType, new
HashMap<>()))
{
resolvedComponents.add(component);
break;
@@ -599,7 +600,7 @@ public class InjectionResolver
boolean isProducer = AbstractProducerBean.class.isInstance(bean);
for (Type type : bean.getTypes())
{
- if (GenericsUtil.satisfiesDependency(isDelegate, isProducer,
injectionPointType, type))
+ if (GenericsUtil.satisfiesDependency(isDelegate, isProducer,
injectionPointType, type, new HashMap<>()))
{
resolved.add(bean);
}
@@ -625,7 +626,7 @@ public class InjectionResolver
for (Type componentApiType : component.getTypes())
{
- if (GenericsUtil.satisfiesDependency(isDelegate, isProducer,
injectionPointType, componentApiType))
+ if (GenericsUtil.satisfiesDependency(isDelegate, isProducer,
injectionPointType, componentApiType, new HashMap<>()))
{
resolvedComponents.add(component);
break;
Modified:
openwebbeans/trunk/webbeans-impl/src/main/java/org/apache/webbeans/decorator/DecoratorsManager.java
URL:
http://svn.apache.org/viewvc/openwebbeans/trunk/webbeans-impl/src/main/java/org/apache/webbeans/decorator/DecoratorsManager.java?rev=1861905&r1=1861904&r2=1861905&view=diff
==============================================================================
---
openwebbeans/trunk/webbeans-impl/src/main/java/org/apache/webbeans/decorator/DecoratorsManager.java
(original)
+++
openwebbeans/trunk/webbeans-impl/src/main/java/org/apache/webbeans/decorator/DecoratorsManager.java
Sun Jun 23 09:10:31 2019
@@ -21,6 +21,7 @@ package org.apache.webbeans.decorator;
import java.lang.annotation.Annotation;
import java.lang.reflect.Type;
import java.util.ArrayList;
+import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
@@ -238,7 +239,7 @@ public class DecoratorsManager
boolean ok = false;
for (Type apiType : apiTypes)
{
- if (GenericsUtil.satisfiesDependency(true, false,
decorator.getDelegateType(), apiType))
+ if (GenericsUtil.satisfiesDependency(true, false,
decorator.getDelegateType(), apiType, new HashMap<>()))
{
ok = true;
break;
Modified:
openwebbeans/trunk/webbeans-impl/src/main/java/org/apache/webbeans/event/NotificationManager.java
URL:
http://svn.apache.org/viewvc/openwebbeans/trunk/webbeans-impl/src/main/java/org/apache/webbeans/event/NotificationManager.java?rev=1861905&r1=1861904&r2=1861905&view=diff
==============================================================================
---
openwebbeans/trunk/webbeans-impl/src/main/java/org/apache/webbeans/event/NotificationManager.java
(original)
+++
openwebbeans/trunk/webbeans-impl/src/main/java/org/apache/webbeans/event/NotificationManager.java
Sun Jun 23 09:10:31 2019
@@ -29,6 +29,7 @@ import java.lang.reflect.TypeVariable;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Comparator;
+import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedList;
@@ -346,8 +347,8 @@ public final class NotificationManager
for (Type eventType : eventTypes)
{
if ((ParameterizedType.class.isInstance(eventType) &&
Class.class.isInstance(observedType)
- && GenericsUtil.isAssignableFrom(true, false,
observedType, ParameterizedType.class.cast(eventType).getRawType()))
- || GenericsUtil.isAssignableFrom(true, false,
observedType, eventType))
+ && GenericsUtil.isAssignableFrom(true, false,
observedType, ParameterizedType.class.cast(eventType).getRawType(), new
HashMap<>()))
+ || GenericsUtil.isAssignableFrom(true, false,
observedType, eventType, new HashMap<>()))
{
Set<ObserverMethod<?>> observerMethods =
observerEntry.getValue();
@@ -498,7 +499,7 @@ public final class NotificationManager
}
else if (observerTypeActualArg instanceof ParameterizedType)
{
- return GenericsUtil.isAssignableFrom(false, true,
observerTypeActualArg, beanClass);
+ return GenericsUtil.isAssignableFrom(false, true,
observerTypeActualArg, beanClass, new HashMap<>());
}
return false;
@@ -533,7 +534,7 @@ public final class NotificationManager
if(checkEventTypeParameterForExtensions(beanClass, actualArgs[0])
&& (secondParam == null || actualArgs.length == 1
||
checkEventTypeParameterForExtensions(secondParam, actualArgs[1])
- || GenericsUtil.isAssignableFrom(true, false,
actualArgs[1], secondParam)))
+ || GenericsUtil.isAssignableFrom(true, false,
actualArgs[1], secondParam, new HashMap<>())))
{
addToMatching(type, matching);
}
Modified:
openwebbeans/trunk/webbeans-impl/src/main/java/org/apache/webbeans/portable/EventProducer.java
URL:
http://svn.apache.org/viewvc/openwebbeans/trunk/webbeans-impl/src/main/java/org/apache/webbeans/portable/EventProducer.java?rev=1861905&r1=1861904&r2=1861905&view=diff
==============================================================================
---
openwebbeans/trunk/webbeans-impl/src/main/java/org/apache/webbeans/portable/EventProducer.java
(original)
+++
openwebbeans/trunk/webbeans-impl/src/main/java/org/apache/webbeans/portable/EventProducer.java
Sun Jun 23 09:10:31 2019
@@ -22,6 +22,7 @@ import java.lang.annotation.Annotation;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.util.ArrayList;
+import java.util.HashMap;
import java.util.List;
import java.util.Map;
@@ -64,7 +65,8 @@ public class EventProducer<T> extends Ab
{
ParameterizedType arg = ParameterizedType.class.cast(event);
Type[] actualTypeArguments = arg.getActualTypeArguments();
- if (actualTypeArguments.length > 0 &&
GenericsUtil.isAssignableFrom(true, false, actualTypeArguments[0], type))
+ if (actualTypeArguments.length > 0 &&
GenericsUtil.isAssignableFrom(
+ true, false, actualTypeArguments[0], type, new
HashMap<>()))
{
list.add(original);
}
Modified:
openwebbeans/trunk/webbeans-impl/src/main/java/org/apache/webbeans/util/GenericsUtil.java
URL:
http://svn.apache.org/viewvc/openwebbeans/trunk/webbeans-impl/src/main/java/org/apache/webbeans/util/GenericsUtil.java?rev=1861905&r1=1861904&r2=1861905&view=diff
==============================================================================
---
openwebbeans/trunk/webbeans-impl/src/main/java/org/apache/webbeans/util/GenericsUtil.java
(original)
+++
openwebbeans/trunk/webbeans-impl/src/main/java/org/apache/webbeans/util/GenericsUtil.java
Sun Jun 23 09:10:31 2019
@@ -33,6 +33,7 @@ import java.util.ArrayList;
import java.util.Collection;
import java.util.HashSet;
import java.util.List;
+import java.util.Map;
import java.util.Set;
import org.apache.webbeans.config.OwbGenericArrayTypeImpl;
@@ -45,11 +46,15 @@ import org.apache.webbeans.config.OwbWil
*/
public final class GenericsUtil
{
- public static boolean satisfiesDependency(boolean isDelegateOrEvent,
boolean isProducer, Type injectionPointType, Type beanType)
+
+ private static final int MAX_GENERIC_LOOPS = 4; // todo: config? it is
already crazy :s
+
+ public static boolean satisfiesDependency(boolean isDelegateOrEvent,
boolean isProducer, Type injectionPointType, Type beanType,
+ Map<Type, Integer> visited)
{
if (beanType instanceof TypeVariable || beanType instanceof
WildcardType || beanType instanceof GenericArrayType)
{
- return isAssignableFrom(isDelegateOrEvent, isProducer,
injectionPointType, beanType);
+ return isAssignableFrom(isDelegateOrEvent, isProducer,
injectionPointType, beanType, visited);
}
else
{
@@ -58,18 +63,19 @@ public final class GenericsUtil
if (ClassUtil.isSame(injectionPointRawType, beanRawType))
{
- return isAssignableFrom(isDelegateOrEvent, isProducer,
injectionPointType, beanType);
+ return isAssignableFrom(isDelegateOrEvent, isProducer,
injectionPointType, beanType, visited);
}
}
return false;
}
- public static boolean satisfiesDependencyRaw(boolean isDelegateOrEvent,
boolean isProducer, Type injectionPointType, Type beanType)
+ public static boolean satisfiesDependencyRaw(boolean isDelegateOrEvent,
boolean isProducer, Type injectionPointType, Type beanType,
+ Map<Type, Integer> visited)
{
if (beanType instanceof TypeVariable || beanType instanceof
WildcardType || beanType instanceof GenericArrayType)
{
- return isAssignableFrom(isDelegateOrEvent, isProducer,
injectionPointType, beanType);
+ return isAssignableFrom(isDelegateOrEvent, isProducer,
injectionPointType, beanType, visited);
}
else
{
@@ -78,7 +84,7 @@ public final class GenericsUtil
if (ClassUtil.isSame(injectionPointRawType, beanRawType))
{
- return isAssignableFrom(isDelegateOrEvent, isProducer,
injectionPointRawType, beanRawType);
+ return isAssignableFrom(isDelegateOrEvent, isProducer,
injectionPointRawType, beanRawType, visited);
}
else
{
@@ -110,36 +116,35 @@ public final class GenericsUtil
/**
* 5.2.3 and 5.2.4
*/
- public static boolean isAssignableFrom(boolean isDelegateOrEvent, boolean
isProducer, Type requiredType, Type beanType)
+ public static boolean isAssignableFrom(boolean isDelegateOrEvent, boolean
isProducer, Type requiredType, Type beanType,
+ Map<Type, Integer> visited)
{
if (requiredType instanceof Class)
{
- return isAssignableFrom(isDelegateOrEvent, (Class<?>)requiredType,
beanType);
+ return isAssignableFrom(isDelegateOrEvent, (Class<?>)requiredType,
beanType, visited);
}
else if (requiredType instanceof ParameterizedType)
{
- return isAssignableFrom(isDelegateOrEvent, isProducer,
(ParameterizedType)requiredType, beanType);
+ return isAssignableFrom(isDelegateOrEvent, isProducer,
(ParameterizedType)requiredType, beanType, visited);
}
else if (requiredType instanceof TypeVariable)
{
- return isAssignableFrom(isDelegateOrEvent,
(TypeVariable<?>)requiredType, beanType);
+ return isAssignableFrom(isDelegateOrEvent,
(TypeVariable<?>)requiredType, beanType, visited);
}
else if (requiredType instanceof GenericArrayType)
{
return Class.class.isInstance(beanType) &&
Class.class.cast(beanType).isArray()
- && isAssignableFrom(isDelegateOrEvent,
(GenericArrayType)requiredType, beanType);
+ && isAssignableFrom(isDelegateOrEvent,
(GenericArrayType)requiredType, beanType, visited);
}
else if (requiredType instanceof WildcardType)
{
- return isAssignableFrom(isDelegateOrEvent,
(WildcardType)requiredType, beanType);
- }
- else
- {
- throw new IllegalArgumentException("Unsupported type " +
requiredType.getClass());
+ return isAssignableFrom(isDelegateOrEvent,
(WildcardType)requiredType, beanType, visited);
}
+ throw new IllegalArgumentException("Unsupported type " +
requiredType.getClass());
}
- private static boolean isAssignableFrom(boolean isDelegateOrEvent,
Class<?> injectionPointType, Type beanType)
+ private static boolean isAssignableFrom(boolean isDelegateOrEvent,
Class<?> injectionPointType, Type beanType,
+ Map<Type, Integer> visited)
{
if (beanType instanceof Class)
{
@@ -147,19 +152,19 @@ public final class GenericsUtil
}
else if (beanType instanceof TypeVariable)
{
- return isAssignableFrom(isDelegateOrEvent, injectionPointType,
(TypeVariable<?>)beanType);
+ return isAssignableFrom(isDelegateOrEvent, injectionPointType,
(TypeVariable<?>)beanType, visited);
}
else if (beanType instanceof ParameterizedType)
{
- return isAssignableFrom(isDelegateOrEvent, injectionPointType,
(ParameterizedType)beanType);
+ return isAssignableFrom(isDelegateOrEvent, injectionPointType,
(ParameterizedType)beanType, visited);
}
else if (beanType instanceof GenericArrayType)
{
- return isAssignableFrom(isDelegateOrEvent, injectionPointType,
(GenericArrayType)beanType);
+ return isAssignableFrom(isDelegateOrEvent, injectionPointType,
(GenericArrayType)beanType, visited);
}
else if (beanType instanceof WildcardType)
{
- return isAssignableFrom(isDelegateOrEvent,
(Type)injectionPointType, (WildcardType)beanType);
+ return isAssignableFrom(isDelegateOrEvent,
(Type)injectionPointType, (WildcardType)beanType, visited);
}
else
{
@@ -172,11 +177,12 @@ public final class GenericsUtil
return ClassUtil.isClassAssignableFrom(injectionPointType, beanType);
}
- private static boolean isAssignableFrom(boolean isDelegateOrEvent,
Class<?> injectionPointType, TypeVariable<?> beanType)
+ private static boolean isAssignableFrom(boolean isDelegateOrEvent,
Class<?> injectionPointType, TypeVariable<?> beanType,
+ Map<Type, Integer> visited)
{
for (Type bounds: beanType.getBounds())
{
- if (isAssignableFrom(isDelegateOrEvent, injectionPointType,
bounds))
+ if (isAssignableFrom(isDelegateOrEvent, injectionPointType,
bounds, visited))
{
return true;
}
@@ -188,7 +194,8 @@ public final class GenericsUtil
* CDI Spec. 5.2.4: "A parameterized bean type is considered assignable to
a raw required type
* if the raw types are identical and all type parameters of the bean type
are either unbounded type variables or java.lang.Object."
*/
- private static boolean isAssignableFrom(boolean isDelegateOrEvent,
Class<?> injectionPointType, ParameterizedType beanType)
+ private static boolean isAssignableFrom(boolean isDelegateOrEvent,
Class<?> injectionPointType, ParameterizedType beanType,
+ Map<Type, Integer> visited)
{
if (beanType.getRawType() != injectionPointType)
{
@@ -199,7 +206,7 @@ public final class GenericsUtil
{
// for delegate and events we match 'in reverse' kind off
// @Observes ProcessInjectionPoint<?, Instance> does also match
Instance<SomeBean>
- return isAssignableFrom(true, injectionPointType,
beanType.getRawType());
+ return isAssignableFrom(true, injectionPointType,
beanType.getRawType(), visited);
}
for (Type typeArgument: beanType.getActualTypeArguments())
@@ -224,23 +231,29 @@ public final class GenericsUtil
return true;
}
- private static boolean isAssignableFrom(boolean isDelegateOrEvent,
Class<?> injectionPointType, GenericArrayType beanType)
+ private static boolean isAssignableFrom(boolean isDelegateOrEvent,
Class<?> injectionPointType, GenericArrayType beanType,
+ Map<Type, Integer> visited)
{
- return injectionPointType.isArray() &&
isAssignableFrom(isDelegateOrEvent, injectionPointType.getComponentType(),
beanType.getGenericComponentType());
+ return injectionPointType.isArray() &&
isAssignableFrom(isDelegateOrEvent, injectionPointType.getComponentType(),
beanType.getGenericComponentType(), visited);
}
- private static boolean isAssignableFrom(boolean isDelegateOrEvent, Type
injectionPointType, WildcardType beanType)
+ private static boolean isAssignableFrom(boolean isDelegateOrEvent, Type
injectionPointType, WildcardType beanType,
+ Map<Type, Integer> visited)
{
+ if (isGenericLoop(beanType, visited))
+ {
+ return false;
+ }
for (Type bounds: beanType.getLowerBounds())
{
- if (!isAssignableFrom(isDelegateOrEvent, false, bounds,
injectionPointType))
+ if (!isAssignableFrom(isDelegateOrEvent, false, bounds,
injectionPointType, visited))
{
return false;
}
}
for (Type bounds: beanType.getUpperBounds())
{
- if (isAssignableFrom(isDelegateOrEvent, false, injectionPointType,
bounds))
+ if (isAssignableFrom(isDelegateOrEvent, false, injectionPointType,
bounds, visited))
{
return true;
}
@@ -248,23 +261,29 @@ public final class GenericsUtil
return false;
}
- private static boolean isAssignableFrom(boolean isDelegateOrEvent, boolean
isProducer, ParameterizedType injectionPointType, Type beanType)
+ private static boolean isGenericLoop(Type beanType, Map<Type, Integer>
visited)
+ {
+ return visited.compute(beanType, (type, integer) -> integer == null ?
1 : (integer + 1)) > MAX_GENERIC_LOOPS;
+ }
+
+ private static boolean isAssignableFrom(boolean isDelegateOrEvent, boolean
isProducer, ParameterizedType injectionPointType, Type beanType,
+ Map<Type, Integer> visited)
{
if (beanType instanceof Class)
{
- return isAssignableFrom(isDelegateOrEvent, isProducer,
injectionPointType, (Class<?>)beanType);
+ return isAssignableFrom(isDelegateOrEvent, isProducer,
injectionPointType, (Class<?>)beanType, visited);
}
else if (beanType instanceof TypeVariable)
{
- return isAssignableFrom(isDelegateOrEvent, isProducer,
injectionPointType, (TypeVariable<?>)beanType);
+ return isAssignableFrom(isDelegateOrEvent, isProducer,
injectionPointType, (TypeVariable<?>)beanType, visited);
}
else if (beanType instanceof ParameterizedType)
{
- return isAssignableFrom(isDelegateOrEvent, injectionPointType,
(ParameterizedType)beanType);
+ return isAssignableFrom(isDelegateOrEvent, injectionPointType,
(ParameterizedType)beanType, visited);
}
else if (beanType instanceof WildcardType)
{
- return isAssignableFrom(isDelegateOrEvent, injectionPointType,
(WildcardType)beanType);
+ return isAssignableFrom(isDelegateOrEvent, injectionPointType,
(WildcardType)beanType, visited);
}
else if (beanType instanceof GenericArrayType)
{
@@ -276,7 +295,8 @@ public final class GenericsUtil
}
}
- private static boolean isAssignableFrom(boolean isDelegateOrEvent, boolean
isProducer, ParameterizedType injectionPointType, Class<?> beanType)
+ private static boolean isAssignableFrom(boolean isDelegateOrEvent, boolean
isProducer, ParameterizedType injectionPointType, Class<?> beanType,
+ Map<Type, Integer> visited)
{
Class<?> rawInjectionPointType = getRawType(injectionPointType);
if (rawInjectionPointType.equals(beanType))
@@ -300,13 +320,13 @@ public final class GenericsUtil
{
return false;
}
- if (beanType.getSuperclass() != null &&
isAssignableFrom(isDelegateOrEvent, isProducer, injectionPointType,
beanType.getGenericSuperclass()))
+ if (beanType.getSuperclass() != null &&
isAssignableFrom(isDelegateOrEvent, isProducer, injectionPointType,
beanType.getGenericSuperclass(), visited))
{
return true;
}
for (Type genericInterface: beanType.getGenericInterfaces())
{
- if (isAssignableFrom(isDelegateOrEvent, isProducer,
injectionPointType, genericInterface))
+ if (isAssignableFrom(isDelegateOrEvent, isProducer,
injectionPointType, genericInterface, visited))
{
return true;
}
@@ -314,7 +334,8 @@ public final class GenericsUtil
return false;
}
- private static boolean isAssignableFrom(boolean isDelegateOrEvent, boolean
isProducer, ParameterizedType injectionPointType, TypeVariable<?> beanType)
+ private static boolean isAssignableFrom(boolean isDelegateOrEvent, boolean
isProducer, ParameterizedType injectionPointType, TypeVariable<?> beanType,
+ Map<Type, Integer> visited)
{
Type[] types = beanType.getBounds();
if (isNotBound(types))
@@ -323,7 +344,7 @@ public final class GenericsUtil
}
for (Type bounds: types)
{
- if (isAssignableFrom(isDelegateOrEvent, isProducer,
injectionPointType, bounds))
+ if (isAssignableFrom(isDelegateOrEvent, isProducer,
injectionPointType, bounds, visited))
{
return true;
}
@@ -334,7 +355,8 @@ public final class GenericsUtil
/**
* CDI Spec. 5.2.4
*/
- private static boolean isAssignableFrom(boolean isDelegateOrEvent,
ParameterizedType injectionPointType, ParameterizedType beanType)
+ private static boolean isAssignableFrom(boolean isDelegateOrEvent,
ParameterizedType injectionPointType, ParameterizedType beanType,
+ Map<Type, Integer> visited)
{
if (injectionPointType.getRawType() != beanType.getRawType())
{
@@ -360,7 +382,7 @@ public final class GenericsUtil
{
for (Type upperBound : bounds)
{
- if (!isAssignableFrom(true, false, upperBound,
injectionPointTypeArgument))
+ if (!isAssignableFrom(true, false, upperBound,
injectionPointTypeArgument, visited))
{
return false;
}
@@ -377,7 +399,7 @@ public final class GenericsUtil
return injectionPointTypeArgument.equals(beanTypeArgument);
}
- else if (!isAssignableFrom(isDelegateOrEvent, false,
injectionPointTypeArgument, beanTypeArgument))
+ else if (!isAssignableFrom(isDelegateOrEvent, false,
injectionPointTypeArgument, beanTypeArgument, visited))
{
return false;
}
@@ -390,11 +412,16 @@ public final class GenericsUtil
return bounds == null || bounds.length == 0 || (bounds.length == 1 &&
Object.class == bounds[0]);
}
- private static boolean isAssignableFrom(boolean isDelegateOrEvent,
TypeVariable<?> injectionPointType, Type beanType)
+ private static boolean isAssignableFrom(boolean isDelegateOrEvent,
TypeVariable<?> injectionPointType, Type beanType,
+ Map<Type, Integer> visited)
{
+ if (isGenericLoop(beanType, visited))
+ {
+ return false; // looping type so not resolvable
+ }
for (Type bounds: injectionPointType.getBounds())
{
- if (!isAssignableFrom(isDelegateOrEvent, false, bounds, beanType))
+ if (!isAssignableFrom(isDelegateOrEvent, false, bounds, beanType,
visited))
{
return false;
}
@@ -403,7 +430,8 @@ public final class GenericsUtil
}
// rules are a bit different when in an array so we handle
ParameterizedType manually (not reusing isAssignableFrom)
- private static boolean isAssignableFrom(boolean isDelegateOrEvent,
GenericArrayType injectionPointType, Type beanType)
+ private static boolean isAssignableFrom(boolean isDelegateOrEvent,
GenericArrayType injectionPointType, Type beanType,
+ Map<Type, Integer> visited)
{
Type genericComponentType =
injectionPointType.getGenericComponentType();
Class componentType = Class.class.cast(beanType).getComponentType();
@@ -413,20 +441,21 @@ public final class GenericsUtil
}
if (ParameterizedType.class.isInstance(genericComponentType))
{
- return isAssignableFrom(isDelegateOrEvent, false,
ParameterizedType.class.cast(genericComponentType).getRawType(), componentType);
+ return isAssignableFrom(isDelegateOrEvent, false,
ParameterizedType.class.cast(genericComponentType).getRawType(), componentType,
visited);
}
- return isAssignableFrom(isDelegateOrEvent, false,
genericComponentType, componentType);
+ return isAssignableFrom(isDelegateOrEvent, false,
genericComponentType, componentType, visited);
}
- private static boolean isAssignableFrom(boolean isDelegateOrEvent,
WildcardType injectionPointType, Type beanType)
+ private static boolean isAssignableFrom(boolean isDelegateOrEvent,
WildcardType injectionPointType, Type beanType,
+ Map<Type, Integer> visited)
{
if (beanType instanceof TypeVariable)
{
- return isAssignableFrom(isDelegateOrEvent, injectionPointType,
(TypeVariable<?>)beanType);
+ return isAssignableFrom(isDelegateOrEvent, injectionPointType,
(TypeVariable<?>)beanType, visited);
}
for (Type bounds: injectionPointType.getLowerBounds())
{
- if (!isAssignableFrom(isDelegateOrEvent, false, beanType, bounds))
+ if (!isAssignableFrom(isDelegateOrEvent, false, beanType, bounds,
visited))
{
return false;
}
@@ -437,7 +466,7 @@ public final class GenericsUtil
boolean isAssignable = false;
for (Type beanSupertype: beanTypeClosure)
{
- if (isAssignableFrom(isDelegateOrEvent, false, bounds,
beanSupertype)
+ if (isAssignableFrom(isDelegateOrEvent, false, bounds,
beanSupertype, visited)
|| (Class.class.isInstance(bounds)
&& ParameterizedType.class.isInstance(beanSupertype)
&& bounds ==
ParameterizedType.class.cast(beanSupertype).getRawType()))
@@ -457,13 +486,14 @@ public final class GenericsUtil
/**
* CDI 1.1 Spec. 5.2.4, third bullet point
*/
- private static boolean isAssignableFrom(boolean isDelegateOrEvent,
WildcardType injectionPointType, TypeVariable<?> beanType)
+ private static boolean isAssignableFrom(boolean isDelegateOrEvent,
WildcardType injectionPointType, TypeVariable<?> beanType,
+ Map<Type, Integer> visited)
{
for (Type upperBound: injectionPointType.getUpperBounds())
{
for (Type bound: beanType.getBounds())
{
- if (!isAssignableFrom(isDelegateOrEvent, false, upperBound,
bound) && !isAssignableFrom(isDelegateOrEvent, false, bound, upperBound))
+ if (!isAssignableFrom(isDelegateOrEvent, false, upperBound,
bound, visited) && !isAssignableFrom(isDelegateOrEvent, false, bound,
upperBound, visited))
{
return false;
}
@@ -473,7 +503,7 @@ public final class GenericsUtil
{
for (Type bound: beanType.getBounds())
{
- if (!isAssignableFrom(isDelegateOrEvent, false, bound,
lowerBound))
+ if (!isAssignableFrom(isDelegateOrEvent, false, bound,
lowerBound, visited))
{
return false;
}
Modified:
openwebbeans/trunk/webbeans-impl/src/main/java/org/apache/webbeans/util/WebBeansUtil.java
URL:
http://svn.apache.org/viewvc/openwebbeans/trunk/webbeans-impl/src/main/java/org/apache/webbeans/util/WebBeansUtil.java?rev=1861905&r1=1861904&r2=1861905&view=diff
==============================================================================
---
openwebbeans/trunk/webbeans-impl/src/main/java/org/apache/webbeans/util/WebBeansUtil.java
(original)
+++
openwebbeans/trunk/webbeans-impl/src/main/java/org/apache/webbeans/util/WebBeansUtil.java
Sun Jun 23 09:10:31 2019
@@ -151,6 +151,7 @@ import java.lang.reflect.WildcardType;
import java.util.Arrays;
import java.util.Collections;
import java.util.EnumSet;
+import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
@@ -1471,7 +1472,8 @@ public final class WebBeansUtil
rawType.equals(Interceptor.class))
{
Type[] types =
ClassUtil.getActualTypeArguments(injectionPoint.getType());
- if (types.length != 1 ||
!GenericsUtil.isAssignableFrom(false,
AbstractProducerBean.class.isInstance(bean), bean.getBeanClass(), types[0]))
+ if (types.length != 1 || !GenericsUtil.isAssignableFrom(
+ false,
AbstractProducerBean.class.isInstance(bean), bean.getBeanClass(), types[0], new
HashMap<>()))
{
throw new WebBeansConfigurationException("injected
bean parameter must be " + rawType);
}
@@ -1720,7 +1722,8 @@ public final class WebBeansUtil
Class<?> beanClass =
AbstractOwbBean.class.isInstance(injectionPointBean) ?
AbstractOwbBean.class.cast(injectionPointBean).getReturnType() :
injectionPointBean.getBeanClass();
Type beanType = pt.getActualTypeArguments()[0];
- if (!GenericsUtil.isAssignableFrom(false,
AbstractProducerBean.class.isInstance(bean), beanClass, beanType))
+ if (!GenericsUtil.isAssignableFrom(
+ false,
AbstractProducerBean.class.isInstance(bean), beanClass, beanType, new
HashMap<>()))
{
throw new WebBeansConfigurationException("@Inject
Bean<X> can only be done in X, found " + beanType + " and " + beanClass);
}
Modified:
openwebbeans/trunk/webbeans-impl/src/test/java/org/apache/webbeans/test/unittests/inject/parametrized/GenericClassTest.java
URL:
http://svn.apache.org/viewvc/openwebbeans/trunk/webbeans-impl/src/test/java/org/apache/webbeans/test/unittests/inject/parametrized/GenericClassTest.java?rev=1861905&r1=1861904&r2=1861905&view=diff
==============================================================================
---
openwebbeans/trunk/webbeans-impl/src/test/java/org/apache/webbeans/test/unittests/inject/parametrized/GenericClassTest.java
(original)
+++
openwebbeans/trunk/webbeans-impl/src/test/java/org/apache/webbeans/test/unittests/inject/parametrized/GenericClassTest.java
Sun Jun 23 09:10:31 2019
@@ -20,6 +20,7 @@ package org.apache.webbeans.test.unittes
import java.lang.reflect.Field;
import java.lang.reflect.Type;
+import java.util.HashMap;
import org.apache.webbeans.test.injection.generics.zoo.Horse;
import org.apache.webbeans.test.injection.generics.zoo.HorseStable;
@@ -44,10 +45,10 @@ public class GenericClassTest
Field check22Bound = Dao.class.getField("check22WithBound");
Field check4 = WithTypeVariable.class.getField("check4");
- Assert.assertFalse(GenericsUtil.satisfiesDependency(false, false,
raw.getGenericType(), t.getGenericType()));
- Assert.assertTrue(GenericsUtil.satisfiesDependency(false, false,
check4.getGenericType(), t.getGenericType()));
- Assert.assertTrue(GenericsUtil.satisfiesDependency(false, false,
check22.getGenericType(), t.getGenericType()));
- Assert.assertTrue(GenericsUtil.satisfiesDependency(false, false,
check22Bound.getGenericType(), t.getGenericType()));
+ Assert.assertFalse(GenericsUtil.satisfiesDependency(false, false,
raw.getGenericType(), t.getGenericType(), new HashMap<>()));
+ Assert.assertTrue(GenericsUtil.satisfiesDependency(false, false,
check4.getGenericType(), t.getGenericType(), new HashMap<>()));
+ Assert.assertTrue(GenericsUtil.satisfiesDependency(false, false,
check22.getGenericType(), t.getGenericType(), new HashMap<>()));
+ Assert.assertTrue(GenericsUtil.satisfiesDependency(false, false,
check22Bound.getGenericType(), t.getGenericType(), new HashMap<>()));
}
@Test
@@ -59,8 +60,8 @@ public class GenericClassTest
Field f4 = UserDao.class.getField("field4");
- Assert.assertTrue(GenericsUtil.satisfiesDependency(false, false,
f3.getGenericType(), f1.getGenericType()));
- Assert.assertTrue(GenericsUtil.satisfiesDependency(false, false,
f4.getGenericType(), f1.getGenericType()));
+ Assert.assertTrue(GenericsUtil.satisfiesDependency(false, false,
f3.getGenericType(), f1.getGenericType(), new HashMap<>()));
+ Assert.assertTrue(GenericsUtil.satisfiesDependency(false, false,
f4.getGenericType(), f1.getGenericType(), new HashMap<>()));
}
@Test
@@ -74,8 +75,8 @@ public class GenericClassTest
Type pigStableType =
this.getClass().getDeclaredField("pigStable").getType().getGenericSuperclass();
Type horseStableType =
this.getClass().getDeclaredField("horseStable").getType().getGenericSuperclass();
- Assert.assertTrue(GenericsUtil.satisfiesDependency(false, false,
horseStableType, parameterizedHorseStableType));
- Assert.assertTrue(GenericsUtil.satisfiesDependency(false, false,
parameterizedPigStableType, pigStableType));
+ Assert.assertTrue(GenericsUtil.satisfiesDependency(false, false,
horseStableType, parameterizedHorseStableType, new HashMap<>()));
+ Assert.assertTrue(GenericsUtil.satisfiesDependency(false, false,
parameterizedPigStableType, pigStableType, new HashMap<>()));
}
// fields for {@link #testStable}
private Stable<Horse> parameterizedHorseStable;
@@ -91,8 +92,8 @@ public class GenericClassTest
Type parameterizedHorseStableType =
this.getClass().getDeclaredField("parameterizedHorseStable").getGenericType();
Type stableProducerMethodType =
this.getClass().getDeclaredMethod("stableProducer").getGenericReturnType();
- Assert.assertTrue(GenericsUtil.satisfiesDependency(false, false,
parameterizedPigStableType, stableProducerMethodType));
- Assert.assertTrue(GenericsUtil.satisfiesDependency(false, false,
parameterizedHorseStableType, stableProducerMethodType));
+ Assert.assertTrue(GenericsUtil.satisfiesDependency(false, false,
parameterizedPigStableType, stableProducerMethodType, new HashMap<>()));
+ Assert.assertTrue(GenericsUtil.satisfiesDependency(false, false,
parameterizedHorseStableType, stableProducerMethodType, new HashMap<>()));
}
// method and field for {@link #testGenericProducerType}
private <T> Stable<T> stableProducer()
Modified:
openwebbeans/trunk/webbeans-impl/src/test/java/org/apache/webbeans/test/util/GenericsUtilTest.java
URL:
http://svn.apache.org/viewvc/openwebbeans/trunk/webbeans-impl/src/test/java/org/apache/webbeans/test/util/GenericsUtilTest.java?rev=1861905&r1=1861904&r2=1861905&view=diff
==============================================================================
---
openwebbeans/trunk/webbeans-impl/src/test/java/org/apache/webbeans/test/util/GenericsUtilTest.java
(original)
+++
openwebbeans/trunk/webbeans-impl/src/test/java/org/apache/webbeans/test/util/GenericsUtilTest.java
Sun Jun 23 09:10:31 2019
@@ -20,8 +20,11 @@ package org.apache.webbeans.test.util;
import static java.util.Arrays.asList;
import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
+import java.lang.annotation.Annotation;
+import java.lang.reflect.AnnotatedType;
import java.lang.reflect.Field;
import java.lang.reflect.GenericArrayType;
import java.lang.reflect.Method;
@@ -30,6 +33,8 @@ import java.lang.reflect.Type;
import java.lang.reflect.TypeVariable;
import java.util.ArrayList;
import java.util.Collection;
+import java.util.HashMap;
+import java.util.HashSet;
import java.util.Set;
import org.apache.webbeans.config.OwbParametrizedTypeImpl;
@@ -87,6 +92,100 @@ public class GenericsUtilTest {
Assert.assertFalse(GenericsUtil.containsWildcardType(GenericObject.class.getMethod("getObject").getGenericReturnType()));
}
+ @Test
+ public void genericsLoop()
+ {
+ final ParameterizedType injectionPointType = new
OwbParametrizedTypeImpl(null, GenericFoo.class, Long.class);
+ final TypeVariable<Class<?>> t = new TypeVariable<Class<?>>() {
+ @Override
+ public Type[] getBounds() {
+ final TypeVariable<?> ref = this;
+ return new Type[]{
+ new OwbParametrizedTypeImpl(null, Comparable.class, new
TypeVariable<Class<?>>() {
+ @Override
+ public <T extends Annotation> T getAnnotation(Class<T>
annotationClass)
+ {
+ return null;
+ }
+
+ @Override
+ public Annotation[] getAnnotations()
+ {
+ return new Annotation[0];
+ }
+
+ @Override
+ public Annotation[] getDeclaredAnnotations()
+ {
+ return new Annotation[0];
+ }
+
+ @Override
+ public Type[] getBounds()
+ {
+ return new Type[] { new
OwbParametrizedTypeImpl(null, Comparable.class, ref) };
+ }
+
+ @Override
+ public Class<?> getGenericDeclaration() {
+ return GenericFoo.class;
+ }
+
+ @Override
+ public String getName()
+ {
+ return "T";
+ }
+
+ @Override
+ public AnnotatedType[] getAnnotatedBounds()
+ {
+ return new AnnotatedType[0];
+ }
+ })
+ };
+ }
+
+ @Override
+ public Class<?> getGenericDeclaration()
+ {
+ return GenericFoo.class;
+ }
+
+ @Override
+ public String getName()
+ {
+ return "T";
+ }
+
+ @Override
+ public AnnotatedType[] getAnnotatedBounds()
+ {
+ return new AnnotatedType[0];
+ }
+
+ @Override
+ public <T extends Annotation> T getAnnotation(Class<T>
annotationClass)
+ {
+ return null;
+ }
+
+ @Override
+ public Annotation[] getAnnotations()
+ {
+ return new Annotation[0];
+ }
+
+ @Override
+ public Annotation[] getDeclaredAnnotations()
+ {
+ return new Annotation[0];
+ }
+ };
+ final ParameterizedType beanType = new OwbParametrizedTypeImpl(null,
GenericFoo.class, t);
+ assertFalse(GenericsUtil.satisfiesDependency(false, false,
injectionPointType, beanType, new HashMap<>()));
+ }
+
public static abstract class AbstractObject<V>
{
@@ -180,4 +279,23 @@ public class GenericsUtilTest {
return this;
}
}
+
+ public interface GenericFoo<T extends Comparable<T>>
+ {
+ T someMethod();
+ }
+
+ public static class FooImpl<T extends Comparable<T>> implements
GenericFoo<T>
+ {
+ @Override
+ public T someMethod()
+ {
+ return null;
+ }
+ }
+
+ public static class Bar
+ {
+ GenericFoo<Long> foo;
+ }
}