You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@tomee.apache.org by Quintin Beukes <qu...@skywalk.co.za> on 2009/10/09 17:59:29 UTC
Re: OpenEJB Injection's findSetter Method
Here is the patch (made on rev. 823520 of the trunk):
https://issues.apache.org/jira/browse/OPENEJB-1081
Quintin Beukes
On Tue, Sep 29, 2009 at 9:46 AM, Quintin Beukes <qu...@skywalk.co.za> wrote:
> Hey,
>
> What I meant with the abstract check was to ask if it will ever match
> against an abstract method? I've been trying to think, and is it
> possible to have an instance of an abstract class? Or in which
> scenario would you ever match against an abstract method? I was
> thinking it might be possible to do so when injection should happen on
> a static variable in an abstract class. Because it's impossible to get
> an instance to an abstract class. Just out of curiosity - I assume
> there is some way it will match.
>
> Secondly.
> NP. Will send a patch. Mostly sent the mail to see you guys are
> interested in it. Otherwise there is no point to it.
>
> Quintin Beukes
>
>
>
> On Tue, Sep 29, 2009 at 3:33 AM, David Blevins <da...@visi.com> wrote:
>> 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
>>>
>>
>>
>