You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cayenne.apache.org by aa...@apache.org on 2013/06/28 03:37:30 UTC

svn commit: r1497631 - in /cayenne/main/trunk: docs/doc/src/main/resources/ framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/map/ framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/reflect/

Author: aadamchik
Date: Fri Jun 28 01:37:30 2013
New Revision: 1497631

URL: http://svn.apache.org/r1497631
Log:
CAY-1559  Use Lifecycle Annotations as markers on PersistentObject methods

patch by Mike M Pestorich, that I reworked a bit for 3.2 compatibility and naming (and minor optimizations)

Modified:
    cayenne/main/trunk/docs/doc/src/main/resources/RELEASE-NOTES.txt
    cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/map/EntityResolver.java
    cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/reflect/LifecycleCallbackRegistry.java

Modified: cayenne/main/trunk/docs/doc/src/main/resources/RELEASE-NOTES.txt
URL: http://svn.apache.org/viewvc/cayenne/main/trunk/docs/doc/src/main/resources/RELEASE-NOTES.txt?rev=1497631&r1=1497630&r2=1497631&view=diff
==============================================================================
--- cayenne/main/trunk/docs/doc/src/main/resources/RELEASE-NOTES.txt (original)
+++ cayenne/main/trunk/docs/doc/src/main/resources/RELEASE-NOTES.txt Fri Jun 28 01:37:30 2013
@@ -8,6 +8,14 @@ To browse individual bug reports check o
 https://issues.apache.org/jira/browse/CAY
 
 ----------------------------------
+Release: 3.2M2
+Date: 
+----------------------------------
+Changes/New Features:
+
+CAY-1559 Use Lifecycle Annotations as markers on PersistentObject methods 
+
+----------------------------------
 Release: 3.2M1
 Date: 
 ----------------------------------

Modified: cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/map/EntityResolver.java
URL: http://svn.apache.org/viewvc/cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/map/EntityResolver.java?rev=1497631&r1=1497630&r2=1497631&view=diff
==============================================================================
--- cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/map/EntityResolver.java (original)
+++ cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/map/EntityResolver.java Fri Jun 28 01:37:30 2013
@@ -219,6 +219,10 @@ public class EntityResolver implements M
                     }
                 }
 
+                // callbacks using annotations go first
+                callbackRegistry.addCallbacks(entityClass);
+
+                // callbacks mapped in the modeler follow
                 CallbackDescriptor[] callbacks = entity.getCallbackMap().getCallbacks();
                 for (CallbackDescriptor callback : callbacks) {
                     for (String method : callback.getCallbackMethods()) {

Modified: cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/reflect/LifecycleCallbackRegistry.java
URL: http://svn.apache.org/viewvc/cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/reflect/LifecycleCallbackRegistry.java?rev=1497631&r1=1497630&r2=1497631&view=diff
==============================================================================
--- cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/reflect/LifecycleCallbackRegistry.java (original)
+++ cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/reflect/LifecycleCallbackRegistry.java Fri Jun 28 01:37:30 2013
@@ -55,6 +55,7 @@ public class LifecycleCallbackRegistry {
     private LifecycleCallbackEventHandler[] eventCallbacks;
     private Map<String, AnnotationReader> annotationsMap;
     private Map<String, Collection<Class<?>>> entitiesByAnnotation;
+    private Map<Class<?>, Boolean> processedEntityClasses;
 
     /**
      * Creates an empty callback registry.
@@ -73,6 +74,11 @@ public class LifecycleCallbackRegistry {
 
         // other "static" lookup maps are initialized on-demand
         this.entitiesByAnnotation = new ConcurrentHashMap<String, Collection<Class<?>>>();
+        this.processedEntityClasses = new ConcurrentHashMap<Class<?>, Boolean>();
+
+        // prepopulating the map so that class hierarchy traversal could
+        // terminate when it reaches Object.
+        processedEntityClasses.put(Object.class, true);
     }
 
     /**
@@ -158,6 +164,52 @@ public class LifecycleCallbackRegistry {
     }
 
     /**
+     * Registers annotated methods of the entity class as callbacks for entity
+     * events.
+     * 
+     * @since 3.2
+     */
+    public void addCallbacks(Class<?> entityClass) {
+        if (entityClass == null) {
+            throw new NullPointerException("Null entity class");
+        }
+
+        // Only process Persistent Objects
+        if (!Persistent.class.isAssignableFrom(entityClass)) {
+            throw new CayenneRuntimeException("Class not assignable from Entity");
+        }
+
+        while (entityClass != null && processedEntityClasses.put(entityClass, true) == null) {
+
+            for (Method m : entityClass.getDeclaredMethods()) {
+                for (Annotation a : m.getAnnotations()) {
+                    AnnotationReader reader = this.getAnnotationsMap().get(a.annotationType().getName());
+                    if (reader != null) {
+
+                        // Only register lifecycle annotations used as markers
+                        // (both entities and entityAnnotations must be empty)
+                        if (reader.entities(a).length > 0) {
+                            throw new CayenneRuntimeException(
+                                    "Entity listener annotation should not contain 'entities': " + m.getName());
+                        }
+
+                        if (reader.entityAnnotations(a).length > 0) {
+                            throw new CayenneRuntimeException(
+                                    "Entity listener annotation should not contain 'entityAnnotations': " + m.getName());
+                        }
+
+                        this.eventCallbacks[reader.eventType().ordinal()].addListener(entityClass, m.getName());
+
+                    }
+                }
+            }
+
+            entityClass = entityClass.getSuperclass();
+        }
+
+    }
+
+    /**
      * Adds a listener, mapping its methods to events based on annotations.
      * 
      * @since 3.1