Allow callback methods to accept the Entity subclass of the type they are listening on, rather than forcing them to all take an argument of type java.lang.Object (section 3.5.1)

git-svn-id: https://svn.apache.org/repos/asf/incubator/openjpa/trunk@443509 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Marc Prud'hommeaux 2006-09-14 23:06:11 +00:00
parent 7846adbf3f
commit c6c683e8ac
5 changed files with 46 additions and 7 deletions

View File

@ -38,9 +38,10 @@ public class BeanLifecycleCallbacks
*
* @arg whether another argunent is expected such as AfterDetach
*/
public BeanLifecycleCallbacks(Class cls, String method, boolean arg) {
public BeanLifecycleCallbacks(Class cls, String method, boolean arg,
Class type) {
this(cls, getMethod(cls, method, arg ? new Class[]{ Object.class,
Object.class } : new Class[]{ Object.class }), arg);
type } : new Class[]{ type }), arg);
}
/**

View File

@ -16,6 +16,7 @@
package org.apache.openjpa.event;
import java.lang.reflect.Method;
import java.util.Arrays;
import org.apache.openjpa.lib.util.Localizer;
import org.apache.openjpa.util.UserException;
@ -92,7 +93,14 @@ public class MethodLifecycleCallbacks
*/
protected static Method getMethod(Class cls, String method, Class[] args) {
try {
return cls.getMethod(method, args);
Method[] methods = cls.getMethods();
for (int i = 0; i < methods.length; i++) {
if (!method.equals(methods[i].getName()))
continue;
if (isAssignable(methods[i].getParameterTypes(), args))
return methods[i];
}
} catch (Throwable t) {
try {
// try again with the declared methods, which will
@ -103,8 +111,32 @@ public class MethodLifecycleCallbacks
return m;
} catch (Throwable t2) {
throw new UserException(_loc.get("method-notfound",
cls.getName(), method), t);
cls.getName(), method,
args == null ? null : Arrays.asList(args)), t);
}
}
throw new UserException(_loc.get("method-notfound",
cls.getName(), method,
args == null ? null : Arrays.asList(args)));
}
/**
* Returns true if all parameters in the from array are assignable
* from the corresponding parameters of the to array.
*/
private static boolean isAssignable(Class[] from, Class[] to) {
if (from == null)
return to == null;
if (from.length != to.length)
return false;
for (int i = 0; i < from.length; i++) {
if (from[i] == null || !from[i].isAssignableFrom(to[i]))
return false;
}
return true;
}
}

View File

@ -205,7 +205,7 @@ class InterfaceImplGenerator {
return true;
try {
Method meth = iface.getDeclaredMethod("is" + StringUtils.capitalize
(fmd.getName()), null);
(fmd.getName()), (Class[]) null);
return meth == null;
} catch (NoSuchMethodException e) {}
return true;

View File

@ -75,4 +75,5 @@ tcp-close-pool-error: Exception thrown while closing connection pool.
tcp-wrong-version-error: Received packet from "{0}" with invalid version \
number. Check if a prior release of OpenJPA is being used on this host.
bean-constructor: Could not instantiate class {0}.
method-notfound: Method "{1}" not found in class "{0}".
method-notfound: Method "{1}" with arguments of type: {2} \
not found in class "{0}".

View File

@ -1528,6 +1528,11 @@ public class XMLPersistenceMetaDataParser
return false;
boolean system = currentElement() == null;
Class type = currentElement() == null ? null :
((ClassMetaData) currentElement()).getDescribedType();
if (type == null)
type = Object.class;
if (_callbacks == null) {
_callbacks = (Collection<LifecycleCallbacks>[])
new Collection[LifecycleEvent.ALL_EVENTS.length];
@ -1538,7 +1543,7 @@ public class XMLPersistenceMetaDataParser
LifecycleCallbacks adapter;
if (_listener != null)
adapter = new BeanLifecycleCallbacks(_listener,
attrs.getValue("method-name"), false);
attrs.getValue("method-name"), false, type);
else
adapter = new MethodLifecycleCallbacks(_cls,
attrs.getValue("method-name"), false);