Hi,

I've got a start for a generified IVisitor implementation. Basically,
it would be used like this:

                // Visit all Forms contained in the page
                visitChildren(new Component.IVisitor<Form>()
                {
                        // For each FormComponent found on the Page (not Form)
                        public Object component(final Form form)
                        {
                                form.loadPersistentFormComponentValues();
                                return CONTINUE_TRAVERSAL;
                        }
                });


However, I'm kind of stuck at the dirty details of introspecting
parameterized types. It's probably doable, but pretty messy and
inefficient at times (to catch all cases, you'd have to implement a
recursive alg that searches for the proper type, with a lot of 'ifs').
I'm not sure it's worth it, also as it seems a bit like misusing
generics.

Anyway, if anyone likes to take a look: here's a patch. A couple of
unit test fail, and that's where the real fun begins :)

Eelco



Index: 
/Users/eelcohillenius/Documents/workspace/wicket/src/java/wicket/Component.java
===================================================================
--- 
/Users/eelcohillenius/Documents/workspace/wicket/src/java/wicket/Component.java 
    (revision
5923)
+++ 
/Users/eelcohillenius/Documents/workspace/wicket/src/java/wicket/Component.java 
    (working
copy)
@@ -271,11 +271,9 @@

        /**
         * Generic component visitor interface for component traversals.
-        *
-        * @param <T>
-        *            The type of the component where a visitor walks over.
+        * @param <E> The type of the component where a visitor walks over.
         */
-       public static interface IVisitor
+       public static interface IVisitor<E>
        {
                /**
                 * Value to return to continue a traversal.
@@ -303,7 +301,7 @@
                 *         should stop. If no return value is useful, the 
generic
                 *         non-null value STOP_TRAVERSAL can be used.
                 */
-               public Object component(Component component);
+               public Object component(E component);
        }

        /**
@@ -1717,12 +1715,12 @@
                                        // to
                                        // collect their messages before 
components like ListViews
                                        // remove any child components
-                                       
container.visitChildren(IFeedback.class, new IVisitor()
+                                       container.visitChildren(new 
IVisitor<IFeedback>()
                                        {
-                                               public Object 
component(Component component)
+                                               public Object 
component(IFeedback feedback)
                                                {
-                                                       
((IFeedback)component).updateFeedback();
-                                                       
component.internalAttach();
+                                                       
feedback.updateFeedback();
+                                                       
((Component)feedback).internalAttach();
                                                        return 
IVisitor.CONTINUE_TRAVERSAL;
                                                }
                                        });
Index: 
/Users/eelcohillenius/Documents/workspace/wicket/src/java/wicket/MarkupContainer.java
===================================================================
--- 
/Users/eelcohillenius/Documents/workspace/wicket/src/java/wicket/MarkupContainer.java
       (revision
5923)
+++ 
/Users/eelcohillenius/Documents/workspace/wicket/src/java/wicket/MarkupContainer.java
       (working
copy)
@@ -18,6 +18,8 @@
 */
package wicket;

+import java.lang.reflect.ParameterizedType;
+import java.lang.reflect.Type;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
@@ -644,9 +646,9 @@
                super.setModel(model);
                if (previous instanceof ICompoundModel)
                {
-                       visitChildren(new IVisitor()
+                       visitChildren(new IVisitor<Component<?>>()
                        {
-                               public Object component(Component component)
+                               public Object component(Component<?> component)
                                {
                                        IModel compModel = component.getModel();
                                        if (compModel == previous)
@@ -725,11 +727,9 @@
        }

        /**
-        * Traverses all child components of the given class in this container,
+        * Traverses all child components of the visitor's type in this 
container,
         * calling the visitor's visit method at each one.
         *
-        * @param clazz
-        *            The class of child to visit, or null to visit all children
         * @param visitor
         *            The visitor to call back to
         * @return The return value from a visitor which halted the traversal, 
or
@@ -735,7 +735,8 @@
         * @return The return value from a visitor which halted the traversal, 
or
         *         null if the entire traversal occurred
         */
-       public final Object visitChildren(final Class clazz, final IVisitor 
visitor)
+       @SuppressWarnings("unchecked")
+       public final Object visitChildren(final IVisitor visitor)
        {
                if (visitor == null)
                {
@@ -742,6 +743,25 @@
                        throw new IllegalArgumentException("argument visitor may not 
be null");
                }

+               final Class c = visitor.getClass();
+
+               final Type type = c.getGenericInterfaces()[0];
+               final Class clazz;
+               if (type instanceof ParameterizedType)
+               {
+                       Type typeArg = 
((ParameterizedType)type).getActualTypeArguments()[0];
+                       if (!(typeArg instanceof Class))
+                       {
+                               clazz = 
(Class)((ParameterizedType)typeArg).getRawType();
+                       }
+                       else
+                       {
+                               clazz = (Class)typeArg;
+                       }
+               } else {
+                       clazz = Component.class;
+               }
+               
                // Iterate through children of this container
                for (int i = 0; i < children_size(); i++)
                {
@@ -750,7 +770,7 @@
                        Object value = null;

                        // Is the child of the correct class (or was no class 
specified)?
-                       if (clazz == null || clazz.isInstance(child))
+                       if (clazz.isInstance(child))
                        {
                                // Call visitor
                                value = visitor.component(child);
@@ -768,7 +788,7 @@
                                        && (value != 
IVisitor.CONTINUE_TRAVERSAL_BUT_DONT_GO_DEEPER))
                        {
                                // visit the children in the container
-                               value = 
((MarkupContainer<?>)child).visitChildren(clazz, visitor);
+                               value = 
((MarkupContainer<?>)child).visitChildren(visitor);

                                // If visitor returns a non-null value, it 
halts the traversal
                                if ((value != IVisitor.CONTINUE_TRAVERSAL)
@@ -783,20 +803,6 @@
        }

        /**
-        * Traverses all child components in this container, calling the 
visitor's
-        * visit method at each one.
-        *
-        * @param visitor
-        *            The visitor to call back to
-        * @return The return value from a visitor which halted the traversal, 
or
-        *         null if the entire traversal occurred
-        */
-       public final Object visitChildren(final IVisitor visitor)
-       {
-               return visitChildren(null, visitor);
-       }
-
-       /**
         * Get the markup stream for this component.
         *
         * @return The markup stream for this component, or if it doesn't have 
one,
@@ -1295,7 +1301,7 @@
                // detach children models
                if (component instanceof MarkupContainer)
                {
-                       ((MarkupContainer<?>)component).visitChildren(new 
IVisitor()
+                       ((MarkupContainer<?>)component).visitChildren(new 
IVisitor<Component<?>>()
                        {
                                public Object component(Component component)
                                {
Index: 
/Users/eelcohillenius/Documents/workspace/wicket/src/java/wicket/Page.java
===================================================================
--- /Users/eelcohillenius/Documents/workspace/wicket/src/java/wicket/Page.java  
(revision
5923)
+++ /Users/eelcohillenius/Documents/workspace/wicket/src/java/wicket/Page.java  
(working
copy)
@@ -1,6 +1,6 @@
/*
- * $Id$ $Revision$ $Date:
- * 2006-05-26 00:32:40 +0200 (vr, 26 mei 2006) $
+ * $Id$
+ * $Revision$ $Date$
 *
 * 
==============================================================================
 * Licensed under the Apache License, Version 2.0 (the "License"); you may not
@@ -326,7 +326,7 @@
        public void detachModels()
        {
                // visit all this page's children to detach the models
-               visitChildren(new IVisitor()
+               visitChildren(new IVisitor<Component>()
                {
                        public Object component(Component component)
                        {
@@ -381,12 +381,12 @@
                // First, give priority to IFeedback instances, as they have to
                // collect their messages before components like ListViews
                // remove any child components
-               visitChildren(IFeedback.class, new IVisitor()
+               visitChildren(new IVisitor<IFeedback>()
                {
-                       public Object component(Component component)
+                       public Object component(IFeedback feedback)
                        {
-                               ((IFeedback)component).updateFeedback();
-                               component.internalAttach();
+                               feedback.updateFeedback();
+                               ((Component)feedback).internalAttach();
                                return IVisitor.CONTINUE_TRAVERSAL;
                        }
                });
@@ -404,7 +404,7 @@
                // or negative as a temporary boolean in the components, and 
when a
                // authorization exception is thrown it will block the 
rendering of this
                // page
-               visitChildren(new IVisitor()
+               visitChildren(new IVisitor<Component>()
                {
                        public Object component(final Component component)
                        {
@@ -643,7 +643,7 @@
        {
                final StringBuffer buffer = new StringBuffer();
                buffer.append("Page " + getId() + " (version " +
getCurrentVersionNumber() + ")");
-               visitChildren(new IVisitor()
+               visitChildren(new IVisitor<Component>()
                {
                        public Object component(Component component)
                        {
@@ -705,16 +705,16 @@
                }

                // Visit all children which are an instance of formClass
-               visitChildren(formClass, new IVisitor()
+               visitChildren(new IVisitor<Form>()
                {
-                       public Object component(final Component component)
+                       public Object component(final Form form)
                        {
                                // They must be of type Form as well
-                               if (component instanceof Form)
+                               if (form.getClass().equals(formClass))
                                {
                                        // Delete persistet FormComponent data 
and disable
                                        // persistence
-                                       
((Form)component).removePersistentFormComponentValues(disablePersistence);
+                                       
form.removePersistentFormComponentValues(disablePersistence);
                                }
                                return CONTINUE_TRAVERSAL;
                        }
@@ -841,7 +841,7 @@
        @Override
        protected final void internalOnModelChanged()
        {
-               visitChildren(new Component.IVisitor()
+               visitChildren(new Component.IVisitor<Component>()
                {
                        public Object component(final Component component)
                        {
@@ -991,7 +991,7 @@
        {
                if (stateless == null)
                {
-                       Object returnValue = visitChildren(Component.class, new 
IVisitor()
+                       Object returnValue = visitChildren(new 
IVisitor<Component>()
                        {
                                public Object component(Component component)
                                {
@@ -1026,12 +1026,12 @@
        final void setFormComponentValuesFromCookies()
        {
                // Visit all Forms contained in the page
-               visitChildren(Form.class, new Component.IVisitor()
+               visitChildren(new Component.IVisitor<Form>()
                {
                        // For each FormComponent found on the Page (not Form)
-                       public Object component(final Component component)
+                       public Object component(final Form form)
                        {
-                               
((Form)component).loadPersistentFormComponentValues();
+                               form.loadPersistentFormComponentValues();
                                return CONTINUE_TRAVERSAL;
                        }
                });
@@ -1103,7 +1103,7 @@
                        final Count unrenderedComponents = new Count();
                        final List<Component> unrenderedAutoComponents = new 
ArrayList<Component>();
                        final StringBuffer buffer = new StringBuffer();
-                       renderedContainer.visitChildren(new IVisitor()
+                       renderedContainer.visitChildren(new 
IVisitor<Component>()
                        {
                                public Object component(final Component 
component)
                                {
Index: 
/Users/eelcohillenius/Documents/workspace/wicket/src/java/wicket/ajax/form/AjaxFormValidatingBehavior.java
===================================================================
--- 
/Users/eelcohillenius/Documents/workspace/wicket/src/java/wicket/ajax/form/AjaxFormValidatingBehavior.java
  (revision
5922)
+++ 
/Users/eelcohillenius/Documents/workspace/wicket/src/java/wicket/ajax/form/AjaxFormValidatingBehavior.java
  (working
copy)
@@ -56,11 +56,11 @@
        @Override
        protected void onSubmit(final AjaxRequestTarget target)
        {
-               getComponent().getPage().visitChildren(IFeedback.class, new 
IVisitor()
+               getComponent().getPage().visitChildren(new IVisitor<IFeedback>()
                {
-                       public Object component(Component component)
+                       public Object component(IFeedback feedback)
                        {
-                               target.addComponent(component);
+                               target.addComponent((Component)feedback);
                                return IVisitor.CONTINUE_TRAVERSAL;
                        }

@@ -88,9 +88,9 @@
        public static void addToAllFormComponents(final Form form, final String 
event,
                        final Duration throttleDelay)
        {
-               form.visitChildren(FormComponent.class, new IVisitor()
+               form.visitChildren(new IVisitor<FormComponent>()
                {
-                       public Object component(Component component)
+                       public Object component(FormComponent component)
                        {
                                AjaxFormValidatingBehavior behavior = new
AjaxFormValidatingBehavior(form, event);
                                if (throttleDelay != null)
Index: 
/Users/eelcohillenius/Documents/workspace/wicket/src/java/wicket/markup/html/debug/PageView.java
===================================================================
--- 
/Users/eelcohillenius/Documents/workspace/wicket/src/java/wicket/markup/html/debug/PageView.java
    (revision
5923)
+++ 
/Users/eelcohillenius/Documents/workspace/wicket/src/java/wicket/markup/html/debug/PageView.java
    (working
copy)
@@ -123,7 +123,7 @@
        {
                final List<ComponentData> data = new ArrayList<ComponentData>();

-               page.visitChildren(new IVisitor()
+               page.visitChildren(new IVisitor<Component>()
                {
                        public Object component(final Component component)
                        {
Index: 
/Users/eelcohillenius/Documents/workspace/wicket/src/java/wicket/markup/html/form/Form.java
===================================================================
--- 
/Users/eelcohillenius/Documents/workspace/wicket/src/java/wicket/markup/html/form/Form.java
 (revision
5918)
+++ 
/Users/eelcohillenius/Documents/workspace/wicket/src/java/wicket/markup/html/form/Form.java
 (working
copy)
@@ -479,11 +479,11 @@
         */
        public final void visitFormComponents(final FormComponent.IVisitor 
visitor)
        {
-               visitChildren(FormComponent.class, new IVisitor()
+               visitChildren(new IVisitor<FormComponent>()
                {
-                       public Object component(final Component component)
+                       public Object component(final FormComponent component)
                        {
-                               visitor.formComponent((FormComponent)component);
+                               visitor.formComponent(component);
                                return CONTINUE_TRAVERSAL;
                        }
                });
@@ -607,13 +607,10 @@
         */
        protected final Button findSubmittingButton()
        {
-               Button button = (Button)visitChildren(Button.class, new 
IVisitor()
+               Button button = (Button)visitChildren(new IVisitor<Button>()
                {
-                       public Object component(final Component component)
+                       public Object component(final Button button)
                        {
-                               // Get button
-                               final Button button = (Button)component;
-
                                // Check for button-name or button-name.x 
request string
                                if 
(getRequest().getParameter(button.getInputName()) != null
                                                || 
getRequest().getParameter(button.getInputName() + ".x") != null)
@@ -630,13 +627,10 @@

                if (button == null)
                {
-                       button = 
(Button)getPage().visitChildren(SubmitLink.class, new IVisitor()
+                       button = (Button)getPage().visitChildren(new 
IVisitor<SubmitLink>()
                        {
-                               public Object component(final Component 
component)
+                               public Object component(final SubmitLink button)
                                {
-                                       // Get button
-                                       final SubmitLink button = 
(SubmitLink)component;
-
                                        // Check for button-name or 
button-name.x request string
                                        if (button.getForm() == Form.this
                                                        && 
(getRequest().getParameter(button.getInputName()) != null
|| getRequest()
@@ -1126,7 +1120,7 @@
         */
        private boolean anyFormComponentError()
        {
-               final Object value = visitChildren(new IVisitor()
+               final Object value = visitChildren(new IVisitor<Component>()
                {
                        public Object component(final Component component)
                        {
Index: 
/Users/eelcohillenius/Documents/workspace/wicket/src/java/wicket/markup/html/internal/HtmlHeaderContainer.java
===================================================================
--- 
/Users/eelcohillenius/Documents/workspace/wicket/src/java/wicket/markup/html/internal/HtmlHeaderContainer.java
      (revision
5918)
+++ 
/Users/eelcohillenius/Documents/workspace/wicket/src/java/wicket/markup/html/internal/HtmlHeaderContainer.java
      (working
copy)
@@ -211,7 +211,7 @@
        {
                // Make sure all Components interested in contributing to the 
header
                // and there attached behaviors are asked.
-               page.visitChildren(new IVisitor()
+               page.visitChildren(new IVisitor<Component>()
                {
                        /**
                         * @see 
wicket.Component.IVisitor#component(wicket.Component)
Index: 
/Users/eelcohillenius/Documents/workspace/wicket/src/java/wicket/protocol/http/ClientPageSavingSessionStore.java
===================================================================
--- 
/Users/eelcohillenius/Documents/workspace/wicket/src/java/wicket/protocol/http/ClientPageSavingSessionStore.java
    (revision
5922)
+++ 
/Users/eelcohillenius/Documents/workspace/wicket/src/java/wicket/protocol/http/ClientPageSavingSessionStore.java
    (working
copy)
@@ -295,12 +295,11 @@

                                final AppendingStringBuffer forms = new 
AppendingStringBuffer(64);
                                forms.append(JavascriptUtils.SCRIPT_OPEN_TAG);
-                               page.visitChildren(Form.class, new IVisitor()
+                               page.visitChildren(new IVisitor<Form>()
                                {
-                                       public Object component(Component 
component)
+                                       public Object component(Form form)
                                        {
                                                
forms.append("document.getElementById('");
-                                               Form form = (Form)component;
                                                
forms.append(form.getHiddenFieldId(Form.HIDDEN_FIELD_WICKET_STATE));
                                                
forms.append("').value=wicketState;\n");
                                                return null;
Index: 
/Users/eelcohillenius/Documents/workspace/wicket/src/java/wicket/protocol/http/MockHttpServletRequest.java
===================================================================
--- 
/Users/eelcohillenius/Documents/workspace/wicket/src/java/wicket/protocol/http/MockHttpServletRequest.java
  (revision
5918)
+++ 
/Users/eelcohillenius/Documents/workspace/wicket/src/java/wicket/protocol/http/MockHttpServletRequest.java
  (working
copy)
@@ -1056,7 +1056,7 @@
                setRequestToComponent(form);

                final Map<String, Component> valuesApplied = new HashMap<String,
Component>();
-               form.visitChildren(new Component.IVisitor()
+               form.visitChildren(new Component.IVisitor<Component>()
                {
                        public Object component(final Component component)
                        {
Index: 
/Users/eelcohillenius/Documents/workspace/wicket/src/java/wicket/util/tester/FormTester.java
===================================================================
--- 
/Users/eelcohillenius/Documents/workspace/wicket/src/java/wicket/util/tester/FormTester.java
        (revision
5923)
+++ 
/Users/eelcohillenius/Documents/workspace/wicket/src/java/wicket/util/tester/FormTester.java
        (working
copy)
@@ -58,9 +58,9 @@
        protected abstract class ChoiceSelector
        {
                /**
-                * ???
+                * @param <E> Visitor type
                 */
-               private final class SearchOptionByIndexVisitor implements 
IVisitor
+               private final class SearchOptionByIndexVisitor<E> implements 
IVisitor<E>
                {
                        int count = 0;

@@ -68,7 +68,6 @@

                        private SearchOptionByIndexVisitor(int index)
                        {
-                               super();
                                this.index = index;
                        }

@@ -75,7 +74,7 @@
                        /**
                         * @see 
wicket.Component.IVisitor#component(wicket.Component)
                         */
-                       public Object component(Component component)
+                       public Object component(E component)
                        {
                                if (count == index)
                                {
@@ -117,8 +116,8 @@
                {
                        if (formComponent instanceof RadioGroup)
                        {
-                               Radio foundRadio = 
(Radio)formComponent.visitChildren(Radio.class,
-                                               new 
SearchOptionByIndexVisitor(index));
+                               Radio foundRadio = 
(Radio)formComponent.visitChildren(
+                                               new 
SearchOptionByIndexVisitor<Radio>(index));
                                if (foundRadio == null)
                                {
                                        Assert.fail("RadioGroup " + 
formComponent.getPath() + " does not
has index:"
@@ -131,8 +130,8 @@
                        }
                        else if (formComponent instanceof CheckGroup)
                        {
-                               Check foundCheck = 
(Check)formComponent.visitChildren(Check.class,
-                                               new 
SearchOptionByIndexVisitor(index));
+                               Check foundCheck = 
(Check)formComponent.visitChildren(
+                                               new 
SearchOptionByIndexVisitor<Check>(index));
                                if (foundCheck == null)
                                {
                                        Assert.fail("CheckGroup " + 
formComponent.getPath() + " does not
has index:"
Index: 
/Users/eelcohillenius/Documents/workspace/wicket/src/java/wicket/util/tester/WicketTesterHelper.java
===================================================================
--- 
/Users/eelcohillenius/Documents/workspace/wicket/src/java/wicket/util/tester/WicketTesterHelper.java
        (revision
5923)
+++ 
/Users/eelcohillenius/Documents/workspace/wicket/src/java/wicket/util/tester/WicketTesterHelper.java
        (working
copy)
@@ -65,7 +65,7 @@
        {
                final List<ComponentData> data = new ArrayList<ComponentData>();

-               page.visitChildren(new IVisitor()
+               page.visitChildren(new IVisitor<Component>()
                {
                        public Object component(final Component component)
                        {
@@ -106,8 +106,7 @@
         * @param expects
         * @param actuals
         */
-       public static void assertEquals(final Collection<?> expects,
-                       final Collection<?> actuals)
+       public static void assertEquals(final Collection<?> expects, final
Collection<?> actuals)
        {
                if (!expects.containsAll(actuals) || 
!actuals.containsAll(expects))
                {


-------------------------------------------------------
All the advantages of Linux Managed Hosting--Without the Cost and Risk!
Fully trained technicians. The highest number of Red Hat certifications in
the hosting industry. Fanatical Support. Click to learn more
http://sel.as-us.falkag.net/sel?cmd=lnk&kid=107521&bid=248729&dat=121642
_______________________________________________
Wicket-develop mailing list
Wicket-develop@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/wicket-develop

Reply via email to