<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	xmlns:georss="http://www.georss.org/georss" xmlns:geo="http://www.w3.org/2003/01/geo/wgs84_pos#" xmlns:media="http://search.yahoo.com/mrss/"
	>

<channel>
	<title>Dan Haywood</title>
	<atom:link href="http://danhaywood.com/feed/" rel="self" type="application/rss+xml" />
	<link>http://danhaywood.com</link>
	<description>domain driven design, restful objects, apache isis, the naked objects pattern, agile and more</description>
	<lastBuildDate>Sat, 19 May 2012 08:20:59 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.com/</generator>
<cloud domain='danhaywood.com' port='80' path='/?rsscloud=notify' registerProcedure='' protocol='http-post' />
<image>
		<url>http://1.gravatar.com/blavatar/b1eb53d82980ace193f5d50c92bc059d?s=96&#038;d=http%3A%2F%2Fs2.wp.com%2Fi%2Fbuttonw-com.png</url>
		<title>Dan Haywood</title>
		<link>http://danhaywood.com</link>
	</image>
	<atom:link rel="search" type="application/opensearchdescription+xml" href="http://danhaywood.com/osd.xml" title="Dan Haywood" />
	<atom:link rel='hub' href='http://danhaywood.com/?pushpress=hub'/>
		<item>
		<title>Fail a Maven build when conflicting or unused dependencies</title>
		<link>http://danhaywood.com/2012/05/10/fail-a-maven-build-when-conflicting-or-unused-dependencies/</link>
		<comments>http://danhaywood.com/2012/05/10/fail-a-maven-build-when-conflicting-or-unused-dependencies/#comments</comments>
		<pubDate>Thu, 10 May 2012 17:48:23 +0000</pubDate>
		<dc:creator>danhaywood</dc:creator>
				<category><![CDATA[maven]]></category>

		<guid isPermaLink="false">http://danhaywood.com/?p=970</guid>
		<description><![CDATA[Currently teaching my Maven course, and a couple of questions have come up about how to fail a build when a pom either has conflicting dependencies, or has (through a smidge too much copy-n-paste) even just unused dependencies. Good questions both. For the first of these, dependency conflicts, we can use the enforcer plugin. Add [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=danhaywood.com&#038;blog=25721749&#038;post=970&#038;subd=danhaywood&#038;ref=&#038;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>
Currently teaching my Maven course, and a couple of questions have come up about how to fail a build when a pom either has conflicting dependencies, or has (through a smidge too much copy-n-paste) even just unused dependencies.  Good questions both.</p>
<p>
For the first of these, dependency conflicts, <span id="more-970"></span> we can use the enforcer plugin.  Add the following to your POM:</p>
<p><pre class="brush: xml;">
&lt;build&gt;
  &lt;plugins&gt;
    &lt;plugin&gt;
      &lt;groupId&gt;org.apache.maven.plugins&lt;/groupId&gt;
      &lt;artifactId&gt;maven-enforcer-plugin&lt;/artifactId&gt;
      &lt;version&gt;1.0.1&lt;/version&gt;
      &lt;executions&gt;
        &lt;execution&gt;
          &lt;id&gt;validate-enforce&lt;/id&gt;
          &lt;configuration&gt;
            &lt;rules&gt; 
               &lt;DependencyConvergence /&gt;
            &lt;/rules&gt;
          &lt;/configuration&gt;
          &lt;phase&gt;validate&lt;/phase&gt;
          &lt;goals&gt; 
            &lt;goal&gt;enforce&lt;/goal&gt;
          &lt;/goals&gt;
        &lt;/execution&gt;
      &lt;/executions&gt;
    &lt;/plugin&gt;
    ... other plugins ...
  &lt;/plugins&gt;
&lt;/build&gt;
</pre></p>
<p>
This binds the enforcer:enforce goal to the validate phase, ie right at the beginning of the build of each project (or submodule, if an aggregator project).  Any conflicts for that project/submodule, and the build will break.</p>
<p>
For the other case, unused dependencies, we can use the dependency:analyze-only goal:</p>
<p><pre class="brush: xml;">
&lt;build&gt;
  &lt;plugins&gt;
    &lt;plugin&gt;
      &lt;groupId&gt;org.apache.maven.plugins&lt;/groupId&gt;
      &lt;artifactId&gt;maven-dependency-plugin&lt;/artifactId&gt;
      &lt;version&gt;2.4&lt;/version&gt;
      &lt;configuration&gt;
        &lt;failOnWarning&gt;true&lt;/failOnWarning&gt;
      &lt;/configuration&gt;
      &lt;executions&gt;
        &lt;execution&gt;
          &lt;id&gt;process-test-classes-dependency-analyze&lt;/id&gt;
          &lt;!-- needs all code to be compiled --&gt;
          &lt;phase&gt;process-test-classes&lt;/phase&gt;
          &lt;goals&gt;
            &lt;goal&gt;analyze-only&lt;/goal&gt;
          &lt;/goals&gt;
        &lt;/execution&gt;
      &lt;/executions&gt;
    &lt;/plugin&gt;

    ... other plugins ...
  &lt;/plugins&gt;
&lt;/build&gt;
</pre></p>
<p>
There is one tiny oddity here; we want to do the analysis as soon as we can, but the plugin does require that code and test code is compiled.  The next phase on from test-compile is the process-test-classes, which runs directly before the test phase.  The execution binding above ensures that we do the dependency analysis without having to wait for unit tests to run (ie we &#8220;fail as early as we can&#8221;).</p>
<p>
If you use a corporate POM (one that every project&#8217;s POM would use as its parent), then you could consider moving both of these configurations up into it.  That would then allow you to enforce these rules across all projects.</p>
<br />Filed under: <a href='http://danhaywood.com/category/random/maven/'>maven</a>  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/danhaywood.wordpress.com/970/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/danhaywood.wordpress.com/970/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/danhaywood.wordpress.com/970/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/danhaywood.wordpress.com/970/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/danhaywood.wordpress.com/970/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/danhaywood.wordpress.com/970/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/danhaywood.wordpress.com/970/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/danhaywood.wordpress.com/970/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/danhaywood.wordpress.com/970/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/danhaywood.wordpress.com/970/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/danhaywood.wordpress.com/970/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/danhaywood.wordpress.com/970/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/danhaywood.wordpress.com/970/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/danhaywood.wordpress.com/970/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=danhaywood.com&#038;blog=25721749&#038;post=970&#038;subd=danhaywood&#038;ref=&#038;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://danhaywood.com/2012/05/10/fail-a-maven-build-when-conflicting-or-unused-dependencies/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/204ef8a2259ebe0716f985f96c1c350d?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">danhaywood</media:title>
		</media:content>
	</item>
		<item>
		<title>Further work on the Restful Objects spec.</title>
		<link>http://danhaywood.com/2012/04/29/further-work-on-the-restful-objects-spec/</link>
		<comments>http://danhaywood.com/2012/04/29/further-work-on-the-restful-objects-spec/#comments</comments>
		<pubDate>Sun, 29 Apr 2012 15:47:32 +0000</pubDate>
		<dc:creator>danhaywood</dc:creator>
				<category><![CDATA[restful objects]]></category>

		<guid isPermaLink="false">http://danhaywood.com/?p=964</guid>
		<description><![CDATA[The Restful Objects spec &#8211; a hypermedia API for domain objects models &#8211; is getting ever closer to a v1.0.0 release. Right now it&#8217;s at 0.69.0 (pdf) (yes, there have actually been 69 versions, though some of the earliest ones are lost in the mists&#8230;) Recent changes have brought in: namespaced rel links the concept [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=danhaywood.com&#038;blog=25721749&#038;post=964&#038;subd=danhaywood&#038;ref=&#038;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>The <a href="http://restfulobjects.org" target="_blank">Restful Objects spec</a> &#8211; a hypermedia API for domain objects models &#8211; is getting ever closer to a v1.0.0 release.  Right now it&#8217;s at <a href="https://bitbucket.org/danhaywood/restfulobjects-spec/src/1b5e7960907a/restfulobjects-spec.pdf" title="Restful Objects PDF, v0.69.0">0.69.0 (pdf)</a> (yes, there have actually been 69 versions, though some of the earliest ones are lost in the mists&#8230;)</p>
<p><span id="more-964"></span><br />
Recent changes have brought in:</p>
<ul>
<li>namespaced rel links</li>
<li>the concept of addressable view models (a key part of supporting conneg)</li>
<li>a slight change in the URL format so that the object&#8217;s domain type is no longer considered opaque</li>
<li> deferral of some more advanced features such as paging and sorting and eager following of links (these will be added back in at a later date, for now they have moved to the &#8216;discussions&#8217; chapters at the end)</li>
<li><a href="http://semver.org" target="_blank">semantic versioning</a> of the spec itself</li>
</ul>
<p>There&#8217;s a reasonably complete change history in the doc itself.</p>
<p>The current state of implementations varies.  <a href="http://restfulobjects.codeplex.com" target="_blank">Restful Objects for .NET</a> has been tracking the spec closely, and is almost feature complete.  On the Java platform, <a href="http://incubator.apache.org/isis" target="_blank">Restful Objects for Isis</a> (as I&#8217;m now calling it) hasn&#8217;t moved on very much &#8211; it&#8217;s still back at v0.56 or thereabouts.  Such time as I&#8217;ve had has been working on the spec itself, rather than the Isis implementation.</p>
<p>Anyway, any feedback welcome as ever.</p>
<br />Filed under: <a href='http://danhaywood.com/category/restful-objects/'>restful objects</a>  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/danhaywood.wordpress.com/964/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/danhaywood.wordpress.com/964/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/danhaywood.wordpress.com/964/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/danhaywood.wordpress.com/964/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/danhaywood.wordpress.com/964/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/danhaywood.wordpress.com/964/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/danhaywood.wordpress.com/964/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/danhaywood.wordpress.com/964/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/danhaywood.wordpress.com/964/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/danhaywood.wordpress.com/964/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/danhaywood.wordpress.com/964/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/danhaywood.wordpress.com/964/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/danhaywood.wordpress.com/964/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/danhaywood.wordpress.com/964/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=danhaywood.com&#038;blog=25721749&#038;post=964&#038;subd=danhaywood&#038;ref=&#038;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://danhaywood.com/2012/04/29/further-work-on-the-restful-objects-spec/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/204ef8a2259ebe0716f985f96c1c350d?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">danhaywood</media:title>
		</media:content>
	</item>
		<item>
		<title>Updating Visual Studio project references from NuGet packages.config (2)</title>
		<link>http://danhaywood.com/2012/04/04/updating-visual-studio-project-references-from-nuget-packages-config-2/</link>
		<comments>http://danhaywood.com/2012/04/04/updating-visual-studio-project-references-from-nuget-packages-config-2/#comments</comments>
		<pubDate>Wed, 04 Apr 2012 14:22:33 +0000</pubDate>
		<dc:creator>danhaywood</dc:creator>
				<category><![CDATA[powershell]]></category>

		<guid isPermaLink="false">http://danhaywood.com/?p=960</guid>
		<description><![CDATA[Here&#8217;s a small refinement to the script I wrote a while back to update VS project references from the packages.config file: You can then use it to update selected packages, eg: Filed under: powershell<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=danhaywood.com&#038;blog=25721749&#038;post=960&#038;subd=danhaywood&#038;ref=&#038;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>Here&#8217;s a small refinement to the script I wrote a while back to update VS project references from the packages.config file:</p>
<p><pre class="brush: powershell;">
function Sync-References([string]$PackageId) {
  get-project -all | %{
    Write-Host $proj.name; 
    $proj = $_ ;
    get-package -project $proj.name | ? { $_.id -match $PackageId } | % { 
      Write-Host $_.id; 
      uninstall-package -projectname $proj.name -id $_.id -version $_.version -RemoveDependencies -force ;
      install-package -projectname $proj.name -id $_.id -version $_.version
    }
  }
}
</pre></p>
<p>You can then use it to update selected packages, eg:</p>
<p><pre class="brush: powershell;">
Sync-References FluentAssertions
</pre></p>
<br />Filed under: <a href='http://danhaywood.com/category/random/powershell/'>powershell</a>  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/danhaywood.wordpress.com/960/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/danhaywood.wordpress.com/960/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/danhaywood.wordpress.com/960/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/danhaywood.wordpress.com/960/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/danhaywood.wordpress.com/960/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/danhaywood.wordpress.com/960/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/danhaywood.wordpress.com/960/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/danhaywood.wordpress.com/960/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/danhaywood.wordpress.com/960/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/danhaywood.wordpress.com/960/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/danhaywood.wordpress.com/960/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/danhaywood.wordpress.com/960/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/danhaywood.wordpress.com/960/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/danhaywood.wordpress.com/960/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=danhaywood.com&#038;blog=25721749&#038;post=960&#038;subd=danhaywood&#038;ref=&#038;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://danhaywood.com/2012/04/04/updating-visual-studio-project-references-from-nuget-packages-config-2/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/204ef8a2259ebe0716f985f96c1c350d?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">danhaywood</media:title>
		</media:content>
	</item>
		<item>
		<title>Apache Isis refactorings</title>
		<link>http://danhaywood.com/2012/03/25/apache-isis-refactorings/</link>
		<comments>http://danhaywood.com/2012/03/25/apache-isis-refactorings/#comments</comments>
		<pubDate>Sun, 25 Mar 2012 17:43:45 +0000</pubDate>
		<dc:creator>danhaywood</dc:creator>
				<category><![CDATA[apache isis]]></category>
		<category><![CDATA[domain driven design]]></category>
		<category><![CDATA[isis]]></category>

		<guid isPermaLink="false">http://danhaywood.com/?p=945</guid>
		<description><![CDATA[For the last week or two I&#8217;ve been doing some refactoring deep in the bowels of Apache Isis, working on simplifying some of the infrastructure there. One of the major changes in the next release to enable this is that we&#8217;re going to ditch the client/server &#8220;remoting&#8221; support. Although this was important feature when originally [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=danhaywood.com&#038;blog=25721749&#038;post=945&#038;subd=danhaywood&#038;ref=&#038;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>For the last week or two I&#8217;ve been doing some refactoring deep in the bowels of <a href="http://incubator.apache.org/isis" target="_blank">Apache Isis</a>, working on simplifying some of the infrastructure there.</p>
<p>One of the major changes in the next release <span id="more-945"></span>to enable this is that we&#8217;re going to ditch the client/server &#8220;remoting&#8221; support. Although this was important feature when originally implemented (the big Irish government system that runs on Naked Objects is deployed in this configuration), it adds a heck of a lot of complexity and is increasingly less important in these days of Ajax, rich web apps, REST and mobile. So&#8230; the client/server support is being removed. As a by-the-by, that will mean that the original drag-n-drop viewer will be demoted<br />
for use either in very simple single-user systems, or just as a prototyping and design tool.</p>
<p>Another, more technical, reason for that dropping the client/server remoting is important is that it allows the OIDs to become immutable. In Isis every domain object is wrapped in an &#8220;adapter&#8221;, which is the link into the Isis metamodel and which also keeps track of whether the object has been resolved from the object store. Each adapter is identified by an OID; in other words the OID is an object identifiers that act as keys to every object that is managed by Isis.</p>
<p>Now, with client/server, a lot of the complexity arose because it was necessary to track the persistence state of an object across the client and server. And this was done by having the OID as being mutable, keeping track of the previous OID (when the object was transient) and its current OID. With this requirement gone, OIDs can become immutable.</p>
<p>I&#8217;ve also taken the opportunity to simplify the OID hierarchy. In the original design of Isis, every object store implementation was responsible for defining its own OIDs. So the in-memory object store has a very simple OID, whereas the NoSQL and SQL object stores&#8217; implementations are rather more complex. Fundamentally, though, all that an OID needs to do is to identify the class of an object, and its unique identity within that type.</p>
<p>The Irish government system has an OID that can be converted to a string, and this has proven really useful for scenarios such as publish/subscribe. For example, CUS|1234567A identifies a customer with a unique id of 1234567A. The format of the identifier varies; for some types it is multiple components (usually corresponding to a composite primary key in a database table).</p>
<p>So, the simpler design that I&#8217;m working to is that a single Oid implementation has an object type (&#8220;CUS&#8221;) and a (string) identifier. The object store is responsible for creating and interpreting this identifier, but the OID implementation itself is fixed. So, basically, an Oid is just a value object of two strings: CUS|1234567A. Much simpler!</p>
<p>Of course, I lie. In fact, we need to distinguish between the Oid of a standalone entity (in DDD jargon, the root of an aggregate), and the Oid of an aggregated entity (one that is owned by the root). The canonical example is always Order/OrderLine, but equally one could have a Customer/Name or &#8211; perhaps &#8211; Customer/Address. So, in fact root entities have a RootOid (as described above), while aggregate entities have an AggregatedOid. An AggregatedOid consists of a reference to the parent Oid, along with an identifier that is (at least) unique within the aggregate.</p>
<p>In Isis there is another type of object that also gets its own OID, namely the List/Set instances that manage the &#8220;internal&#8221; collections. These have an adapter because we need to support lazy loading; rather than introducing a proxy collecioon object, the adapter keeps track of whether the collection have been retrieved from the object store or not.</p>
<p>So, the full set of OIDs are:<br />
- Oid as a top-level interface<br />
- RootOid, as an implementation for aggregate roots<br />
- AggregatedOid, as an implementation for aggregated entities<br />
- CollectionOid, as an implementaion for List/Set instances.</p>
<p>To illustrate all this, consider the following classes:</p>
<p><pre class="brush: java;">
public class Customer {
  private Name name;
  public Name getName() { ... }
  public void setName(Name n) { ... }

  private Address billingAddress;
  @Aggregated
  public Address getBillingAddress() { ... }
  public void setBillingAddress(Address a) { ... }

  private Order mostRecentOrder;
  public Order getMostRecentOrder() { ... }
  public void setMostRecentOrder(Order o) { ... }

  private List&lt;Name&gt; previousNames = Lists.newArrayList();
  public List&lt;Name&gt; getPreviousNames() { ... }
  public void setPreviousNames(List&lt;Name&gt; n) { ... }

  public List&lt;Address&gt; shipToAddresses = Lists.newArrayList();
  @Aggregated
  public List&lt;Address&gt; getShipToAddresses() { ... }
  public void setShipToAddresses(List&amp;lt;Address&gt; a) { ... }

  private List&lt;Order&gt; orders = Lists.newArrayList();
  public List&lt;Order&gt; getOrders() { ... }
  public void setOrders(List&lt;Order&gt; o) { ... }
}
</pre></p>
<p>Here, the Name class is always intended to be aggregated (irrespective of context); it is thus annotated as @Aggregated:</p>
<p><pre class="brush: xml;">
@Aggregated
public class Name {
...
}
</pre></p>
<p>
The Address class, meanwhile, may be aggregated in some contexts, but not in others. Therefore the class is not aggregated:</p>
<p><pre class="brush: xml;">
public class Address {
...
}
</pre></p>
<p>However, as you can see from the Customer&#8217;s billingAddress property and shipToAddresses collections, these references are annotated with @Aggregated. Therefore, for Customer at least, Address is part of its aggregate.</p>
<p>Finally, we have Order:</p>
<p><pre class="brush: xml;">
public class Order {
...
}
</pre></p>
<p>This is not annotated with @Aggregated, and its references from Customer also have no @Aggregate annoation. Each Order is therefore is its own aggregate root.</p>
<p>
And the following object instance diagram shows what would be going on inside of Isis:</p>
<p><a href="http://danhaywood.files.wordpress.com/2012/03/oids.png"><img src="http://danhaywood.files.wordpress.com/2012/03/oids.png?w=604&h=453" alt="" title="Object Adapters and OIDs in Apache Isis" width="604" height="453" class="aligncenter size-full wp-image-947" /></a></p>
<br />Filed under: <a href='http://danhaywood.com/category/naked-objects-pattern/apache-isis/'>apache isis</a>, <a href='http://danhaywood.com/category/domain-driven-design/'>domain driven design</a>  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/danhaywood.wordpress.com/945/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/danhaywood.wordpress.com/945/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/danhaywood.wordpress.com/945/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/danhaywood.wordpress.com/945/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/danhaywood.wordpress.com/945/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/danhaywood.wordpress.com/945/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/danhaywood.wordpress.com/945/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/danhaywood.wordpress.com/945/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/danhaywood.wordpress.com/945/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/danhaywood.wordpress.com/945/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/danhaywood.wordpress.com/945/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/danhaywood.wordpress.com/945/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/danhaywood.wordpress.com/945/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/danhaywood.wordpress.com/945/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=danhaywood.com&#038;blog=25721749&#038;post=945&#038;subd=danhaywood&#038;ref=&#038;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://danhaywood.com/2012/03/25/apache-isis-refactorings/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/204ef8a2259ebe0716f985f96c1c350d?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">danhaywood</media:title>
		</media:content>

		<media:content url="http://danhaywood.files.wordpress.com/2012/03/oids.png" medium="image">
			<media:title type="html">Object Adapters and OIDs in Apache Isis</media:title>
		</media:content>
	</item>
		<item>
		<title>Restful Objects (.NET) screencasts</title>
		<link>http://danhaywood.com/2012/03/09/restfulobjects_net_screencasts/</link>
		<comments>http://danhaywood.com/2012/03/09/restfulobjects_net_screencasts/#comments</comments>
		<pubDate>Fri, 09 Mar 2012 17:12:29 +0000</pubDate>
		<dc:creator>danhaywood</dc:creator>
				<category><![CDATA[apache isis]]></category>
		<category><![CDATA[restful objects]]></category>
		<category><![CDATA[isis]]></category>
		<category><![CDATA[restful]]></category>
		<category><![CDATA[ronet]]></category>
		<category><![CDATA[screencast]]></category>

		<guid isPermaLink="false">http://danhaywood.com/?p=933</guid>
		<description><![CDATA[For those interested in the work I&#8217;ve been doing on Restful Objects, you might be interested to see that Richard Pawson has recorded some screencasts on the .NET implementation of Restful Objects. I&#8217;ve linked to them from the Restful Objects website. The Apache Isis impl of Restful Objects currently lags behind the .NET impl, though [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=danhaywood.com&#038;blog=25721749&#038;post=933&#038;subd=danhaywood&#038;ref=&#038;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>For those interested in the work I&#8217;ve been doing on <a href="http://restfulobjects.org" target="_blank">Restful Objects</a>, you might be interested to see that Richard Pawson has recorded some screencasts on the <a href="http://restfulobjects.codeplex.com" target="_blank">.NET implementation</a> of Restful Objects.</p>
<p>I&#8217;ve linked to them from the <a href="http://restfulobjects.org/screencasts/" target="_blank">Restful Objects website</a>.</p>
<p>The <a href="http://incubator.apache.org/isis" target="_blank">Apache Isis</a> impl of Restful Objects currently lags behind the .NET impl, though not too far behind.  Check out <a href="http://mmyco.co.uk:8180/isis-onlinedemo" target="_blank">Isis&#8217; online demo</a> to see the current state.</p>
<br />Filed under: <a href='http://danhaywood.com/category/naked-objects-pattern/apache-isis/'>apache isis</a>, <a href='http://danhaywood.com/category/restful-objects/'>restful objects</a>  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/danhaywood.wordpress.com/933/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/danhaywood.wordpress.com/933/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/danhaywood.wordpress.com/933/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/danhaywood.wordpress.com/933/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/danhaywood.wordpress.com/933/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/danhaywood.wordpress.com/933/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/danhaywood.wordpress.com/933/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/danhaywood.wordpress.com/933/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/danhaywood.wordpress.com/933/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/danhaywood.wordpress.com/933/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/danhaywood.wordpress.com/933/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/danhaywood.wordpress.com/933/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/danhaywood.wordpress.com/933/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/danhaywood.wordpress.com/933/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=danhaywood.com&#038;blog=25721749&#038;post=933&#038;subd=danhaywood&#038;ref=&#038;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://danhaywood.com/2012/03/09/restfulobjects_net_screencasts/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/204ef8a2259ebe0716f985f96c1c350d?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">danhaywood</media:title>
		</media:content>
	</item>
		<item>
		<title>Apache Isis 0.2.0-incubating released</title>
		<link>http://danhaywood.com/2012/02/27/apache-isis-0-2-0-incubating-released/</link>
		<comments>http://danhaywood.com/2012/02/27/apache-isis-0-2-0-incubating-released/#comments</comments>
		<pubDate>Mon, 27 Feb 2012 08:36:48 +0000</pubDate>
		<dc:creator>danhaywood</dc:creator>
				<category><![CDATA[apache isis]]></category>
		<category><![CDATA[domain driven design]]></category>

		<guid isPermaLink="false">http://danhaywood.com/?p=928</guid>
		<description><![CDATA[Just a quick announcement that last week we put out our second release of Apache Isis from the incubator, namely 0.2.0-incubating. The main theme in this release is to try to simplify things a little, so that would-be users can more easily grok what Isis is about: We&#8217;ve updated the website, hopefully explaining better what [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=danhaywood.com&#038;blog=25721749&#038;post=928&#038;subd=danhaywood&#038;ref=&#038;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>Just a quick announcement that last week we put out our second release of <a href="http://incubator.apache.org/isis" title="Apache Isis (incubating)" target="_blank">Apache Isis</a> from the incubator, namely 0.2.0-incubating.</p>
<p>The main theme in this release is to try to simplify things a little, so that would-be users can more easily grok what Isis is about:<br />
<span id="more-928"></span></p>
<ul>
<li>We&#8217;ve updated the website, hopefully explaining better what Isis is and what use cases it hits.</li>
<li>we now have the <a href="http://mmyco.co.uk:8180/isis-onlinedemo" title="Isis online demo" target="_blank">online demo</a> linked directly from the website.</li>
<li>the archetype has also been reworked; rather than have a module for each of the viewers, we&#8217;ve reduced the number of viewers (just HTML viewer and JSON viewer) and put them into a single webapp module.</li>
</ul>
<p>You can read full release notes <a href="http://incubator.apache.org/isis/release-notes-0.2.0-incubating.html" title="Isis 0.2.0-incubating" target="_blank">here</a>.</p>
<p>And, as for all Isis releases, the release can be found in the <a href="http://search.maven.org" target="_blank">Maven central repo</a>, you can use the Maven archetype to create a <a href="http://incubator.apache.org/isis/quick-start.html" target="_blank">quickstart app</a>, or you can <a href="http://incubator.apache.org/isis/downloads.html" target="_blank">download the release</a> and build it from source.</p>
<p>By the way, work is well under way on the next release, where the plan is to re-introduce the Scimpi viewer to the archetype, and also to bring in NoSQL (MongoDB) support.</p>
<br />Filed under: <a href='http://danhaywood.com/category/naked-objects-pattern/apache-isis/'>apache isis</a>, <a href='http://danhaywood.com/category/domain-driven-design/'>domain driven design</a>  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/danhaywood.wordpress.com/928/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/danhaywood.wordpress.com/928/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/danhaywood.wordpress.com/928/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/danhaywood.wordpress.com/928/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/danhaywood.wordpress.com/928/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/danhaywood.wordpress.com/928/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/danhaywood.wordpress.com/928/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/danhaywood.wordpress.com/928/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/danhaywood.wordpress.com/928/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/danhaywood.wordpress.com/928/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/danhaywood.wordpress.com/928/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/danhaywood.wordpress.com/928/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/danhaywood.wordpress.com/928/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/danhaywood.wordpress.com/928/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=danhaywood.com&#038;blog=25721749&#038;post=928&#038;subd=danhaywood&#038;ref=&#038;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://danhaywood.com/2012/02/27/apache-isis-0-2-0-incubating-released/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/204ef8a2259ebe0716f985f96c1c350d?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">danhaywood</media:title>
		</media:content>
	</item>
		<item>
		<title>Restful Objects spec v0.60</title>
		<link>http://danhaywood.com/2012/02/12/restful-objects-spec-v0-60/</link>
		<comments>http://danhaywood.com/2012/02/12/restful-objects-spec-v0-60/#comments</comments>
		<pubDate>Sun, 12 Feb 2012 18:57:26 +0000</pubDate>
		<dc:creator>danhaywood</dc:creator>
				<category><![CDATA[restful objects]]></category>

		<guid isPermaLink="false">http://danhaywood.com/?p=925</guid>
		<description><![CDATA[Work continues on the Restful Objects spec, which aims to define a set of RESTful resources, and corresponding representations, for accessing and manipulating a domain object model. Recent significant changes include a full description of how to use view models to encapsulate the domain entities while preserving the RESTful HATEOAS principle, and support support for [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=danhaywood.com&#038;blog=25721749&#038;post=925&#038;subd=danhaywood&#038;ref=&#038;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>Work continues on the <a href="http://restfulobjects.org" title="Restful Objects specification" target="_blank">Restful Objects</a> spec, which aims to define a set of RESTful resources, and corresponding<br />
representations, for accessing and manipulating a domain object model.</p>
<p>
Recent significant changes include a full description of how to use view models to encapsulate the domain entities while preserving the RESTful HATEOAS principle, and support support for blobs/clobs, in other words media types such as application/pdf, image/jpeg etc.</p>
<p>
Feedback always welcome.</p>
<br />Filed under: <a href='http://danhaywood.com/category/restful-objects/'>restful objects</a>  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/danhaywood.wordpress.com/925/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/danhaywood.wordpress.com/925/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/danhaywood.wordpress.com/925/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/danhaywood.wordpress.com/925/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/danhaywood.wordpress.com/925/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/danhaywood.wordpress.com/925/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/danhaywood.wordpress.com/925/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/danhaywood.wordpress.com/925/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/danhaywood.wordpress.com/925/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/danhaywood.wordpress.com/925/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/danhaywood.wordpress.com/925/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/danhaywood.wordpress.com/925/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/danhaywood.wordpress.com/925/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/danhaywood.wordpress.com/925/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=danhaywood.com&#038;blog=25721749&#038;post=925&#038;subd=danhaywood&#038;ref=&#038;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://danhaywood.com/2012/02/12/restful-objects-spec-v0-60/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/204ef8a2259ebe0716f985f96c1c350d?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">danhaywood</media:title>
		</media:content>
	</item>
		<item>
		<title>Filters don&#8217;t fire when bouncing off web.xml for error handling</title>
		<link>http://danhaywood.com/2012/02/10/filters-dont-fire-when-bouncing-off-web-xml-for-error-handling/</link>
		<comments>http://danhaywood.com/2012/02/10/filters-dont-fire-when-bouncing-off-web-xml-for-error-handling/#comments</comments>
		<pubDate>Fri, 10 Feb 2012 22:25:36 +0000</pubDate>
		<dc:creator>danhaywood</dc:creator>
				<category><![CDATA[java]]></category>

		<guid isPermaLink="false">http://danhaywood.com/?p=917</guid>
		<description><![CDATA[Here&#8217;s a nice little gotcha for ya! A fairly common pattern is to use a filter that wraps the (Http)ServletRequest and (Http)ServletResponse in an app-specific wrapper; this can be used to hold user credentials and state etc. In essence it is: where and AppResponse similarly subclasses from HttpServletResponseWrapper. But let&#8217;s now look at the following [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=danhaywood.com&#038;blog=25721749&#038;post=917&#038;subd=danhaywood&#038;ref=&#038;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>Here&#8217;s a nice little gotcha for ya!</p>
<p>
A fairly common pattern is to use a filter that wraps the <tt>(Http)ServletRequest</tt> and <tt>(Http)ServletResponse</tt> in an app-specific wrapper; this can be used to hold user credentials and state etc.  In essence it is:<br />
<span id="more-917"></span><br />
<pre class="brush: java;">
@WebFilter(&quot;*&quot;)
public class AppRequestResponseFilter implements Filter {
  public void init(FilterConfig fConfig) throws ServletException { }
  public void destroy() {}
  public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
      throws IOException, ServletException {
    chain.doFilter(new AppRequest(request), new AppResponse(response));
  }
}
</pre></p>
<p>
where<br />
<pre class="brush: java;">
public class AppRequest extends HttpServletRequestWrapper {
  public AppRequest(ServletRequest request) {
    super((HttpServletRequest) request);
  }
}
</pre></p>
<p>
and <tt>AppResponse</tt> similarly subclasses from <tt>HttpServletResponseWrapper</tt>.</p>
<p>
But let&#8217;s now look at the following servlet that simply returns an error:</p>
<p><pre class="brush: java;">
@WebServlet(&quot;/sendsAnError&quot;)
public class SendsAnErrorServlet extends HttpServlet {
  protected void doGet(HttpServletRequest request, HttpServletResponse response)
      throws ServletException, IOException {
    // safe to downcast here...
    // AppRequest appRequest = (AppRequest)request;
    response.sendError(401);
  }
}
</pre></p>
<p>
As the comments note, this servlet could downcast <tt>HttpServletRequest</tt> to <tt>AppRequest</tt> if it so desired.  Indeed, any filter or servlet could do perform this downcast.  And you can see this in the stacktrace when I put a breakpoint in the servlet:<br />
<a href="http://danhaywood.files.wordpress.com/2012/02/sendsanerror.png"><img src="http://danhaywood.files.wordpress.com/2012/02/sendsanerror.png?w=300&h=196" alt="" title="Regular servlet gets the application-specific request/response objects" width="300" height="196" class="aligncenter size-medium wp-image-918" /></a></p>
<p>
Or could it?  Well, no, not always.  Because in <tt>web.xml</tt> we have the following entry:<br />
<pre class="brush: xml;">
&lt;error-page&gt;
  &lt;error-code&gt;401&lt;/error-code&gt;
  &lt;location&gt;/catchAnError&lt;/location&gt;
&lt;/error-page&gt;
</pre></p>
<p>
This instructs the servlet container that if a servlet returns a 401, then to redirect to the resource at the <tt>/catchAnError</tt> mapping.  In our case, this corresponds to the following servlet:</p>
<p><pre class="brush: java;">
@WebServlet(&quot;/catchAnError&quot;)
public class CatchAnErrorServlet extends HttpServlet {
  protected void doGet(HttpServletRequest request, HttpServletResponse response)
      throws ServletException, IOException {
    // ... but not safe to downcast here
    // AppRequest appRequest = (AppRequest)request;
    response.getWriter().println(&quot;&lt;p&gt;an error occurred&lt;/p&gt;&quot;);
  }
}
</pre></p>
<p>
And so here&#8217;s the catch: when the servlet container invokes this servlet to handle the error, any filters are NOT called.  And you can see this in the stacktrace when I break in this second servlet; the implementation that is provided is that of the servlet container, not of the filter:<br />
<a href="http://danhaywood.files.wordpress.com/2012/02/catchanerror.png"><img src="http://danhaywood.files.wordpress.com/2012/02/catchanerror.png?w=300&h=195" alt="" title="Error handling servlet gets only the servlet container&#039;s impl of HttpServletRequest etc." width="300" height="195" class="aligncenter size-medium wp-image-919" /></a></p>
<p>
What would happen, do you think, if you were to blindly downcast to <tt>AppRequest</tt> in this second servlet?  Well, it&#8217;d be a <tt>ClassCastException</tt>, of course, which the servlet container will deal with by just rendering its default error page (for a 401, in this case).  Meanwhile you&#8217;ll be stuck there wondering why your error handling servlet didn&#8217;t (seem to) fire.</p>
<p>
I guess this is in the servlet spec somewhere, but it&#8217;s surprising behaviour.  And it had us stumped for a little while.</p>
<p>
As ever, comments welcome.</p>
<br />Filed under: <a href='http://danhaywood.com/category/random/java/'>java</a>  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/danhaywood.wordpress.com/917/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/danhaywood.wordpress.com/917/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/danhaywood.wordpress.com/917/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/danhaywood.wordpress.com/917/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/danhaywood.wordpress.com/917/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/danhaywood.wordpress.com/917/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/danhaywood.wordpress.com/917/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/danhaywood.wordpress.com/917/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/danhaywood.wordpress.com/917/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/danhaywood.wordpress.com/917/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/danhaywood.wordpress.com/917/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/danhaywood.wordpress.com/917/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/danhaywood.wordpress.com/917/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/danhaywood.wordpress.com/917/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=danhaywood.com&#038;blog=25721749&#038;post=917&#038;subd=danhaywood&#038;ref=&#038;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://danhaywood.com/2012/02/10/filters-dont-fire-when-bouncing-off-web-xml-for-error-handling/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/204ef8a2259ebe0716f985f96c1c350d?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">danhaywood</media:title>
		</media:content>

		<media:content url="http://danhaywood.files.wordpress.com/2012/02/sendsanerror.png?w=300" medium="image">
			<media:title type="html">Regular servlet gets the application-specific request/response objects</media:title>
		</media:content>

		<media:content url="http://danhaywood.files.wordpress.com/2012/02/catchanerror.png?w=300" medium="image">
			<media:title type="html">Error handling servlet gets only the servlet container&#039;s impl of HttpServletRequest etc.</media:title>
		</media:content>
	</item>
		<item>
		<title>JQueryMobile demo app walk-thru</title>
		<link>http://danhaywood.com/2012/02/01/jquerymobile-demo-app-walkthr/</link>
		<comments>http://danhaywood.com/2012/02/01/jquerymobile-demo-app-walkthr/#comments</comments>
		<pubDate>Wed, 01 Feb 2012 23:29:59 +0000</pubDate>
		<dc:creator>danhaywood</dc:creator>
				<category><![CDATA[apache isis]]></category>
		<category><![CDATA[jquerymobile]]></category>
		<category><![CDATA[restful objects]]></category>

		<guid isPermaLink="false">http://danhaywood.com/?p=900</guid>
		<description><![CDATA[In the previous post I showed some screenshots of the simple JQueryMobile app that is hosted by the Apache Isis&#8216; online demo app, demonstrating one way of using the built-in Restful API. In this post, I want to look at the JQueryMobile code in a little more detail. The app consists of a single html [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=danhaywood.com&#038;blog=25721749&#038;post=900&#038;subd=danhaywood&#038;ref=&#038;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>In the <a title="JQueryMobile on the Apache Isis’ REST API" href="http://danhaywood.com/2012/01/20/jquerymobile-on-apache-isis-rest-api/">previous post</a> I showed some screenshots of the simple <a title="JQueryMobile" href="http://jquerymobile.com" target="_blank">JQueryMobile</a> app that is hosted by the <a href="http://incubator.apache.org/isis" title="Apache Isis" target="_blank">Apache Isis</a>&#8216; <a href="http://mmyco.co.uk:8180/isis-onlinedemo" title="Apache Isis online demo app" target="_blank">online demo</a> app, demonstrating one way of using the built-in <a title="Restful Objects" href="http://restfulobjects.org" target="_blank">Restful API</a>. In this post, I want to look at the JQueryMobile code in a little more detail.</p>
<p>The app consists of a single html page, index.html, along with a number of supporting Javascript files.  We start by bring in the Javascript libraries, most notably JQueryMobile and JQuery:<br />
<span id="more-900"></span><br />
<pre class="brush: xml;">
&lt;link rel=&quot;stylesheet&quot; href=&quot;../jquery.mobile/jquery.mobile-1.0.min.css&quot; /&gt;
&lt;script src=&quot;../jquery/jquery-1.6.4.min.js&quot;&gt;&lt;/script&gt;
&lt;script src=&quot;../jquery.mobile/jquery.mobile-1.0.min.js&quot;&gt;&lt;/script&gt;
&lt;script src=&quot;../jquery.tmpl/jquery.tmpl-vBeta1.0.0.min.js&quot;&gt;&lt;/script&gt;
</pre></p>
<p>You&#8217;ll note that I&#8217;ve also brought in the JQuery.tmpl library for templating.  This has actually been discontinued by the JQuery team, but its replacement isn&#8217;t yet available.  Since one templating solution is very much like another, I decided to carry on using it for this demo.</p>
<p>In addition to the third-party libraries, the app itself is broken up into a number of Javascript files:</p>
<p><pre class="brush: xml;">
&lt;script type=&quot;text/javascript&quot; src=&quot;namespace.js&quot;&gt;&lt;/script&gt;
&lt;script type=&quot;text/javascript&quot; src=&quot;util.js&quot;&gt;&lt;/script&gt;
&lt;script type=&quot;text/javascript&quot; src=&quot;generic.js&quot;&gt;&lt;/script&gt;
&lt;script type=&quot;text/javascript&quot; src=&quot;app.js&quot;&gt;&lt;/script&gt;
</pre></p>
<p>The namespace.js just defines a namespace() function in order that the other stuff can be namespaced properly:</p>
<p><pre class="brush: jscript;">
namespace = function(namespaceString) {
  var parts = namespaceString.split('.'),
  parent = window,
  currentPart = '';

  for(var i = 0, length = parts.length; i &lt; length; i++) {
    currentPart = parts[i];
    parent[currentPart] = parent[currentPart] || {};
    parent = parent[currentPart];
  }
  return parent;
}
</pre></p>
<p>Using this, the other script files define &#8220;util&#8221; and &#8220;generic&#8221; as aliases for a fully-qualified hierarchy:</p>
<p><pre class="brush: jscript;">
var util = namespace('org.apache.isis.viewer.json.jqmobile.util');
var generic = namespace('org.apache.isis.viewer.json.jqmobile.generic');
</pre></p>
<p>We&#8217;ll dig into the Javascript some more in a moment, but the next thing we should look at is the index.html.  JQueryMobile works by serving a single div&#8217;s at a time, and does all the animation between those div&#8217;s.  In some apps those div&#8217;s could be pulled down from a server dynamically; in the case of this app, though, all the div&#8217;s we need are already within the index.html:</p>
<p><pre class="brush: xml;">
&lt;body id=&quot;pageHolder&quot;&gt;
  &lt;div data-role=&quot;page&quot; id=&quot;home&quot;&gt; ... &lt;/div&gt;
  &lt;div data-role=&quot;page&quot; id=&quot;genericListView&quot;&gt; ... &lt;/div&gt;
  &lt;div data-role=&quot;page&quot; id=&quot;genericDomainObjectView&quot;&gt; ... &lt;/div&gt;
  &lt;div data-role=&quot;page&quot; id=&quot;genericObjectCollectionView&quot;&gt; ... &lt;/div&gt;
&lt;/body&gt;
</pre></p>
<p>When we load the index.html initially into the browser, JQuery automatically shows the first div.  In our case this is the home div:</p>
<p><pre class="brush: xml;">
&lt;div data-role=&quot;page&quot; id=&quot;home&quot;&gt;

  &lt;div data-role=&quot;header&quot;&gt;
    &lt;h1&gt;Home&lt;/h1&gt;
  &lt;/div&gt;

  &lt;div data-role=&quot;content&quot;&gt;
    &lt;br/&gt;
    &lt;button&gt;Todays Tasks&lt;/button&gt;
    &lt;ul data-role=&quot;listview&quot; class=&quot;tasks&quot;&gt;&lt;/ul&gt;
  &lt;/div&gt;

  &lt;script class=&quot;tmpl&quot; type=&quot;text/x-jquery-tmpl&quot;&gt;
    &lt;li&gt;
      &lt;a href=&quot;${href}&quot;&gt;${title}&lt;/a&gt;
    &lt;/li&gt;
  &lt;/script&gt;

  &lt;script type=&quot;text/javascript&quot;&gt;
    $(&quot;#home button&quot;).click(function(){
      $.mobile.changePage(&quot;../services/toDoItems/actions/toDosForToday/invoke&quot;, &quot;pop&quot;)
    });
  &lt;/script&gt;
&lt;/div&gt;
</pre></p>
<p>This renders a single button on the page.  The inline Javascript binds that to a JQueryMobile function to change page to the provided URL.  </p>
<p>As you can probably guess, that URL actually corresponds to the &#8220;toDosForToday&#8221;  action provided by the ToDoItems domain service.  In the normal scheme of things, if that URL served up a div, then JQueryMobile would automatically bring that div into the browser&#8217;s DOM, and render it.  For our app, though, things are a little more complex, because invoking that URL will retrieve JSON.  What we need to do is to use that JSON to generate a div and then transition to it. </p>
<p>The hook for doing this lives within app.js:</p>
<p><pre class="brush: jscript;">
  $(document).bind(&quot;pagebeforechange&quot;, generic.submitRenderAndNavigate);
</pre></p>
<p>This will cause the page transition ($.mobile.changePage) that we requested in the Javascript earlier to actually call the generic.submitRenderAndNavigate() function.  You can find this function in generic.js:</p>
<p><pre class="brush: jscript;">
generic.submitRenderAndNavigate = function(e, pageChangeData) {
  if (typeof pageChangeData.toPage !== &quot;string&quot;) {
    return;
  }

  var url = $.mobile.path.parseUrl(pageChangeData.toPage)
  var urlHref = generic.extract(url.href)
  if(!urlHref) {
    return;
  }

  generic.submitAndRender(urlHref, pageChangeData);
  e.preventDefault();
}
</pre></p>
<p>The function can be called by JQueryMobile in two different ways: either the pageChangeData.toPage is a string, or it is an in-memory page object.  We intercept the former case (checking that the URL is parseable), and then delegate off to generic.submitAndRender() to do the ajax etc.  The call to e.preventDefault() suppresses JQueryMobile&#8217;s usual page handling.</p>
<p>We&#8217;re going to look at generic.submitAndRender() in a second, but for now it&#8217;s worth understanding that the end result of that processing is a page object.  This is given back to JQueryMobile, which then calls back into this function.  The second time around the function just returns; because in this flow the e.preventDefault() is not called, JQueryMobile does its usual page transitions.</p>
<p>But, let&#8217;s look to see how generic.submitAndRender() function ends up generating the page.  For a start, this is the method where the ajax call gets made:</p>
<p><pre class="brush: jscript;">
generic.submitAndRender = function(urlHref, pageChangeData) {
  $.ajax({
    url : urlHref,
    dataType : 'json',
    success : function(json, str, xhr) {
      var contentType = xhr.getResponseHeader(&quot;Content-Type&quot;);
      var handler = generic.handlers[contentType];
      if(!handler) {
        alert(&quot;unable to handle response&quot;)
        return;
      }
      var pageAndOptions = handler(urlHref, pageChangeData, json, xhr)
     $.mobile.changePage(pageAndOptions.page, pageAndOptions.options);
   }
 })
}
</pre></p>
<p>The example given here is only a demo, so there&#8217;s no sad-case failure handling.  But assuming that the ajax call completes, the success callback looks up a<br />
handler function based on the returned &#8220;Content-Type&#8221;.  Here&#8217;s the lookup table:</p>
<p><pre class="brush: jscript;">
generic.handlers = {
  &quot;application/json;profile=\&quot;urn:org.restfulobjects/domainobject\&quot;&quot;: generic.handleDomainObjectRepresentation,
  &quot;application/json;profile=\&quot;urn:org.restfulobjects/list\&quot;&quot;: generic.handleListRepresentation,
  &quot;application/json;profile=\&quot;urn:org.restfulobjects/objectcollection\&quot;&quot;: generic.handleObjectCollectionRepresentation,
  &quot;application/json;profile=\&quot;urn:org.restfulobjects/actionresult\&quot;&quot;: generic.handleActionResultRepresentation
}
</pre></p>
<p>This looking up of the relevant handler is the heart of the app; using it we can handle representations of domain objects, a list, or a domain object collection, or an action result.</p>
<p>Since the demo app initially starts by invoking an action, let&#8217;s look at the generic.handleActionResultRepresentation():</p>
<p><pre class="brush: jscript;">
generic.handleActionResultRepresentation = function(urlHref, pageChangeData, json, xhr) {
  var resultType = json.resulttype
  var handler = generic.actionResultHandlers[resultType];
  if(!handler) {
    alert(&quot;unable to handle result type&quot;)
    return;
  } 
  return handler(urlHref, pageChangeData, json.result, xhr)
}
</pre></p>
<p>As you can see, this also looks up a handler, this time based on the json.resultType of the returned json.result:</p>
<p><pre class="brush: jscript;">
generic.actionResultHandlers = {
  &quot;object&quot;: generic.handleDomainObjectRepresentation,
  &quot;list&quot;: generic.handleListRepresentation
}
</pre></p>
<p>Perhaps no surprise, the handler functions that the action result handler delegates to one-and-the-same as those we noted earlier.  So let&#8217;s look at generic.handleListRepresentation in more detail (starting there simply because that&#8217;s what the demo app does when you invoke the &#8220;todaysTasks&#8221; service action):</p>
<p><pre class="brush: jscript;">
generic.handleListRepresentation = function(urlHref, pageChangeData, json, xhr) {

  var page = $(&quot;#genericListView&quot;);
  var header = page.children(&quot;:jqmData(role=header)&quot;);
  var content = page.children(&quot;:jqmData(role=content)&quot;);

  var items = generic.itemLinks(json.value)

  header.find(&quot;h1&quot;).html(&quot;Objects&quot;);

  var div = page.find(&quot;ul&quot;);
  var templateDiv = page.find(&quot;.tmpl&quot;);

  util.applyTemplateDiv(items, div, templateDiv);

  page.page();
  content.find( &quot;:jqmData(role=listview)&quot; ).listview(&quot;refresh&quot;);
  page.trigger(&quot;create&quot;);

  return generic.pageAndOptions(page, &quot;genericListView&quot;, urlHref)
}
</pre></p>
<p>The function uses a helper function generic.itemLinks to build a list of link objects.  Then, we identify the template script $(&#8220;#genericListView .tmpl&#8221;), and pass both to the util.applyTemplateDiv helper function.  This in turn calls the jQuery.tmpl library to do the heavy lifting.  </p>
<p>Here&#8217;s the HTML div that it works against:</p>
<p><pre class="brush: xml;">
&lt;div data-role=&quot;page&quot; id=&quot;genericListView&quot;&gt;

  &lt;div data-role=&quot;header&quot;&gt;
    &lt;a data-icon=&quot;back&quot; data-rel=&quot;back&quot;&gt;Back&lt;/a&gt;
    &lt;h1&gt;List&lt;/h1&gt;
  &lt;/div&gt;

  &lt;div data-role=&quot;content&quot;&gt;
    &lt;br/&gt;
    &lt;ul data-filter=&quot;true&quot; data-role=&quot;listview&quot;&gt;&lt;/ul&gt;
  &lt;/div&gt;

  &lt;script class=&quot;tmpl&quot; type=&quot;text/x-jquery-tmpl&quot;&gt;
    &lt;li&gt;
      &lt;a href=&quot;${href}&quot;&gt;${title}&lt;/a&gt;
    &lt;/li&gt;
  &lt;/script&gt;
&lt;/div&gt;
</pre></p>
<p>The href&#8217;s of the link objects are formulated such that, when followed, they will again trigger the generic.submitRenderAndNavigate() function.  In this way, we are able to walk between (the representations of) connected domain objects.</p>
<p>Once the content has been generated, we call a bunch of JQueryMobile functions (page.page() and so on) to tell the framework to &#8220;enhance&#8221; the generated page.   And once that has been done, we call the generic.pageAndOptions() function to create the in-memory page.  We&#8217;ll drill into that helper shortly.</p>
<p>Let&#8217;s now have a look at the biggest of the handlers, the generic.handleDomainObjectRepresentation:</p>
<p><pre class="brush: jscript;">
generic.handleDomainObjectRepresentation = function(urlHref, pageChangeData, json, xhr) {

  var page = $(&quot;#genericDomainObjectView&quot;);
  var header = page.children(&quot;:jqmData(role=header)&quot;);
  var content = page.children(&quot;:jqmData(role=content)&quot;);

  header.find(&quot;h1&quot;).html(json.title);

  // value properties
  var valueProperties = json.members.filter(function(item) {
    return item.memberType === &quot;property&quot; &amp;&amp; !item.value.href;
  });

  valueProperties = $.map( valueProperties, function(value, i) {
    var dataType = generic.dataTypeFor(value)
    return {
      &quot;id&quot;: value.id,
      &quot;value&quot;: value.value,
      &quot;dataTypeIsString&quot;: dataType === &quot;string&quot;,
      &quot;dataTypeIsBoolean&quot;: dataType === &quot;boolean&quot;
    }
  });

  var valuePropertiesDiv = page.children(&quot;:jqmData(role=content)&quot;).find(&quot;.valueProperties&quot;);
  var valuePropertiesTemplateDiv = page.children(&quot;.valueProperties-tmpl&quot;);
  util.applyTemplateDiv(valueProperties, valuePropertiesDiv, valuePropertiesTemplateDiv);

  // reference properties
  var referenceProperties = json.members.filter(function(item) {
    return item.memberType === &quot;property&quot; &amp;&amp; item.value.href;
  });

  var referencePropertiesList = page.children(&quot;:jqmData(role=content)&quot;).find(&quot;.referenceProperties&quot;);
  var referencePropertiesTemplateDiv = page.children(&quot;.referenceProperties-tmpl&quot;);
  util.applyTemplateDiv(referenceProperties, referencePropertiesList, referencePropertiesTemplateDiv);

  var collections = json.members.filter(function(item) {
    return item.memberType === &quot;collection&quot;;
  }).map(function(value, i) {
    var href = util.grepLink(value.links, &quot;details&quot;).href
    return {
      &quot;hrefUrlEncoded&quot; : util.urlencode(value.links[0].href),
      &quot;id&quot; : value.id,
      &quot;href&quot; : value.links[0].href
    }
  });

  // collections
  var collectionsList = page.children(&quot;:jqmData(role=content)&quot;).find(&quot;.collections&quot;);
  var collectionsTemplateDiv = page.children(&quot;.collections-tmpl&quot;);
  util.applyTemplateDiv(collections, collectionsList, collectionsTemplateDiv);

  page.page();
  content.find( &quot;:jqmData(role=listview)&quot; ).listview(&quot;refresh&quot;);
  page.trigger(&quot;create&quot;);

  return generic.pageAndOptions(page, &quot;genericDomainObjectView&quot;, urlHref)
}
</pre></p>
<p>Although this handler is longer, it&#8217;s doing much the same thing as the list handler.  Specifically, it processes the JSON into three lists, one for value properties, one for references properties, and one for collections.  For each, it uses the util.applyTemplateDiv function again in order to render against the corresponding templates, $(&#8220;#genericDomainObjectView .valueProperties-tmpl&#8221;) and so forth.</p>
<p>The corresponding div in the HTML is:</p>
<p><pre class="brush: xml;">
&lt;div data-role=&quot;page&quot; id=&quot;genericDomainObjectView&quot;&gt;

  &lt;div data-role=&quot;header&quot;&gt;
    &lt;a data-icon=&quot;back&quot; data-rel=&quot;back&quot;&gt;Back&lt;/a&gt;
    &lt;h1&gt;Object&lt;/h1&gt;
  &lt;/div&gt;

  &lt;div data-role=&quot;content&quot;&gt;
    &lt;div class=&quot;valueProperties&quot;&gt;&lt;/div&gt;
    &lt;br/&gt;
    &lt;p&gt;References&lt;/p&gt;
    &lt;ul data-role=&quot;listview&quot; data-inset=&quot;true&quot; class=&quot;referenceProperties&quot;&gt;&lt;/ul&gt;
    &lt;br/&gt;
    &lt;p&gt;Collections&lt;/p&gt;
    &lt;ul data-role=&quot;listview&quot; data-inset=&quot;true&quot; class=&quot;collections&quot;&gt;&lt;/ul&gt;
  &lt;/div&gt;

  &lt;script class=&quot;valueProperties-tmpl&quot; type=&quot;text/x-jquery-tmpl&quot;&gt;
  {{if dataTypeIsString}}
    &lt;label for=&quot;${id}&quot;&gt;${id}:&lt;/label&gt;
    &lt;input type=&quot;text&quot; name=&quot;${id}&quot; id=&quot;${id}&quot; value=&quot;${value}&quot; placeholder=&quot;${id}&quot; class=&quot;required&quot;/&gt;
  {{/if}}
  {{if dataTypeIsBoolean}}
    &lt;div data-role=&quot;fieldcontain&quot;&gt;
      &lt;fieldset data-role=&quot;controlgroup&quot;&gt;
        &lt;legend&gt;${id}?&lt;/legend&gt;
        &lt;input type=&quot;checkbox&quot; name=&quot;${id}&quot; id=&quot;${id}&quot; value=&quot;${value}&quot; class=&quot;required&quot;/&gt;
        &lt;label for=&quot;${id}&quot;&gt;${id}&lt;/label&gt;
      &lt;/fieldset&gt;
    &lt;/div&gt;
  {{/if}}
  &lt;/script&gt;

  &lt;script class=&quot;referenceProperties-tmpl&quot; type=&quot;text/x-jquery-tmpl&quot;&gt;
    &lt;li&gt;
      &lt;a data-transition=&quot;slide&quot; href=&quot;${value.href}&quot;&gt;
        &lt;p&gt;${id}&lt;/p&gt;
        &lt;p&gt;&lt;b&gt;${value.title}&lt;/b&gt;&lt;/p&gt;
      &lt;/a&gt;
    &lt;/li&gt;
  &lt;/script&gt;

  &lt;script class=&quot;collections-tmpl&quot; type=&quot;text/x-jquery-tmpl&quot;&gt;
    &lt;li&gt;
      &lt;a data-transition=&quot;slideup&quot; href=&quot;${href}&quot;&gt;${id}&lt;/a&gt;
    &lt;/li&gt;
  &lt;/script&gt;
&lt;/div&gt;
</pre></p>
<p>The template for value properties is, admittedly, a little ugly: it uses the {{if}} template in order to bring in either a checkbox or a textbox widget dependent on the value&#8217;s type.  A more fully-featured application would probably generalize this to use subtemplates (and might even be extensible) to allow richer value types such as images or maps to be rendered accordingly.</p>
<p>The last of our handlers, generic.handleObjectCollectionRepresentation, is very similar to the generic.handleListRepresentation:</p>
<p><pre class="brush: jscript;">
generic.handleObjectCollectionRepresentation = function(urlHref, pageChangeData, json, xhr) {
  var page = $(&quot;#genericObjectCollectionView&quot;);
  var header = page.children(&quot;:jqmData(role=header)&quot;);
  var content = page.children(&quot;:jqmData(role=content)&quot;);

  var items = generic.itemLinks(json.value)

  var parentTitle = util.grepLink(json.links, &quot;up&quot;).title

  var collectionId = json.id;
  header.find(&quot;h1&quot;).html(collectionId + &quot; for &quot; + parentTitle);

  var div = page.find(&quot;ul&quot;);
  var templateDiv = page.find(&quot;.tmpl&quot;);
  util.applyTemplateDiv(items, div, templateDiv);

  page.page();
  content.find( &quot;:jqmData(role=listview)&quot; ).listview(&quot;refresh&quot;);
  page.trigger(&quot;create&quot;);

  return generic.pageAndOptions(page, &quot;genericObjectCollectionView&quot;, urlHref, &quot;slideup&quot;)
}
</pre></p>
<p>It&#8217;s corresponding div in the HTML is: </p>
<p><pre class="brush: xml;">
&lt;div data-role=&quot;page&quot; id=&quot;genericObjectCollectionView&quot;&gt;

  &lt;div data-role=&quot;header&quot;&gt;
    &lt;a data-icon=&quot;back&quot; data-rel=&quot;back&quot;&gt;Back&lt;/a&gt;
    &lt;h1&gt;Collection&lt;/h1&gt;
  &lt;/div&gt;

  &lt;div data-role=&quot;content&quot;&gt;
    &lt;br/&gt;
    &lt;ul data-filter=&quot;true&quot; data-role=&quot;listview&quot;&gt;&lt;/ul&gt;
  &lt;/div&gt;

  &lt;script class=&quot;tmpl&quot; type=&quot;text/x-jquery-tmpl&quot;&gt;
    &lt;li&gt;
      &lt;a href=&quot;${href}&quot;&gt;${title}&lt;/a&gt;
    &lt;/li&gt;
  &lt;/script&gt;
&lt;/div&gt;
</pre></p>
<p>There&#8217;s just a couple more functions I want to go through.  The first is generic.pageAndOptions(); this is the function, if you recall, that creates and hands back the in-memory page option:</p>
<p><pre class="brush: jscript;">
generic.pageAndOptions = function(page, view, dataUrl, transition) {
  var pageAndOptions = {
    &quot;page&quot;: page,
    &quot;options&quot;: {
      &quot;dataUrl&quot;: &quot;#&quot; + view + &quot;?dataUrl=&quot; + util.urlencode(dataUrl),
      &quot;allowSamePageTransition&quot;: true,
      &quot;transition&quot;: transition
    }
  }
  return pageAndOptions
}
</pre></p>
<p>This little function returns a tuple consisting of the newly created page, along with an options object that has a dataUrl.  This options.dataUrl property that is important, because it is what appears in the browser&#8217;s address bar.  </p>
<p>As you can see, I&#8217;ve designed it to include both the view name (as an anchor), along with a ?dataUrl query param.  Why so?  Well, it allows the page to be bookmarked, so that the user can come back to any domain object rather than starting from home.  The little bit of processing to do this is in app.js:</p>
<p><pre class="brush: jscript;">
// if user manually refreshes page for domain object, then re-retrieve
var locationHref = location.href;
if(locationHref.indexOf(&quot;genericDomainObjectView&quot;) != -1) {
  var urlHref = generic.extract(locationHref);
  generic.submitAndRender(urlHref, &quot;pop&quot;);
} else {
  $.mobile.changePage($(&quot;#home&quot;))
}
</pre></p>
<p>Here we try to extract the dataUrl from the locationHref, in other words the dataUrl query param.  If successful, we call generic.submitAndRender(), as described above.  Or, if the dataUrl cannot be interpreted, then we just revert back to the home page.</p>
<p>I hope the above run-thru has been useful.  Bear in mind that this is far from production quality, and there could be bugs in it (in fact, I&#8217;m pretty sure that there are&#8230;).  And there are, of course, plenty of things that this demo doesn&#8217;t yet support &#8211; invoking actions, for one.  </p>
<p>In the future we expect that there&#8217;ll be a fully fledged generic REST client.  In the meantime, though, hopefully this is a good demonstrator for the potential of the <a href="http://restfulobjects.org" title="Restful Objects" target="_blank">Rest API</a> that ships with Isis.</p>
<p>PS: If you&#8217;re interested in the source code, you can either just save the files from the online demo (index.html, app.js, generic.js, util.js, namespace.js), or you can browse to the <a href="http://svn.apache.org/repos/asf/incubator/isis/trunk/examples/onlinedemo/webapp/src/main/webapp/mobile/" title="Apache Isis subversion repo" target="_blank">Isis subversion repository</a>.</p>
<br />Filed under: <a href='http://danhaywood.com/category/naked-objects-pattern/apache-isis/'>apache isis</a>, <a href='http://danhaywood.com/category/javascript/jquerymobile/'>jquerymobile</a>, <a href='http://danhaywood.com/category/restful-objects/'>restful objects</a>  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/danhaywood.wordpress.com/900/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/danhaywood.wordpress.com/900/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/danhaywood.wordpress.com/900/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/danhaywood.wordpress.com/900/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/danhaywood.wordpress.com/900/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/danhaywood.wordpress.com/900/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/danhaywood.wordpress.com/900/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/danhaywood.wordpress.com/900/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/danhaywood.wordpress.com/900/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/danhaywood.wordpress.com/900/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/danhaywood.wordpress.com/900/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/danhaywood.wordpress.com/900/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/danhaywood.wordpress.com/900/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/danhaywood.wordpress.com/900/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=danhaywood.com&#038;blog=25721749&#038;post=900&#038;subd=danhaywood&#038;ref=&#038;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://danhaywood.com/2012/02/01/jquerymobile-demo-app-walkthr/feed/</wfw:commentRss>
		<slash:comments>8</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/204ef8a2259ebe0716f985f96c1c350d?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">danhaywood</media:title>
		</media:content>
	</item>
		<item>
		<title>JQueryMobile on the Apache Isis&#8217; REST API</title>
		<link>http://danhaywood.com/2012/01/20/jquerymobile-on-apache-isis-rest-api/</link>
		<comments>http://danhaywood.com/2012/01/20/jquerymobile-on-apache-isis-rest-api/#comments</comments>
		<pubDate>Fri, 20 Jan 2012 19:58:57 +0000</pubDate>
		<dc:creator>danhaywood</dc:creator>
				<category><![CDATA[apache isis]]></category>
		<category><![CDATA[jquerymobile]]></category>
		<category><![CDATA[restful objects]]></category>

		<guid isPermaLink="false">http://danhaywood.com/?p=888</guid>
		<description><![CDATA[We&#8217;re currently working towards 0.2.0 of Apache Isis (incubating), and one of the most significant new areas of functionality is the REST API that it automatically provides through the json-viewer component.  As you can probably guess from the name, this viewer provides a REST interface which exposes JSON representations of the domain object models. However, [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=danhaywood.com&#038;blog=25721749&#038;post=888&#038;subd=danhaywood&#038;ref=&#038;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>We&#8217;re currently working towards 0.2.0 of <a title="Apache Isis (incubating)" href="http://incubator.apache.org/isis" target="_blank">Apache Isis</a> (incubating), and one of the most significant new areas of functionality is the REST API that it automatically provides through the json-viewer component.  As you can probably guess from the name, this viewer provides a REST interface which exposes JSON representations of the domain object models.</p>
<p>However, JSON representations do not a user interface make; instead the idea is that the developer will write either custom or generic UIs to consume those representations.  As an example of such an app (and by way of learning a little more Javascript) I&#8217;ve put together a very simple mobile app using the recently-released <a title="JQueryMobile" href="http://jquerymobile.com" target="_blank">JQueryMobile</a> framework.</p>
<p><span id="more-888"></span></p>
<p>For now, this mobile app is part of the Apache Isis online demo, which you can download as a <a title="Isis online demo WAR" href="https://sites.google.com/a/haywood-associates.co.uk/restfulobjects/files/onlinedemo-webapp-0.2.0-incubating-SNAPSHOT.war" target="_blank">WAR</a> or as a <a title="Isis online demo WAR (self-hosting)" href="https://sites.google.com/a/haywood-associates.co.uk/restfulobjects/files/onlinedemo-webapp-0.2.0-incubating-SNAPSHOT-jetty-console.war" target="_blank">self-hosted WAR</a> (run using java -jar &#8230;).  By the time you read this it may well also be available online <a title="Apache Isis online demo" href="http://mmyco.co.uk:8180/isis-onlinedemo/" target="_blank">here</a>.</p>
<p>To try out the demo, the first thing you&#8217;ll need to do is to register a user through the HTML viewer, and then reset the demo fixtures to create some initial data for your newly-created user.  The demo has full documentation on how to do this, so I won&#8217;t repeat it here.</p>
<p>Once you&#8217;ve done that, you&#8217;ll be able to browse to the home page for the mobile app (under mobile/index.html); you should see a home page showing just a single button:</p>
<p><a href="http://danhaywood.files.wordpress.com/2012/01/jqm-home.png"><img class="aligncenter size-medium wp-image-893" title="jqm-home" src="http://danhaywood.files.wordpress.com/2012/01/jqm-home.png?w=173&h=300" alt="" width="173" height="300" /></a></p>
<p>When you press that button, you&#8217;ll find that your prompted for a username/password; this is the Basic Authentication that is used to secure the demo app.  Enter the username/password that you just entered.</p>
<p>With the username/password successfully entered, you should see a list of todo-items; these are the result of a domain service action ( ToDoItems#todaysTasks(), to be exact):</p>
<p><a href="http://danhaywood.files.wordpress.com/2012/01/jqm-list.png"><img class="aligncenter size-medium wp-image-894" title="jqm-list" src="http://danhaywood.files.wordpress.com/2012/01/jqm-list.png?w=173&h=300" alt="" width="173" height="300" /></a></p>
<p>Thereafter everything in the app is generic; in other words it is able to display any domain object that is in the model.  For example, click on a link and you&#8217;ll find yourself viewing one of the ToDoItems:</p>
<p><a href="http://danhaywood.files.wordpress.com/2012/01/jqm-object.png"><img class="aligncenter size-medium wp-image-895" title="jqm-object" src="http://danhaywood.files.wordpress.com/2012/01/jqm-object.png?w=173&h=300" alt="" width="173" height="300" /></a></p>
<p>Similarly, you can look at the contents of the &#8216;similarItems&#8217; collection:</p>
<p><a href="http://danhaywood.files.wordpress.com/2012/01/jqm-collection.png"><img class="aligncenter size-medium wp-image-892" title="jqm-collection" src="http://danhaywood.files.wordpress.com/2012/01/jqm-collection.png?w=173&h=300" alt="" width="173" height="300" /></a></p>
<p>And, from there, you can navigate to other domain objects, and so on.</p>
<p>This little webapp consists of ~200 lines of HTML (mobile/index.html), about ~300 lines of custom Javascript (mobile/app.js, mobile/generic.js, mobile/util.js and mobile/namespace.js).  The rest of the Javascript magic is JQuery, JQueryMobile and JQuery-tmpl.</p>
<p>In the <a href="http://danhaywood.com/2012/02/01/jquerymobile-demo-app-walkthr/" title="JQueryMobile demo app walk-thru" target="_blank">next post</a> I&#8217;ll go through the source code and dissect it a little; in the meantime though you&#8217;re welcome to reverse-engineer it yourself.</p>
<p>As ever, comments welcome.</p>
<br />Filed under: <a href='http://danhaywood.com/category/naked-objects-pattern/apache-isis/'>apache isis</a>, <a href='http://danhaywood.com/category/javascript/jquerymobile/'>jquerymobile</a>, <a href='http://danhaywood.com/category/restful-objects/'>restful objects</a>  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/danhaywood.wordpress.com/888/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/danhaywood.wordpress.com/888/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/danhaywood.wordpress.com/888/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/danhaywood.wordpress.com/888/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/danhaywood.wordpress.com/888/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/danhaywood.wordpress.com/888/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/danhaywood.wordpress.com/888/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/danhaywood.wordpress.com/888/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/danhaywood.wordpress.com/888/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/danhaywood.wordpress.com/888/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/danhaywood.wordpress.com/888/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/danhaywood.wordpress.com/888/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/danhaywood.wordpress.com/888/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/danhaywood.wordpress.com/888/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=danhaywood.com&#038;blog=25721749&#038;post=888&#038;subd=danhaywood&#038;ref=&#038;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://danhaywood.com/2012/01/20/jquerymobile-on-apache-isis-rest-api/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/204ef8a2259ebe0716f985f96c1c350d?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">danhaywood</media:title>
		</media:content>

		<media:content url="http://danhaywood.files.wordpress.com/2012/01/jqm-home.png?w=173" medium="image">
			<media:title type="html">jqm-home</media:title>
		</media:content>

		<media:content url="http://danhaywood.files.wordpress.com/2012/01/jqm-list.png?w=173" medium="image">
			<media:title type="html">jqm-list</media:title>
		</media:content>

		<media:content url="http://danhaywood.files.wordpress.com/2012/01/jqm-object.png?w=173" medium="image">
			<media:title type="html">jqm-object</media:title>
		</media:content>

		<media:content url="http://danhaywood.files.wordpress.com/2012/01/jqm-collection.png?w=173" medium="image">
			<media:title type="html">jqm-collection</media:title>
		</media:content>
	</item>
	</channel>
</rss>
