Hello, Tapestry hackers!
I know you are pushing for rc-1 now, but I'd like to suggest
one more thing that will make Tapestry even better :)
Some injected objects are only used in a class that declares the accessor
methods
but AnnotationEnhancementWorker only enhances public methods, so we're
forced to
declare them public:
@InjectObject("infrastructure:cookieSource")
public abstract CookieSource getCookieSource();
IMHO, this unnecessarily polutes the interface of a page class.
I think it would be useful to enhance protected (and package visible)
methods as well.
This would let us inject some objects "privately":
@InjectObject("infrastructure:cookieSource")
protected abstract CookieSource getCookieSource();
Should be simple to implement, huh? Nope..
I've tried to make a patch that adds support for protected accessor methods
to
AnnotationEnhancementWorker but it doesn't work :(
I gues the culprit is EnhancementOperationImpl class which uses java.beans
for
property introspection, and that handles only public methods.
Now I see two possible solutions:
- change all inject workers so that they use method.getReturnType() for
property type
or
- add some support for overriding property type in
EnhancementOperation(-Impl)
so that inject workers get proper property type (instead of null)
And these are the kind of changes I'm not very keen to make or suggest.
Maybe Howard or another Tapestry developper could think of a better
solution..
-- dpr
PS. Here's my attempted patch:
--- AnnotationEnhancementWorker.java 2005-10-30 17:26:08.000000000 +0200
+++ AnnotationEnhancementWorker.java.new 2005-12-04 18:47:53.000000000 +0200
@@ -16,7 +16,12 @@
import java.lang.annotation.Annotation;
import java.lang.reflect.Method;
+import java.lang.reflect.Modifier;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.HashSet;
import java.util.Map;
+import java.util.Set;
import org.apache.hivemind.ClassResolver;
import org.apache.hivemind.ErrorLog;
@@ -65,7 +70,7 @@
performClassEnhancement(op, spec, clazz, a, classResource);
}
- for (Method m : clazz.getMethods())
+ for (Method m : getMethods(clazz))
{
performMethodEnhancement(op, spec, m, classResource);
}
@@ -76,6 +81,49 @@
return new ClasspathResource(_classResolver,
clazz.getName().replace('.', '/'));
}
+ private Set<Method> getMethods(Class clazz)
+ {
+ Set<Method> methods = new HashSet<Method>();
+
+ Collections.addAll(methods, clazz.getMethods());
+
+ do
+ {
+ addProtectedMethods(methods, clazz);
+
+ clazz = clazz.getSuperclass();
+
+ } while (clazz != null);
+
+ return methods;
+ }
+
+ private static final int MODIFIER_FILTER = Modifier.PUBLIC |
Modifier.PRIVATE
+ | Modifier.STATIC | Modifier.FINAL | Modifier.NATIVE;
+
+ private void addProtectedMethods(Set<Method> methods, Class clazz)
+ {
+ for (Method m : clazz.getDeclaredMethods())
+ {
+ if ((m.getModifiers() & MODIFIER_FILTER) == 0)
+ addIfNotPresent(methods, m);
+ }
+ }
+
+ private void addIfNotPresent(Set<Method> methods, Method method)
+ {
+ for (Method m : methods)
+ {
+ if (!m.getName().equals(method.getName()))
+ continue;
+
+ if (Arrays.equals(m.getParameterTypes(),
method.getParameterTypes())
+ && m.getReturnType().equals(method.getReturnType()))
+ return;
+ }
+ methods.add(method);
+ }
+
void performClassEnhancement(EnhancementOperation op,
IComponentSpecification spec,
Class clazz, Annotation annotation, Resource classResource)
{
---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]