Overriding ChoiceRenderer#getIdValue throws a ClassCastException
----------------------------------------------------------------

                 Key: WICKET-2733
                 URL: https://issues.apache.org/jira/browse/WICKET-2733
             Project: Wicket
          Issue Type: Bug
          Components: wicket-extensions
    Affects Versions: 1.4.2
         Environment: winxp pro, jdk1.6.0_16, tomcat 6.0.24
            Reporter: Sebastien Briquet


Dear Wicket Team, dear Igor,

There is a strange behaviour while setting a ChoiceRenderer (with a custom 
bean) to a ChoiceFilteredPropertyColumn.

I provide you a simple sample :
Consider a User (id, name, roleId) and Role (id, name). The goal is to display 
the User(s) in a DefaultDataTable, allowing to filter by their Role name. 
Except if I miss something, it appears logical to me to provide a new 
ChoiceRenderer<Role>("name", "id") to the ChoiceFilteredPropertyColumn. But the 
parameter "id" cause an issue when retrieved by getIdValue() (overrided or not, 
but it's most explicit when overrided). Please find the whole example and the 
stack strace bellow:

----- Java File -----
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

import org.apache.wicket.IClusterable;
import org.apache.wicket.extensions.markup.html.repeater.data.table.DataTable;
import 
org.apache.wicket.extensions.markup.html.repeater.data.table.DefaultDataTable;
import org.apache.wicket.extensions.markup.html.repeater.data.table.IColumn;
import 
org.apache.wicket.extensions.markup.html.repeater.data.table.PropertyColumn;
import 
org.apache.wicket.extensions.markup.html.repeater.data.table.filter.ChoiceFilteredPropertyColumn;
import 
org.apache.wicket.extensions.markup.html.repeater.data.table.filter.FilterForm;
import 
org.apache.wicket.extensions.markup.html.repeater.data.table.filter.FilterToolbar;
import 
org.apache.wicket.extensions.markup.html.repeater.data.table.filter.IFilterStateLocator;
import 
org.apache.wicket.extensions.markup.html.repeater.util.SortableDataProvider;
import org.apache.wicket.markup.html.WebPage;
import org.apache.wicket.markup.html.form.ChoiceRenderer;
import org.apache.wicket.markup.html.form.IChoiceRenderer;
import org.apache.wicket.model.IModel;
import org.apache.wicket.model.LoadableDetachableModel;
import org.apache.wicket.model.Model;

public class TestDropDown extends WebPage
{
        private ArrayList<User> users;
        
        public TestDropDown()
        {
                users = new ArrayList<User>();
                users.add(new User(10, "Sebastien Briquet", 1));
                users.add(new User(20, "Igor Vaynberg", 2));
                
                List<IColumn<User>> columns = new ArrayList<IColumn<User>>();
                columns.add(new PropertyColumn<User>(new Model<String>("Id"), 
"id"));
                columns.add(new PropertyColumn<User>(new Model<String>("Name"), 
"name"));
                columns.add(new ChoiceFilteredPropertyColumn<User, Role>(new 
Model<String>("Role"), "roleId", new RoleChoiceModel())
                {
                        private static final long serialVersionUID = 1L;
                        
                        @Override
                        protected IChoiceRenderer<Role> getChoiceRenderer()
                        {
//                              return new ChoiceRenderer<Role>("name"); // 
this "works", because of the Role#toString, but the selection isn't memorized
                                return new ChoiceRenderer<Role>("name", "id") {

                                        private static final long 
serialVersionUID = 1L;
                                        
                                        @Override
                                        public String getIdValue(Role object, 
int index) // FIXME java.lang.ClassCastException: java.lang.Integer cannot be 
cast to Role
                                        {
                                                return super.getIdValue(object, 
index);
                                        }
                                };
                        }
                });
                
                UserDataProvider dataProvider = new UserDataProvider(users);
                
                FilterForm form = new FilterForm("filter-form", dataProvider);
                this.add(form);

                DataTable<User> table = new DefaultDataTable<User>("table", 
columns, dataProvider, 5);
                table.addTopToolbar(new FilterToolbar(table, form, 
dataProvider));

                form.add(table);
        }       
}

class RoleChoiceModel extends LoadableDetachableModel<List<? extends Role>>
{
        private static final long serialVersionUID = 1L;

        private ArrayList<Role> roles;

        @Override
        protected List<? extends Role> load()
        {
                if(roles == null)
                {
                        roles = new ArrayList<Role>();
                        roles.add(new Role(1, "User"));
                        roles.add(new Role(2, "Master"));
                }

                return roles;
        }
}


class UserDataProvider extends SortableDataProvider<User> implements 
IFilterStateLocator
{
        private static final long serialVersionUID = 1L;
        private ArrayList<User> users;
        private User filter = new User();
        
        public UserDataProvider(ArrayList<User> users)
        {
                this.users = users;
        }

        public Iterator<? extends User> iterator(int first, int count)
        {
                ArrayList<User> list = new ArrayList<User>();
                
                for(User user : users)
                {
                        if(filter.getRoleId() == 0 || filter.getRoleId() == 
user.getRoleId())
                                list.add(user);
                }
                
                return list.iterator();
        }

        public IModel<User> model(User object)
        {
                return new Model<User>(object);
        }

        public int size()
        {
                return users.size();
        }

        public Object getFilterState()
        {
                return filter;
        }

        public void setFilterState(Object state)
        {
                filter = (User) state;
        }
}

class User implements IClusterable
{
        private static final long serialVersionUID = 1L;
        
        private int id;
        private String name;
        private int roleId;
        
        public User()
        {
                this(0, null, 0);
        }

        public User(int id, String name, int roleId)
        {
                this.id = id;
                this.name = name;
                this.roleId = roleId;
        }

        public int getId()
        {
                return id;
        }

        public String getName()
        {
                return name;
        }

        public int getRoleId()
        {
                return roleId;
        }
}

class Role implements IClusterable
{
        private static final long serialVersionUID = 1L;
        
        private int id;
        private String name;
        
        public Role(int id, String name)
        {
                this.id = id;
                this.name = name;
        }

        public int getId()
        {
                return id;
        }

        public String getName()
        {
                return name;
        }

        @Override
        public String toString()
        {
                return Integer.toString(this.id);
        }
}


----- HTML Markup -----
<html 
xmlns:wicket="http://wicket.apache.org/dtds.data/wicket-xhtml1.3-strict.dtd"; >
<head>
</head>
<body>
        <form wicket:id="filter-form">
                <input wicket:id="focus-tracker" type="hidden" name="tracker" />
                <span wicket:id="focus-restore"></span>
                <table wicket:id="table" width="300" border="1" />
        </form>
</body>
</html>


----- Stack Trace -----
ava.lang.ClassCastException: java.lang.Integer cannot be cast to 
com.amadeus.ppl.intranet.samples.Role
     at 
com.amadeus.ppl.intranet.samples.TestDropDown$1$1.getIdValue(TestDropDown.java:1)
     at 
org.apache.wicket.markup.html.form.AbstractSingleSelectChoice.getModelValue(AbstractSingleSelectChoice.java:166)
     at 
org.apache.wicket.markup.html.form.FormComponent.getValue(FormComponent.java:896)
     at 
org.apache.wicket.markup.html.form.AbstractChoice.onComponentTagBody(AbstractChoice.java:352)
     at org.apache.wicket.Component.renderComponent(Component.java:2626)

-- 
This message is automatically generated by JIRA.
-
You can reply to this email to add a comment to the issue online.

Reply via email to