[jboss-cvs] JBossAS SVN: r104639 - in projects/jboss-mdr/branches/2.0.2.GA_JBPAPP-4220: src/main/java/org/jboss/metadata/plugins/loader/reflection and 4 other directories.

jboss-cvs-commits at lists.jboss.org jboss-cvs-commits at lists.jboss.org
Mon May 10 18:46:44 EDT 2010


Author: dstephan
Date: 2010-05-10 18:46:43 -0400 (Mon, 10 May 2010)
New Revision: 104639

Modified:
   projects/jboss-mdr/branches/2.0.2.GA_JBPAPP-4220/pom.xml
   projects/jboss-mdr/branches/2.0.2.GA_JBPAPP-4220/src/main/java/org/jboss/metadata/plugins/loader/reflection/AnnotatedElementMetaDataLoader.java
   projects/jboss-mdr/branches/2.0.2.GA_JBPAPP-4220/src/main/java/org/jboss/metadata/spi/retrieval/MetaDataRetrievalToMetaDataBridge.java
   projects/jboss-mdr/branches/2.0.2.GA_JBPAPP-4220/src/main/java/org/jboss/metadata/spi/scope/Scope.java
   projects/jboss-mdr/branches/2.0.2.GA_JBPAPP-4220/src/main/java/org/jboss/metadata/spi/scope/ScopeKey.java
   projects/jboss-mdr/branches/2.0.2.GA_JBPAPP-4220/src/test/java/org/jboss/test/metadata/loader/reflection/test/AnnotatedElementMetadataLoaderTestCase.java
   projects/jboss-mdr/branches/2.0.2.GA_JBPAPP-4220/src/test/java/org/jboss/test/metadata/shared/ComponentBasicAnnotationsTest.java
Log:
JBPAPP-4220 - Updates required to backport JBMDR-69 to EAP 5.0.1. 

Modified: projects/jboss-mdr/branches/2.0.2.GA_JBPAPP-4220/pom.xml
===================================================================
--- projects/jboss-mdr/branches/2.0.2.GA_JBPAPP-4220/pom.xml	2010-05-10 22:42:17 UTC (rev 104638)
+++ projects/jboss-mdr/branches/2.0.2.GA_JBPAPP-4220/pom.xml	2010-05-10 22:46:43 UTC (rev 104639)
@@ -6,7 +6,7 @@
   </parent>
   <modelVersion>4.0.0</modelVersion>
   <artifactId>jboss-mdr</artifactId>
-  <version>2.0.2.GA</version>
+  <version>2.0.2.GA_JBPAPP-4220</version>
   <packaging>jar</packaging>
   <name>JBoss MetaData Repository</name>
   <url>http://www.jboss.com/products/jbossmc</url>

Modified: projects/jboss-mdr/branches/2.0.2.GA_JBPAPP-4220/src/main/java/org/jboss/metadata/plugins/loader/reflection/AnnotatedElementMetaDataLoader.java
===================================================================
--- projects/jboss-mdr/branches/2.0.2.GA_JBPAPP-4220/src/main/java/org/jboss/metadata/plugins/loader/reflection/AnnotatedElementMetaDataLoader.java	2010-05-10 22:42:17 UTC (rev 104638)
+++ projects/jboss-mdr/branches/2.0.2.GA_JBPAPP-4220/src/main/java/org/jboss/metadata/plugins/loader/reflection/AnnotatedElementMetaDataLoader.java	2010-05-10 22:46:43 UTC (rev 104639)
@@ -21,13 +21,6 @@
 */
 package org.jboss.metadata.plugins.loader.reflection;
 
-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 org.jboss.logging.Logger;
 import org.jboss.metadata.plugins.loader.BasicMetaDataLoader;
 import org.jboss.metadata.plugins.loader.SimpleMetaDataLoader;
@@ -39,16 +32,17 @@
 import org.jboss.metadata.spi.scope.CommonLevels;
 import org.jboss.metadata.spi.scope.Scope;
 import org.jboss.metadata.spi.scope.ScopeKey;
-import org.jboss.metadata.spi.signature.ConstructorParametersSignature;
-import org.jboss.metadata.spi.signature.ConstructorSignature;
-import org.jboss.metadata.spi.signature.DeclaredMethodSignature;
-import org.jboss.metadata.spi.signature.FieldSignature;
-import org.jboss.metadata.spi.signature.MethodParametersSignature;
-import org.jboss.metadata.spi.signature.MethodSignature;
-import org.jboss.metadata.spi.signature.Signature;
+import org.jboss.metadata.spi.scope.UnmodifiableScopeKey;
+import org.jboss.metadata.spi.signature.*;
 import org.jboss.util.JBossStringBuilder;
 import org.jboss.util.Strings;
 
+import java.lang.annotation.Annotation;
+import java.lang.reflect.*;
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+
 /**
  * AnnotatedElementMetaDataLoader.
  * 
@@ -80,7 +74,7 @@
       {
          return ScopeKey.DEFAULT_SCOPE;
       }
-      return new ScopeKey(scope);
+      return new UnmodifiableScopeKey(scope);
    }
    
    /**
@@ -137,6 +131,8 @@
                   log.trace("Constructor with signature " + signature + " does not exist on class " + clazz.getName());
                return null;
             }
+            if (constructor.getAnnotations().length == 0)
+               return null;
             return new AnnotatedElementMetaDataLoader(constructor);
          }
          else if (signature instanceof MethodSignature)
@@ -151,6 +147,17 @@
                   log.trace("Method with signature " + signature + " does not exist on class " + clazz.getName());
                return null;
             }
+            if (method.getAnnotations().length == 0)
+            {
+               if (!method.isBridge())
+                  return null;
+               else
+               {
+                  method = searchForRealBridgeMethodSignature(method); 
+                  if (method == null)
+                     return null;
+               }
+            }
             return new AnnotatedElementMetaDataLoader(method);
          }
          else if (signature instanceof DeclaredMethodSignature)
@@ -173,6 +180,17 @@
                   return null;     
                }
             }
+            if (method.getAnnotations().length == 0)
+            {
+               if (!method.isBridge())
+                  return null;
+               else
+               {
+                  method = searchForRealBridgeMethodSignature(method);
+                  if (method == null)
+                     return null;
+               }
+            }
             return new AnnotatedElementMetaDataLoader(method);
          }
          else if (signature instanceof MethodParametersSignature)
@@ -188,6 +206,8 @@
                return null;
             }
             Annotation[][] paramAnnotations = method.getParameterAnnotations();
+            if (paramAnnotations[methodParametersSignature.getParam()].length == 0)
+               return null;
             return new SimpleMetaDataLoader(paramAnnotations[methodParametersSignature.getParam()]);
          }
          else if (signature instanceof ConstructorParametersSignature)
@@ -203,6 +223,8 @@
                return null;
             }
             Annotation[][] paramAnnotations = constructor.getParameterAnnotations();
+            if (paramAnnotations[constructorParametersSignature.getParam()].length == 0)
+               return null;
             return new SimpleMetaDataLoader(paramAnnotations[constructorParametersSignature.getParam()]);
          }
          else if (signature instanceof FieldSignature)
@@ -217,6 +239,8 @@
                   log.trace("Field " + signature.getName() + " does not exist on class " + clazz.getName());
                return null;
             }
+            if (field.getAnnotations().length == 0)
+               return null;
             return new AnnotatedElementMetaDataLoader(field);
          }
       }
@@ -228,6 +252,8 @@
             Method method = (Method)annotated;
             Annotation[][] paramAnnotations = method.getParameterAnnotations();
             MethodParametersSignature sig = (MethodParametersSignature) signature;
+            if (paramAnnotations[sig.getParam()].length == 0)
+               return null;
             return new SimpleMetaDataLoader(paramAnnotations[sig.getParam()]);
          }
       }
@@ -239,6 +265,8 @@
             Constructor<?> constructor = Constructor.class.cast(annotated);
             Annotation[][] paramAnnotations = constructor.getParameterAnnotations();
             ConstructorParametersSignature sig = (ConstructorParametersSignature) signature;
+            if (paramAnnotations[sig.getParam()].length == 0)
+               return null;
             return new SimpleMetaDataLoader(paramAnnotations[sig.getParam()]);
          }
       }
@@ -280,4 +308,57 @@
       }
       return null;
    }
+   
+   private Method searchForRealBridgeMethodSignature(Method bridge)
+   {
+      List<Method> matching = new ArrayList<Method>();
+      Method[] all = bridge.getDeclaringClass().getDeclaredMethods();
+      for (int i = 0 ; i < all.length ; i++)
+      {
+         if (all[i].getName().equals(bridge.getName()) &&
+               all[i].getParameterTypes().length == bridge.getParameterTypes().length &&
+               !all[i].equals(bridge) &&
+               !all[i].isBridge())
+            matching.add(all[i]);
+      }
+      
+      if (matching.size() == 1)
+         return matching.get(0);
+      
+      //Should not happen
+      if (matching.size() == 0)
+         throw new IllegalStateException("No original methods found");
+      
+      for (Iterator<Method> it = matching.iterator() ; it.hasNext() ; )
+      {
+         Method cur = it.next();
+         if (!bridge.getReturnType().isAssignableFrom(cur.getReturnType()))
+         {
+            it.remove();
+            continue;
+         }
+         
+         
+         for (int i = 0 ; i < bridge.getParameterTypes().length ; i++)
+         {
+            if (!bridge.getParameterTypes()[i].isAssignableFrom(cur.getParameterTypes()[i]))
+            {
+               it.remove();
+               continue;
+            }
+         }
+      }
+
+      if (matching.size() == 1)
+         return matching.get(0);
+       
+      //Should not happen
+      if (matching.size() == 0)
+         throw new IllegalStateException("No original methods found");
+
+      if (log.isTraceEnabled())
+         log.trace("Could not determine original method for " + bridge + " found: " + matching);
+      
+      return null;
+   }
 }

Modified: projects/jboss-mdr/branches/2.0.2.GA_JBPAPP-4220/src/main/java/org/jboss/metadata/spi/retrieval/MetaDataRetrievalToMetaDataBridge.java
===================================================================
--- projects/jboss-mdr/branches/2.0.2.GA_JBPAPP-4220/src/main/java/org/jboss/metadata/spi/retrieval/MetaDataRetrievalToMetaDataBridge.java	2010-05-10 22:42:17 UTC (rev 104638)
+++ projects/jboss-mdr/branches/2.0.2.GA_JBPAPP-4220/src/main/java/org/jboss/metadata/spi/retrieval/MetaDataRetrievalToMetaDataBridge.java	2010-05-10 22:46:43 UTC (rev 104639)
@@ -82,6 +82,14 @@
       return item.getValue();
    }
 
+//   public Annotation[] getAnnotationsAnnotatedWith(Class<? extends Annotation> meta)
+//   {
+//      AnnotationsItem item = retrieval.retrieveAnnotationsAnnotatedWith(meta);
+//      if (item == null)
+//         return NO_ANNOTATIONS;
+//      return item.getValue();
+//   }
+
    public Object[] getMetaData()
    {
       MetaDatasItem item = retrieval.retrieveMetaData();
@@ -159,7 +167,7 @@
    {
       MetaDataRetrieval component = retrieval.getComponentMetaDataRetrieval(signature);
       if (component == null)
-         return null;
+         return NullComponentMetaData.INSTANCE;
       return new MetaDataRetrievalToMetaDataBridge(component);
    }
 
@@ -210,4 +218,95 @@
    {
       return retrieval;
    }
+   
+   private static class NullComponentMetaData implements MetaData
+   {
+      final static NullComponentMetaData INSTANCE = new NullComponentMetaData();
+
+      public <T extends Annotation> T getAnnotation(Class<T> annotationType)
+      {
+         return null;
+      }
+
+      public Annotation[] getAnnotations()
+      {
+         return MetaData.NO_ANNOTATIONS;
+      }
+
+      public Annotation[] getAnnotationsAnnotatedWith(Class<? extends Annotation> meta)
+      {
+         return MetaData.NO_ANNOTATIONS;
+      }
+
+      public MetaData getComponentMetaData(Signature signature)
+      {
+         return null;
+      }
+
+      public Annotation[] getLocalAnnotations()
+      {
+         return MetaData.NO_ANNOTATIONS;
+      }
+
+      public Object[] getLocalMetaData()
+      {
+         return MetaData.NO_METADATA;
+      }
+
+      public <T> T getMetaData(Class<T> type)
+      {
+         return null;
+      }
+
+      public Object[] getMetaData()
+      {
+         return MetaData.NO_METADATA;
+      }
+
+      public Object getMetaData(String name)
+      {
+         return null;
+      }
+
+      public <T> T getMetaData(String name, Class<T> type)
+      {
+         return null;
+      }
+
+      public MetaData getScopeMetaData(ScopeLevel level)
+      {
+         return null;
+      }
+
+      public long getValidTime()
+      {
+         return 0;
+      }
+
+      public boolean isAnnotationPresent(Class<? extends Annotation> annotationType)
+      {
+         return false;
+      }
+
+      public boolean isEmpty()
+      {
+         return true;
+      }
+
+      public boolean isMetaDataPresent(Class<?> type)
+      {
+         return false;
+      }
+
+      public boolean isMetaDataPresent(String name)
+      {
+         return false;
+      }
+
+      public boolean isMetaDataPresent(String name, Class<?> type)
+      {
+         return false;
+      }
+      
+   }
 }

Modified: projects/jboss-mdr/branches/2.0.2.GA_JBPAPP-4220/src/main/java/org/jboss/metadata/spi/scope/Scope.java
===================================================================
--- projects/jboss-mdr/branches/2.0.2.GA_JBPAPP-4220/src/main/java/org/jboss/metadata/spi/scope/Scope.java	2010-05-10 22:42:17 UTC (rev 104638)
+++ projects/jboss-mdr/branches/2.0.2.GA_JBPAPP-4220/src/main/java/org/jboss/metadata/spi/scope/Scope.java	2010-05-10 22:46:43 UTC (rev 104639)
@@ -29,7 +29,7 @@
  * @author <a href="adrian at jboss.com">Adrian Brock</a>
  * @version $Revision$
  */
-public class Scope implements Serializable
+public class Scope implements Serializable,  Comparable
 {
    /** The serialVersionUID */
    private static final long serialVersionUID = 5255750644324593361L;
@@ -80,6 +80,21 @@
       return qualifier.equals(other.qualifier);
    }
    
+   /**
+    * @param o the object to be compared.
+    * @return a negative integer, zero, or a positive integer as this object
+    *         is less than, equal to, or greater than the specified object.
+    * @throws ClassCastException if the specified object's type prevents it
+    *                            from being compared to this object.
+    */
+   public int compareTo(Object o)
+   {
+      if (o == this)
+         return 0;
+      Scope other = (Scope) o;
+      return (level.compareTo(other.getScopeLevel()));
+   }
+   
    public int hashCode()
    {
       return level.hashCode();

Modified: projects/jboss-mdr/branches/2.0.2.GA_JBPAPP-4220/src/main/java/org/jboss/metadata/spi/scope/ScopeKey.java
===================================================================
--- projects/jboss-mdr/branches/2.0.2.GA_JBPAPP-4220/src/main/java/org/jboss/metadata/spi/scope/ScopeKey.java	2010-05-10 22:42:17 UTC (rev 104638)
+++ projects/jboss-mdr/branches/2.0.2.GA_JBPAPP-4220/src/main/java/org/jboss/metadata/spi/scope/ScopeKey.java	2010-05-10 22:46:43 UTC (rev 104639)
@@ -22,28 +22,54 @@
 package org.jboss.metadata.spi.scope;
 
 import java.io.Serializable;
+import java.util.Arrays;
 import java.util.Collection;
 import java.util.Collections;
 import java.util.Iterator;
-import java.util.SortedMap;
-import java.util.TreeMap;
+import java.util.Map;
 
+import org.jboss.util.collection.ConcurrentSkipListMap;
+
 /**
- * ScopeKey.
- * 
+ * The ScopeKey represents a path which is made up of the path entries.  Elements may be added dynamically
+ * until the ScopeKey is frozen.  If you want to add more elements to a frozen ScopeKey, clone it
+ * (cloned objects are not frozen).
+ *
+ * To use the ScopeKey as a key object, use the UnmodifiableScopeKey returned from getOptimizedKey().
+ * UnmodifiableScopeKey's are immutable and suitable for use as a key (also thread-safe with no object lock contention). 
+ *
+ * The ScopeKey (Server=Bob,Deployment=Foo.war,Class=Bar)
+ * is the child of (Server=Bob,Deployment=Foo.war),
+ * which is the child of (Server=Bob).  Think about this statement in terms of
+ * a path relationship.  The server (Bob) contains a deployment (Foo.war) and
+ * the deployment contains a class (Bar).
+ *
+ * See historical design notes
+ * http://www.jboss.org/index.html?module=bb&op=viewtopic&p=3972233#3972233
+ * http://www.jboss.org/index.html?module=bb&op=viewtopic&p=4013747#4013747
+ *
+ * Thread Safety:  This class is thread safe.
+ *
+ * Warning:  This class is (delicately) extended by UnmodifiableScopeKey.
+ * Since there is no common interface class between the two classes, there are risks to be
+ * aware of.  If a new method is added to ScopeKey and not to UnmodifiableScopeKey, undesireable
+ * behavior will occur when that UnmodifiableScopeKey.method is invoked (ScopeKey's member variables will be null). 
+ *
  * @author <a href="adrian at jboss.com">Adrian Brock</a>
  * @version $Revision$
  */
 public class ScopeKey implements Serializable, Cloneable
 {
+   private final static ConcurrentSkipListMap<ScopeLevel, Scope> EMPTY_SCOPES = new UnmodifiableConcurrentSkipListMap<ScopeLevel, Scope>(); 
+   
    /** The serialVersionUID */
-   private static final long serialVersionUID = -496238095349593371L;
+   private static final long serialVersionUID = -496238095349593371L + 1L;
 
    /** The default scope */
-   public static ScopeKey DEFAULT_SCOPE = new ScopeKey(new Scope(CommonLevels.JVM, "THIS"));
+   public static final ScopeKey DEFAULT_SCOPE = new ScopeKey(new Scope(CommonLevels.JVM, "THIS"));
    
-   /** The scopes */
-   private SortedMap<ScopeLevel, Scope> scopes = Collections.synchronizedSortedMap(new TreeMap<ScopeLevel, Scope>());
+   /** The scopes () */
+   private volatile ConcurrentSkipListMap<ScopeLevel, Scope> scopes = EMPTY_SCOPES;
    
    /** The scope level for this key */
    private ScopeLevel maxScopeLevel;
@@ -87,7 +113,8 @@
    /**
     * Create a new ScopeKey.
     * 
-    * @param scopes the scopes
+    * @param scopes is a collection of Scope instances that make up the represented path
+    * @throws IllegalArgumentException if parameter scopes is null
     */
    public ScopeKey(Collection<Scope> scopes)
    {
@@ -100,7 +127,8 @@
    /**
     * Create a new ScopeKey.
     * 
-    * @param scopes the scopes
+    * @param scopes is zero or more Scope instances that make up the represented path
+    * @throws IllegalArgumentException if parameter scopes is null
     */
    public ScopeKey(Scope[] scopes)
    {
@@ -122,6 +150,8 @@
 
    /**
     * Set to frozen.
+    *
+    * @throws IllegalArgumentException if there are no Scope entries added.
     */
    public void freeze()
    {
@@ -131,9 +161,19 @@
    }
    
    /**
-    * Get the scopes
+    * The returned ScopeKey is immutable and optimized for use at runtime.
+    *
+    * @return Optimized immutable ScopeKey
+    */
+   public ScopeKey getOptimizedKey()
+   {
+      return new UnmodifiableScopeKey(this);
+   }
+
+   /**
+    * Get the scopes 
     * 
-    * @return the scopes
+    * @return the scopes in expected path order
     */
    public Collection<Scope> getScopes()
    {
@@ -145,6 +185,7 @@
     * 
     * @param level the scope level
     * @return the scope
+    * @throws IllegalArgumentException if level is null.
     */
    public Scope getScope(ScopeLevel level)
    {
@@ -166,7 +207,8 @@
    /**
     * Get the parent scope key
     * 
-    * @return the parent or null if there is no parent
+    * @return the parent or null if there is no parent (meaning that we
+    * are at the top most element in the path)
     */
    public ScopeKey getParent()
    {
@@ -188,22 +230,24 @@
     *
     * @param key the key parameter
     * @return true if this is direct parent of key param
+    * @throws IllegalArgumentException if parameter key is null
     */
    public boolean isParent(ScopeKey key)
    {
       if (key == null)
          throw new IllegalArgumentException("Null key");
+      Collection keyValues = key.getScopesCollection();
 
       // The passed key doesn't have a parent
-      if (key.scopes.size() < 2)
+      if (keyValues.size() < 2)
          return false;
       
       // If it is a child, it will have one more scope
-      if (scopes.size() != key.scopes.size() - 1)
+      if (scopes.size() != keyValues.size() - 1)
          return false;
 
       Iterator<Scope> thisScopes = scopes.values().iterator();
-      Iterator<Scope> keyScopes = key.scopes.values().iterator();
+      Iterator<Scope> keyScopes = keyValues.iterator();
       
       while (thisScopes.hasNext())
       {
@@ -221,6 +265,8 @@
     * 
     * @param scope the scope
     * @return the previous value or null if there wasn't one
+    * @throws IllegalArgumentException if scope is null.
+    * @throws IllegalStateException if frozen
     */
    public Scope addScope(Scope scope)
    {
@@ -228,7 +274,15 @@
          throw new IllegalArgumentException("Null scope");
       if (frozen)
          throw new IllegalStateException("The scope key is frozen");
-      
+      if (scopes == EMPTY_SCOPES)
+      {
+         synchronized (this)
+         {
+            if (scopes == EMPTY_SCOPES)
+               scopes = new ConcurrentSkipListMap<ScopeLevel, Scope>();
+         }
+      }
+
       ScopeLevel level = scope.getScopeLevel();
       Scope result = scopes.put(level, scope);
       if (maxScopeLevel == null || level.compareTo(maxScopeLevel) >= 0)
@@ -268,12 +322,13 @@
     * 
     * @param scopeLevel the scope level
     * @return the scope or null if there is no such level
+    * @throws IllegalArgumentException if parameter key is null    
     */
    public Scope getScopeLevel(ScopeLevel scopeLevel)
    {
       if (scopeLevel == null)
          throw new IllegalArgumentException("Null scope level");
-
+      
       return scopes.get(scopeLevel);
    }
    
@@ -290,6 +345,9 @@
       if (frozen)
          throw new IllegalStateException("The scope key is frozen");
 
+      if (scopes == EMPTY_SCOPES)
+         return null;
+      
       Scope result = scopes.remove(scopeLevel);
       if (scopeLevel.equals(maxScopeLevel))
       {
@@ -311,22 +369,29 @@
          return true;
       if (object == null || object instanceof ScopeKey == false)
          return false;
-      
       ScopeKey other = (ScopeKey) object;
-      return scopes.equals(other.scopes);
+      if (other instanceof UnmodifiableScopeKey)
+         return other.equals(this);
+      else
+         return scopes.equals(other.scopes);
    }
-   
+
    public int hashCode()
    {
-      return scopes.hashCode();
+      return computeHashCode(scopes.values());  
    }
 
+   /**
+    * Clone a ScopeKey instance.
+    *
+    * @return an unfrozen instance (even if the current instance is frozen).
+    */
    public ScopeKey clone()
    {
       try
       {
          ScopeKey result = (ScopeKey) super.clone();
-         result.scopes = Collections.synchronizedSortedMap(new TreeMap<ScopeLevel, Scope>(scopes));
+         result.scopes = new ConcurrentSkipListMap<ScopeLevel, Scope>(scopes);
          result.frozen = false;
          return result;
       }
@@ -335,4 +400,81 @@
          throw new Error(e);
       }
    }
+
+   protected Scope[] getArray()
+   {
+      Collection<Scope> scopes = getScopes();
+      return scopes.toArray(new Scope[0]);
+   }
+
+   protected Collection<Scope> getScopesCollection()
+   {
+      return scopes.values();
+   }
+   
+   protected static int computeHashCode(Scope[] scopeArray)
+   {
+      return computeHashCode(Arrays.asList(scopeArray));
+   }
+
+   protected static int computeHashCode(Iterable<Scope> scopeCollection)
+   {
+      int hashCode = 0;
+      for (Scope scope : scopeCollection)
+         hashCode += scope.hashCode();
+      return hashCode;
+   }
+   
+   private final static class UnmodifiableConcurrentSkipListMap<K, V> extends ConcurrentSkipListMap<K, V>
+   {
+      private static final long serialVersionUID = 1L;
+
+      @Override
+      public void clear()
+      {
+         throw new UnsupportedOperationException();
+      }
+
+      @Override
+      public V put(K key, V value)
+      {
+         throw new UnsupportedOperationException();
+      }
+
+      @Override
+      public V putIfAbsent(K key, V value)
+      {
+         throw new UnsupportedOperationException();
+      }
+
+      @Override
+      public boolean remove(Object key, Object value)
+      {
+         throw new UnsupportedOperationException();
+      }
+
+      @Override
+      public V remove(Object key)
+      {
+         throw new UnsupportedOperationException();
+      }
+
+      @Override
+      public boolean replace(K key, V oldValue, V newValue)
+      {
+         throw new UnsupportedOperationException();
+      }
+
+      @Override
+      public V replace(K key, V value)
+      {
+         throw new UnsupportedOperationException();
+      }
+
+      @Override
+      public void putAll(Map<? extends K, ? extends V> m)
+      {
+         throw new UnsupportedOperationException();
+      }
+   }
 }

Modified: projects/jboss-mdr/branches/2.0.2.GA_JBPAPP-4220/src/test/java/org/jboss/test/metadata/loader/reflection/test/AnnotatedElementMetadataLoaderTestCase.java
===================================================================
--- projects/jboss-mdr/branches/2.0.2.GA_JBPAPP-4220/src/test/java/org/jboss/test/metadata/loader/reflection/test/AnnotatedElementMetadataLoaderTestCase.java	2010-05-10 22:42:17 UTC (rev 104638)
+++ projects/jboss-mdr/branches/2.0.2.GA_JBPAPP-4220/src/test/java/org/jboss/test/metadata/loader/reflection/test/AnnotatedElementMetadataLoaderTestCase.java	2010-05-10 22:46:43 UTC (rev 104639)
@@ -22,19 +22,21 @@
 
 package org.jboss.test.metadata.loader.reflection.test;
 
-import java.lang.annotation.Annotation;
-import java.lang.reflect.Method;
-
 import org.jboss.metadata.plugins.loader.reflection.AnnotatedElementMetaDataLoader;
 import org.jboss.metadata.spi.MetaData;
 import org.jboss.metadata.spi.retrieval.MetaDataRetrieval;
 import org.jboss.metadata.spi.retrieval.MetaDataRetrievalToMetaDataBridge;
 import org.jboss.metadata.spi.signature.DeclaredMethodSignature;
 import org.jboss.metadata.spi.signature.MethodSignature;
+import org.jboss.metadata.spi.signature.Signature;
 import org.jboss.test.metadata.AbstractMetaDataTest;
+import org.jboss.test.metadata.loader.reflection.support.BridgeMethodBean;
 import org.jboss.test.metadata.loader.reflection.support.MethodBean;
 import org.jboss.test.metadata.loader.reflection.support.NoAnnotationBean;
 
+import java.lang.annotation.Annotation;
+import java.lang.reflect.Method;
+
 /**
  * AnnotatedElementMetadataLoaderTestCase
  *
@@ -134,4 +136,50 @@
       Annotation[] annotationsOnMethodWithTwoAnnotations = anotherMetadata.getAnnotations();
       assertTrue("Expected two annotations on testAnnotation12 method of " + MethodBean.class, annotationsOnMethodWithTwoAnnotations.length == 2);
    }
+   
+   /**
+    * Tests that the {@link AnnotatedElementMetaDataLoader} correctly identifies
+    * bridge methods.
+    */
+   public void testMethodLevelAnnotationOnBridgeMethod() throws Exception
+   {
+      AnnotatedElementMetaDataLoader annotatedElementLoader = new AnnotatedElementMetaDataLoader(BridgeMethodBean.class);
+
+      Method method = BridgeMethodBean.class.getMethod("unambiguous", Object.class);
+      assertTrue(method.isBridge());
+      MethodSignature methodSignature = new MethodSignature(method);
+      MetaDataRetrieval retrieval = annotatedElementLoader.getComponentMetaDataRetrieval(methodSignature);
+      assertNotNull("Expected a MetaDataRetrieval for method " + method, retrieval);
+      MetaData metadata = new MetaDataRetrievalToMetaDataBridge(retrieval);
+      Annotation[] annotations = metadata.getAnnotations();
+      assertTrue("Expected one annotation on unambiguous method of " + BridgeMethodBean.class, annotations.length == 1);
+
+      method = BridgeMethodBean.class.getMethod("ambiguous", Object.class);
+      assertTrue(method.isBridge());
+      methodSignature = new MethodSignature(method);
+      assertNull(annotatedElementLoader.getComponentMetaDataRetrieval(methodSignature));
+   }
+
+   /**
+    * Tests that the {@link AnnotatedElementMetaDataLoader} correctly identifies
+    * bridge methods.
+    */
+   public void testMethodLevelAnnotationOnDeclaredBridgeMethod() throws Exception
+   {
+      AnnotatedElementMetaDataLoader annotatedElementLoader = new AnnotatedElementMetaDataLoader(BridgeMethodBean.class);
+
+      Method method = BridgeMethodBean.class.getMethod("unambiguous", Object.class);
+      assertTrue(method.isBridge());
+      Signature methodSignature = new DeclaredMethodSignature(method);
+      MetaDataRetrieval retrieval = annotatedElementLoader.getComponentMetaDataRetrieval(methodSignature);
+      assertNotNull("Expected a MetaDataRetrieval for method " + method, retrieval);
+      MetaData metadata = new MetaDataRetrievalToMetaDataBridge(retrieval);
+      Annotation[] annotations = metadata.getAnnotations();
+      assertTrue("Expected one annotation on unambiguous method of " + BridgeMethodBean.class, annotations.length == 1);
+
+      method = BridgeMethodBean.class.getMethod("ambiguous", Object.class);
+      assertTrue(method.isBridge());
+      methodSignature = new DeclaredMethodSignature(method);
+      assertNull(annotatedElementLoader.getComponentMetaDataRetrieval(methodSignature));
+   }
 }

Modified: projects/jboss-mdr/branches/2.0.2.GA_JBPAPP-4220/src/test/java/org/jboss/test/metadata/shared/ComponentBasicAnnotationsTest.java
===================================================================
--- projects/jboss-mdr/branches/2.0.2.GA_JBPAPP-4220/src/test/java/org/jboss/test/metadata/shared/ComponentBasicAnnotationsTest.java	2010-05-10 22:42:17 UTC (rev 104638)
+++ projects/jboss-mdr/branches/2.0.2.GA_JBPAPP-4220/src/test/java/org/jboss/test/metadata/shared/ComponentBasicAnnotationsTest.java	2010-05-10 22:46:43 UTC (rev 104639)
@@ -98,6 +98,7 @@
    protected void testEmpty(MetaData metaData) throws Exception
    {
       assertNotNull(metaData);
+      assertNotNull(metaData.getValidTime());
       ExpectedAnnotations expectedAnnotations = emptyExpectedAnnotations();
 
       assertNoAnnotation(metaData, NotPresentAnnotation.class);
@@ -199,6 +200,7 @@
       assertNoAnnotation(metaData, NotPresentAnnotation.class);
       
       expectedAnnotations.add(TestAnnotation1.class);
+
       expectedAnnotations.add(TestAnnotation2.class);
       assertAllAnnotations(metaData, expectedAnnotations, local);
    }




More information about the jboss-cvs-commits mailing list