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 2011/06/13 23:49:24 UTC

svn commit: r1135303 - in /incubator/isis/trunk/runtimes/dflt/src/docbkx/guide: images/architecture.png images/architecture.pptx isis-default-runtime.xml

Author: danhaywood
Date: Mon Jun 13 21:49:24 2011
New Revision: 1135303

URL: http://svn.apache.org/viewvc?rev=1135303&view=rev
Log:
updates to default runtime docbkx guide

Added:
    incubator/isis/trunk/runtimes/dflt/src/docbkx/guide/images/architecture.png   (with props)
Modified:
    incubator/isis/trunk/runtimes/dflt/src/docbkx/guide/images/architecture.pptx
    incubator/isis/trunk/runtimes/dflt/src/docbkx/guide/isis-default-runtime.xml

Added: incubator/isis/trunk/runtimes/dflt/src/docbkx/guide/images/architecture.png
URL: http://svn.apache.org/viewvc/incubator/isis/trunk/runtimes/dflt/src/docbkx/guide/images/architecture.png?rev=1135303&view=auto
==============================================================================
Binary file - no diff available.

Propchange: incubator/isis/trunk/runtimes/dflt/src/docbkx/guide/images/architecture.png
------------------------------------------------------------------------------
    svn:mime-type = application/octet-stream

Modified: incubator/isis/trunk/runtimes/dflt/src/docbkx/guide/images/architecture.pptx
URL: http://svn.apache.org/viewvc/incubator/isis/trunk/runtimes/dflt/src/docbkx/guide/images/architecture.pptx?rev=1135303&r1=1135302&r2=1135303&view=diff
==============================================================================
Binary files - no diff available.

Modified: incubator/isis/trunk/runtimes/dflt/src/docbkx/guide/isis-default-runtime.xml
URL: http://svn.apache.org/viewvc/incubator/isis/trunk/runtimes/dflt/src/docbkx/guide/isis-default-runtime.xml?rev=1135303&r1=1135302&r2=1135303&view=diff
==============================================================================
--- incubator/isis/trunk/runtimes/dflt/src/docbkx/guide/isis-default-runtime.xml (original)
+++ incubator/isis/trunk/runtimes/dflt/src/docbkx/guide/isis-default-runtime.xml Mon Jun 13 21:49:24 2011
@@ -155,9 +155,84 @@
         <title>Components of the Default Runtime</title>
 
         <para>As will be clear if you've explored the codebase, the
-        <emphasis>default runtime</emphasis> implementation consists of a
-        fairly large number of submodules. These are organized around the
-        major <acronym>API</acronym>s that the default runtime exposes:</para>
+        <emphasis>default runtime</emphasis> implementation consists of a main
+        <emphasis>runtime</emphasis>
+        module<package>[oai.runtimes.dflt:runtime]</package> along with a
+        fairly large number of submodules.</para>
+
+        <para>The main <emphasis>runtime</emphasis> module provides the
+        following functionality:</para>
+
+        <itemizedlist>
+          <listitem>
+            <para>classes to bootstrap the default runtime</para>
+          </listitem>
+
+          <listitem>
+            <para>the "installer" registry; a repository of components that
+            can be bootstrapped</para>
+          </listitem>
+
+          <listitem>
+            <para>implementations of the
+            <classname>AuthenticationManager</classname> and
+            <classname>AuthorizationFacetFactory</classname> interfaces for
+            the default runtime</para>
+          </listitem>
+
+          <listitem>
+            <para>an abstract <classname>PersistenceSession</classname>
+            <acronym>API</acronym> that provides a very generalized means for
+            managing the lifecycle of domain objects</para>
+
+            <para>This includes an <classname>ObjectFactory</classname> API
+            which (in conjunction with the
+            <classname>ClassSubstitor</classname> interface defined in the
+            <package>[oai.core:metamodel]</package> module) provides hook-in
+            points for bytecode enhancement libraries (discussed further
+            below);</para>
+          </listitem>
+
+          <listitem>
+            <para>an implementation of the
+            <classname>PersistenceSession</classname> <acronym>API</acronym>
+            which does some of the common work for persistence management and
+            defines its own object store <acronym>API</acronym></para>
+          </listitem>
+
+          <listitem>
+            <para>a mechanism to define the set of application domain services
+            to make available to the domain objects</para>
+          </listitem>
+
+          <listitem>
+            <para>a mechanism to define the set of fixtures to automatically
+            install into the object store (for use when testing or
+            prototyping)</para>
+          </listitem>
+
+          <listitem>
+            <para>a mechanism (<classname>Memento</classname>) for capturing
+            the state of domain objects over time</para>
+          </listitem>
+
+          <listitem>
+            <para>support for more easily building <acronym>XML</acronym>
+            snapshots (using the
+            <classname>oai.applib.snapshot.Snapshottable</classname>
+            interface)</para>
+          </listitem>
+
+          <listitem>
+            <para>a means of storing user preference / profile information
+            (including, for example, bookmarks to objects).</para>
+          </listitem>
+        </itemizedlist>
+
+        <para>The rest of the <emphasis>default runtime</emphasis>
+        (sub)modules provide implementations of the major
+        <acronym>API</acronym>s that the <emphasis>default runtime</emphasis>
+        exposes:</para>
 
         <itemizedlist>
           <listitem>
@@ -166,37 +241,58 @@
             <para>The object store <acronym>API</acronym> defines a
             persistence mechanism for storing domain objects. Examples include
             a simple in-memory object store (useful only for prototyping), an
-            XML objectstore, a simple SQL objectstore, and a "NoSQL"
-            (JSON-based) objectstore.</para>
+            <acronym>XML</acronym> objectstore, a simple
+            <acronym>SQL</acronym> objectstore, and a "NoSQL" (JSON-based)
+            objectstore.</para>
           </listitem>
 
           <listitem>
-            <para>bytecode providers</para>
+            <para>bytecode enhancement</para>
 
-            <para>Bytecode providers provide the ability to support lazy
-            loading while walking a graph from one domain object to another.
-            This is a similar technique to that employed by
-            <acronym>ORM</acronym>s, but is available even if the object store
-            involved does not support lazy loading.<footnote>
+            <para>Bytecode enhancement classes provide the ability to support
+            lazy loading while walking a graph from one domain object to
+            another, using tools such as <ulink
+            url="http://cglib.sourceforge.net">cglib</ulink> or <ulink
+            url="http://www.javassist.org">javassist</ulink>. This is a
+            similar technique to that employed by <acronym>ORM</acronym>s, but
+            is available even if the object store involved does not support
+            lazy loading.<footnote>
                 <para>Indeed, ORM-based object stores (are likely to) require
                 the bytecode providers to be disabled.</para>
               </footnote></para>
+
+            <para>The bytecode enhancement is also used for automatic tracking
+            of dirty objects (so that Isis knows to flush them to the object
+            store at the end of the transaction). The primary
+            <acronym>API</acronym> that supports bytecode enhancement is
+            <classname>ObjectFactory</classname>, discussed in <xref
+            linkend="sec.SessionLevelScope" />.</para>
           </listitem>
 
           <listitem>
             <para>profile store</para>
 
-            <para>The profile store is responsible for holding user profile
-            information, by which we mean their preferences and any other
-            information, for example bookmarks.</para>
+            <para>The profile store <acronym>API</acronym> defines a
+            persistence mechanism for storing user profile information.
+            Examples include a simple in-memory profile store (useful only for
+            prototyping and testing), and an <acronym>XML</acronym>
+            profilestore.</para>
           </listitem>
 
           <listitem>
             <para>client/server remoting support</para>
 
-            <para>The default runtime also provides support for client/server
-            remoting. For example, the DnD viewer can be configured to act as
-            a client, holding a cache of domain objects client-side.
+            <para>The <emphasis>default runtime</emphasis> also provides
+            support for client/server remoting, through an alternative
+            implementation of the <classname>PersistenceSession</classname>
+            <acronym>API</acronym><footnote>
+                <para>Alternative, that is, to the
+                <classname>PersistenceSession</classname> implementation for
+                object stores.</para>
+              </footnote>.</para>
+
+            <para>For example, the DnD viewer can be configured to act as a
+            client, holding a cache of domain objects client-side.
             Interactions with these domain objects are sent transparently
             across to a server running the same application domain classes;
             the changes are performed server-side and the results sent back
@@ -204,229 +300,610 @@
           </listitem>
         </itemizedlist>
 
-        <para></para>
+        <para>In addition, because many of the <emphasis>Isis</emphasis>
+        viewers are webapps, the <emphasis>default runtime</emphasis> also
+        has:</para>
 
-        <para></para>
+        <itemizedlist>
+          <listitem>
+            <para>a module <package>[oai.runtimes.dflt:webapp]</package> with
+            <classname>ServletContextListener</classname> and
+            <classname>javax.servlet.Filter</classname> implementations to
+            allow <emphasis>Isis</emphasis> to be bootstrapped from a
+            webapp</para>
+          </listitem>
+
+          <listitem>
+            <para>provides a convenience module
+            <package>[oai.runtimes.dflt:webserver]</package> that provides a
+            command-line utility to allow any Maven webapp-structured project
+            to be hosted within Jetty.</para>
+          </listitem>
+        </itemizedlist>
       </sect1>
 
-      <sect1>
-        <title><classname>ObjectAdapter</classname>s and
-        <classname>Oid</classname>s</title>
+      <sect1 id="sec.InstallerLookup">
+        <title><classname>InstallerLookup</classname> and
+        <filename>installer-registry.properties</filename></title>
 
-        <para><emphasis>Apache Isis</emphasis> components do not deal directly
-        with domain object pojos; instead they are always wrapped by an
-        adapter, call <classname>ObjectAdapter</classname>. This has two main
-        responsibilities:</para>
+        <para>The <emphasis>Isis</emphasis> core modules
+        <package>[oai:core]</package> already provide the
+        <classname>oai.core.commons.components.Installer</classname> interface
+        which defines a factory interface for any component within
+        <emphasis>Isis</emphasis>.</para>
+
+        <para>The <emphasis>default runtime</emphasis> builds upon this
+        infrastructure by providing the <classname>InstallerLookup</classname>
+        interface (in
+        <package>oai.runtimes.dflt.runtime.installerregistry</package>) to act
+        as a registry of all available <classname>Installer</classname>s that
+        have been bootstrapped. It also provides an implementation,
+        <classname>InstallerLookupDefault</classname>, which looks up the
+        implementations from the
+        <filename>installer-registry.properties</filename> file. This registry
+        file can be found in <package>oai.runtimes.dflt.runtime</package>
+        package. If no implementation is specified, then a default (defined in
+        <package>oai.runtimes.dflt.runtime.system.SystemConstants</package>)
+        is used. For some components the specified
+        <classname>DeploymentType</classname> will cause the default to vary;
+        for example, the default persistence mechanism when running in
+        exploration mode is to use the in-memory object store; otherwise
+        though the XML object store is defaulted.</para>
+
+        <para>In addition to loading components, the
+        <classname>InstallerLookupDefault</classname> also updates the
+        (mutable) <classname>IsisConfigurationBuilder</classname>, from which
+        an <classname>IsisConfiguration</classname> is snapshotted. It does
+        this by asking each <classname>Installer</classname> for its
+        configuration files
+        (<methodname>Installer#getConfigurationResources()</methodname>). For
+        those installers that inherit from
+        <classname>oai.core.commons.config.InstallerAbstract</classname> (ie
+        most if not all of them), this returns a collection of two file names
+        that follow the convention:</para>
 
         <itemizedlist>
           <listitem>
-            <para>it provides reference to the
-            <classname>ObjectSpecification</classname>, which describes the
-            structure (properties, collections, actions) of the object's
-            type</para>
+            <para><filename>type.properties</filename></para>
           </listitem>
 
           <listitem>
-            <para>it provides reference to an <classname>Oid</classname>,
-            which is an opaque value that uniquely identifies the object
-            instance.</para>
+            <para><filename>type_name.properties</filename></para>
           </listitem>
         </itemizedlist>
 
-        <para>You can think of <classname>ObjectAdapter</classname> as
-        equivalent to <classname>java.lang.Object</classname>, while
-        <classname>ObjectSpecification</classname> is in some sense equivalent
-        to <classname>java.lang.Class</classname>. The
-        <classname>Oid</classname> interface meanwhile is something akin to a
-        primary key identifier for an row in a relational database, but it is
-        slightly more abstract than that because it can also represent a
-        non-persisted object.</para>
-
-        <para>It is the <emphasis>metamodel</emphasis> module of
-        <emphasis>Isis</emphasis> <package>[oai.core:metamodel]</package>
-        defines these interfaces (<classname>ObjectAdapter,
-        ObjectSpecifation</classname> and <classname>Oid</classname>), the
-        object itself (<classname>ObjectAdapter</classname>), and the object's
-        identity (<classname>Oid</classname>). The metamodel itself also
-        provides an implementation of
-        <classname>ObjectSpecification</classname>.</para>
-
-        <para>The <emphasis>default runtime</emphasis> module
-        <package>[oai.runtimes:dflt]</package> provides an implementations of
-        the <classname>ObjectAdapter</classname> interface
-        (<classname>oai.runtimes.dflt.persistence.adapterfactory.pojo.PojoAdapter</classname>)
-        as well as an implementation of the <classname>Oid</classname>
-        interface. The actual implementation of <classname>Oid</classname>
-        will depend on the object store (persistence) mechanism that the
-        runtime has been configured to use.</para>
+        <para>For example, if loading the XML persistence mechanism/object
+        store this will search for <filename>persistor.properties</filename>
+        and then <filename>persistor_xml.properties</filename>.</para>
+
+        <para>It's worth pointing out that
+        <classname>InstallerLookupDefault</classname> is, in turn, defaulted
+        from <classname>IsisModule</classname>. This is an implementation if a
+        <classname>com.google.inject.Module</classname>, meaning that
+        <emphasis>Isis</emphasis> is, in fact, ultimately bootstrapped by
+        <ulink url="http://code.google.com/p/google-guice/">Google
+        Guice</ulink><footnote>
+            <para>At least, when the <emphasis>default runtime</emphasis> is
+            used.</para>
+          </footnote>.</para>
       </sect1>
 
       <sect1>
-        <title>AdapterManager</title>
-
-        <para>As already mentioned, the <classname>ObjectAdapter</classname>
-        maintains a reference to an <classname>Oid</classname> and the
-        underlying pojo domain object. To traverse in the other direction -
-        that is, from <classname>Oid</classname> to
-        <classname>ObjectAdapter</classname> or from pojo to
-        <classname>ObjectAdapter</classname> - the default runtime uses its
-        internal <classname>AdapterManager</classname> component, which
-        maintains two sets of maps. This is shown below:</para>
+        <title>Component Scopes</title>
+
+        <para>The components loaded by <classname>InstallerLookup</classname>
+        are thread-safe singletons with application (global) scope. From them
+        the <emphasis>Isis</emphasis> runtime instantiates further components
+        at session, and within that transaction-level scope. This is shown
+        below:</para>
 
         <mediaobject>
           <imageobject>
-            <imagedata fileref="images/adapter-manager.png" scale="45" />
+            <imagedata fileref="images/architecture.png" scale="45" />
           </imageobject>
         </mediaobject>
 
-        <para>The <classname>AdapterManager</classname> is an example of the
-        <ulink
-        url="http://martinfowler.com/eaaCatalog/identityMap.html">object-identity
-        map pattern</ulink> (as documented more fully in Martin Fowler's
-        Patterns of Enterprise Application Architecture). Whenever a domain
-        object pojo is handled by the system, and before an adapter for it has
-        been created, the runtime checks the
-        <classname>AdapterManager</classname> for the instance first, and only
-        creates an adapter if the pojo is not mapped. Similarly, if the
-        adapter has only an <classname>Oid</classname> value then the
-        <classname>AdapterManager</classname> is determine if the object's
-        adapter exists.</para>
-      </sect1>
+        <para>For webapp-based viewers, an <classname>IsisSession</classname>
+        is instantiated at the beginning of the HTTP request, and is
+        automatically closed at the end of the request. In this regard it is
+        very similar to the concept of a <acronym>JPA
+        </acronym><classname>javax.persistence.PersistenceContext</classname>
+        or <ulink url="http://hibernate.org">Hibernate</ulink>
+        <classname>org.hibernate.Session</classname>.</para>
+
+        <para>For client/server deployments, an
+        <classname>IsisSession</classname> is similar for the server, but for
+        the client an <classname>IsisSession</classname> is started when the
+        user starts the client, and is only closed when the user quits
+        out.<footnote>
+            <para>There are, arguably, some issues with this design. In the
+            future we may deprecate this design in favour of a design of
+            client that is wholly stateless.</para>
+          </footnote></para>
+
+        <para>As the diagram illustrates, an
+        <classname>IsisSession</classname> can give rise to one or multiple
+        <classname>IsisTransaction</classname>s. If running within a webapp or
+        the server-side of a client/server remoting, each
+        <classname>IsisSession</classname> will instantiate precisely one
+        <classname>IsisTransaction</classname>, automatically begun at the
+        beginning of the session and committed at the end. On the client-side
+        of a client/server deployment, an
+        <classname>IsisTransaction</classname> is created for each
+        client/server interaction.</para>
+
+        <para>The following look at the role of each of the components shown,
+        in each scope.</para>
+
+        <sect2>
+          <title>Application-level scope</title>
+
+          <para>The <classname>IsisSystem</classname> is the top-level object
+          that represents the running <emphasis>Isis</emphasis> instance.
+          Within this top-level object are a number of subsidiary
+          objects:</para>
 
-      <sect1>
-        <title>Lazy Loading</title>
+          <itemizedlist>
+            <listitem>
+              <para>the <classname>DeploymentType</classname> is used to
+              categorise the "mode" in which <emphasis>Isis</emphasis> is
+              being used. This combines two different dimensions: whether
+              <emphasis>Isis</emphasis> is running in a server (multiuser) or
+              client context, and whether it is running in
+              exploration/prototyping/production. The
+              <classname>DeploymentType</classname> in effect can influence
+              which implementation of components are created (see <xref
+              linkend="sec.InstallerLookup" />).</para>
+            </listitem>
 
-        <para></para>
+            <listitem>
+              <para>the <classname>IsisConfiguration</classname> is the final
+              configuration after all components have been
+              loaded;eLoade</para>
+            </listitem>
 
-        <para>(eg as the result of receiving an object during a client/server
-        interaction, or from a memento, see ), then</para>
+            <listitem>
+              <para>the <classname>IsisSessionFactory</classname> is used to
+              create <classname>IsisSession</classname>s as required (more on
+              this below)</para>
+            </listitem>
 
-        <para>This is one of the main mechanisms by which the
-        <emphasis>default runtime</emphasis> is able to support lazy loading,
-        even if the underlying object store itself does not. So, for example,
-        if an object</para>
+            <listitem>
+              <para>the <classname>LogonFixture</classname> allows automatic
+              logon if running with a test/exploration mode
+              (<classname>DeploymentType</classname>)</para>
+            </listitem>
+          </itemizedlist>
 
-        <para></para>
+          <para>Of the above top-level objects, the
+          <classname>IsisSessionFactory</classname> is by far the most
+          important, because it is responsible for creating
+          <classname>IsisSession</classname>s as and when required. There are
+          several elements to an <classname>IsisSession</classname>, and so
+          <classname>IsisSessionFactory</classname> delegates the
+          instantiation of these elements to its own subsidiary
+          objects:</para>
 
-        <para>One of the</para>
+          <itemizedlist>
+            <listitem>
+              <para>The <classname>AuthenticationManager</classname> is used
+              for authenticated users into the system, and is used to
+              instantiate an <classname>AuthenticationSession</classname>.
+              This is discussed further in <xref
+              linkend="sec.SessionLevelScope" />.</para>
+            </listitem>
 
-        <para></para>
+            <listitem>
+              <para>The <classname>PersistenceSessionFactory</classname> is
+              used to instantiate the corresponding
+              <classname>PersistenceSession</classname>. This is discussed
+              further in <xref linkend="sec.SessionLevelScope" />.</para>
+            </listitem>
+          </itemizedlist>
 
-        <para></para>
+          <para>In addition, the <classname>IsisSessionFactory</classname>
+          holds references to a number of other top-evel components, namely
+          <classname>AuthorizationManager</classname>, the
+          <classname>SpecificationLoader</classname> (ie the Isis metamodel),
+          the <classname>TemplateImageLoader</classname> (for loading
+          images/icons) and the <classname>UserProfileLoader</classname>
+          (responsible for interacting with the profile store
+          component).</para>
+        </sect2>
+
+        <sect2 id="sec.SessionLevelScope">
+          <title>Session-level scope</title>
+
+          <para>The <classname>AuthenticationSession</classname> holds the
+          credentials (basically: username and roles) of the user that is
+          currently (ie with respect to the current
+          <classname>IsisContext</classname>) interacting with
+          <emphasis>Isis</emphasis>. In principal this information could
+          change over time; for example a user might be added or removed from
+          roles.</para>
+
+          <para>The <classname>PersistenceSession</classname>, on the other
+          hand, is a somewhat more complex beast, consisting in turn
+          of:</para>
 
-        <para></para>
-      </sect1>
+          <itemizedlist>
+            <listitem>
+              <para><classname>IsisTransactionManager</classname>, which is
+              responsible for managing <classname>IsisTransaction</classname>s
+              within the persistence session.</para>
+
+              <para>As mentioned above, when running as a webapp there is
+              precisely one <classname>IsisTransaction</classname> per
+              session, however when running as a client in client/server mode
+              there may be many transactions per session.</para>
+            </listitem>
 
-      <sect1>
-        <title>Oid subtypes</title>
+            <listitem>
+              <para><classname>ServicesInjector</classname>, which is
+              responsible for injecting domain services into each domain
+              object as it is instantiated.</para>
 
-        <para></para>
-      </sect1>
+              <para>Services are discussed further in <xref
+              linkend="sec.RegisteringServices" />.</para>
+            </listitem>
 
-      <sect1>
-        <title></title>
+            <listitem>
+              <para><classname>PojoAdapterFactory</classname>, which is an
+              implementation of the
+              <classname>oai.core.metamodel.adapter.ObjectAdapterFactory</classname>
+              <acronym>API</acronym>. </para>
+
+              <para>The default implementation instantiates
+              <classname>PojoAdapter</classname> as the corresponding
+              implementation of
+              <classname>oai.core.metamodel.adapter.ObjectAdapter</classname>.
+              There is further coverage of
+              <classname>ObjectAdapter</classname>s in <xref
+              linkend="sec.ObjectLifecycleManagement" />.</para>
+
+              <para>In principle this is an extension point; the
+              <emphasis>default runtime</emphasis> could be extended to
+              provide different implementations of
+              <classname>ObjectAdapterFactory</classname>. for example to
+              provide more extensive binding support for certain viewers, or
+              to provide a fine-grained notifications of changes to underlying
+              objects.</para>
+            </listitem>
 
-        <para></para>
-      </sect1>
+            <listitem>
+              <para><classname>ObjectFactory</classname>, which provides
+              different implementations for instantiating domain object
+              pojos.</para>
+
+              <para>This is the primary <acronym>API</acronym> that enables
+              lazy-loading and automatic tracking of dirty objects.
+              Specifically, the <classname>ObjectFactory</classname>
+              <acronym>API</acronym> is implemented to allow the bytecode
+              implementation to instantiate objects (they provide custom
+              subclasses which act as wrappers around the underlying
+              object).</para>
+
+              <para>In addition, the <classname>ClassSubstitutor</classname>
+              <acronym>API</acronym> should also be implemented; this allows
+              the metamodel to walk the graph ignoring the custom
+              subclasses.</para>
+            </listitem>
 
-      <sect1>
-        <title>IsisContext</title>
+            <listitem>
+              <para><classname>OidGenerator</classname>, which provides an
+              <acronym>API</acronym> to generate unique
+              <classname>Oid</classname>s (object identifiers) for each
+              persistent instance.</para>
+
+              <para>You can think of the <classname>OidGenerator</classname>
+              as a generalization of the automatic generation of primary keys
+              for entities (using a SQL Server <code>identity</code> keyword
+              or Oracle SEQUENCE). However, whereas a primary key id only
+              relates to persisted objects, <emphasis>Isis</emphasis>'
+              <emphasis>default runtime</emphasis> also allows
+              <classname>Oid</classname>s to be created for still-transient
+              objects. Because such objects may later be persisted, this
+              meanst that the value of the <classname>Oid</classname> can
+              change at this point. <emphasis>Isis</emphasis> automatically
+              manages this transition.</para>
+            </listitem>
+
+            <listitem>
+              <para><classname>AdapterManager</classname>, which is
+              responsible for tracking the associations between domain object
+              pojos, <classname>ObjectAdapter</classname>s and
+              <classname>Oid</classname>s.</para>
 
-        <para><emphasis>Context</emphasis></para>
+              <para>This, too, is discussed fruther in <xref
+              linkend="sec.ObjectLifecycleManagement" />.</para>
+            </listitem>
+          </itemizedlist>
 
-        <para>The <classname>IsisContext</classname> class responsibility
-        provide access to the main components of the framework.</para>
+          <para>The final scope is for transactions that are created within an
+          session.</para>
+        </sect2>
 
-        <para>If the system is started in a multi-user mode then the context
-        will hold specific components for specific execution contexts,
-        allowing the same process to access the same components and different
-        processes to access unique instances.</para>
+        <sect2 id="sec.TransactionLevelScope">
+          <title>Transaction-level scope</title>
 
-        <para>Each execution context will have its own Persistor, Message
-        Broker and Update Notifier.</para>
+          <para>The <classname>IsisTransactionManager</classname> (referenced
+          by <classname>PersistenceSession</classname>) is responsible for
+          creating an <classname>IsisTransaction</classname>. The
+          implementation used depends on the
+          <classname>PersistenceSession</classname>, but for the more common
+          case, object stores, the implementation that is used is
+          <classname>ObjectStoreTransaction</classname>. This in turn holds a
+          collection of <classname>PersistenceCommand</classname>s which
+          represent instructions to add, update or delete objects as required.
+          When the transaction is committed, each of these
+          <classname>PersistenceCommand</classname>s is executed by the
+          configured object store.</para>
 
-        <para>The Reflector and Configuration are shared among all execution
-        contexts.</para>
+          <para>In addition to the commands, the IsisTransaction also holds
+          two further sub-components:</para>
 
-        <para><emphasis>Persistor</emphasis></para>
+          <itemizedlist>
+            <listitem>
+              <para>the <classname>UpdateNotifier</classname> is used to
+              capture the list of objects that have been added, updated or
+              deleted (disposed of). This can be queried by other components
+              (such as viewers) as necessary (for example, to know which
+              objects to repaint).</para>
 
-        <para>During startup the persistor is given a set of service objects.
-        During intialisation the persistor must determine the OIDs for these
-        service objects. If the persistor does not know about a service (by
-        its ID) from a previous run then it must generate an OID for the
-        service and persist that with the ID of the service. This allows
-        references to be held persistently to service objects despite the fact
-        that they are singletons.</para>
+              <para>Once changes are retrieved by client the notifier resets
+              its collection so that changes are only available once.</para>
+            </listitem>
 
-        <para></para>
+            <listitem>
+              <para>the <classname>MessageBroker</classname> is used to
+              capture any messages, warnings, or errors that either the system
+              or the domain objects themselves have raised.</para>
+
+              <para>Domain objects can raise messages using the
+              <classname>oai.applib.DomainObjectContainer</classname>,
+              automatically injected into all domain objects. The system may
+              raise messages if, for example, a concurrency exception
+              occurs.</para>
+            </listitem>
+          </itemizedlist>
 
-        <para></para>
+          <para>In general it is invalid to access an object from any scope
+          once it has been closed. So, for example, the behaviour of the
+          <classname>AdapterManager</classname> of a
+          <classname>PersistenceSession</classname> is undefined once its
+          owning <classname>PersistenceSession</classname> is closed. The
+          exception to this rule is the <classname>UpdateNotifier</classname>
+          and <classname>MessageBroker</classname>. Other components in the
+          framework are free to access these even after the transaction has
+          completed, for example in order to repaint the view. See <xref
+          linkend="sec.IsisContext" /> for details on how to obtain these
+          components and any others.</para>
+        </sect2>
       </sect1>
 
-      <sect1>
-        <title>Installers and
-        <filename>installer-registry.properties</filename></title>
+      <sect1 id="sec.IsisContext">
+        <title>Service Locator (<classname>IsisContext</classname>)</title>
+
+        <para>The <emphasis>default runtime</emphasis> uses the service
+        locator pattern to make components (of different scopes) available.
+        This is implemented through the <classname>IsisContext</classname>
+        class.</para>
+
+        <para><classname>IsisContext</classname> itself is abstract; concrete
+        subclasses take responsibility for binding the services as
+        appropriate. For example, the default implementation for server-side
+        deployments is to use the
+        <classname>IsisContextThreadLocal</classname>, which (as might be
+        expected) binds the <classname>IsisContext</classname> singleton to
+        thread-local storage. This is, however, pluggable; the Wicket viewer
+        <package>[oai.viewer:wicket]</package> for example provides its own
+        implementation <classname>IsisContextForWicket</classname>, which
+        binds the IsisContext to an <ulink
+        url="http://wicket.apache.org">Apache Wicket</ulink>
+        <classname>org.apache.wicket.Session</classname>.</para>
+
+        <para>As noted above, in general it is invalid to access an object
+        from any scope once it has been closed; an
+        <classname>IllegalStateException</classname> will be thrown
+        otherwise.</para>
+      </sect1>
+
+      <sect1 id="sec.ObjectLifecycleManagement">
+        <title>Object Lifecycle Management</title>
+
+        <para>Managing the lifecycle of domain objects is one of the major
+        responsibilities of the <emphasis>default runtime</emphasis>. Most of
+        the work goes on in the <classname>PersistenceSession</classname>
+        component, discussed earlier in <xref
+        linkend="sec.SessionLevelScope" />. In this section we dig a little
+        deeper into some of the internals of this component.</para>
+
+        <sect2>
+          <title><classname>ObjectAdapter</classname>s and
+          <classname>Oid</classname>s</title>
+
+          <para><emphasis>Apache Isis</emphasis> components do not deal
+          directly with domain object pojos; instead they are always wrapped
+          by an adapter, call <classname>ObjectAdapter</classname>. This has
+          two main responsibilities:</para>
 
-        <para></para>
+          <itemizedlist>
+            <listitem>
+              <para>it provides reference to the
+              <classname>ObjectSpecification</classname>, which describes the
+              structure (properties, collections, actions) of the object's
+              type</para>
+            </listitem>
 
-        <para></para>
-      </sect1>
+            <listitem>
+              <para>it provides reference to an <classname>Oid</classname>,
+              which is an opaque value that uniquely identifies the object
+              instance.</para>
+            </listitem>
+          </itemizedlist>
 
-      <sect1>
-        <title>Scopes</title>
+          <para>You can think of <classname>ObjectAdapter</classname> as
+          equivalent to <classname>java.lang.Object</classname>, while
+          <classname>ObjectSpecification</classname> is in some sense
+          equivalent to <classname>java.lang.Class</classname>. The
+          <classname>Oid</classname> interface meanwhile is something akin to
+          a primary key identifier for an row in a relational database, but it
+          is slightly more abstract than that because it can also represent a
+          non-persisted object.</para>
+
+          <para>It is the <emphasis>metamodel</emphasis> module of
+          <emphasis>Isis</emphasis> <package>[oai.core:metamodel]</package>
+          defines these interfaces (<classname>ObjectAdapter,
+          ObjectSpecifation</classname> and <classname>Oid</classname>), the
+          object itself (<classname>ObjectAdapter</classname>), and the
+          object's identity (<classname>Oid</classname>). The metamodel itself
+          also provides an implementation of
+          <classname>ObjectSpecification</classname>.</para>
+
+          <para>The <emphasis>default runtime</emphasis> module
+          <package>[oai.runtimes:dflt]</package> provides an implementations
+          of the <classname>ObjectAdapter</classname> interface
+          (<classname>oai.runtimes.dflt.persistence.adapterfactory.pojo.PojoAdapter</classname>)
+          as well as an implementation of the <classname>Oid</classname>
+          interface. The actual implementation of <classname>Oid</classname>
+          will depend on the object store (persistence) mechanism that the
+          runtime has been configured to use.</para>
+        </sect2>
+
+        <sect2>
+          <title><classname>AdapterManager</classname></title>
+
+          <para>As already mentioned, the <classname>ObjectAdapter</classname>
+          maintains a reference to an <classname>Oid</classname> and the
+          underlying pojo domain object. To traverse in the other direction -
+          that is, from <classname>Oid</classname> to
+          <classname>ObjectAdapter</classname> or from pojo to
+          <classname>ObjectAdapter</classname> - the default runtime uses its
+          internal <classname>AdapterManager</classname> component, which
+          maintains two sets of maps. This is shown below:</para>
+
+          <mediaobject>
+            <imageobject>
+              <imagedata fileref="images/adapter-manager.png" scale="45" />
+            </imageobject>
+          </mediaobject>
+
+          <para>The <classname>AdapterManager</classname> is an example of the
+          <ulink
+          url="http://martinfowler.com/eaaCatalog/identityMap.html">object-identity
+          map pattern</ulink> (as documented more fully in Martin Fowler's
+          Patterns of Enterprise Application Architecture). Whenever a domain
+          object pojo is handled by the system, and before an adapter for it
+          has been created, the runtime checks the
+          <classname>AdapterManager</classname> for the instance first, and
+          only creates an adapter if the pojo is not mapped. Similarly, if the
+          adapter has only an <classname>Oid</classname> value then the
+          <classname>AdapterManager</classname> is determine if the object's
+          adapter exists.</para>
+
+          <para>For value types (such as <classname>String</classname> or
+          <classname>java.math.BigDecimal</classname>), things are a little
+          different. All values <emphasis>do</emphasis> still have an
+          associated <classname>ObjectAdapter</classname>, however the
+          <classname>Oid</classname> of these is null, and these objects are
+          not stored within the <classname>AdapterManager</classname> maps. A
+          value is any object whose <classname>ObjectSpecification</classname>
+          has a <classname>ValueFacet</classname> associated with it.
+          Typically this is as a result of it have the
+          <classname>@Value</classname> annotation; or it might be one of the
+          built-in types supported by <emphasis>Isis</emphasis> (such as
+          <classname>String</classname>).</para>
+        </sect2>
 
-        <para></para>
+        <sect2>
+          <title>Aggregate roots and <classname>Oid</classname>
+          subtypes</title>
 
-        <para></para>
+          <para>Whereas value types have no <classname>Oid</classname>, all
+          other domain objects do:</para>
 
-        <mediaobject>
-          <imageobject>
-            <imagedata fileref="images/architecture.gif" scale="40" />
-          </imageobject>
-        </mediaobject>
+          <itemizedlist>
+            <listitem>
+              <para>Most domain objects that have an
+              <classname>Oid</classname> will be domain entities that,
+              moreover, are aggregate roots. That is, these are entities that
+              are intended to be directly referenced from other entities, and
+              have their own, independent identity.</para>
+
+              <para>For example, a <classname>Customer</classname>,
+              <classname>Product</classname> and <classname>Order</classname>
+              are all likely to be aggregate root entities.</para>
+            </listitem>
 
-        <para></para>
-      </sect1>
+            <listitem>
+              <para>Lists or sets also have an
+              <classname>Oid</classname>.</para>
 
-      <sect1>
-        <title>Update Notifier (Change Listener)</title>
+              <para>For example, the <classname>List&lt;Order&gt;</classname>
+              held internally by a <classname>Customer</classname> to
+              represent its list of <classname>Order</classname>s will be
+              wrapped in an <classname>ObjectAdapter</classname> and have its
+              own <classname>Oid</classname>. Moreover, this
+              <classname>ObjectAdapter</classname> will be able to track
+              whether the list has been populated from the persistence
+              mechanism (so that the collection can be lazily loaded if
+              required).</para>
+
+              <para>However, such internal lists do not exist outside of their
+              owning entity, so these are considered "aggregated" by that
+              owning entity. The <classname>Oid</classname> of such objects is
+              an instance of type <classname>AggregatedOid</classname>, which
+              is basically the <classname>Oid</classname> of its owning entity
+              along with an Id for the collection of the object member in
+              question (eg "orders").</para>
+            </listitem>
 
-        <para></para>
+            <listitem>
+              <para>Entities can also be aggregated.</para>
 
-        <para>Changes to objects are collected by the
-        <classname>UpdateNotifier</classname> object once they have been
-        persisted. These changes can then be asynchronously accessed by a
-        client to keep it in sync with the underlying model. Once changes are
-        retrieved by client the notifier resets its collection so that changes
-        are only available once.</para>
-
-        <para>Within the framework, specifically the persistor, when objects
-        changes and deletions are persisted the notifier should be informed
-        via its <methodname>addChangedObject(ObjectAdapter)</methodname> and
-        <methodname>addDisposedObject(ObjectAdapter)</methodname>
-        methods.</para>
-
-        <para>Clients should use the
-        <methodname>allChangedObjects()</methodname> and
-        <methodname>allDisposedObjects()</methodname> to get an
-        <classname>Enumeration</classname> of the changes.</para>
+              <para>If an entity type is annotated with
+              <classname>@Aggregated</classname>, then it means that all
+              instances of that type are considered as non-root aggregated
+              entities, and will also be identified using an
+              <classname>AggregatedOid</classname>.</para>
+
+              <para>For example, <classname>OrderItem</classname> might be
+              considered an aggregate type (within its aggregate root,
+              <classname>Order</classname>).</para>
+            </listitem>
+          </itemizedlist>
 
-        <para>The notifier itself can be got from system context using
-        <methodname>IsisContext.getUpdateNotifer()</methodname>.</para>
+          <para>Marking an entity as aggregated may or may not impact how it
+          is persisted. For example, an XML or No-SQL (JSON-based) object
+          store might conceivably inline the persisted representation of the
+          aggregated entity within the document representing the aggregate
+          root. An RDBMS-based object store, on the other hand, might choose
+          to simply persist every entity in its own table (meaning that the
+          distinction between aggregate root entities vs aggregated entities
+          is less obvious).</para>
+        </sect2>
 
-        <para></para>
-      </sect1>
+        <sect2 id="sec.RegisteringServices">
+          <title>Services</title>
 
-      <sect1>
-        <title>Profile Stores</title>
+          <para>***</para>
 
-        <para></para>
+          <para>During startup the persistor is given a set of service
+          objects. During intialisation the persistor must determine the OIDs
+          for these service objects. If the persistor does not know about a
+          service (by its ID) from a previous run then it must generate an OID
+          for the service and persist that with the ID of the service. This
+          allows references to be held persistently to service objects despite
+          the fact that they are singletons.</para>
 
-        <para></para>
+          <para></para>
+
+          <para></para>
+        </sect2>
       </sect1>
 
       <sect1>
-        <title>Exploration vs Prototype Modes</title>
+        <title>Profile Stores</title>
 
         <para></para>