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 <[email protected]> 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 <[email protected]> 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 >>> >> >> >
