Repository: wicket
Updated Branches:
  refs/heads/master 356bed21c -> 9126194a1


WICKET-6190 Added a new paragraph on IModel and lambda


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

Branch: refs/heads/master
Commit: 9126194a16fab1775a6df3c2a0226e92734b56fd
Parents: 356bed2
Author: Andrea Del Bene <[email protected]>
Authored: Mon Jul 4 11:36:01 2016 +0200
Committer: Andrea Del Bene <[email protected]>
Committed: Mon Jul 4 11:41:28 2016 +0200

----------------------------------------------------------------------
 .../docs/guide/modelsforms/modelsforms_1.gdoc   |  15 --
 .../docs/guide/modelsforms/modelsforms_10.gdoc  |   4 +
 .../docs/guide/modelsforms/modelsforms_2.gdoc   | 125 ++---------
 .../docs/guide/modelsforms/modelsforms_3.gdoc   | 214 +++++++------------
 .../docs/guide/modelsforms/modelsforms_4.gdoc   | 181 +++++++++++++---
 .../docs/guide/modelsforms/modelsforms_5.gdoc   | 123 ++++-------
 .../docs/guide/modelsforms/modelsforms_6.gdoc   | 157 ++++++++------
 .../docs/guide/modelsforms/modelsforms_7.gdoc   |  92 ++++++--
 .../docs/guide/modelsforms/modelsforms_8.gdoc   |  26 ++-
 .../docs/guide/modelsforms/modelsforms_9.gdoc   |  22 +-
 wicket-user-guide/src/docs/guide/toc.yml        |  17 +-
 11 files changed, 491 insertions(+), 485 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/wicket/blob/9126194a/wicket-user-guide/src/docs/guide/modelsforms/modelsforms_1.gdoc
----------------------------------------------------------------------
diff --git a/wicket-user-guide/src/docs/guide/modelsforms/modelsforms_1.gdoc 
b/wicket-user-guide/src/docs/guide/modelsforms/modelsforms_1.gdoc
index 431fa38..95d1c3e 100644
--- a/wicket-user-guide/src/docs/guide/modelsforms/modelsforms_1.gdoc
+++ b/wicket-user-guide/src/docs/guide/modelsforms/modelsforms_1.gdoc
@@ -48,21 +48,6 @@ From now on we will use these factory methods in our 
examples.
 It's quite clear that if our Label must display a static text it doesn't make 
much sense to build a model by hand like we did in the last code example.
 However is not unusual to have a Label that must display a dynamic value, like 
the input provided by a user or a value read from a database. Wicket models are 
designed to solve these kinds of problems.
 
-Let's say we need a label to display the current time stamp each time a page 
is rendered. We can implement a custom model which returns a new Date instance 
when the getObject() method is called:
-
-{code}
-IModel timeStampModel = new Model<String>(){
-       @Override
-       public String getObject() {
-               return new Date().toString();
-       }
-};
-
-add(new Label("timeStamp", timeStampModel));
-{code}
-
-Even if sometimes writing a custom model could be a good choice to solve a 
specific problem, Wicket already provides a set of IModel implementations which 
should fit most of our needs. In the next paragraph we will see a couple of 
models that allow us to easily integrate JavaBeans with our web applications 
and in particular with our forms.
-
 {note}
 By default the class Component escapes HTML sensitive characters (like '<', 
'>' or '&') from the textual representation of its model object. The term 
'escape' means that these characters will be replaced with their corresponding 
HTML "entity":http://en.wikipedia.org/wiki/Character_entity_reference (for 
example '<' becomes '&lt; '). This is done for security reasons as a malicious 
user could attempt to inject markup or JavaScript into our pages. If we want to 
display the raw content stored inside a model, we can tell the Component class 
not to escape characters by calling the setEscapeModelStrings(false) method.
 {note}

http://git-wip-us.apache.org/repos/asf/wicket/blob/9126194a/wicket-user-guide/src/docs/guide/modelsforms/modelsforms_10.gdoc
----------------------------------------------------------------------
diff --git a/wicket-user-guide/src/docs/guide/modelsforms/modelsforms_10.gdoc 
b/wicket-user-guide/src/docs/guide/modelsforms/modelsforms_10.gdoc
new file mode 100644
index 0000000..95f3d97
--- /dev/null
+++ b/wicket-user-guide/src/docs/guide/modelsforms/modelsforms_10.gdoc
@@ -0,0 +1,4 @@
+
+
+Models are at the core of Wicket and they are the basic ingredient needed to 
taste the real power of the framework. In this chapter we have seen how to use 
models to bring data to our components without littering their code with 
technical details about their persistence strategy.
+We have also introduced Wicket forms as complementary topic. With forms and 
models we are able to bring our applications to life allowing them to interact 
with users. But what we have seen in this chapter about Wicket forms is just 
the tip of the iceberg. That's why the next chapter is entirely dedicated to 
them.
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/wicket/blob/9126194a/wicket-user-guide/src/docs/guide/modelsforms/modelsforms_2.gdoc
----------------------------------------------------------------------
diff --git a/wicket-user-guide/src/docs/guide/modelsforms/modelsforms_2.gdoc 
b/wicket-user-guide/src/docs/guide/modelsforms/modelsforms_2.gdoc
index b49ffcb..27e875e 100644
--- a/wicket-user-guide/src/docs/guide/modelsforms/modelsforms_2.gdoc
+++ b/wicket-user-guide/src/docs/guide/modelsforms/modelsforms_2.gdoc
@@ -1,121 +1,20 @@
+With Wicket 8 @IModel@ has been extended with new methods to fully leverage 
lambdas. The most interesting thing of the new version of @IModel@ is that it 
provides a default implementation for all of its methods (included 
@setObject()@), with the only exception of @getObject()@. 
+In this way @IModel@ is eligible as functional interface and this greatly 
simplify the creation of cutom models. As long as we need to display a static 
test it doesn't make much sense building a custom model, but if we need to 
display a dynamic value (like the input provided by a user or a value read from 
a database), defining a model with a lambda expression comes quite in handy. 
 
-
-One of the main goals of Wicket is to use JavaBeans and POJO as data model, 
overcoming the impedance mismatch between web technologies and OO paradigm. In 
order to make this task as easy as possible, Wicket offers two special model 
classes: @org.apache.wicket.model.PropertyModel@ and 
@org.apache.wicket.model.CompoundPropertyModel@. We will see how to use them in 
the next two examples, using the following JavaBean as the data object:
-
-{code}
-public class Person implements Serializable {  
-       
-       private String name;
-       private String surname;
-       private String address;
-       private String email;
-       private String passportCode;
-       
-       private Person spouse;
-       private List<Person> children;
-       
-       public Person(String name, String surname) {
-               this.name = name;
-               this.surname = surname;
-       }
-
-       public String getFullName(){
-               return name + " " + surname;
-       } 
-
-       /*       
-        * Getters and setters for private fields
-     */
-}
-{code}
-
-h3. PropertyModel
-
-Let's say we want to display the name field of a Person instance with a label. 
We could, of course, use the Model class like we did in the previous example, 
obtaining something like this:
-
-{code}
-Person person = new Person();          
-//load person's data...
-               
-Label label = new Label("name", new Model(person.getName()));
-{code}
-
-However this solution has a huge drawback: the text displayed by the label 
will be static and if we change the value of the field, the label won't update 
its content. Instead, to always display the current value of a class field, we 
should use the @org.apache.wicket.model.PropertyModel@ model class:
-
-{code}
-Person person = new Person();          
-//load person's data...
-               
-Label label = new Label("name", new PropertyModel(person, "name"));
-{code}
-
-PropertyModel has just one constructor with two parameters: the model object 
(person in our example) and the name of the property we want to read/write 
("name" in our example). This last parameter is called property expression. 
Internally, methods getObject/setObject use property expression to get/set 
property's value. To resolve class properties PropertyModel uses class 
@org.apache.wicket.util.lang.Property@ Resolver which can access any kind of 
property, private fields included.
-
-Just like the Java language, property expressions support dotted notation to 
select sub properties. So if we want to display the name of the Person's spouse 
we can write:
-
-{code}
-Label label = new Label("spouseName", new PropertyModel(person, 
"spouse.name"));
-{code}
-
-{note}
-PropertyModel is null-safe, which means we don't have to worry if property 
expression includes a null value in its path. If such a value is encountered, 
an empty string will be returned.
-{note}
-
-If property is an array or a List, we can specify an index after its name. For 
example, to display the name of the first child of a Person we can write the 
following property expression:
-
-{code}
-Label label = new Label("firstChildName", new PropertyModel(person, 
"children.0.name"));
-{code}
-
-Indexes and map keys can be also specified using squared brackets: 
-
-{code}
-children[0].name ...
-mapField[key].subfield ...
-{code}
-
-h3. CompoundPropertyModel and model inheritance
-
-Class @org.apache.wicket.model.CompoundPropertyModel@ is a particular kind of 
model which is usually used in conjunction with another Wicket feature called 
model inheritance. With this feature, when a component needs to use a model but 
none has been assigned to it, it will search through the whole container 
hierarchy for a parent with an inheritable model. Inheritable models are those 
which implement interface @org.apache.wicket.model.IComponentInheritedModel@ 
and @CompoundPropertyModel@ is one of them. Once a @CompoundPropertyModel@ has 
been inherited by a component, it will behave just like a PropertyModel using 
the id of the component as property expression. As a consequence, to make the 
most of CompoundPropertyModel we must assign it to one of the containers of a 
given component, rather than directly to the component itself.
-
-For example if we use CompoundPropertyModel with the previous example (display 
spouse's name), the code would become like this:
+Let's say we need a label to display the current time stamp each time a page 
is rendered. This could be a possible solution:
 
 {code}
-//set CompoundPropertyModel as model for the container of the label
-setDefaultModel(new CompoundPropertyModel(person));
-
-Label label = new Label("spouse.name");        
-
-add(label);
-{code}
-
-Note that now the id of the label is equal to the property expression 
previously used with PropertyModel. Now as a further example let's say we want 
to extend the code above to display all of the main informations of a person 
(name, surname, address and email). All we have to do is to add one label for 
every additional information using the relative property expression as 
component id:
-
+add(new Label("timeStamp", () -> new Date().toString()));
 {code}
-//Create a person named 'John Smith'
-Person person = new Person("John", "Smith");
-setDefaultModel(new CompoundPropertyModel(person));
 
-add(new Label("name"));
-add(new Label("surname"));
-add(new Label("address"));
-add(new Label("email"));
-add(new Label("spouse.name"));
+As mentioned above, method @setObject()@ comes with a default implementation. 
The code is the following:
+ 
 {code}
-
-CompoundPropertyModel can save us a lot of boring coding if we choose the id 
of components according to properties name. However it's also possible to use 
this type of model even if the id of a component does not correspond to a valid 
property expression. The method bind(String property) allows to create a 
property model from a given CompoundPropertyModel using the provided parameter 
as property expression. For example if we want to display the spouse's name in 
a label having "xyz" as id, we can write the following code:
-
-{code}
-//Create a person named 'John Smith'
-Person person = new Person("John", "Smith");
-CompoundPropertyModel compoundModel;
-setDefaultModel(compoundModel = new CompoundPropertyModel(person));
-
-add(new Label("xyz", compoundModel.bind("spouse.name")));
+default void setObject(final T object)
+{
+  throw new UnsupportedOperationException(
+    "Override this method to support setObject(Object)");
+}
 {code}
 
-CompoundPropertyModel are particularly useful when used in combination with 
Wicket forms, as we will see in the next paragraph.
-
-{note}
-Model is referred to as static model because the result of its method 
getObject is fixed and it is not dynamically evaluated each time the method is 
called. In contrast, models like PropertyModel and CompoundProperty Model are 
called dynamic models.
-{note}
\ No newline at end of file
+This means that models obtained using @IModel@ as lambda expressions are 
_read-only_. When we work with forms we need to use a model that support also 
data storing. In the next paragraph we will see a couple of models shipped with 
Wicket that allow us to easily use JavaBeans as backing objects.
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/wicket/blob/9126194a/wicket-user-guide/src/docs/guide/modelsforms/modelsforms_3.gdoc
----------------------------------------------------------------------
diff --git a/wicket-user-guide/src/docs/guide/modelsforms/modelsforms_3.gdoc 
b/wicket-user-guide/src/docs/guide/modelsforms/modelsforms_3.gdoc
index 25c7840..b49ffcb 100644
--- a/wicket-user-guide/src/docs/guide/modelsforms/modelsforms_3.gdoc
+++ b/wicket-user-guide/src/docs/guide/modelsforms/modelsforms_3.gdoc
@@ -1,185 +1,121 @@
 
 
-Web applications use HTML forms to collect user input and send it to the 
server. Wicket provides @org.apache.wicket.markup.html.form.Form@ class to 
handle web forms. This component must be bound to <form> tag. The following 
snippet shows how to create a very basic Wicket form in a page:
+One of the main goals of Wicket is to use JavaBeans and POJO as data model, 
overcoming the impedance mismatch between web technologies and OO paradigm. In 
order to make this task as easy as possible, Wicket offers two special model 
classes: @org.apache.wicket.model.PropertyModel@ and 
@org.apache.wicket.model.CompoundPropertyModel@. We will see how to use them in 
the next two examples, using the following JavaBean as the data object:
 
-Html:
-
-{code:html}
-<form wicket:id="form">
-    <input type="submit" value="submit"/>
-</form>
 {code}
+public class Person implements Serializable {  
+       
+       private String name;
+       private String surname;
+       private String address;
+       private String email;
+       private String passportCode;
+       
+       private Person spouse;
+       private List<Person> children;
+       
+       public Person(String name, String surname) {
+               this.name = name;
+               this.surname = surname;
+       }
 
+       public String getFullName(){
+               return name + " " + surname;
+       } 
 
-Java code:
-
-{code}
-Form form = new Form("form"){
-    @Override
-    protected void onSubmit() {
-       System.out.println("Form submitted.");
-    }
-};
-add(form);
+       /*       
+        * Getters and setters for private fields
+     */
+}
 {code}
 
-Method onSubmit is called whenever a form has been submitted and it can be 
overridden to perform custom actions. Please note that a Wicket form can be 
submitted using a standard HTML submit button which is not mapped to any 
component (i.e. it does not have a wicket:id attribute). 
-In the next chapter we will continue to explore Wicket forms and we will see 
how to submit forms using special components which implement interface 
@org.apache.wicket.markup.html.form.IFormSubmitter@.
-
-h3. Form and models
-
-A form should contain some input fields (like text fields, check boxes, radio 
buttons, drop-down lists, text areas, etc.) to interact with users. Wicket 
provides an abstraction for all these kinds of elements with component 
org.apache.wicket.markup.html.form.FormComponent:
-
-!uml-form-component.png!
-
-The purpose of FormComponent is to store the corresponding user input into its 
model when the form is submitted. The form is responsible for mapping input 
values to the corresponding components, avoiding us the burden of manually 
synchronizing models with input fields and vice versa.
+h3. PropertyModel
 
-h3. Login form
+Let's say we want to display the name field of a Person instance with a label. 
We could, of course, use the Model class like we did in the previous example, 
obtaining something like this:
 
-As first example of interaction between the form and its models, we will build 
a classic login form which asks for username and password (project LoginForm).
-
-{warning}
-The topic of security will be discussed later in chapter 22. The following 
form is for example purposes only and is not suited for a real application.
-If you need to use a login form you should consider to use component 
@org.apache.wicket.authroles.authentication.panel.SignInPanel@ shipped with 
Wicket.
-{warning}
-
-This form needs two text fields, one of which must be a password field. We 
should also use a label to display the result of login process1. For the sake 
of simplicity, the login logic is all inside onSubmit and is quite trivial.
+{code}
+Person person = new Person();          
+//load person's data...
+               
+Label label = new Label("name", new Model(person.getName()));
+{code}
 
-The following is a possible implementation of our form:
+However this solution has a huge drawback: the text displayed by the label 
will be static and if we change the value of the field, the label won't update 
its content. Instead, to always display the current value of a class field, we 
should use the @org.apache.wicket.model.PropertyModel@ model class:
 
 {code}
-public class LoginForm extends Form {
-       
-       private TextField usernameField;
-       private PasswordTextField passwordField;
-       private Label loginStatus;
+Person person = new Person();          
+//load person's data...
                
-       public LoginForm(String id) {
-               super(id);
-                       
-               usernameField = new TextField("username", Model.of(""));
-               passwordField = new PasswordTextField("password", 
Model.of(""));                        
-               loginStatus = new Label("loginStatus", Model.of(""));
-                       
-               add(usernameField);
-               add(passwordField);
-               add(loginStatus);
-       }
+Label label = new Label("name", new PropertyModel(person, "name"));
+{code}
 
-       public final void onSubmit() {
-               String username = (String)usernameField.getDefaultModelObject();
-               String password = (String)passwordField.getDefaultModelObject();
+PropertyModel has just one constructor with two parameters: the model object 
(person in our example) and the name of the property we want to read/write 
("name" in our example). This last parameter is called property expression. 
Internally, methods getObject/setObject use property expression to get/set 
property's value. To resolve class properties PropertyModel uses class 
@org.apache.wicket.util.lang.Property@ Resolver which can access any kind of 
property, private fields included.
+
+Just like the Java language, property expressions support dotted notation to 
select sub properties. So if we want to display the name of the Person's spouse 
we can write:
 
-               if(username.equals("test") && password.equals("test"))
-                       loginStatus.setDefaultModelObject("Congratulations!");
-               else
-                       loginStatus.setDefaultModelObject("Wrong username or 
password!");                       
-       }
-}
 {code}
+Label label = new Label("spouseName", new PropertyModel(person, 
"spouse.name"));
+{code}
+
+{note}
+PropertyModel is null-safe, which means we don't have to worry if property 
expression includes a null value in its path. If such a value is encountered, 
an empty string will be returned.
+{note}
 
-Inside form's constructor we build the three components used in the form and 
we assign them a model containing an empty string:
+If property is an array or a List, we can specify an index after its name. For 
example, to display the name of the first child of a Person we can write the 
following property expression:
 
 {code}
-usernameField = new TextField("username", Model.of(""));
-passwordField = new PasswordTextField("password", Model.of(""));               
        
-loginStatus = new Label("loginStatus", Model.of(""));
+Label label = new Label("firstChildName", new PropertyModel(person, 
"children.0.name"));
 {code}
 
-If we don't provide a model to a form component, we will get the following 
exception on form submission:
+Indexes and map keys can be also specified using squared brackets: 
 
 {code}
-java.lang.IllegalStateException: Attempt to set model object on null model of 
component: 
+children[0].name ...
+mapField[key].subfield ...
 {code}
 
-Component TextField corresponds to the standard text field, without any 
particular behavior or restriction on the allowed values. We must bind this 
component to the <input> tag with the attribute type set to "text". 
PasswordTextField is a subtype of TextFiled and it must be used with an <input> 
tag with the attribute type set to"password". For security reasons component 
PasswordTextField cleans its value at each request, so it wil be always empty 
after the form has been rendered. By default PasswordTextField fields are 
required, meaning that if we left them empty, the form won't be submitted (i.e. 
onSubmit won't be called). Class FormComponent provides method 
setRequired(boolean required) to change this behavior. Inside onSubmit, to 
get/set model objects we have used shortcut methods setDefaultModelObject and 
getDefaultModelObject. Both methods are defined in class Component (see class 
diagram from Illustration 9.1).
+h3. CompoundPropertyModel and model inheritance
 
-The following are the possible markup and code for the login page:
+Class @org.apache.wicket.model.CompoundPropertyModel@ is a particular kind of 
model which is usually used in conjunction with another Wicket feature called 
model inheritance. With this feature, when a component needs to use a model but 
none has been assigned to it, it will search through the whole container 
hierarchy for a parent with an inheritable model. Inheritable models are those 
which implement interface @org.apache.wicket.model.IComponentInheritedModel@ 
and @CompoundPropertyModel@ is one of them. Once a @CompoundPropertyModel@ has 
been inherited by a component, it will behave just like a PropertyModel using 
the id of the component as property expression. As a consequence, to make the 
most of CompoundPropertyModel we must assign it to one of the containers of a 
given component, rather than directly to the component itself.
 
-Html:
+For example if we use CompoundPropertyModel with the previous example (display 
spouse's name), the code would become like this:
 
-{code:html}
-<html>
-       <head>
-               <title>Login page</title>
-       </head>
-       <body>
-               <form id="loginForm" method="get" wicket:id="loginForm">
-                       <fieldset>
-                       <legend style="color: #F90">Login</legend>
-                               <p wicket:id="loginStatus"></p>
-                               <span>Username: </span><input 
wicket:id="username" type="text" id="username" /><br/>
-                               <span>Password: </span><input 
wicket:id="password" type="password" id="password" />
-                               <p>
-                                       <input type="submit" name="Login" 
value="Login"/>
-                               </p>
-                   </fieldset>
-               </form>
-       </body>
-</html>
 {code}
+//set CompoundPropertyModel as model for the container of the label
+setDefaultModel(new CompoundPropertyModel(person));
 
-Java code:
+Label label = new Label("spouse.name");        
 
+add(label);
 {code}
-public class HomePage extends WebPage {
- 
-   public HomePage(final PageParameters parameters) {
-               
-               super(parameters);
-       add(new LoginForm("loginForm"));
 
-    }
-}
-{code}
-
-The example shows how Wicket form components can be used to store user input 
inside their model. However we can dramatically improve the form code using 
CompoundPropertyModel and its ability to access the properties of its model 
object. The revisited code is the following (the LoginFormRevisited project):
+Note that now the id of the label is equal to the property expression 
previously used with PropertyModel. Now as a further example let's say we want 
to extend the code above to display all of the main informations of a person 
(name, surname, address and email). All we have to do is to add one label for 
every additional information using the relative property expression as 
component id:
 
 {code}
-public class LoginForm extends Form{
-               
-               private String username;
-               private String password;
-               private String loginStatus;
-               
-               public LoginForm(String id) {
-                       super(id);                      
-                       setDefaultModel(new CompoundPropertyModel(this));
-                       
-                       add(new TextField("username"));
-                       add(new PasswordTextField("password"));
-                       add(new Label("loginStatus"));
-               }
-
-               public final void onSubmit() {                  
-                       if(username.equals("test") && password.equals("test"))
-                               loginStatus = "Congratulations!";
-                       else
-                               loginStatus = "Wrong username or password !";   
                
-               }
-       }
-{code}
+//Create a person named 'John Smith'
+Person person = new Person("John", "Smith");
+setDefaultModel(new CompoundPropertyModel(person));
 
-In this version the form itself is used as model object for its 
CompoundPropertyModel. This allows children components to have direct access to 
form fields and use them as backing objects, without explicitly creating a 
model for themselves.
+add(new Label("name"));
+add(new Label("surname"));
+add(new Label("address"));
+add(new Label("email"));
+add(new Label("spouse.name"));
+{code}
 
-{note}
-Keep in mind that when CompoundPropertyModel is inherited, it does not 
consider the ids of traversed containers for the final property expression, but 
it will always use the id of the visited child. To understand this potential 
pitfall, let's consider the following initialization code of a page:
+CompoundPropertyModel can save us a lot of boring coding if we choose the id 
of components according to properties name. However it's also possible to use 
this type of model even if the id of a component does not correspond to a valid 
property expression. The method bind(String property) allows to create a 
property model from a given CompoundPropertyModel using the provided parameter 
as property expression. For example if we want to display the spouse's name in 
a label having "xyz" as id, we can write the following code:
 
 {code}
 //Create a person named 'John Smith'
 Person person = new Person("John", "Smith");
-//Create a person named 'Jill Smith'
-Person spouse = new Person("Jill", "Smith");
-//Set Jill as John's spouse
-person.setSpouse(spouse);
+CompoundPropertyModel compoundModel;
+setDefaultModel(compoundModel = new CompoundPropertyModel(person));
 
-setDefaultModel(new CompoundPropertyModel(person));
-WebMarkupContainer spouseContainer = new WebMarkupContainer("spouse");
-Label name;
-spouseContainer.add(name = new Label("name"));
-
-add(spouseContainer);
+add(new Label("xyz", compoundModel.bind("spouse.name")));
 {code}
 
-The value displayed by label "name" will be "John" and not the spouse's name  
"Jill" as you may expect. In this example the label doesn't own a model, so it 
must search up its container hierarchy for an inheritable model. However, its 
container (WebMarkup Container with id 'spouse') doesn't own a model, hence the 
request for a model is forwarded to the parent container, which in this case is 
the page. In the end the label inherits CompoundPropertyModel from page but 
only its own id is used for the property expression. The containers in between 
are never taken into account for the final property expression.
+CompoundPropertyModel are particularly useful when used in combination with 
Wicket forms, as we will see in the next paragraph.
+
 {note}
+Model is referred to as static model because the result of its method 
getObject is fixed and it is not dynamically evaluated each time the method is 
called. In contrast, models like PropertyModel and CompoundProperty Model are 
called dynamic models.
+{note}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/wicket/blob/9126194a/wicket-user-guide/src/docs/guide/modelsforms/modelsforms_4.gdoc
----------------------------------------------------------------------
diff --git a/wicket-user-guide/src/docs/guide/modelsforms/modelsforms_4.gdoc 
b/wicket-user-guide/src/docs/guide/modelsforms/modelsforms_4.gdoc
index 9d8695f..25c7840 100644
--- a/wicket-user-guide/src/docs/guide/modelsforms/modelsforms_4.gdoc
+++ b/wicket-user-guide/src/docs/guide/modelsforms/modelsforms_4.gdoc
@@ -1,54 +1,185 @@
 
 
-Class @org.apache.wicket.markup.html.form.DropDownChoice@ is the form 
component needed to display a list of possible options as a drop-down list 
where users can select one of the proposed options. This component must be used 
with <select> tag:
+Web applications use HTML forms to collect user input and send it to the 
server. Wicket provides @org.apache.wicket.markup.html.form.Form@ class to 
handle web forms. This component must be bound to <form> tag. The following 
snippet shows how to create a very basic Wicket form in a page:
 
 Html:
 
 {code:html}
 <form wicket:id="form">
-       Select a fruit: <select wicket:id="fruits"></select>
-<div><input type="submit" value="submit"/></div>
+    <input type="submit" value="submit"/>
 </form>
 {code}
 
+
 Java code:
 
 {code}
-List<String> fruits = Arrays.asList("apple", "strawberry", "watermelon"); 
-form.add(new DropDownChoice<String>("fruits", new Model(), fruits));
+Form form = new Form("form"){
+    @Override
+    protected void onSubmit() {
+       System.out.println("Form submitted.");
+    }
+};
+add(form);
 {code}
 
-Screenshot of generated page:
+Method onSubmit is called whenever a form has been submitted and it can be 
overridden to perform custom actions. Please note that a Wicket form can be 
submitted using a standard HTML submit button which is not mapped to any 
component (i.e. it does not have a wicket:id attribute). 
+In the next chapter we will continue to explore Wicket forms and we will see 
how to submit forms using special components which implement interface 
@org.apache.wicket.markup.html.form.IFormSubmitter@.
 
-!dropdown-choice.png!
+h3. Form and models
 
-In addition to the component id, in order to build a DropDownChoice we need to 
provide to its constructor two further parameters:
+A form should contain some input fields (like text fields, check boxes, radio 
buttons, drop-down lists, text areas, etc.) to interact with users. Wicket 
provides an abstraction for all these kinds of elements with component 
org.apache.wicket.markup.html.form.FormComponent:
 
-* a model containing the current selected item. This parameter is not required 
if we are going to inherit a CompoundPropertyModel for this component.
-* a list of options to display which can be supplied as a model or as a 
regular java.util.List.
+!uml-form-component.png!
 
-In the example above the possible options are provided as a list of String 
objects. Now let's take a look at the markup generated for them:
+The purpose of FormComponent is to store the corresponding user input into its 
model when the form is submitted. The form is responsible for mapping input 
values to the corresponding components, avoiding us the burden of manually 
synchronizing models with input fields and vice versa.
+
+h3. Login form
+
+As first example of interaction between the form and its models, we will build 
a classic login form which asks for username and password (project LoginForm).
+
+{warning}
+The topic of security will be discussed later in chapter 22. The following 
form is for example purposes only and is not suited for a real application.
+If you need to use a login form you should consider to use component 
@org.apache.wicket.authroles.authentication.panel.SignInPanel@ shipped with 
Wicket.
+{warning}
+
+This form needs two text fields, one of which must be a password field. We 
should also use a label to display the result of login process1. For the sake 
of simplicity, the login logic is all inside onSubmit and is quite trivial.
+
+The following is a possible implementation of our form:
+
+{code}
+public class LoginForm extends Form {
+       
+       private TextField usernameField;
+       private PasswordTextField passwordField;
+       private Label loginStatus;
+               
+       public LoginForm(String id) {
+               super(id);
+                       
+               usernameField = new TextField("username", Model.of(""));
+               passwordField = new PasswordTextField("password", 
Model.of(""));                        
+               loginStatus = new Label("loginStatus", Model.of(""));
+                       
+               add(usernameField);
+               add(passwordField);
+               add(loginStatus);
+       }
+
+       public final void onSubmit() {
+               String username = (String)usernameField.getDefaultModelObject();
+               String password = (String)passwordField.getDefaultModelObject();
+
+               if(username.equals("test") && password.equals("test"))
+                       loginStatus.setDefaultModelObject("Congratulations!");
+               else
+                       loginStatus.setDefaultModelObject("Wrong username or 
password!");                       
+       }
+}
+{code}
+
+Inside form's constructor we build the three components used in the form and 
we assign them a model containing an empty string:
+
+{code}
+usernameField = new TextField("username", Model.of(""));
+passwordField = new PasswordTextField("password", Model.of(""));               
        
+loginStatus = new Label("loginStatus", Model.of(""));
+{code}
+
+If we don't provide a model to a form component, we will get the following 
exception on form submission:
 
-{code:html}
-<select name="fruits" wicket:id="fruits">
-       <option value="" selected="selected">Choose One</option>
-       <option value="0">apple</option>
-       <option value="1">strawberry</option>
-       <option value="2">watermelon</option>
-</select>
 {code}
+java.lang.IllegalStateException: Attempt to set model object on null model of 
component: 
+{code}
+
+Component TextField corresponds to the standard text field, without any 
particular behavior or restriction on the allowed values. We must bind this 
component to the <input> tag with the attribute type set to "text". 
PasswordTextField is a subtype of TextFiled and it must be used with an <input> 
tag with the attribute type set to"password". For security reasons component 
PasswordTextField cleans its value at each request, so it wil be always empty 
after the form has been rendered. By default PasswordTextField fields are 
required, meaning that if we left them empty, the form won't be submitted (i.e. 
onSubmit won't be called). Class FormComponent provides method 
setRequired(boolean required) to change this behavior. Inside onSubmit, to 
get/set model objects we have used shortcut methods setDefaultModelObject and 
getDefaultModelObject. Both methods are defined in class Component (see class 
diagram from Illustration 9.1).
 
-The first option is a placeholder item corresponding to a null model value. By 
default DropDownChoice cannot have a null value so users are forced to select a 
not-null option. If we want to change this behavior we can set the nullValid 
flag to true via the setNullValid method. Please note that the placeholder text 
(“Chose one”) can be localized, as we will see in chapter 15. The other 
options are identified by the attribute value. By default the value of this 
attribute is the index of the single option inside the provided list of 
choices, while the text displayed to the user is obtained by  calling 
toString()on the choice object. This default behavior works fine as long as our 
options are simple objects like strings, but when we move to more complex 
objects we may need to implement a more sophisticated algorithm to generate the 
value to use as the option id and the one to display to user. Wicket has solved 
this problem with @org.apache.wicket.markup.html.form.IChoiceRender@ inte
 rface. This interface defines method getDisplayValue(T object) that is called 
to generate the value to display for the given choice object, and method 
getIdValue(T object, int index) that is called to generate the option id. The 
built-in implementation of this interface is class 
@org.apache.wicket.markup.html.form.ChoiceRenderer@ which renders the two 
values using property expressions.
+The following are the possible markup and code for the login page:
+
+Html:
 
-In the following code we want to show a list of Person objects using their 
full name as value to display and using their passport code as option id: 
+{code:html}
+<html>
+       <head>
+               <title>Login page</title>
+       </head>
+       <body>
+               <form id="loginForm" method="get" wicket:id="loginForm">
+                       <fieldset>
+                       <legend style="color: #F90">Login</legend>
+                               <p wicket:id="loginStatus"></p>
+                               <span>Username: </span><input 
wicket:id="username" type="text" id="username" /><br/>
+                               <span>Password: </span><input 
wicket:id="password" type="password" id="password" />
+                               <p>
+                                       <input type="submit" name="Login" 
value="Login"/>
+                               </p>
+                   </fieldset>
+               </form>
+       </body>
+</html>
+{code}
 
 Java code:
 
 {code}
-List<Person> persons; 
-//Initialize the list of persons here...
-ChoiceRenderer personRenderer = new ChoiceRenderer("fullName", "passportCode");
-form.add(new DropDownChoice<String>("persons", new Model<Person>(), persons, 
personRenderer));
+public class HomePage extends WebPage {
+ 
+   public HomePage(final PageParameters parameters) {
+               
+               super(parameters);
+       add(new LoginForm("loginForm"));
+
+    }
+}
+{code}
+
+The example shows how Wicket form components can be used to store user input 
inside their model. However we can dramatically improve the form code using 
CompoundPropertyModel and its ability to access the properties of its model 
object. The revisited code is the following (the LoginFormRevisited project):
+
+{code}
+public class LoginForm extends Form{
+               
+               private String username;
+               private String password;
+               private String loginStatus;
+               
+               public LoginForm(String id) {
+                       super(id);                      
+                       setDefaultModel(new CompoundPropertyModel(this));
+                       
+                       add(new TextField("username"));
+                       add(new PasswordTextField("password"));
+                       add(new Label("loginStatus"));
+               }
+
+               public final void onSubmit() {                  
+                       if(username.equals("test") && password.equals("test"))
+                               loginStatus = "Congratulations!";
+                       else
+                               loginStatus = "Wrong username or password !";   
                
+               }
+       }
+{code}
+
+In this version the form itself is used as model object for its 
CompoundPropertyModel. This allows children components to have direct access to 
form fields and use them as backing objects, without explicitly creating a 
model for themselves.
+
+{note}
+Keep in mind that when CompoundPropertyModel is inherited, it does not 
consider the ids of traversed containers for the final property expression, but 
it will always use the id of the visited child. To understand this potential 
pitfall, let's consider the following initialization code of a page:
+
+{code}
+//Create a person named 'John Smith'
+Person person = new Person("John", "Smith");
+//Create a person named 'Jill Smith'
+Person spouse = new Person("Jill", "Smith");
+//Set Jill as John's spouse
+person.setSpouse(spouse);
+
+setDefaultModel(new CompoundPropertyModel(person));
+WebMarkupContainer spouseContainer = new WebMarkupContainer("spouse");
+Label name;
+spouseContainer.add(name = new Label("name"));
+
+add(spouseContainer);
 {code}
 
-The choice renderer can be assigned to the DropDownChoice using one of its 
constructor that accepts this type of parameter (like we did in the example 
above) or after its creation invoking setChoiceRenderer method.
\ No newline at end of file
+The value displayed by label "name" will be "John" and not the spouse's name  
"Jill" as you may expect. In this example the label doesn't own a model, so it 
must search up its container hierarchy for an inheritable model. However, its 
container (WebMarkup Container with id 'spouse') doesn't own a model, hence the 
request for a model is forwarded to the parent container, which in this case is 
the page. In the end the label inherits CompoundPropertyModel from page but 
only its own id is used for the property expression. The containers in between 
are never taken into account for the final property expression.
+{note}

http://git-wip-us.apache.org/repos/asf/wicket/blob/9126194a/wicket-user-guide/src/docs/guide/modelsforms/modelsforms_5.gdoc
----------------------------------------------------------------------
diff --git a/wicket-user-guide/src/docs/guide/modelsforms/modelsforms_5.gdoc 
b/wicket-user-guide/src/docs/guide/modelsforms/modelsforms_5.gdoc
index a194524..9d8695f 100644
--- a/wicket-user-guide/src/docs/guide/modelsforms/modelsforms_5.gdoc
+++ b/wicket-user-guide/src/docs/guide/modelsforms/modelsforms_5.gdoc
@@ -1,101 +1,54 @@
 
 
-Models that implement the interface @org.apache.wicket.model.IChainingModel@ 
can be used to build a chain of models. These kinds of models are able to 
recognize whether their model object is itself an implementation of IModel and 
if so, they will call getObject on the wrapped model and the returned value 
will be the actual model object. In this way we can combine the action of an 
arbitrary number of models, making exactly a chain of models. Chaining models 
allows to combine different data persistence strategies, similarly to what we 
do with chains of "I/O 
streams.":http://java.sun.com/developer/technicalArticles/Streams/ProgIOStreams 
To see model chaining in action we will build a page that implements the 
List/Detail View pattern, where we have a drop-down list of Person objects and 
a form to display and edit the data of the current selected Person.
+Class @org.apache.wicket.markup.html.form.DropDownChoice@ is the form 
component needed to display a list of possible options as a drop-down list 
where users can select one of the proposed options. This component must be used 
with <select> tag:
 
-The example page will look like this:
-
-!model-chaining.png!
-
-What we want to do in this example is to chain the model of the DropDownChoice 
(which contains the selected Person) with the model of the Form. In this way 
the Form will work with the selected Person as backing object. The 
DropDownChoice component can be configured to automatically update its model 
each time we change the selected item on the client side. All we have to do is 
to override method wantOnSelectionChangedNotifications to make it return true. 
In practice, when this method returns true, DropDownChoice will submit its 
value every time JavaScript event onChange occurs, and its model will be 
consequently updated. To leverage this functionality, DropDownChoice doesn't 
need to be inside a form.
-
-The following is the resulting markup of the example page:
+Html:
 
 {code:html}
-...
-<body>
-       List of persons <select wicket:id="persons"></select> <br/>
-       <br/>
-       <form wicket:id="form">         
-               <div style="display: table;">
-                       <div style="display: table-row;">
-                               <div style="display: table-cell;">Name: </div>
-                               <div style="display: table-cell;">
-                                       <input type="text" wicket:id="name"/> 
-                               </div>  
-                       </div>
-                       <div style="display: table-row;">
-                               <div style="display: table-cell;">Surname: 
</div>
-                               <div style="display: table-cell;">
-                                                                       <input 
type="text" wicket:id="surname"/>
-                                                               </div>  
-                                                       </div>
-                                                       <div style="display: 
table-row;">
-                                                               <div 
style="display: table-cell;">Address: </div>
-                                                               <div 
style="display: table-cell;">
-                                                                       <input 
type="text" wicket:id="address"/>
-                                                               </div>  
-                                                       </div>
-                                                       <div style="display: 
table-row;">
-                                                               <div 
style="display: table-cell;">Email: </div>
-                                                               <div 
style="display: table-cell;">
-                                                                       <input 
type="text" wicket:id="email"/>
-                                                               </div>
-                                                       </div>
-                                               </div>  
-                                               <input type="submit" 
value="Save"/>
-                                       </form>
-                               </body>                         
+<form wicket:id="form">
+       Select a fruit: <select wicket:id="fruits"></select>
+<div><input type="submit" value="submit"/></div>
+</form>
 {code}
 
-The initialization code for DropDownChoice is the following:
+Java code:
 
 {code}
-Model<Person> listModel = new Model<Person>();
-ChoiceRenderer<Person> personRender = new ChoiceRenderer<Person>("fullName");
-personsList = new DropDownChoice<Person>("persons", listModel, loadPersons(), 
personRender){
-               
-               @Override
-               protected boolean wantOnSelectionChangedNotifications() {
-                       return true;
-               }
-               
-};
+List<String> fruits = Arrays.asList("apple", "strawberry", "watermelon"); 
+form.add(new DropDownChoice<String>("fruits", new Model(), fruits));
+{code}
+
+Screenshot of generated page:
+
+!dropdown-choice.png!
+
+In addition to the component id, in order to build a DropDownChoice we need to 
provide to its constructor two further parameters:
+
+* a model containing the current selected item. This parameter is not required 
if we are going to inherit a CompoundPropertyModel for this component.
+* a list of options to display which can be supplied as a model or as a 
regular java.util.List.
+
+In the example above the possible options are provided as a list of String 
objects. Now let's take a look at the markup generated for them:
+
+{code:html}
+<select name="fruits" wicket:id="fruits">
+       <option value="" selected="selected">Choose One</option>
+       <option value="0">apple</option>
+       <option value="1">strawberry</option>
+       <option value="2">watermelon</option>
+</select>
 {code}
 
-As choice render we have used the basic implementation provided with the 
org.apache.wicket .markup.html.form.ChoiceRenderer class that we have seen in 
the previous paragraph. loadPersons() is just an utility method which generates 
a list of Person instances. The model for DropDownChoice is a simple instance 
of the Model class.
+The first option is a placeholder item corresponding to a null model value. By 
default DropDownChoice cannot have a null value so users are forced to select a 
not-null option. If we want to change this behavior we can set the nullValid 
flag to true via the setNullValid method. Please note that the placeholder text 
(“Chose one”) can be localized, as we will see in chapter 15. The other 
options are identified by the attribute value. By default the value of this 
attribute is the index of the single option inside the provided list of 
choices, while the text displayed to the user is obtained by  calling 
toString()on the choice object. This default behavior works fine as long as our 
options are simple objects like strings, but when we move to more complex 
objects we may need to implement a more sophisticated algorithm to generate the 
value to use as the option id and the one to display to user. Wicket has solved 
this problem with @org.apache.wicket.markup.html.form.IChoiceRender@ inte
 rface. This interface defines method getDisplayValue(T object) that is called 
to generate the value to display for the given choice object, and method 
getIdValue(T object, int index) that is called to generate the option id. The 
built-in implementation of this interface is class 
@org.apache.wicket.markup.html.form.ChoiceRenderer@ which renders the two 
values using property expressions.
+
+In the following code we want to show a list of Person objects using their 
full name as value to display and using their passport code as option id: 
 
-Here is the whole code of the page (except for the loadPersons() method):
+Java code:
 
 {code}
-public class PersonListDetails extends WebPage {
-  private Form form;
-  private DropDownChoice<Person> personsList;
-  
-  public PersonListDetails(){
-    Model<Person> listModel = new Model<Person>();
-    ChoiceRenderer<Person> personRender = new 
ChoiceRenderer<Person>("fullName");
-    
-    personsList = new DropDownChoice<Person>("persons", listModel, 
loadPersons(),
-                                                         personRender){
-      @Override
-      protected boolean wantOnSelectionChangedNotifications() {
-        return true;
-      }
-           };    
-
-           add(personsList);
-
-           form = new Form("form", new 
CompoundPropertyModel<Person>(listModel));    
-           form.add(new TextField("name"));
-           form.add(new TextField("surname"));
-           form.add(new TextField("address"));
-           form.add(new TextField("email"));
-
-           add(form);
-         }
-              //loadPersons()
-              //...
-       }
+List<Person> persons; 
+//Initialize the list of persons here...
+ChoiceRenderer personRenderer = new ChoiceRenderer("fullName", "passportCode");
+form.add(new DropDownChoice<String>("persons", new Model<Person>(), persons, 
personRenderer));
 {code}
 
-The two models work together as a pipeline where the output of method 
getObject of Model is the model object of CompoundPropertyModel. As we have 
seen, model chaining allows us to combine the actions of two or more models 
without creating new custom implementations.
\ No newline at end of file
+The choice renderer can be assigned to the DropDownChoice using one of its 
constructor that accepts this type of parameter (like we did in the example 
above) or after its creation invoking setChoiceRenderer method.
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/wicket/blob/9126194a/wicket-user-guide/src/docs/guide/modelsforms/modelsforms_6.gdoc
----------------------------------------------------------------------
diff --git a/wicket-user-guide/src/docs/guide/modelsforms/modelsforms_6.gdoc 
b/wicket-user-guide/src/docs/guide/modelsforms/modelsforms_6.gdoc
index 2a9a097..a194524 100644
--- a/wicket-user-guide/src/docs/guide/modelsforms/modelsforms_6.gdoc
+++ b/wicket-user-guide/src/docs/guide/modelsforms/modelsforms_6.gdoc
@@ -1,82 +1,101 @@
 
 
-In chapter 6 we have seen how Wicket uses serialization to store page 
instances. When an object is serialized, all its referenced objects are 
recursively serialized. For a page this means that all its children components, 
their related models as well as the model objects inside them will be 
serialized. 
-For model objects this could be a serious issue for (at least) two main 
reasons:
-
-# The model object could be a very large instance, hence serialization would 
become very expensive in terms of time and memory.
-# We simply may not be able to use a serializable object as model object. In 
paragraphs 1.4 and 9.2 we stated that Wicket allows us to use a POJO as backing 
object, but 
"POJOs":http://en.wikipedia.org/wiki/Plain_Old_Java_Object#Definition are 
ordinary objects with no prespecified interface, annotation or superclass, 
hence they are not required to implement the standard Serializable interface.
-
-To cope with these problems IModel extends another interface called 
IDetachable.
-
-!detachable-models.png!
-
-This interface provides a method called detach() which is invoked by Wicket at 
the end of web request processing when data model is no more needed but before 
serialization occurs. Overriding this method we can clean any reference to data 
object keeping just the information needed to retrieve it later (for example 
the id of the table row where our data are stored). In this way we can avoid 
the serialization of the object wrapped into the model overcoming both the 
problem with non-serializable objects and the one with large data objects.
-
-Since IModel inherits from IDetachable, every model of Wicket is 
“detachable”, although not all of them implement a detaching policy (like 
the Model class). 
-Usually detaching operations are strictly dependent on the persistence 
technology adopted for model objects (like a relational db, a NoSQL db, a 
queue, etc), so it's not unusual to write a custom detachable model suited for 
the persistence technology chosen for a given project. To ease this task Wicket 
provides abstract model LoadableDetachableModel. This class internally holds a 
transient reference to a model object which is initialized the first time 
getObject()is called to precess a request. The concrete data loading is 
delegated to abstract method T load(). The reference to a model object is 
automatically set to null at the end of the request by the detach() method.
-
-The following class diagram summarizes the methods defined inside 
LoadableDetachableModel.
+Models that implement the interface @org.apache.wicket.model.IChainingModel@ 
can be used to build a chain of models. These kinds of models are able to 
recognize whether their model object is itself an implementation of IModel and 
if so, they will call getObject on the wrapped model and the returned value 
will be the actual model object. In this way we can combine the action of an 
arbitrary number of models, making exactly a chain of models. Chaining models 
allows to combine different data persistence strategies, similarly to what we 
do with chains of "I/O 
streams.":http://java.sun.com/developer/technicalArticles/Streams/ProgIOStreams 
To see model chaining in action we will build a page that implements the 
List/Detail View pattern, where we have a drop-down list of Person objects and 
a form to display and edit the data of the current selected Person.
+
+The example page will look like this:
+
+!model-chaining.png!
+
+What we want to do in this example is to chain the model of the DropDownChoice 
(which contains the selected Person) with the model of the Form. In this way 
the Form will work with the selected Person as backing object. The 
DropDownChoice component can be configured to automatically update its model 
each time we change the selected item on the client side. All we have to do is 
to override method wantOnSelectionChangedNotifications to make it return true. 
In practice, when this method returns true, DropDownChoice will submit its 
value every time JavaScript event onChange occurs, and its model will be 
consequently updated. To leverage this functionality, DropDownChoice doesn't 
need to be inside a form.
+
+The following is the resulting markup of the example page:
+
+{code:html}
+...
+<body>
+       List of persons <select wicket:id="persons"></select> <br/>
+       <br/>
+       <form wicket:id="form">         
+               <div style="display: table;">
+                       <div style="display: table-row;">
+                               <div style="display: table-cell;">Name: </div>
+                               <div style="display: table-cell;">
+                                       <input type="text" wicket:id="name"/> 
+                               </div>  
+                       </div>
+                       <div style="display: table-row;">
+                               <div style="display: table-cell;">Surname: 
</div>
+                               <div style="display: table-cell;">
+                                                                       <input 
type="text" wicket:id="surname"/>
+                                                               </div>  
+                                                       </div>
+                                                       <div style="display: 
table-row;">
+                                                               <div 
style="display: table-cell;">Address: </div>
+                                                               <div 
style="display: table-cell;">
+                                                                       <input 
type="text" wicket:id="address"/>
+                                                               </div>  
+                                                       </div>
+                                                       <div style="display: 
table-row;">
+                                                               <div 
style="display: table-cell;">Email: </div>
+                                                               <div 
style="display: table-cell;">
+                                                                       <input 
type="text" wicket:id="email"/>
+                                                               </div>
+                                                       </div>
+                                               </div>  
+                                               <input type="submit" 
value="Save"/>
+                                       </form>
+                               </body>                         
+{code}
 
-!loadable-detachable-model.png!
+The initialization code for DropDownChoice is the following:
 
-onDetach and onAttach can be overridden in order to obtain further control 
over the detaching procedure.
+{code}
+Model<Person> listModel = new Model<Person>();
+ChoiceRenderer<Person> personRender = new ChoiceRenderer<Person>("fullName");
+personsList = new DropDownChoice<Person>("persons", listModel, loadPersons(), 
personRender){
+               
+               @Override
+               protected boolean wantOnSelectionChangedNotifications() {
+                       return true;
+               }
+               
+};
+{code}
 
-Now as example of a possible use of LoadableDetachableModel, we will build a 
model designed to work with entities managed via 
"JPA.":http://en.wikipedia.org/wiki/Java_Persistence_API To understand the 
following code a basic knowledge of JPA is required even if we won't go into 
the detail of this standard.
+As choice render we have used the basic implementation provided with the 
org.apache.wicket .markup.html.form.ChoiceRenderer class that we have seen in 
the previous paragraph. loadPersons() is just an utility method which generates 
a list of Person instances. The model for DropDownChoice is a simple instance 
of the Model class.
 
-{warning}
-The following model is provided for example purposes only and is not intended 
to be used in production environment. Important aspects such as transaction 
management are not taken into account and you should rework the code before 
considering to use it.
-{warning}
+Here is the whole code of the page (except for the loadPersons() method):
 
 {code}
-public class JpaLoadableModel<T> extends LoadableDetachableModel<T> {
-  
-  private EntityManagerFactory entityManagerFactory;
-  private Class<T> entityClass;
-  private Serializable identifier;
-  private List<Object> constructorParams;
+public class PersonListDetails extends WebPage {
+  private Form form;
+  private DropDownChoice<Person> personsList;
   
-  public JpaLoadableModel(EntityManagerFactory entityManagerFactory, T entity) 
{
-     
-       super();
-     
-       PersistenceUnitUtil util = 
entityManagerFactory.getPersistenceUnitUtil();
-             
-               this.entityManagerFactory = entityManagerFactory;
-           this.entityClass = (Class<T>) entity.getClass();
-           this.identifier = (Serializable) util.getIdentifier(entity);
-
-           setObject(entity);
-       }
-
-       @Override
-       protected T load() {
-          T entity = null;
-
-          if(identifier != null) {  
-              EntityManager entityManager = 
entityManagerFactory.createEntityManager();
-              entity = entityManager.find(entityClass, identifier);
-            }
-            return entity;
-          }
-
-       @Override
-       protected void onDetach() {
-          super.onDetach();
-
-            T entity = getObject();
-            PersistenceUnitUtil persistenceUtil = 
entityManagerFactory.getPersistenceUnitUtil();
-
-            if(entity == null) return;
-
-            identifier = (Serializable) persistenceUtil.getIdentifier(entity); 
   
+  public PersonListDetails(){
+    Model<Person> listModel = new Model<Person>();
+    ChoiceRenderer<Person> personRender = new 
ChoiceRenderer<Person>("fullName");
+    
+    personsList = new DropDownChoice<Person>("persons", listModel, 
loadPersons(),
+                                                         personRender){
+      @Override
+      protected boolean wantOnSelectionChangedNotifications() {
+        return true;
+      }
+           };    
+
+           add(personsList);
+
+           form = new Form("form", new 
CompoundPropertyModel<Person>(listModel));    
+           form.add(new TextField("name"));
+           form.add(new TextField("surname"));
+           form.add(new TextField("address"));
+           form.add(new TextField("email"));
+
+           add(form);
          }
+              //loadPersons()
+              //...
        }
 {code}
 
-The constructor of the model takes as input two parameters: an implementation 
of the JPA interface  javax.persistence.EntityManagerFactory to manage JPA 
entities and the entity that must be handled by this model. Inside its 
constructor the model saves the class of the entity and its id (which could be 
null if the entity has not been persisted yet). These two informations are 
required to retrieve the entity at a later time and are used by the load method.
-
-onDetach is responsible for updating the entity id before detachment occurs. 
The id can change the first time an entity is persisted (JPA generates a new id 
and assigns it to the entity). Please note that this model is not responsible 
for saving any changes occurred to the entity object before it is detached. If 
we don't want to loose these changes we must explicitly persist the entity 
before the detaching phase occurs.
-
-{warning}
-Since the model of this example holds a reference to the EntityManager 
Factory, the implementation in use must be serializable.
-{warning}
\ No newline at end of file
+The two models work together as a pipeline where the output of method 
getObject of Model is the model object of CompoundPropertyModel. As we have 
seen, model chaining allows us to combine the actions of two or more models 
without creating new custom implementations.
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/wicket/blob/9126194a/wicket-user-guide/src/docs/guide/modelsforms/modelsforms_7.gdoc
----------------------------------------------------------------------
diff --git a/wicket-user-guide/src/docs/guide/modelsforms/modelsforms_7.gdoc 
b/wicket-user-guide/src/docs/guide/modelsforms/modelsforms_7.gdoc
index a34b7f5..2a9a097 100644
--- a/wicket-user-guide/src/docs/guide/modelsforms/modelsforms_7.gdoc
+++ b/wicket-user-guide/src/docs/guide/modelsforms/modelsforms_7.gdoc
@@ -1,30 +1,82 @@
 
 
-Sometimes our custom components may need to use more than a single model to 
work properly. In such a case we must manually detach the additional models 
used by our components. In order to do this we can overwrite the Component's 
onDetach method that is called at the end of the current request. The following 
is the generic code of a component that uses two models:
+In chapter 6 we have seen how Wicket uses serialization to store page 
instances. When an object is serialized, all its referenced objects are 
recursively serialized. For a page this means that all its children components, 
their related models as well as the model objects inside them will be 
serialized. 
+For model objects this could be a serious issue for (at least) two main 
reasons:
+
+# The model object could be a very large instance, hence serialization would 
become very expensive in terms of time and memory.
+# We simply may not be able to use a serializable object as model object. In 
paragraphs 1.4 and 9.2 we stated that Wicket allows us to use a POJO as backing 
object, but 
"POJOs":http://en.wikipedia.org/wiki/Plain_Old_Java_Object#Definition are 
ordinary objects with no prespecified interface, annotation or superclass, 
hence they are not required to implement the standard Serializable interface.
+
+To cope with these problems IModel extends another interface called 
IDetachable.
+
+!detachable-models.png!
+
+This interface provides a method called detach() which is invoked by Wicket at 
the end of web request processing when data model is no more needed but before 
serialization occurs. Overriding this method we can clean any reference to data 
object keeping just the information needed to retrieve it later (for example 
the id of the table row where our data are stored). In this way we can avoid 
the serialization of the object wrapped into the model overcoming both the 
problem with non-serializable objects and the one with large data objects.
+
+Since IModel inherits from IDetachable, every model of Wicket is 
“detachable”, although not all of them implement a detaching policy (like 
the Model class). 
+Usually detaching operations are strictly dependent on the persistence 
technology adopted for model objects (like a relational db, a NoSQL db, a 
queue, etc), so it's not unusual to write a custom detachable model suited for 
the persistence technology chosen for a given project. To ease this task Wicket 
provides abstract model LoadableDetachableModel. This class internally holds a 
transient reference to a model object which is initialized the first time 
getObject()is called to precess a request. The concrete data loading is 
delegated to abstract method T load(). The reference to a model object is 
automatically set to null at the end of the request by the detach() method.
+
+The following class diagram summarizes the methods defined inside 
LoadableDetachableModel.
+
+!loadable-detachable-model.png!
+
+onDetach and onAttach can be overridden in order to obtain further control 
over the detaching procedure.
+
+Now as example of a possible use of LoadableDetachableModel, we will build a 
model designed to work with entities managed via 
"JPA.":http://en.wikipedia.org/wiki/Java_Persistence_API To understand the 
following code a basic knowledge of JPA is required even if we won't go into 
the detail of this standard.
+
+{warning}
+The following model is provided for example purposes only and is not intended 
to be used in production environment. Important aspects such as transaction 
management are not taken into account and you should rework the code before 
considering to use it.
+{warning}
 
 {code}
-/**
- * 
- * fooModel is used as main model while beeModel must be manually detached
- *
- */
-public class ComponetTwoModels extends Component{
-
-       private IModel<Bee> beeModel;
-
-       public ComponetTwoModels(String id, IModel<Foo> fooModel, IModel<Bee> 
beeModel) {
-               super(id, fooModel);
-               this.beeModel = beeModel;
+public class JpaLoadableModel<T> extends LoadableDetachableModel<T> {
+  
+  private EntityManagerFactory entityManagerFactory;
+  private Class<T> entityClass;
+  private Serializable identifier;
+  private List<Object> constructorParams;
+  
+  public JpaLoadableModel(EntityManagerFactory entityManagerFactory, T entity) 
{
+     
+       super();
+     
+       PersistenceUnitUtil util = 
entityManagerFactory.getPersistenceUnitUtil();
+             
+               this.entityManagerFactory = entityManagerFactory;
+           this.entityClass = (Class<T>) entity.getClass();
+           this.identifier = (Serializable) util.getIdentifier(entity);
+
+           setObject(entity);
        }
 
        @Override
-       public void onDetach() {
-               if(beeModel != null)
-          beeModel.detach();
-             
-              super.onDetach();
+       protected T load() {
+          T entity = null;
+
+          if(identifier != null) {  
+              EntityManager entityManager = 
entityManagerFactory.createEntityManager();
+              entity = entityManager.find(entityClass, identifier);
+            }
+            return entity;
+          }
+
+       @Override
+       protected void onDetach() {
+          super.onDetach();
+
+            T entity = getObject();
+            PersistenceUnitUtil persistenceUtil = 
entityManagerFactory.getPersistenceUnitUtil();
+
+            if(entity == null) return;
+
+            identifier = (Serializable) persistenceUtil.getIdentifier(entity); 
   
+         }
        }
-}
 {code}
 
-When we overwrite onDetach we must call the super class implementation of this 
method, usually as last line in our custom implementation.
\ No newline at end of file
+The constructor of the model takes as input two parameters: an implementation 
of the JPA interface  javax.persistence.EntityManagerFactory to manage JPA 
entities and the entity that must be handled by this model. Inside its 
constructor the model saves the class of the entity and its id (which could be 
null if the entity has not been persisted yet). These two informations are 
required to retrieve the entity at a later time and are used by the load method.
+
+onDetach is responsible for updating the entity id before detachment occurs. 
The id can change the first time an entity is persisted (JPA generates a new id 
and assigns it to the entity). Please note that this model is not responsible 
for saving any changes occurred to the entity object before it is detached. If 
we don't want to loose these changes we must explicitly persist the entity 
before the detaching phase occurs.
+
+{warning}
+Since the model of this example holds a reference to the EntityManager 
Factory, the implementation in use must be serializable.
+{warning}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/wicket/blob/9126194a/wicket-user-guide/src/docs/guide/modelsforms/modelsforms_8.gdoc
----------------------------------------------------------------------
diff --git a/wicket-user-guide/src/docs/guide/modelsforms/modelsforms_8.gdoc 
b/wicket-user-guide/src/docs/guide/modelsforms/modelsforms_8.gdoc
index e19ac44..a34b7f5 100644
--- a/wicket-user-guide/src/docs/guide/modelsforms/modelsforms_8.gdoc
+++ b/wicket-user-guide/src/docs/guide/modelsforms/modelsforms_8.gdoc
@@ -1,22 +1,30 @@
 
 
-Like many people new to Wicket, you may need a little time to fully understand 
the power and the advantages of using models. Taking your first steps with 
Wicket you may be tempted to pass row objects to your components instead of 
using models:
+Sometimes our custom components may need to use more than a single model to 
work properly. In such a case we must manually detach the additional models 
used by our components. In order to do this we can overwrite the Component's 
onDetach method that is called at the end of the current request. The following 
is the generic code of a component that uses two models:
 
 {code}
 /**
  * 
- * NOT TO DO: passing row objects to components instead of using models!
+ * fooModel is used as main model while beeModel must be manually detached
  *
  */
-public class CustomComponent extends Component{
-       private FooBean fooBean;
+public class ComponetTwoModels extends Component{
 
-       public CustomComponent(String id, FooBean fooBean) {
-               super(id);
-               this.fooBean = fooBean;
+       private IModel<Bee> beeModel;
+
+       public ComponetTwoModels(String id, IModel<Foo> fooModel, IModel<Bee> 
beeModel) {
+               super(id, fooModel);
+               this.beeModel = beeModel;
+       }
+
+       @Override
+       public void onDetach() {
+               if(beeModel != null)
+          beeModel.detach();
+             
+              super.onDetach();
        }
-       //...some other ugly code :)...
 }
 {code}
 
-That's a bad practice and you must avoid it. Using models we do not only 
decouple our components from the data source, but we can also relay on them (if 
they are dynamic) to work with the most up-to-date version of our model object. 
If we decide to bypass models we lose all these advantages and we force model 
objects to be serialized.
\ No newline at end of file
+When we overwrite onDetach we must call the super class implementation of this 
method, usually as last line in our custom implementation.
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/wicket/blob/9126194a/wicket-user-guide/src/docs/guide/modelsforms/modelsforms_9.gdoc
----------------------------------------------------------------------
diff --git a/wicket-user-guide/src/docs/guide/modelsforms/modelsforms_9.gdoc 
b/wicket-user-guide/src/docs/guide/modelsforms/modelsforms_9.gdoc
index 95f3d97..e19ac44 100644
--- a/wicket-user-guide/src/docs/guide/modelsforms/modelsforms_9.gdoc
+++ b/wicket-user-guide/src/docs/guide/modelsforms/modelsforms_9.gdoc
@@ -1,4 +1,22 @@
 
 
-Models are at the core of Wicket and they are the basic ingredient needed to 
taste the real power of the framework. In this chapter we have seen how to use 
models to bring data to our components without littering their code with 
technical details about their persistence strategy.
-We have also introduced Wicket forms as complementary topic. With forms and 
models we are able to bring our applications to life allowing them to interact 
with users. But what we have seen in this chapter about Wicket forms is just 
the tip of the iceberg. That's why the next chapter is entirely dedicated to 
them.
\ No newline at end of file
+Like many people new to Wicket, you may need a little time to fully understand 
the power and the advantages of using models. Taking your first steps with 
Wicket you may be tempted to pass row objects to your components instead of 
using models:
+
+{code}
+/**
+ * 
+ * NOT TO DO: passing row objects to components instead of using models!
+ *
+ */
+public class CustomComponent extends Component{
+       private FooBean fooBean;
+
+       public CustomComponent(String id, FooBean fooBean) {
+               super(id);
+               this.fooBean = fooBean;
+       }
+       //...some other ugly code :)...
+}
+{code}
+
+That's a bad practice and you must avoid it. Using models we do not only 
decouple our components from the data source, but we can also relay on them (if 
they are dynamic) to work with the most up-to-date version of our model object. 
If we decide to bypass models we lose all these advantages and we force model 
objects to be serialized.
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/wicket/blob/9126194a/wicket-user-guide/src/docs/guide/toc.yml
----------------------------------------------------------------------
diff --git a/wicket-user-guide/src/docs/guide/toc.yml 
b/wicket-user-guide/src/docs/guide/toc.yml
index 5ceb256..d75318e 100644
--- a/wicket-user-guide/src/docs/guide/toc.yml
+++ b/wicket-user-guide/src/docs/guide/toc.yml
@@ -69,14 +69,15 @@ urls:
 modelsforms:
   title: Wicket models and forms
   modelsforms_1: What is a model?
-  modelsforms_2: Models and JavaBeans
-  modelsforms_3: Wicket forms
-  modelsforms_4: Component DropDownChoice
-  modelsforms_5: Model chaining
-  modelsforms_6: Detachable models
-  modelsforms_7: Using more than one model in a component
-  modelsforms_8: Use models!
-  modelsforms_9: Summary
+  modelsforms_2: IModel and Lambda  
+  modelsforms_3: Models and JavaBeans
+  modelsforms_4: Wicket forms
+  modelsforms_5: Component DropDownChoice
+  modelsforms_6: Model chaining
+  modelsforms_7: Detachable models
+  modelsforms_8: Using more than one model in a component
+  modelsforms_9: Use models!
+  modelsforms_10: Summary
 forms2:
   title: Wicket forms in detail
   forms2_1: Default form processing

Reply via email to