wrapped models

Project: http://git-wip-us.apache.org/repos/asf/wicket/repo
Commit: http://git-wip-us.apache.org/repos/asf/wicket/commit/d93701fe
Tree: http://git-wip-us.apache.org/repos/asf/wicket/tree/d93701fe
Diff: http://git-wip-us.apache.org/repos/asf/wicket/diff/d93701fe

Branch: refs/heads/reference-guide
Commit: d93701fe8d58da0d314137c47f5a0b5af2a90bdb
Parents: 8d310e9
Author: Michael Mosmann <mich...@mosmann.de>
Authored: Mon Feb 18 22:41:47 2013 +0100
Committer: Michael Mosmann <mich...@mosmann.de>
Committed: Mon Feb 18 22:41:47 2013 +0100

----------------------------------------------------------------------
 wicket-reference-guide/models/pom.xml              |    4 +
 .../wicket/reference/models/compound/Person.java   |    6 +-
 .../wicket/reference/models/wrapped/Address.java   |   21 +++++
 .../reference/models/wrapped/AddressModel.java     |   55 +++++++++++
 .../reference/models/wrapped/CustomLabel.java      |   33 +++++++
 .../wicket/reference/models/wrapped/Person.java    |   42 +++++++++
 .../reference/models/wrapped/PersonModel.java      |   70 +++++++++++++++
 .../reference/models/wrapped/PersonProvider.java   |   36 ++++++++
 .../models/wrapped/PersonTableColumn.java          |   43 +++++++++
 .../wrapped/PersonTableColumnWithCustomLabel.java  |   59 ++++++++++++
 .../models/wrapped/WrappedModelFormPage.html       |   15 +++
 .../models/wrapped/WrappedModelFormPage.java       |   53 +++++++++++
 .../src/documentation/source/models.rst            |   59 ++++++++++++
 13 files changed, 493 insertions(+), 3 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/wicket/blob/d93701fe/wicket-reference-guide/models/pom.xml
----------------------------------------------------------------------
diff --git a/wicket-reference-guide/models/pom.xml 
b/wicket-reference-guide/models/pom.xml
index cecc5e9..9e775e9 100644
--- a/wicket-reference-guide/models/pom.xml
+++ b/wicket-reference-guide/models/pom.xml
@@ -32,5 +32,9 @@
                        <groupId>org.apache.wicket</groupId>
                        <artifactId>wicket-core</artifactId>
                </dependency>
+               <dependency>
+                       <groupId>org.apache.wicket</groupId>
+                       <artifactId>wicket-extensions</artifactId>
+               </dependency>
        </dependencies>
 </project>

http://git-wip-us.apache.org/repos/asf/wicket/blob/d93701fe/wicket-reference-guide/models/src/main/java/org/apache/wicket/reference/models/compound/Person.java
----------------------------------------------------------------------
diff --git 
a/wicket-reference-guide/models/src/main/java/org/apache/wicket/reference/models/compound/Person.java
 
b/wicket-reference-guide/models/src/main/java/org/apache/wicket/reference/models/compound/Person.java
index 3f27e85..4bbd950 100644
--- 
a/wicket-reference-guide/models/src/main/java/org/apache/wicket/reference/models/compound/Person.java
+++ 
b/wicket-reference-guide/models/src/main/java/org/apache/wicket/reference/models/compound/Person.java
@@ -6,7 +6,7 @@ import java.io.Serializable;
 public class Person implements Serializable
 {
        String name;
-       Integer age;
+       int age;
        Address address;
 
        public String getName()
@@ -19,12 +19,12 @@ public class Person implements Serializable
                this.name = name;
        }
 
-       public Integer getAge()
+       public int getAge()
        {
                return age;
        }
 
-       public void setAge(Integer age)
+       public void setAge(int age)
        {
                this.age = age;
        }

http://git-wip-us.apache.org/repos/asf/wicket/blob/d93701fe/wicket-reference-guide/models/src/main/java/org/apache/wicket/reference/models/wrapped/Address.java
----------------------------------------------------------------------
diff --git 
a/wicket-reference-guide/models/src/main/java/org/apache/wicket/reference/models/wrapped/Address.java
 
b/wicket-reference-guide/models/src/main/java/org/apache/wicket/reference/models/wrapped/Address.java
new file mode 100644
index 0000000..9fb7d9d
--- /dev/null
+++ 
b/wicket-reference-guide/models/src/main/java/org/apache/wicket/reference/models/wrapped/Address.java
@@ -0,0 +1,21 @@
+package org.apache.wicket.reference.models.wrapped;
+
+import java.io.Serializable;
+
+//#classOnly
+public class Address implements Serializable
+{
+       String city;
+
+       public String getCity()
+       {
+               return city;
+       }
+
+       public void setCity(String city)
+       {
+               this.city = city;
+       }
+}
+//#classOnly
+

http://git-wip-us.apache.org/repos/asf/wicket/blob/d93701fe/wicket-reference-guide/models/src/main/java/org/apache/wicket/reference/models/wrapped/AddressModel.java
----------------------------------------------------------------------
diff --git 
a/wicket-reference-guide/models/src/main/java/org/apache/wicket/reference/models/wrapped/AddressModel.java
 
b/wicket-reference-guide/models/src/main/java/org/apache/wicket/reference/models/wrapped/AddressModel.java
new file mode 100644
index 0000000..42bb760
--- /dev/null
+++ 
b/wicket-reference-guide/models/src/main/java/org/apache/wicket/reference/models/wrapped/AddressModel.java
@@ -0,0 +1,55 @@
+package org.apache.wicket.reference.models.wrapped;
+
+import org.apache.wicket.model.IModel;
+
+//#classOnly
+public class AddressModel<T> implements IModel<T>
+{
+       private final IModel<Address> addressContainingModel;
+
+       private final AddressModelType type;
+
+       public enum AddressModelType {
+               CITY_MODEL;
+       };
+
+       public AddressModel(IModel<Address> addressContainingModel, 
AddressModelType type)
+       {
+               this.addressContainingModel = addressContainingModel;
+               this.type = type;
+       }
+
+       @Override
+       public T getObject()
+       {
+               Address address = addressContainingModel.getObject();
+               switch (type)
+               {
+                       case CITY_MODEL :
+                               return (T)address.getCity();
+                       default :
+                               throw new 
UnsupportedOperationException("invalid AddressModelType = " + type.name());
+               }
+       }
+
+       @Override
+       public void setObject(T object)
+       {
+               Address address = addressContainingModel.getObject();
+               switch (type)
+               {
+                       case CITY_MODEL :
+                               address.setCity((String)object);
+                               break;
+                       default :
+                               throw new 
UnsupportedOperationException("invalid AddressModelType = " + type.name());
+               }
+       }
+
+       @Override
+       public void detach()
+       {
+               addressContainingModel.detach();
+       }
+}
+//#classOnly

http://git-wip-us.apache.org/repos/asf/wicket/blob/d93701fe/wicket-reference-guide/models/src/main/java/org/apache/wicket/reference/models/wrapped/CustomLabel.java
----------------------------------------------------------------------
diff --git 
a/wicket-reference-guide/models/src/main/java/org/apache/wicket/reference/models/wrapped/CustomLabel.java
 
b/wicket-reference-guide/models/src/main/java/org/apache/wicket/reference/models/wrapped/CustomLabel.java
new file mode 100644
index 0000000..8d61ada
--- /dev/null
+++ 
b/wicket-reference-guide/models/src/main/java/org/apache/wicket/reference/models/wrapped/CustomLabel.java
@@ -0,0 +1,33 @@
+package org.apache.wicket.reference.models.wrapped;
+
+import org.apache.wicket.markup.html.basic.Label;
+import org.apache.wicket.model.IModel;
+import org.apache.wicket.util.convert.IConverter;
+
+//#classOnly
+public class CustomLabel extends Label
+{
+       private final IConverter<?> converter;
+
+       /**
+        * @param id
+        * @param label
+        */
+       public <T> CustomLabel(String id, IModel<T> labelModel, IConverter<T> 
converter)
+       {
+               super(id, labelModel);
+               this.converter = converter;
+       }
+
+       /*
+        * (non-Javadoc)
+        * 
+        * @see org.apache.wicket.Component#getConverter(java.lang.Class)
+        */
+       @Override
+       public <C> IConverter<C> getConverter(Class<C> type)
+       {
+               return (IConverter<C>)this.converter;
+       }
+}
+//#classOnly

http://git-wip-us.apache.org/repos/asf/wicket/blob/d93701fe/wicket-reference-guide/models/src/main/java/org/apache/wicket/reference/models/wrapped/Person.java
----------------------------------------------------------------------
diff --git 
a/wicket-reference-guide/models/src/main/java/org/apache/wicket/reference/models/wrapped/Person.java
 
b/wicket-reference-guide/models/src/main/java/org/apache/wicket/reference/models/wrapped/Person.java
new file mode 100644
index 0000000..b18e3ee
--- /dev/null
+++ 
b/wicket-reference-guide/models/src/main/java/org/apache/wicket/reference/models/wrapped/Person.java
@@ -0,0 +1,42 @@
+package org.apache.wicket.reference.models.wrapped;
+
+import java.io.Serializable;
+
+//#classOnly
+public class Person implements Serializable
+{
+       String name;
+       int age;
+       Address address;
+
+       public String getName()
+       {
+               return name;
+       }
+
+       public void setName(String name)
+       {
+               this.name = name;
+       }
+
+       public int getAge()
+       {
+               return age;
+       }
+
+       public void setAge(int age)
+       {
+               this.age = age;
+       }
+
+       public Address getAddress()
+       {
+               return address;
+       }
+
+       public void setAddress(Address address)
+       {
+               this.address = address;
+       }
+}
+//#classOnly

http://git-wip-us.apache.org/repos/asf/wicket/blob/d93701fe/wicket-reference-guide/models/src/main/java/org/apache/wicket/reference/models/wrapped/PersonModel.java
----------------------------------------------------------------------
diff --git 
a/wicket-reference-guide/models/src/main/java/org/apache/wicket/reference/models/wrapped/PersonModel.java
 
b/wicket-reference-guide/models/src/main/java/org/apache/wicket/reference/models/wrapped/PersonModel.java
new file mode 100644
index 0000000..4348e1a
--- /dev/null
+++ 
b/wicket-reference-guide/models/src/main/java/org/apache/wicket/reference/models/wrapped/PersonModel.java
@@ -0,0 +1,70 @@
+package org.apache.wicket.reference.models.wrapped;
+
+import org.apache.wicket.model.IModel;
+
+public class PersonModel<T> implements IModel<T>
+{
+       private final IModel<Person> personContainingModel;
+       private final PersonModelType type;
+
+       public enum PersonModelType {
+               NAME_MODEL, AGE_MODEL, ADDRESS_MODEL;
+       }
+
+       public PersonModel(IModel<Person> personContainingModel, 
PersonModelType type)
+       {
+               this.personContainingModel = personContainingModel;
+               this.type = type;
+       }
+
+       @Override
+       public T getObject()
+       {
+               Person person = personContainingModel.getObject();
+
+               switch (type)
+               {
+                       case NAME_MODEL :
+                               return (T)person.getName();
+
+                       case AGE_MODEL :
+                               return (T)Integer.valueOf(person.getAge());
+
+                       case ADDRESS_MODEL :
+                               return (T)person.getAddress();
+
+                       default :
+                               throw new 
UnsupportedOperationException("invalid PersonModelType = " + type.name());
+               }
+       }
+
+       @Override
+       public void setObject(T object)
+       {
+               Person person = personContainingModel.getObject();
+
+               switch (type)
+               {
+                       case NAME_MODEL :
+                               person.setName((String)object);
+                               break;
+
+                       case AGE_MODEL :
+                               person.setAge((Integer)object);
+                               break;
+
+                       case ADDRESS_MODEL :
+                               person.setAddress((Address)object);
+                               break;
+
+                       default :
+                               throw new 
UnsupportedOperationException("invalid PersonModelType = " + type.name());
+               }
+       }
+
+       @Override
+       public void detach()
+       {
+               personContainingModel.detach();
+       }
+}

http://git-wip-us.apache.org/repos/asf/wicket/blob/d93701fe/wicket-reference-guide/models/src/main/java/org/apache/wicket/reference/models/wrapped/PersonProvider.java
----------------------------------------------------------------------
diff --git 
a/wicket-reference-guide/models/src/main/java/org/apache/wicket/reference/models/wrapped/PersonProvider.java
 
b/wicket-reference-guide/models/src/main/java/org/apache/wicket/reference/models/wrapped/PersonProvider.java
new file mode 100644
index 0000000..873eeb5
--- /dev/null
+++ 
b/wicket-reference-guide/models/src/main/java/org/apache/wicket/reference/models/wrapped/PersonProvider.java
@@ -0,0 +1,36 @@
+package org.apache.wicket.reference.models.wrapped;
+
+import java.util.ArrayList;
+import java.util.Iterator;
+
+import org.apache.wicket.markup.repeater.data.IDataProvider;
+import org.apache.wicket.model.IModel;
+import org.apache.wicket.model.Model;
+
+public class PersonProvider implements IDataProvider<Person>
+{
+       @Override
+       public void detach()
+       {
+
+       }
+
+       @Override
+       public Iterator<? extends Person> iterator(long first, long count)
+       {
+               return new ArrayList<Person>().iterator();
+       }
+
+       @Override
+       public long size()
+       {
+               return 0;
+       }
+
+       @Override
+       public IModel<Person> model(Person person)
+       {
+               return Model.of(person);
+       }
+
+}

http://git-wip-us.apache.org/repos/asf/wicket/blob/d93701fe/wicket-reference-guide/models/src/main/java/org/apache/wicket/reference/models/wrapped/PersonTableColumn.java
----------------------------------------------------------------------
diff --git 
a/wicket-reference-guide/models/src/main/java/org/apache/wicket/reference/models/wrapped/PersonTableColumn.java
 
b/wicket-reference-guide/models/src/main/java/org/apache/wicket/reference/models/wrapped/PersonTableColumn.java
new file mode 100644
index 0000000..bc8e3a5
--- /dev/null
+++ 
b/wicket-reference-guide/models/src/main/java/org/apache/wicket/reference/models/wrapped/PersonTableColumn.java
@@ -0,0 +1,43 @@
+package org.apache.wicket.reference.models.wrapped;
+
+import 
org.apache.wicket.extensions.markup.html.repeater.data.grid.ICellPopulator;
+import 
org.apache.wicket.extensions.markup.html.repeater.data.table.AbstractColumn;
+import org.apache.wicket.markup.html.basic.Label;
+import org.apache.wicket.markup.repeater.Item;
+import org.apache.wicket.model.IModel;
+import org.apache.wicket.model.Model;
+import 
org.apache.wicket.reference.models.wrapped.AddressModel.AddressModelType;
+import org.apache.wicket.reference.models.wrapped.PersonModel.PersonModelType;
+
+//#classOnly
+public class PersonTableColumn extends AbstractColumn<Person, Void>
+{
+       private final PersonModelType type;
+
+       public PersonTableColumn(String columnName, PersonModelType type)
+       {
+               super(Model.of(columnName));
+               this.type = type;
+       }
+
+       @Override
+       public void populateItem(Item<ICellPopulator<Person>> cellItem, String 
componentId,
+               IModel<Person> rowModel)
+       {
+
+               switch (type)
+               {
+                       // this needs to be handled seperately due to it being 
an Address
+                       // instance from the Person object.
+                       case ADDRESS_MODEL :
+                               cellItem.add(new Label(componentId, new 
AddressModel<String>(
+                                       new PersonModel<Address>(rowModel, 
PersonModelType.ADDRESS_MODEL),
+                                       AddressModelType.CITY_MODEL)));
+                               break;
+
+                       default :
+                               cellItem.add(new Label(componentId, new 
PersonModel(rowModel, type)));
+               }
+       }
+}
+//#classOnly

http://git-wip-us.apache.org/repos/asf/wicket/blob/d93701fe/wicket-reference-guide/models/src/main/java/org/apache/wicket/reference/models/wrapped/PersonTableColumnWithCustomLabel.java
----------------------------------------------------------------------
diff --git 
a/wicket-reference-guide/models/src/main/java/org/apache/wicket/reference/models/wrapped/PersonTableColumnWithCustomLabel.java
 
b/wicket-reference-guide/models/src/main/java/org/apache/wicket/reference/models/wrapped/PersonTableColumnWithCustomLabel.java
new file mode 100644
index 0000000..4ea1b3e
--- /dev/null
+++ 
b/wicket-reference-guide/models/src/main/java/org/apache/wicket/reference/models/wrapped/PersonTableColumnWithCustomLabel.java
@@ -0,0 +1,59 @@
+package org.apache.wicket.reference.models.wrapped;
+
+import java.util.Locale;
+
+import 
org.apache.wicket.extensions.markup.html.repeater.data.grid.ICellPopulator;
+import 
org.apache.wicket.extensions.markup.html.repeater.data.table.AbstractColumn;
+import org.apache.wicket.markup.html.basic.Label;
+import org.apache.wicket.markup.repeater.Item;
+import org.apache.wicket.model.IModel;
+import org.apache.wicket.model.Model;
+import org.apache.wicket.reference.models.wrapped.PersonModel.PersonModelType;
+import org.apache.wicket.util.convert.IConverter;
+
+//#classOnly
+public class PersonTableColumnWithCustomLabel extends AbstractColumn<Person, 
Void>
+{
+       private final PersonModelType type;
+
+       public PersonTableColumnWithCustomLabel(String columnName, 
PersonModelType type)
+       {
+               super(Model.of(columnName));
+               this.type = type;
+       }
+
+       //#refactor
+       @Override
+       public void populateItem(Item<ICellPopulator<Person>> cellItem, String 
componentId,
+               IModel<Person> rowModel)
+       {
+
+               switch (type)
+               {
+                       // this needs to be handled seperately due to it being 
an Address
+                       // instance from the Person object.
+                       case ADDRESS_MODEL :
+                               cellItem.add(new CustomLabel(componentId, new 
PersonModel<Address>(rowModel,
+                                       PersonModelType.ADDRESS_MODEL), new 
IConverter<Address>()
+                               {
+                                       @Override
+                                       public Address convertToObject(String 
value, Locale locale)
+                                       {
+                                               throw new 
UnsupportedOperationException("converter is readonly.");
+                                       }
+
+                                       @Override
+                                       public String convertToString(Address 
address, Locale locale)
+                                       {
+                                               return address.getCity();
+                                       }
+                               }));
+                               break;
+
+                       default :
+                               cellItem.add(new Label(componentId, new 
PersonModel(rowModel, type)));
+               }
+       }
+       //#refactor
+}
+// #classOnly

http://git-wip-us.apache.org/repos/asf/wicket/blob/d93701fe/wicket-reference-guide/models/src/main/java/org/apache/wicket/reference/models/wrapped/WrappedModelFormPage.html
----------------------------------------------------------------------
diff --git 
a/wicket-reference-guide/models/src/main/java/org/apache/wicket/reference/models/wrapped/WrappedModelFormPage.html
 
b/wicket-reference-guide/models/src/main/java/org/apache/wicket/reference/models/wrapped/WrappedModelFormPage.html
new file mode 100644
index 0000000..2db0eeb
--- /dev/null
+++ 
b/wicket-reference-guide/models/src/main/java/org/apache/wicket/reference/models/wrapped/WrappedModelFormPage.html
@@ -0,0 +1,15 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<html xmlns="http://www.w3.org/1999/xhtml";
+       xmlns:wicket="http://wicket.apache.org";>
+<head>
+<title>Compound Model Form</title>
+</head>
+<body>
+       <form wicket:id="form">
+               <label>Name</label> <input wicket:id="name" />
+               <label>Age</label><input wicket:id="age" />
+               <label>City</label><input wicket:id="address.city" />
+               <input type="submit" value="Submit">
+       </form>
+</body>
+</html>

http://git-wip-us.apache.org/repos/asf/wicket/blob/d93701fe/wicket-reference-guide/models/src/main/java/org/apache/wicket/reference/models/wrapped/WrappedModelFormPage.java
----------------------------------------------------------------------
diff --git 
a/wicket-reference-guide/models/src/main/java/org/apache/wicket/reference/models/wrapped/WrappedModelFormPage.java
 
b/wicket-reference-guide/models/src/main/java/org/apache/wicket/reference/models/wrapped/WrappedModelFormPage.java
new file mode 100644
index 0000000..c152c9a
--- /dev/null
+++ 
b/wicket-reference-guide/models/src/main/java/org/apache/wicket/reference/models/wrapped/WrappedModelFormPage.java
@@ -0,0 +1,53 @@
+package org.apache.wicket.reference.models.wrapped;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.wicket.extensions.markup.html.repeater.data.table.DataTable;
+import org.apache.wicket.extensions.markup.html.repeater.data.table.IColumn;
+import org.apache.wicket.markup.html.WebPage;
+import org.apache.wicket.markup.html.form.Form;
+import org.apache.wicket.markup.html.form.RequiredTextField;
+import org.apache.wicket.model.Model;
+import 
org.apache.wicket.reference.models.wrapped.AddressModel.AddressModelType;
+import org.apache.wicket.reference.models.wrapped.PersonModel.PersonModelType;
+
+public class WrappedModelFormPage extends WebPage
+{
+       public WrappedModelFormPage()
+       {
+               //#form
+               Person person = new Person();
+               Model<Person> beanModel = Model.of(person);
+               
+               //#form
+               person.setAge(12);
+               person.setName("Klaus");
+               Address address = new Address();
+               address.setCity("Lübeck");
+               person.setAddress(address);
+               //#form
+               Form<Void> form = new Form<Void>("form");
+               
+               form.add(new RequiredTextField<String>("name", new 
PersonModel<String>(beanModel,
+                       PersonModelType.NAME_MODEL)));
+               form.add(new RequiredTextField<Integer>("age", new 
PersonModel<Integer>(beanModel,
+                       PersonModelType.AGE_MODEL), Integer.class));
+               form.add(new RequiredTextField<String>("address.city", new 
AddressModel<String>(
+                       new PersonModel<Address>(beanModel, 
PersonModelType.ADDRESS_MODEL),
+                       AddressModelType.CITY_MODEL)));
+
+               add(form);
+               //#form
+
+               //#datatable
+               List<IColumn<Person,Void>> columns=new 
ArrayList<IColumn<Person,Void>>();
+               
+               columns.add(new PersonTableColumn("Name", 
PersonModelType.NAME_MODEL));
+               columns.add(new PersonTableColumn("Age", 
PersonModelType.AGE_MODEL));
+               columns.add(new PersonTableColumn("City", 
PersonModelType.ADDRESS_MODEL));
+               
+               DataTable<Person, Void> table = new DataTable<Person, 
Void>("datatable", columns, new PersonProvider(), 10);
+               //#datatable
+       }
+}

http://git-wip-us.apache.org/repos/asf/wicket/blob/d93701fe/wicket-reference-guide/src/documentation/source/models.rst
----------------------------------------------------------------------
diff --git a/wicket-reference-guide/src/documentation/source/models.rst 
b/wicket-reference-guide/src/documentation/source/models.rst
index 0840927..acfdaf6 100644
--- a/wicket-reference-guide/src/documentation/source/models.rst
+++ b/wicket-reference-guide/src/documentation/source/models.rst
@@ -183,6 +183,65 @@ Also, note that if you are using a component that you do 
not want to reference t
 
 
 
+Wrapped Object Models
+---------------------
+
+.. todo:: IMHO this is not the best way to explain and implement this concept
+
+It is possible to create Models that explicitly define in normal java code 
what is to be returned as the model object for each property within the object 
being wrapped. So instead of specifying via a string the name of the property 
to fetch the value you from the specification is done in Java.
+
+While creating Model's in this pattern takes longer (more classes) than using 
Reflection based PropertyModels it prevents the problems that can occur when 
critical functionality is defined in String based context that most IDE's do 
not refactor properly.
+
+It also helps with readability when the models are added to components to be 
able to easily see the types involved.
+
+These are the Address and Person classes used in the previous examples:
+
+.. includecode:: 
../../../models/src/main/java/org/apache/wicket/reference/models/wrapped/Address.java#classOnly
+
+.. includecode:: 
../../../models/src/main/java/org/apache/wicket/reference/models/wrapped/Person.java#classOnly
+
+The first step is to create a Wrapped Object Model for the Address and Person 
classes:
+
+.. includecode:: 
../../../models/src/main/java/org/apache/wicket/reference/models/wrapped/AddressModel.java#classOnly
+
+.. includecode:: 
../../../models/src/main/java/org/apache/wicket/reference/models/wrapped/PersonModel.java#classOnly
+
+Notice how each wrapped model contains an inner model that contains the actual 
pojo instance. This allows for the wrapped model to be a plain Model or a 
LoadableDetachableModel, or even another wrapped model where its .getObject() 
results in a suitably typed input value (see the "address.city" field in the 
example below).
+
+At this point to create a form using our wrapped object models looks like:
+
+.. todo:: IMHO this needs refactoring (improve generic type handling)
+
+.. includecode:: 
../../../models/src/main/java/org/apache/wicket/reference/models/wrapped/WrappedModelFormPage.java#form
+
+A wrapped object model also makes working with DataTables's easier as one 
IColumn implementation can be written for each object class which makes the 
declaration of the table much simpler.
+
+e.g.
+
+.. todo:: IMHO refactoring needed
+
+.. includecode:: 
../../../models/src/main/java/org/apache/wicket/reference/models/wrapped/PersonTableColumn.java#classOnly
+       
+So the table could be declared like:
+
+.. todo:: IMHO refactoring needed
+
+.. includecode:: 
../../../models/src/main/java/org/apache/wicket/reference/models/wrapped/WrappedModelFormPage.java#datatable
+  
+Another option with the complex object is to create a custom ``IConverter`` 
that will take in this case the Address instance from the PersonModel and 
render the string value as the city name.
+
+e.g.
+
+.. todo:: IMHO refactoring needed
+
+.. includecode:: 
../../../models/src/main/java/org/apache/wicket/reference/models/wrapped/CustomLabel.java#classOnly
+
+
+With the populate from above as:
+
+.. includecode:: 
../../../models/src/main/java/org/apache/wicket/reference/models/wrapped/PersonTableColumnWithCustomLabel.java#refactor
+
+
 
 
 

Reply via email to