[jboss-cvs] JBossAS SVN: r77851 - in projects/metadata/trunk/src: test/java/org/jboss/test/metadata/javaee and 1 other directory.

jboss-cvs-commits at lists.jboss.org jboss-cvs-commits at lists.jboss.org
Wed Sep 3 11:22:28 EDT 2008


Author: alex.loubyansky at jboss.com
Date: 2008-09-03 11:22:28 -0400 (Wed, 03 Sep 2008)
New Revision: 77851

Added:
   projects/metadata/trunk/src/test/java/org/jboss/test/metadata/javaee/OrderCallbacksUnitTestCase.java
Modified:
   projects/metadata/trunk/src/main/java/org/jboss/metadata/javaee/spec/LifecycleCallbacksMetaData.java
Log:
JBMETA-101

Modified: projects/metadata/trunk/src/main/java/org/jboss/metadata/javaee/spec/LifecycleCallbacksMetaData.java
===================================================================
--- projects/metadata/trunk/src/main/java/org/jboss/metadata/javaee/spec/LifecycleCallbacksMetaData.java	2008-09-03 14:44:32 UTC (rev 77850)
+++ projects/metadata/trunk/src/main/java/org/jboss/metadata/javaee/spec/LifecycleCallbacksMetaData.java	2008-09-03 15:22:28 UTC (rev 77851)
@@ -21,7 +21,13 @@
 */
 package org.jboss.metadata.javaee.spec;
 
+import java.lang.reflect.Method;
 import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Set;
 
 /**
  * LifecycleCallbacksMetaData.
@@ -41,4 +47,77 @@
    {
       // For serialization
    }
+
+   /**
+    * Return a list of the post construct callbacks ordered according to the spec rules defined in
+    * 12.4.1 Multiple Callback Interceptor Methods for a Life Cycle Callback Event.
+    * 
+    * @param defaultClass
+    * @return
+    */
+   public List<Method> getOrderedCallbacks(Class<?> defaultClass)
+   {
+      if(isEmpty())
+         return Collections.emptyList();
+
+      Class<?> parameterTypes[] = new Class[0];
+      ClassLoader cl = Thread.currentThread().getContextClassLoader();
+      String className = null;
+      String methodName = null;
+
+      try
+      {
+         Set<Class<?>> callbacksSet = new HashSet<Class<?>>();
+         LinkedList<Method> methods = new LinkedList<Method>();
+         for (LifecycleCallbackMetaData callback : this)
+         {
+            className = callback.getClassName();
+            methodName = callback.getMethodName();
+            Class<?> lifecycleClass = className == null ? defaultClass : cl.loadClass(className);
+
+            // If we haven't yet added the callback for this class
+            if (callbacksSet.add(lifecycleClass))
+            {
+               Method method = lifecycleClass.getDeclaredMethod(methodName, parameterTypes);
+
+               boolean added = false;
+               for (int i = 0; i < methods.size(); ++i)
+               {
+                  Method m = methods.get(i);
+                  Class<?> methodClass = m.getDeclaringClass();
+                  // insert the class before the current class in the list if the class is a superclass of the current class
+                  if (lifecycleClass.isAssignableFrom(methodClass))
+                  {
+                     methods.add(i, method);
+                     added = true;
+                     break;
+                  }
+                  // insert the class before the current class in the list
+                  // if the class is not a subclass of the current class and
+                  // it is a superclass of the default class or the default class itself 
+                  else if(!methodClass.isAssignableFrom(lifecycleClass) &&
+                        (lifecycleClass == defaultClass || lifecycleClass.isAssignableFrom(defaultClass)))
+                  {
+                     methods.add(i, method);
+                     added = true;
+                     break;
+                  }
+               }
+
+               if (!added)
+                  methods.add(method);
+            }
+         }
+         
+         return methods;
+      }
+      catch (ClassNotFoundException e)
+      {
+         throw new IllegalStateException("Failed to load class for callback method " + methodName + ": " + className, e);
+      }
+      catch (NoSuchMethodException e)
+      {
+         throw new IllegalStateException("Failed to get callback method in class " + className + ": " + methodName, e);
+      }
+   }
 }

Added: projects/metadata/trunk/src/test/java/org/jboss/test/metadata/javaee/OrderCallbacksUnitTestCase.java
===================================================================
--- projects/metadata/trunk/src/test/java/org/jboss/test/metadata/javaee/OrderCallbacksUnitTestCase.java	                        (rev 0)
+++ projects/metadata/trunk/src/test/java/org/jboss/test/metadata/javaee/OrderCallbacksUnitTestCase.java	2008-09-03 15:22:28 UTC (rev 77851)
@@ -0,0 +1,190 @@
+/*
+  * JBoss, Home of Professional Open Source
+  * Copyright 2005, JBoss Inc., and individual contributors as indicated
+  * by the @authors tag. See the copyright.txt in the distribution for a
+  * full listing of individual contributors.
+  *
+  * This is free software; you can redistribute it and/or modify it
+  * under the terms of the GNU Lesser General Public License as
+  * published by the Free Software Foundation; either version 2.1 of
+  * the License, or (at your option) any later version.
+  *
+  * This software is distributed in the hope that it will be useful,
+  * but WITHOUT ANY WARRANTY; without even the implied warranty of
+  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+  * Lesser General Public License for more details.
+  *
+  * You should have received a copy of the GNU Lesser General Public
+  * License along with this software; if not, write to the Free
+  * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+  * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+  */
+package org.jboss.test.metadata.javaee;
+
+import java.lang.reflect.Method;
+import java.util.List;
+
+import org.jboss.metadata.javaee.spec.LifecycleCallbackMetaData;
+import org.jboss.metadata.javaee.spec.LifecycleCallbacksMetaData;
+
+import junit.framework.TestCase;
+
+/**
+ * A OrderCallbacksUnitTestCase.
+ * 
+ * @author <a href="alex at jboss.com">Alexey Loubyansky</a>
+ * @version $Revision: 1.1 $
+ */
+public class OrderCallbacksUnitTestCase extends TestCase
+{
+   public void testOrder() throws Exception
+   {
+      LifecycleCallbacksMetaData callbacks = new LifecycleCallbacksMetaData();      
+      LifecycleCallbackMetaData callback;
+
+      callback = new LifecycleCallbackMetaData();
+      callback.setClassName(DefaultSuperSuperClass.class.getName());
+      callback.setMethodName("superSuperClassCallback");
+      callbacks.add(callback);
+
+      callback = new LifecycleCallbackMetaData();
+      callback.setClassName(DefaultSuperClass.class.getName());
+      callback.setMethodName("superClassCallback");
+      callbacks.add(callback);
+      
+      callback = new LifecycleCallbackMetaData();
+      callback.setMethodName("callback");
+      callbacks.add(callback);
+
+      callback = new LifecycleCallbackMetaData();
+      callback.setClassName(DefaultSubclass.class.getName());
+      callback.setMethodName("subclassCallback");
+      callbacks.add(callback);
+
+      callback = new LifecycleCallbackMetaData();
+      callback.setClassName(DefaultSubsubclass.class.getName());
+      callback.setMethodName("subsubclassCallback");
+      callbacks.add(callback);
+
+      callback = new LifecycleCallbackMetaData();
+      callback.setClassName(CallbackInterceptorSuperClass.class.getName());
+      callback.setMethodName("superClassCallback");
+      callbacks.add(callback);
+
+      callback = new LifecycleCallbackMetaData();
+      callback.setClassName(CallbackInterceptorClass1.class.getName());
+      callback.setMethodName("callback");
+      callbacks.add(callback);
+
+      callback = new LifecycleCallbackMetaData();
+      callback.setClassName(CallbackInterceptorClass2.class.getName());
+      callback.setMethodName("callback");
+      callbacks.add(callback);
+
+      // test it a few times
+      for(int i = 0; i < 10; ++i)
+         shuffleAndOrder(callbacks);
+   }
+
+   private void shuffleAndOrder(LifecycleCallbacksMetaData callbacks)
+   {
+      // shuffle the list
+      java.util.Collections.shuffle(callbacks);
+      
+      // make sure all the callbacks are added
+      assertEquals(8, callbacks.size());
+
+      // get the ordered list
+      List<Method> ordered = callbacks.getOrderedCallbacks(DefaultClass.class);
+      assertNotNull(ordered);
+      assertEquals(8, ordered.size());
+      
+      int i = 0;
+      Method method;
+      
+      // default class and its superclasses are first
+      method = ordered.get(i++);
+      assertNotNull(method);
+      assertEquals(DefaultSuperSuperClass.class, method.getDeclaringClass());
+
+      method = ordered.get(i++);
+      assertNotNull(method);
+      assertEquals(DefaultSuperClass.class, method.getDeclaringClass());
+
+      method = ordered.get(i++);
+      assertNotNull(method);
+      assertEquals(DefaultClass.class, method.getDeclaringClass());
+
+      // now check that superclasses don't appear before their subclasses
+      boolean sawDefaultSubclass = false;
+      boolean sawCallbackInterceptorSuperclass = false;
+      for(;i < ordered.size(); ++i)
+      {
+         method = ordered.get(i);
+         Class<?> callbackClass = method.getDeclaringClass();
+         if(DefaultSubclass.class.equals(callbackClass))
+            sawDefaultSubclass = true;
+         else if(DefaultSubsubclass.class.equals(callbackClass))
+         {
+            if(!sawDefaultSubclass)
+               fail(DefaultSubsubclass.class.getName() + " appeared before " + DefaultSubclass.class.getName());
+         }
+         else if(CallbackInterceptorSuperClass.class.equals(callbackClass))
+            sawCallbackInterceptorSuperclass = true;
+         else if(!sawCallbackInterceptorSuperclass)
+            fail(method.getDeclaringClass().getName() + " appeared before " + CallbackInterceptorSuperClass.class.getName());
+      }
+   }
+
+   private String listContents(LifecycleCallbacksMetaData callbacks, List<Method> methods)
+   {
+      StringBuffer sb = new StringBuffer();
+      sb.append("lifecycle callbaacks:\n");
+      for(LifecycleCallbackMetaData c : callbacks)
+         sb.append(c.getClassName()).append('\n');
+      sb.append("\nmethods:\n");
+      for(Method m : methods)
+         sb.append(m.getDeclaringClass().getName()).append('\n');
+      return sb.toString();
+   }
+   
+   public static class DefaultSuperSuperClass
+   {
+      public void superSuperClassCallback() {}
+   }
+
+   public static class DefaultSuperClass extends DefaultSuperSuperClass
+   {
+      public void superClassCallback() {}
+   }
+   
+   public static class DefaultClass extends DefaultSuperClass
+   {
+      public void callback() {}
+   }
+   
+   public static class DefaultSubclass extends DefaultClass
+   {
+      public void subclassCallback() {}
+   }
+
+   public static class DefaultSubsubclass extends DefaultSubclass
+   {
+      public void subsubclassCallback() {}
+   }
+
+   public static class CallbackInterceptorSuperClass
+   {
+      public void superClassCallback() {}
+   }
+
+   public static class CallbackInterceptorClass1 extends CallbackInterceptorSuperClass
+   {
+      public void callback() {}
+   }
+
+   public static class CallbackInterceptorClass2 extends CallbackInterceptorSuperClass
+   {
+      public void callback() {}
+   }
+}




More information about the jboss-cvs-commits mailing list