I've been looking around the tutorial from wicket-util-6.19 source, samples library and so forth but did not find an answer to this question. This question is about what kind of parameters (specialization) I can use with an IVisitor.
Spoiler : I know how to have the code to work, I just would like to know why I cannot do the way I want it to.
I have a NestedTree. If you are familiar with wicket-6 NestedTree you may know that the tree is composed of Node whose models is the object you declared your tree with. So it is composed of Node<MyObjectType> (the tree is more complex than that - this is just to exemplify).
I want to traverse the tree with a visitor and return the MyObjectType object backing the Node based on a PropertyEn (an enum, but could be a number or anything).
This is how I would write the visit:
private MyObjectType findNode(final PropertyEn propertyEn) {
return myNestedTree.visitChildren(new IVisitor<Node<MyObjectType>, MyObjectType>() {
@Override
public void component(Node<MyObjectType> object, IVisit<MyObjectType> visit) {
if ( object.getModelObject().getPropertyEn == propertyEn ) {
visit.stop(object.getModelObject());
}
}
});
There is a problem with generic in the use of the first IVisitor generic argument Node<MyObjectType> object
...Cannot instantiate from arguments because actual and formal arguments lists differ in length...
This would compile and possibly work but requires unchecked casting and reflexion :
private MyObjectType findNode(final PropertyEn propertyEn) {
return myNestedTree.visitChildren(new IVisitor<Node<MyObjectType>, MyObjectType>() {
@Override
public void component(Component object, IVisit<MyObjectType> visit) {
if ( object instanceof Node) {
if (((Node<PropertyEn>) object).getModelObject().getProto() == lxproto) {
visit.stop(((Node<PropertyEn>) object).getModelObject());
}
// A Node has no concept of nesting. The tree is made as such with other data structures.
// No need to go deeper within an Node thus.
visit.dontGoDeeper();
}
}
)};
Why can't I just use a specialized Type as the first Type argument of IVisitor?
I found the problem... it's the signature of the visitChildren() method.
The one I was using is :
public final <R> R visitChildren(final IVisitor<Component, R> visitor)
{ ... }
The one I should be using is :
public final <S extends Component, R> R visitChildren(final Class<?> clazz, final IVisitor<S, R> visitor)
{ ... }
So the code would look like this:
private MyObjectType findNode(final PropertyEn propertyEn) {
return myNestedTree.visitChildren(Node.class, new IVisitor<Node<MyObjectType>, MyObjectType>() {
@Override
public void component(Node<MyObjectType> object, IVisit<MyObjectType> visit) {
if ( object.getModelObject().getPropertyEn() == propertyEn ) {
visit.stop(object.getModelObject());
}
}
)};