You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@openwebbeans.apache.org by ge...@apache.org on 2010/09/29 08:22:03 UTC

svn commit: r1002487 - in /openwebbeans/trunk/webbeans-impl/src: main/java/org/apache/webbeans/config/ main/java/org/apache/webbeans/container/ main/java/org/apache/webbeans/decorator/ main/java/org/apache/webbeans/event/ main/java/org/apache/webbeans/...

Author: gerdogdu
Date: Wed Sep 29 06:22:02 2010
New Revision: 1002487

URL: http://svn.apache.org/viewvc?rev=1002487&view=rev
Log:
[OWB-462] Refactor AnnotationUtil.hasAnnotationMember. Some updates to patch. Thanks to Jakob Korherr for this patch

Added:
    openwebbeans/trunk/webbeans-impl/src/test/java/org/apache/webbeans/newtests/util/
    openwebbeans/trunk/webbeans-impl/src/test/java/org/apache/webbeans/newtests/util/AnnotationUtilTest.java   (with props)
Modified:
    openwebbeans/trunk/webbeans-impl/src/main/java/org/apache/webbeans/config/DefaultAnnotation.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/WebBeansDecorator.java
    openwebbeans/trunk/webbeans-impl/src/main/java/org/apache/webbeans/event/NotificationManager.java
    openwebbeans/trunk/webbeans-impl/src/main/java/org/apache/webbeans/intercept/WebBeansInterceptorConfig.java
    openwebbeans/trunk/webbeans-impl/src/main/java/org/apache/webbeans/intercept/webbeans/WebBeansInterceptor.java
    openwebbeans/trunk/webbeans-impl/src/main/java/org/apache/webbeans/util/AnnotationUtil.java
    openwebbeans/trunk/webbeans-impl/src/main/java/org/apache/webbeans/util/WebBeansAnnotatedTypeUtil.java

Modified: openwebbeans/trunk/webbeans-impl/src/main/java/org/apache/webbeans/config/DefaultAnnotation.java
URL: http://svn.apache.org/viewvc/openwebbeans/trunk/webbeans-impl/src/main/java/org/apache/webbeans/config/DefaultAnnotation.java?rev=1002487&r1=1002486&r2=1002487&view=diff
==============================================================================
--- openwebbeans/trunk/webbeans-impl/src/main/java/org/apache/webbeans/config/DefaultAnnotation.java (original)
+++ openwebbeans/trunk/webbeans-impl/src/main/java/org/apache/webbeans/config/DefaultAnnotation.java Wed Sep 29 06:22:02 2010
@@ -29,15 +29,91 @@ import java.lang.reflect.Proxy;
  * The annotation literal gets filled with the default values.
  * TODO implement class caching!
  */
-public class DefaultAnnotation implements InvocationHandler
+public class DefaultAnnotation implements InvocationHandler, Annotation
 {
+    
+    private static final Object[] EMPTY_OBJECT_ARRAY = new Object[0];
+
     public static Annotation of(Class<? extends Annotation> annotation) 
     {
-        return (Annotation) Proxy.newProxyInstance(annotation.getClassLoader(), new Class[] {annotation}, new DefaultAnnotation());
+        return (Annotation) Proxy.newProxyInstance(annotation.getClassLoader(),
+                new Class[] {annotation}, new DefaultAnnotation(annotation));
+    }
+
+    private final Class<? extends Annotation> annotationClass;
+
+    private DefaultAnnotation(Class<? extends Annotation> annotationClass)
+    {
+        this.annotationClass = annotationClass;
     }
     
-    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable 
+    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable
     {
+        if ("hashCode".equals(method.getName()))
+        {
+            return hashCode();
+        }
+        else if ("equals".equals(method.getName()))
+        {
+            return equals(args[0]);
+        }
+        else if ("annotationType".equals(method.getName()))
+        {
+            return annotationType();
+        }
+        else if ("toString".equals(method.getName()))
+        {
+            return toString();
+        }
+
         return method.getDefaultValue();
     }
+
+    public Class<? extends Annotation> annotationType()
+    {
+        return annotationClass;
+    }
+
+    /**
+     * Copied from javax.enterprise.util.AnnotationLiteral#toString()
+     * with minor changes.
+     *
+     * @return
+     */
+    @Override
+    public String toString()
+    {
+        Method[] methods = this.annotationClass.getDeclaredMethods();
+
+        StringBuilder sb = new StringBuilder("@" + annotationType().getName() + "(");
+        int lenght = methods.length;
+
+        for (int i = 0; i < lenght; i++)
+        {
+            // Member name
+            sb.append(methods[i].getName()).append("=");
+
+            // Member value
+            Object memberValue;
+            try
+            {
+                memberValue = invoke(this, methods[i], EMPTY_OBJECT_ARRAY);
+            }
+            catch (Throwable throwable)
+            {
+                memberValue = "";
+            }
+            sb.append(memberValue);
+
+            if (i < lenght - 1)
+            {
+                sb.append(",");
+            }
+        }
+
+        sb.append(")");
+
+        return sb.toString();
+    }
+    
 }

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=1002487&r1=1002486&r2=1002487&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 Wed Sep 29 06:22:02 2010
@@ -18,22 +18,6 @@
  */
 package org.apache.webbeans.container;
 
-import java.lang.annotation.Annotation;
-import java.lang.reflect.ParameterizedType;
-import java.lang.reflect.Type;
-import java.util.Collections;
-import java.util.HashSet;
-import java.util.Iterator;
-import java.util.Map;
-import java.util.Set;
-import java.util.concurrent.ConcurrentHashMap;
-
-import javax.enterprise.event.Event;
-import javax.enterprise.inject.Instance;
-import javax.enterprise.inject.New;
-import javax.enterprise.inject.spi.Bean;
-import javax.enterprise.inject.spi.InjectionPoint;
-
 import org.apache.webbeans.annotation.AnyLiteral;
 import org.apache.webbeans.annotation.DefaultLiteral;
 import org.apache.webbeans.component.AbstractOwbBean;
@@ -45,6 +29,21 @@ import org.apache.webbeans.util.Asserts;
 import org.apache.webbeans.util.ClassUtil;
 import org.apache.webbeans.util.WebBeansUtil;
 
+import javax.enterprise.event.Event;
+import javax.enterprise.inject.Instance;
+import javax.enterprise.inject.New;
+import javax.enterprise.inject.spi.Bean;
+import javax.enterprise.inject.spi.InjectionPoint;
+import java.lang.annotation.Annotation;
+import java.lang.reflect.ParameterizedType;
+import java.lang.reflect.Type;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.Set;
+import java.util.concurrent.ConcurrentHashMap;
+
 /**
  * Injection point resolver class. 
  * 
@@ -583,7 +582,7 @@ public class InjectionResolver
                     Annotation qualifier = itQualifiers.next();
                     if (annot.annotationType().equals(qualifier.annotationType()))
                     {
-                        if (AnnotationUtil.hasAnnotationMember(qualifier.annotationType(), qualifier, annot))
+                        if (AnnotationUtil.isQualifierEqual(qualifier, annot))
                         {
                             i++;
                         }

Modified: openwebbeans/trunk/webbeans-impl/src/main/java/org/apache/webbeans/decorator/WebBeansDecorator.java
URL: http://svn.apache.org/viewvc/openwebbeans/trunk/webbeans-impl/src/main/java/org/apache/webbeans/decorator/WebBeansDecorator.java?rev=1002487&r1=1002486&r2=1002487&view=diff
==============================================================================
--- openwebbeans/trunk/webbeans-impl/src/main/java/org/apache/webbeans/decorator/WebBeansDecorator.java (original)
+++ openwebbeans/trunk/webbeans-impl/src/main/java/org/apache/webbeans/decorator/WebBeansDecorator.java Wed Sep 29 06:22:02 2010
@@ -18,27 +18,8 @@
  */
 package org.apache.webbeans.decorator;
 
-import java.io.Serializable;
-import java.lang.annotation.Annotation;
-import java.lang.reflect.AnnotatedElement;
-import java.lang.reflect.Constructor;
-import java.lang.reflect.Field;
-import java.lang.reflect.Member;
-import java.lang.reflect.Method;
-import java.lang.reflect.Type;
-import java.util.HashSet;
-import java.util.Set;
-
-import javax.decorator.Delegate;
-import javax.enterprise.context.spi.Context;
-import javax.enterprise.context.spi.CreationalContext;
-import javax.enterprise.inject.spi.Bean;
-import javax.enterprise.inject.spi.Decorator;
-import javax.enterprise.inject.spi.InjectionPoint;
-import javax.inject.Inject;
-
-import org.apache.webbeans.component.AbstractOwbBean;
 import org.apache.webbeans.component.AbstractInjectionTargetBean;
+import org.apache.webbeans.component.AbstractOwbBean;
 import org.apache.webbeans.component.ManagedBean;
 import org.apache.webbeans.component.WebBeansType;
 import org.apache.webbeans.config.OWBLogConst;
@@ -52,6 +33,24 @@ import org.apache.webbeans.util.Annotati
 import org.apache.webbeans.util.ClassUtil;
 import org.apache.webbeans.util.SecurityUtil;
 
+import javax.decorator.Delegate;
+import javax.enterprise.context.spi.Context;
+import javax.enterprise.context.spi.CreationalContext;
+import javax.enterprise.inject.spi.Bean;
+import javax.enterprise.inject.spi.Decorator;
+import javax.enterprise.inject.spi.InjectionPoint;
+import javax.inject.Inject;
+import java.io.Serializable;
+import java.lang.annotation.Annotation;
+import java.lang.reflect.AnnotatedElement;
+import java.lang.reflect.Constructor;
+import java.lang.reflect.Field;
+import java.lang.reflect.Member;
+import java.lang.reflect.Method;
+import java.lang.reflect.Type;
+import java.util.HashSet;
+import java.util.Set;
+
 /**
  * Defines decorators. It wraps the bean instance related
  * with decorator class. Actually, each decorator is an instance
@@ -232,7 +231,7 @@ public class WebBeansDecorator<T> extend
 
         for (Annotation annot : annotations)
         {
-            if (AnnotationUtil.hasAnnotationMember(bindingType.annotationType(), annot, bindingType))
+            if (AnnotationUtil.isQualifierEqual(annot, bindingType))
             {
                 return true;
             }

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=1002487&r1=1002486&r2=1002487&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 Wed Sep 29 06:22:02 2010
@@ -19,27 +19,6 @@
 
 package org.apache.webbeans.event;
 
-import java.lang.annotation.Annotation;
-import java.lang.reflect.InvocationTargetException;
-import java.lang.reflect.Method;
-import java.lang.reflect.ParameterizedType;
-import java.lang.reflect.Type;
-import java.lang.reflect.TypeVariable;
-import java.util.Arrays;
-import java.util.HashSet;
-import java.util.Map;
-import java.util.Set;
-import java.util.concurrent.ConcurrentHashMap;
-
-import javax.enterprise.event.ObserverException;
-import javax.enterprise.event.Observes;
-import javax.enterprise.event.Reception;
-import javax.enterprise.event.TransactionPhase;
-import javax.enterprise.inject.spi.AnnotatedMethod;
-import javax.enterprise.inject.spi.ObserverMethod;
-import javax.enterprise.inject.spi.ProcessObserverMethod;
-import javax.enterprise.util.TypeLiteral;
-
 import org.apache.webbeans.annotation.AnyLiteral;
 import org.apache.webbeans.component.InjectionTargetBean;
 import org.apache.webbeans.config.OWBLogConst;
@@ -56,6 +35,26 @@ import org.apache.webbeans.util.Asserts;
 import org.apache.webbeans.util.ClassUtil;
 import org.apache.webbeans.util.WebBeansUtil;
 
+import javax.enterprise.event.ObserverException;
+import javax.enterprise.event.Observes;
+import javax.enterprise.event.Reception;
+import javax.enterprise.event.TransactionPhase;
+import javax.enterprise.inject.spi.AnnotatedMethod;
+import javax.enterprise.inject.spi.ObserverMethod;
+import javax.enterprise.inject.spi.ProcessObserverMethod;
+import javax.enterprise.util.TypeLiteral;
+import java.lang.annotation.Annotation;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.lang.reflect.ParameterizedType;
+import java.lang.reflect.Type;
+import java.lang.reflect.TypeVariable;
+import java.util.Arrays;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+import java.util.concurrent.ConcurrentHashMap;
+
 @SuppressWarnings("unchecked")
 public final class NotificationManager
 {
@@ -395,7 +394,7 @@ public final class NotificationManager
                 boolean found = false;
                 for(Annotation inList : eventQualifiers)
                 {
-                    if(AnnotationUtil.hasAnnotationMember(qualifier.annotationType(), inList, qualifier))
+                    if(AnnotationUtil.isQualifierEqual(inList, qualifier))
                     {
                         found = true;
                         break;

Modified: openwebbeans/trunk/webbeans-impl/src/main/java/org/apache/webbeans/intercept/WebBeansInterceptorConfig.java
URL: http://svn.apache.org/viewvc/openwebbeans/trunk/webbeans-impl/src/main/java/org/apache/webbeans/intercept/WebBeansInterceptorConfig.java?rev=1002487&r1=1002486&r2=1002487&view=diff
==============================================================================
--- openwebbeans/trunk/webbeans-impl/src/main/java/org/apache/webbeans/intercept/WebBeansInterceptorConfig.java (original)
+++ openwebbeans/trunk/webbeans-impl/src/main/java/org/apache/webbeans/intercept/WebBeansInterceptorConfig.java Wed Sep 29 06:22:02 2010
@@ -18,27 +18,8 @@
  */
 package org.apache.webbeans.intercept;
 
-import java.lang.annotation.Annotation;
-import java.lang.reflect.Method;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collections;
-import java.util.HashSet;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Set;
-
-import javax.annotation.PostConstruct;
-import javax.annotation.PreDestroy;
-import javax.enterprise.context.Dependent;
-import javax.enterprise.inject.spi.AnnotatedMethod;
-import javax.enterprise.inject.spi.AnnotatedType;
-import javax.enterprise.inject.spi.Bean;
-import javax.enterprise.inject.spi.Interceptor;
-import javax.interceptor.AroundInvoke;
-
-import org.apache.webbeans.component.AbstractOwbBean;
 import org.apache.webbeans.component.AbstractInjectionTargetBean;
+import org.apache.webbeans.component.AbstractOwbBean;
 import org.apache.webbeans.config.OWBLogConst;
 import org.apache.webbeans.config.inheritance.IBeanInheritedMetaData;
 import org.apache.webbeans.container.BeanManagerImpl;
@@ -49,6 +30,24 @@ import org.apache.webbeans.util.Annotati
 import org.apache.webbeans.util.SecurityUtil;
 import org.apache.webbeans.util.WebBeansUtil;
 
+import javax.annotation.PostConstruct;
+import javax.annotation.PreDestroy;
+import javax.enterprise.context.Dependent;
+import javax.enterprise.inject.spi.AnnotatedMethod;
+import javax.enterprise.inject.spi.AnnotatedType;
+import javax.enterprise.inject.spi.Bean;
+import javax.enterprise.inject.spi.Interceptor;
+import javax.interceptor.AroundInvoke;
+import java.lang.annotation.Annotation;
+import java.lang.reflect.Method;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Set;
+
 /**
  * Configures the Web Beans related interceptors.
  * 
@@ -122,7 +121,7 @@ public final class WebBeansInterceptorCo
         {
             if(old.annotationType().equals(ann.annotationType()))
             {
-                if(!AnnotationUtil.hasAnnotationMember(ann.annotationType(), ann, old))
+                if(!AnnotationUtil.isQualifierEqual(ann, old))
                 {
                     throw new WebBeansConfigurationException("Interceptor Binding types must be equal for interceptor : " + bean);
                 }                

Modified: openwebbeans/trunk/webbeans-impl/src/main/java/org/apache/webbeans/intercept/webbeans/WebBeansInterceptor.java
URL: http://svn.apache.org/viewvc/openwebbeans/trunk/webbeans-impl/src/main/java/org/apache/webbeans/intercept/webbeans/WebBeansInterceptor.java?rev=1002487&r1=1002486&r2=1002487&view=diff
==============================================================================
--- openwebbeans/trunk/webbeans-impl/src/main/java/org/apache/webbeans/intercept/webbeans/WebBeansInterceptor.java (original)
+++ openwebbeans/trunk/webbeans-impl/src/main/java/org/apache/webbeans/intercept/webbeans/WebBeansInterceptor.java Wed Sep 29 06:22:02 2010
@@ -18,31 +18,8 @@
  */
 package org.apache.webbeans.intercept.webbeans;
 
-import java.lang.annotation.Annotation;
-import java.lang.reflect.Field;
-import java.lang.reflect.Method;
-import java.lang.reflect.Type;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-
-import javax.enterprise.context.spi.Context;
-import javax.enterprise.context.spi.CreationalContext;
-import javax.enterprise.inject.spi.AnnotatedType;
-import javax.enterprise.inject.spi.Bean;
-import javax.enterprise.inject.spi.InjectionPoint;
-import javax.enterprise.inject.spi.InterceptionType;
-import javax.enterprise.inject.spi.Interceptor;
-import javax.enterprise.util.Nonbinding;
-import javax.interceptor.AroundInvoke;
-import javax.interceptor.AroundTimeout;
-import javax.interceptor.InvocationContext;
-
-import org.apache.webbeans.component.AbstractOwbBean;
 import org.apache.webbeans.component.AbstractInjectionTargetBean;
+import org.apache.webbeans.component.AbstractOwbBean;
 import org.apache.webbeans.component.ManagedBean;
 import org.apache.webbeans.component.WebBeansType;
 import org.apache.webbeans.container.BeanManagerImpl;
@@ -59,6 +36,28 @@ import org.apache.webbeans.util.Security
 import org.apache.webbeans.util.WebBeansUtil;
 import org.apache.webbeans.xml.XMLAnnotationTypeManager;
 
+import javax.enterprise.context.spi.Context;
+import javax.enterprise.context.spi.CreationalContext;
+import javax.enterprise.inject.spi.AnnotatedType;
+import javax.enterprise.inject.spi.Bean;
+import javax.enterprise.inject.spi.InjectionPoint;
+import javax.enterprise.inject.spi.InterceptionType;
+import javax.enterprise.inject.spi.Interceptor;
+import javax.enterprise.util.Nonbinding;
+import javax.interceptor.AroundInvoke;
+import javax.interceptor.AroundTimeout;
+import javax.interceptor.InvocationContext;
+import java.lang.annotation.Annotation;
+import java.lang.reflect.Field;
+import java.lang.reflect.Method;
+import java.lang.reflect.Type;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
 /**
  * Defines the webbeans specific interceptors.
  * <p>
@@ -162,7 +161,7 @@ public class WebBeansInterceptor<T> exte
                 return false; /* at least one of this interceptors types is not in the beans bindingTypes */
             }
 
-            if (!AnnotationUtil.hasAnnotationMember(bindingTypes.get(index), annots.get(index), ann))
+            if (!AnnotationUtil.isQualifierEqual(ann, annots.get(index)))
 
             {
                 return false;

Modified: openwebbeans/trunk/webbeans-impl/src/main/java/org/apache/webbeans/util/AnnotationUtil.java
URL: http://svn.apache.org/viewvc/openwebbeans/trunk/webbeans-impl/src/main/java/org/apache/webbeans/util/AnnotationUtil.java?rev=1002487&r1=1002486&r2=1002487&view=diff
==============================================================================
--- openwebbeans/trunk/webbeans-impl/src/main/java/org/apache/webbeans/util/AnnotationUtil.java (original)
+++ openwebbeans/trunk/webbeans-impl/src/main/java/org/apache/webbeans/util/AnnotationUtil.java Wed Sep 29 06:22:02 2010
@@ -18,6 +18,20 @@
  */
 package org.apache.webbeans.util;
 
+import org.apache.webbeans.annotation.DefaultLiteral;
+import org.apache.webbeans.container.BeanManagerImpl;
+import org.apache.webbeans.exception.WebBeansConfigurationException;
+import org.apache.webbeans.exception.WebBeansException;
+import org.apache.webbeans.xml.XMLAnnotationTypeManager;
+
+import javax.enterprise.inject.Any;
+import javax.enterprise.inject.Stereotype;
+import javax.enterprise.inject.spi.AnnotatedMethod;
+import javax.enterprise.inject.spi.AnnotatedParameter;
+import javax.enterprise.inject.spi.Bean;
+import javax.enterprise.util.Nonbinding;
+import javax.inject.Qualifier;
+import javax.interceptor.InterceptorBinding;
 import java.lang.annotation.Annotation;
 import java.lang.reflect.Constructor;
 import java.lang.reflect.Field;
@@ -25,24 +39,11 @@ import java.lang.reflect.Method;
 import java.lang.reflect.ParameterizedType;
 import java.lang.reflect.Type;
 import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
 import java.util.HashSet;
 import java.util.List;
 import java.util.Set;
-import java.util.StringTokenizer;
-
-import javax.enterprise.inject.Any;
-import javax.enterprise.inject.Stereotype;
-import javax.enterprise.inject.spi.AnnotatedMethod;
-import javax.enterprise.inject.spi.AnnotatedParameter;
-import javax.enterprise.inject.spi.Bean;
-import javax.enterprise.util.Nonbinding;
-import javax.inject.Qualifier;
-import javax.interceptor.InterceptorBinding;
-
-import org.apache.webbeans.annotation.DefaultLiteral;
-import org.apache.webbeans.container.BeanManagerImpl;
-import org.apache.webbeans.exception.WebBeansConfigurationException;
-import org.apache.webbeans.xml.XMLAnnotationTypeManager;
 
 /**
  * Utility class related with {@link Annotation} operations.
@@ -53,6 +54,8 @@ import org.apache.webbeans.xml.XMLAnnota
 public final class AnnotationUtil
 {
     public static final Annotation[] EMPTY_ANNOTATION_ARRAY = new Annotation[0];
+
+    public static final Object[] EMPTY_OBJECT_ARRAY = new Object[0];
     
     // No instantiate
     private AnnotationUtil()
@@ -537,116 +540,224 @@ public final class AnnotationUtil
     }
 
     /**
-     * Returns true if the injection point binding type and {@link Nonbinding}
-     * member values are equal to the given member annotation.
-     * 
-     * @param clazz annotation class
-     * @param src component binding type annotation
-     * @param member annotation for querying the binding type
-     * @return true or false
+     * Checks if the given qualifiers are equal.
+     *
+     * Qualifiers are equal if they have the same annotationType and all their
+     * methods, except those annotated with @Nonbinding, return the same value.
+     *
+     * @param qualifier1
+     * @param qualifier2
+     * @return
      */
-    public static boolean hasAnnotationMember(Class<? extends Annotation> clazz, Annotation src, Annotation member)
+    public static boolean isQualifierEqual(Annotation qualifier1, Annotation qualifier2)
     {
-        Asserts.nullCheckForClass(clazz);
-        Asserts.assertNotNull(src, "Src argument can not be null");
-        Asserts.assertNotNull(member, "Member argument can not be null");
+        Asserts.assertNotNull(qualifier1, "qualifier1 argument can not be null");
+        Asserts.assertNotNull(qualifier2, "qualifier2 argument can not be null");
+
+        Class<? extends Annotation> qualifier1AnnotationType
+                = qualifier1.annotationType();
 
-        if (!src.annotationType().equals(member.annotationType()))
+        // check if the annotationTypes are equal
+        if (qualifier1AnnotationType == null
+                || !qualifier1AnnotationType.equals(qualifier2.annotationType()))
         {
             return false;
         }
 
-        Method[] methods = SecurityUtil.doPrivilegedGetDeclaredMethods(clazz);
+        // check the values of all qualifier-methods
+        // except those annotated with @Nonbinding
+        List<Method> bindingQualifierMethods
+                = getBindingQualifierMethods(qualifier1AnnotationType);
 
-        List<String> list = new ArrayList<String>();
+        for (Method method : bindingQualifierMethods)
+        {
+            Object value1 = callMethod(qualifier1, method);
+            Object value2 = callMethod(qualifier2, method);
 
-        for (Method method : methods)
+            if (!checkEquality(value1, value2))
+            {
+                return false;
+            }
+        }
+
+        return true;
+    }
+
+    /**
+     * Quecks if the two values are equal.
+     *
+     * @param value1
+     * @param value2
+     * @return
+     */
+    private static boolean checkEquality(Object value1, Object value2)
+    {
+        if ((value1 == null && value2 != null)
+                || (value1 != null && value2 == null))
+        {
+            return false;
+        }
+
+        if (value1 == null && value2 == null)
         {
-            Annotation[] annots = method.getDeclaredAnnotations();
+            return true;
+        }
 
-            if (annots.length > 0)
+        // now both values are != null
+
+        Class<?> valueClass = value1.getClass();
+
+        if (!valueClass.equals(value2.getClass()))
+        {
+            return false;
+        }
+
+        if (valueClass.isPrimitive())
+        {
+            // primitive types can be checked with ==
+            return value1 == value2;
+        }
+        else if (valueClass.isArray())
+        {
+            Class<?> arrayType = valueClass.getComponentType();
+
+            if (arrayType.isPrimitive())
             {
-                for (Annotation annot : annots)
+                if (Long.TYPE == arrayType)
                 {
-                    if (!annot.annotationType().equals(Nonbinding.class))
-                    {
-                        list.add(method.getName());
-                    }
+                    return Arrays.equals(((long[]) value1), (long[]) value2);
                 }
-
+                else if (Integer.TYPE == arrayType)
+                {
+                    return Arrays.equals(((int[]) value1), (int[]) value2);
+                }
+                else if (Short.TYPE == arrayType)
+                {
+                    return Arrays.equals(((short[]) value1), (short[]) value2);
+                }
+                else if (Double.TYPE == arrayType)
+                {
+                    return Arrays.equals(((double[]) value1), (double[]) value2);
+                }
+                else if (Float.TYPE == arrayType)
+                {
+                    return Arrays.equals(((float[]) value1), (float[]) value2);
+                }
+                else if (Boolean.TYPE == arrayType)
+                {
+                    return Arrays.equals(((boolean[]) value1), (boolean[]) value2);
+                }
+                else if (Byte.TYPE == arrayType)
+                {
+                    return Arrays.equals(((byte[]) value1), (byte[]) value2);
+                }
+                else if (Character.TYPE == arrayType)
+                {
+                    return Arrays.equals(((char[]) value1), (char[]) value2);
+                }
+                return false;
             }
             else
             {
-                list.add(method.getName());
+                return Arrays.equals(((Object[]) value1), (Object[]) value2);
             }
         }
-
-        return checkEquality(src.toString(), member.toString(), list);
-
+        else
+        {
+            return value1.equals(value2);
+        }
     }
 
     /**
-     * Check that given two annotation values are equal or not.
-     * 
-     * @param src annotation toString method
-     * @param member annotation toString method
-     * @param arguments annotation member values with {@link Nonbinding}
-     *            annoations.
-     * @return true or false
+     * Calls the given method on the given instance.
+     * Used to determine the values of annotation instances.
+     *
+     * @param instance
+     * @param method
+     * @return
      */
-    private static boolean checkEquality(String src, String member, List<String> arguments)
+    private static Object callMethod(Object instance, Method method)
     {
-        if ((checkEquBuffer(src, arguments).toString().trim().equals(checkEquBuffer(member, arguments).toString().trim())))
+        boolean accessible = method.isAccessible();
+
+        try
         {
-            return true;
+            if (!accessible)
+            {
+                SecurityUtil.doPrivilegedSetAccessible(method, true);
+            }
+
+            return method.invoke(instance, EMPTY_OBJECT_ARRAY);
+        }
+        catch (Exception e)
+        {
+            throw new WebBeansException("Exception in method call : " + method.getName(), e);
+        }
+        finally
+        {
+            // reset accessible value
+            SecurityUtil.doPrivilegedSetAccessible(method, accessible);
         }
-        
-        return false;
     }
 
-    /*
-     * Private check method
+    /**
+     * Return a List of all methods of the qualifier,
+     * which are not annotated with @Nonbinding.
+     *
+     * @param qualifierAnnotationType
+     * @return
      */
-    private static StringBuffer checkEquBuffer(String src, List<String> arguments)
+    private static List<Method> getBindingQualifierMethods(
+            Class<? extends Annotation> qualifierAnnotationType)
     {
-        int index = src.indexOf('(');
-
-        String sbstr = src.substring(index + 1, src.length() - 1);
+        Method[] qualifierMethods = SecurityUtil
+                .doPrivilegedGetDeclaredMethods(qualifierAnnotationType);
 
-        StringBuffer srcBuf = new StringBuffer();
-
-        StringTokenizer tok = new StringTokenizer(sbstr, ",");
-        while (tok.hasMoreTokens())
+        if (qualifierMethods.length > 0)
         {
-            String token = tok.nextToken();
+            List<Method> bindingMethods = new ArrayList<Method>();
 
-            StringTokenizer tok2 = new StringTokenizer(token, "=");
-            while (tok2.hasMoreElements())
+            for (Method qualifierMethod : qualifierMethods)
             {
-                String tt = tok2.nextToken();
-                if (arguments.contains(tt.trim()))
+                Annotation[] qualifierMethodAnnotations
+                        = qualifierMethod.getDeclaredAnnotations();
+
+                if (qualifierMethodAnnotations.length > 0)
                 {
-                    srcBuf.append(tt);
-                    srcBuf.append("=");
+                    // look for @Nonbinding
+                    boolean nonbinding = false;
 
-                    if (tok2.hasMoreElements())
+                    for (Annotation qualifierMethodAnnotation : qualifierMethodAnnotations)
                     {
-                        String str = tok2.nextToken();
-                        if(str.charAt(0) == '"' && str.charAt(str.length() -1) == '"')
+                        if (Nonbinding.class.equals(
+                                qualifierMethodAnnotation.annotationType()))
                         {
-                            str = str.substring(1,str.length()-1);
+                            nonbinding = true;
+                            break;
                         }
-                        
-                        srcBuf.append(str);   
                     }
+
+                    if (!nonbinding)
+                    {
+                        // no @Nonbinding found - add to list
+                        bindingMethods.add(qualifierMethod);
+                    }
+                }
+                else
+                {
+                    // no method-annotations - add to list
+                    bindingMethods.add(qualifierMethod);
                 }
             }
 
+            return bindingMethods;
         }
 
-        return srcBuf;
+        // annotation has no methods
+        return Collections.emptyList();
     }
 
+
     /**
      * Gets the array of qualifier annotations on the given array.
      * 

Modified: openwebbeans/trunk/webbeans-impl/src/main/java/org/apache/webbeans/util/WebBeansAnnotatedTypeUtil.java
URL: http://svn.apache.org/viewvc/openwebbeans/trunk/webbeans-impl/src/main/java/org/apache/webbeans/util/WebBeansAnnotatedTypeUtil.java?rev=1002487&r1=1002486&r2=1002487&view=diff
==============================================================================
--- openwebbeans/trunk/webbeans-impl/src/main/java/org/apache/webbeans/util/WebBeansAnnotatedTypeUtil.java (original)
+++ openwebbeans/trunk/webbeans-impl/src/main/java/org/apache/webbeans/util/WebBeansAnnotatedTypeUtil.java Wed Sep 29 06:22:02 2010
@@ -18,43 +18,9 @@
  */
 package org.apache.webbeans.util;
 
-import java.lang.annotation.Annotation;
-import java.lang.reflect.Field;
-import java.lang.reflect.Method;
-import java.lang.reflect.Modifier;
-import java.lang.reflect.ParameterizedType;
-import java.lang.reflect.Type;
-import java.lang.reflect.TypeVariable;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Set;
-
-import javax.decorator.Decorator;
-import javax.decorator.Delegate;
-import javax.enterprise.context.Dependent;
-import javax.enterprise.event.Observes;
-import javax.enterprise.event.Reception;
-import javax.enterprise.inject.Default;
-import javax.enterprise.inject.Disposes;
-import javax.enterprise.inject.Produces;
-import javax.enterprise.inject.Specializes;
-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.Bean;
-import javax.enterprise.inject.spi.InjectionPoint;
-import javax.enterprise.inject.spi.ObserverMethod;
-import javax.inject.Inject;
-import javax.inject.Named;
-import javax.interceptor.Interceptor;
-
 import org.apache.webbeans.annotation.DependentScopeLiteral;
-import org.apache.webbeans.component.AbstractOwbBean;
 import org.apache.webbeans.component.AbstractInjectionTargetBean;
+import org.apache.webbeans.component.AbstractOwbBean;
 import org.apache.webbeans.component.InjectionTargetBean;
 import org.apache.webbeans.component.ManagedBean;
 import org.apache.webbeans.component.OwbBean;
@@ -77,6 +43,40 @@ import org.apache.webbeans.intercept.Web
 import org.apache.webbeans.logger.WebBeansLogger;
 import org.apache.webbeans.proxy.JavassistProxyFactory;
 import org.apache.webbeans.spi.api.ResourceReference;
+
+import javax.decorator.Decorator;
+import javax.decorator.Delegate;
+import javax.enterprise.context.Dependent;
+import javax.enterprise.event.Observes;
+import javax.enterprise.event.Reception;
+import javax.enterprise.inject.Default;
+import javax.enterprise.inject.Disposes;
+import javax.enterprise.inject.Produces;
+import javax.enterprise.inject.Specializes;
+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.Bean;
+import javax.enterprise.inject.spi.InjectionPoint;
+import javax.enterprise.inject.spi.ObserverMethod;
+import javax.inject.Inject;
+import javax.inject.Named;
+import javax.interceptor.Interceptor;
+import java.lang.annotation.Annotation;
+import java.lang.reflect.Field;
+import java.lang.reflect.Method;
+import java.lang.reflect.Modifier;
+import java.lang.reflect.ParameterizedType;
+import java.lang.reflect.Type;
+import java.lang.reflect.TypeVariable;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+
 import static org.apache.webbeans.util.InjectionExceptionUtils.throwUnsatisfiedResolutionException;
 
 public final class WebBeansAnnotatedTypeUtil
@@ -1025,7 +1025,7 @@ public final class WebBeansAnnotatedType
                                 {
                                     for(Annotation ann :annots)
                                     {
-                                        if(!AnnotationUtil.hasAnnotationMember(qualifier.annotationType(), qualifier, ann))
+                                        if(!AnnotationUtil.isQualifierEqual(qualifier, ann))
                                         {
                                             return null;
                                         }

Added: openwebbeans/trunk/webbeans-impl/src/test/java/org/apache/webbeans/newtests/util/AnnotationUtilTest.java
URL: http://svn.apache.org/viewvc/openwebbeans/trunk/webbeans-impl/src/test/java/org/apache/webbeans/newtests/util/AnnotationUtilTest.java?rev=1002487&view=auto
==============================================================================
--- openwebbeans/trunk/webbeans-impl/src/test/java/org/apache/webbeans/newtests/util/AnnotationUtilTest.java (added)
+++ openwebbeans/trunk/webbeans-impl/src/test/java/org/apache/webbeans/newtests/util/AnnotationUtilTest.java Wed Sep 29 06:22:02 2010
@@ -0,0 +1,347 @@
+/*
+ * 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.newtests.util;
+
+import org.apache.webbeans.config.DefaultAnnotation;
+import org.apache.webbeans.util.AnnotationUtil;
+import org.junit.Assert;
+import org.junit.Test;
+
+import javax.enterprise.util.AnnotationLiteral;
+import javax.enterprise.util.Nonbinding;
+import javax.inject.Qualifier;
+import java.lang.annotation.Annotation;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+
+import static java.lang.annotation.RetentionPolicy.RUNTIME;
+
+/**
+ * Tests for AnnotationUtil.
+ */
+public class AnnotationUtilTest
+{
+    @Test
+    public void test_isQualifierEqual_DefaultAnnotation_emptyQualifier()
+    {
+        Annotation q1 = DefaultAnnotation.of(EmptyQualifier.class);
+        Annotation q2 = DefaultAnnotation.of(EmptyQualifier.class);
+
+        Assert.assertTrue(AnnotationUtil.isQualifierEqual(q1, q2));
+    }
+
+    @Test
+    public void test_isQualifierEqual_DefaultAnnotation_AnnotationLiteral_emptyQualifier()
+    {
+        Annotation q1 = DefaultAnnotation.of(EmptyQualifier.class);
+        EmptyQualifier q2 = new EmptyQualifierAnnotationLiteral();
+
+        Assert.assertTrue(AnnotationUtil.isQualifierEqual(q1, q2));
+    }
+
+    @Test
+    public void test_isQualifierEqual_DefaultAnnotation_nonEmptyQualifier()
+    {
+        Annotation q1 = DefaultAnnotation.of(TestQualifier.class);
+        Annotation q2 = DefaultAnnotation.of(TestQualifier.class);
+
+        Assert.assertTrue(AnnotationUtil.isQualifierEqual(q1, q2));
+    }
+
+    @Test
+    public void test_isQualifierEqual_DefaultAnnotation_AnnotationLiteral_nonEmptyQualifier()
+    {
+        Annotation q1 = DefaultAnnotation.of(TestQualifier.class);
+        TestQualifier q2 = new TestQualifierAnnotationLiteral();
+
+        Assert.assertTrue(AnnotationUtil.isQualifierEqual(q1, q2));
+    }
+
+    @Test
+    public void test_isQualifierEqual_AnnotationLiteral_nonEmptyQualifier()
+    {
+        TestQualifier q1 = new TestQualifierAnnotationLiteral();
+        TestQualifier q2 = new TestQualifierAnnotationLiteral();
+
+        Assert.assertTrue(AnnotationUtil.isQualifierEqual(q1, q2));
+    }
+
+    @Test
+    public void test_isQualifierEqual_AnnotationLiteral_Different_String()
+    {
+        TestQualifier q1 = new TestQualifierAnnotationLiteral();
+        TestQualifierAnnotationLiteral q2 = new TestQualifierAnnotationLiteral();
+    
+        q2.setValue("different value");
+
+        Assert.assertFalse(AnnotationUtil.isQualifierEqual(q1, q2));
+    }
+
+    @Test
+    public void test_isQualifierEqual_AnnotationLiteral_Different_int()
+    {
+        TestQualifier q1 = new TestQualifierAnnotationLiteral();
+        TestQualifierAnnotationLiteral q2 = new TestQualifierAnnotationLiteral();
+
+        q2.setNumber(4711);
+
+        Assert.assertFalse(AnnotationUtil.isQualifierEqual(q1, q2));
+    }
+
+    @Test
+    public void test_isQualifierEqual_AnnotationLiteral_Different_array()
+    {
+        TestQualifier q1 = new TestQualifierAnnotationLiteral();
+        TestQualifierAnnotationLiteral q2 = new TestQualifierAnnotationLiteral();
+
+        q2.setFloatArray(new float[]{47F, 11F});
+
+        Assert.assertFalse(AnnotationUtil.isQualifierEqual(q1, q2));
+    }
+
+    @Test
+    public void test_isQualifierEqual_AnnotationLiteral_Different_Enum()
+    {
+        TestQualifier q1 = new TestQualifierAnnotationLiteral();
+        TestQualifierAnnotationLiteral q2 = new TestQualifierAnnotationLiteral();
+
+        q2.setEnumValue(RetentionPolicy.SOURCE);
+
+        Assert.assertFalse(AnnotationUtil.isQualifierEqual(q1, q2));
+    }
+
+    @Test
+    public void test_isQualifierEqual_AnnotationLiteral_Nonbinding_Different()
+    {
+        Annotation q1 = DefaultAnnotation.of(TestQualifierNonbinding.class);
+        TestQualifierNonbinding q2 = new TestQualifierNonbindingAnnotationLiteral();
+
+        Assert.assertTrue(AnnotationUtil.isQualifierEqual(q1, q2));
+    }
+
+    @Test
+    public void test_isQualifierEqual_AnnotationLiteral_MultipleNonbinding_Different()
+    {
+        Annotation q1 = DefaultAnnotation.of(TestQualifierMultipleNonbinding.class);
+        TestQualifierMultipleNonbindingAnnotationLiteral q2 = new TestQualifierMultipleNonbindingAnnotationLiteral();
+        q2.setValue("my value");
+
+        Assert.assertFalse(AnnotationUtil.isQualifierEqual(q1, q2));
+    }
+    
+    @Test
+    public void test_isQualifierEqual_AnnotationLiteral_MultipleNonbinding_Equals()
+    {
+        Annotation q1 = DefaultAnnotation.of(TestQualifierMultipleNonbinding.class);
+        TestQualifierMultipleNonbindingAnnotationLiteral q2 = new TestQualifierMultipleNonbindingAnnotationLiteral();
+        q2.setValue("default-value");
+
+        Assert.assertTrue(AnnotationUtil.isQualifierEqual(q1, q2));
+    }
+    
+    @Test
+    public void test_isQualifierEqual_AnnotationLiteralMutliple_MultipleNonbinding_Equals()
+    {
+        TestQualifierMultipleNonbindingAnnotationLiteral q1 = new TestQualifierMultipleNonbindingAnnotationLiteral();
+        q1.setValue("hello");
+        
+        TestQualifierMultipleNonbindingAnnotationLiteral q2 = new TestQualifierMultipleNonbindingAnnotationLiteral();
+        q2.setValue("hello");
+
+        Assert.assertTrue(AnnotationUtil.isQualifierEqual(q1, q2));
+    }
+    
+    @Test
+    public void test_isQualifierEqual_AnnotationLiteralMutliple_MultipleNonbinding_different()
+    {
+        TestQualifierMultipleNonbindingAnnotationLiteral q1 = new TestQualifierMultipleNonbindingAnnotationLiteral();
+        q1.setValue("hello_different");
+        
+        TestQualifierMultipleNonbindingAnnotationLiteral q2 = new TestQualifierMultipleNonbindingAnnotationLiteral();
+        q2.setValue("hello");
+
+        Assert.assertFalse(AnnotationUtil.isQualifierEqual(q1, q2));
+    }    
+}
+
+@Retention(RUNTIME)
+@Qualifier
+@interface EmptyQualifier
+{
+
+}
+
+class EmptyQualifierAnnotationLiteral
+        extends AnnotationLiteral<EmptyQualifier>
+        implements EmptyQualifier
+{
+}
+
+@Retention(RUNTIME)
+@Qualifier
+@interface TestQualifier
+{
+
+    String value() default "default-value";
+
+    int number() default -1;
+
+    float[] floatArray() default {1.0F, 1.2F};
+
+    RetentionPolicy enumValue() default RetentionPolicy.RUNTIME;
+
+}
+
+class TestQualifierAnnotationLiteral
+        extends AnnotationLiteral<TestQualifier>
+        implements TestQualifier
+{
+
+    // default values
+    private String value = "default-value";
+    private int number = -1;
+    private float[] floatArray = new float[]{1.0F, 1.2F};
+    private RetentionPolicy enumValue = RetentionPolicy.RUNTIME;
+
+    // annotation methods
+
+    public String value()
+    {
+        return value;
+    }
+
+    public int number()
+    {
+        return number;
+    }
+
+    public float[] floatArray()
+    {
+        return floatArray;
+    }
+
+    public RetentionPolicy enumValue()
+    {
+        return enumValue;
+    }
+
+    // setter
+
+    public void setValue(String value)
+    {
+        this.value = value;
+    }
+
+    public void setNumber(int number)
+    {
+        this.number = number;
+    }
+
+    public void setFloatArray(float[] floatArray)
+    {
+        this.floatArray = floatArray;
+    }
+
+    public void setEnumValue(RetentionPolicy enumValue)
+    {
+        this.enumValue = enumValue;
+    }
+
+}
+
+@Retention(RUNTIME)
+@Qualifier
+@interface TestQualifierNonbinding
+{
+
+    String value() default "default-value";
+
+    @MyCustomAnnotation // to show that there can be more than one annotation here
+    @Nonbinding
+    int number() default -1;
+
+}
+
+@Retention(RUNTIME)
+@Qualifier
+@interface TestQualifierMultipleNonbinding
+{
+
+    String value() default "default-value";
+
+    @Nonbinding
+    int number() default -1;
+    
+    @Nonbinding
+    long card() default -1;    
+
+}
+
+@Retention(RUNTIME)
+@interface MyCustomAnnotation
+{
+}
+
+class TestQualifierMultipleNonbindingAnnotationLiteral
+    extends AnnotationLiteral<TestQualifierMultipleNonbinding>
+    implements TestQualifierMultipleNonbinding
+
+{
+    String value;
+    
+    public void setValue(String value)
+    {
+        this.value = value;
+    }
+
+    @Override
+    public String value()
+    {
+        return value;
+    }
+
+    @Override
+    public int number()
+    {
+        return 10;
+    }
+
+    @Override
+    public long card()
+    {
+        return 20;
+    }
+    
+}
+
+class TestQualifierNonbindingAnnotationLiteral
+        extends AnnotationLiteral<TestQualifierNonbinding>
+        implements TestQualifierNonbinding
+{
+
+    public String value()
+    {
+        return "default-value";
+    }
+
+    public int number()
+    {
+        return 4711;
+    }
+}

Propchange: openwebbeans/trunk/webbeans-impl/src/test/java/org/apache/webbeans/newtests/util/AnnotationUtilTest.java
------------------------------------------------------------------------------
    svn:eol-style = native