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