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 2012/12/21 15:13:51 UTC

[4/4] ISIS-289: refactoring applib doc

http://git-wip-us.apache.org/repos/asf/isis/blob/208dc100/core/applib/src/docbkx/guide/isis-applib.xml
----------------------------------------------------------------------
diff --git a/core/applib/src/docbkx/guide/isis-applib.xml b/core/applib/src/docbkx/guide/isis-applib.xml
index 45ebd3a..28ccc04 100644
--- a/core/applib/src/docbkx/guide/isis-applib.xml
+++ b/core/applib/src/docbkx/guide/isis-applib.xml
@@ -58,13 +58,8 @@
     <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 framework plus a number of alternate
-    implementations, and supports various viewers and runtimes/object stores.
-    Apache Isis 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>
+    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
@@ -72,981 +67,16 @@
     <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 -->
 
-  <chapter>
-    <title>Introduction</title>
-
-    <abstract>
-      <para>What this guide contains, who it is for, and how the applib
-      relates to other parts of the framework.</para>
-    </abstract>
-
-    <sect1>
-      <title>What's in this Guide</title>
-
-      <para>This guide describes the set of conventions for writing domain
-      objects, that are together known as the <emphasis>Apache Isis</emphasis>
-      Programming Model. It's important reading for developers who are looking
-      to write domain-driven applications either for prototyping or deployment
-      on <emphasis>Apache Isis</emphasis>.</para>
-
-      <para>More correctly, this guide actually documents the
-      <emphasis>default</emphasis> programming model, targetted for the Java
-      programming language, and implemented by the
-      <classname>org.apache.isis.progmodels:dflt</classname> module.
-      <emphasis>Isis</emphasis> is in fact capable of supporting different
-      programming models, either for other JVM-based languages; for example
-      the Groovy language is supported in the
-      <classname>org.apache.isis.progmodels:groovy</classname> module. Those
-      other programming models have their own documentation.</para>
-    </sect1>
-
-    <sect1>
-      <title>This Guide vs the Core Documentation</title>
-
-      <para>This guide assumes that you have at least the outline of a running
-      <emphasis>Apache Isis</emphasis> application, for example having run the
-      quickstart archetype. Details of how to run the quickstart archetype can
-      be found on the <emphasis>Isis</emphasis> <ulink
-      url="http://incubator.apache.org/isis">website</ulink>.</para>
-
-      <para>This guide has two main objectives:</para>
-
-      <itemizedlist>
-        <listitem>
-          <para>to describe the general approach for developing Isis
-          applications solely by writing domain objects</para>
-        </listitem>
-
-        <listitem>
-          <para>to describe the specifics of writing domain objects according
-          to the conventions of the <emphasis>default</emphasis> programming
-          model.</para>
-        </listitem>
-      </itemizedlist>
-
-      <para>The core documentation, on the other hand, explains the wider
-      landscape of what makes up an <emphasis>Isis</emphasis> application,
-      dealing with such matters as running the app with different components,
-      eg viewers, security, programming models, profile stores and
-      runtimes/object stores. Included within this is an explanation of how
-      you can build your <emphasis>own</emphasis> programming model (typically
-      as a subset of the default programming model described here, but
-      possibly with additional custom elements).</para>
-    </sect1>
-
-    <sect1>
-      <title>Where Next?</title>
-
-      <para>This guide is in several parts. The first part is intended to
-      explain, from a developers' perspective, what exactly <emphasis>Apache
-      Isis</emphasis> is. The second part has chapters that describe the
-      specifics in the style of recipes/cookbooks, providing a "how-to" guide
-      on developing domain objects. The third part provides details on other
-      supporting features relevant to writing domain applications. The final
-      part is a series of appendices that provide details of the programming
-      model in reference form. You should find this more useful if you've used
-      <emphasis>Isis</emphasis> for a while and just need to check on a
-      specific detail.</para>
-    </sect1>
-  </chapter>
-
-  <part id="prt.UnderstandingApacheIsis">
-    <title>Understanding Apache Isis</title>
-
-    <partintro>
-      <para>The chapters in this part of the guide are intended to help you
-      understand <emphasis>Apache Isis</emphasis> from a developers'
-      perspective:</para>
-
-      <itemizedlist>
-        <listitem>
-          <para>the principles and patterns that underpin
-          <emphasis>Isis</emphasis> (<xref
-          linkend="chp.PrinciplesAndPatterns" />)</para>
-        </listitem>
-
-        <listitem>
-          <para>a development process to follow (<xref
-          linkend="chp.DevelopmentProcess" />)</para>
-        </listitem>
-      </itemizedlist>
-    </partintro>
-
-    <chapter id="chp.PrinciplesAndPatterns">
-      <title>Apache Isis and Naked Objects</title>
-
-      <abstract>
-        <para>Understanding Apache Isis and the naked objects pattern by way
-        of a series of questions and answers.</para>
-      </abstract>
-
-      <para>The headline feature that distinguishes <emphasis>Apache
-      Isis</emphasis> from other frameworks is its support for the naked
-      objects pattern - the ability to generate a user interface (at runtime)
-      directly from the domain model. However, there's much more to
-      <emphasis>Apache Isis</emphasis> than this.</para>
-
-      <para>This chapter introduces the <emphasis>Apache Isis</emphasis> and
-      the naked objects pattern by way of a series of questions and answers.
-      It is adapted from an <ulink
-      url="http://www.infoq.com/articles/haywood-ddd-no">interview originally
-      published on InfoQ</ulink>.</para>
-
-      <sect1>
-        <title>Apache Isis implements the naked objects pattern... but what is
-        that, exactly?</title>
-
-        <para>Naked objects is an architectural pattern where the idea is to
-        automatically expose a domain model objects directly within a
-        object-oriented user interface... not just their state (properties and
-        collections) but also their behaviour (what we call actions). You can
-        think of it as analogous to an <acronym>ORM</acronym> such as <ulink
-        url="http://hibernate.org">Hibernate</ulink>; but whereas an
-        <acronym>ORM</acronym> reflects the domain model into the persistence
-        layer, naked objects reflects the domain model into the presentation
-        layer.</para>
-
-        <para>Naked Objects (capitals) was a Java framework that implemented
-        the naked objects (lower case) pattern. Since then, we've taken the
-        original framework, along with a number of sister projects developed
-        by the community, into the Apache Incubator. So, what was originally
-        "Naked Objects" is now Apache Isis.</para>
-      </sect1>
-
-      <sect1>
-        <title>What type of applications are best suited to Isis?</title>
-
-        <para>The naked objects pattern requires that your primary
-        consideration is in building an object-oriented domain model, so it's
-        most suitable for enterprise applications that have complex business
-        rules where there's a desire to represented them within such a domain
-        model. The idea - at least during the initial stages - is to build up
-        a domain model quickly, and to get feedback from the domain experts by
-        exploiting the framework's ability to expose that directly domain
-        model within the user interface. A picture tells a thousand
-        words.</para>
-
-        <para>Apache Isis "sweet spot" are those applications that are used
-        internally within the organization, by experienced users who are
-        comfortable with the entities within the domain model, and just need
-        an application that imposes as few constraints as possible on how it
-        is used. These are sometimes called <emphasis>sovereign
-        applications</emphasis>. If you're a developer then your
-        <acronym>IDE</acronym> is probably the sovereign application you use
-        the most, and how often did you use any of its wizards? And if you use
-        telephone banking then you'll also know how frustrating a sovereign
-        application can be that is too invasive in dictating the workflow...
-        that poor person on the other end asks making apologies while she goes
-        exits from one screen and then goes into another to check some detail
-        on a bank account. The generic <acronym>OO</acronym>
-        <acronym>UI</acronym>s generated by naked objects impose no such
-        restrictions, and so are ideal for this sort of application.</para>
-      </sect1>
-
-      <sect1>
-        <title>And are there applications where the OO UIs generated by Isis
-        are less suitable?</title>
-
-        <para>The opposite of a sovereign application (above) is sometimes
-        called a <emphasis>transient application</emphasis>. These are ones
-        used only occasionally or by inexperienced users, typically outside
-        the organization (ie your customers), who don't know or care to know
-        the domain model, and just want to be led through the system to
-        accomplish some well-defined goal. A good example here is a check-in
-        kiosk at an airport... you just want to get on the plane, and be given
-        the opportunity to choose your seat. But you likely won't care which
-        plane, or even plane type, nor who the pilot is; these are unimportant
-        details.</para>
-
-        <para>For this sort of application a generic <acronym>OO</acronym>
-        <acronym>UI</acronym> that exposes lots of the domain is clearly not
-        appropriate. Instead, we want an application that exposes view models
-        rather than entities, and where the <acronym>UI</acronym> can be
-        customized. The view model object is responsible for managing the
-        workflow for the user story, exposing just the subset of the domain
-        that is relevant, and hiding the rest of the domain. We find that
-        these view models can be layered on top of the entities once those
-        entities are understood.</para>
-
-        <para>Using view model objects is necessary but probably not
-        sufficient for transient applications; we also usually need to
-        customize the <acronym>UI</acronym>. <emphasis>Apache Isis</emphasis>
-        has two viewers that allow the UI to be customized, one that provides
-        a set of taglibs, and one that provides a set of <ulink
-        url="http://wicket.apache.org">Apache Wicket</ulink>
-        components.</para>
-
-        <para>Putting both of these techniques together (custom view models
-        and views) means that Apache Isis is suitable for transient
-        applications as well as sovereign applications. However, the former
-        will necessarily take more work as opposed to the latter.</para>
-      </sect1>
-
-      <sect1>
-        <title>What is the typical development process life cycle for
-        applications built with Isis, and how does it compare to traditional
-        application development process?</title>
-
-        <para>The main difference you're likely to encounter is the emphasis
-        on developing the domain model at the same time as identifying and
-        prioritizing user stories, what those practicing domain driven design
-        call a "ubiquitous language" for the team.</para>
-
-        <para>So, rather than let the developers in the team "discover" the
-        domain model as part of story implementation, we'd expect that the
-        domain experts/business analysts have already identified some of the
-        main domain concepts through prototyping or spikes, and these can be
-        used to help communicate the stories to the developers during the
-        planning game. Not every business analyst is going to feel comfortable
-        working with an <acronym>IDE</acronym>, but it works well to pair with
-        a developer. Because an Apache Isis application can be runs just from
-        domain classes, it's possible to develop the app very very quickly.
-        We've found a good technique is to run workshops with the business
-        analyst facilitating the meeting with the domain experts, and the
-        developer acting as "code monkey" to rapidly convert the ideas into an
-        app. Obviously the code isn't production quality, but it allows the
-        team as a whole to go very quickly and experiment with different
-        representations of the model.</para>
-
-        <para>Another alternative is to go a little more slowly, and have the
-        analyst and developer pairing to write production code. The analyst
-        still focuses on identifying and naming the domain concepts and their
-        relationships, while the developer's role (as well as learning about
-        the domain) is to ensure that there's enough rigour and tests around
-        the code that's been written while this is being done. Of course, both
-        approaches to pairing can be used, sometimes spiking ideas, sometimes
-        going straight to writing tested code.</para>
-
-        <para>Of course, while the naked objects pattern means that no
-        <acronym>UI</acronym> code needs to be written in order to elicit
-        feedback, there do still need to be objects in the app for the domain
-        expert to view. Apache Isis has a pluggable runtime/persistence layer,
-        and for prototyping and most of development we recommend using the
-        in-memory object store. To populate this object store for each run we
-        use fixtures, which we usually arrange into a composite pattern to
-        setup data needed for the particular scenario we might be working on.
-        Using Isis in this way means that we spend our time alternating
-        between defining domain classes and writing fixture data. This can be
-        a great benefit because it helps the domain experts - who after all
-        aren't necessarily technical - distinguish between what are classes
-        and what are instances of classes. For example, if I'm writing a
-        library system and we identify there are loanable books and reference
-        books, we need to know whether "loanable book" and "reference book"
-        are different subclasses of a book superclass, or merely different
-        instances of a book class with, say, a loanable property set to true
-        or false. Seeing a running application makes it much easier for the
-        domain expert to make the call.</para>
-
-        <para>In terms of writing tests, there are several options. First,
-        because the domain objects you write are basically pojos that follow
-        some naming conventions, they are very easy to test using standard
-        <acronym>TDD</acronym> tools such as <ulink
-        url="http://junit.org">JUnit</ulink> and <ulink
-        url="http://jmock.org">JMock</ulink>. And if you wanted to, you could
-        test the <acronym>UI</acronym> generated by Isis using <ulink
-        url="http://seleniumhq.org/">Selenium</ulink> and similar; indeed we'd
-        recommend that if you've customized the <acronym>UI</acronym>.</para>
-
-        <para>In addition, though, Isis provides a couple of additional
-        BDD/testing framework integrations. One of these is an integration
-        with <ulink url="http://fitnesse.org">FitNesse</ulink>, and a newer
-        one we've worked on is an integration with <ulink
-        url="http://concordion.org">Concordion</ulink>. In both cases the
-        integrations provide the glue code so you can exercise your domain
-        objects directly. For example, your spec might say "the place order
-        action cannot be invoked if the product is out of stock". All the
-        developer needs to do is to wire the spec to these pre-canned
-        integrations, specifying that the
-        <methodname>placeOrder()</methodname> action should be called on a
-        <classname>Product</classname>.</para>
-
-        <para>Isis also provides a JUnit runner that works by bootstrapping
-        the Isis runtime for each test, and proxying the domain objects with a
-        bit of cglib so that they are interacted with "as if" through the
-        <acronym>UI</acronym>. For example, let's go back to that
-        <methodname>placeOrder()</methodname> action. To prevent this from
-        being called for a <classname>Product</classname> that's out of stock,
-        the developer would write a corresponding
-        <methodname>validatePlaceOrder()</methodname> method. Isis
-        automatically calls this validate method prior to the
-        <methodname>placeOrder()</methodname> method, and uses the return
-        value ("that product is out of stock") as the reason why the action
-        can't be invoked. In the <acronym>UI</acronym>, this business rule is
-        represented by greying out the OK button of the action. In the JUnit
-        runner, this rule is represented by having the cglib proxy throw a
-        validation exception if the test calls
-        <methodname>placeOrder()</methodname> with an out of stock
-        <classname>Product</classname>.</para>
-
-        <para>In terms of deployment, there's several steps involved, probably
-        the most significant being to select the runtime and object store. As
-        noted above, Isis has a pluggable persistence layer; you can use the
-        in-memory object store for developing, but will want to switch to a
-        "real" object store for deployment. The amount of work required here
-        depends on the object store selected; in the case of
-        <acronym>JPA</acronym>/Hibernate support, for example, it amounts to
-        annotating your domain entities with annotations, and writing
-        implementations of some of the repositories to make the relevant
-        <acronym>SQL</acronym> calls.</para>
-      </sect1>
-
-      <sect1>
-        <title>What are the limitations of Apache Isis framework?</title>
-
-        <para>It's certainly true that naked objects pattern implemented by
-        <emphasis>Apache Isis</emphasis> is opinionated, so if you don't agree
-        with all of its opinions then you're going to find it limiting in one
-        way or another.</para>
-
-        <para>The first of these is that everything that the user wants to
-        interact with has to be an object of some sort. As already explained,
-        for sovereign applications, these are likely to be the persisted
-        domain entities, but for a transient application, the object may be a
-        view model to be support a particular workflow, and which may or may
-        not be persisted. Such an approach probably wouldn't be considered
-        much of a limitation, but it's worth contrasting with architectures
-        (eg Spring Web Flow or Struts) where put the responsibility for
-        tracking workflow lives not in an object but instead within some sort
-        of declarative XML markup (or even just in the interplay between
-        controllers and views).</para>
-
-        <para>A slightly more subtle consequence of the above is that
-        integration of different technologies happens through the domain
-        objects, rather than in front of them through application-layer or
-        <acronym>UI</acronym> layer mashups. For example, supposing that we
-        wanted to have an <acronym>SMS</acronym> sent out to confirm a
-        checkout. If you were writing the <acronym>UI</acronym> and
-        application service layer yourself, you might choose to have the
-        application layer make the call to the <acronym>SMS</acronym> service,
-        judging it to be a coordination responsibility. With
-        <emphasis>Isis</emphasis>, though, you don't get the chance to write
-        any application layer code, and so this would be done by having the
-        domain object call out to the <acronym>SMS</acronym> service. The
-        <acronym>SMS</acronym> service would be defined by an interface, and
-        the implementation would be injected into the domain object by the
-        framework. For some reason not everyone is necessarily comfortable
-        about injecting domain services into entities; but it works well for
-        us and we're sticking with it.</para>
-
-        <para>Another area where <emphasis>Isis</emphasis> is going to feel
-        different - and perhaps limiting to some - is that it pushes some
-        responsibilities onto the domain objects that otherwise might sit in
-        other layers. For example, above we discussed that a
-        <methodname>placeOrder()</methodname> action on a
-        <classname>Customer</classname> can have a supporting
-        <methodname>validatePlaceOrder()</methodname> method. It's also
-        possible to have <methodname>disablePlaceOrder()</methodname> method,
-        which if returning non-null will cause the action to be greyed out the
-        action in the <acronym>UI</acronym>. For example, a blacklisted
-        <classname>Customer</classname> might not allow any orders to be
-        placed, and would indicate this through the disable method. Some might
-        consider this as a misplaced presentation concern. However, the
-        <classname>Customer</classname> isn't greying out the
-        <acronym>UI</acronym> itself; the disable method is merely a
-        convention by which the presentation layer can interrogate the
-        entity.</para>
-
-        <para>Something else we hear sometimes about naked objects-style
-        systems is that they are really only suitable for
-        <acronym>CRUD</acronym> style applications. It has to be said that
-        it's a criticism that does irk; because although its true that naked
-        objects frameworks automatically expose object state, they also expose
-        object's behaviour. That is, every public method that is not a
-        property or a collection is taken to be an action and will rendered by
-        the <acronym>UI</acronym> as a button or a link. Indeed, we sometimes
-        like to talk of behaviourally complete domain objects; it's the very
-        antithesis of the anaemic domain model anti-pattern.</para>
-
-        <para>All the above notwithstanding, probably the biggest impediment
-        to going out and using Isis right now is that it's a small community
-        and as such the codebase is still relatively new. But if that is a
-        turn-off, note that you can still use Apache Isis to prototype your
-        domain model, because they are just pojos after all. Indeed, embedding
-        Isis' metamodel for a deployment hosted on some other framework is the
-        objective of the <emphasis>embedded runtime</emphasis> component of
-        Isis</para>
-      </sect1>
-
-      <sect1>
-        <title>How extensive is the application security support provided by
-        Isis?</title>
-
-        <para><emphasis>Apache Isis</emphasis> exposes a pluggable
-        authentication <acronym>API</acronym> and an authorization
-        <acronym>API</acronym>, with default implementations of both.</para>
-
-        <para>The job of the authentication <acronym>API</acronym> is to
-        authenticate the user credentials and return the user Id and a set of
-        roles for that user. This information is then used in one of two ways.
-        The authorization <acronym>API</acronym> uses it to implement
-        declarative class-based security, that is, associating access to
-        features based on the roles of the user. In addition, though, a domain
-        object instance can also access the user credentials, and so can
-        implement imperative instance-based checks if required.</para>
-
-        <para>For example, we might say that only a user with
-        <acronym>HR</acronym> role can award pay rises to an
-        <classname>Employee</classname>. This is a class-based check and would
-        be implemented through the authorization <acronym>API</acronym>. But,
-        we might also say that a user is allowed to view (though not modify)
-        their own salary of their <classname>Employee</classname> object, but
-        no-one else's. This would be an instance-based check, and would be
-        implemented in the object itself.</para>
-
-        <para>In terms of how naked objects restricts access, this is done
-        either by making an object member (property, collection or action)
-        invisible, or, if it is visible, then making it unusable (greyed
-        out).</para>
-      </sect1>
-
-      <sect1>
-        <title>How does an Isis applications manage the custom logic in terms
-        of business rules, workflow and other business logic that developers
-        have to manually implement outside the generated code?</title>
-
-        <para>"Business rules" is one of those amorphous terms that means
-        different things to different people. A consequence is that the team
-        can struggle to nail down exactly where such rules should reside, so
-        that these rules can start to leach out of the domain layer and the
-        application layer, or even worse, the presentation layer. As noted
-        already, one of the principles of naked objects is that domain objects
-        are behaviourally complete. What that means is that business rules and
-        "other business logic" are the responsibility of domain objects. For
-        workflow, again as noted earlier, we suggest that you introduce a view
-        model object and have that manage the user's interaction.</para>
-
-        <para>However, saying that business rules are an object's
-        responsibility doesn't necessarily mean that the implementation has to
-        be in Java. We already said that domain objects can delegate work out
-        to domain services that are injected into them. So if you want to put
-        your business rules into a rules engine, that's fine. Wrap the
-        interface to the rules engine within a domain service, and have the
-        domain object call out to the domain service in order to fulfil its
-        responsibility.</para>
-
-        <para>In practical terms, you're going to see business rules both in
-        the small-scale and the large. Small-scale business rules tend to be
-        implemented in terms of the supporting methods (disable, validate and
-        so on) that encode the preconditions for interactions. These ensure
-        that the object or the providing arguments is are valid and will veto
-        the interaction otherwise (blacklisted customers, out-of-stock
-        products). The larger-scale business rules are represented as actions
-        on an object that can perform arbitrary business logic, such as
-        modifying its own state, or related objects, and/or delegating out to
-        domain services.</para>
-      </sect1>
-
-      <sect1>
-        <title>How does Isis support SOA-based applications, eg where an
-        enterprise service component is consumed by several different
-        applications and other clients?</title>
-
-        <para>We can actually answer this both in terms of an Isis application
-        consuming <acronym>SOA</acronym><footnote>
-            <para>SOA=Service Oriented Architecture</para>
-          </footnote> services, and in it <emphasis>providing</emphasis>
-        services.</para>
-
-        <para>For consuming <acronym>SOA</acronym> services, the answer is
-        easy enough: wrap the <acronym>SOA</acronym> service in a domain
-        service interface, and then register the implementation with the
-        framework so that the service is injected into each domain object.
-        That interaction can be either synchronous or asynchronous; there's
-        nothing to prevent the domain object publishing an event to be picked
-        up by some other component out there on your enterprise service
-        bus.</para>
-
-        <para>As to providing <acronym>SOA</acronym> services, Isis'
-        <acronym>JSON</acronym> viewer exposes the domain objects as a set of
-        RESTful resources. We map objects and object members to the standard
-        <acronym>HTTP</acronym> verbs, eg so that a GET on an object returns
-        an object representation, a PUT on an object's property will modify
-        the state, or a POST on an object's actions will invoke the action. As
-        its name suggests, the <acronym>JSON</acronym> viewer produces a
-        <acronym>JSON</acronym> representation, making it easy to consume (eg
-        in HTML5 or RIA applications).</para>
-      </sect1>
-
-      <sect1>
-        <title>Most enterprise applications need to reuse the domain and
-        service layer classes between several different applications. How does
-        Apache Isis address this?</title>
-
-        <para>One way to think of reuse in terms of strategic domain-driven
-        design, which couches the discussion in terms of identifying bounded
-        contexts and understanding the relationship between these contexts -
-        context maps.</para>
-
-        <para>You can think of a bounded context as both the user population
-        that understands a particular ubiquitous language as well as the
-        actual system that they use. For example, the term "Customer" is going
-        to mean one thing to the marketing department, but a potentially
-        different thing to those in shipping. Those two user populations
-        therefore have incompatible languages, and so any integration of
-        systems that support both sets of users will need to explicitly map
-        their meanings of those terms.</para>
-
-        <para>Simplifying somewhat, an Isis (naked objects) application can be
-        thought of in three parts: the domain model objects themselves, the
-        viewer that provides a channel to interact with the domain model, and
-        the domain services that are used by the domain model objects. The
-        domain model objects encode a ubiquitous language for a particular
-        bounded context, so it only makes sense to reuse them by users who
-        have the same understanding of that language. We can if we want use
-        view model objects to provide projections of the domain entities to
-        different subsets of that user population, but all must agree with
-        what a Customer is, even if they use different parts of said
-        Customer.</para>
-
-        <para>Viewers are channels by which the domain model is accessed.
-        <emphasis>Apache Isis</emphasis> has viewers that expose the domain
-        model as either a desktop app or as a webapp, and also has a RESTful
-        viewer (producing <acronym>JSON</acronym>) which allow the view model
-        objects/domain objects to be surfaced as RESTful resources. In
-        <acronym>DDD</acronym> terms the RESTful viewers are examples of an
-        "open host service" context mapping from some client bounded context
-        up to our model's context.</para>
-
-        <para>With respect to domain services, these are not reusable per se,
-        rather they allow the domain objects to be the client of some other
-        service within the enterprise. That said, one common type of domain
-        service is to provide an interface to an enterprise service bus, in
-        which case the domain objects can publish events onto that bus. In
-        <acronym>DDD</acronym> terms this would be an example of a "published
-        language" context mapping; the downstream systems consuming the events
-        of the publishing domain objects.</para>
-
-        <para>Naked objects also allows a somewhat finer-grained level of
-        reuse; indeed its support for "don't repeat yourself" is one of the
-        reasons that some people are attracted to the pattern. For example, if
-        we declare a property or an action parameter to be a date, then the
-        viewers will automatically provide a date chooser widget for that
-        property or parameter unless indicated otherwise. Or, if a property's
-        type is an enum, then we'll get a drop-down box. It's the conventions
-        of the naked objects programming model - establishing a protocol of
-        interaction between the presentation layer and the domain model - that
-        enable this sort of reuse.</para>
-
-        <para>Some of Isis' more recent viewers also allow mashups within the
-        <acronym>UI</acronym>. For example, the viewer that we've implemented
-        using Apache Wicket uses the chain of responsibility pattern to build
-        the <acronym>UI</acronym>. If we have an entity can provide its
-        <classname>Location</classname> (eg, it implements
-        <classname>Locatable</classname>), then a GoogleMapsWidget will render
-        the entity in a map. Or, if an entity has a date, then a
-        CalendarWidget might render the entity on a calendar. This stuff is
-        extensible so you're free to write your own components and reuse (or
-        indeed invent your own) domain semantics as you see fit.</para>
-      </sect1>
-
-      <sect1>
-        <title>What is the future road map of the project?</title>
-
-        <para>Our proposal to join the incubator is online, and that captured
-        the thoughts we had at that point in time <ulink
-        url="http://wiki.apache.org/incubator/IsisProposal">[1]</ulink>. A
-        general theme is in the ongoing development of the various viewers,
-        such as the Wicket viewer, improving JSON support within the RESTful
-        viewers, and ongoing development of the taglib-based viewer, Scimpi.
-        Contributors who have expressed interest in developing similar viewers
-        using JSF/Facelets, Tapestry, on Android and in JavaFX/Visage.</para>
-
-        <para>Isis has a pluggable architecture with about five major APIs
-        (and numerous more fine-grained APIs) that can be developed. Probably
-        the most significant of these is the runtime/persistence
-        <acronym>API</acronym>. One piece of work is to develop an ORM-based
-        object store from Hibernate (which is not compatible with Apache's) to
-        a compatible JPA implementation, We've also had a suggestion [<ulink
-        url="https://issues.apache.org/jira/browse/ISIS-14">2</ulink>] to
-        re-implement using JDO 3.0/DataNucleus, which would allow us to cover
-        a lot of persistence technologies in one fell swoop</para>
-
-        <para>Another objective during incubation is to make Isis more easily
-        bootstrappable and embeddable, and for that JSR-299 (Contexts and
-        Dependency Injection) looks promising. For example, it should be easy
-        to take just the <emphasis>Isis</emphasis> metamodel component and use
-        it within your own applications, eg to drive the rendering of domain
-        objects within custom <acronym>UI</acronym> code.</para>
-
-        <para>One other area we might see work is in support for other JVM
-        languages. Isis already supports Groovy as well as Java, and the way
-        that Isis builds up its metamodel means that supporting other
-        languages (Scala, Fantom, Go) ought to be pretty
-        straightforward.</para>
-
-        <para>Ultimately, though, Apache Isis' roadmap depends on where its
-        community wants to take it; so any of the above might change as we
-        progress through to graduation.</para>
-      </sect1>
-    </chapter>
-
-    <chapter id="chp.DevelopmentProcess">
-      <title>A Development Process</title>
-
-      <abstract>
-        <para>This chapter describes the general approach to follow that we
-        recommend for developing domain-driven applications on Isis.</para>
-      </abstract>
-
-      <para>There's quite a lot to <emphasis>Apache Isis</emphasis>, with lots
-      of optional components, and we do recognize that it may be difficult to
-      know how to get going. This chapter outlines a development process which
-      you can use as the basis for developing your own way of working.</para>
-
-      <sect1 id="sec.ApplicationArchetypes">
-        <title>Run the Quickstart Archetype</title>
-
-        <para>We tend to organize <emphasis>Isis</emphasis> applications to
-        follow a standard structure, and you can use the
-        <emphasis>quickstart</emphasis> Maven archetype (see the
-        <emphasis>Isis</emphasis> <ulink
-        url="http://incubator.apache.org/isis">website</ulink>) to set this up
-        for you. This sets up a simple application that can be run
-        out-of-the-box using the default runtime and in-memory object store,
-        and supporting a number of the webapp viewers. The WAR file can be run
-        either standalone from the command line or deployed to a servlet
-        container such as Tomcat.</para>
-      </sect1>
-
-      <sect1>
-        <title>Programming Model</title>
-
-        <para>Once you've got the archetype application running, you're ready
-        to start developing your own domain objects. But no matter what
-        application you are developing, you'll need to understand the
-        <emphasis>Isis programming model</emphasis>.</para>
-
-        <para>The programming model is the set of annotations and programming
-        conventions that Isis recognizes. You'll find full details of the
-        programming model in this guide; see <xref
-        linkend="prt.WritingDomainObjects" />.</para>
-
-        <para>In addition, the applib contains a small number of utilities
-        which can be useful when writing your application: one such is the
-        ability to create XML snapshots of your domain object graphs, see
-        <xref linkend="chp.XmlSnapshots" />.</para>
-      </sect1>
-
-      <sect1>
-        <title>Fixtures and Prototyping</title>
-
-        <para>We suggest that the fastest way to develop your application is
-        to start prototyping using the in-memory object store (set up
-        automatically by the quickstart archetype). The nice thing about
-        working this way is that there is no database schema to slow you down;
-        you can make changes and then rapidly try them out.</para>
-
-        <para>On the other hand, the in-memory object store doesn't persist
-        objects between runs, so you'll soon tire of continually recreating
-        test objects to try out your changes. You should therefore use
-        fixtures: blocks of code that are used to setup objects in the
-        in-memory object store prior to the app running.</para>
-
-        <para>You can find more information about using fixtures in <xref
-        linkend="chp.Fixtures" />. It's also worth knowing about fixtures
-        because they are used when writing tests for your domain application
-        (see <xref linkend="sec.AgileTesting" />).</para>
-      </sect1>
-
-      <sect1 id="sec.Viewers">
-        <title>Viewers</title>
-
-        <para><emphasis>Apache Isis</emphasis> allows the same domain object
-        model to be consumed by multiple presentation layers. You'll find that
-        the quickstart archetype sets up a webapp module that bundles together
-        two of the viewers currently available, namely:</para>
-
-        <itemizedlist>
-          <listitem>
-            <para>The <acronym>HTML</acronym> viewer (in
-            <filename>viewers/html</filename>) provides a basic webapp.</para>
-
-            <para>Other than tweaking <acronym>CSS</acronym>, the views that
-            it provides of objects cannot be customized.</para>
-          </listitem>
-
-          <listitem>
-            <para>The <acronym>JSON</acronym> viewer (in
-            <filename>viewers/restfulobjects</filename>) which exposes your
-            domain objects through a <ulink
-            url="http://en.wikipedia.org/wiki/Representational_State_Transfer">RESTful</ulink>
-            interface.</para>
-
-            <para>The intention of this viewer is to allow programmatic access
-            to your domain objects from other (perhaps non-Java)
-            clients.</para>
-          </listitem>
-
-          <listitem>
-            <para>The <acronym>BDD</acronym> viewer (in
-            <filename>viewers/</filename>bdd) provides an integration with the
-            <ulink url="http://concordion.org">Concordion</ulink> BDD
-            framework; see <xref linkend="sec.BddTesting" />.</para>
-          </listitem>
-
-          <listitem>
-            <para>The <acronym>JUnit</acronym> viewer (in
-            <filename>viewers/junit</filename>) uses wrappers and a custom
-            Isis JUnit test class runner (<code>IsisTestRunner</code>); see
-            <xref linkend="sec.UnitTesting" />.</para>
-          </listitem>
-        </itemizedlist>
-      </sect1>
-
-      <sect1 id="sec.AgileTesting">
-        <title>Agile Testing</title>
-
-        <para><emphasis>Apache Isis</emphasis> is very much aligned to agile
-        development practices, and provides two complementary mechanisms for
-        you to test-drive the development of your application. A story test
-        (BDD ensures that the right system is built. A unit test ensures that
-        the system is built right.</para>
-
-        <sect2 id="sec.BddTesting">
-          <title>Story (BDD) Testing</title>
-
-          <para>Many agile practitioners use story tests as a means to capture
-          the acceptance (or completion) criteria for high-level user stories.
-          These story tests are typically captured in a non-programmatic form
-          so that is understandable to domain experts as well as
-          programmers.</para>
-
-          <para><emphasis>Apache Isis</emphasis> provides an out-of-the-box
-          integration with <ulink
-          url="http://concordion.org">Concordion</ulink> (where the story test
-          is captured as <acronym>HTML</acronym>).<footnote>
-              <para>An integration with <ulink
-              url="http://fitnesse.org">FitNesse</ulink> (where the story test
-              is captured within a wiki) also exists. Due to licensing this is
-              not part of <emphasis>Isis</emphasis> proper.</para>
-            </footnote>There is full coverage of how to use this integration
-          in the <acronym>BDD</acronym> viewer's
-          (<filename>viewers/bdd</filename>) documentation.</para>
-        </sect2>
-
-        <sect2 id="sec.UnitTesting">
-          <title xreflabel="ref.unittesting">Unit Testing</title>
-
-          <para>Unlike story tests, unit tests are normally written in a
-          programming language, typically in a framework such as <ulink
-          url="http://junit.org">JUnit</ulink>.</para>
-
-          <para>When writing unit tests, you have a choice. Since all the
-          business logic in Isis applications is encapsulated in domain object
-          pojos, you can just write unit tests using nothing more than JUnit
-          and perhaps also a mocking library such as <ulink
-          url="http://jmock.org">JMock</ulink>.</para>
-
-          <para>A slightly more sophisticated approach is to use the JUnit
-          integrations and supporting classes of the Wrapper programming model
-          . The idea of these utilities is to wrap your domain objects in
-          proxies that apply the same rules as an <emphasis>Apache
-          Isis</emphasis> viewer. For example, if you try to change a property
-          or invoke an action that is disabled, then the proxy will throw an
-          exception. You write your test to pass if the exception is thrown,
-          and failed otherwise (eg using
-          <code>@Test(expected=DisabledException.class)</code>).</para>
-
-          <para>Full documentation for unit testing support is in the JUnit
-          viewer's guide (<filename>viewers/junit</filename>).</para>
-        </sect2>
-      </sect1>
-
-      <sect1>
-        <title>A Domain Library</title>
-
-        <para>The idea behind the <filename>domain</filename> module is to
-        provide some off-the-shelf code for you to use and adapt in your own
-        applications. This code is fully tested (comes with tests), and is
-        intended to be well-designed. Using code from the library should give
-        you a kick-start in writing your own domain applications.</para>
-
-        <note>
-          <para>The library is currently very modest, but we hope it might
-          build up in time.</para>
-        </note>
-
-        <para>Of course, there's a limit to the complexity of the code that's
-        included in the library, because every domain is different. But having
-        a full set of tests should allow you to safely refactor the code to
-        your own requirements.</para>
-
-        <para>There's also no guarantee that the library will contain code for
-        your specific requirement. But if you do write some domain logic that
-        you think might be reusable by others, why not consider donating it
-        back to Isis when you've done so?</para>
-
-        <para>The domain library breaks out into three: services, entities and
-        values.</para>
-
-        <sect2>
-          <title>Domain Services</title>
-
-          <para><emphasis>Apache Isis</emphasis> applications use
-          <emphasis>domain service</emphasis>s (a domain-driven design
-          pattern) to allow objects to interact with other domains (or
-          <emphasis>bounded context</emphasis>s, to use the correct term).
-          These domain services are automatically injected into each domain
-          object as it is instantiated.</para>
-
-          <para>Domain services split into two: those that interact with
-          technical domains (such as sending email, or rendering
-          <acronym>PDF</acronym>s), and those that interact with business
-          domains (such as general ledger, <acronym>CRM</acronym>s or legacy
-          systems).</para>
-
-          <para>Obviously domain services that bridge to business domain
-          services are always likely to be specific to each individual
-          application. So the services in the
-          <filename>domain/services</filename> module focus on providing
-          off-the-shelf implementations for some of the more common
-          <emphasis>technical</emphasis> domain services.</para>
-        </sect2>
-
-        <sect2>
-          <title>Domain Values</title>
-
-          <para>As you probably would expect, <emphasis>Apache Isis</emphasis>
-          treats Java primitives, Java wrapper classes,
-          <classname>java.lang.String</classname>,
-          <classname>java.math.BigDecimal</classname> and
-          <classname>java.math.BigInteger</classname> as immutable values, It
-          allows <classname>java.util.Date</classname> and its subclasses
-          (java.sql.Date, java.sql.Time and
-          <classname>java.sql.Timestamp</classname>) to be treated as values
-          also. In addition, it offers a small number of its own value types,
-          such as <classname>Money</classname>.</para>
-
-          <para>In addition, it is possible to extend Isis support for value
-          types using its <classname>@Value</classname> annotation. We hope in
-          time to provide out-of-the-box integrations for popular 3rd party
-          libraries such as JodaTime.</para>
-        </sect2>
-
-        <sect2>
-          <title>Domain Entities</title>
-
-          <para>In the future we hope that Isis will provide some well-defined
-          and ready-tested domain entities for use in your systems. For
-          example, a set of entities to model customers
-          (<classname>Customer</classname>/<classname>Name</classname>/<classname>Address</classname>)
-          might be useful in many systems.</para>
-        </sect2>
-      </sect1>
-
-      <sect1 id="sec.DeployingAnIsisApplication">
-        <title>Deploying an Isis Application</title>
-
-        <para>There are two main decisions to make in deploying an
-        <emphasis>Isis</emphasis> application.</para>
-
-        <sect2>
-          <title>Persistence (the Default Runtime / Object Store)</title>
-
-          <para>In the same way that viewers provide pluggability for the
-          "front-end", <emphasis>Apache Isis</emphasis> also offers
-          pluggability on the back-end, i.e. persistence.</para>
-
-          <para>In fact, there are two decisions to be made here: which
-          runtime to use, and (if using the default runtime), which object
-          store to use. The default runtime is the one originally developed
-          within the <emphasis>Naked Objects Framework</emphasis>, and
-          therefore has been inherited by <emphasis>Apache
-          Isis</emphasis>.<footnote>
-              <para>At the time of writing the default runtime is the only
-              real runtime available; however we expect to be developing
-              lighter-weight replacements for the default runtime in the
-              future.</para>
-            </footnote>The default runtime is also the one configured by the
-          quickstart archetype.</para>
-
-          <para>If using the default runtime, you have the option of choosing
-          the objectstore. As already discussed, the quickstart archetype
-          configures the in-memory objectstore by default, which is great for
-          rapid prototyping. However, at some point you will need to integrate
-          with a "real" object store that persists object to some sort of
-          serialized persistence.</para>
-
-          <para>Of the object stores to provided by the default runtime, some
-          are easy to configure, some more complex; some are only suitable for
-          single-user apps, others for multi-users. Each of the object stores
-          has its own documentation, so you can select the correct object
-          store to choose:<footnote>
-              <para>In addition to those listed here, there have also been
-              objectstores for JPA (using Hibernate) and BerkeleyDB. These are
-              currently not part of Apache Isis distribution because of
-              incompatible licenses. Support for an ORM will in the future be
-              provided either by porting the JPA object store to the default
-              runtime, or, we may support it via a JDO-based new
-              runtime.</para>
-            </footnote></para>
-
-          <itemizedlist>
-            <listitem>
-              <para>the <acronym>XML</acronym> object store (in
-              <filename>objectstores/xml</filename>) is designed for
-              single-user systems, and persists to its own internal
-              (proprietary) <acronym>XML</acronym> format;</para>
-            </listitem>
-
-            <listitem>
-              <para>the <acronym>SQL</acronym> object store (in
-              <filename>objectstores/sql</filename>) is a multi-user object
-              store that persists to an <acronym>RDBMS</acronym> (direct over
-              <acronym>JDBC</acronym>);</para>
-            </listitem>
-
-            <listitem>
-              <para>the <acronym>NoSQL</acronym> object store (in
-              <filename>objectstores/nosql</filename>) is a multi-user object
-              store that persists to NoSQL databases in JSON form.</para>
-            </listitem>
-          </itemizedlist>
-
-          <para>You'll also find coverage of the object store
-          <acronym>API</acronym> itself in the default runtime's
-          documentation.</para>
-
-          <para>Alternatively, the default runtime can be configured to
-          support client/server remoting. This configuration only makes sense
-          for the <acronym>DnD</acronym> viewer, whereby it is configured as
-          the client and a separate instance of Isis runs as the server.
-          Again, full guidance is available in the default runtime's
-          documentation.</para>
-        </sect2>
-
-        <sect2>
-          <title>Authentication and Authorization</title>
-
-          <para><emphasis>Apache Isis</emphasis> provides an
-          <acronym>API</acronym>s for both authentication and
-          authorization.</para>
-
-          <para>The core implementation of these <acronym>API</acronym>s are
-          simple basic noop-based authentication and authorization mechanisms.
-          For deployment into production, you'll need to configure with
-          another alternative implementation.</para>
-
-          <para>One option is the file-based implementation (in
-          <filename>security/file</filename>), that stores the security
-          information in flat files. This is simple, but unlikely to be robust
-          enough for enterprise use.</para>
-
-          <para>Another alternative is to use the <acronym>LDAP</acronym>
-          implementation (in <filename>security/ldap</filename>), which can
-          integrate with an <acronym>LDAP </acronym>infrastructure if you have
-          one. If you have a different security infrastructure, then you might
-          consider to write your own implementation (the
-          <acronym>API</acronym> is not complex).</para>
-        </sect2>
-      </sect1>
-    </chapter>
-  </part>
-
   <part id="prt.WritingDomainObjects">
     <title>Writing Domain Objects</title>
 
@@ -1089,7 +119,8 @@
       linkend="chp.ValueTypes" />.</para>
 
       <sect1>
-        <title>How to not inherit from framework superclasses</title>
+        <title>How to have entities be POJOs (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
@@ -1112,726 +143,487 @@
       </sect1>
 
       <sect1>
-        <title condition="java">How to specify a title for an object</title>
+        <title>How to add a property to an object</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>Properties are specified using the JavaBean conventions,
+        recognizing a standard accessor/mutator pair (<code>get</code> and
+        <code>set</code>).</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>The syntax is:</para>
 
-        <para><programlisting>public class Customer {
-  @Title
-  public String getFirstName() { ... }
-  @Title
-  public String getLastName() { ... }
-  ...
-}</programlisting></para>
+        <para><programlisting>public PropertyType getPropertyName() 
 
-        <para>For more control, the order of the title components can be
-        specified using a sequence number (specified in Dewey decimal
-        format):</para>
+public void setPropertyName(PropertyType param)</programlisting></para>
 
-        <programlisting>public class Customer {
-  @Title("1.0")
-  public String getFirstName() { ... }
-  @Title("1.1")
-  public String getLastName() { ... }
-  ...
-}</programlisting>
+        <para>where <literal moreinfo="none">PropertyType</literal> is a
+        primitive, a value object or an entity object.</para>
 
-        <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>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><programlisting>public class Customer {
-  public String title() {
-    return getLastName() + ", " + getFirstName().substring(0,1);
-  } 
-  ...
-}</programlisting></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>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>
+        <programlisting format="linespecific">public class Customer {
 
-      <sect1 id="sec.HowToSpecifyTheIconForAnObjectsClass">
-        <title condition=".net">How to specify the icon for an object's
-        class</title>
+    private String firstName;
+    public String getFirstName() {
+        return firstName;
+    }
+    public void setFirstName(String firstName) {
+        this.firstName = firstName;
+    }
 
-        <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>
+    private Organisation organisation;
+    public Organisation getOrganisation() {
+        return organisation;
+    }
+    public void setOrganisation(Organisation organisation) { 
+        this.organisation = organisation;
+    }
 
-        <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>
-        <title>How to specify the icon for an individual object's
-        state</title>
-
-        <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>
+        <title>How to add a collection to an object</title>
 
-        <para>For example, an instance of <classname>Product</classname> could
-        use a photograph of the product as an icon, using:</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>
 
-        <programlisting format="linespecific">public class Product {
-    public String iconName() {
-        return "Product-" + getPhotograph();
-    }
-    ...
-}</programlisting>
+        <para>The syntax is either:</para>
 
-        <para>Alternatively, an <classname>Order</classname> might vary the
-        icon according to the status of the object:<programlisting>public class Order {
-    public String iconName() {
-        return "Order-" + getStatus();
-    }
-    ...
-}</programlisting></para>
-      </sect1>
+        <para><programlisting>public Collection&lt;EntityType&gt; getCollectionName()
+private void setCollectionName(Collection&lt;EntityType&gt; param)</programlisting></para>
 
-      <sect1>
-        <title condition="j#">How to specify a name and/or description for an
-        object</title>
+        <para>or:</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, or when - for whatever reason - the name of the class includes
-        technical artifacts (for example project-defined prefixes or
-        suffices). It is also useful if the required name cannot be used
-        because it is a keyword in the language.</para>
+        <para><programlisting>public List&lt;EntityType&gt; getCollectionName()
+private void setCollectionName(List&lt;EntityType&gt; param)</programlisting></para>
 
-        <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.t</para>
+        <para>or:</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 a tooltip.</para>
+        <para><programlisting>public Set&lt;EntityType&gt; getCollectionName()
+private void setCollectionName(Set&lt;EntityType&gt; param)</programlisting></para>
 
-        <para>For example:</para>
+        <para>A mutator is required, but it need only have
+        <code>private</code> visibility.</para>
 
-        <programlisting>@Named("Customer")
-@Plural("Customers")
-@DescribedAs("Individuals or organizations that have either "+
-             "purchased from us in the past or "+
-             "are likely to in the future")
-public class CustomerImpl implements ICustomer {
-    ...
-}</programlisting>
+        <para>Note:</para>
 
         <note>
-          <para>There is an entirely separate mechanism for dealing with
-          Internationalisation, details of which can be found in the core
-          documentation.</para>
+          <para><classname>Map</classname>s cannot be used for
+          collections.</para>
         </note>
-      </sect1>
-
-      <sect1>
-        <title condition="vb">How to specify that an object should not be
-        persisted</title>
 
-        <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 id="sec.entity.immutable">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>
+        <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>@Immutable
-public class ChasingLetter implements PaymentReclaimStrategy {
+        <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>
-
-        <para>See also <xref linkend="sec.Entity.Disabled" />.</para>
       </sect1>
 
-      <sect1 id="sec.Entity.Disabled">
-        <title>How to control when an object can be modified</title>
+      <sect1>
+        <title>How to add an action to an object</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>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>To indicate that an object cannot be modified, use the <literal
-        moreinfo="none">String disabled(Type type)</literal> method.</para>
+        <para>The syntax is:</para>
 
-        <para>For example:</para>
+        <para><programlisting>public void actionName([ValueOrEntityType param] ...)</programlisting></para>
 
-        <programlisting>public class FeeInvoice implements Invoice {
-   public String disabled(Type type){
-    ...
-   }
-}</programlisting>
+        <para>or</para>
 
-        <para>The Type is from
-        <classname>org.apache.isis.applib.Identifier</classname>:</para>
+        <para><programlisting>public ReturnType actionName([ValueOrEntityType param] ...)</programlisting></para>
 
-        <programlisting>    /**
-     * What type of feature this identifies.
-     */
-    public static enum Type {
-        CLASS, PROPERTY_OR_COLLECTION, ACTION
-    }</programlisting>
+        <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>and provides fine grain control over disabling actions and
-        properties.</para>
+        <para>We refer to all methods that are intended to be invoked by users
+        as 'action methods'.</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>If you have a method that you don't want to be made available as
+        a user-action you can either:</para>
 
-        <para>See also <xref linkend="sec.Entity.Disabled" />.</para>
-      </sect1>
+        <itemizedlist>
+          <listitem>
+            <para>make it non-<literal>public</literal> (eg <literal
+            moreinfo="none">protected</literal> or <literal
+            moreinfo="none">private</literal>)</para>
+          </listitem>
 
-      <sect1 id="sec.Entity.Hidden">
-        <title>How to control when an object is visible</title>
+          <listitem>
+            <para>annotate it with <classname>@Ignore</classname></para>
+          </listitem>
 
-        <para>To when an object is visible, provide a hidden() method:</para>
+          <listitem>
+            <para>annotate it with <classname>@Hidden</classname> (discussed
+            further in <xref linkend="sec.HiddenActions" />)</para>
+          </listitem>
+        </itemizedlist>
 
-        <para><programlisting>public class TrackingAction implements Tracking {
-   public boolean hidden(){
-    ...
-   }
-}</programlisting>If the function returns true, all properties and methods
-        will be hidden from the user, similar to <xref
-        linkend="sec.HiddenProperty" />.</para>
+        <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>
       </sect1>
 
-      <sect1 id="sec.Bounded">
-        <title>How to specify that a class of objects has a limited number of
-        instances</title>
+      <sect1>
+        <title condition="java">How to specify a title for an object</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>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>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>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>An alternative way to specify a selection of objects is using
-        the <classname>choicesXxx()</classname> supporting methods.</para>
+        <para><programlisting>public class Customer {
+  @Title
+  public String getFirstName() { ... }
+  @Title
+  public String getLastName() { ... }
+  ...
+}</programlisting></para>
 
-        <para>For example:</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>@Bounded
-public class PaymentMethod {
-    ...
+        <programlisting>public class Customer {
+  @Title("1.0")
+  public String getFirstName() { ... }
+  @Title("1.1")
+  public String getLastName() { ... }
+  ...
 }</programlisting>
 
-        <para>Alternatively, you might want to use a (Java) <code>enum</code>,
-        because these are implicitly bounded.</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>
+        <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>
 
-          <listitem>
-            <para><methodname>void persistIfNotAlready(Object
-            domainObject)</methodname></para>
+        <para><programlisting>public class Customer {
+  public String title() {
+    return getLastName() + ", " + getFirstName().substring(0,1);
+  } 
+  ...
+}</programlisting></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>
+        <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>
 
-          <listitem>
-            <para><methodname>void remove(Object
-            persistentObject)</methodname></para>
+      <sect1 id="sec.HowToSpecifyTheIconForAnObjectsClass">
+        <title condition=".net">How to specify the icon for an object's
+        class</title>
 
-            <para>Removes (deletes) from the object store, making the
-            reference transient.</para>
-          </listitem>
+        <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>
 
-          <listitem>
-            <para><methodname>void removeIfNotAlready(Object
-            domainObject)</methodname></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>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>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>A domain object specifies that it needs to have a reference to
-        the <classname>DomainObjectContainer</classname> injected into by
-        including the following code:</para>
+        <para>Alternatively, you can use the <literal
+        moreinfo="none">iconName</literal>() method instead:</para>
 
-        <programlisting format="linespecific">private DomainObjectContainer container;
-protected DomainObjectContainer getContainer() {
-    return container;
-}
-public final void setContainer(final DomainObjectContainer container) {
-    this.container = container;
+        <programlisting format="linespecific">public String iconName() {
+    return "Person";
 }</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>
+        <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.LifecycleMethods">
-        <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" colwidth="105" />
-
-            <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>
+      <sect1 id="sec.MemberOrderForProperties">


<TRUNCATED>