Responded on dev@
On Sep 28, 2009, at 3:37 AM, Quintin Beukes wrote:
Hey,
Re the class ./server/openejb-client/src/main/java/org/apache/
openejb/client/ClientInjectionProcessor.java
and method public Method findSetter(Class typeClass, String
propertyName, Object propertyValue);
I have 2 questions.
1. In which cases would the following match:
(Modifier.isAbstract(method.getModifiers()))
I would think it's never necessary to inject into an Abstract class,
as you can't get a container created instance? or does it so happen
that you inject into static variables of an non-instantiated abstract
class?
2. The findSetter method doesn't currently return the most specific
setter. If you were for instance to try inject a String field called
"myString", and you have 2 methods:
void setMyString(Object)
and
void setMyString(String)
OpenEJB would use the first.
I used this code in the junit-runner and modified it to find the more
specific setter. It's a simple check really. Before the loop define a
variable "Method mostSpecific = null;"
Then move this check so it's the last one: if
(!isInstance(methodParameterType, propertyValue) &&
!isConvertable(methodParameterType, propertyValue)) {
And add an "else" clause that does the following:
else if (methodParameterType != propertyValue.getClass())
{
if (mostSpecific == null)
{
mostSpecific = clazzMethod;
}
else
{
mostSpecific =
getMostSpecificMethod(unpreferredValidMethod, clazzMethod);
}
continue;
}
Then return "mostSpecific" instead of "null" at the end, because if
it's never been set, null will be returned, otherwise the most
specific would be returned.
And then the meat of the logic:
public static Method getMostSpecificMethod(Method method1, Method
method2)
{
Class<?> class1 = method1.getParameterTypes()[0];
Class<?> class2 = method2.getParameterTypes()[0];
if (class1.isAssignableFrom(class2))
{
return method2;
}
else
{
return method1;
}
}
What this does is check if the parameter is the exact type we're
looking for. If it is, then return that method. If it's NOT, then
store it till later. If there is already one store, picked the one
that has the supertype relation to the other.
You can see this in it's full implementation (though the findSetter
method was changed a bit to suite the junit-runner) in the class:
org.apache.openejb.junit.context.Util
Quintin Beukes