You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@isis.apache.org by da...@apache.org on 2014/02/12 00:31:11 UTC

[14/51] [partial] ISIS-694: mothballing the docbkx folders.

http://git-wip-us.apache.org/repos/asf/isis/blob/7a7836e3/mothballed/docbkx/core/applib/src/docbkx/guide/isis-applib.xml
----------------------------------------------------------------------
diff --git a/mothballed/docbkx/core/applib/src/docbkx/guide/isis-applib.xml b/mothballed/docbkx/core/applib/src/docbkx/guide/isis-applib.xml
new file mode 100644
index 0000000..d88bc58
--- /dev/null
+++ b/mothballed/docbkx/core/applib/src/docbkx/guide/isis-applib.xml
@@ -0,0 +1,7488 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN"
+"file:./src/docbkx/dtd-4.5/docbookx.dtd">
+<!--
+  Licensed to the Apache Software Foundation (ASF) under one
+  or more contributor license agreements.  See the NOTICE file
+  distributed with this work for additional information
+  regarding copyright ownership.  The ASF licenses this file
+  to you under the Apache License, Version 2.0 (the
+  "License"); you may not use this file except in compliance
+  with the License.  You may obtain a copy of the License at
+
+        http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing,
+  software distributed under the License is distributed on an
+  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+  KIND, either express or implied.  See the License for the
+  specific language governing permissions and limitations
+  under the License.
+-->
+<book>
+  <bookinfo>
+    <title><?eval ${docbkxGuideTitle}?></title>
+
+    <subtitle><?eval ${docbkxGuideSubTitle}?></subtitle>
+
+    <releaseinfo><?eval ${project.version}?></releaseinfo>
+
+    <authorgroup>
+      <author>
+        <firstname>Dan</firstname>
+
+        <surname>Haywood</surname>
+      </author>
+
+      <author>
+        <firstname>Robert</firstname>
+
+        <surname>Matthews</surname>
+      </author>
+    </authorgroup>
+
+    <legalnotice>
+      <para>Permission is granted to make and distribute verbatim copies of
+      this manual provided that the copyright notice and this permission
+      notice are preserved on all copies.</para>
+    </legalnotice>
+  </bookinfo>
+
+  <!-- front matter -->
+
+  <toc></toc>
+
+  <preface id="preface">
+    <title>Preface</title>
+
+    <para><emphasis>Apache Isis</emphasis> is designed to allow programmers
+    rapidly develop domain-driven applications following the <ulink
+    url="http://en.wikipedia.org/wiki/Naked_Objects">Naked Objects</ulink>
+    pattern. It is made up of a core plus a number of components for each of
+    the main APIs: objectstores, security, viewers and profilestores.</para>
+
+    <para>This guide is written for programmers looking to understand the
+    programming conventions, annotations and supporting utilities within the
+    <emphasis>Apache Isis</emphasis> application library (or
+    <emphasis>applib</emphasis>), in order that the framework can correctly
+    pick up and render the business rules and logic encoded within their
+    domain objects.</para>
+
+    <para><emphasis>Apache Isis</emphasis> is hosted at the <ulink
+    url="http://incubator.apache.org/isis">Apache Foundation</ulink>, and is
+    licensed under <ulink
+    url="http://www.apache.org/licenses/LICENSE-2.0.html">Apache Software
+    License v2</ulink>.</para>
+  </preface>
+
+  <!-- main content -->
+
+  <part id="prt.WritingDomainObjects">
+    <title>Writing Domain Objects</title>
+
+    <partintro>
+      <para>The conventions of the programming model are best described as
+      'intentional' - they convey an intention as to how domain objects, their
+      properties and behaviours, are to be made available to users. The
+      specific way in which those intentions are interpreted or implemented
+      will depend upon the framework, and/or the particular components or
+      options selected within that framework.</para>
+
+      <para>To pick a single example, marking up a domain class with the
+      annotation <code>@Bounded</code> is an indication that the class is
+      intended to have only a small number of instances and that the set does
+      not change very often - such as the class <code>Country</code>. This is
+      an indication to a viewer, for example, that the whole set of instances
+      might be offered to the user in a convenient form such as a drop-down
+      list. The programming convention has <emphasis>not</emphasis> been
+      defined as <code>@DropDownList</code> because any equivalent mechanism
+      will suffice: a viewer might not support drop-down-lists but instead
+      might provide a capability to select from an <code>@Bounded</code> class
+      by typing the initial letters of the desired instance.</para>
+
+      <para>This part of the guide is a set of chapters that provides how-to's
+      for writing domain objects, by which we mean domain entities, value
+      types, services and repositories/factories.</para>
+    </partintro>
+
+    <chapter id="chp.Objects">
+      <title>How to write a basic Domain Entity or Service</title>
+
+      <abstract>
+        <para>How-to write a basic domain entity or service, specifying its
+        properties, collections and actions, and using some of the most
+        commonly-used additional semantics.</para>
+      </abstract>
+
+      <para>Domain entities are instances of some class, usually (the vast
+      majority) being persisted. Domain services are singletons that act
+      typically act as factories and repositories. Domain entities have state
+      in the form of properties and collections; domain services do not. Both
+      domain entities and services have behaviour, in the form of
+      actions.</para>
+
+      <sect1>
+        <title>How to have a domain entity be a POJO (not inherit from
+        framework superclasses)</title>
+
+        <para>It isn't mandatory for domain entities to inherit from any
+        framework superclass; they can be plain old java objects (pojos) if
+        required. However, they do at a minimum need to have a
+        <classname>org.apache.isis.applib.DomainObjectContainer</classname>
+        injected into them (an interface), from which other framework services
+        can be accessed.</para>
+
+        <para>If you don't have a requirement to inherit from any other
+        superclass, then it usually makes sense to inherit from mention
+        <classname>org.apache.isis.applib.AbstractDomainObject</classname>,
+        which already supports the
+        <classname>DomainObjectContainer</classname> and has a number of
+        convenience helper methods.</para>
+
+        <para>There is further coverage of
+        <classname>DomainObjectContainer</classname> in <xref
+        linkend="sec.LifecycleMethods" /> and also in <xref
+        linkend="chp.DomainServices" />.</para>
+      </sect1>
+
+      <sect1 id="sec.AbstractService">
+        <title>How to have a domain service be a POJO (not inherit from
+        framework superclasses)</title>
+
+        <para>Like entities, it isn't mandatory for domain services to inherit
+        from any framework superclass; they can be plain-old pojos if
+        required. However, again, like entities, they do at a minimum need to
+        have a
+        <classname>org.apache.isis.applib.DomainObjectContainer</classname>
+        injected into them (an interface), from which other framework services
+        can be accessed.</para>
+
+        <para>If you don't have a requirement to inherit from any other
+        superclass, then it usually makes sense to inherit from one of the
+        abstract classes in the applib, either
+        <classname>org.apache.isis.applib.AbstractService</classname> or
+        <classname>org.apache.isis.applib.AbstractRepositoryAndFactory</classname>.
+        These already supports the
+        <classname>DomainObjectContainer</classname> and have a number of
+        convenience helper methods.</para>
+
+        <para>The <acronym>UML</acronym> class diagram below shows the
+        relationship between these types and the
+        <classname>DomainObjectContainer</classname>.</para>
+
+        <mediaobject>
+          <imageobject>
+            <imagedata fileref="images/AbstractContainedObject-hierarchy.png"
+                       scale="65" />
+          </imageobject>
+        </mediaobject>
+
+        <para>What this means is that <emphasis>Apache Isis</emphasis> treats
+        factories and repositories as just another type of domain
+        service.</para>
+      </sect1>
+
+      <sect1>
+        <title>How to add a property to a domain entity</title>
+
+        <para>A property is a scalar attribute or field of a domain entity.
+        Its type can be either a value type (such as an int, Date or String),
+        or a reference to another entity.</para>
+
+        <para>Properties are specified using the JavaBean conventions,
+        recognizing a standard accessor/mutator pair (<code>get</code> and
+        <code>set</code>).</para>
+
+        <para>The syntax is:</para>
+
+        <para><programlisting>public PropertyType getPropertyName() 
+
+public void setPropertyName(PropertyType param)</programlisting></para>
+
+        <para>where <literal moreinfo="none">PropertyType</literal> is a
+        primitive, a value object or an entity object.</para>
+
+        <para>Properties may either be for a value type or may reference
+        another entity. Values include Java primitives, and JDK classes with
+        value semantics (eg <literal
+        moreinfo="none">java.lang.Strings</literal> and <literal
+        moreinfo="none">java.util.Dates</literal>; see <xref
+        linkend="chp.ValueTypes" /> for the full list). It is also possible to
+        write your own value types (see <xref linkend="chp.ValueTypes" />). A
+        property referencing another domain object is sometimes called an
+        association.</para>
+
+        <para>For example, the following example contains both a value
+        (<literal moreinfo="none">String</literal>) property and a reference
+        (<literal moreinfo="none">Organisation</literal>) property:</para>
+
+        <programlisting format="linespecific">public class Customer {
+
+    private String firstName;
+    public String getFirstName() {
+        return firstName;
+    }
+    public void setFirstName(String firstName) {
+        this.firstName = firstName;
+    }
+
+
+    private Organisation organisation;
+    public Organisation getOrganisation() {
+        return organisation;
+    }
+    public void setOrganisation(Organisation organisation) { 
+        this.organisation = organisation;
+    }
+
+    ...
+}</programlisting>
+      </sect1>
+
+      <sect1>
+        <title condition="java">How to specify a title for a domain
+        entity</title>
+
+        <para>A title is used to identify an object to the user in the user
+        interface. For example, a <classname>Customer</classname>'s title
+        might be the organization's customer reference, or perhaps (more
+        informally) their first and last names.</para>
+
+        <para>By default, the framework will use the object's <literal
+        moreinfo="none">toString()</literal> method as the title. Most titles
+        tend to be made up of the same set of elements: for example a
+        Customer's name might be the concatenation of their customer first
+        name and their ;ast name. For these the <classname>@Title</classname>
+        annotation can be used:</para>
+
+        <para><programlisting>public class Customer {
+  @Title
+  public String getFirstName() { ... }
+  @Title
+  public String getLastName() { ... }
+  ...
+}</programlisting></para>
+
+        <para>For more control, the order of the title components can be
+        specified using a sequence number (specified in Dewey decimal
+        format):</para>
+
+        <programlisting>public class Customer {
+  @Title("1.0")
+  public String getFirstName() { ... }
+  @Title("1.1")
+  public String getLastName() { ... }
+  ...
+}</programlisting>
+
+        <para>For more control the title can be declared imperately using the
+        <literal moreinfo="none">title()</literal> method (returning a
+        <literal moreinfo="none">String</literal>). This leaves the programmer
+        needs to make use of the <literal moreinfo="none">toString()</literal>
+        method for other purposes, such as for debugging. For example, to
+        return the title for a customer which is their last name and then
+        first initial of their first name, we could use:</para>
+
+        <para><programlisting>public class Customer {
+  public String title() {
+    return getLastName() + ", " + getFirstName().substring(0,1);
+  } 
+  ...
+}</programlisting></para>
+
+        <para>The applib contains a class,
+        <classname>org.apache.isis.applib.util.TitleBuffer</classname>, which
+        you can use to help create title strings if you so wish. See <xref
+        linkend="apx.UtilityClasses" /> for more details.</para>
+      </sect1>
+
+      <sect1>
+        <title>How to add a collection to a domain entity</title>
+
+        <para>A collection is a multi-valued attribute/field of a entity, in
+        other words a <code>List</code> or a <code>Set</code>, containing
+        references to other domain entities. <code>Map</code>s are not
+        supported. Collections of value types are not supported.</para>
+
+        <para>A collection is recognized via an accessor/mutator method pair
+        (<code>get</code> and set) for any type of collection provided by the
+        programming language.</para>
+
+        <para>The syntax is either:</para>
+
+        <para><programlisting>public Collection&lt;EntityType&gt; getCollectionName()
+private void setCollectionName(Collection&lt;EntityType&gt; param)</programlisting></para>
+
+        <para>or:</para>
+
+        <para><programlisting>public List&lt;EntityType&gt; getCollectionName()
+private void setCollectionName(List&lt;EntityType&gt; param)</programlisting></para>
+
+        <para>or:</para>
+
+        <para><programlisting>public Set&lt;EntityType&gt; getCollectionName()
+private void setCollectionName(Set&lt;EntityType&gt; param)</programlisting></para>
+
+        <para>A mutator is required, but it need only have
+        <code>private</code> visibility.</para>
+
+        <para>Note:</para>
+
+        <note>
+          <para><classname>Map</classname>s cannot be used for
+          collections.</para>
+        </note>
+
+        <para>It is recommended that the collections be specified using
+        generics (for example: <literal
+        moreinfo="none">List&lt;Customer&gt;</literal> ). That way the
+        framework will be able to display the collection based on that type
+        definition. If a raw type is used then the framework will attempt to
+        infer the type from the addToXxx() / removeFromXxx() supporting
+        methods, if specified (see <xref linkend="sec.AddToRemoveFrom" />). If
+        the framework is unable to determine the type of the collection, it
+        will mean that some viewers will represent the collection is a less
+        sophisticated manner (eg a simple list of titles rather than a
+        table).</para>
+
+        <para>For example:</para>
+
+        <programlisting format="linespecific">public class Employee { ... }
+
+public class Department {
+    private List&lt;Employee&gt; employees = new ArrayList&lt;Employee&gt;();
+    public List &lt;Employee&gt; getEmployees() {
+        return employees;
+    }
+    private void setEmployees(List&lt;Employee&gt; employees) { 
+        this.employees = employees;
+    }
+    ...
+}</programlisting>
+      </sect1>
+
+      <sect1>
+        <title>How to add an action (or bulk action) to a domain entity or
+        service</title>
+
+        <para>An 'action' is a method that we expect the user to be able to
+        invoke on a domain entity via the user interface, though it may also
+        be invoked programmatically within the object model. The following
+        conventions are used to determine when and how methods are made
+        available to the user as actions, and the means by which a user can
+        interact with those actions</para>
+
+        <para>By default, any <literal moreinfo="none">public</literal>
+        instance method that you add to a class will be treated as a user
+        action, unless it represents a property, collection, or another
+        reserved method defined in this guide.</para>
+
+        <para>The syntax is:</para>
+
+        <para><programlisting>public void actionName([ValueOrEntityType param] ...)</programlisting></para>
+
+        <para>or</para>
+
+        <para><programlisting>public ReturnType actionName([ValueOrEntityType param] ...)</programlisting></para>
+
+        <para>When a method returns a reference the viewer will attempt to
+        display that object. If the return value is <code>null</code> then
+        nothing is displayed.</para>
+
+        <para>We refer to all methods that are intended to be invoked by users
+        as 'action methods'.</para>
+
+        <para>If you have a method that you don't want to be made available as
+        a user-action you can either:</para>
+
+        <itemizedlist>
+          <listitem>
+            <para>make it non-<literal>public</literal> (eg <literal
+            moreinfo="none">protected</literal> or <literal
+            moreinfo="none">private</literal>)</para>
+          </listitem>
+
+          <listitem>
+            <para>annotate it with <classname>@Ignore</classname></para>
+          </listitem>
+
+          <listitem>
+            <para>annotate it with <classname>@Hidden</classname> (discussed
+            further in <xref linkend="sec.HiddenActions" />)</para>
+          </listitem>
+        </itemizedlist>
+
+        <para>Note also that <literal moreinfo="none">static</literal> methods
+        are ignored: such functionality should reside in a service, such as a
+        repository or factory (see <xref
+        linkend="chp.DomainServices" />).</para>
+
+        <para>If the action is a bulk action - meaning that it should only be
+        applied to a collection of instances of the entity - then annotate
+        using <classname>@Bulk</classname>:</para>
+
+        <programlisting>@Bulk
+public void actionName() { ... }</programlisting>
+
+        <para>Note that bulk actions have a couple of important
+        restrictions.</para>
+
+        <itemizedlist>
+          <listitem>
+            <para>entity actions cannot take any arguments, while contributed
+            actions can take only a single parameter (the contributee)</para>
+
+            <para>This restriction might be lifted in the future;</para>
+          </listitem>
+
+          <listitem>
+            <para>any business rules for hiding, disabling or validating the
+            action are ignored.</para>
+          </listitem>
+        </itemizedlist>
+
+        <para>See <xref linkend="chp.BusinessRules" /> for more details on
+        writing business rules.</para>
+
+        <para>At the time of writing, only the Wicket viewer recognizes bulk
+        actions; other viewers treat the action as a regular action.</para>
+      </sect1>
+
+      <sect1 id="sec.HowToSpecifyTheIconForAnObjectsClass">
+        <title condition=".net">How to specify the icon for a domain
+        entity</title>
+
+        <para condition="1.5">By default, the framework will look for an image
+        in the <filename class="directory" moreinfo="none">images</filename>
+        directory (either from the classpath or from the filesystem) that has
+        the same name as the object class. Multiple file extensions are
+        searched for, including <filename>.png</filename>,
+        <filename>.gif</filename> and <filename>.jpg</filename> (in order of
+        preference). For example, fan object of type
+        <classname>Customer</classname> it will look for <filename
+        class="directory" moreinfo="none">Customer.png</filename>, <filename
+        class="directory" moreinfo="none">Customer.gif</filename>,
+        <filename>Customer.jpg</filename> etc.</para>
+
+        <para condition="1.5">If the framework finds no such file, then it
+        will work up the inheritance hierarchy to see if there is an icon
+        matching the name of any of the super-classes, and use that instead.
+        If no matching icon is found then the framework will look for an image
+        called <filename class="directory"
+        moreinfo="none">default.png</filename>,
+        <filename>default.gif</filename> or <filename>default.jpg</filename>
+        in the images directory, and if this has not been specified, then the
+        framework will use its own default image for an icon.</para>
+
+        <para>We strongly recommend that you adopt 'pascal case' as the
+        convention for icon file names: if you have a class called <classname
+        condition="vb"> OrderLine</classname>, then call the icon <filename
+        class="directory" moreinfo="none">OrderLine.png</filename>. Actually,
+        the framework will also recognise <filename class="directory"
+        moreinfo="none">orderline.png</filename>, but some operating systems
+        and deployment environments are case sensitive, so it is good practice
+        to adopt an unambiguous convention.</para>
+
+        <para>Alternatively, you can use the <literal
+        moreinfo="none">iconName</literal>() method instead:</para>
+
+        <programlisting format="linespecific">public String iconName() {
+    return "Person";
+}</programlisting>
+
+        <para>This makes it easy for more than one class to use the same icon,
+        without having to duplicate the image file.</para>
+      </sect1>
+
+      <sect1 id="sec.MemberOrderForProperties">
+        <title>How to specify the order in which properties or collections are
+        displayed</title>
+
+        <para>The <literal moreinfo="none">@MemberOrder</literal> annotation
+        provides a hint to the viewer as to the order in which the properties
+        and collections should appear in the <acronym>GUI</acronym>.</para>
+
+        <para>For example:</para>
+
+        <programlisting format="linespecific">public class Customer() {
+    @MemberOrder("1")
+    public String getFirstName() { ... }
+    ...
+
+    @MemberOrder("2")
+    public String getLastName() { ... }
+    ...
+
+    @MemberOrder("3")
+    public Collection&lt;Order&gt; getOrders() { ... }
+    ...
+}</programlisting>
+      </sect1>
+
+      <sect1>
+        <title>How to specify the order in which actions appear on the
+        menu</title>
+
+        <para>The <literal moreinfo="none">@MemberOrder</literal> annotation
+        provides a hint to the viewer as to the order in which the actions
+        should be displayed, eg in a menu.</para>
+
+        <para>For example:</para>
+
+        <programlisting format="linespecific">public class Customer {
+    @MemberOrder("3")
+    public void placeOrder(Product p) { ... }
+    ...
+
+    @MemberOrder("4")
+    public void blackList() { ... }
+    ...
+}</programlisting>
+
+        <para>The syntax for the <classname>@MemberOrder</classname> is dewey
+        decimal notation, so "3.5" and "3.6" come between "3" and "4"; "3.5.1"
+        comes between "3.5" and "3.6".</para>
+      </sect1>
+
+      <sect1>
+        <title>How to make a property optional (when saving an object)</title>
+
+        <para>By default, when a new transient (unsaved) object is presented
+        to the user, values must be specified for all properties before the
+        object may be saved.</para>
+
+        <para>To specify that a particular property is optional, use the
+        <literal moreinfo="none">@Optional</literal> annotation.</para>
+      </sect1>
+
+      <sect1>
+        <title>How to make an action parameter optional</title>
+
+        <para>By default, the framework assumes that when an action method is
+        to be invoked, all the parameters are mandatory. You may override this
+        behaviour by marking up one or more of the paramaters with the
+        <literal moreinfo="none">@Optional</literal> annotation.</para>
+      </sect1>
+
+      <sect1 id="sec.SizeProperties">
+        <title>How to specify the size of <classname>String</classname>
+        properties</title>
+
+        <para>Use:</para>
+
+        <itemizedlist>
+          <listitem>
+            <para>the <literal moreinfo="none">@MaxLength</literal> to specify
+            the maximum number of characters that may be stored within a
+            <classname>String</classname> property.</para>
+          </listitem>
+
+          <listitem>
+            <para>the <literal moreinfo="none">@TypicalLength</literal> to
+            specify the typical number of characters that are likely to be
+            stored within a <classname>String</classname> property. Viewers
+            are expected to use this as a hint as to the size of the field to
+            render for the property.</para>
+          </listitem>
+
+          <listitem>
+            <para>the <literal moreinfo="none">@MultiLine</literal> annotation
+            as a hint to indicate that the property should be displayed over
+            multiple lines (eg as a text area rather than a text
+            field).</para>
+          </listitem>
+        </itemizedlist>
+
+        <para>For example:</para>
+
+        <programlisting format="linespecific">public class Ticket {
+    @TypicalLength(50)
+    @MaxLength(255)
+    public String getDescription() { ... }
+    ...
+
+    @MaxLength(2048)
+    @MultiLine
+    public String getNotes() { ... }
+    ...
+}</programlisting>
+      </sect1>
+
+      <sect1>
+        <title>How to specify the size of <classname>String</classname> action
+        parameters</title>
+
+        <para>As for properties (see <xref linkend="sec.SizeProperties" />),
+        use:</para>
+
+        <itemizedlist>
+          <listitem>
+            <para>the <literal moreinfo="none">@MaxLength</literal> to specify
+            the maximum number of characters that may be stored within a
+            <classname>String</classname> parameter.</para>
+          </listitem>
+
+          <listitem>
+            <para>the <literal moreinfo="none">@TypicalLength</literal> to
+            specify the typical number of characters that are likely to be
+            stored within a <classname>String</classname> parameter. Viewers
+            are expected to use this as a hint as to the size of the field to
+            render for the parameter.</para>
+          </listitem>
+
+          <listitem>
+            <para>the <literal moreinfo="none">@MultiLine</literal> annotation
+            as a hint to indicate that the parameter should be displayed over
+            multiple lines (eg as a text area rather than a text
+            field).</para>
+          </listitem>
+        </itemizedlist>
+
+        <para>For example:</para>
+
+        <programlisting format="linespecific">public class TicketRaiser {
+
+    public void raiseTicket(
+            @TypicalLength(50) @MaxLength(255) @Named("Description")
+            String getDescription,
+            @MaxLength(2048) @MultiLine @Named("Notes")
+            String notes) {
+        ...
+    }
+    ...
+}</programlisting>
+      </sect1>
+
+      <sect1 id="sec.ActionParameterNames">
+        <title>How to specify names and/or descriptions for an action
+        parameter</title>
+
+        <para>Unlike with properties, the framework cannot pick up the names
+        of parameters that you use within the domain code. By default
+        parameters will be labelled only with the type of the object required
+        (e.g. 'String:' or 'Customer:)</para>
+
+        <para>If you want a parameter to have a different name (such as 'First
+        Name', 'Last Name') then that parameter should be marked up with an
+        <literal moreinfo="none">@Named</literal> annotation - very often
+        taking the same form as the parameter name used in the code.
+        Alternatively though, you could create a user-defined value type,
+        using <literal>@Value</literal> (see <xref
+        linkend="chp.ValueTypes" />).</para>
+
+        <para>Similarly, any parameter may be given a short user-description
+        using the <literal moreinfo="none">@DescribedAs</literal> annotation.
+        The framework takes responsibility to make this available to the
+        user.</para>
+
+        <para>For example:</para>
+
+        <programlisting format="linespecific">public class Customer {
+    public Order placeOrder(
+            Product p, 
+            @Named("Quantity")
+            @DescribedAs("The number of units of the specified product in this order")
+            int quantity) {
+        ...
+    }
+    ...
+}</programlisting>
+      </sect1>
+
+      <sect1>
+        <title>How to inject services into a domain entity or other
+        service</title>
+
+        <para>All that is required to inject a service into an entity (or
+        indeed into another service) is to provide an appropriately typed
+        setter. The name of the method does not matter, only that it is
+        prefixed "set", is public, and has a single parameter of the correct
+        type.</para>
+
+        <para>For example:</para>
+
+        <programlisting>public class Customer {
+    private OrderRepository orderRepository;
+    public void setOrderRepository(OrderRepository orderRepository) {
+        this.orderRepository = orderRepository;
+    }
+    ...
+}</programlisting>
+
+        <para>Note that we consider
+        <classname>DomainObjectContainer</classname> to be a service too;
+        hence it can be injected in exactly the same manner.</para>
+      </sect1>
+
+      <sect1 id="sec.HowToCreateAnObject">
+        <title>How to create or delete objects within your code</title>
+
+        <para>When you create any domain object within your application code,
+        it is important that the framework is made aware of the existence of
+        this new object - in order that it may be persisted to the object
+        store, and in order that any services that the new object needs are
+        injected into it.</para>
+
+        <para>Just specifying <literal moreinfo="none">new
+        Customer()</literal>, for example, will create a
+        <classname>Customer</classname> object, but that object will
+        <emphasis>not</emphasis> be known to the framework. However, since we
+        do not want to tie our domain objects to a particular framework, we
+        use the idea of a 'container' to mediate, specified by the <literal
+        moreinfo="none">org.apache.isis.applib.DomainObjectContainer</literal>
+        interface. See <xref linkend="apx.DomainObjectContainer" /> for the
+        full list of methods provided by
+        <classname>DomainObjectContainer</classname>.</para>
+
+        <para>This interface defines the following methods for managing domain
+        objects:</para>
+
+        <itemizedlist>
+          <listitem>
+            <para><literal moreinfo="none">&lt;T&gt; T
+            newTransientInstance(final Class&lt;T&gt;
+            ofClass)</literal></para>
+
+            <para>Returns a new instance of the specified class, that is
+            transient (unsaved). The object may subsequently be saved either
+            by the user invoking the Save action (that will automatically be
+            rendered on the object view) or programmatically by calling
+            <literal moreinfo="none">persist(Object
+            transientObject)</literal></para>
+          </listitem>
+
+          <listitem>
+            <para><methodname>&lt;T&gt; T newPersistentInstance(final
+            Class&lt;T&gt; ofClass)</methodname></para>
+
+            <para>Creates a new object already persisted.</para>
+          </listitem>
+
+          <listitem>
+            <para><methodname>boolean isPersistent()</methodname></para>
+
+            <para>Checks whether an object has already been persisted. This is
+            often useful in controlling visibility or availability of
+            properties or actions.</para>
+          </listitem>
+
+          <listitem>
+            <para><methodname>void persist(Object
+            transientObject)</methodname></para>
+
+            <para>Persists a transient object (created using
+            <methodname>newTransientInstance(...)</methodname>, see
+            above).</para>
+          </listitem>
+
+          <listitem>
+            <para><methodname>void persistIfNotAlready(Object
+            domainObject)</methodname></para>
+
+            <para>It is an error to persist an object if it is already
+            persistent; this method will persist only if the object is not
+            already persistent (otherwise it will do nothing).</para>
+          </listitem>
+
+          <listitem>
+            <para><methodname>void remove(Object
+            persistentObject)</methodname></para>
+
+            <para>Removes (deletes) from the object store, making the
+            reference transient.</para>
+          </listitem>
+
+          <listitem>
+            <para><methodname>void removeIfNotAlready(Object
+            domainObject)</methodname></para>
+
+            <para>It is an error to remove an object if it is not persistent;
+            this method will remove only if the object is known to be
+            persistent (otherwise it will do nothing).</para>
+          </listitem>
+        </itemizedlist>
+
+        <para>A domain object specifies that it needs to have a reference to
+        the <classname>DomainObjectContainer</classname> injected into by
+        including the following code:</para>
+
+        <programlisting format="linespecific">private DomainObjectContainer container;
+protected DomainObjectContainer getContainer() {
+    return container;
+}
+public final void setContainer(final DomainObjectContainer container) {
+    this.container = container;
+}</programlisting>
+
+        <para>Creating or deleting objects is then done by invoking those
+        methods on the container. For example the following code would then
+        create a new <classname>Customer</classname> object within another
+        method:</para>
+
+        <programlisting format="linespecific">Customer newCust = getContainer().newTransientInstance(Customer.class);
+newCust.setName("Charlie");
+getContainer().persist(newCust);</programlisting>
+
+        <para>If you are able to make your domain object inherit from <literal
+        moreinfo="none">org.apache.isis.applib.AbstractDomainObject</literal>
+        then you have direct access to those methods, so the code would
+        become:</para>
+
+        <programlisting format="linespecific">Customer newCust = newTransientInstance(Customer.class);
+newCust.setName("Charlie");
+persist(newCust);</programlisting>
+
+        <para>As an alternative to putting the creation logic within your
+        domain objects, you could alternatively delegate to an injected
+        factory (see <xref linkend="chp.DomainServices" />). Ultimately
+        factories just delegate back to
+        <classname>DomainObjectContainer</classname> in the same way, so from
+        a technical standpoint there is little difference. However it is
+        generally worth introducing a factory because it provides a place to
+        centralize any business logic. It also affords the opportunity to
+        introduce a domain term (eg <classname>ProductCatalog</classname> or
+        <classname>StudentRegister</classname>), thereby reinforcing the
+        "ubiquitous language".</para>
+
+        <para>These methods are actually provided by the
+        <classname>org.apache.isis.applib.AbstractContainedObject</classname>
+        and so are also available on <literal
+        moreinfo="none">org.apache.isis.applib.AbstractService</literal> (and,
+        hence, on <literal
+        moreinfo="none">org.apache.isis.applib.AbstractFactoryAndRepository</literal>)
+        for creating objects within a service.</para>
+
+        <warning>
+          <para>It is possible to create a transient object within another
+          transient object. When the framework persists any transient object,
+          by default it will automatically persist any other transient object
+          referenced by that object. However, if any of these transient
+          objects are to be exposed to the user (while in their transient
+          state), then you need to write your code very carefully -
+          anticipating the fact that the user could elect to save any of the
+          transient objects at any point - which could cause the graph of
+          related objects to be persisted in an invalid state.</para>
+
+          <para>The recommended approach is, if possible, to mark these
+          supplementary classes as not persistable by the user (see <xref
+          linkend="not-persistable" />), or not to permit the user to create a
+          new transient object that is a child of an existing transient
+          object, but, rather, to require the user to save the parent object
+          first.</para>
+        </warning>
+      </sect1>
+    </chapter>
+
+    <chapter id="chp.BusinessRules">
+      <title>How to add business rules</title>
+
+      <abstract>
+        <para>How-to add business rules to domain entities and services,
+        controlling whether a domain entity or service's class members are
+        visible, if they are enabled, and to validate arguments.</para>
+      </abstract>
+
+      <para>Business rules can be added to domain objects in a number of ways.
+      As well as the business logic encapsulated by domain object actions, the
+      framework also supports a number of conventions that allow a domain
+      entity or service's members to be made visible or hidden, to be enabled
+      or disabled (greyed out), and to validate arguments when invoking an
+      action, setting a new value for a property, or if adding a new element
+      to a collection.</para>
+
+      <para>Or, in other words: "see it, use it, do it".</para>
+
+      <sect1 id="sec.HiddenProperty">
+        <title>How to hide a property</title>
+
+        <para>The mechanism for hiding a property is broadly the same as for
+        hiding a collection (see <xref linkend="sec.HiddenCollection" />) or
+        an action (see <xref linkend="sec.HiddenActions" />).</para>
+
+        <para>For control over the entire object, see <xref
+        linkend="sec.Entity.Hidden" />.</para>
+
+        <sect2>
+          <title>Hiding a property always</title>
+
+          <para>To prevent a user from viewing a property at all, use the
+          <literal moreinfo="none">@Hidden</literal> annotation. A common use
+          case is to hide an internal Id, eg perhaps as required by the object
+          store.</para>
+
+          <para>For example:</para>
+
+          <programlisting format="linespecific">public class OrderLine {
+    private Integer id;
+    @Hidden
+    public Integer getId() { ... }
+    public void setId(Integer id) { ... }
+    ...
+}</programlisting>
+        </sect2>
+
+        <sect2>
+          <title>Hiding a property based on the persistence state of the
+          object</title>
+
+          <para>As a refinement of the above, a property may be optionally
+          hidden using the <classname>@Hidden</classname> annotation based on
+          the persistence state of the object:</para>
+
+          <itemizedlist>
+            <listitem>
+              <para>to hide the property when the object is transient, use
+              <code>@Hidden(When.UNTIL_PERSISTED)</code></para>
+            </listitem>
+
+            <listitem>
+              <para>to hide the property when the object is persistent, use
+              <code>@Hidden(When.ONCE_PERSISTED)</code></para>
+            </listitem>
+          </itemizedlist>
+        </sect2>
+
+        <sect2>
+          <title>Hiding a property under certain conditions</title>
+
+          <para>A <literal moreinfo="none">hideXxx()</literal> method can be
+          used to indicate that a particular object's property should be
+          hidden under certain conditions, typically relating to the state of
+          that instance.</para>
+
+          <para>The syntax is:</para>
+
+          <programlisting><literal moreinfo="none">public boolean hidePropertyName()</literal> </programlisting>
+
+          <para>Returning a value of <code>true</code> indicates that the
+          property should be hidden.</para>
+
+          <para>For example:</para>
+
+          <programlisting format="linespecific">public class Order {
+    public String getShippingInstructions() { ... }
+    public void setShippingInstructions(String shippingInstructions) { ... }
+    public boolean hideShippingInstructions() {
+        return hasShipped();
+    }
+    ...
+}</programlisting>
+        </sect2>
+
+        <sect2>
+          <title>Hiding a property for specific users or roles</title>
+
+          <para>It is possible to hide properties for certain users/roles by
+          calling the <methodname>DomainObjectContainer#getUser()</methodname>
+          method. See <xref
+          linkend="sec.BusinessRulesForCertainUsersOrRoles" />for further
+          discussion.</para>
+        </sect2>
+      </sect1>
+
+      <sect1 id="sec.HiddenCollection">
+        <title>How to hide a collection</title>
+
+        <para>The mechanism for hiding a collection is broadly the same as for
+        hiding a property (see <xref linkend="sec.HiddenProperty" />) or an
+        action (see <xref linkend="sec.HiddenActions" />).</para>
+
+        <sect2>
+          <title>Hiding a collection permanently</title>
+
+          <para>To prevent a user from viewing a collection at all, use the
+          <literal moreinfo="none">@Hidden</literal> annotation.</para>
+
+          <para>For example:</para>
+
+          <programlisting format="linespecific">public class Order {
+    private List&lt;Order&gt; cancelledOrders = new ArrayList&lt;Order&gt;();
+    @Hidden
+    public List&lt;Order&gt; getCancelledOrders() { ... }
+    private void setCancelledOrders(List&lt;Order&gt; cancelledOrders) { ... }
+    ...
+}</programlisting>
+        </sect2>
+
+        <sect2>
+          <title>Hiding a collection based on the persistence state of the
+          object</title>
+
+          <para>As a refinement of the above, a collection may be optionally
+          hidden using the <classname>@Hidden</classname> annotation based on
+          the persistence state of the object:</para>
+
+          <itemizedlist>
+            <listitem>
+              <para>to hide the collection when the object is transient, use
+              <code>@Hidden(When.UNTIL_PERSISTED)</code></para>
+            </listitem>
+
+            <listitem>
+              <para>to hide the collection when the object is persistent, use
+              <code>@Hidden(When.ONCE_PERSISTED)</code></para>
+            </listitem>
+          </itemizedlist>
+        </sect2>
+
+        <sect2>
+          <title>Hiding a collection under certain conditions</title>
+
+          <para>A <literal moreinfo="none">hideXxx()</literal> method can be
+          used to indicate that a particular object's collection should be
+          hidden under certain conditions, typically relating to the state of
+          that instance.</para>
+
+          <para>The syntax is:</para>
+
+          <programlisting><literal moreinfo="none">public boolean hideCollectionName()</literal> </programlisting>
+
+          <para>Returning a value of <code>true</code> indicates that the
+          collection should be hidden.</para>
+
+          <para>For example:</para>
+
+          <programlisting format="linespecific">public class Order {
+    @Hidden
+    public List&lt;Order&gt; getRushOrders() { ... }
+    ...
+}</programlisting>
+        </sect2>
+
+        <sect2>
+          <title>Hiding a collection for specific users or roles</title>
+
+          <para>It is possible to hide collections for certain users/roles by
+          calling the <methodname>DomainObjectContainer#getUser()</methodname>
+          method. See <xref
+          linkend="sec.BusinessRulesForCertainUsersOrRoles" /> for further
+          discussion.</para>
+        </sect2>
+      </sect1>
+
+      <sect1 id="sec.HiddenActions">
+        <title>How to hide an action</title>
+
+        <para>The mechanism for hiding an action is broadly the same as for
+        hiding a property (see <xref linkend="sec.HiddenProperty" />) or a
+        collection (see <xref linkend="sec.HiddenCollection" />).</para>
+
+        <sect2>
+          <title>Hiding an action permanently</title>
+
+          <para>To prevent a user from viewing an action at all, use the
+          <literal moreinfo="none">@Hidden</literal> annotation. This is
+          generally used where a <literal moreinfo="none">public</literal>
+          method on an object is not intended to be a user action</para>
+
+          <para>For example:</para>
+
+          <programlisting format="linespecific">public class Order {
+    @Hidden
+    public void markAsCancelled() { ... }
+    ...
+}</programlisting>
+        </sect2>
+
+        <sect2>
+          <title>Hiding an action based on the persistence state of the
+          object</title>
+
+          <para>As a refinement of the above, an action may be optionally
+          hidden using the <classname>@Hidden</classname> annotation based on
+          the persistence state of the object:</para>
+
+          <itemizedlist>
+            <listitem>
+              <para>to hide the action when the object is transient, use
+              <code>@Hidden(When.UNTIL_PERSISTED)</code></para>
+            </listitem>
+
+            <listitem>
+              <para>to hide the action when the object is persistent, use
+              <code>@Hidden(When.ONCE_PERSISTED)</code></para>
+            </listitem>
+          </itemizedlist>
+        </sect2>
+
+        <sect2>
+          <title>Hiding an action under certain conditions</title>
+
+          <para>A <literal moreinfo="none">hideXxx()</literal> method can be
+          used to indicate that a particular object's action should be hidden
+          under certain conditions, typically relating to the state of that
+          instance.</para>
+
+          <para>The syntax is:</para>
+
+          <programlisting><literal moreinfo="none">public boolean hideActionName([ValueOrEntityType param] ...)</literal> </programlisting>
+
+          <para>where the parameter types should match the action itself.
+          Returning a value of <code>true</code> indicates that the action
+          should be hidden.</para>
+
+          <para>For example:</para>
+
+          <programlisting format="linespecific">public class Order {
+    public void applyDiscount(int percentage) { ... }
+    public boolean hideApplyDiscount() {
+        return isWholesaleOrder();
+    }
+}</programlisting>
+        </sect2>
+
+        <sect2>
+          <title>Hiding an action for specific users or roles</title>
+
+          <para>It is possible to hide actions for certain users/roles by
+          calling the <methodname>DomainObjectContainer#getUser()</methodname>
+          method. See <xref
+          linkend="sec.BusinessRulesForCertainUsersOrRoles" /> for further
+          discussion.</para>
+        </sect2>
+      </sect1>
+
+      <sect1 id="sec.Entity.Hidden">
+        <title>How to specify that none of an object's members is
+        visible</title>
+
+        <para>To when an object is visible, provide a hidden() method:</para>
+
+        <para><programlisting>public class TrackingAction implements Tracking {
+   public boolean hidden(){
+    ...
+   }
+}</programlisting>If the function returns true, all properties and actions
+        will be hidden from the user, similar to <xref
+        linkend="sec.HiddenProperty" />.</para>
+      </sect1>
+
+      <sect1 id="sec.DisabledProperty">
+        <title>How to prevent a property from being modified</title>
+
+        <para>Preventing the user from modifying a property value is known as
+        'disabling' the property. Note that this doesn't prevent the property
+        from being modified programmatically.</para>
+
+        <para>The mechanism for disabling a property is broadly the same as
+        for disabling a collection (see <xref
+        linkend="sec.DisabledCollection" />) or a collection (see <xref
+        linkend="sec.DisabledCollection" />).</para>
+
+        <para>For control over the entire object, see <xref
+        linkend="sec.Entity.Disabled" />.</para>
+
+        <sect2>
+          <title>Disabling a property permanently</title>
+
+          <para>To prevent a user from being able to modify the property at
+          all, use the <literal moreinfo="none">@Disabled</literal>
+          annotation.</para>
+
+          <para>For example:</para>
+
+          <programlisting format="linespecific">public class OrderLine {
+    private int quantity;
+    @Disabled
+    public String getQuantity() { ... }
+    public void setQuantity(int quantity) { ... }
+    ...
+}</programlisting>
+
+          <para>Note that a setter is still required; this is used by the
+          framework to recreate the object when pulled back from the
+          persistent object store.</para>
+        </sect2>
+
+        <sect2>
+          <title>Disabling a property based on the persistence state of the
+          object</title>
+
+          <para>As a refinement of the above, a property may be optionally
+          disabled using the <classname>@Disabled</classname> annotation based
+          on the persistence state of the object:</para>
+
+          <itemizedlist>
+            <listitem>
+              <para>to disable the property when the object is transient, use
+              <code>@Disabled(When.UNTIL_PERSISTED)</code></para>
+            </listitem>
+
+            <listitem>
+              <para>to disable the property when the object is persistent, use
+              <code>@Disabled(When.ONCE_PERSISTED)</code></para>
+            </listitem>
+          </itemizedlist>
+        </sect2>
+
+        <sect2>
+          <title>Disabling a property under certain conditions</title>
+
+          <para>A supporting <literal moreinfo="none">disableXxx()</literal>
+          method can be used to disable a particular instance's member under
+          certain conditions</para>
+
+          <para>The syntax is:</para>
+
+          <programlisting><literal moreinfo="none">public String disablePropertyName()</literal></programlisting>
+
+          <para>A non-<code>null</code> return value indicates the reason why
+          the property cannot be modified. The framework is responsible for
+          providing this feedback to the user.</para>
+
+          <para>For example:</para>
+
+          <programlisting format="linespecific">public class OrderLine {
+    public String getQuantity() { ... }
+    public void setQuantity(int quantity) { ... }
+    public String disableQuantity() { 
+        if (isSubmitted()) {
+            return "Cannot alter any quantity after Order has been submitted"; 
+        }
+        return null;
+    }
+}</programlisting>
+
+          <para>If there are multiple reasons to disable a property, take a
+          look at the
+          <classname>org.apache.isis.applib.util.ReasonBuffer</classname>
+          helper.</para>
+        </sect2>
+
+        <sect2>
+          <title>Disabling a property for certain users/roles</title>
+
+          <para>It is possible to disable properties for certain users/roles
+          by calling the
+          <methodname>DomainObjectContainer#getUser()</methodname> method. See
+          <xref linkend="sec.BusinessRulesForCertainUsersOrRoles" />for
+          further discussion.</para>
+        </sect2>
+      </sect1>
+
+      <sect1 id="sec.DisabledCollection">
+        <title>How to prevent a collection from being modified</title>
+
+        <para>Preventing the user from adding to or removing from a collection
+        is known as 'disabling' the collection.</para>
+
+        <para>The mechanism for disabling a collection is broadly the same as
+        for disabling a property (see <xref linkend="sec.DisabledProperty" />)
+        or a action (see <xref linkend="sec.DisabledAction" />).</para>
+
+        <sect2>
+          <title>Disabling a collection permanently</title>
+
+          <para>Some, though not all, viewers allow the user to directly
+          manipulate the contents of a collection. For example, the DnD viewer
+          will allow new objects to be "dropped" into a collection, and
+          existing objects removed from a collection.</para>
+
+          <para>Although it is possible to associate behaviour with such
+          actions (see <xref linkend="sec.AddToRemoveFrom" />), it may be
+          preferred to only allow modification through actions. Or, the
+          application may be deployed using a viewer that doesn't fully
+          support direct manipulation of collections.</para>
+
+          <para>In either case, annotate the collection using the <literal
+          moreinfo="none">@Disabled</literal> annotation.</para>
+
+          <para>For example:</para>
+
+          <programlisting format="linespecific">public class Order {
+    private List&lt;Order&gt; cancelledOrders = new ArrayList&lt;Order&gt;();
+    @Disabled
+    public List&lt;Order&gt; getCancelledOrders() { ... }
+    private void setCancelledOrders(List&lt;Order&gt; cancelledOrders) { ... }
+    ...
+}</programlisting>
+        </sect2>
+
+        <sect2>
+          <title>Disabling a collection based on the persistence state of the
+          object</title>
+
+          <para>As a refinement of the above, a collection may be optionally
+          disabled using the <classname>@Disabled</classname> annotation based
+          on the persistence state of the object:</para>
+
+          <itemizedlist>
+            <listitem>
+              <para>to disable the collection when the object is transient,
+              use <code>@Disabled(When.UNTIL_PERSISTED)</code></para>
+            </listitem>
+
+            <listitem>
+              <para>to disable the collection when the object is persistent,
+              use <code>@Disabled(When.ONCE_PERSISTED)</code></para>
+            </listitem>
+          </itemizedlist>
+        </sect2>
+
+        <sect2>
+          <title>Disabling a collection under certain conditions</title>
+
+          <para>A <literal moreinfo="none">disableXxx()</literal> method can
+          be used to disable a particular instance's collection under certain
+          conditions:</para>
+
+          <para>The syntax is:</para>
+
+          <programlisting><literal moreinfo="none">public String disableCollectionName()</literal> </programlisting>
+
+          <para>For example:</para>
+
+          <programlisting format="linespecific">public class Department {
+    public List&lt;Employee&gt; getEmployees() { ... }
+    private void setEmployees(List&lt;Employee&gt; employees) { ... }
+    public void disableEmployees() {
+        return isClosed()? "This department is closed" : null;
+    }
+    ...
+}</programlisting>
+        </sect2>
+
+        <sect2>
+          <title>Disabling a collection for specific users or roles</title>
+
+          <para>It is possible to disable collections for certain users/roles
+          by calling the
+          <methodname>DoymainObjectContainer#getUser()</methodname> method.
+          See <xref linkend="sec.BusinessRulesForCertainUsersOrRoles" /> for
+          further discussion.</para>
+        </sect2>
+      </sect1>
+
+      <sect1 id="sec.DisabledAction">
+        <title>How to prevent an action from being invoked</title>
+
+        <para>Preventing the user from invoking an action is known as
+        'disabling' the action.</para>
+
+        <para>The mechanism for disabling an action is broadly the same as for
+        disabling a property (see <xref linkend="sec.DisabledProperty" />) or
+        a collection (see <xref linkend="sec.DisabledCollection" />).</para>
+
+        <sect2>
+          <title>Disabling an action permanently</title>
+
+          <para>It is possible to prevent an action from ever being invoked
+          using the <classname>@Disabled</classname> annotation, exactly
+          equivalent to the use of the annotation for properties and
+          collections. However, it's not a particularly meaningful usecase:
+          why display an action that can never be invoked? The only reason we
+          can think of is as a placeholder during prototyping - to indicate to
+          the user that an action is planned, but has not yet been
+          implemented.</para>
+        </sect2>
+
+        <sect2>
+          <title>Disabling an action based on the persistence state of the
+          object</title>
+
+          <para>Whereas annotating an action simply as
+          <classname>@Disabled</classname> probably does not make sense (see
+          above), it does make sense to optionally disable an action using the
+          <classname>@Disabled</classname> annotation based on the persistence
+          state of the object:</para>
+
+          <itemizedlist>
+            <listitem>
+              <para>to disable the action when the object is transient, use
+              <code>@Disabled(When.UNTIL_PERSISTED)</code></para>
+            </listitem>
+
+            <listitem>
+              <para>to disable the action when the object is persistent, use
+              <code>@Disabled(When.ONCE_PERSISTED)</code></para>
+            </listitem>
+          </itemizedlist>
+        </sect2>
+
+        <sect2>
+          <title>Based on the state of the object</title>
+
+          <para>There may be circumstances in which we do not want the user to
+          be able to initiate the action at all - for example because that
+          action is not appropriate to the current state of the object on
+          which the action resides. Such rules are enforced by means of a
+          <literal moreinfo="none">disableXxx()</literal> supporting
+          method.</para>
+
+          <para>The syntax is:</para>
+
+          <para><programlisting>public String disableActionName([ValueOrEntityType param]...)</programlisting></para>
+
+          <para>A non-<literal>null</literal> return <code>String</code>
+          indicates the reason why the action may not be invoked. The
+          framework takes responsibility to provide this feedback to the
+          user.</para>
+
+          <para>For example:</para>
+
+          <programlisting format="linespecific">public class Customer {
+    public Order placeOrder(Product p, int quantity) { ... }
+    public String disablePlaceOrder(Product p, int quantity) { 
+        return isBlackListed()?
+            "Blacklisted customers cannot place orders"
+            :null;
+    }
+    ...
+}</programlisting>
+        </sect2>
+
+        <sect2>
+          <title>Disabling an action for certain users or roles</title>
+
+          <para>It is possible to disable actions for certain users/roles by
+          calling the <methodname>DomainObjectContainer#getUser()</methodname>
+          method. See <xref
+          linkend="sec.BusinessRulesForCertainUsersOrRoles" /> for further
+          discussion.</para>
+        </sect2>
+      </sect1>
+
+      <sect1 id="sec.Entity.Disabled">
+        <title>How to specify that none of an object's members can be
+        modified/invoked</title>
+
+        <para>Some objects have state which should not be modifiable only
+        under certain conditions; for example an invoice can not be modified
+        after it has been paid. The viewer is expected to interpret this by
+        suppressing any sort of "edit" button.</para>
+
+        <para>To indicate that an object cannot be modified, use the <literal
+        moreinfo="none">String disabled(Type type)</literal> method.</para>
+
+        <para>For example:</para>
+
+        <programlisting>public class FeeInvoice implements Invoice {
+   public String disabled(Type type){
+    ...
+   }
+}</programlisting>
+
+        <para>The <code>Type</code> is from
+        <classname>org.apache.isis.applib.Identifier</classname>:</para>
+
+        <programlisting>    /**
+     * What type of feature this identifies.
+     */
+    public static enum Type {
+        CLASS, PROPERTY_OR_COLLECTION, ACTION
+    }</programlisting>
+
+        <para>and provides fine grain control over disabling actions and
+        properties.</para>
+
+        <para>The return String is null if the the object (action or property)
+        is not disabled, or the reason why it is disabled, similar to <xref
+        linkend="sec.DisabledProperty" />.</para>
+
+        <para>See also <xref linkend="sec.Entity.Disabled" />.</para>
+      </sect1>
+
+      <sect1 id="sec.Immutable">
+        <title id="sec.entity.immutable">How to specify that an object is
+        immutable (that none of its members can ever be modified)</title>
+
+        <para>Some objects have state which should not be modifiable; for
+        example those representing reference data. The viewer is expected to
+        interpret this by which suppressing any sort of "edit" button.</para>
+
+        <para>To indicate that an object cannot be modified, use the <literal
+        moreinfo="none">@Immutable</literal> annotation.</para>
+
+        <para>For example:</para>
+
+        <programlisting>@Immutable
+public class ChasingLetter implements PaymentReclaimStrategy {
+    ...
+}</programlisting>
+
+        <para>See also <xref linkend="sec.Entity.Disabled" />.</para>
+      </sect1>
+
+      <sect1>
+        <title>How to validate user input for a property</title>
+
+        <sect2>
+          <title>Declarative validation</title>
+
+          <para>For properties that accept a text input string, such as
+          <code>String</code> and <code>Date</code>, there are convenient
+          mechanisms to validate and/or normalise the values typed in:</para>
+
+          <itemizedlist>
+            <listitem>
+              <para>For <literal moreinfo="none">Date</literal> and number
+              values the <literal moreinfo="none">@Mask</literal> annotation
+              may be used.</para>
+            </listitem>
+
+            <listitem>
+              <para>For <literal moreinfo="none">String</literal> properties
+              the <literal moreinfo="none">@RegEx</literal> annotation may be
+              used.</para>
+            </listitem>
+          </itemizedlist>
+
+          <para>More complex validation can also be performed imperatively
+          (below).</para>
+        </sect2>
+
+        <sect2>
+          <title>Imperative validation</title>
+
+          <para>A supporting <literal moreinfo="none">validateXxx()</literal>
+          method is used to check that a new value for a property is
+          valid.</para>
+
+          <para>If the proffered value is deemed to be invalid then the
+          property will not be changed. A non-null return <code>String</code>
+          indicates the reason why the member cannot be modified/action be
+          invoked; the framework is responsible for providing this feedback to
+          the user.</para>
+
+          <para>The syntax is:</para>
+
+          <para><programlisting>public String validatePropertyName(PropertyType param)</programlisting></para>
+
+          <para>where <literal moreinfo="none">PropertyType</literal> is the
+          same type as that of the property itself.</para>
+
+          <para>For example:</para>
+
+          <programlisting format="linespecific">public class Exam {
+    public int getMark() { ... }
+    public void setMark(int mark) { ... }
+    public validateMark(int mark) {
+        return !withinRange(mark)? "Mark must be in range 0 to 30":null;
+    }
+    private boolean withinRange(int mark) { return mark &gt;= 0 &amp;&amp; mark &lt;= 30; }
+}</programlisting>
+        </sect2>
+      </sect1>
+
+      <sect1>
+        <title>How to validate an object being added or removed from a
+        collection</title>
+
+        <para>A <literal moreinfo="none">validateAddToXxx()</literal> method
+        can be used to check that an object is valid to be added to a
+        collection. Conversely, the
+        <methodname>validateRemoveFromXxx()</methodname> method can be used to
+        check that it is valid to remove an object from a collection is
+        valid.</para>
+
+        <para>The syntax is:</para>
+
+        <para><programlisting>public String validateAddToCollectionName(EntityType param)</programlisting></para>
+
+        <para>and</para>
+
+        <programlisting>public String validateRemoveFromCollectionName(EntityType param)</programlisting>
+
+        <para>A non-<code>null</code> return <code>String</code> indicates the
+        reason why the object cannot be added/removed, and the viewing
+        mechanism will display this to the user.</para>
+
+        <para>For example:</para>
+
+        <programlisting format="linespecific">public class Department {
+    public List&lt;Employee&gt; getEmployees() { ... }
+    private void setEmployees(List&lt;Employee&gt; employees) { ... }
+    public String validateAddToEmployee(Employee employee) {
+        return employee.isRetired()?
+            "Cannot add retired employees to department"
+            :null;
+    ...
+}</programlisting>
+      </sect1>
+
+      <sect1>
+        <title>How to validate an action parameter argument</title>
+
+        <sect2>
+          <title>Declarative validation</title>
+
+          <para>For parameters that accept a text input string, such as
+          <code>String</code> and <code>Date</code>, there are convenient
+          mechanisms to validate and/or normalise the values typed in:</para>
+
+          <itemizedlist>
+            <listitem>
+              <para>For <literal moreinfo="none">Date</literal> and number
+              values the <literal moreinfo="none">@Mask</literal> annotation
+              may be used.</para>
+            </listitem>
+
+            <listitem>
+              <para>For <literal moreinfo="none">String</literal> parameters
+              the <literal moreinfo="none">@RegEx</literal> annotation may be
+              used.</para>
+            </listitem>
+          </itemizedlist>
+
+          <para>More complex validation can also be performed imperatively
+          (below).</para>
+        </sect2>
+
+        <sect2>
+          <title>Imperative validation</title>
+
+          <para>A <literal moreinfo="none">validateXxx()</literal> method is
+          used to check that the set of arguments used by an action method is
+          valid. If the arguments are invalid then the framework will not
+          invoke the action.</para>
+
+          <para>The syntax is:</para>
+
+          <para><programlisting>public String validate&lt;ActionName&gt;([ValueOrEntityType param]...)</programlisting></para>
+
+          <para>A non-<code>null</code> return <classname>String</classname>
+          indicates the reason why the member cannot be modified/action be
+          invoked, and the viewing mechanism will display this feedback to the
+          user.</para>
+
+          <para>For example:</para>
+
+          <programlisting format="linespecific">public class Customer {
+    public Order placeOrder(Product p, int quantity) { ... }
+    public String validatePlaceOrder(Product p, int quantity) {
+        if (p.isOutOfStock()) { return "Product is out of stock"; }
+        if (quantity &lt;= 0) { return "Quantity must be a positive value"; }
+        return null;
+    }
+    ...
+}</programlisting>
+
+          <para>For complex validation, you may wish to use the
+          <classname>org.apache.isis.applib.util.ReasonBuffer</classname>
+          helper class.</para>
+        </sect2>
+      </sect1>
+
+      <sect1 id="sec.MustSpecify">
+        <title>How to validate declaratively using @MustSatisfy</title>
+
+        <para>The <literal>@MustSatisfy</literal> annotation is an alternative
+        to using imperative validation, allowing validation rules to be
+        captured in an (implementation of a)
+        <classname>org.apache.isis.applib.spec.Specification</classname>.</para>
+
+        <para>For example:</para>
+
+        <programlisting format="linespecific">public class DomainObjectWithMustSatisfyAnnotations extends AbstractDomainObject {
+
+    private String lastName;
+    @MustSatisfy(SpecificationRequiresFirstLetterToBeUpperCase.class)
+    public String getLastName() {
+        resolve(lastName);
+        return lastName;
+    }
+    public void setLastName(String lastName) {
+        this.lastName = lastName;
+        objectChanged();
+    }
+
+    public void changeLastName(
+            @MustSatisfy(SpecificationRequiresFirstLetterToBeUpperCase.class)
+            String lastName
+            ) {
+        setLastName(lastName);
+    }
+
+}</programlisting>
+
+        <para>To help you write your own
+        <classname>Specification</classname>s, there are some adapter classes
+        in <package>org.apache.isis.applib.specs</package>:</para>
+
+        <itemizedlist>
+          <listitem>
+            <para><classname>AbstractSpecification</classname>, which
+            implements <classname>Specification</classname> and takes
+            inspiration from the <ulink
+            url="http://code.google.com/p/hamcrest/">Hamcrest</ulink>
+            library's <classname>TypeSafeMatcher</classname> class</para>
+          </listitem>
+
+          <listitem>
+            <para><classname>SpecificationAnd</classname>, which allows a set
+            of <classname>Specification</classname>s to be grouped together
+            and require that <emphasis>all</emphasis> of them are
+            satisfied</para>
+          </listitem>
+
+          <listitem>
+            <para><classname>SpecificationOr</classname>, which allows a set
+            of <classname>Specification</classname>s to be grouped together
+            and require that <emphasis>at least one</emphasis> of them is
+            satisfied</para>
+          </listitem>
+
+          <listitem>
+            <para><classname>SpecificationNot</classname>, which requires that
+            the provided <classname>Specification</classname> is
+            <emphasis>not</emphasis> satisfied</para>
+          </listitem>
+        </itemizedlist>
+      </sect1>
+    </chapter>
+
+    <chapter>
+      <title>How to provide drop-downs and default values</title>
+
+      <abstract>
+        <para>How-to make actions easier to use from an end-user perspective,
+        by providing sets of choices and defaults.</para>
+      </abstract>
+
+      <para>Invoking actions or setting properties requires that the user
+      specify a valid value; of the correct type, and that passes any
+      validation rules that may have been defined. To make things are easier
+      for the user, you can provide lists of choices; viewers typically render
+      these values in a drop-down list box.</para>
+
+      <para>In a similar vein, there may be a default value for an action
+      parameter; this can also be specified.</para>
+
+      <sect1>
+        <title>How to specify a set of choices for a property</title>
+
+        <para>The simplest way to provide the user with a set of choices for a
+        property (possibly rendered as a drop-down list, for example) is to
+        ensure that the type used by the property is marked up as
+        <code>@Bounded</code> (see <xref linkend="sec.Bounded" />).</para>
+
+        <para>However, this is not always appropriate. For example you might
+        wish to provide the user with the choice of all the
+        <classname>Address</classname>es known for that
+        <classname>Customer</classname>, with the most recently-used address
+        as the default.</para>
+
+        <para>The syntax for specifying a list of choices is either:</para>
+
+        <para><programlisting>public Collection&lt;PropertyType&gt; choicesPropertyName()</programlisting></para>
+
+        <para>or alternatively</para>
+
+        <programlisting>public PropertyType[] choicesPropertyName()</programlisting>
+
+        <para>where <literal moreinfo="none">PropertyType</literal> is the
+        same type as that of the property itself.</para>
+
+        <para>For example:</para>
+
+        <programlisting format="linespecific">public class Order {
+    public Address getShippingAddress() { ... }
+    public void setShippingAddress() { ... }
+    public List&lt;Address&gt; choicesShippingAddress() {
+        return getCustomer().allActiveAddresses();
+    }
+    ...
+}</programlisting>
+      </sect1>
+
+      <sect1>
+        <title>How to specify a set of choices for an action parameter</title>
+
+        <para>The programmer may provide a set of choices for the value of any
+        or all of the parameters of an action. These will be made available to
+        the user - for example as a drop-down list.</para>
+
+        <para>If the type of the parameter is annotated with <literal
+        moreinfo="none">@Bounded</literal>, then it is not necessary to
+        specify the choices for that parameter, as the user will automatically
+        be offered the full set to choose from.</para>
+
+        <para>If this isn't the case, then - as for defaults - there are two
+        different ways to specify parameters; either per parameter, or for all
+        parameters.</para>
+
+        <sect2>
+          <title>Per parameter syntax (preferred)</title>
+
+          <para>The per-parameter form is simpler and generally
+          preferred.</para>
+
+          <para>The syntax is:</para>
+
+          <programlisting>public List&lt;ParameterType&gt; choicesNActionName()</programlisting>
+
+          <para>where N indicates the 0-based parameter number.</para>
+
+          <para>For example:</para>
+
+          <programlisting format="linespecific">public class Order {
+    public Order placeOrder(
+            Product product,
+            @Named("Quantity") 
+            int quantity) {
+        ...
+    }
+    public List&lt;Product&gt; choices0PlaceOrder() {
+        return lastFiveProductsOrderedBy(this.getCustomer());
+    }
+    public List&lt;Integer&gt; choices1PlaceOrder() {
+        return Arrays.asList(1,2,3,4,5);
+    }
+    ....
+}</programlisting>
+        </sect2>
+
+        <sect2>
+          <title>All parameters syntax</title>
+
+          <para>The alternative mechanism is to supply all the parameter
+          choices in one go:</para>
+
+          <para><programlisting>public Object[] choices&lt;ActionName&gt;([&lt;parameter type&gt; param]...)</programlisting></para>
+
+          <para>returning an array, which must have one element per parameter
+          in the method signature. Each element of the array should itself
+          either be an array or a list, containing the set of values
+          representing the choices for that parameter, or <literal
+          moreinfo="none">null</literal> if there are no choices to be
+          specified for that parameter.</para>
+
+          <para>For example:</para>
+
+          <programlisting format="linespecific">public class Order {
+    public Order placeOrder(
+            Product product,
+            @Named("Quantity") 
+            int quantity) {
+        ...
+    }
+    public Object[] choicesPlaceOrder(
+            Product product,
+            int quantity) {
+        return new Object[] {
+            lastFiveProductsOrderedBy(this.getCustomer()).toArray(), 
+            Arrays.asList(1,2,3,4,5)
+        };
+    }
+    ...
+}</programlisting>
+        </sect2>
+      </sect1>
+
+      <sect1 id="sec.Bounded">
+        <title>How to specify that a class of objects has a limited number of
+        instances</title>
+
+        <para>Sometimes an entity may only have a relatively small number of
+        instances, for example the types of credit cards accepted (Visa,
+        Mastercard, Amex). Viewers will typically expected to render the
+        complete set of instances as a drop down list whenever the object type
+        is used (ie as a property or action parameter).</para>
+
+        <para>To indicate that a class has a limited number of instances, use
+        the <classname>@Bounded</classname> annotation. Note that there is an
+        implied expectation is that the list of objects is small, and
+        relatively cheap to obtain from the object store.</para>
+
+        <para>An alternative way to specify a selection of objects is using
+        the <classname>choicesXxx()</classname> supporting methods.</para>
+
+        <para>For example:</para>
+
+        <programlisting>@Bounded
+public class PaymentMethod {
+    ...
+}</programlisting>
+
+        <para>Alternatively, you might want to use a (Java) <code>enum</code>,
+        because these are implicitly bounded.</para>
+      </sect1>
+
+      <sect1>
+        <title>How to find an entity (for an action parameter or property)
+        using auto-complete</title>
+
+        <para>Some viewers (eg the Wicket viewer) allow an entity to be
+        specified (as an argument for an action parameter, or as the new value
+        of a property) by enabling the user to type its title. The framework
+        then searches for a matching instance, presenting them in a drop-down
+        list.</para>
+
+        <para>This is accomplished using two annotations. The
+        <classname>@AutoComplete</classname> annotation is used on the entity
+        type itself:</para>
+
+        <programlisting>@AutoComplete(repository=Customers.class)
+public class Customer {
+    ...
+}</programlisting>
+
+        <para>The <code>repository</code> attribute indicates the class of the
+        domain service that has an autoComplete() method. This is required to
+        accept a single <classname>String</classname> and return a
+        <classname>List</classname> of candidates:</para>
+
+        <programlisting>public class Customers {
+    ...
+    @Hidden
+    public List&lt;Property&gt; autoComplete(String searchPhrase) {        
+        return allMatches(new QueryDefault&lt;Customer&gt;("customers_findByName", "name", searchPhrase));
+    }
+}</programlisting>
+
+        <para>If required, a different action name than "autoComplete" can be
+        specified.</para>
+      </sect1>
+
+      <sect1>
+        <title>How to specify default values for an action parameter</title>
+
+        <para>When an action is about to be invoked, then default values can
+        be provided for any or all of its parameters.</para>
+
+        <para>There are two different ways to specify parameters; either per
+        parameter, or for all parameters.</para>
+
+        <sect2>
+          <title>Per-parameter syntax (preferred)</title>
+
+          <para>The per-parameter form is simpler and generally to be
+          preferred.</para>
+
+          <para>The syntax is:</para>
+
+          <programlisting>public ParameterType defaultNActionName()</programlisting>
+
+          <para>where N indicates the 0-based parameter number. For
+          example:</para>
+
+          <programlisting format="linespecific">public class Customer {
+    public Order placeOrder(
+             Product product,
+             @Named("Quantity") 
+             int quantity) {
+        ...
+    }
+    public Product default0PlaceOrder() {
+        return productMostRecentlyOrderedBy(this.getCustomer());
+    }
+    public int default1PlaceOrder() {
+        return 1;
+    }
+}</programlisting>
+        </sect2>
+
+        <sect2>
+          <title>All parameters syntax</title>
+
+          <para>The syntax for specifying all the parameter default values in
+          one go is:</para>
+
+          <para><programlisting>public Object[] defaultActionName([ValueOrEntityType param]...)</programlisting></para>
+
+          <para>returning an array which must have one element per parameter
+          in the action method signature of corresponding default
+          values.</para>
+
+          <para>For example:</para>
+
+          <programlisting format="linespecific">public class Customer {
+    public Order placeOrder(
+            Product product,
+            @Named("Quantity") 
+            int quantity) {
+        ...
+    }
+    public Object[] defaultPlaceOrder(
+            Product product,
+            int quantity) {
+        return new Object[] {
+            productMostRecentlyOrderedBy(this.getCustomer()),
+            1
+        };
+    }
+    ...
+}</programlisting>
+        </sect2>
+      </sect1>
+    </chapter>
+
+    <chapter>
+      <title>How to derive properties and collections, and other
+      side-effects</title>
+
+      <abstract>
+        <para>How-to derive properties and collections from persisting state,
+        and provide other side-effects.</para>
+      </abstract>
+
+      <para>The Isis viewers will automatically render the state of properties
+      and collections, but the values of such need not be persisted; they can
+      be derived from other information available to the object.</para>
+
+      <para>For collections</para>
+
+      <sect1 id="sec.DerivedProperty">
+        <title>How to make a derived property</title>
+
+        <sect2>
+          <title>Read-only</title>
+
+          <para>Most derived properties are read-only, their value being
+          derived from other information available to the object.</para>
+
+          <para>Omitting the mutator (<code>setXxx()</code>) method for a
+          property indicates both that the field is derived, and is not be
+          persisted.</para>
+
+          <para>For example:</para>
+
+          <programlisting format="linespecific">public class Employee {
+    public Department getDepartment() { ... }
+    ...
+
+    // this is the derived property
+    public Employee getManager() {
+        if (getDepartment() == null) { return null; }
+        return getDepartment().getManager();
+    }
+    ...
+}</programlisting>
+        </sect2>
+
+        <sect2>
+          <title>Read-write</title>
+
+          <para>A derived property can be made updateable (in that it takes
+          the provided value and does something sensible with it) by providing
+          a <code>modifyXxx()</code> supporting method:</para>
+
+          <programlisting format="linespecific">public class Employee {
+    public Department getDepartment() { ... }
+    ...
+
+    // this is the derived property
+    public Employee getManager() { ... }
+
+    // this makes the derived property modifiable
+    public void modifyManager(Employee manager) {
+        if (getDepartment() == null) { return; }
+        getDepartment().modifyManager(manager);
+    }
+
+    ...
+}</programlisting>
+
+          <para>Note how the implementation of such a <code>modifyXxx()</code>
+          method typically modifies the original source of the information
+          (the <classname>Department</classname> object).</para>
+
+          <para>Alternatively, if you prefer to have a setter, then you can
+          use Isis' <classname>@NotPersisted</classname> attribute.</para>
+
+          <programlisting format="linespecific">public class Employee {
+    public Department getDepartment() { ... }
+    ...
+
+    @NotPersisted
+    public Employee getManager() { ... }
+    public void setManager(Employee manager) {
+        if (getDepartment() == null) { return; }
+        getDepartment().modifyManager(manager);
+    }
+    ...
+}</programlisting>
+
+          <note>
+            <para>If you use this approach, then for some object stores you
+            may also need to annotate the property to exclude it. For example
+            the JDO/DataNucleus object store requires the property being
+            annotated with
+            <classname>@javax.jdo.annotations.NotPersistent</classname>.</para>
+          </note>
+        </sect2>
+      </sect1>
+
+      <sect1 id="sec.DerivedCollection">
+        <title>How to make a derived collection</title>
+
+        <para>Collections can be derived by omitting the mutator (the same way
+        as properties, see <xref linkend="sec.DerivedProperty" />).</para>
+
+        <para>For example:</para>
+
+        <programlisting format="linespecific">public class Department {
+    // Standard collection
+    private List&lt;Employee&gt; employees = new ArrayList&lt;Employee&gt;();
+    public List&lt;Employee&gt; getEmployees() { ... }
+    private void setEmployees(List&lt;Employee&gt;) { ... }
+
+    // Derived collection
+    public List&lt;Employee&gt; getTerminatedEmployees() {
+        List&lt;Employee&gt; terminatedEmployees = new ArrayList&lt;Employee&gt;();
+        for(Employee e: employees) {
+            if (e.isTerminated()) {
+                addTo(terminatedEmployees, e);
+            }
+        }
+        return terminatedEmployees;
+    }
+    ...
+}</programlisting>
+
+        <para>Derived collections are not persisted, though may be modified if
+        there is an <code>addToXxx()</code> or <code>removeFromXxx()</code>
+        supporting method. As for derived properties, the implementations of
+        these mutators change the underlying data. For example:</para>
+
+        <programlisting format="linespecific">public class Department {
+    ...
+
+    public void addToTerminatedEmployees(Employee employee) {
+        employee.setTerminated(true);
+    }
+    public void removeFromTerminatedEmployees(Employee employee) {
+        employee.setTerminated(false);
+    }
+}</programlisting>
+      </sect1>
+
+      <sect1>
+        <title>How to inline the results of a query-only repository
+        action</title>
+
+        <para>While derived properties (<xref
+        linkend="sec.DerivedProperty" />) and derived collections (<xref
+        linkend="sec.DerivedCollection" />) typically "walk the graph" to
+        associated objects, there is nothing to prevent the returned value
+        being the result of invoking a repository (domain service)
+        action.</para>
+
+        <para>For example:</para>
+
+        <programlisting>public class Customer {
+    ...
+    public List&lt;Order&gt; getMostRecentOrders() {
+        return orderRepo.findMostRecentOrders(this, 5);
+    }
+}</programlisting>
+      </sect1>
+
+      <sect1 id="sec.ModifyAndClear">
+        <title>How to trigger other behaviour when a property is
+        changed</title>
+
+        <para>If you want to invoke functionality whenever a property is
+        changed by the user, then you should create a supporting <literal
+        moreinfo="none">modifyXxx()</literal> method and include the
+        functionality within that. The syntax is:</para>
+
+        <programlisting>public void modifyPropertyName(PropertyType param)</programlisting>
+
+        <para>Why not just put this functionality in the setter? Well, the
+        setter is used by the object store to recreate the state of an already
+        persisted object. Putting additional behaviour in the setter would
+        cause it to be triggered incorrectly.</para>
+
+        <para>For example:</para>
+
+        <programlisting format="linespecific">public class Order() {
+    public Integer getAmount() { ... }
+    public void setAmount(Integer amount) { ... }
+    public void modifyAmount(Integer amount) {
+        setAmount(amount);
+        addToTotal(amount);
+    }
+    ...
+}</programlisting>
+
+        <para>Here the <literal moreinfo="none">modifyAmount()</literal>
+        method also calls the <literal moreinfo="none">addToTotal()</literal>
+        call as well as the <literal moreinfo="none">setAmount()</literal>
+        method. We don't want this <methodname>addToCall()</methodname> method
+        to be called when pulling the object back from the object store, so we
+        put it into the modify, not the setter.</para>
+
+        <para>You may optionally also specify a <code>clearXxx()</code> which
+        works the same way as modify <literal moreinfo="none">modify</literal>
+        <literal moreinfo="none">Xxx()</literal> but is called when the
+        property is cleared by the user (i.e. the current value replaced by
+        nothing). The syntax is:</para>
+
+        <programlisting>public void clearPropertyName()</programlisting>
+
+        <para>To extend the above example:</para>
+
+        <programlisting format="linespecific">public class Order() {
+    public Integer getAmount() { ... }
+    public void setAmount(Integer amount) { ... }
+    public void modifyAmount(Integer amount) { ... }
+    public void clearAmount() {
+        removeFromTotal(this.amount);
+        setAmount(null);
+    }
+    ...
+}</programlisting>
+      </sect1>
+
+      <sect1 id="sec.AddToRemoveFrom">
+        <title>How to 

<TRUNCATED>