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
>>>
>>
>>
>