incubator-isis-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From danhayw...@apache.org
Subject svn commit: r1044696 [2/3] - in /incubator/isis/trunk/applib/src: docbkx/guide/isis-applib.xml main/java/org/apache/isis/applib/DomainObjectContainer.java main/java/org/apache/isis/applib/annotation/Hidden.java
Date Sat, 11 Dec 2010 19:34:20 GMT

Modified: incubator/isis/trunk/applib/src/docbkx/guide/isis-applib.xml
URL: http://svn.apache.org/viewvc/incubator/isis/trunk/applib/src/docbkx/guide/isis-applib.xml?rev=1044696&r1=1044695&r2=1044696&view=diff
==============================================================================
--- incubator/isis/trunk/applib/src/docbkx/guide/isis-applib.xml (original)
+++ incubator/isis/trunk/applib/src/docbkx/guide/isis-applib.xml Sat Dec 11 19:34:20 2010
@@ -164,7 +164,7 @@
   </chapter>
 
   <part>
-    <title>AppLib Recipes</title>
+    <title>Recipes</title>
 
     <partintro>
       <para>This part of the guide is a set of chapters that provides recipes
@@ -172,7 +172,7 @@
       so-forth.</para>
     </partintro>
 
-    <chapter>
+    <chapter id="chp.Objects">
       <title>Object Recipes</title>
 
       <abstract>
@@ -180,398 +180,508 @@
       </abstract>
 
       <para>This chapter contains how-to's for programming conventions that
-      apply to the object itself: object-level specifications (<xref
-      linkend="sec.ObjectLevelSpecifications" />) and the object lifecycle
-      (<xref linkend="sec.ObjectLifecycle" />).</para>
-
-      <sect1 id="sec.ObjectLevelSpecifications">
-        <title>Object-level specifications</title>
-
-        <para>The first set of conventions are concerned with the capabilities
-        or behaviour of an object as a whole.</para>
-
-        <sect2>
-          <title condition="java">How to specify a title for an object</title>
-
-          <para>A title is used to identify an object to the user in the user
-          interface. For example, a Customer's title might be the
-          organization's customer reference, or perhaps (more informally)
-          their first and last names. By default, the framework will use the
-          object's <literal moreinfo="none">toString()</literal> method as the
-          title. However, if a <literal moreinfo="none">title()
-          </literal>method (returning a <literal
-          moreinfo="none">String</literal>) is present, then that is used
-          instead, thus:</para>
-
-          <para><programlisting>public String toString()</programlisting></para>
-
-          <para>or</para>
-
-          <para><programlisting>public String title()</programlisting></para>
-
-          <para>The reason for providing the option to use a <literal
-          moreinfo="none">title</literal> method is in case the programmer
-          needs to make use of the <literal moreinfo="none">toString</literal>
-          method for other purposes, such as for debugging.</para>
-        </sect2>
-
-        <sect2>
-          <title condition=".net">How to specify the icon for an
-          object</title>
-
-          <para condition="1.5">By default, the framework will look for an
-          image in the <filename class="directory"
-          moreinfo="none">images</filename> directory (which must be on the
-          classpath) that has the same name as the object class. So for an
-          object of type Customer, it will look for <filename
-          class="directory" moreinfo="none">Customer.gif</filename> or
-          <filename class="directory" moreinfo="none">Customer.png</filename>.
-          If it 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</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 'camel 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.gif</filename>
-          or <filename class="directory"
-          moreinfo="none">OrderLine.png</filename> (JPEG suffixes
-          <filename>OrderLine.jpg</filename> or
-          <filename>OrderLine.jpeg</filename> will also be recognized but
-          generally GIF or PNG are to be preferred). Actually, the framework
-          will also recognise <filename class="directory"
-          moreinfo="none">orderline.gif</filename>, but some operating systems
-          and deployment environments are case sensitive, so it is good
-          practice to adopt an unambiguous convention.</para>
-
-          <para>The programmer may choose to specify, manually, which icon to
-          use, by specifying an <literal moreinfo="none">iconName</literal>
-          method:</para>
+      apply to the object itself.</para>
 
-          <programlisting format="linespecific">    public String iconName() {
-        return "Person";
-    }</programlisting>
+      <sect1>
+        <title condition="java">How to specify a title for an object</title>
 
-          <para>This makes it easy for more than one class to use the same
-          icon, without having to duplicate the image file.</para>
+        <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. By default, the framework will
+        use the object's <literal moreinfo="none">toString()</literal> method
+        as the title. However, if a <literal moreinfo="none">title()
+        </literal>method (returning a <literal
+        moreinfo="none">String</literal>) is present, then that is used
+        instead, thus:</para>
 
-          <para>The <code>iconName</code> method may also be used to specify
-          an individual icon for each instance. For example, an instance of
-          <classname>Product</classname> could use a photograph of the product
-          as an icon, using:</para>
+        <para><programlisting>public String toString()</programlisting></para>
 
-          <programlisting format="linespecific">    public String iconName() {
-        return getProductName() + "-photograph";
-    }</programlisting>
+        <para>or</para>
 
-          <para>or to vary the icon according to the status of the
-          object:<programlisting>    public String iconName() {
-        return "Order-" + getStatus();
-    }</programlisting></para>
-        </sect2>
+        <para><programlisting>public String title()</programlisting></para>
 
-        <sect2>
-          <title condition="j#">How to specify a name and/or description for
-          an object</title>
+        <para>The reason for providing the option to use a <literal
+        moreinfo="none">title()</literal> method is in case the programmer
+        needs to make use of the <literal moreinfo="none">toString()</literal>
+        method for other purposes, such as for debugging.</para>
 
-          <para>By default, the name (or type) of an object, as displayed to
-          the user will be the class name. However, if an <literal
-          moreinfo="none">@Named</literal> annotation is included, then this
-          will override the default name. This might be used to include
-          punctuation or other characters that may not be used within a class
-          name.</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.</para>
+      </sect1>
 
-          <para>By default the framework will create a plural version of the
-          object name by adding an 's' to singular name, or a 'ies' to names
-          ending 'y'. For irregular nouns or other special case, the
-          <code>@Plural</code> annotation may be used to specify the plural
-          form of the name explicitly.</para>
+      <sect1 id="sec.HowToSpecifyTheIconForAnObjectsClass">
+        <title condition=".net">How to specify the icon for an object's
+        class</title>
 
-          <para>(Note that there is an entirely separate mechanism for dealing
-          with Internationalisation, which is described elsewhere).</para>
+        <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>The programmer may optionally also provide a <literal
-          moreinfo="none">@DescribedAs</literal> annotations, containing a
-          brief description of the object's purpose, from a user perspective.
-          The framework will make this available to the user in a form
-          appropriate to the user interface style - for example as 'balloon'
-          help.</para>
-        </sect2>
+        <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</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>
 
-        <sect2>
-          <title condition="vb">How to specify that an object should not be
-          persisted</title>
+        <para>We strongly recommend that you adopt 'camel 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>Use the <literal moreinfo="none">@NotPersistable</literal>
-          annotation.</para>
-        </sect2>
+        <para>You may alternatively choose to specify, manually, which icon to
+        use, by specifying an <literal moreinfo="none">iconName</literal>()
+        method:</para>
 
-        <sect2>
-          <title>How to specify that an object should never be modified by the
-          user</title>
+        <programlisting format="linespecific">public String iconName() {
+    return "Person";
+}</programlisting>
 
-          <para>Use the <literal moreinfo="none">@Immutable</literal>
-          annotation.</para>
-        </sect2>
+        <para>This makes it easy for more than one class to use the same icon,
+        without having to duplicate the image file.</para>
+      </sect1>
 
-        <sect2>
-          <title>How to specify that a class of objects has a limited number
-          of instances</title>
+      <sect1>
+        <title>How to specify the icon for an individual object's
+        state</title>
 
-          <para>Use the <literal moreinfo="none">@Bounded</literal>
-          annotation. A common way of describing this is that the whole
-          (limited) set of instances may be rendered to the user as a drop
-          down list - but the actual interpretation will depend upon the form
-          of the user interface.</para>
-        </sect2>
+        <para>As discussed in <xref
+        linkend="sec.HowToSpecifyTheIconForAnObjectsClass" />, the
+        <code>iconName()</code> method may be used to specify an object. The
+        value returned from this method need not be static, and so it can be
+        used to represent the state of an individual object.</para>
 
-        <sect2>
-          <title>How to specify that an object should always be hidden from
-          the user</title>
+        <para>For example, an instance of <classname>Product</classname> could
+        use a photograph of the product as an icon, using:</para>
 
-          <para>Use the <literal moreinfo="none">@Hidden</literal>
-          annotation.</para>
-        </sect2>
+        <programlisting format="linespecific">public String iconName() {
+    return getProductName() + "-photograph";
+}</programlisting>
+
+        <para>Alternatively, an <classname>Order</classname> might vary the
+        icon according to the status of the object:<programlisting>public String iconName() {
+    return "Order-" + getStatus();
+}</programlisting></para>
       </sect1>
 
-      <sect1 id="sec.ObjectLifecycle">
-        <title>The object lifecycle</title>
+      <sect1>
+        <title condition="j#">How to specify a name and/or description for an
+        object</title>
 
-        <para>These conventions are concerned with the creation, retrieval,
-        updating and deletion of objects.</para>
+        <para>By default, the name (or type) of an object, as displayed to the
+        user will be the class name. However, if an <literal
+        moreinfo="none">@Named</literal> annotation is included, then this
+        will override the default name. This might be used to include
+        punctuation or other characters that may not be used within a class
+        name.</para>
 
-        <sect2>
-          <title>How to create or delete objects within your code</title>
+        <para>By default the framework will create a plural version of the
+        object name by adding an 's' to singular name, or a 'ies' to names
+        ending 'y'. For irregular nouns or other special case, the
+        <code>@Plural</code> annotation may be used to specify the plural form
+        of the name explicitly.</para>
 
-          <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. Just specifying <literal
-          moreinfo="none">new Customer()</literal>, for example, will create a
-          Customer 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 intermediate. The application library provides an
-          interface:</para>
-
-          <para><literal
-          moreinfo="none">org.apache.isis.applib.DomainObjectContainer</literal>
-          which in turn defines the following methods for managing domain
-          objects:</para>
-
-          <para><literal moreinfo="none">&lt;T&gt; T
-          newTransientInstance(final Class&lt;T&gt; ofClass)</literal> returns
-          a new instance of the specified class, that is transient (unsaved).
-          This may subsequently 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">void
-          makePersistent(Object transientObject)</literal></para>
-
-          <para><literal moreinfo="none">&lt;T&gt; T
-          newPersistentInstance(final Class&lt;T&gt; ofClass)</literal>
-          creates a new object already persisted.</para>
-
-          <para><literal moreinfo="none">boolean
-          isPersistent()</literal>checks whether an object has already been
-          persisted. (Useful in controlling visibility or availability of
-          properties or actions).</para>
-
-          <para><literal moreinfo="none">void remove(Object object)</literal>
-          deletes a persistent object from the object store.</para>
-
-          <para>Any framework that recognises the Apache Isis Programming
-          Model will provide an implementation of
-          <code>DomainObjectContainer</code> and will take responsibility to
-          inject a reference to that Container into any domain object that
-          needs it.</para>
-
-          <para>A domain object specifies that it needs to have a reference to
-          the Container injected into by including the following code:</para>
+        <para>(Note that there is an entirely separate mechanism for dealing
+        with Internationalisation, which is described in the core
+        documentation).</para>
 
-          <programlisting format="linespecific">    private DomainObjectContainer container;
+        <para>The programmer may optionally also provide a <literal
+        moreinfo="none">@DescribedAs</literal> annotations, containing a brief
+        description of the object's purpose, from a user perspective. The
+        framework will make this available to the user in a form appropriate
+        to the user interface style - for example as 'balloon' help.</para>
+      </sect1>
 
-    protected DomainObjectContainer getContainer() {
-        return this.container;
-    }
-    public final void setContainer(final DomainObjectContainer container) {
-        this.container = container;
-    }</programlisting>
+      <sect1>
+        <title condition="vb">How to specify that an object should not be
+        persisted</title>
 
-          <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 Customer object within another method:</para>
-
-          <programlisting format="linespecific">    Customer newCust = (Customer) 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 = (Customer) newTransientInstance(Customer.class);
-    newCust.setName("Charlie");
-    persist(newCust);</programlisting>
-
-          <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, 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>
-        </sect2>
-
-        <sect2>
-          <title>How to insert behaviour into the object life cycle</title>
-
-          <para>The following is a list of methods that correspond to various
-          events in the life-cycle of a domain object. If a domain object
-          implements any of these methods (they are all optional) then the
-          framework will call that method whenever the corresponding event
-          occurs. For example, <literal
-          moreinfo="none"><methodname>persisted</methodname></literal> is
-          called after an object has been persisted. One reason for
-          implementing the <literal
-          moreinfo="none"><methodname>persisted</methodname></literal> method
-          might be to set up a reverse association that we do not want to be
-          set up until the new object has been persisted.</para>
-
-          <para><literal moreinfo="none">public void created() </literal>will
-          be called by the framework at logical creation of the object</para>
-
-          <para><literal moreinfo="none">public void loading()</literal> will
-          be called by the framework when a persistent object is about to be
-          loaded into memory</para>
-
-          <para><literal moreinfo="none">public void loaded()</literal> will
-          be called by the framework when a persistent object has just been
-          loaded into memory</para>
-
-          <para><literal moreinfo="none">public void persisting()
-          </literal>will be called by the framework just before a transient
-          object is first persisted. (For backwards compatibility
-          <methodname>saving()</methodname> is also supported).</para>
-
-          <para><literal moreinfo="none">public void persisted() </literal>
-          will be called by the framework just after a transient object is
-          first persisted. (For backwards compatibility
-          <methodname>saved()</methodname> is also supported).</para>
-
-          <para><literal moreinfo="none">public void updating() </literal>will
-          be called by the framework after any property on a persistent object
-          has been changed and just before this change is persisted</para>
-
-          <para><literal moreinfo="none">public void updated() </literal>will
-          be called by the framework just after a changed property on a
-          persistent object has been persisted</para>
-
-          <para><literal moreinfo="none">public void removing()</literal> will
-          be called by the framework when a persistent object is just about to
-          be deleted from the persistent object store. (For backwards
-          compatibility <methodname>deleting()</methodname> is also
-          supported).</para>
-
-          <para><literal moreinfo="none">public void removed()</literal> will
-          be called by the framework when a persistent object has just been
-          deleted from the persistent object store. (For backwards
-          compatibility <methodname>deleted()</methodname> is also
-          supported).</para>
-        </sect2>
-
-        <sect2 id="sec.ResolveAndObjectChanged">
-          <title>The resolve() and objectChanged() methods</title>
-
-          <para>In earlier versions of the framework it was necessary to call
-          the inherited <methodname>resolve()</methodname> method within every
-          property or collection's getter, and
-          <methodname>objectChanged()</methodname> within every property's
-          setter and every collection's addTo or removeFrom.</para>
-
-          <para>These methods still exist in
-          <classname>AbstractDomainObject</classname>, but no longer need to
-          be called explicitly. Instead Apache Isis uses bytecode enhancement
-          (using either cglib or javassist) to automatically call these
-          methods. This bytecode enhancement can be disabled in
-          <filename>isis.properties</filename> file; if it is then the methods
-          must be called manually.</para>
-        </sect2>
+        <para>Non-persisted objects are intended to be used as view models;
+        they aggregate some state with respect to a certain process. This may
+        be read-only (eg a projection of certain informaiton) or read-write
+        (eg a wizard-like process object). Either way, the viewer is expected
+        to interpret this by not providing any sort of automatic "save" menu
+        item if such an object is returned to the
+        <acronym>GUI</acronym>.</para>
+
+        <para>Non-persisted objects that are read-only are typically also
+        marked as immutable (see <xref linkend="sec.Immutable" />).</para>
+
+        <para>To indicate that an object cannot be persisted, use the <literal
+        moreinfo="none">@NotPersistable</literal> annotation.</para>
+      </sect1>
+
+      <sect1 id="sec.Immutable">
+        <title>How to specify that an object should never be modified by the
+        user</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>
+      </sect1>
+
+      <sect1>
+        <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>
+      </sect1>
+
+      <sect1>
+        <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.</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 = (Customer) 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>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>
+
+      <sect1>
+        <title>How to insert behaviour into the object life cycle</title>
+
+        <para><emphasis>Apache Isis</emphasis> is responsible for managing the
+        object lifecycle, persisting, updating or removing objects from the
+        persistent object store as required. For many applications the domain
+        objects are unaware of this. If required, though, an object can
+        provide callback methods (all optional) so that the framework can
+        notify it of its persistence state.</para>
+
+        <para>For example, the <literal
+        moreinfo="none"><methodname>persisted</methodname></literal>() method
+        is called after an object has been persisted. This could be used to
+        setup a reverse association that should only be created once the new
+        object has been persisted.</para>
+
+        <para>The full list of callbacks is shown below.</para>
+
+        <table>
+          <title>Object lifecycle methods</title>
+
+          <tgroup cols="2">
+            <colspec align="left" />
+
+            <thead>
+              <row>
+                <entry align="center">Method</entry>
+
+                <entry align="center">When called by framework</entry>
+              </row>
+            </thead>
+
+            <tbody>
+              <row>
+                <entry><methodname>created()</methodname></entry>
+
+                <entry>following the logical creation of the object (that is,
+                after <methodname>newTransientInstance()</methodname> has been
+                called)</entry>
+              </row>
+
+              <row>
+                <entry><methodname>loading()</methodname></entry>
+
+                <entry>when a persistent object is about to be loaded into
+                memory</entry>
+              </row>
+
+              <row>
+                <entry><methodname>loaded()</methodname></entry>
+
+                <entry>once the persistent object has just been loaded into
+                memory</entry>
+              </row>
+
+              <row>
+                <entry><methodname>persisting()</methodname> or
+                <methodname>saving()</methodname></entry>
+
+                <entry> just before a transient object is first
+                persisted.</entry>
+              </row>
+
+              <row>
+                <entry><methodname>persisted()</methodname> or
+                <methodname>saved()</methodname></entry>
+
+                <entry>just after a transient object is first
+                persisted.</entry>
+              </row>
+
+              <row>
+                <entry><methodname>updating()</methodname></entry>
+
+                <entry>after any property on a persistent object has been
+                changed and just before this change is persisted</entry>
+              </row>
+
+              <row>
+                <entry><methodname>updated()</methodname></entry>
+
+                <entry>after a changed property on a persistent object has
+                been persisted</entry>
+              </row>
+
+              <row>
+                <entry><methodname>removing()</methodname> or
+                <methodname>deleting()</methodname></entry>
+
+                <entry>when a persistent object is just about to be deleted
+                from the persistent object store.</entry>
+              </row>
+
+              <row>
+                <entry><methodname>removed()</methodname> or
+                <methodname>deleted()</methodname></entry>
+
+                <entry>when a persistent object has just been deleted from the
+                persistent object store.</entry>
+              </row>
+            </tbody>
+          </tgroup>
+        </table>
+      </sect1>
+
+      <sect1 id="sec.ResolveAndObjectChanged">
+        <title>How to perform lazy loading (generally done
+        automatically)</title>
+
+        <para>The DomainObjectContainer provides the resolve() method in order
+        to lazily resolve the value of a property or a collection. In earlier
+        versions of the framework it was necessary to call this method prior
+        to accessing or mutating any property or collection. This is no longer
+        required because <emphasis>Apache Isis</emphasis> uses bytecode
+        enhancement to automatically call this method.</para>
+
+        <para>While it is possible to disable this bytecode enhancement using
+        <filename>isis.properties</filename> file, this is not generally
+        recommended. If it is disabled then the
+        <methodname>resolve()</methodname> method may need to be called
+        manually.</para>
+      </sect1>
+
+      <sect1>
+        <title>How to perform dirty object tracking (generally done
+        automatically)</title>
+
+        <para>The <classname>DomainObjectContainer</classname> provides the
+        <methodname>objectChanged()</methodname> method in order to mark an
+        object's state as having changed, and therefore requiring an update to
+        the persistent object store. In earlier versions of the framework it
+        was necessary to call this method after mutating any the property or
+        collection. This is no longer required because <emphasis>Apache
+        Isis</emphasis> uses bytecode enhancement to automatically call this
+        method.</para>
+
+        <para>While it is possible to disable this bytecode enhancement using
+        <filename>isis.properties</filename> file, this is not generally
+        recommended. If it is disabled then the
+        <methodname>objectChanged()</methodname> method may need to be called
+        manually.</para>
       </sect1>
     </chapter>
 
-    <chapter>
-      <title>Object Member Recipes</title>
+    <chapter id="chp.Properties">
+      <title>Object Property Recipes</title>
 
       <abstract>
-        <para>How-to's relating to an object's class members.</para>
+        <para>How-to's relating to an object's properties.</para>
       </abstract>
 
-      <para>This chapter contains how-to's for programming conventions that
-      apply to an object's class members: properties (<xref
-      linkend="sec.Properties" />), collections (<xref
-      linkend="sec.Collections" />) and actions (<xref
-      linkend="sec.Actions" />). It also covers an alternative mechanism for
-      specifying business rules (<xref linkend="sec.MustSpecify" />).</para>
-
-      <sect1 id="sec.Properties">
-        <title>Properties</title>
+      <para>The following conventions are concerned with specifying the
+      properties of an object, and the way in which users can interact with
+      those properties.</para>
 
-        <para>The following conventions are concerned with specifying the
-        properties of an object, and the way in which users can interact with
-        those properties.</para>
-
-        <sect2>
-          <title>How to add a property to an object</title>
+      <sect1>
+        <title>How to add a property to an object</title>
 
-          <para>Properties are specified using the JavaBean conventions,
-          recognizing a standard accessor/mutator pair (<code>get</code> and
-          <code>set</code>). The syntax is:</para>
+        <para>Properties are specified using the JavaBean conventions,
+        recognizing a standard accessor/mutator pair (<code>get</code> and
+        <code>set</code>). The syntax is:</para>
 
-          <para><programlisting>public &lt;property type&gt; get&lt;PropertyName&gt;() 
+        <para><programlisting>public &lt;property type&gt; get&lt;PropertyName&gt;() 
 
 public void set&lt;PropertyName&gt;(&lt;property type&gt; param)</programlisting></para>
 
-          <para>where <literal moreinfo="none">&lt;property type&gt;</literal>
-          is a primitive, a value object or an entity object.</para>
+        <para>where <literal moreinfo="none">&lt;property type&gt;</literal>
+        is a primitive, a value object or an entity object.</para>
 
-          <para>Properties may reference either a value or another domain
-          object. Values include Java primitives, and JDK classes with value
-          semantics (<literal moreinfo="none">java.lang.Strings</literal> and
-          <literal moreinfo="none">java.util.Dates</literal>). 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>
+        <para>Properties may reference either a value or another domain
+        object. Values include Java primitives, and JDK classes with value
+        semantics (<literal moreinfo="none">java.lang.Strings</literal> and
+        <literal moreinfo="none">java.util.Dates</literal>). 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 {
+        <programlisting format="linespecific">public class Customer {
     private String firstName;
     public String getFirstName() {
         return firstName;
@@ -590,35 +700,35 @@ public void set&lt;PropertyName&gt;(&lt;
 
     ...
 }</programlisting>
-        </sect2>
+      </sect1>
 
-        <sect2>
-          <title>How to prevent the user from modifying a property</title>
+      <sect1>
+        <title>How to prevent the user from modifying a property</title>
 
-          <para>Preventing the user from modifying a property value is known
-          as 'disabling' the property.</para>
+        <para>Preventing the user from modifying a property value is known as
+        'disabling' the property.</para>
 
-          <sect3>
-            <title>Disabling a property always</title>
+        <sect2>
+          <title>Disabling a property always</title>
 
-            <para>Use the <literal moreinfo="none">@Disabled</literal>
-            annotation.</para>
-          </sect3>
+          <para>Use the <literal moreinfo="none">@Disabled</literal>
+          annotation.</para>
+        </sect2>
 
-          <sect3>
-            <title>Disabling a property under certain conditions</title>
+        <sect2>
+          <title>Disabling a property under certain conditions</title>
 
-            <para>A <literal moreinfo="none">disable</literal> method can be
-            used to disable a particular instance's member under certain
-            conditions. The syntax is:</para>
-
-            <para><literal moreinfo="none">public String
-            disable&lt;PropertyName&gt;()</literal> A non-null return value
-            indicates the reason why the property cannot be modified. The
-            framework is responsible for providing this feedback to the user.
-            For example:</para>
+          <para>A <literal moreinfo="none">disable</literal> method can be
+          used to disable a particular instance's member under certain
+          conditions. The syntax is:</para>
+
+          <para><literal moreinfo="none">public String
+          disable&lt;PropertyName&gt;()</literal> A non-null return value
+          indicates the reason why the property cannot be modified. The
+          framework is responsible for providing this feedback to the user.
+          For example:</para>
 
-            <programlisting format="linespecific">public class OrderLine {
+          <programlisting format="linespecific">public class OrderLine {
     public String getQuantity() { ... }
     public void setQuantity(int quantity) { ... }
 
@@ -629,24 +739,23 @@ public void set&lt;PropertyName&gt;(&lt;
         return null;
     }
 }</programlisting>
-          </sect3>
-
-          <sect3>
-            <title>Disabling a property for specific users or roles</title>
+        </sect2>
 
-            <para>Generally it is not good practice to embed knowledge of
-            roles and/or users into the domain classes. This is the
-            responsibility of the framework or platform and should be
-            specified and administered externally to the domain model.</para>
+        <sect2>
+          <title>Disabling a property for specific users or roles</title>
 
-            <para>However, in rare circumstances it might be necessary or
-            pragmatic to implement access control within the domain model
-            using the inherited <methodname>getUser()</methodname>
-            method:</para>
+          <para>Generally it is not good practice to embed knowledge of roles
+          and/or users into the domain classes. This is the responsibility of
+          the framework or platform and should be specified and administered
+          externally to the domain model.</para>
+
+          <para>However, in rare circumstances it might be necessary or
+          pragmatic to implement access control within the domain model using
+          the inherited <methodname>getUser()</methodname> method:</para>
 
-            <para>For example:</para>
+          <para>For example:</para>
 
-            <programlisting format="linespecific">import org.apache.isis.applib.UserMemento;
+          <programlisting format="linespecific">import org.apache.isis.applib.UserMemento;
 
 public class Employee {
     public BigDecimal getSalary() { ... }
@@ -658,45 +767,44 @@ public class Employee {
               "Need MODIFY_SALARY role to increase salary above 30000": null;
     }
 }</programlisting>
-          </sect3>
         </sect2>
+      </sect1>
 
-        <sect2>
-          <title>How to make a property optional (when saving an
-          object)</title>
+      <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. To specify that a particular property is
-          optional, use the <literal moreinfo="none">@Optional</literal>
-          annotation.</para>
-        </sect2>
+        <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. To specify that a particular property is
+        optional, use the <literal moreinfo="none">@Optional</literal>
+        annotation.</para>
+      </sect1>
 
-        <sect2>
-          <title>How to specify the size of String properties</title>
+      <sect1>
+        <title>How to specify the size of String properties</title>
 
-          <para>Use the <literal moreinfo="none">@MaxLength</literal>,
-          <literal moreinfo="none">@TypicalLength</literal> and <literal
-          moreinfo="none">@MultiLine</literal> annotations.</para>
-        </sect2>
+        <para>Use the <literal moreinfo="none">@MaxLength</literal>, <literal
+        moreinfo="none">@TypicalLength</literal> and <literal
+        moreinfo="none">@MultiLine</literal> annotations.</para>
+      </sect1>
 
-        <sect2>
-          <title>How to validate user input to a property</title>
+      <sect1>
+        <title>How to validate user input to a property</title>
 
-          <para>A <literal moreinfo="none">validate</literal> method is used
-          to check that a new value for a property is valid. 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>A <literal moreinfo="none">validate</literal> method is used to
+        check that a new value for a property is valid. 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>The syntax is:</para>
 
-          <para><programlisting>public String validate&lt;PropertyName&gt;(&lt;property type&gt; param)</programlisting></para>
+        <para><programlisting>public String validate&lt;PropertyName&gt;(&lt;property type&gt; param)</programlisting></para>
 
-          <para>For example:</para>
+        <para>For example:</para>
 
-          <programlisting format="linespecific">public class Exam {
+        <programlisting format="linespecific">public class Exam {
     public int getMark() { ... }
     public void setMark(int mark) { ... }
     public validateMark(int mark) {
@@ -706,47 +814,46 @@ public class Employee {
     }
 }</programlisting>
 
-          <sect3>
-            <title>Format validation</title>
+        <sect2>
+          <title>Format 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>
-
-            <para>For <literal moreinfo="none">Date</literal> and number
-            values the <literal moreinfo="none">@Mask</literal> annotation may
-            be used.</para>
-
-            <para>For <literal moreinfo="none">String</literal> properties the
-            <literal moreinfo="none">@RegEx</literal> annotation may be
-            used.</para>
-          </sect3>
+          <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>
+
+          <para>For <literal moreinfo="none">Date</literal> and number values
+          the <literal moreinfo="none">@Mask</literal> annotation may be
+          used.</para>
+
+          <para>For <literal moreinfo="none">String</literal> properties the
+          <literal moreinfo="none">@RegEx</literal> annotation may be
+          used.</para>
         </sect2>
+      </sect1>
 
-        <sect2>
-          <title>How to specify a set of choices and or a default value for a
-          property</title>
+      <sect1>
+        <title>How to specify a set of choices and or a default value 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>. However, this is not always appropriate. For
-          example you might wish to provide the user with the choice of all
-          the Addresses known for that Customer, with the most recently-used
-          address as the default.</para>
+        <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>. However, this is not always appropriate. For
+        example you might wish to provide the user with the choice of all the
+        Addresses known for that Customer, with the most recently-used address
+        as the default.</para>
 
-          <para>The syntax for specifying a default value is:</para>
+        <para>The syntax for specifying a default value is:</para>
 
-          <para><programlisting>public &lt;property type&gt; default&lt;PropertyName&gt;()</programlisting></para>
+        <para><programlisting>public &lt;property type&gt; default&lt;PropertyName&gt;()</programlisting></para>
 
-          <para>And for specifying a list of choices is:</para>
+        <para>And for specifying a list of choices is:</para>
 
-          <para><programlisting>public &lt;array or collection of property type&gt; choices&lt;PropertyName&gt;()</programlisting></para>
+        <para><programlisting>public &lt;array or collection of property type&gt; choices&lt;PropertyName&gt;()</programlisting></para>
 
-          <para>The full code for our example above is:</para>
+        <para>The full code for our example above is:</para>
 
-          <programlisting format="linespecific">public class Order {
+        <programlisting format="linespecific">public class Order {
     public Address getShippingAddress() { ... }
     public void setShippingAddress() { ... }
     public Address defaultShippingAddress() {
@@ -756,28 +863,28 @@ public class Employee {
         return getCustomer().allActiveAddresses();
     }
 }</programlisting>
-        </sect2>
+      </sect1>
 
-        <sect2>
-          <title>How to set up the initial value of a property
-          programmatically</title>
+      <sect1>
+        <title>How to set up the initial value of a property
+        programmatically</title>
 
-          <para>Initial values for properties may be set up programmatically
-          within the <literal moreinfo="none">created()</literal> method on
-          the object. (See Object: Life Cycle).</para>
-        </sect2>
+        <para>Initial values for properties may be set up programmatically
+        within the <literal moreinfo="none">created()</literal> method on the
+        object. (See Object: Life Cycle).</para>
+      </sect1>
 
-        <sect2>
-          <title>How to trigger other behaviour when a property is
-          changed</title>
+      <sect1>
+        <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 <literal
-          moreinfo="none">modify</literal> <literal
-          moreinfo="none">&lt;propertyName&gt;</literal> and include the
-          functionality within that. For example:</para>
+        <para>If you want to invoke functionality whenever a property is
+        changed by the user, then you should create a <literal
+        moreinfo="none">modify</literal> <literal
+        moreinfo="none">&lt;propertyName&gt;</literal> and include the
+        functionality within that. For example:</para>
 
-          <programlisting format="linespecific">public int getAmount() {}
+        <programlisting format="linespecific">public int getAmount() {}
 public void setAmount(int amount) {}
 
 public void modifyAmount(int amount) {
@@ -785,26 +892,26 @@ public void modifyAmount(int amount) {
      addToTotal(amount);
 }</programlisting>
 
-          <para>The reason for the <literal
-          moreinfo="none">modifyAmount</literal> method is that it would not
-          be a good idea to include the <literal
-          moreinfo="none">addToTotal</literal> call within the <literal
-          moreinfo="none">setAmount</literal> method , because that method may
-          be called by the persistence mechanism when an object is retrieved
-          from storage.</para>
-
-          <para>You may optionally also specify a
-          <code>clear&lt;PropertyName&gt;</code> which works the same way as
-          modify <literal moreinfo="none">modify</literal> <literal
-          moreinfo="none">&lt;propertyName&gt;</literal> but is called when
-          the property is cleared by the user (i.e. the current value replaced
-          by nothing).</para>
+        <para>The reason for the <literal
+        moreinfo="none">modifyAmount</literal> method is that it would not be
+        a good idea to include the <literal
+        moreinfo="none">addToTotal</literal> call within the <literal
+        moreinfo="none">setAmount</literal> method , because that method may
+        be called by the persistence mechanism when an object is retrieved
+        from storage.</para>
+
+        <para>You may optionally also specify a
+        <code>clear&lt;PropertyName&gt;</code> which works the same way as
+        modify <literal moreinfo="none">modify</literal> <literal
+        moreinfo="none">&lt;propertyName&gt;</literal> but is called when the
+        property is cleared by the user (i.e. the current value replaced by
+        nothing).</para>
 
-          <para>These methods may also be used for setting up bidirectional
-          relationships (using the 'mutual registration pattern'). For
-          example:</para>
+        <para>These methods may also be used for setting up bidirectional
+        relationships (using the 'mutual registration pattern'). For
+        example:</para>
 
-          <programlisting format="linespecific">public class Employee {
+        <programlisting format="linespecific">public class Employee {
     private Department department;
     public Department getDepartment() {
         return department;
@@ -823,106 +930,104 @@ public void modifyAmount(int amount) {
 
     ...
 }</programlisting>
-        </sect2>
+      </sect1>
+
+      <sect1>
+        <title>How to control the order in which properties are
+        displayed</title>
+
+        <para>Use the <literal moreinfo="none">@MemberOrder</literal>
+        annotation.</para>
+      </sect1>
+
+      <sect1>
+        <title>How to specify a name and/or description for a property</title>
 
         <sect2>
-          <title>How to control the order in which properties are
-          displayed</title>
+          <title>Specifying the name for a property</title>
 
-          <para>Use the <literal moreinfo="none">@MemberOrder</literal>
-          annotation.</para>
+          <para>By default the framework will use the property name itself to
+          label the property on the user interface. If you wish to over-ride
+          this, use the <literal moreinfo="none">@Named </literal>annotation
+          on the property.</para>
         </sect2>
 
         <sect2>
-          <title>How to specify a name and/or description for a
-          property</title>
+          <title>Specifying a description for a property</title>
 
-          <sect3>
-            <title>Specifying the name for a property</title>
+          <para>Use the <literal moreinfo="none">@DescribedAs</literal>
+          annotation on the property itself.</para>
 
-            <para>By default the framework will use the property name itself
-            to label the property on the user interface. If you wish to
-            over-ride this, use the <literal moreinfo="none">@Named
-            </literal>annotation on the property.</para>
-          </sect3>
+          <para>The framework will take responsibility to make this
+          description available to the user, for example in the form of a
+          'balloon help'.</para>
+        </sect2>
+      </sect1>
 
-          <sect3>
-            <title>Specifying a description for a property</title>
+      <sect1>
+        <title>How to hide a property from the user</title>
 
-            <para>Use the <literal moreinfo="none">@DescribedAs</literal>
-            annotation on the property itself.</para>
+        <sect2>
+          <title>Hiding a property always</title>
 
-            <para>The framework will take responsibility to make this
-            description available to the user, for example in the form of a
-            'balloon help'.</para>
-          </sect3>
+          <para>Use the <literal moreinfo="none">@Hidden</literal>
+          annotation.</para>
         </sect2>
 
         <sect2>
-          <title>How to hide a property from the user</title>
+          <title>Hiding a property under certain conditions</title>
 
-          <sect3>
-            <title>Hiding a property always</title>
-
-            <para>Use the <literal moreinfo="none">@Hidden</literal>
-            annotation.</para>
-          </sect3>
+          <para>A <literal moreinfo="none">hide</literal> method can be used
+          to indicate that a particular instance's member should be hidden
+          (rendered invisible to the user) under certain conditions. The
+          syntax is:</para>
+
+          <para><literal moreinfo="none">public boolean
+          hide&lt;PropertyName&gt;()</literal> A true return value indicates
+          that the property is hidden. For example:</para>
 
-          <sect3>
-            <title>Hiding a property under certain conditions</title>
-
-            <para>A <literal moreinfo="none">hide</literal> method can be used
-            to indicate that a particular instance's member should be hidden
-            (rendered invisible to the user) under certain conditions. The
-            syntax is:</para>
-
-            <para><literal moreinfo="none">public boolean
-            hide&lt;PropertyName&gt;()</literal> A true return value indicates
-            that the property is hidden. For example:</para>
-
-            <programlisting format="linespecific">public class Order {
+          <programlisting format="linespecific">public class Order {
     public String getShippingInstructions() { ... }
     public void setShippingInstructions(String shippingInstructions) { ... }
     public boolean hideShippingInstructions() {
         return hasShipped();
     }
 }</programlisting>
-          </sect3>
+        </sect2>
 
-          <sect3>
-            <title>Hiding a property for specific users or roles</title>
+        <sect2>
+          <title>Hiding a property for specific users or roles</title>
 
-            <para><emphasis role="strong">Important</emphasis>: see the
-            comments under 'Disabling a property for specific users or
-            roles'.</para>
-
-            <para>Session controls provide a way for the class to hide
-            properties from specific users, or users not in specific roles.
-            The syntax is: <literal moreinfo="none">public boolean
-            hide&lt;PropertyName&gt;(Session session)</literal> For
-            example:</para>
+          <para><emphasis role="strong">Important</emphasis>: see the comments
+          under 'Disabling a property for specific users or roles'.</para>
 
-            <programlisting format="linespecific">public class Employee {
+          <para>Session controls provide a way for the class to hide
+          properties from specific users, or users not in specific roles. The
+          syntax is: <literal moreinfo="none">public boolean
+          hide&lt;PropertyName&gt;(Session session)</literal> For
+          example:</para>
+
+          <programlisting format="linespecific">public class Employee {
     public BigDecimal getSalary() { ... }
     public void setSalary(BigDecimal salary) { ... }
     public boolean hideSalary(UserMemento user, BigDecimal salary) {
         return !user.hasRole("VIEW_SALARY");
     }
 }</programlisting>
-          </sect3>
         </sect2>
+      </sect1>
 
-        <sect2>
-          <title>How to make a property non-persisted</title>
+      <sect1>
+        <title>How to make a property non-persisted</title>
 
-          <para>If there is no mutator (<code>set</code>) method then the
-          field is not only unmodifiable but will also
-          <emphasis>not</emphasis> be persisted. This approach is by design
-          and also happens to be compatible with Java Persistence Api (JPA)
-          semantics. This may be used to derive a property from other
-          information available to the object, for example:</para>
+        <para>If there is no mutator (<code>set</code>) method then the field
+        is not only unmodifiable but will also <emphasis>not</emphasis> be
+        persisted. This approach is by design and also happens to be
+        compatible with Java Persistence Api (JPA) semantics. This may be used
+        to derive a property from other information available to the object,
+        for example:</para>
 
-          <programlisting format="linespecific">public class Employee {
+        <programlisting format="linespecific">public class Employee {
     public Department getDepartment() { ... }
     public void setDepartment(Department department) { ... }
     public void modifyDepartment(Department department) { ... }
@@ -937,47 +1042,87 @@ public void modifyAmount(int amount) {
     ...
 }</programlisting>
 
-          <para>If you need to have a <literal moreinfo="none">get</literal>
-          and <literal moreinfo="none">set</literal> method for the property
-          but do not wish to have that property persisted, use the <literal
-          moreinfo="none">@NotPersisted</literal> annotation.</para>
-        </sect2>
+        <para>If you need to have a <literal moreinfo="none">get</literal> and
+        <literal moreinfo="none">set</literal> method for the property but do
+        not wish to have that property persisted, use the <literal
+        moreinfo="none">@NotPersisted</literal> annotation.</para>
       </sect1>
 
-      <sect1 id="sec.Collections">
-        <title>Collections</title>
+      <sect1 id="sec.MustSpecify">
+        <title>@MustSatisfy Specification</title>
 
-        <para>A collection is a list of references to several entity objects
-        that have a common type.</para>
+        <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>
 
-        <sect2>
-          <title>How to add a collection to an object</title>
+        <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);
+    }
 
-          <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. The syntax is:</para>
+}</programlisting>
+
+        <para><remark>TODO: @MustSatisfy may not work for action parameters;
+        see <ulink
+        url="http://dev.nakedobjects.org/trac/ticket/669">http://dev.nakedobjects.org/trac/ticket/669</ulink>.</remark></para>
+      </sect1>
+    </chapter>
+
+    <chapter id="chp.Collections">
+      <title>Collections</title>
+
+      <abstract>
+        <para>***</para>
+      </abstract>
+
+      <para>*** A collection is a list of references to several entity objects
+      that have a common type.</para>
+
+      <sect1>
+        <title>How to add a collection to an object</title>
 
-          <para><programlisting>public &lt;collection type&gt; get&lt;CollectionName&gt;()
+        <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. The syntax is:</para>
+
+        <para><programlisting>public &lt;collection type&gt; get&lt;CollectionName&gt;()
 
 private void set&lt;CollectionName&gt;(&lt;collection type&gt; param)</programlisting></para>
 
-          <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. (Generics are also required by some persistence
-          mechanisms). For example the viewer might display the collection as
-          a table, with the columns defined by the visible properties of that
-          type. The viewer will then automatically prevent the user from
-          adding objects not of that type. If generics are not used then the
-          type may be inferred from the <literal
-          moreinfo="none">addTo</literal> / <literal
-          moreinfo="none">removeFrom</literal> methods, if specified (see
-          below).</para>
+        <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. (Generics are also required by some persistence
+        mechanisms). For example the viewer might display the collection as a
+        table, with the columns defined by the visible properties of that
+        type. The viewer will then automatically prevent the user from adding
+        objects not of that type. If generics are not used then the type may
+        be inferred from the <literal moreinfo="none">addTo</literal> /
+        <literal moreinfo="none">removeFrom</literal> methods, if specified
+        (see below).</para>
 
-          <para>For example:</para>
+        <para>For example:</para>
 
-          <programlisting format="linespecific">public class Employee { ... }
+        <programlisting format="linespecific">public class Employee { ... }
 
 public class Department {
     private List&lt;Employee&gt; employees = new ArrayList&lt;Employee&gt;();
@@ -989,27 +1134,27 @@ public class Department {
     }
     ...
 }</programlisting>
-        </sect2>
+      </sect1>
 
-        <sect2>
-          <title>How to trigger other behaviour when an object is added or
-          removed</title>
+      <sect1>
+        <title>How to trigger other behaviour when an object is added or
+        removed</title>
 
-          <para>A collection may have a corresponding <literal
-          moreinfo="none">addTo</literal> and/or <literal
-          moreinfo="none">removeFrom</literal> method. This is equivalent to
-          the <literal moreinfo="none">modify</literal> and <literal
-          moreinfo="none">clear</literal> methods for properties. The syntax
-          is:</para>
+        <para>A collection may have a corresponding <literal
+        moreinfo="none">addTo</literal> and/or <literal
+        moreinfo="none">removeFrom</literal> method. This is equivalent to the
+        <literal moreinfo="none">modify</literal> and <literal
+        moreinfo="none">clear</literal> methods for properties. The syntax
+        is:</para>
 
-          <para><programlisting>public void addTo&lt;CollectionName&gt;(&lt;entity type&gt; param)
+        <para><programlisting>public void addTo&lt;CollectionName&gt;(&lt;entity type&gt; param)
 
 public void removeFrom&lt;CollectionName&gt;(&lt;entity type&gt; param)</programlisting></para>
 
-          <para>where <literal moreinfo="none">&lt;entity type&gt;</literal>
-          is the same type as the generic collection type. For example:</para>
+        <para>where <literal moreinfo="none">&lt;entity type&gt;</literal> is
+        the same type as the generic collection type. For example:</para>
 
-          <programlisting format="linespecific">public class Employee { ... }
+        <programlisting format="linespecific">public class Employee { ... }
 
 public class Department {
     private List&lt;Employee&gt; employees = new ArrayList&lt;Employee&gt;();
@@ -1029,37 +1174,37 @@ public class Department {
     ...
 }</programlisting>
 
-          <para>The addTo / removeFrom and modify / clear methods are
-          particularly useful in setting up bidirectional relationships using
-          the 'mutual registration pattern'; for a write-up of this pattern,
-          see <ulink
-          url="???">http://www.two-sdg.demon.co.uk/curbralan/papers/MutualRegistration.pdf</ulink>.</para>
-        </sect2>
+        <para>The addTo / removeFrom and modify / clear methods are
+        particularly useful in setting up bidirectional relationships using
+        the 'mutual registration pattern'; for a write-up of this pattern, see
+        <ulink
+        url="???">http://www.two-sdg.demon.co.uk/curbralan/papers/MutualRegistration.pdf</ulink>.</para>
+      </sect1>
 
-        <sect2>
-          <title>How to prevent the user from modifying a collection</title>
+      <sect1>
+        <title>How to prevent the user from modifying a collection</title>
 
-          <para>Preventing the user from adding to or removing from a
-          collection is known as 'disabling' the collection.</para>
+        <para>Preventing the user from adding to or removing from a collection
+        is known as 'disabling' the collection.</para>
 
-          <sect3>
-            <title>Disabling a collection permanently</title>
+        <sect2>
+          <title>Disabling a collection permanently</title>
 
-            <para>Use the <literal moreinfo="none">@Disabled</literal>
-            annotation.</para>
-          </sect3>
+          <para>Use the <literal moreinfo="none">@Disabled</literal>
+          annotation.</para>
+        </sect2>
 
-          <sect3>
-            <title>Disabling a collection under certain conditions</title>
+        <sect2>
+          <title>Disabling a collection under certain conditions</title>
 
-            <para>A <literal moreinfo="none">disable</literal> method can be
-            used to disable a particular instance's collection under certain
-            conditions: The syntax is:</para>
+          <para>A <literal moreinfo="none">disable</literal> method can be
+          used to disable a particular instance's collection under certain
+          conditions: The syntax is:</para>
 
-            <para><literal moreinfo="none">public String
-            disable&lt;CollectionName&gt;()</literal> For example:</para>
+          <para><literal moreinfo="none">public String
+          disable&lt;CollectionName&gt;()</literal> For example:</para>
 
-            <programlisting format="linespecific">public class Department {
+          <programlisting format="linespecific">public class Department {
     public List&lt;Employee&gt; getEmployees() { ... }
     public void addToEmployees(Employee employee) { ... }
     public void removeFromEmployees(Employee employee) { ... }
@@ -1067,33 +1212,33 @@ public class Department {
         return isClosed()? "This department is closed" : null;
     }
 }</programlisting>
-          </sect3>
+        </sect2>
 
-          <sect3>
-            <title>Disabling a collection for specific users or roles</title>
+        <sect2>
+          <title>Disabling a collection for specific users or roles</title>
 
-            <para>See Properties: Disabling a property for specific users or
-            roles'. The same technique can be applied to collections, with the
-            same caveats applying.</para>
-          </sect3>
+          <para>See Properties: Disabling a property for specific users or
+          roles'. The same technique can be applied to collections, with the
+          same caveats applying.</para>
         </sect2>
+      </sect1>
 
-        <sect2>
-          <title>How to validate an object to be added or removed</title>
+      <sect1>
+        <title>How to validate an object to be added or removed</title>
 
-          <para>A <literal moreinfo="none">validate</literal> method is used
-          to check that an object to be added or removed from a collection is
-          valid. A non-null return <code>String</code> indicates the reason
-          why the object cannot be added/removed, and the viewing mechanism
-          will display this to the user. The syntax is:</para>
+        <para>A <literal moreinfo="none">validate</literal> method is used to
+        check that an object to be added or removed from a collection is
+        valid. A non-null return <code>String</code> indicates the reason why
+        the object cannot be added/removed, and the viewing mechanism will
+        display this to the user. The syntax is:</para>
 
-          <para><programlisting>public String validateAddTo&lt;CollectionName&gt;(&lt;property type&gt; param) 
+        <para><programlisting>public String validateAddTo&lt;CollectionName&gt;(&lt;property type&gt; param) 
 
 public String validateRemoveFrom&lt;CollectionName&gt;(&lt;property type&gt; param)</programlisting></para>
 
-          <para>For example:</para>
+        <para>For example:</para>
 
-          <programlisting format="linespecific">public class Department {
+        <programlisting format="linespecific">public class Department {
     private List&lt;Employee&gt; employees = new ArrayList&lt;Employee&gt;();
     public List&lt;Employee&gt; getEmployees() { ... }
     private void setEmployees(List&lt;Employee&gt; employees) { ... }
@@ -1102,39 +1247,39 @@ public String validateRemoveFrom&lt;Coll
             "Cannot add retired employees to department"
             :null;
 }</programlisting>
-        </sect2>
+      </sect1>
 
-        <sect2>
-          <title>How to control the order in which collections are
-          displayed</title>
+      <sect1>
+        <title>How to control the order in which collections are
+        displayed</title>
 
-          <para>Use the <literal moreinfo="none">@MemberOrder</literal>
-          annotation.</para>
-        </sect2>
+        <para>Use the <literal moreinfo="none">@MemberOrder</literal>
+        annotation.</para>
+      </sect1>
 
-        <sect2>
-          <title>How to specify a name and/or description for a
-          collection</title>
+      <sect1>
+        <title>How to specify a name and/or description for a
+        collection</title>
 
-          <para>Use the <literal moreinfo="none">@Named</literal> and/or
-          <literal moreinfo="none">@DescribedAs</literal> annotations.</para>
-        </sect2>
+        <para>Use the <literal moreinfo="none">@Named</literal> and/or
+        <literal moreinfo="none">@DescribedAs</literal> annotations.</para>
+      </sect1>
 
-        <sect2>
-          <title>How to hide a collection</title>
+      <sect1>
+        <title>How to hide a collection</title>
 
-          <para>See 'Properties: How to hide a property'. The same approaches
-          work for collections.</para>
-        </sect2>
+        <para>See 'Properties: How to hide a property'. The same approaches
+        work for collections.</para>
+      </sect1>
 
-        <sect2>
-          <title>How to create a derived collection</title>
+      <sect1>
+        <title>How to create a derived collection</title>
 
-          <para>Collections can be derived, in the same way as properties.
-          These are not persisted, but are represented as read only
-          collections. For example:</para>
+        <para>Collections can be derived, in the same way as properties. These
+        are not persisted, but are represented as read only collections. For
+        example:</para>
 
-          <programlisting format="linespecific">public class Department {
+        <programlisting format="linespecific">public class Department {
     // Standard collection
     List&lt;Employee&gt; employees = new ArrayList&lt;Employee&gt;();
     public List&lt;Employee&gt; getEmployees() { ... }
@@ -1153,108 +1298,111 @@ public String validateRemoveFrom&lt;Coll
         return terminatedEmployees;
     }
 }</programlisting>
-        </sect2>
       </sect1>
+    </chapter>
 
-      <sect1 id="sec.Actions">
-        <title>Actions</title>
+    <chapter id="sec.Actions">
+      <title>Actions</title>
 
-        <para>An 'action' is a method that we expect the user to be able to
-        invoke 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.</para>
-
-        <sect2>
-          <title>How to add an action to an object</title>
-
-          <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 manual.</para>
-
-          <para>If you have a method that you don't want to be made available
-          as a user-action you should either make it <literal
-          moreinfo="none">protected</literal> or <literal
-          moreinfo="none">private</literal> or use the <literal
-          moreinfo="none">@Hidden</literal> annotation. Note also that
-          <literal moreinfo="none">static</literal> methods are ignored: such
-          functionality should reside in a service, such as a Repository or
-          Factory.</para>
+      <abstract>
+        <para>***</para>
+      </abstract>
 
-          <para>We refer to all methods that are intended to be invoked by
-          users as 'action methods'.</para>
+      <para>An 'action' is a method that we expect the user to be able to
+      invoke 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.</para>
 
-          <para>The syntax is:</para>
+      <sect1>
+        <title>How to add an action to an object</title>
 
-          <para><programlisting>public void &lt;actionName&gt;([&lt;value or entity type&gt; param]...)</programlisting></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 manual.</para>
 
-          <para>or</para>
+        <para>If you have a method that you don't want to be made available as
+        a user-action you should either make it <literal
+        moreinfo="none">protected</literal> or <literal
+        moreinfo="none">private</literal> or use the <literal
+        moreinfo="none">@Hidden</literal> annotation. Note also that <literal
+        moreinfo="none">static</literal> methods are ignored: such
+        functionality should reside in a service, such as a Repository or
+        Factory.</para>
 
-          <para><programlisting>public &lt;return type&gt; &lt;actionName&gt;([&lt;value or entity type&gt; param]...)</programlisting></para>
+        <para>We refer to all methods that are intended to be invoked by users
+        as 'action methods'.</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>
-        </sect2>
+        <para>The syntax is:</para>
 
-        <sect2>
-          <title>How to specify parameters for an action</title>
+        <para><programlisting>public void &lt;actionName&gt;([&lt;value or entity type&gt; param]...)</programlisting></para>
 
-          <para>If an action method takes parameters, the viewing mechanism
-          will automatically require the user to specify these parameters (for
-          example, in the form of a dialog box) - and ensure that they are of
-          the correct type.</para>
+        <para>or</para>
 
-          <sect3>
-            <title>Specifying parameter names and/or descriptions</title>
+        <para><programlisting>public &lt;return type&gt; &lt;actionName&gt;([&lt;value or entity type&gt; param]...)</programlisting></para>
 
-            <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:) 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. (This is one
-            of the few forms of duplication that we cannot eliminate; the
-            parameter name is not available in the class' bytecode and so
-            cannot be inferred automatically. Alternatively though, you could
-            create a user-defined value type, using
-            <literal>@Value</literal>).</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>
-          </sect3>
+        <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>
+      </sect1>
 
-          <sect3>
-            <title>How to make a parameter optional</title>
+      <sect1>
+        <title>How to specify parameters for an action</title>
 
-            <para>By default, the framework assumes that when an action method
-            is to be invoked, all the parameters are mandatory. You may
-            over-ride this behaviour by marking up one or more of the
-            paramaters with the <literal moreinfo="none">@Optional</literal>
-            annotation.</para>
-          </sect3>
+        <para>If an action method takes parameters, the viewing mechanism will
+        automatically require the user to specify these parameters (for
+        example, in the form of a dialog box) - and ensure that they are of
+        the correct type.</para>
 
-          <sect3>
-            <title>How to specify default values for parameters</title>
+        <sect2>
+          <title>Specifying parameter names and/or descriptions</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>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:) 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. (This is one of
+          the few forms of duplication that we cannot eliminate; the parameter
+          name is not available in the class' bytecode and so cannot be
+          inferred automatically. Alternatively though, you could create a
+          user-defined value type, using <literal>@Value</literal>).</para>
 
-            <para>There are two different ways to specify parameters; either
-            per parameter, or for all parameters. The per-parameter form is
-            simpler and probably preferred; the syntax is:</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>
+        </sect2>
 
-            <programlisting>public &lt;parameter type&gt; defaultN&lt;ActionName&gt;()</programlisting>
+        <sect2>
+          <title>How to make a 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

[... 514 lines stripped ...]


Mime
View raw message