Author: ppoddar
Date: Tue Sep 26 12:23:48 2006
New Revision: 450158

URL: http://svn.apache.org/viewvc?view=rev&rev=450158
Log:
Applying the constraints that the entity listner class 
a) must have a no-arg constructor 
b) multiple methods of the same class must not register for the same event 
(JPA Spec Section 3.5)  


Modified:
    
incubator/openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/meta/AbstractMetaDataDefaults.java
    
incubator/openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/meta/MetaDataDefaults.java
    
incubator/openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/meta/NoneMetaDataFactory.java
    
incubator/openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/AnnotationPersistenceMetaDataParser.java
    
incubator/openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/XMLPersistenceMetaDataParser.java
    
incubator/openjpa/trunk/openjpa-persistence/src/main/resources/org/apache/openjpa/persistence/localizer.properties

Modified: 
incubator/openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/meta/AbstractMetaDataDefaults.java
URL: 
http://svn.apache.org/viewvc/incubator/openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/meta/AbstractMetaDataDefaults.java?view=diff&rev=450158&r1=450157&r2=450158
==============================================================================
--- 
incubator/openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/meta/AbstractMetaDataDefaults.java
 (original)
+++ 
incubator/openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/meta/AbstractMetaDataDefaults.java
 Tue Sep 26 12:23:48 2006
@@ -45,6 +45,8 @@
     private boolean _interface = true;
     private boolean _pcRegistry = true;
     private int _callback = CALLBACK_RETHROW;
+    private boolean _allowsMultipleMethodsOnSameCallback = true;
+    private boolean _allowsMissingCallbackConstructor = true;
 
     /**
      * Whether to attempt to use the information from registered classes
@@ -352,6 +354,22 @@
         return UnsupportedOperationException.class;
     }
 
+    public boolean getAllowsMultipleMethodsOnSameCallback() {
+        return _allowsMultipleMethodsOnSameCallback;
+    }
+    
+    public void setAllowsMultipleMethodsOnSameCallback(boolean flag) {
+        _allowsMultipleMethodsOnSameCallback = flag;
+    }
+    
+    public boolean getAllowsMissingCallbackConstructor() {
+        return _allowsMissingCallbackConstructor;
+    }
+    
+    public void setAllowsMissingCallbackConstructor(boolean flag) {
+        _allowsMissingCallbackConstructor = flag;
+    }
+    
     /**
      * Helper method; returns true if the given class appears to be
      * user-defined.

Modified: 
incubator/openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/meta/MetaDataDefaults.java
URL: 
http://svn.apache.org/viewvc/incubator/openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/meta/MetaDataDefaults.java?view=diff&rev=450158&r1=450157&r2=450158
==============================================================================
--- 
incubator/openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/meta/MetaDataDefaults.java
 (original)
+++ 
incubator/openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/meta/MetaDataDefaults.java
 Tue Sep 26 12:23:48 2006
@@ -49,7 +49,17 @@
      * event type. Defaults to false.
      */
     public boolean getCallbacksBeforeListeners(int type);
+    
+    /** Flags if multiple methods of the same class can handle the same 
+     * callback event.
+     */
+    public boolean getAllowsMultipleMethodsOnSameCallback();
 
+    /** Flags if it allowed for the callback listener class not to have a 
no-arg 
+     * constructor.
+     */
+    public boolean getAllowsMissingCallbackConstructor();
+    
     /**
      * Whether to ignore members which are not persistent by default
      * during metadata population. Defaults to true.

Modified: 
incubator/openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/meta/NoneMetaDataFactory.java
URL: 
http://svn.apache.org/viewvc/incubator/openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/meta/NoneMetaDataFactory.java?view=diff&rev=450158&r1=450157&r2=450158
==============================================================================
--- 
incubator/openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/meta/NoneMetaDataFactory.java
 (original)
+++ 
incubator/openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/meta/NoneMetaDataFactory.java
 Tue Sep 26 12:23:48 2006
@@ -122,4 +122,12 @@
     public Class getUnimplementedExceptionType() {
         return null;
     }
+    
+    public boolean getAllowsMultipleMethodsOnSameCallback() {
+        return true;
+    }
+    
+    public boolean getAllowsMissingCallbackConstructor() {
+        return true;
+    }
 }

Modified: 
incubator/openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/AnnotationPersistenceMetaDataParser.java
URL: 
http://svn.apache.org/viewvc/incubator/openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/AnnotationPersistenceMetaDataParser.java?view=diff&rev=450158&r1=450157&r2=450158
==============================================================================
--- 
incubator/openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/AnnotationPersistenceMetaDataParser.java
 (original)
+++ 
incubator/openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/AnnotationPersistenceMetaDataParser.java
 Tue Sep 26 12:23:48 2006
@@ -84,6 +84,7 @@
 import org.apache.openjpa.lib.conf.Configurations;
 import org.apache.openjpa.lib.log.Log;
 import org.apache.openjpa.lib.util.Localizer;
+import org.apache.openjpa.lib.util.Localizer.Message;
 import org.apache.openjpa.meta.ClassMetaData;
 import org.apache.openjpa.meta.DelegatingMetaDataFactory;
 import org.apache.openjpa.meta.FieldMetaData;
@@ -98,12 +99,13 @@
 import org.apache.openjpa.meta.UpdateStrategies;
 import org.apache.openjpa.meta.ValueMetaData;
 import org.apache.openjpa.meta.ValueStrategies;
+import org.apache.openjpa.meta.MetaDataDefaults;
 import static org.apache.openjpa.persistence.MetaDataTag.*;
-import static org.apache.openjpa.persistence.MetaDataTag.LRS;
 import org.apache.openjpa.util.ImplHelper;
 import org.apache.openjpa.util.InternalException;
 import org.apache.openjpa.util.MetaDataException;
 import org.apache.openjpa.util.UnsupportedException;
+import org.apache.openjpa.util.UserException;
 import serp.util.Numbers;
 import serp.util.Strings;
 
@@ -769,7 +771,7 @@
      * @param sups whether to scan superclasses
      * @param listener whether this is a listener or not
      */
-    public static Collection<LifecycleCallbacks>[] parseCallbackMethods
+    public Collection<LifecycleCallbacks>[] parseCallbackMethods
         (Class cls, Collection<LifecycleCallbacks>[] callbacks, boolean sups,
             boolean listener) {
         // first sort / filter based on inheritance
@@ -813,9 +815,15 @@
 
                 for (int i = 0; events != null && i < events.length; i++) {
                     int e = events[i];
-                    if (callbacks[e] == null)
-                        callbacks[e] = new ArrayList(3);
+                    if (!verifyHasNoArgConstructor(cls))
+                        continue; 
+                    if (!verifyMultipleMethodsOnSameEvent(cls, callbacks[e], 
m, 
+                        tag))
+                        continue;
 
+                    if (callbacks[e] == null)
+                        callbacks[e] = new ArrayList(3);                   
+                    
                     if (listener) {
                         callbacks[e].add(new BeanLifecycleCallbacks(cls, m,
                             false));
@@ -829,6 +837,51 @@
         return callbacks;
     }
 
+    private boolean verifyMultipleMethodsOnSameEvent(Class cls, 
+            Collection<LifecycleCallbacks> callbacks, Method method, 
+            MetaDataTag tag) {
+        boolean result = true;
+        if (callbacks == null || callbacks.isEmpty())
+            return true;
+        MetaDataDefaults defaults = getRepository().getMetaDataFactory().
+            getDefaults();
+        for (LifecycleCallbacks lc: callbacks) {
+            if (!(lc instanceof MethodLifecycleCallbacks))
+                continue;
+            Method exists = ((MethodLifecycleCallbacks)lc).getCallbackMethod();
+            if (exists.getDeclaringClass().equals(method.getDeclaringClass())) 
{
+                result = false;
+                Object[] args = new Object[]{method.getDeclaringClass()
+                    .getName(), method.getName(), exists.getName(), 
+                    tag.toString()};
+                if (defaults.getAllowsMultipleMethodsOnSameCallback()) {
+                    _log.warn(_loc.get("multiple-methods-on-callback", 
+                        args));
+                 } else {
+                    throw new UserException(
+                        _loc.get("multiple-methods-on-callback-error", args));
+                 }
+             }
+        }
+        return result;
+    }
+    
+    private boolean verifyHasNoArgConstructor(Class cls) {
+        MetaDataDefaults defaults = getRepository().getMetaDataFactory().
+            getDefaults();
+        try {
+            cls.getConstructor(new Class[]{});
+            return true;
+        } catch (Throwable t) {
+            Message msg = _loc.get("missing-no-arg-constructor", 
cls.getName());
+            if (defaults.getAllowsMissingCallbackConstructor())
+                _log.warn(msg);
+            else
+                throw new UserException(msg, t);
+        } 
+        return false;
+    }
+    
     /**
      * Store lifecycle metadata.
      */

Modified: 
incubator/openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/XMLPersistenceMetaDataParser.java
URL: 
http://svn.apache.org/viewvc/incubator/openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/XMLPersistenceMetaDataParser.java?view=diff&rev=450158&r1=450157&r2=450158
==============================================================================
--- 
incubator/openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/XMLPersistenceMetaDataParser.java
 (original)
+++ 
incubator/openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/XMLPersistenceMetaDataParser.java
 Tue Sep 26 12:23:48 2006
@@ -1485,9 +1485,9 @@
         throws SAXException {
         _listener = classForName(attrs.getValue("class"));
         boolean system = currentElement() == null;
-        Collection<LifecycleCallbacks>[] parsed =
-            AnnotationPersistenceMetaDataParser.parseCallbackMethods(_listener,
-                null, true, true);
+        Collection<LifecycleCallbacks>[] parsed = 
+            new AnnotationPersistenceMetaDataParser(_conf).parseCallbackMethods
+            (_listener, null, true, true);
         if (parsed == null)
             return true;
 
@@ -1593,8 +1593,8 @@
         Class supCls = cls.getDescribedType().getSuperclass();
         Collection<LifecycleCallbacks>[] supCalls = null;
         if (!Object.class.equals(supCls)) {
-            supCalls = AnnotationPersistenceMetaDataParser.parseCallbackMethods
-                (supCls, null, true, false);
+            supCalls = new AnnotationPersistenceMetaDataParser(_conf).
+                parseCallbackMethods(supCls, null, true, false);
         }
         if (supCalls != null) {
             for (int event : LifecycleEvent.ALL_EVENTS) {

Modified: 
incubator/openjpa/trunk/openjpa-persistence/src/main/resources/org/apache/openjpa/persistence/localizer.properties
URL: 
http://svn.apache.org/viewvc/incubator/openjpa/trunk/openjpa-persistence/src/main/resources/org/apache/openjpa/persistence/localizer.properties?view=diff&rev=450158&r1=450157&r2=450158
==============================================================================
--- 
incubator/openjpa/trunk/openjpa-persistence/src/main/resources/org/apache/openjpa/persistence/localizer.properties
 (original)
+++ 
incubator/openjpa/trunk/openjpa-persistence/src/main/resources/org/apache/openjpa/persistence/localizer.properties
 Tue Sep 26 12:23:48 2006
@@ -91,4 +91,12 @@
 system-listener-err: An error occurred invoking system entity listener \
        callback on instance "{0}".
 no-transaction: Cannot perform operation with no transaction.
-
+multiple-methods-on-callback: Class "{0}" declares method "{1}" as well \
+       as "{2}" for handling the same "{3}" callback. 
+multiple-methods-on-callback-error: Class "{0}" declares method "{1}" as well \
+       as "{2}" for handling the same "{3}" callback. \
+       "AllowsMultipleMethodsOnSameCallback" property of MetaDataDefaults can 
be \
+       set to true to supress this exception.
+missing-no-arg-constructor: Entity listener class "{0}" must declare a no-arg \
+       constructor. "AllowsNoArgConstructorCallback" property of 
MetaDataDefaults \
+       can be set to true to ignore this exception.      


Reply via email to