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

svn commit: r897662 - in /websites/staging/isis/trunk: cgi-bin/ content/ content/documentation.html content/reference/services/bulk-interaction.html content/reference/services/scratchpad.html content/reference/services/xmlsnapshot-service.html

Author: buildbot
Date: Wed Feb 12 18:38:07 2014
New Revision: 897662

Log:
Staging update by buildbot for isis

Modified:
    websites/staging/isis/trunk/cgi-bin/   (props changed)
    websites/staging/isis/trunk/content/   (props changed)
    websites/staging/isis/trunk/content/documentation.html
    websites/staging/isis/trunk/content/reference/services/bulk-interaction.html
    websites/staging/isis/trunk/content/reference/services/scratchpad.html
    websites/staging/isis/trunk/content/reference/services/xmlsnapshot-service.html

Propchange: websites/staging/isis/trunk/cgi-bin/
------------------------------------------------------------------------------
--- cms:source-revision (original)
+++ cms:source-revision Wed Feb 12 18:38:07 2014
@@ -1 +1 @@
-1567686
+1567713

Propchange: websites/staging/isis/trunk/content/
------------------------------------------------------------------------------
--- cms:source-revision (original)
+++ cms:source-revision Wed Feb 12 18:38:07 2014
@@ -1 +1 @@
-1567686
+1567713

Modified: websites/staging/isis/trunk/content/documentation.html
==============================================================================
--- websites/staging/isis/trunk/content/documentation.html (original)
+++ websites/staging/isis/trunk/content/documentation.html Wed Feb 12 18:38:07 2014
@@ -561,8 +561,8 @@
 
 <ul>
 <li><a href="./reference/services/bookmark-service.html">Bookmark Service</a></li>
-<li><a href="./reference/services/memento-service.html">Memento Service</a> [1.4.0-SNAPSHOT]</li>
-<li><a href="./reference/services/xmlsnapshot-service.html">XmlSnapshot Service</a> [1.4.0-SNAPSHOT, stub]
+<li><a href="./reference/services/memento-service.html">Memento Service</a> [1.4.0-snapshot]</li>
+<li><a href="./reference/services/xmlsnapshot-service.html">XmlSnapshot Service</a> [1.4.0-snapshot]
 </div>
 <div class="col-md-4"></li>
 </ul>
@@ -588,7 +588,7 @@
 <ul>
 <li><a href="./reference/services/query-results-cache.html">QueryResultsCache</a></li>
 <li><a href="./reference/services/scratchpad.html">Scratchpad</a></li>
-<li><a href="./reference/services/bulk-interaction.html">Bulk.Interaction</a> [stub]</li>
+<li><a href="./reference/services/bulk-interaction.html">Bulk.Interaction</a></li>
 </ul>
 
 <h4>Other:</h4>
@@ -614,7 +614,7 @@
 <li><a href="./reference/configuration-files.html">Configuration Files</a></li>
 </ul>
 
-<h4>Non-UI execution [1.4.0-SNAPSHOT]</h4>
+<h4>Non-UI execution [1.4.0-snapshot]</h4>
 
 <ul>
 <li><a href="./reference/non-ui/isis-session-template.html">IsisSessionTemplate</a></li>

Modified: websites/staging/isis/trunk/content/reference/services/bulk-interaction.html
==============================================================================
--- websites/staging/isis/trunk/content/reference/services/bulk-interaction.html (original)
+++ websites/staging/isis/trunk/content/reference/services/bulk-interaction.html Wed Feb 12 18:38:07 2014
@@ -282,12 +282,12 @@
 </h1>
 </div>
 
-<blockquote>
-  <p>this is a stub, see <a href="https://issues.apache.org/jira/browse/ISIS-655">ISIS-655</a></p>
-</blockquote>
+<p>The <code>Bulk.InteractionContext</code> domain service is a <a href="../../more-advanced-topics/how-to-09-020-How-to-write-a-typical-domain-service.html">request-scoped</a> service intended to support the implementation of <a href="../recognized-annotations/Bulk.html">@Bulk</a> actions.  That is, when a bulk action is invoked over a collection of objects, each object instance "knows where it is" in the collection.  In essence, the <code>Bulk.InteractionContext</code> service acts a little like an iterator.</p>
 
 <h3>API</h3>
 
+<p>The API defined by the service is:</p>
+
 <pre><code>@RequestScoped
 public static class InteractionContext {
 
@@ -300,67 +300,70 @@ public static class InteractionContext {
     public int getIndex() { ... }
     public boolean isFirst() { ... }
     public boolean isLast() { ... }
-
 }
+</code></pre>
 
+<p>where:</p>
 
-
-    /**
-     * Whether this particular {@link InteractionContext} was applied as a {@link InvokedAs#BULK bulk} action 
-     * (against each domain object in a list of domain objects) or as a {@link InvokedAs#REGULAR regular} 
-     * action (against a single domain object).
-     */
-    @Programmatic
-
-
-    /**
-     * The list of domain objects which are being acted upon.
-     */
-
-
-    /**
-     * The 0-based index to the object being acted upon.
-     * 
-     * &lt;p&gt;
-     * Will be a value in range [0, {@link #getSize() size}).
-     */
-</code></pre>
+<ul>
+<li><code>getInvokedAs()</code> tells the domain object whether this particular action invocation is being performed as a
+bulk action (against each domain object in a list of domain objects) or merely as a regular action (against 
+a single domain object).</li>
+<li><code>getDomainObjects())</code> returns the list of domain objects which are being acted upon</li>
+<li><code>getIndex()</code> is the 0-based index to the object being acted upon.</li>
+</ul>
 
 <h3>Usage</h3>
 
-<h3>Implementation</h3>
+<p>For bulk actions that are void or that return null, Isis will return to the list once executed.  But for bulk 
+actions that are non-void, Isis will render the returned object/value from the last object invoked (and simply 
+discards the object/value of all actions except the last).</p>
+
+<p>One idiom is for the domain objects to also use the <a href="./scratchpad.html">Scratchpad</a> service to share information,
+for example to aggregate values.  The <code>Bulk.InteractionContext#isLast()</code> method can then be used to determine if
+all the information has been gathered, and then do something with it (eg derive variance across a range of values, 
+render a graph etc).</p>
+
+<p>More prosaically, the <code>Bulk.InteractionContext</code> can be used to ensure that the bulk action behaves appropriately
+depending on whether it is called in bulk mode or regular mode.  Here's a snippet of code from the bulk action in 
+the <a href="../../intro/getting-started/quickstart-archetype.html">quickstart app</a>:</p>
+
+<pre><code>@Bulk
+public ToDoItem completed() {
+    setComplete(true);
+    ...        
+
+    // if invoked as a regular action, return this object;
+    // otherwise (if invoked as bulk), return null (so go back to the list)
+    return bulkInteractionContext.getInvokedAs() == InvokedAs.REGULAR? this: null;
+}
+</code></pre>
 
 <h3>Registering the Service</h3>
 
-<h3>Related Services</h3>
+<p>The <code>Bulk.InteractionContext</code> is a concrete class, so can be registered directly
+as a service in <code>isis.properties</code>:</p>
+
+<pre><code>isis.services=...,\
+              org.apache.isis.applib.annotation.Bulk.InteractionContext,\
+              ...
+</code></pre>
 
 <h3>Unit testing support</h3>
 
-<pre><code>@RequestScoped
-public static class InteractionContext {
+<p>The <code>Bulk.InteractionContext</code> class also has a couple of static factory 
+methods intended to support unit testing:</p>
 
+<pre><code>public static InteractionContext regularAction(Object domainObject) {
+    return new InteractionContext(InvokedAs.REGULAR, Collections.singletonList(domainObject));
+}
 
-    /**
-     * Intended only to support unit testing.
-     */
-    public static InteractionContext regularAction(Object domainObject) {
-        return new InteractionContext(InvokedAs.REGULAR, Collections.singletonList(domainObject));
-    }
-
-    /**
-     * Intended only to support unit testing.
-     */
-    public static InteractionContext bulkAction(Object... domainObjects) {
-        return bulkAction(Arrays.asList(domainObjects));
-    }
-
-    /**
-     * Intended only to support unit testing.
-     */
-    public static InteractionContext bulkAction(List&lt;Object&gt; domainObjects) {
-        return new InteractionContext(InvokedAs.BULK, domainObjects);
-    }
+public static InteractionContext bulkAction(Object... domainObjects) {
+    return bulkAction(Arrays.asList(domainObjects));
+}
 
+public static InteractionContext bulkAction(List&lt;Object&gt; domainObjects) {
+    return new InteractionContext(InvokedAs.BULK, domainObjects);
 }
 </code></pre>
 

Modified: websites/staging/isis/trunk/content/reference/services/scratchpad.html
==============================================================================
--- websites/staging/isis/trunk/content/reference/services/scratchpad.html (original)
+++ websites/staging/isis/trunk/content/reference/services/scratchpad.html Wed Feb 12 18:38:07 2014
@@ -367,10 +367,10 @@ public void injectScratchpad(Scratchpad 
 
 <h3>Registering the Service</h3>
 
-<p>Register like any other service in <code>isis.properties</code>:</p>
+<p>Register the concrete implementation (from isis-core) in <code>isis.properties</code>:</p>
 
 <pre><code>isis.services=...,\
-              com.mycompany.myapp.isis.SomeAuditingService,\
+              org.apache.isis.applib.services.scratchpad.Scratchpad,\
               ...
 </code></pre>
 

Modified: websites/staging/isis/trunk/content/reference/services/xmlsnapshot-service.html
==============================================================================
--- websites/staging/isis/trunk/content/reference/services/xmlsnapshot-service.html (original)
+++ websites/staging/isis/trunk/content/reference/services/xmlsnapshot-service.html Wed Feb 12 18:38:07 2014
@@ -332,9 +332,9 @@
 
 <h2>Usage</h2>
 
-<h3>Simple Usage</h3>
+<h3>Basic Usage</h3>
 
-<p>The simplest usage is:</p>
+<p>The most straight-forward usage of this service is simply:</p>
 
 <pre><code>XmlSnapshot snapshot = xmlsnapshotService.snapshotFor(customer);
 Element customerAsXml = snapshot.getXmlElement();
@@ -345,83 +345,47 @@ of the customer's value properties, alon
 
 <h3>Including other Elements</h3>
 
-<p>The contents of the snapshot can be adjusted by including "paths" to other references or collections.</p>
+<p>The contents of the snapshot can be adjusted by including "paths" to other references or collections.  To do this, the
+builder is used.  We start by obtaining a builder:</p>
 
-<p>For example, suppose that we want the snapshot to also include details of the customer's address, where <code>address</code> in this case
-is a reference property to an instance of the <code>Address</code> class.  We can "walk-the-graph" by including these references within
-the snapshot:</p>
-
-<pre><code>XmlSnapshot snapshot = xmlsnapshotService.snapshotFor(customer);
-...
-snapshot.include("address");
-...
-Element customerAsXml = snapshot.getXmlElement();
+<pre><code>XmlSnapshot.Builder builder = xmlsnapshotService.builderFor(customer);
 </code></pre>
 
-<p>Or, we could go further and include details of every order in the customer's <code>orders</code> collection, and details of every
-product of every order:</p>
+<p>Suppose now that we want the snapshot to also include details of the customer's address, where <code>address</code> in this case
+is a reference property to an instance of the <code>Address</code> class.  We can "walk-the-graph" by including these references within
+the builder.</p>
 
-<pre><code>...
-snapshot.include("orders/product"); // (2)
-...
+<pre><code>builder.includePath("address");
 </code></pre>
 
-<blockquote>
-  <p>As you might imagine, the resultant XML document can get quite large very quickly with only a few "include"s.</p>
-</blockquote>
-
-<h3>Using the Builder (fluent API)</h3>
-
-<p>An alternative way to build customized snapshots is to use the builder (fluent) API:</p>
+<p>We could then go further and include details of every order in the customer's <code>orders</code> collection, and details of every
+product of every order:</p>
 
-<pre><code>XmlSnapshot.Builder builder = xmlsnapshotService.builderFor(customer)
-                              .includePath("address")
-                              .includePath("orders/product");
-Element customerAsXml = builder.build().getXmlElement();
+<pre><code>builder.includePath("orders/product");
 </code></pre>
 
-<h4>Generating an XML Snapshot</h4>
-
-<p>The <code>XmlSnapshot</code> can be created either directly or using a builder.</p>
-
-<h4>Basic Usage</h4>
-
-<p>In order to use the <code>XmlSnapshot</code>, the domain object must implement <code>org.apache.isis.applib.snapshot.Snapshottable</code>. This is just a marker interface.</p>
-
-<h4>Including other Elements</h4>
-
-<p>It's also possible to instruct the <code>XmlSnapshot</code> to "walk" the object graph and include other information within the generated XML.</p>
-
-<p>For example:</p>
+<p>When all paths are included, then the builder can build the snapshot:</p>
 
-<pre><code>XmlSnapshot snapshot = new XmlSnapshot(customer);
-snapshot.include("placeOfBirth");   // (1)
-snapshot.include("orders/product"); // (2)
+<pre><code>XmlSnapshot snapshot = builder.build();
 Element customerAsXml = snapshot.getXmlElement();
 </code></pre>
 
-<p>In (1), we indicate that we want to also navigate to another domain object represented by simple reference <code>"placeOfBirth"</code>; in (2), we indicate that we want to navigate the <code>"orders"</code> collection (presumably of <code>Order</code>s) and for each referenced <code>Order</code>, to navigate in turn its <code>"product"</code> reference (presumably to a <code>Product</code> class).</p>
+<p>All of this can be strung together in a fluent API:</p>
 
-<p>Note that <code>XmlSnapshot</code> is mutable, in that calls to its <code>getXmlElement()</code> may return different XML structures based on whether additional paths have been <code>include()</code>d, or whether the state of the domain objects themselves have changed.</p>
-
-<h4>Using the Fluent API</h4>
-
-<p>An <code>XmlSnapshot</code> can also be constructed using an alternative "fluent" API:</p>
-
-<pre><code>XmlSnapshot snapshot = 
-     XmlSnapshot.create(customer)
-                .includePath("placeOfBirth")
-                .include("orders/product")
-                .build();
-Element customerAsXml = snapshot.getXmlElement();
+<pre><code>Element customerAsXml = xmlsnapshotService.builderFor(customer)
+                        .includePath("address")
+                        .includePath("orders/product")
+                        .build()
+                        .getXmlElement();
 </code></pre>
 
-<h4>The SnapshottableWithInclusions interface</h4>
+<blockquote>
+  <p>As you might imagine, the resultant XML document can get quite large very quickly with only a few "include"s.</p>
+</blockquote>
 
-<p>As already mentioned, in order to be snapshotted a domain object must implement the <code>Snapshottable</code> interface. This is just a marker interface, so implementing it is trivial.</p>
+<h4>Automatically including other elements</h4>
 
-<p>Alternatively, the domain object can choose to implement the
-sub-interface, <code>SnapshottableWithInclusions</code>. This moves the
+<p>If the domain object being snapshotted implements the <code>SnapshottableWithInclusions</code> interace, then this moves the
 responsibility for determining what is included within the snapshot from the caller to the snapshottable object itself:</p>
 
 <pre><code>public interface SnapshottableWithInclusions extends Snapshottable {
@@ -444,29 +408,26 @@ Element customerXsd = snapshot.getXsdEle
 
 <h3>Hints and Tips</h3>
 
-<p>As an alternative to using <code>include()</code>, you might consider building a non-persisted domain object (a "view model") which can reference only the relevant information required for the snapshot.</p>
+<p>As an alternative to using <code>include()</code>, you might consider building a view model domain object which can reference only the relevant information required for the snapshot.  For example, if only the 5 most recent Orders for a Customer were required, a <code>CustomerAndRecentOrders</code> view model could hold a collection of just those 5 <code>Order</code>s.  Typically such view models would implement <code>SnapshottableWithInclusions</code>.</p>
 
-<p>For example, if only the 5 most recent Orders for a Customer were required, a <code>CustomerAndRecentOrders</code> view model could hold a collection of just those 5 <code>Order</code>s.</p>
+<p>One reason for doing this is to provide a stable API between the domain model and whatever it is that might be consuming the XML.  With a view model you can refactor the domain entities but still preserve a view model such that the XML is the same.</p>
 
-<p>Typically such view models would implement <code>SnapshottableWithInclusions</code>.</p>
-
-<h3>Implementation</h3>
+<h3>Registering the Service</h3>
 
-<blockquote>
-  <p>TO DOCUMENT</p>
-</blockquote>
+<h2>Registering the services</h2>
 
-<h3>Registering the Service</h3>
+<p>Register the concrete implementation (from isis-core) in <code>isis.properties</code>:</p>
 
-<blockquote>
-  <p>TO DOCUMENT</p>
-</blockquote>
+<pre><code>isis.services=...,\
+              org.apache.isis.core.runtime.services.xmlsnapshot.XmlSnapshotServiceDefault,\
+              ...
+</code></pre>
 
 <h3>Related Services</h3>
 
-<blockquote>
-  <p>TO DOCUMENT</p>
-</blockquote>
+<p>The <a href="./memento-service.html">memento service</a> also provides a mechanism for generating string representations of domain objects.</p>
+
+<p>The <a href="./bookmark-service.html">bookmark service</a> provides a mechanism for obtaining a string representations of a single domain object.</p>