Further work on documentation
authorben.clark <ben.clark@localhost>
Fri, 24 Jul 2009 12:14:50 +0000 (12:14 +0000)
committerben.clark <ben.clark@localhost>
Fri, 24 Jul 2009 12:14:50 +0000 (12:14 +0000)
.gitattributes
src/docbkx/ReferenceDocumentation.xml
src/docbkx/basic-persistence.xml
src/docbkx/free-text-search.xml [new file with mode: 0644]
src/docbkx/guid-resolution.xml [new file with mode: 0644]
src/docbkx/identifiable-entities.xml
src/docbkx/resources/images/dao.png [new file with mode: 0644]
src/docbkx/resources/images/service.png [new file with mode: 0644]
src/docbkx/security.xml [new file with mode: 0644]
src/docbkx/service.xml [new file with mode: 0644]
src/docbkx/versioning.xml [new file with mode: 0644]

index 38e8e49c5c3dc7748e7baa5aee1ca405eb51c52d..b61a58b8062a51f8c33b44e71a55227fea461692 100644 (file)
@@ -2297,14 +2297,21 @@ src/docbkx/ReferenceDocumentation.xml -text
 src/docbkx/annotation-and-markers.xml -text
 src/docbkx/base-classes.xml -text
 src/docbkx/basic-persistence.xml -text
+src/docbkx/free-text-search.xml -text
+src/docbkx/guid-resolution.xml -text
 src/docbkx/identifiable-entities.xml -text
 src/docbkx/resources/css/html.css -text
 src/docbkx/resources/images/ModelOverview20.gif -text
 src/docbkx/resources/images/cdmlib-arch3.png -text
+src/docbkx/resources/images/dao.png -text
 src/docbkx/resources/images/logo.png -text
+src/docbkx/resources/images/service.png -text
 src/docbkx/resources/xsl/cdmlib.xsl -text
 src/docbkx/resources/xsl/fopdf.xsl -text
 src/docbkx/resources/xsl/html_chunk.xsl -text
+src/docbkx/security.xml -text
+src/docbkx/service.xml -text
+src/docbkx/versioning.xml -text
 src/site/resources/images/logos/logo_edit.png -text
 src/site/resources/images/logos/logo_edit2.png -text
 src/site/site.xml -text
index dcf8fd72d9d7bc49b4e6fb5a67ff5f36bb69d3aa..fe951a787002aca9af45c75a5c218e4ffcadfd1e 100644 (file)
     plain-old-java-objects (<link
     xlink:href="http://en.wikipedia.org/wiki/Plain_Old_Java_Object">pojo's</link>),
     a set of java components has been created that provide common services
-    across all java applications using the CDM. In addition to serving as the
-    basis of core components of the Internet Platform for Cyberplatform, they
-    also allow the development of other applications using the CDM by
-    providing basic functionality that can be extended for a particular
-    purpose.</para>
+    across all java applications using the CDM. They serve as the basis of
+    core components of the Internet Platform for Cyberplatform and also allow
+    the development of other applications using the CDM by providing basic
+    functionality that can be extended for a particular purpose.</para>
 
     <para>The CDM Library, as it is known, consists of four major modules that
     can be used by any java application based on the CDM. These libraries are
@@ -87,6 +86,8 @@
     web applications based on the CDM.</para>
 
     <figure>
+      <title>An overview of the main CDM Components</title>
+
       <mediaobject>
         <imageobject role="html">
           <imagedata fileref="resources/images/cdmlib-arch3.png" format="png" />
         Dataportal, CATE) applications.</caption>
       </mediaobject>
     </figure>
+
+    <para>This reference documentation is aimed at anyone who would like to
+    understand the software components that make up the core of the
+    cyberplatform: the CDM Java Library and the CDM Server application. More
+    generic information about the applications that make up the cyberplatform,
+    information for end-users of specific applications, and information on the
+    EDIT project itself are beyond the scope of this document. More
+    information about EDIT can be found on the <link linkend="???">EDIT
+    website</link>, and more information on the specific software applications
+    produced by EDIT can be found on the <link linkend="???">Work Package 5
+    website</link>.</para>
   </preface>
 
+  <part>
+    <title>Getting Started</title>
+
+    <partintro>
+      <para>This part of the reference documentation aims to provide simple
+      step-by-step instructions to enable application developers to start
+      using the CDM Java Library in their java application. To do this, we
+      will create a small toy application. The CDM Java Library is packaged
+      and published using the Apache Maven software project managment and
+      comprehension tool. To make life easier, we'll use maven to create our
+      application too. Assuming that Maven (2.0.x+) installed, we begin by
+      creating a new maven application (substituting the group id, artifact
+      id, and version of our application):</para>
+
+      <screen>mvn archetype:create -DgroupId=<emphasis>org.myproject</emphasis> -DartifactId=<emphasis>myapp</emphasis> -Dversion=<emphasis>1.0</emphasis></screen>
+
+      <para>The next step is to add the EDIT maven repository to your maven
+      <emphasis>project object model</emphasis> or <emphasis>pom</emphasis>
+      file, thus:</para>
+
+      <programlisting>. . .
+&lt;repositories&gt;
+  &lt;repository&gt;
+    &lt;id&gt;EditRepository&lt;/id&gt;
+    &lt;url&gt;http://wp5.e-taxonomy.eu/cdmlib/mavenrepo/&lt;/url&gt;
+  &lt;/repository&gt;
+&lt;/repositories&gt;
+&lt;/project&gt;</programlisting>
+
+      <para>We also need to add the specific dependency that we would like our
+      project to include.</para>
+
+      <programlisting>. . .
+&lt;dependencies&gt;
+    &lt;dependency&gt;
+      &lt;groupId&gt;eu.etaxonomy&lt;/groupId&gt;
+      &lt;artifactId&gt;cdmlib-services&lt;/artifactId&gt;
+      &lt;version&gt;1.1.1&lt;/version&gt;<!--ben: We will need to change this to reflect the new release once it is available-->
+    &lt;/dependency&gt;
+  &lt;/dependencies&gt;
+&lt;repositories&gt;
+. . .</programlisting>
+
+      <para>In most cases, application developers will wish to include the
+      cdmlib services (which include the data model and persistence layer
+      too). In some cases, developers might wish to use components from the
+      <package>cdmlib-io</package> and <package>cdmlib-remote</package>
+      packages too. New releases of the CDM Java Library are published in the
+      EDIT Maven Repository, and maven will download and use these artifacts
+      automatically if you change the version number of the dependency
+      specified in your pom file.</para>
+
+      <para>All that remains is to set up the cdmlib services within the
+      application context. The CDM Java Library is uses the Spring Framework
+      to manage its components. Whilst it is not mandatory to wire the CDM
+      services and DAOs using Spring, it is certainly easier to configure your
+      application this way. A minimal applicationContext.xml (placed in
+      <filename>src/main/resources</filename>) file might look like
+      this:</para>
+
+      <programlisting>&lt;import resource="classpath:/eu/etaxonomy/cdm/services.xml" /&gt;
+
+&lt;bean id="dataSource" 
+  lazy-init="true"
+  class="eu.etaxonomy.cdm.database.LocalHsqldb"        
+  init-method="init"
+  destroy-method="destroy"&gt;
+  &lt;property name="driverClassName" value="org.hsqldb.jdbcDriver"/&gt;
+  &lt;property name="username" value="sa"/&gt;
+  &lt;property name="password" value=""/&gt;
+  &lt;property name="startServer" value="true"/&gt;
+  &lt;property name="silent" value="true"/&gt;
+&lt;/bean&gt;
+    
+&lt;bean id="hibernateProperties" 
+  class="org.springframework.beans.factory.config.PropertiesFactoryBean"&gt;
+  &lt;property name="properties"&gt;
+    &lt;props&gt;
+      &lt;prop key="hibernate.hbm2ddl.auto"&gt;create-drop&lt;/prop&gt;
+      &lt;prop key="hibernate.dialect"&gt;org.hibernate.dialect.HSQLDialect&lt;/prop&gt;
+      &lt;prop key="hibernate.cache.provider_class"&gt;org.hibernate.cache.NoCacheProvider&lt;/prop&gt;
+    &lt;/props&gt;
+  &lt;/property&gt;
+&lt;/bean&gt;</programlisting>
+
+      <para>The first element imports the cdmlib service definitions. The two
+      other beans supply a data source and a properties object that the CDM
+      library uses to configure the hibernate session factory and connect to
+      the database. In this case, we're using an in-memory HSQL database, but
+      the CDM can be used with many other databases. The only thing left to do
+      is to start using the CDM services. In real applications, CDM services
+      may well be autowired into components using Spring or another dependency
+      injection mechanism. To keep this example simple, we'll initialize the
+      application context and obtain a service programatically.</para>
+
+      <programlisting>ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
+
+INameService nameService = (INameService)context.getBean("nameServiceImpl");
+
+BotanicalName botanicalName = BotanicalName.NewInstance(Rank.SPECIES());
+botanicalName.setGenusOrUninomial("Arum");
+botanicalName.setSpecificEpithet("maculatum");
+UUID uuid = nameService.saveTaxonName(botanicalName);<!--ben: Again, this example reflects the 1.1.1 release, and will need to be changed slightly once the new release is available-->
+
+System.out.println("Saved \'Arum maculatum\' under uuid " + uuid.toString());</programlisting>
+
+      <para>In this simple example, we've covered the basics of using the CDM
+      Java Library. We created a simple maven project, and added the
+      repository and a single dependency to our pom file. We then created a
+      simple application context that used the default CDM configuration, and
+      specified a couple of objects that allowed the CDM to connect to a
+      database. Finally we initialized these services by loading the
+      application context, and then retrieved a specific service, and used it
+      to persist a new taxonomic name.</para>
+    </partintro>
+  </part>
+
   <part>
     <title>Common Data Model</title>
 
     <!--<xi:include href="taxonomic-names.xml" />-->
 
     <!--<xi:include href="taxonomic-concepts.xml" />-->
+
     <!--<xi:include href="specimens-and-observations.xml" />-->
 
     <!--<xi:include href="descriptive-data.xml" />-->
     <!--<xi:include href="terms-and-vocabularies.xml" />-->
 
     <!-- ben: We'll need to touch on _where_ these external files live . . .-->
+
     <!--<xi:include href="media.xml" />-->
 
     <!-- ben: I'll include something about validation once I start 
               work on the validation framework next month
-      --> 
+      -->
+
     <!--<xi:include href="validation.xml" />-->
-    
   </part>
 
   <part>
       persistence and query service as the basis of its persistence layer.
       Several member projects of the Hibernate stable, including <link
       xlink:href="http://annotations.hibernate.org">Hibernate
-      Annotations</link>, <link xlink:href="http://search.hibernate.org">Hibernate Search</link> and
-      <link linkend="http://jboss.org/envers/">Hibernate Envers</link> (part of Hibernate Core)
-      provide the basis of the more advanced persistence-related functionality
-      in the CDM Library. As a consequence some of the behaviour of the CDM
-      Library is constrained by the underlying ORM technology. The advantage
-      of using an ORM is that the same software can be used with multiple
-      database systems with (almost) no changes to the application. Currently
-      the CDM Library has been tested with (version numbers &amp; platforms in
-      brackets)</para>
+      Annotations</link>, <link
+      xlink:href="http://search.hibernate.org">Hibernate Search</link> and
+      <link linkend="http://jboss.org/envers/">Hibernate Envers</link> (part
+      of Hibernate Core) provide the basis of the more advanced
+      persistence-related functionality in the CDM Library. As a consequence
+      some of the behaviour of the CDM Library is constrained by the
+      underlying ORM technology. The advantage of using an ORM is that the
+      same software can be used with multiple database systems with (almost)
+      no changes to the application. Currently the CDM Library has been tested
+      with (version numbers &amp; platforms in brackets)</para>
 
       <!--I don't know how many of these have been tested, on which platforms, but it would be good to include some measure of which platform / database combinations 
 have been used and how, so that potential users can evaluate the technology. In an ideal world, we would pick some databases as "supported" and ensure that
@@ -371,31 +502,31 @@ the CDM on this platform and it seemed to work".-->
 
     <xi:include href="basic-persistence.xml" />
 
-    <!--<xi:include href="listing-sorting-initializing.xml" />-->
+    <xi:include href="versioning.xml" />
 
-    <!--<xi:include href="versioning.xml" />-->
-
-    <!--<xi:include href="free-text-search.xml" />-->
+    <xi:include href="free-text-search.xml" />
   </part>
 
   <part xml:id="api">
     <title>API Methods</title>
 
     <partintro>
-      <para>This part discusses the service layer:</para>
+      <para>Apart from the Common Data Model classes themselves, the CDM
+      Service layer contains the components most likely to be used directly by
+      applications based upon the CDM Java Library. This layer contains a set
+      of basic service objects that can be used as a facade over the
+      persistence logic.</para>
     </partintro>
 
-    <!--<xi:include href="service.xml" />-->
-
-    <!--<xi:include href="paging-resultsets.xml" />-->
+    <xi:include href="service.xml" />
 
     <!--<xi:include href="application-controller.xml" />-->
 
     <!--<xi:include href="transactions.xml" />-->
 
-    <!--<xi:include href="guid-resolution.xml" />-->
+    <xi:include href="guid-resolution.xml" />
 
-    <!--<xi:include href="security.xml" />-->
+    <xi:include href="security.xml" />
   </part>
 
   <part>
index 990c55935b80d716c94191dca528b8d3399c429c..11bd32e37c9d87b24f159f2f48aea33037c853e0 100644 (file)
 \r
   <section>\r
     <para>The persistence layer of the CDM primarily consists of a set of\r
-    <emphasis>data access objects (DAOs)</emphasis>. These DAOs are\r
-    generically typed, and form a hierachy that reflects the inheritance of the data entities that they provide access too. The root DAO implements <interfacename>ICdmEntityDao</interfacename>.</para>\r
+    <emphasis>data access objects (DAOs)</emphasis>. These DAOs are generic,\r
+    strongly typed, and form a hierachy that reflects the inheritance of the\r
+    data entities that they provide access too. The root DAO implements\r
+    <interfacename>ICdmEntityDao</interfacename>.</para>\r
 \r
-    <table xml:id="icdmentitydao-methods" frame='all'>\r
+    <table frame="all" xml:id="icdmentitydao-methods">\r
       <title><interfacename>ICdmEntityDao</interfacename> methods</title>\r
-      <tgroup cols='2' align='left' colsep='1' rowsep='1'>\r
-        <colspec colname='c1'/>\r
-        <colspec colname='c2'/>\r
+\r
+      <tgroup align="left" cols="2" colsep="1" rowsep="1">\r
+        <colspec colname="c1" />\r
+\r
+        <colspec colname="c2" />\r
+\r
         <thead>\r
           <row>\r
             <entry>Method</entry>\r
+\r
             <entry>Description</entry>\r
           </row>\r
         </thead>\r
+\r
         <tbody>\r
           <row>\r
-            <entry><methodsynopsis><type>UUID</type><methodname>saveOrUpdate</methodname><methodparam><type>T</type><parameter>newEntity</parameter></methodparam></methodsynopsis></entry>\r
-           <entry><para>Makes a new object persistent, or persists the state of a transient object.</para></entry>\r
+            <entry>\r
+              <methodsynopsis>\r
+                <type>UUID</type>\r
+\r
+                <methodname>saveOrUpdate</methodname>\r
+\r
+                <methodparam>\r
+                  <type>T</type>\r
+\r
+                  <parameter>newOrTransientEntity</parameter>\r
+                </methodparam>\r
+              </methodsynopsis>\r
+            </entry>\r
+\r
+            <entry>\r
+              <para>Makes a new object persistent, or persists the state of a\r
+              transient object.</para>\r
+            </entry>\r
+          </row>\r
+\r
+          <row>\r
+            <entry>\r
+              <methodsynopsis>\r
+                <type>Map&lt;UUID,T&gt;</type>\r
+\r
+                <methodname>save</methodname>\r
+\r
+                <methodparam>\r
+                  <type>Collection&lt;T&gt;</type>\r
+\r
+                  <parameter>newEntities</parameter>\r
+                </methodparam>\r
+              </methodsynopsis>\r
+            </entry>\r
+\r
+            <entry>\r
+              <para>Makes a collection of new objects persistent.</para>\r
+            </entry>\r
+          </row>\r
+\r
+          <row>\r
+            <entry>\r
+              <methodsynopsis>\r
+                <type>UUID</type>\r
+\r
+                <methodname>save</methodname>\r
+\r
+                <methodparam>\r
+                  <type>T</type>\r
+\r
+                  <parameter>newEntity</parameter>\r
+                </methodparam>\r
+              </methodsynopsis>\r
+            </entry>\r
+\r
+            <entry>\r
+              <para>Makes a new object persistent.</para>\r
+            </entry>\r
+          </row>\r
+\r
+          <row>\r
+            <entry>\r
+              <methodsynopsis>\r
+                <type>UUID</type>\r
+\r
+                <methodname>update</methodname>\r
+\r
+                <methodparam>\r
+                  <type>T</type>\r
+\r
+                  <parameter>newEntity</parameter>\r
+                </methodparam>\r
+              </methodsynopsis>\r
+            </entry>\r
+\r
+            <entry>\r
+              <para>Makes changes to a transient object persistent.</para>\r
+            </entry>\r
+          </row>\r
+\r
+          <row>\r
+            <entry>\r
+              <methodsynopsis>\r
+                <type>UUID</type>\r
+\r
+                <methodname>merge</methodname>\r
+\r
+                <methodparam>\r
+                  <type>T</type>\r
+\r
+                  <parameter>newEntity</parameter>\r
+                </methodparam>\r
+              </methodsynopsis>\r
+            </entry>\r
+\r
+            <entry>\r
+              <para>Merges the state of a detached object into the persisted\r
+              version.</para>\r
+            </entry>\r
+          </row>\r
+\r
+          <row>\r
+            <entry>\r
+              <methodsynopsis>\r
+                <type>UUID</type>\r
+\r
+                <methodname>delete</methodname>\r
+\r
+                <methodparam>\r
+                  <type>T</type>\r
+\r
+                  <parameter>persistentEntity</parameter>\r
+                </methodparam>\r
+              </methodsynopsis>\r
+            </entry>\r
+\r
+            <entry>\r
+              <para>Deletes a persistent object.</para>\r
+            </entry>\r
+          </row>\r
+\r
+          <row>\r
+            <entry>\r
+              <methodsynopsis>\r
+                <type>List&lt;T&gt;</type>\r
+\r
+                <methodname>list</methodname>\r
+\r
+                <methodparam>\r
+                  <type>Class&lt;? extends T&gt;</type>\r
+\r
+                  <parameter>clazz</parameter>\r
+                </methodparam>\r
+\r
+                <methodparam>\r
+                  <type>Integer</type>\r
+\r
+                  <parameter>limit</parameter>\r
+                </methodparam>\r
+\r
+                <methodparam>\r
+                  <type>Integer</type>\r
+\r
+                  <parameter>start</parameter>\r
+                </methodparam>\r
+\r
+                <methodparam>\r
+                  <type>List&lt;OrderHint&gt;</type>\r
+\r
+                  <parameter>orderHints</parameter>\r
+                </methodparam>\r
+\r
+                <methodparam>\r
+                  <type>List&lt;String&gt;</type>\r
+\r
+                  <parameter>propertyPaths</parameter>\r
+                </methodparam>\r
+              </methodsynopsis>\r
+            </entry>\r
+\r
+            <entry>\r
+              <para>Returns a (sub-)list of objects matching the type\r
+              <parameter>clazz</parameter>, sorted according to the order\r
+              hints and initialized according to the propertyPaths.</para>\r
+            </entry>\r
+          </row>\r
+\r
+          <row>\r
+            <entry>\r
+              <methodsynopsis>\r
+                <type>int</type>\r
+\r
+                <methodname>count</methodname>\r
+\r
+                <methodparam>\r
+                  <type>Class&lt;? extends T&gt;</type>\r
+\r
+                  <parameter>clazz</parameter>\r
+                </methodparam>\r
+              </methodsynopsis>\r
+            </entry>\r
+\r
+            <entry>\r
+              <para>Returns a count of objects matching the type\r
+              <parameter>clazz</parameter>.</para>\r
+            </entry>\r
+          </row>\r
+\r
+          <row>\r
+            <entry>\r
+              <methodsynopsis>\r
+                <type>T</type>\r
+\r
+                <methodname>find</methodname>\r
+\r
+                <methodparam>\r
+                  <type>UUID</type>\r
+\r
+                  <parameter>uuid</parameter>\r
+                </methodparam>\r
+              </methodsynopsis>\r
+            </entry>\r
+\r
+            <entry>\r
+              <para>Returns an object of type T matching the supplied uuid if\r
+              it exists.</para>\r
+            </entry>\r
+          </row>\r
+\r
+          <row>\r
+            <entry>\r
+              <methodsynopsis>\r
+                <type>Collection&lt;T&gt;</type>\r
+\r
+                <methodname>find</methodname>\r
+\r
+                <methodparam>\r
+                  <type>Collection&lt;UUID&gt;</type>\r
+\r
+                  <parameter>uuids</parameter>\r
+                </methodparam>\r
+              </methodsynopsis>\r
+            </entry>\r
+\r
+            <entry>\r
+              <para>Returns a collection of objects of type T matching the\r
+              uuids supplied, if they exist.</para>\r
+            </entry>\r
           </row>\r
+\r
           <row>\r
-            <entry><methodname>save</methodname></entry>\r
-           <entry><para>Makes a new object persistent.</para></entry>\r
+            <entry>\r
+              <methodsynopsis>\r
+                <type>T</type>\r
+\r
+                <methodname>load</methodname>\r
+\r
+                <methodparam>\r
+                  <type>UUID</type>\r
+\r
+                  <parameter>uuid</parameter>\r
+                </methodparam>\r
+\r
+                <methodparam>\r
+                  <type>Collection&lt;String&gt;</type>\r
+\r
+                  <parameter>propertyPaths</parameter>\r
+                </methodparam>\r
+              </methodsynopsis>\r
+            </entry>\r
+\r
+            <entry>\r
+              <para>Returns an object of type T with properties initialized\r
+              according to the rules described below.</para>\r
+            </entry>\r
+          </row>\r
+\r
+          <row>\r
+            <entry>\r
+              <methodsynopsis>\r
+                <type>Set&lt;T&gt;</type>\r
+\r
+                <methodname>load</methodname>\r
+\r
+                <methodparam>\r
+                  <type>Collection&lt;UUID&gt;</type>\r
+\r
+                  <parameter>uuids</parameter>\r
+                </methodparam>\r
+\r
+                <methodparam>\r
+                  <type>Collection&lt;String&gt;</type>\r
+\r
+                  <parameter>propertyPaths</parameter>\r
+                </methodparam>\r
+              </methodsynopsis>\r
+            </entry>\r
+\r
+            <entry>\r
+              <para>Returns a collection of objects of type T matching the\r
+              uuids supplied, if they exist, initialized according to the\r
+              rules described below.</para>\r
+            </entry>\r
+          </row>\r
+\r
+          <row>\r
+            <entry>\r
+              <methodsynopsis>\r
+                <type>boolean</type>\r
+\r
+                <methodname>exists</methodname>\r
+\r
+                <methodparam>\r
+                  <type>UUID</type>\r
+\r
+                  <parameter>uuid</parameter>\r
+                </methodparam>\r
+              </methodsynopsis>\r
+            </entry>\r
+\r
+            <entry>\r
+              <para>Returns true if there is an object of type T in the\r
+              database matching the supplied uuid.</para>\r
+            </entry>\r
+          </row>\r
+\r
+          <row>\r
+            <entry>\r
+              <methodsynopsis>\r
+                <type>Class&lt;T&gt;</type>\r
+\r
+                <methodname>getType</methodname>\r
+              </methodsynopsis>\r
+            </entry>\r
+\r
+            <entry>\r
+              <para>Returns the class of objects that this DAO provides access\r
+              to.</para>\r
+            </entry>\r
           </row>\r
         </tbody>\r
       </tgroup>\r
     </table>\r
+\r
+    <figure>\r
+      <title>An overview of the cdm persistence layer</title>\r
+\r
+      <mediaobject>\r
+        <imageobject role="html">\r
+          <imagedata fileref="resources/images/dao.png" format="png" />\r
+        </imageobject>\r
+\r
+        <imageobject role="fo">\r
+          <imagedata contentwidth="160mm"\r
+                     fileref="resources/images/dao.png" format="png"\r
+                     scalefit="1" />\r
+        </imageobject>\r
+\r
+        <caption>The DAO hierarchy in the CDM persistence layer. Data Access Objects are strongly typed\r
+        and their hierarchy follows the hierarchy of major entities in the CDM.</caption>\r
+      </mediaobject>\r
+    </figure>\r
+\r
+    <section>\r
+      <info>\r
+        <title>Object Initialization</title>\r
+      </info>\r
+\r
+      <para>DAO methods that return objects, return entities without any\r
+      relationships initialized by default (to learn more about initialization\r
+      of related entities, lazy-loading etc, please consult the hibernate\r
+      documentation). Because some applications (particularly stateless\r
+      multi-user applications with concise units of work i.e. web\r
+      applications), may wish to limit the length of transactions, it is\r
+      important to be able to explicitly initialize related entities according\r
+      to the particular use-case. The CDM library allows application\r
+      developers to do this on a per-method call basis.</para>\r
+\r
+      <para>Properties of the root object specified using java-beans-like\r
+      syntax and passed using the <parameter>propertyPaths</parameter>\r
+      parameter will be initialialised before the object(s) are returned and\r
+      can safely used. Applications that access other properties (that are\r
+      part of related entities) outside of the transaction in which the entity\r
+      was retrieved (i.e. the entity is detached) are likely to throw a\r
+      <exceptionname>LazyInitializationException</exceptionname>. In addition\r
+      to specifying properties by name, developers can also use an asterisk\r
+      (*) to represent all *-to-many properties, and a dollar sign ($) to\r
+      represent all *-to-one properties of the root entity or a related\r
+      entity. Using a wildcard terminates the property path (i.e. it is not\r
+      valid syntax to include characters after a wildcard in a propertyPath\r
+      expression - the wildcard must be the final character in the\r
+      string).</para>\r
+    </section>\r
+\r
+    <section>\r
+      <info>\r
+        <title>Listing objects and sorting lists</title>\r
+      </info>\r
+\r
+      <para>In addition to allowing single objects and collections of objects\r
+      matching specific UUIDs to be returned, the GenericDAO also allows lists\r
+      of objects of type T to be returned (to allow browsing of the entire\r
+      collection of entities, for example). In many cases, applications will\r
+      wish to restrict the total number of objects returned to a subset of the\r
+      total available objects (to reduce resource requirements, or increase\r
+      speed of rendering of a response, for example). This can be achieved by\r
+      supplying non-null <parameter>limit</parameter> and\r
+      <parameter>start</parameter> parameters to restrict the total number of\r
+      objects returned. These parameters are analogous to the "limit" and\r
+      "offset" parameters in SQL and are zero-based (i.e. the first result is\r
+      0, not 1).</para>\r
+\r
+      <para>Lists of objects are returned sorted according to the\r
+      <parameter>orderHints</parameter> parameter. Like the\r
+      <parameter>propertyPaths</parameter> parameter,\r
+      <classname>OrderHint</classname> objects take a java-beans-style string\r
+      that indicates the property or related entity that the list of returned\r
+      objects should be ordered by, and a <classname>SortOrder</classname>\r
+      that determined whether the list is sorted in ascending or descending\r
+      order.</para>\r
+    </section>\r
   </section>\r
 </chapter>\r
diff --git a/src/docbkx/free-text-search.xml b/src/docbkx/free-text-search.xml
new file mode 100644 (file)
index 0000000..88a31de
--- /dev/null
@@ -0,0 +1,51 @@
+<?xml version="1.0" encoding="UTF-8"?>\r
+<chapter version="5.0" xml:id="free-text-search"\r
+         xmlns="http://docbook.org/ns/docbook"\r
+         xmlns:xlink="http://www.w3.org/1999/xlink"\r
+         xmlns:ns5="http://www.w3.org/1999/xhtml"\r
+         xmlns:ns4="http://www.w3.org/2000/svg"\r
+         xmlns:ns3="http://www.w3.org/1998/Math/MathML"\r
+         xmlns:ns="http://docbook.org/ns/docbook">\r
+  <info>\r
+    <title>Free Text Search</title>\r
+  </info>\r
+\r
+  <section>\r
+    <para>The CDM supports high-performance free-text ("google-like")\r
+    searching of the data that it stores. It uses the hibernate-search library\r
+    to integrate the popular apache Lucene search software into the CDM. The\r
+    persistence layer includes hibernate-search integration by default, so\r
+    objects are added to the lucene index when applications\r
+    <methodname>save</methodname> entities, and the indices are updated when\r
+    applications <methodname>update</methodname> or\r
+    <methodname>delete</methodname> objects. All fields are converted to\r
+    lowercase during indexing, and queries are converted to lowercase during\r
+    parsing. Several properties are indexed per object type, and it is\r
+    possible to search individual fields or combinations of fields. The basic\r
+    syntax used for free text queries is described on the <link xlink:href="http://lucene.apache.org/java/2_4_1/queryparsersyntax.html">lucene\r
+    website</link>.</para>\r
+\r
+    <para>All classes have a default field that is searched when a field is\r
+    not specified. In the case of classes that extend\r
+    <classname>IdentifiableEntity</classname> the\r
+    <parameter>titleCache</parameter> field is used. By default, query strings\r
+    are broken into individual terms and objects are returned that match any\r
+    of the terms (e.g. <emphasis>Acherontia atropos</emphasis>). To return\r
+    objects that match all terms, in any order, the an AND operator can be\r
+    used (e.g. <emphasis>Acherontia AND atropos</emphasis>). By enclosing\r
+    individual terms in double quotes, you can specify that terms must appear\r
+    in a certain order (e.g. <emphasis>"Acherontia atropos"</emphasis>).\r
+    </para>\r
+\r
+    <para>To search a specific property, prepend the name of the property,\r
+    followed by a colon to the query (e.g. <emphasis>nameCache:"Acherontia\r
+    atropos"</emphasis>). Properties of related entities can be searched too,\r
+    provided that they have been indexed, using java-beans-like dot-notation.\r
+    For example, to return all references written by Schott you could use\r
+    <emphasis>authorTeam.titleCache:Schott</emphasis>, and to return all\r
+    publications written in the 1940's you could use either\r
+    <emphasis>datePublished.start:194*</emphasis> or\r
+    <emphasis>datePublished.start:[1940* TO 1949*]</emphasis> (to specify a\r
+    range).</para>\r
+  </section>\r
+</chapter>\r
diff --git a/src/docbkx/guid-resolution.xml b/src/docbkx/guid-resolution.xml
new file mode 100644 (file)
index 0000000..eb3f4e7
--- /dev/null
@@ -0,0 +1,62 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<chapter version="5.0" xml:id="guid-resolution"
+         xmlns="http://docbook.org/ns/docbook"
+         xmlns:ns5="http://www.w3.org/1999/xhtml"
+         xmlns:ns4="http://www.w3.org/2000/svg"
+         xmlns:ns3="http://www.w3.org/1998/Math/MathML"
+         xmlns:ns2="http://www.w3.org/1999/xlink"
+         xmlns:ns="http://docbook.org/ns/docbook">
+  <info>
+    <title>Globally Unique Identifier Resolution</title>
+  </info>
+
+  <section>
+    <caution>
+      <title>Likely To Change</title>
+
+      <para>Globally unique identifiers, their use and implementation are
+      still an unresolved topic. The implementaton of objects that are
+      identifiable and resolvable in a global sense must, given an open world,
+      reflect the standards and best practices being used by the community as
+      a whole. Consequently this area of the CDM is likely to change to
+      reflect this.</para>
+    </caution>
+
+    <para>The service layer implements a number of services designed to serve
+    as the basis of a LSID Resolution Service. This includes implementations
+    of <interfacename>LSIDAuthorityService</interfacename>,
+    <interfacename>LSIDMetadataService</interfacename>, and
+    <interfacename>LSIDDataService</interfacename>. Note that these are
+    service-layer implementations - the http-specific components can be found
+    in the <package>cdmlib-remote</package> package.</para>
+
+    <para>In addition to implementations of the three core LSID Resolution
+    services, the service layer holds the
+    <interfacename>LSIDRegistry</interfacename>, the component that maps LSID
+    authority + namespace combinations onto CDM classes. The implementation
+    assumes that a given authority and namespace will map onto a single CDM
+    base class, but that authorities may use different namespaces for the same
+    class of objects. In addition, the
+    <interfacename>LSIDRegistry</interfacename> provides a way of controlling
+    which authority + namespace combinations a CDM application will respond
+    to. For example, it is possible that an application will store objects
+    with identifiers published by another (foreign) authority, but doesn't
+    wish to serve metadata about these objects. By only registering specific
+    authority + namespace combinations in the
+    <interfacename>LSIDRegistry</interfacename>, a CDM store can resolve some
+    combinations but not others.</para>
+
+    <para>The three most common methods used are the
+    <methodname>getAuthorityWSDL</methodname> and
+    <methodname>getAvailableServices</methodname> methods that return a
+    <interfacename>javax.xml.transform.Source</interfacename> within an
+    <interfacename>ExpiringResponse</interfacename> object suitable for
+    rendering in a response to a client, and
+    <methodname>getMetadata</methodname>, that returns an
+    <interfacename>IIdentifiableEntity</interfacename> within a
+    <interfacename>MetadataResponse</interfacename>. If the
+    authority+namespace is not resolved, or if the object cannot be resolved,
+    or if the client requests metadata in an unavailable format, an exception
+    is thrown.</para>
+  </section>
+</chapter>
index c4bbf3e2fda5537c7ee258ab5c38409b0293e4eb..0fd65670ec8f8cb890bc3f2f27c1d629d61f05e1 100644 (file)
@@ -1,33 +1,85 @@
-<?xml version="1.0" encoding="UTF-8"?>\r
-<chapter version="5.0" xml:id="identifiable-entities" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns="http://docbook.org/ns/docbook"\r
-         xmlns:ns5="http://www.w3.org/1999/xhtml"\r
-         xmlns:ns4="http://www.w3.org/2000/svg"\r
-         xmlns:ns3="http://www.w3.org/1998/Math/MathML"\r
-         xmlns:ns2="http://www.w3.org/1999/xlink"\r
-         xmlns:ns="http://docbook.org/ns/docbook">\r
-  <info>\r
-    <title>Identifiable Entities</title>\r
-  </info>\r
-  <caution>\r
-    <title>Likely to change</title>\r
-    <para>Globally unique identifiers, their use and implementation are still an unresolved topic. The implementaton of objects that are identifiable and resolvable in a global sense must, given an open world, reflect the standards and best practices being used by the community as a whole. Consequently this area of the CDM is likely to change to reflect this.</para>\r
-    </caution>\r
-  <section>\r
-    <para>Some entities in the CDM extend <classname>IdentifiableEntity</classname>. In general there is one or two abstract base classes that extend <classname>IdentifiableEntity</classname> in each package. These classes represent important objects that an application might want to share with another application (and hence, publish globally unique identifiers for).</para>\r
-    <para>Current implemetation of the GUID in the CDM is based on the <link xlink:href="http://www.omg.org/cgi-bin/doc?dtc/04-05-01">LSID Resolution Service</link> implementation of the <link xlink:href="http://www.cate-project.org">CATE project</link>. Each <classname>IdentifiableEntity</classname> has an <varname>lsid</varname> property. See the section on <link linkend="guid-resolution">GUID Resolution</link> to see how the CDM Java Library makes it easier for you to manage and publish your data.</para>  \r
-   </section>\r
-   <section>\r
-     <!--ben: I must admit, I think I prefer formatter to cacheStrategyGenerator, because the purpose of the property seems clearer to me-->\r
-     <title><varname>titleCache</varname> and <varname>cacheStrategyGenerator</varname></title>\r
-     <para>Classes that extend <classname>IdentifiableEntity</classname> have a <varname>titleCache</varname> attribute. This property is used represent the object (for example, in a list of objects or the title for a page displaying metadata about that object). The <varname>titleCache</varname> is also used by default when sorting lists of entities. Applications are free to use other properties or combinations of properties in representing objects and can supply their own implementations of the interfaces in the <package>eu.etaxonomy.cdm.strategy.cache</package> package. If you do wish to supply custom cache strategies, you will need to inject them into your data entities, overriding the default strategy (using something like Springs <emphasis>spring-managed</emphasis> configuration mechanism). </para>\r
-   </section>\r
-   <section>\r
-     <title>Recording Provenance using <varname>originalSource</varname></title>\r
-     <!-- ben: I must admit, I don't really understand how OriginalSource is supposed to work, but then I've not needed to use it. Perhaps someone else has a more clear vision for its use.-->\r
-   </section>\r
-   <section>\r
-     <title>Indicating ownership and use using <varname>rights</varname> property</title>\r
-     <para>Identifiable entities are significant enough that users may wish to indicate ownership of the copyright of the thing that they represent, or to provide some statement of a licence under which that data may be used. This information is held in the <varname>rights</varname> element as a series of <classname>Right</classname> objects, each representing a single rights statement.</para>\r
-     <para>Note that the assertation of rights in the data is not the same as access rights in terms of application-level security which is dealt with in a <link linkend="security">later section</link>.</para>\r
-   </section>\r
-</chapter>\r
+<?xml version="1.0" encoding="UTF-8"?>
+<chapter version="5.0" xml:id="identifiable-entities"
+         xmlns="http://docbook.org/ns/docbook"
+         xmlns:xlink="http://www.w3.org/1999/xlink"
+         xmlns:ns5="http://www.w3.org/1999/xhtml"
+         xmlns:ns4="http://www.w3.org/2000/svg"
+         xmlns:ns3="http://www.w3.org/1998/Math/MathML"
+         xmlns:ns="http://docbook.org/ns/docbook">
+  <info>
+    <title>Identifiable Entities</title>
+  </info>
+
+  <caution>
+    <title>Likely to change</title>
+
+    <para>Globally unique identifiers, their use and implementation are still
+    an unresolved topic. The implementaton of objects that are identifiable
+    and resolvable in a global sense must, given an open world, reflect the
+    standards and best practices being used by the community as a whole.
+    Consequently this area of the CDM is likely to change to reflect
+    this.</para>
+  </caution>
+
+  <section>
+    <para>Some entities in the CDM extend
+    <classname>IdentifiableEntity</classname>. In general there is one or two
+    abstract base classes that extend
+    <classname>IdentifiableEntity</classname> in each package. These classes
+    represent important objects that an application might want to share with
+    another application (and hence, publish globally unique identifiers
+    for).</para>
+
+    <para>Current implemetation of the GUID in the CDM is based on the <link
+    xlink:href="http://www.omg.org/cgi-bin/doc?dtc/04-05-01">LSID Resolution
+    Service</link> implementation of the <link
+    xlink:href="http://www.cate-project.org">CATE project</link>. Each
+    <classname>IdentifiableEntity</classname> has an <varname>lsid</varname>
+    property. See the section on <link linkend="guid-resolution">GUID
+    Resolution</link> to see how the CDM Java Library makes it easier for you
+    to manage and publish your data.</para>
+  </section>
+
+  <section>
+    <!--ben: I must admit, I think I prefer formatter to cacheStrategyGenerator, because the purpose of the property seems clearer to me-->
+
+    <title><varname>titleCache</varname> and
+    <varname>cacheStrategyGenerator</varname></title>
+
+    <para>Classes that extend <classname>IdentifiableEntity</classname> have a
+    <varname>titleCache</varname> attribute. This property is used represent
+    the object (for example, in a list of objects or the title for a page
+    displaying metadata about that object). The <varname>titleCache</varname>
+    is also used by default when sorting lists of entities. Applications are
+    free to use other properties or combinations of properties in representing
+    objects and can supply their own implementations of the interfaces in the
+    <package>eu.etaxonomy.cdm.strategy.cache</package> package. If you do wish
+    to supply custom cache strategies, you will need to inject them into your
+    data entities, overriding the default strategy (using something like
+    Spring's <emphasis>spring-managed</emphasis> configuration
+    mechanism).</para>
+  </section>
+
+  <section>
+    <title>Recording Provenance using
+    <varname>originalSource</varname></title>
+
+    <!-- ben: I must admit, I don't really understand how OriginalSource is supposed to work, but then I've not needed to use it. Perhaps someone else has a more clear vision for its use.-->
+  </section>
+
+  <section>
+    <title>Indicating ownership and use using <varname>rights</varname>
+    property</title>
+
+    <para>Identifiable entities are significant enough that users may wish to
+    indicate ownership of the copyright of the thing that they represent, or
+    to provide some statement of a licence under which that data may be used.
+    This information is held in the <varname>rights</varname> element as a
+    series of <classname>Right</classname> objects, each representing a single
+    rights statement.</para>
+
+    <para>Note that the assertation of rights in the data is not the same as
+    access rights in terms of application-level security which is dealt with
+    in a <link linkend="security">later section</link>.</para>
+  </section>
+</chapter>
diff --git a/src/docbkx/resources/images/dao.png b/src/docbkx/resources/images/dao.png
new file mode 100644 (file)
index 0000000..d7425bb
Binary files /dev/null and b/src/docbkx/resources/images/dao.png differ
diff --git a/src/docbkx/resources/images/service.png b/src/docbkx/resources/images/service.png
new file mode 100644 (file)
index 0000000..eb959ff
Binary files /dev/null and b/src/docbkx/resources/images/service.png differ
diff --git a/src/docbkx/security.xml b/src/docbkx/security.xml
new file mode 100644 (file)
index 0000000..a013555
--- /dev/null
@@ -0,0 +1,118 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<chapter version="5.0" xml:id="security" xmlns="http://docbook.org/ns/docbook"
+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xmlns:xs="http://www.w3.org/2001/XMLSchema"
+         xmlns:xlink="http://www.w3.org/1999/xlink"
+         xmlns:xi="http://www.w3.org/2001/XInclude"
+         xmlns:ns5="http://www.w3.org/1999/xhtml"
+         xmlns:ns4="http://www.w3.org/2000/svg"
+         xmlns:ns3="http://www.w3.org/1998/Math/MathML"
+         xmlns:ns="http://docbook.org/ns/docbook">
+  <info>
+    <title>Security and Identity within the CDM Library</title>
+  </info>
+
+  <section>
+    <para>The CDM Library uses the Spring Security sub-project as the basis of
+    its security implementation. The best place to get information on using
+    Spring Security is the <link
+    xlink:href="http://static.springsource.org/spring-security/site/index.html">project
+    website</link>.</para>
+
+    <para>Spring Security is based around a non-intrusive and non-invasive
+    architecture that can be configured as needed by a particular application.
+    The CDM Java Library does not have any restricted or protected methods by
+    default - it is likely that each application based on the CDM will wish to
+    protect services in a different way. The CDM service layer does provide a
+    number of classes that make it straightforward to set up.</para>
+
+    <para>In addition to providing generic components for authentication and
+    authorization, Spring Security provides a number of components that can be
+    used by web applications. Details on authentication and authorization
+    concepts applied to web applications can be found in the documentation for
+    the <package>cdmlib-remote</package> package.</para>
+
+    <section>
+      <info>
+        <title>Identity</title>
+      </info>
+
+      <para>Identity in Spring Security is based around the
+      <interfacename>UserDetails</interfacename> interface, that provides
+      access to the principal's username, password, granted authorities and
+      other details. The CDM provides the <classname>User</classname> class
+      that implements this interface. In addition, it provides implementations
+      of the <interfacename>GrantedAuthority</interfacename> and a
+      <classname>Group</classname> class to allow group authorities
+      (permissions that belong to a group of individuals rather than belonging
+      to a single <classname>User</classname>). Creation of new user accounts,
+      manipulation of account details, permissions, and group membership is
+      achieved through an implementation of
+      <interfacename>IUserService</interfacename> provided by the
+      library.</para>
+
+      <para>The CDM provides some basic auditing functionality by storing the
+      user account and timestamp each time an object is modified (and a
+      transaction is comitted). The user details are retrieved from the
+      <classname>SecurityContextHolder</classname> provided by Spring
+      Security. If authentication is set up (see below) and the user is logged
+      in, then this data will be present automatically in the
+      <classname>SecurityContext</classname>. In the case of applications that
+      do not use Spring Security, the <classname>User</classname> object must
+      be placed into the <classname>SecurityContext</classname> explicitly for
+      the user details to be recorded in this way.</para>
+    </section>
+
+    <section>
+      <info>
+        <title>Authentication</title>
+      </info>
+
+      <para>To enable authentication within your application, a small number
+      of additional beans need to be added to the application context, thus
+      (note the use of the <emphasis>security</emphasis> spring-security
+      namespace):</para>
+
+      <programlisting>&lt;security:authentication-manager alias="authenticationManager"/&gt;
+   
+&lt;bean id="daoAuthenticationProvider" class="org.springframework.security.providers.dao.DaoAuthenticationProvider"&gt;
+  &lt;security:custom-authentication-provider/&gt;
+  &lt;property name="userDetailsService" ref="userService"/&gt;
+  &lt;property name="saltSource" ref="saltSource"/&gt;
+  &lt;property name="passwordEncoder" ref="passwordEncoder"/&gt;
+&lt;/bean&gt;
+    
+&lt;bean id="passwordEncoder" class="org.springframework.security.providers.encoding.Md5PasswordEncoder"/&gt;
+    
+&lt;bean id="saltSource" class="org.springframework.security.providers.dao.salt.ReflectionSaltSource"&gt;
+  &lt;property name="userPropertyToUse" value="getUsername"/&gt;
+&lt;/bean&gt;</programlisting>
+
+      <para>In the case of web applications, application developers will
+      probably want to authenticate users transparently, using the servlet
+      filter provided by spring security. For desktop applications, you can
+      also authenticate a user programatically:</para>
+
+      <programlisting>UsernamePasswordAuthenticationToken token = new UsernamePasswordAuthenticationToken("<emphasis>username</emphasis>","<emphasis>password</emphasis>");
+authenticationManager.authenticate(token);</programlisting>
+    </section>
+
+    <section>
+      <info>
+        <title>Authorization</title>
+      </info>
+
+      <para>As with authentication, web applications based upon the CDM may
+      find the standard methods provided by Spring Security or protecting URLs
+      to be sufficient in most cases. To protect service methods, or to secure
+      desktop applications, developers can also use global method security by
+      specifying a pointcut expression that matches the service and method
+      that they wish to protect, and a granted authority that is allowed to
+      access the method thus:</para>
+
+      <programlisting>&lt;security:global-method-security&gt;
+  &lt;security:protect-pointcut expression="execution(* eu.etaxonomy.cdm.api.service.UserService.changePasswordForUser(..))" access="ROLE_ADMINISTRATE"/&gt;
+&lt;/security:global-method-security&gt;</programlisting>
+    </section>
+  </section>
+</chapter>
diff --git a/src/docbkx/service.xml b/src/docbkx/service.xml
new file mode 100644 (file)
index 0000000..bde4538
--- /dev/null
@@ -0,0 +1,564 @@
+<?xml version="1.0" encoding="UTF-8"?>\r
+<chapter version="5.0" xml:id="service" xmlns="http://docbook.org/ns/docbook"\r
+         xmlns:ns5="http://www.w3.org/1999/xhtml"\r
+         xmlns:ns4="http://www.w3.org/2000/svg"\r
+         xmlns:ns3="http://www.w3.org/1998/Math/MathML"\r
+         xmlns:ns2="http://www.w3.org/1999/xlink"\r
+         xmlns:ns="http://docbook.org/ns/docbook">\r
+  <info>\r
+    <title>Services</title>\r
+  </info>\r
+\r
+  <section>\r
+    <para>The service layer of the CDM contains a set of service objects that\r
+    are intended to provide basic query, search and persistence functionality\r
+    for the CDM objects, plus business logic to support common tasks. These\r
+    objects are intended to be singleton services used across the whole\r
+    application. As with the persistence layer, the services are strongly\r
+    typed, generic service objects, with a single service per (significant\r
+    base) class. All service classes implement\r
+    <interfacename>IService</interfacename> and most implement\r
+    <interfacename>IVersionableService</interfacename>, providing access to\r
+    generic base methods to deal with the class.</para>\r
+\r
+     <figure>\r
+      <title>An overview of the cdm service layer</title>\r
+\r
+      <mediaobject>\r
+        <imageobject role="html">\r
+          <imagedata fileref="resources/images/service.png" format="png" />\r
+        </imageobject>\r
+\r
+        <imageobject role="fo">\r
+          <imagedata contentwidth="160mm"\r
+                     fileref="resources/images/service.png" format="png"\r
+                     scalefit="1" />\r
+        </imageobject>\r
+\r
+        <caption>The Service layer in the CDM Java Library. There is a service for each major type of data that the CDM deals with.</caption>\r
+      </mediaobject>\r
+    </figure>\r
+\r
+    <table frame="all" xml:id="iservice-methods">\r
+      <title><interfacename>IService</interfacename> methods</title>\r
+\r
+      <tgroup align="left" cols="2" colsep="1" rowsep="1">\r
+        <colspec colname="c1" />\r
+\r
+        <colspec colname="c2" />\r
+\r
+        <thead>\r
+          <row>\r
+            <entry>Method</entry>\r
+\r
+            <entry>Description</entry>\r
+          </row>\r
+        </thead>\r
+\r
+        <tbody>\r
+          <row>\r
+            <entry>\r
+              <methodsynopsis>\r
+                <type>UUID</type>\r
+\r
+                <methodname>saveOrUpdate</methodname>\r
+\r
+                <methodparam>\r
+                  <type>T</type>\r
+\r
+                  <parameter>newOrTransientEntity</parameter>\r
+                </methodparam>\r
+              </methodsynopsis>\r
+            </entry>\r
+\r
+            <entry>\r
+              <para>Makes a new object persistent, or persists the state of a\r
+              transient object.</para>\r
+            </entry>\r
+          </row>\r
+\r
+          <row>\r
+            <entry>\r
+              <methodsynopsis>\r
+                <type>Map&lt;UUID,T&gt;</type>\r
+\r
+                <methodname>save</methodname>\r
+\r
+                <methodparam>\r
+                  <type>Collection&lt;T&gt;</type>\r
+\r
+                  <parameter>newEntities</parameter>\r
+                </methodparam>\r
+              </methodsynopsis>\r
+            </entry>\r
+\r
+            <entry>\r
+              <para>Makes a collection of new objects persistent.</para>\r
+            </entry>\r
+          </row>\r
+\r
+          <row>\r
+            <entry>\r
+              <methodsynopsis>\r
+                <type>UUID</type>\r
+\r
+                <methodname>save</methodname>\r
+\r
+                <methodparam>\r
+                  <type>T</type>\r
+\r
+                  <parameter>newEntity</parameter>\r
+                </methodparam>\r
+              </methodsynopsis>\r
+            </entry>\r
+\r
+            <entry>\r
+              <para>Makes a new object persistent.</para>\r
+            </entry>\r
+          </row>\r
+\r
+          <row>\r
+            <entry>\r
+              <methodsynopsis>\r
+                <type>UUID</type>\r
+\r
+                <methodname>update</methodname>\r
+\r
+                <methodparam>\r
+                  <type>T</type>\r
+\r
+                  <parameter>newEntity</parameter>\r
+                </methodparam>\r
+              </methodsynopsis>\r
+            </entry>\r
+\r
+            <entry>\r
+              <para>Makes changes to a transient object persistent.</para>\r
+            </entry>\r
+          </row>\r
+\r
+          <row>\r
+            <entry>\r
+              <methodsynopsis>\r
+                <type>UUID</type>\r
+\r
+                <methodname>merge</methodname>\r
+\r
+                <methodparam>\r
+                  <type>T</type>\r
+\r
+                  <parameter>newEntity</parameter>\r
+                </methodparam>\r
+              </methodsynopsis>\r
+            </entry>\r
+\r
+            <entry>\r
+              <para>Merges the state of a detached object into the persisted\r
+              version.</para>\r
+            </entry>\r
+          </row>\r
+\r
+          <row>\r
+            <entry>\r
+              <methodsynopsis>\r
+                <type>UUID</type>\r
+\r
+                <methodname>delete</methodname>\r
+\r
+                <methodparam>\r
+                  <type>T</type>\r
+\r
+                  <parameter>persistentEntity</parameter>\r
+                </methodparam>\r
+              </methodsynopsis>\r
+            </entry>\r
+\r
+            <entry>\r
+              <para>Deletes a persistent object.</para>\r
+            </entry>\r
+          </row>\r
+\r
+          <row>\r
+            <entry>\r
+              <methodsynopsis>\r
+                <type>List&lt;T&gt;</type>\r
+\r
+                <methodname>list</methodname>\r
+\r
+                <methodparam>\r
+                  <type>Class&lt;? extends T&gt;</type>\r
+\r
+                  <parameter>clazz</parameter>\r
+                </methodparam>\r
+\r
+                <methodparam>\r
+                  <type>Integer</type>\r
+\r
+                  <parameter>pageSize</parameter>\r
+                </methodparam>\r
+\r
+                <methodparam>\r
+                  <type>Integer</type>\r
+\r
+                  <parameter>pageNumber</parameter>\r
+                </methodparam>\r
+\r
+                <methodparam>\r
+                  <type>List&lt;OrderHint&gt;</type>\r
+\r
+                  <parameter>orderHints</parameter>\r
+                </methodparam>\r
+\r
+                <methodparam>\r
+                  <type>List&lt;String&gt;</type>\r
+\r
+                  <parameter>propertyPaths</parameter>\r
+                </methodparam>\r
+              </methodsynopsis>\r
+            </entry>\r
+\r
+            <entry>\r
+              <para>Returns a (sub-)list of objects matching the type\r
+              <parameter>clazz</parameter>, sorted according to the order\r
+              hints and initialized according to the propertyPaths.</para>\r
+            </entry>\r
+          </row>\r
+\r
+          <row>\r
+            <entry>\r
+              <methodsynopsis>\r
+                <type>Pager&lt;T&gt;</type>\r
+\r
+                <methodname>page</methodname>\r
+\r
+                <methodparam>\r
+                  <type>Class&lt;? extends T&gt;</type>\r
+\r
+                  <parameter>clazz</parameter>\r
+                </methodparam>\r
+\r
+                <methodparam>\r
+                  <type>Integer</type>\r
+\r
+                  <parameter>pageSize</parameter>\r
+                </methodparam>\r
+\r
+                <methodparam>\r
+                  <type>Integer</type>\r
+\r
+                  <parameter>pageNumber</parameter>\r
+                </methodparam>\r
+\r
+                <methodparam>\r
+                  <type>List&lt;OrderHint&gt;</type>\r
+\r
+                  <parameter>orderHints</parameter>\r
+                </methodparam>\r
+\r
+                <methodparam>\r
+                  <type>List&lt;String&gt;</type>\r
+\r
+                  <parameter>propertyPaths</parameter>\r
+                </methodparam>\r
+              </methodsynopsis>\r
+            </entry>\r
+\r
+            <entry>\r
+              <para>Returns a paged (sub-)list of objects matching the type\r
+              <parameter>clazz</parameter>, sorted according to the order\r
+              hints and initialized according to the propertyPaths.</para>\r
+            </entry>\r
+          </row>\r
+\r
+          <row>\r
+            <entry>\r
+              <methodsynopsis>\r
+                <type>int</type>\r
+\r
+                <methodname>count</methodname>\r
+\r
+                <methodparam>\r
+                  <type>Class&lt;? extends T&gt;</type>\r
+\r
+                  <parameter>clazz</parameter>\r
+                </methodparam>\r
+              </methodsynopsis>\r
+            </entry>\r
+\r
+            <entry>\r
+              <para>Returns a count of objects matching the type\r
+              <parameter>clazz</parameter>.</para>\r
+            </entry>\r
+          </row>\r
+\r
+          <row>\r
+            <entry>\r
+              <methodsynopsis>\r
+                <type>T</type>\r
+\r
+                <methodname>find</methodname>\r
+\r
+                <methodparam>\r
+                  <type>UUID</type>\r
+\r
+                  <parameter>uuid</parameter>\r
+                </methodparam>\r
+              </methodsynopsis>\r
+            </entry>\r
+\r
+            <entry>\r
+              <para>Returns an object of type T matching the supplied uuid if\r
+              it exists.</para>\r
+            </entry>\r
+          </row>\r
+\r
+          <row>\r
+            <entry>\r
+              <methodsynopsis>\r
+                <type>Collection&lt;T&gt;</type>\r
+\r
+                <methodname>find</methodname>\r
+\r
+                <methodparam>\r
+                  <type>Collection&lt;UUID&gt;</type>\r
+\r
+                  <parameter>uuids</parameter>\r
+                </methodparam>\r
+              </methodsynopsis>\r
+            </entry>\r
+\r
+            <entry>\r
+              <para>Returns a collection of objects of type T matching the\r
+              uuids supplied, if they exist.</para>\r
+            </entry>\r
+          </row>\r
+\r
+          <row>\r
+            <entry>\r
+              <methodsynopsis>\r
+                <type>T</type>\r
+\r
+                <methodname>load</methodname>\r
+\r
+                <methodparam>\r
+                  <type>UUID</type>\r
+\r
+                  <parameter>uuid</parameter>\r
+                </methodparam>\r
+\r
+                <methodparam>\r
+                  <type>Collection&lt;String&gt;</type>\r
+\r
+                  <parameter>propertyPaths</parameter>\r
+                </methodparam>\r
+              </methodsynopsis>\r
+            </entry>\r
+\r
+            <entry>\r
+              <para>Returns an object of type T with properties initialized\r
+              according to the rules described below.</para>\r
+            </entry>\r
+          </row>\r
+\r
+          <row>\r
+            <entry>\r
+              <methodsynopsis>\r
+                <type>Set&lt;T&gt;</type>\r
+\r
+                <methodname>load</methodname>\r
+\r
+                <methodparam>\r
+                  <type>Collection&lt;UUID&gt;</type>\r
+\r
+                  <parameter>uuids</parameter>\r
+                </methodparam>\r
+\r
+                <methodparam>\r
+                  <type>Collection&lt;String&gt;</type>\r
+\r
+                  <parameter>propertyPaths</parameter>\r
+                </methodparam>\r
+              </methodsynopsis>\r
+            </entry>\r
+\r
+            <entry>\r
+              <para>Returns a collection of objects of type T matching the\r
+              uuids supplied, if they exist, initialized according to the\r
+              rules described below.</para>\r
+            </entry>\r
+          </row>\r
+\r
+          <row>\r
+            <entry>\r
+              <methodsynopsis>\r
+                <type>boolean</type>\r
+\r
+                <methodname>exists</methodname>\r
+\r
+                <methodparam>\r
+                  <type>UUID</type>\r
+\r
+                  <parameter>uuid</parameter>\r
+                </methodparam>\r
+              </methodsynopsis>\r
+            </entry>\r
+\r
+            <entry>\r
+              <para>Returns true if there is an object of type T in the\r
+              database matching the supplied uuid.</para>\r
+            </entry>\r
+          </row>\r
+\r
+          <row>\r
+            <entry>\r
+              <methodsynopsis>\r
+                <type>Class&lt;T&gt;</type>\r
+\r
+                <methodname>getType</methodname>\r
+              </methodsynopsis>\r
+            </entry>\r
+\r
+            <entry>\r
+              <para>Returns the class of objects that this Service provides\r
+              access to.</para>\r
+            </entry>\r
+          </row>\r
+        </tbody>\r
+      </tgroup>\r
+    </table>\r
+\r
+    <table frame="all" xml:id="iversionableservice-methods">\r
+      <title><interfacename>IVersionableService</interfacename>\r
+      methods</title>\r
+\r
+      <tgroup align="left" cols="2" colsep="1" rowsep="1">\r
+        <colspec colname="c1" />\r
+\r
+        <colspec colname="c2" />\r
+\r
+        <thead>\r
+          <row>\r
+            <entry>Method</entry>\r
+\r
+            <entry>Description</entry>\r
+          </row>\r
+        </thead>\r
+\r
+        <tbody>\r
+          <row>\r
+            <entry>\r
+              <methodsynopsis>\r
+                <type>Pager&lt;AuditEventRecord&lt;T&gt;&gt;</type>\r
+\r
+                <methodname>pageAuditEvents</methodname>\r
+\r
+                <methodparam>\r
+                  <type>T</type>\r
+\r
+                  <parameter>versionablentity</parameter>\r
+                </methodparam>\r
+\r
+                <methodparam>\r
+                  <type>Integer</type>\r
+\r
+                  <parameter>pageSize</parameter>\r
+                </methodparam>\r
+\r
+                <methodparam>\r
+                  <type>Integer</type>\r
+\r
+                  <parameter>pageNumber</parameter>\r
+                </methodparam>\r
+\r
+                <methodparam>\r
+                  <type>AuditEventSort</type>\r
+\r
+                  <parameter>sort</parameter>\r
+                </methodparam>\r
+              </methodsynopsis>\r
+            </entry>\r
+\r
+            <entry>\r
+              <para>Makes a new object persistent, or persists the state of a\r
+              transient object.</para>\r
+            </entry>\r
+          </row>\r
+\r
+          <row>\r
+            <entry>\r
+              <methodsynopsis>\r
+                <type>AuditEvent</type>\r
+\r
+                <methodname>getNextAuditEvent</methodname>\r
+\r
+                <methodparam>\r
+                  <type>T</type>\r
+\r
+                  <parameter>t</parameter>\r
+                </methodparam>\r
+              </methodsynopsis>\r
+            </entry>\r
+\r
+            <entry>\r
+              <para>Makes a collection of new objects persistent.</para>\r
+            </entry>\r
+          </row>\r
+\r
+          <row>\r
+            <entry>\r
+              <methodsynopsis>\r
+                <type>AuditEvent</type>\r
+\r
+                <methodname>getPreviousAuditEvent</methodname>\r
+\r
+                <methodparam>\r
+                  <type>T</type>\r
+\r
+                  <parameter>t</parameter>\r
+                </methodparam>\r
+              </methodsynopsis>\r
+            </entry>\r
+\r
+            <entry>\r
+              <para>Makes a new object persistent.</para>\r
+            </entry>\r
+          </row>\r
+\r
+          <row>\r
+            <entry>\r
+              <methodsynopsis>\r
+                <type>boolean</type>\r
+\r
+                <methodname>existed</methodname>\r
+\r
+                <methodparam>\r
+                  <type>UUID</type>\r
+\r
+                  <parameter>uuid</parameter>\r
+                </methodparam>\r
+              </methodsynopsis>\r
+            </entry>\r
+\r
+            <entry>\r
+              <para>Makes a new object persistent.</para>\r
+            </entry>\r
+          </row>\r
+        </tbody>\r
+      </tgroup>\r
+    </table>\r
+\r
+    <section>\r
+      <info>\r
+        <title>Paging Resultsets</title>\r
+      </info>\r
+\r
+      <para>In addition to being able to return results as a\r
+      <interfacename>java.util.List</interfacename>, service layer methods can\r
+      return results as a <interfacename>Pager</interfacename>. Pagers contain\r
+      a sublist of the total result set, plus a count of the total number of\r
+      matching objects. In addition, they contain a number of convenience\r
+      methods to facilitate the rendering of paged resultsets, including the\r
+      generation of labels for pages, based upon the matching objects.</para>\r
+    </section>\r
+  </section>\r
+</chapter>\r
diff --git a/src/docbkx/versioning.xml b/src/docbkx/versioning.xml
new file mode 100644 (file)
index 0000000..b89c13d
--- /dev/null
@@ -0,0 +1,274 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<chapter version="5.0" xml:id="versioning"
+         xmlns="http://docbook.org/ns/docbook"
+         xmlns:xlink="http://www.w3.org/1999/xlink"
+         xmlns:ns5="http://www.w3.org/1999/xhtml"
+         xmlns:ns4="http://www.w3.org/2000/svg"
+         xmlns:ns3="http://www.w3.org/1998/Math/MathML"
+         xmlns:ns="http://docbook.org/ns/docbook">
+  <info>
+    <title>Versioning</title>
+  </info>
+
+  <section>
+    <para>A significant use-case that the CDM aims to support is that of
+    web-based or networked nomenclators, taxonomic treatments, and other
+    applications that serve authoritative, dynamic data for (re-)use by
+    taxonomists and other software applications. As an example, a CDM store
+    containing a web-based monograph or revision of a particular plant or
+    animal family might be referenced by other taxonomists, or other taxonomic
+    databases that deal with the same taxa. To allow applications to record
+    and resolve changes to data over time, for example, to allow users or
+    client applications to determine how a taxonomic classification or species
+    page has been altered since they last accessed that information, the CDM
+    has a fine-grained versioning functionality that records changes to
+    objects and their relationships, and allows the prior state of the dataset
+    to be reconstructed.</para>
+
+    <para>The CDM uses <link
+    xlink:href="http://www.jboss.org/envers/">hibernate-envers</link>, a
+    versioning / auditing library that is part of the hibernate core library.
+    The versioning functionality is limited by the features that envers
+    provides. Envers stores changes to entities on a per-transaction basis.
+    Consequently, it is not possible to resolve changes that take place within
+    the same transaction. Each transaction results in the creation of an
+    <classname>AuditEvent</classname> object that provides metadata about the
+    audit event and also allows the state of the database at that point to be
+    reconstructed (because an <classname>AuditEvent</classname> represents a
+    point in time across the entire database, rather than on a per-object
+    basis). To learn more about envers and the way that it versions data,
+    check out the presentation given by its creator, Adam Warski <link
+    xlink:href="http://jboss.org/file-access/default/members/envers/downloads/presentations/envers_devoxx.pdf">here</link>.</para>
+
+    <para>Versioning is enabled by default, and calls to methods like
+    <methodname>save</methodname>, <methodname>update</methodname>, and
+    <methodname>delete</methodname>, will automatically result in data being
+    versioned. Application developers only need to be aware of the existence
+    of versioning when reading data, and only then if they wish to retrieve an
+    object in its prior state. If applications wish to retrieve objects from
+    the current state of the database, they do not need to perform any
+    additional operations. <methodname /></para>
+
+    <para>Because versions of objects are related to a global
+    <classname>AuditEvent</classname>, and because applications may call
+    several service layer methods when retrieving data for presentation in a
+    particular view, the CDM stores the <classname>AuditEvent</classname> in
+    the static field of an object called
+    <classname>AuditEventContextHolder</classname>, allowing the CDM and any
+    application code to discover which particular
+    <classname>AuditEvent</classname> a view relates to without needing to
+    pass the <classname>AuditEvent</classname> explicitly as a method
+    parameter (this pattern is borrows from the
+    <classname>SecurityContext</classname> class in Spring-Security).</para>
+
+    <para>To query the CDM at a particular <classname>AuditEvent</classname>,
+    applications need to place the <classname>AuditEvent</classname> in to the
+    <classname>AuditEventContextHolder</classname> and then call DAO methods
+    as usual.</para>
+
+    <programlisting>// This would retrieve the current version of the taxon with a matching uuid.
+Taxon taxon = taxonDao.find(uuid);
+
+// Set the audit event you're interested in
+AuditEventContextHolder.<emphasis>getContext</emphasis>().setAuditEvent(auditEvent);
+
+// This method call now retrieves the taxon with a matching uuid at the audit event in context
+// or null if the taxon did not exist at that point.
+Taxon taxon = taxonDao.find(uuid);
+
+// Now clear the context
+AuditEventContextHolder.<emphasis>clearContext</emphasis>();
+
+// Further calls to the persistence layer will return the most recent objects
+</programlisting>
+
+    <para>Not all DAO methods are available in non-current contexts, either
+    because they require certain methods that Envers doesn't currently support
+    (such as case-insensitive string comparison), or are across relationships
+    - currently envers does not support queries that place restrictions on
+    related entities. In some cases this will be addressed in future releases
+    of envers, and the CDM will incorporate these new releases as they occur.
+    Some methods rely on the free-text-search functionality provided by
+    hibernate search. Because hibernate search (and apache Lucene) are based
+    on an optimized set of index files that reflect the current state of the
+    database, it is not possible to search these indices at prior events. It
+    is unlikely that the free-text-search functionality will ever be available
+    in non-current contexts. If an application calls such a method in a
+    non-current context, an
+    <exceptionname>OperationNotSupportedInPriorViewException</exceptionname>
+    is thrown, giving applications an operation to recover.</para>
+
+    <para>Objects retrieved in prior contexts can be initialized using the
+    <parameter>propertyPaths</parameter> parameter, or (if the transaction is
+    still open) by calling accessor methods in domain objects directly (just
+    as you would with normal hibernate-managed entities).</para>
+
+    <para>In addition to being able to retrieve objects at a given state, the
+    DAOs implement the <interfacename>IVersionableDao</interfacename>
+    interface that offers five specific methods for working with versioned
+    objects.</para>
+
+    <table frame="all" xml:id="iversionabledao-methods">
+      <title><interfacename>IVersionableDao</interfacename> methods</title>
+
+      <tgroup align="left" cols="2" colsep="1" rowsep="1">
+        <colspec colname="c1" />
+
+        <colspec colname="c2" />
+
+        <thead>
+          <row>
+            <entry>Method</entry>
+
+            <entry>Description</entry>
+          </row>
+        </thead>
+
+        <tbody>
+          <row>
+            <entry>
+              <methodsynopsis>
+                <type>List&lt;AuditEventRecord&lt;T&gt;&gt;</type>
+
+                <methodname>getAuditEvents</methodname>
+
+                <methodparam>
+                  <type>T</type>
+
+                  <parameter>t</parameter>
+                </methodparam>
+
+                <methodparam>
+                  <type>Integer</type>
+
+                  <parameter>limit</parameter>
+                </methodparam>
+
+                <methodparam>
+                  <type>Integer</type>
+
+                  <parameter>start</parameter>
+                </methodparam>
+
+                <methodparam>
+                  <type>AuditEventSort</type>
+
+                  <parameter>sort</parameter>
+                </methodparam>
+
+                <methodparam>
+                  <type>List&lt;String&gt;</type>
+
+                  <parameter>propertyPaths</parameter>
+                </methodparam>
+              </methodsynopsis>
+            </entry>
+
+            <entry>
+              <para>Returns a list of audit events (in order) which affected
+              the state of an entity t. The events returned either start at
+              the <classname>AuditEvent</classname> in context and go forward
+              in time (<parameter>AuditEventSort.FORWARDS</parameter>) or
+              backwards in time
+              (<parameter>AuditEventSort.BACKWARDS</parameter>). If the
+              <classname>AuditEventContext</classname> is set to null, or to
+              <parameter>AuditEvent.CURRENT_VIEW</parameter>, then all
+              relevant AuditEvents are returned.</para>
+            </entry>
+          </row>
+
+          <row>
+            <entry>
+              <methodsynopsis>
+                <type>int</type>
+
+                <methodname>countAuditEvents</methodname>
+
+                <methodparam>
+                  <type>T</type>
+
+                  <parameter>t</parameter>
+                </methodparam>
+
+                <methodparam>
+                  <type>AuditEventSort</type>
+
+                  <parameter>sort</parameter>
+                </methodparam>
+              </methodsynopsis>
+            </entry>
+
+            <entry>
+              <para>Returns a count of audit events which affected the state
+              of an entity t.</para>
+            </entry>
+          </row>
+
+          <row>
+            <entry>
+              <methodsynopsis>
+                <type>AuditEventRecord&lt;T&gt;</type>
+
+                <methodname>getNextAuditEvent</methodname>
+
+                <methodparam>
+                  <type>T</type>
+
+                  <parameter>t</parameter>
+                </methodparam>
+              </methodsynopsis>
+            </entry>
+
+            <entry>
+              <para>A convenience method which returns a record of the next
+              (relative to the audit event in context).</para>
+            </entry>
+          </row>
+
+          <row>
+            <entry>
+              <methodsynopsis>
+                <type>AuditEventRecord&lt;T&gt;</type>
+
+                <methodname>getPreviousAuditEvent</methodname>
+
+                <methodparam>
+                  <type>T</type>
+
+                  <parameter>t</parameter>
+                </methodparam>
+              </methodsynopsis>
+            </entry>
+
+            <entry>
+              <para>A convenience method which returns a record of the
+              previous (relative to the audit event in context).</para>
+            </entry>
+          </row>
+
+          <row>
+            <entry>
+              <methodsynopsis>
+                <type>boolean</type>
+
+                <methodname>existed</methodname>
+
+                <methodparam>
+                  <type>UUID</type>
+
+                  <parameter>uuid</parameter>
+                </methodparam>
+              </methodsynopsis>
+            </entry>
+
+            <entry>
+              <para>Returns true if an object with uuid matching the one
+              supplied either currently exists, or existed previously and has
+              been deleted from the current view.</para>
+            </entry>
+          </row>
+        </tbody>
+      </tgroup>
+    </table>
+  </section>
+</chapter>