You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@isis.apache.org by da...@apache.org on 2015/07/10 09:41:32 UTC

[09/15] isis-site git commit: ISIS-1133: contributors guide

http://git-wip-us.apache.org/repos/asf/isis-site/blob/e6efa093/content/guides/tg.html
----------------------------------------------------------------------
diff --git a/content/guides/tg.html b/content/guides/tg.html
new file mode 100644
index 0000000..a04e498
--- /dev/null
+++ b/content/guides/tg.html
@@ -0,0 +1,3098 @@
+<!doctype html>
+<html class="no-js" lang="en">
+<head>
+    <meta charset="utf-8"/>
+    <meta name="viewport" content="width=device-width, initial-scale=1.0"/>
+
+    <title>Tutorials</title>
+
+    <!--
+        Licensed to the Apache Software Foundation (ASF) under one
+        or more contributor license agreements.  See the NOTICE file
+        distributed with this work for additional information
+        regarding copyright ownership.  The ASF licenses this file
+        to you under the Apache License, Version 2.0 (the
+        "License"); you may not use this file except in compliance
+        with the License.  You may obtain a copy of the License at
+
+        http://www.apache.org/licenses/LICENSE-2.0
+
+        Unless required by applicable law or agreed to in writing,
+        software distributed under the License is distributed on an
+        "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+        KIND, either express or implied.  See the License for the
+        specific language governing permissions and limitations
+        under the License.
+    -->
+
+    <!-- No caching headers -->
+    <meta http-equiv="cache-control" content="no-cache" />
+    <meta http-equiv="pragma" content="no-cache" />
+    <meta http-equiv="expires" content="-1" />
+
+
+    <!-- TODO: need to (re)instate CDN in the future (not using for now just so can develop off-line -->
+    <link href="../css/foundation/5.5.1/foundation.css" rel="stylesheet" />
+    <script src="../js/foundation/5.5.1/vendor/modernizr.js"></script>
+    <link href="../css/asciidoctor/colony.css" rel="stylesheet">
+    <link href="../css/font-awesome/4.3.0/css/font-awesome.min.css" rel="stylesheet">
+
+
+
+
+    <link href="../css/github-fork-ribbon-css/0.1.1/gh-fork-ribbon.css" rel="stylesheet" />
+    <!--[if lt IE 9]>
+      <link href="../css/github-fork-ribbon-css/0.1.1/gh-fork-ribbon.ie.css" rel="stylesheet" />
+    <![endif]-->
+
+
+    <style type="text/css">
+        /* Stylesheet for CodeRay to match GitHub theme | MIT License | http://foundation.zurb.com */
+/*pre.CodeRay {background-color:#f7f7f8;}*/
+.CodeRay .line-numbers{border-right:1px solid #d8d8d8;padding:0 0.5em 0 .25em}
+.CodeRay span.line-numbers{display:inline-block;margin-right:.5em;color:rgba(0,0,0,.3)}
+.CodeRay .line-numbers strong{font-weight: normal}
+table.CodeRay{border-collapse:separate;border-spacing:0;margin-bottom:0;border:0;background:none}
+table.CodeRay td{vertical-align: top}
+table.CodeRay td.line-numbers{text-align:right}
+table.CodeRay td.line-numbers>pre{padding:0;color:rgba(0,0,0,.3)}
+table.CodeRay td.code{padding:0 0 0 .5em}
+table.CodeRay td.code>pre{padding:0}
+.CodeRay .debug{color:#fff !important;background:#000080 !important}
+.CodeRay .annotation{color:#007}
+.CodeRay .attribute-name{color:#000080}
+.CodeRay .attribute-value{color:#700}
+.CodeRay .binary{color:#509}
+.CodeRay .comment{color:#998;font-style:italic}
+.CodeRay .char{color:#04d}
+.CodeRay .char .content{color:#04d}
+.CodeRay .char .delimiter{color:#039}
+.CodeRay .class{color:#458;font-weight:bold}
+.CodeRay .complex{color:#a08}
+.CodeRay .constant,.CodeRay .predefined-constant{color:#008080}
+.CodeRay .color{color:#099}
+.CodeRay .class-variable{color:#369}
+.CodeRay .decorator{color:#b0b}
+.CodeRay .definition{color:#099}
+.CodeRay .delimiter{color:#000}
+.CodeRay .doc{color:#970}
+.CodeRay .doctype{color:#34b}
+.CodeRay .doc-string{color:#d42}
+.CodeRay .escape{color:#666}
+.CodeRay .entity{color:#800}
+.CodeRay .error{color:#808}
+.CodeRay .exception{color:inherit}
+.CodeRay .filename{color:#099}
+.CodeRay .function{color:#900;font-weight:bold}
+.CodeRay .global-variable{color:#008080}
+.CodeRay .hex{color:#058}
+.CodeRay .integer,.CodeRay .float{color:#099}
+.CodeRay .include{color:#555}
+.CodeRay .inline{color:#00}
+.CodeRay .inline .inline{background:#ccc}
+.CodeRay .inline .inline .inline{background:#bbb}
+.CodeRay .inline .inline-delimiter{color:#d14}
+.CodeRay .inline-delimiter{color:#d14}
+.CodeRay .important{color:#555;font-weight:bold}
+.CodeRay .interpreted{color:#b2b}
+.CodeRay .instance-variable{color:#008080}
+.CodeRay .label{color:#970}
+.CodeRay .local-variable{color:#963}
+.CodeRay .octal{color:#40e}
+.CodeRay .predefined{color:#369}
+.CodeRay .preprocessor{color:#579}
+.CodeRay .pseudo-class{color:#555}
+.CodeRay .directive{font-weight:bold}
+.CodeRay .type{font-weight:bold}
+.CodeRay .predefined-type{color:inherit}
+.CodeRay .reserved,.CodeRay .keyword {color:#000;font-weight:bold}
+.CodeRay .key{color:#808}
+.CodeRay .key .delimiter{color:#606}
+.CodeRay .key .char{color:#80f}
+.CodeRay .value{color:#088}
+.CodeRay .regexp .delimiter{color:#808}
+.CodeRay .regexp .content{color:#808}
+.CodeRay .regexp .modifier{color:#808}
+.CodeRay .regexp .char{color:#d14}
+.CodeRay .regexp .function{color:#404;font-weight:bold}
+.CodeRay .string{color:#d20}
+.CodeRay .string .string .string{background:#ffd0d0}
+.CodeRay .string .content{color:#d14}
+.CodeRay .string .char{color:#d14}
+.CodeRay .string .delimiter{color:#d14}
+.CodeRay .shell{color:#d14}
+.CodeRay .shell .delimiter{color:#d14}
+.CodeRay .symbol{color:#990073}
+.CodeRay .symbol .content{color:#a60}
+.CodeRay .symbol .delimiter{color:#630}
+.CodeRay .tag{color:#008080}
+.CodeRay .tag-special{color:#d70}
+.CodeRay .variable{color:#036}
+.CodeRay .insert{background:#afa}
+.CodeRay .delete{background:#faa}
+.CodeRay .change{color:#aaf;background:#007}
+.CodeRay .head{color:#f8f;background:#505}
+.CodeRay .insert .insert{color:#080}
+.CodeRay .delete .delete{color:#800}
+.CodeRay .change .change{color:#66f}
+.CodeRay .head .head{color:#f4f}
+
+        pre.CodeRay code {
+            background-color: inherit;
+            border-style: none;
+        }
+
+        pre.CodeRay code > span:first-child {
+            margin-left: -5px;
+        }
+
+        .literalblock pre,
+        .listingblock pre:not(.highlight),
+        .listingblock pre[class="highlight"],
+        .listingblock pre[class^="highlight "],
+        .listingblock pre.CodeRay,
+        .listingblock pre.prettyprint {
+            background: rgb(253, 250, 246);
+         }
+        .sidebarblock .literalblock pre,
+        .sidebarblock .listingblock pre:not(.highlight),
+        .sidebarblock .listingblock pre[class="highlight"],
+        .sidebarblock .listingblock pre[class^="highlight "],
+        .sidebarblock .listingblock pre.CodeRay,
+        .sidebarblock .listingblock pre.prettyprint {
+            background: rgb(253, 250, 246);
+         }
+
+    <style>
+
+    <style>
+    .github-fork-ribbon-wrapper.right {
+        position: fixed;
+    }
+    .github-fork-ribbon {
+        background: #090;
+    }
+    .github-fork-ribbon a:hover {
+        background:#0D0;
+        color:#fff;
+        font-size: 1.1em;
+    }
+    </style>
+
+    <style>
+        @media only screen and (min-width: 40.063em) {
+          .top-bar {
+            .contain-to-grid .top-bar {
+                max-width: 80rem;
+            }
+          }
+        }
+        .row {
+            max-width: 80rem;
+        }
+    </style>
+
+    <style>
+        .extended-quote,
+        .extended-quote-first {
+            margin-left: 40px;
+            margin-right: 40px;
+            font-style: italic;
+        }
+        .extended-quote-attribution {
+            text-align: right;
+            margin-right: 100px;
+            color: #10B061;
+        }
+
+        .extended-quote-first:before {
+            content: "\201c";
+            float: left;
+            font-size: 2.75em;
+            font-weight: bold;
+            line-height: 0.6em;
+            margin-left: -0.6em;
+            color: #003b6b;
+            text-shadow: 0 1px 2px rgba(0, 0, 0, 0.1);
+        }
+    </style>
+
+    <style>
+        body {
+          position: relative;
+        }
+
+        *:not(pre) a > code {
+            color: #210DDC;
+        }
+
+        *:not(pre) > code {
+            background-color: inherit;
+            border: none;
+            font-weight: normal;
+        }
+
+        body div#toc li,
+        body div#toc2 li {
+            list-style-type: none;
+        }
+
+        div#doc-content {
+            margin-top: 30px;
+        }
+
+        body div#toc li.active-region:before,
+        body div#toc2 li.active-region:before {
+            content: "\00BB \0020";
+            margin-left: -12px;
+        }
+
+        body div#toc li a.active,
+        body div#toc2 li a.active {
+            color: red;
+        }
+
+        body div#toc.toc,
+        body div#toc.toc2 {
+            position: fixed;
+            left: auto;
+            padding-top: 60px;
+            z-index: auto;
+            background-color: white;
+            border-left-color: #eee;
+            border-left-style: solid;
+            border-right: none;
+            min-height: 2000px;
+        }
+
+    </style>
+
+    <style>
+
+        @media only screen and (min-width: 768px) {
+          #toc.toc2 ul ul { margin-left: -10px; }
+        }
+
+
+        body div#toc .tocify-subheader ul {
+            margin-bottom: 0px;
+        }
+
+        body div#toc .tocify-subheader li {
+            font-size: 14px;
+        }
+        .tocify li.tocify-item, .tocify ul.tocify-item {
+            line-height: 24px;
+        }
+
+        body div#toc li.tocify-item.active:before,
+        body div#toc2 li.tocify-item.active:before {
+            content: "\00BB \0020";
+            margin-left: -12px;
+        }
+
+        body div#toc li.tocify-item.active a,
+        body div#toc2 li.tocify-item.active a {
+            color: red;
+        }
+    </style>
+
+    <style>
+        footer {
+            margin-top: 1000px;
+        }
+    </style>
+
+    <style>
+        /* overriding colony.css stylesheet */
+        .literalblock pre, .literalblock pre[class], .listingblock pre, .listingblock pre[class] {
+           /*padding: 1.25em 1.5625em 1.125em 1.5625em;*/
+           padding: 0.3em 0.6em 0.25em 0.6em;
+        }
+        @media only screen and (min-width: 1280px)
+        #toc.toc2 {
+          /*width: 20em;*/
+          width: 25em;
+        }
+
+        #doc-content a {
+          color: #210DDC;
+        }
+
+        .top-bar h1 {
+            border-bottom: inherit;
+        }
+
+        h2 {
+          margin-top: 80px;
+        }
+        h3 {
+          margin-top: 40px;
+        }
+        h4,h5 {
+          margin-top: 30px;
+        }
+
+        .admonitionblock.tip > table td.content {
+            color: #10B061;
+        }
+        .admonitionblock.note > table td.content {
+            color: #B509AB;
+        }
+        .admonitionblock.important > table td.content {
+            color: #D5810A;
+        }
+
+        .admonitionblock .title {
+            font-size: larger;
+            font-style: italic;
+        }
+
+        .imageblock img {
+            margin-bottom: 10px;
+        }
+    </style>
+
+    <style>
+        /* from http://ben.balter.com/2014/03/13/pages-anchor-links/ */
+        .header-link {
+          position: absolute;
+          left: -0.5em;
+          opacity: 0;
+
+          /*
+          -webkit-transition: opacity 0.2s ease-in-out 0.1s;
+          -moz-transition: opacity 0.2s ease-in-out 0.1s;
+          -ms-transition: opacity 0.2s ease-in-out 0.1s;
+          */
+        }
+
+        h2:hover .header-link,
+        h3:hover .header-link,
+        h4:hover .header-link,
+        h5:hover .header-link,
+        h6:hover .header-link {
+          opacity: 1;
+        }
+    </style>
+
+    <style>
+        .top-bar
+        {
+            -webkit-transition-duration: .5s;
+            transition-duration: .5s;
+
+            -webkit-transition-timing-function: cubic-bezier( 0.215, 0.610, 0.355, 1.000 );
+            transition-timing-function: cubic-bezier( 0.215, 0.610, 0.355, 1.000 );
+
+            -webkit-transition-property: -webkit-transform;
+            transition-property: transform;
+        }
+
+        /*
+        http://osvaldas.info/auto-hide-sticky-header
+        MIT license
+        */
+        .header--hidden
+        {
+            -webkit-transform: translateY( -100% );
+            -ms-transform: translateY( -100% );
+            transform: translateY( -100% );
+
+            transition-duration: .5s;
+            transition-timing-function: cubic-bezier( 0.215, 0.610, 0.355, 1.000 );
+            -webkit-transition-property: -webkit-transform;
+            transition-property: transform;
+        }
+    </style>
+
+    <style>
+        #doc-content a.guide {
+            color: white;
+        }
+    </style>
+
+    <style>
+        .tocify {
+            margin-top: 80px;
+        }
+    </style>
+
+
+</script>
+
+</head>
+<body>
+
+<<div class="github-fork-ribbon-wrapper right" style="position: fixed;">
+    <div class="github-fork-ribbon">
+        <a href="https://github.com/apache/isis/fork">Fork me on GitHub</a>
+    </div>
+</div>
+
+
+<div class="row">
+
+    <div class="fixed contain-to-grid header">
+        <nav class="top-bar" data-topbar role="navigation" style="max-width: 80rem">
+            <ul class="title-area">
+                <li class="name">
+                    <h1>
+                        <a href="/index.html">Apache Isis&trade;</a>
+                    </h1>
+                </li>
+                <!-- Remove the class "menu-icon" to get rid of menu icon. Take out "Menu" to just have icon alone -->
+                <li class="toggle-topbar menu-icon"><a href="#"><span>Menu</span></a></li>
+            </ul>
+
+            <section class="top-bar-section">
+                <ul class="right">
+
+                    <li class="has-form">
+                       <FORM class="searchbox navbar-form navbar-right" id="searchbox_012614087480249044419:dn-q5gtwxya" action="http://www.google.com/cse">
+                        <div class="row collapse">
+                            <input type="hidden" name="cx" value="012614087480249044419:dn-q5gtwxya">
+                            <INPUT type="hidden" name="cof" value="FORID:0">
+                            <INPUT class="form-control" name="q" type="text" placeholder="Search">
+                        </div>
+                    </FORM>
+                     </li>
+
+                </ul>
+
+                <!-- Left Nav Section -->
+                <ul class="left">
+
+                    <li><a href="/documentation.html">Documentation</a></li>
+                    <li><a href="/downloads.html">Downloads</a></li>
+                    <li><a href="/help.html">Help</a></li>
+                    <li><a href="/asf.html">@ASF</a></li>
+
+                </ul>
+
+            </section>
+        </nav>
+    </div>
+</div>
+
+<div class="row">
+
+    <div id="doc-content-left" class="large-9 medium-9 columns">
+
+
+        <div id="doc-content">
+          <div class="sect1">
+<h2 id="_tg">Tutorials</h2>
+<div class="sectionbody">
+<div class="paragraph">
+<p>This page contains a couple of tutorials for you to follow.</p>
+</div>
+<div class="ulist">
+<ul>
+<li>
+<p>the "petclinic" tutorial takes you step-by-step through building a simple application of just three classes.  There are example solutions in the github repo in case you get lost.</p>
+</li>
+<li>
+<p>the "stop scaffolding, start coding" tutorial is taken from a conference workshop.  It has less hand-holding, but lists out the steps for you to follow.  It&#8217;s a good cookbook to follow when you&#8217;re readng to take things further.</p>
+</li>
+</ul>
+</div>
+<div class="paragraph">
+<p>Have fun!</p>
+</div>
+</div>
+</div>
+<div class="sect1">
+<h2 id="_ug_tutorials_pet-clinic">Pet Clinic</h2>
+<div class="sectionbody">
+<div class="paragraph">
+<p>This is a step-by-step tutorial to build up a simple "petclinic" application, starting from the <a href="ug.html#_ug_getting-started_simpleapp-archetype">SimpleApp archetype</a>.</p>
+</div>
+<div class="paragraph">
+<p>It consists of just three domain classes (<a href="http://yuml.me/edit/3db2078c">http://yuml.me/3db2078c</a>):</p>
+</div>
+<div class="imageblock">
+<div class="content">
+<a class="image" href="images/tutorials/pet-clinic/domain-model.png"><img src="images/tutorials/pet-clinic/domain-model.png" alt="domain model"></a>
+</div>
+</div>
+<div class="paragraph">
+<p>This supports the following use cases:</p>
+</div>
+<div class="ulist">
+<ul>
+<li>
+<p>register a Pet</p>
+</li>
+<li>
+<p>register an Owner</p>
+</li>
+<li>
+<p>maintain a Pet&#8217;s details</p>
+</li>
+<li>
+<p>check in a Pet to visit the clinic</p>
+</li>
+<li>
+<p>enter a diagnosis</p>
+</li>
+</ul>
+</div>
+<div class="paragraph">
+<p>check out a Pet to visit the clinic</p>
+</div>
+<div class="paragraph">
+<p>Either follow along or check out the tags from the corresponding <a href="https://github.com/danhaywood/isis-app-petclinic">github repo</a>.</p>
+</div>
+<div class="sect2">
+<h3 id="_prerequisites">Prerequisites</h3>
+<div class="paragraph">
+<p>You&#8217;ll need:</p>
+</div>
+<div class="ulist">
+<ul>
+<li>
+<p>Java 7 JDK</p>
+</li>
+<li>
+<p><a href="http://maven.apache.org/">Maven</a> 3.2.x</p>
+</li>
+<li>
+<p>an IDE, such as <a href="http://www.eclipse.org/">Eclipse</a> or <a href="https://www.jetbrains.com/idea/">IntelliJ IDEA</a>.</p>
+</li>
+</ul>
+</div>
+</div>
+<div class="sect2">
+<h3 id="_run_the_archetype">Run the archetype</h3>
+<div class="paragraph">
+<p>Throughout this tutorial you can, if you wish, just checkout from the github repo wherever you see a "git checkout" note:</p>
+</div>
+<div class="admonitionblock tip">
+<table>
+<tr>
+<td class="icon">
+<i class="fa icon-tip" title="Tip"></i>
+</td>
+<td class="content">
+<div class="listingblock">
+<div class="content">
+<pre class="CodeRay highlight"><code data-lang="bash">git checkout https://github.com/danhaywood/isis-app-petclinic/commit/249abe476797438d83faa12ff88365da2c362451</code></pre>
+</div>
+</div>
+</td>
+</tr>
+</table>
+</div>
+<div class="admonitionblock note">
+<table>
+<tr>
+<td class="icon">
+<i class="fa icon-note" title="Note"></i>
+</td>
+<td class="content">
+<div class="paragraph">
+<p>This tutorial was developed against Apache Isis 1.8.0-SNAPSHOT.  Since then 1.8.0 has been released, so simply replace "1.8.0-SNAPSHOT" for "1.8.0" wherever it appears in the <code>pom.xml</code> files.</p>
+</div>
+</td>
+</tr>
+</table>
+</div>
+<div class="paragraph">
+<p>Run the simpleapp archetype to build an empty Isis application:</p>
+</div>
+<div class="listingblock">
+<div class="content">
+<pre class="CodeRay highlight"><code data-lang="bash">mvn archetype:generate  \
+    -D archetypeGroupId=org.apache.isis.archetype \
+    -D archetypeArtifactId=simpleapp-archetype \
+    -D archetypeVersion=1.8.0 \
+    -D groupId=com.mycompany \
+    -D artifactId=petclinic \
+    -D version=1.0-SNAPSHOT \
+    -D archetypeRepository=http://repository-estatio.forge.cloudbees.com/snapshot/ \
+    -B</code></pre>
+</div>
+</div>
+<div class="paragraph">
+<p>This will generate the app in a <code>petclinic</code> directory. Move the contents back:</p>
+</div>
+<div class="listingblock">
+<div class="content">
+<pre class="CodeRay highlight"><code data-lang="bash">mv petclinic/* .
+rmdir petclinic</code></pre>
+</div>
+</div>
+</div>
+<div class="sect2">
+<h3 id="_build_and_run">Build and run</h3>
+<div class="paragraph">
+<p>Start off by building the app from the command line:</p>
+</div>
+<div class="listingblock">
+<div class="content">
+<pre class="CodeRay highlight"><code data-lang="bash">mvn clean install</code></pre>
+</div>
+</div>
+<div class="paragraph">
+<p>Once that&#8217;s built then run using:</p>
+</div>
+<div class="listingblock">
+<div class="content">
+<pre class="CodeRay highlight"><code data-lang="bash">mvn antrun:run -P self-host</code></pre>
+</div>
+</div>
+<div class="paragraph">
+<p>A splash screen should appear offering to start up the app. Go ahead and start; the web browser should be opened at <a href="http://localhost:8080">http://localhost:8080</a></p>
+</div>
+<div class="paragraph">
+<p>Alternatively, you can run using the mvn-jetty-plugin:</p>
+</div>
+<div class="listingblock">
+<div class="content">
+<pre class="CodeRay highlight"><code data-lang="bash">mvn jetty:run</code></pre>
+</div>
+</div>
+<div class="paragraph">
+<p>This will accomplish the same thing, though the webapp is mounted at a slightly different URL</p>
+</div>
+</div>
+<div class="sect2">
+<h3 id="_using_the_app">Using the app</h3>
+<div class="paragraph">
+<p>Navigate to the Wicket UI (eg <a href="http://localhost:8080/wicket">http://localhost:8080/wicket</a>), and login (sven/pass).</p>
+</div>
+<div class="imageblock">
+<div class="content">
+<a class="image" href="images/tutorials/pet-clinic/010-01-login-page.png"><img src="images/tutorials/pet-clinic/010-01-login-page.png" alt="010 01 login page" width="600px"></a>
+</div>
+</div>
+<div class="paragraph">
+<p>The home page should be shown:</p>
+</div>
+<div class="imageblock">
+<div class="content">
+<a class="image" href="images/tutorials/pet-clinic/010-02-home-page.png"><img src="images/tutorials/pet-clinic/010-02-home-page.png" alt="010 02 home page" width="600px"></a>
+</div>
+</div>
+<div class="paragraph">
+<p>Install the fixtures (example test data) using the <code>Prototyping</code> menu:</p>
+</div>
+<div class="imageblock">
+<div class="content">
+<a class="image" href="images/tutorials/pet-clinic/010-03-prototyping-menu.png"><img src="images/tutorials/pet-clinic/010-03-prototyping-menu.png" alt="010 03 prototyping menu" width="600px"></a>
+</div>
+</div>
+<div class="paragraph">
+<p>List all objects using the <code>Simple Objects</code> menu:</p>
+</div>
+<div class="imageblock">
+<div class="content">
+<a class="image" href="images/tutorials/pet-clinic/010-04-simpleobjects.png"><img src="images/tutorials/pet-clinic/010-04-simpleobjects.png" alt="010 04 simpleobjects" width="600px"></a>
+</div>
+</div>
+<div class="paragraph">
+<p>To return the objects created:</p>
+</div>
+<div class="imageblock">
+<div class="content">
+<a class="image" href="images/tutorials/pet-clinic/010-05-simpleobject-list.png"><img src="images/tutorials/pet-clinic/010-05-simpleobject-list.png" alt="010 05 simpleobject list" width="600px"></a>
+</div>
+</div>
+<div class="paragraph">
+<p>Experiment some more, to:</p>
+</div>
+<div class="ulist">
+<ul>
+<li>
+<p>create a new object</p>
+</li>
+<li>
+<p>list all objects</p>
+</li>
+</ul>
+</div>
+<div class="paragraph">
+<p>Go back to the splash screen, and quit the app. Note that the database runs in-memory (using HSQLDB) so any data created will be lost between runs.</p>
+</div>
+</div>
+<div class="sect2">
+<h3 id="_dev_environment">Dev environment</h3>
+<div class="paragraph">
+<p>Set up <a href="cg.html#_cg_ide">an IDE</a> and import the project to be able to run and debug the app.</p>
+</div>
+<div class="paragraph">
+<p>Then set up a launch configuration so that you can run the app from within the IDE. To save having to run the fixtures
+every time, specify the following system properties:</p>
+</div>
+<div class="listingblock">
+<div class="content">
+<pre class="CodeRay highlight"><code data-lang="bash">-Disis.persistor.datanucleus.install-fixtures=true -Disis.fixtures=fixture.simple.scenario.SimpleObjectsFixture</code></pre>
+</div>
+</div>
+<div class="paragraph">
+<p>For example, here&#8217;s what a launch configuration in IntelliJ idea looks like:</p>
+</div>
+<div class="imageblock">
+<div class="content">
+<a class="image" href="images/tutorials/pet-clinic/020-01-idea-configuration.png"><img src="images/tutorials/pet-clinic/020-01-idea-configuration.png" alt="020 01 idea configuration" width="600px"></a>
+</div>
+</div>
+<div class="paragraph">
+<p>where the "before launch" maven goal (to run the DataNucleus enhancer) is defined as:</p>
+</div>
+<div class="imageblock">
+<div class="content">
+<a class="image" href="images/tutorials/pet-clinic/020-02-idea-configuration.png"><img src="images/tutorials/pet-clinic/020-02-idea-configuration.png" alt="020 02 idea configuration" width="400px"></a>
+</div>
+</div>
+</div>
+<div class="sect2">
+<h3 id="_explore_codebase">Explore codebase</h3>
+<div class="paragraph">
+<p>Apache Isis applications are organized into several Maven modules. Within your IDE navigate to the various classes and correlate back to the generated UI:</p>
+</div>
+<div class="ulist">
+<ul>
+<li>
+<p><code>petclinic</code> : parent module</p>
+</li>
+<li>
+<p><code>petclinic-dom</code>: domain objects module</p>
+<div class="ulist">
+<ul>
+<li>
+<p>entity: <code>dom.simple.SimpleObject</code></p>
+</li>
+<li>
+<p>repository: <code>dom.simple.SimpleObjects</code></p>
+</li>
+</ul>
+</div>
+</li>
+<li>
+<p><code>petclinic-fixture</code>: fixtures module</p>
+<div class="ulist">
+<ul>
+<li>
+<p>fixture script:`fixture.simple.SimpleObjectsFixture`</p>
+</li>
+</ul>
+</div>
+</li>
+<li>
+<p><code>petclinic-integtests</code>: integration tests module</p>
+</li>
+<li>
+<p><code>petclinic-webapp</code>: webapp module</p>
+<div class="ulist">
+<ul>
+<li>
+<p>(builds the WAR file)</p>
+</li>
+</ul>
+</div>
+</li>
+</ul>
+</div>
+</div>
+<div class="sect2">
+<h3 id="_testing">Testing</h3>
+<div class="paragraph">
+<p>Testing is of course massively important, and Apache Isis makes both unit testing and (end-to-end) integration testing easy. Building the app from the Maven command line ("mvn clean install") will run all tests, but you should also run the tests from within the IDE.</p>
+</div>
+<div class="ulist">
+<ul>
+<li>
+<p><code>myapp-dom</code> unit tests</p>
+</li>
+<li>
+<p>run</p>
+</li>
+<li>
+<p>inspect, eg</p>
+<div class="ulist">
+<ul>
+<li>
+<p><code>SimpleObjectTest</code></p>
+</li>
+</ul>
+</div>
+</li>
+<li>
+<p><code>myapp-integtests</code> integration tests</p>
+</li>
+<li>
+<p>run</p>
+</li>
+<li>
+<p>inspect, eg:</p>
+<div class="ulist">
+<ul>
+<li>
+<p><code>integration.tests.smoke.SimpleObjectsTest</code></p>
+</li>
+<li>
+<p><code>integration.specs.simple.SimpleObjectSpec_listAllAndCreate.feature</code></p>
+</li>
+</ul>
+</div>
+</li>
+<li>
+<p>generated report, eg</p>
+<div class="ulist">
+<ul>
+<li>
+<p><code>myapp/integtests/target/cucumber-html-report/index.html</code></p>
+<div class="ulist">
+<ul>
+<li>
+<p>change test in IDE, re-run (in Maven)</p>
+</li>
+</ul>
+</div>
+</li>
+</ul>
+</div>
+</li>
+</ul>
+</div>
+<div class="paragraph">
+<p>If you have issues with the integration tests, make sure that the domain classes have been enhanced by the DataNucleus enhancer. (The exact mechanics depends on the IDE being used).</p>
+</div>
+</div>
+<div class="sect2">
+<h3 id="_update_pom_files">Update POM files</h3>
+<div class="admonitionblock tip">
+<table>
+<tr>
+<td class="icon">
+<i class="fa icon-tip" title="Tip"></i>
+</td>
+<td class="content">
+<div class="listingblock">
+<div class="content">
+<pre class="CodeRay highlight"><code data-lang="bash">git checkout https://github.com/danhaywood/isis-app-petclinic/commit/68904752bc2de9ebb3c853b79236df2b3ad2c944</code></pre>
+</div>
+</div>
+</td>
+</tr>
+</table>
+</div>
+<div class="paragraph">
+<p>The POM files generated by the simpleapp archetype describe the app as "SimpleApp". Update them to say "PetClinic" instead.</p>
+</div>
+</div>
+<div class="sect2">
+<h3 id="_delete_the_bdd_specs">Delete the BDD specs</h3>
+<div class="admonitionblock tip">
+<table>
+<tr>
+<td class="icon">
+<i class="fa icon-tip" title="Tip"></i>
+</td>
+<td class="content">
+<div class="listingblock">
+<div class="content">
+<pre class="CodeRay highlight"><code data-lang="bash">git checkout https://github.com/danhaywood/isis-app-petclinic/commit/9046226249429b269325dfa2baccf03635841c20</code></pre>
+</div>
+</div>
+</td>
+</tr>
+</table>
+</div>
+<div class="paragraph">
+<p>During this tutorial we&#8217;re going to keep the integration tests in-sync with the code, but we&#8217;re going to stop short of writing BDD/Cucumber specs.</p>
+</div>
+<div class="paragraph">
+<p>Therefore delete the BDD feature spec and glue in the <code>integtest</code> module:</p>
+</div>
+<div class="ulist">
+<ul>
+<li>
+<p><code>integration/specs/*</code></p>
+</li>
+<li>
+<p><code>integration/glue/*</code></p>
+</li>
+</ul>
+</div>
+</div>
+<div class="sect2">
+<h3 id="_rename_artifacts">Rename artifacts</h3>
+<div class="admonitionblock tip">
+<table>
+<tr>
+<td class="icon">
+<i class="fa icon-tip" title="Tip"></i>
+</td>
+<td class="content">
+<div class="listingblock">
+<div class="content">
+<pre class="CodeRay highlight"><code data-lang="bash">git checkout https://github.com/danhaywood/isis-app-petclinic/commit/bee3629c0b64058f939b6dd20f226be31810fc66</code></pre>
+</div>
+</div>
+</td>
+</tr>
+</table>
+</div>
+<div class="paragraph">
+<p>Time to start refactoring the app. The heart of the PetClinic app is the <code>Pet</code> concept, so go through the code and refactor. While we&#8217;re at it, refactor the app itself from "SimpleApp" to "PetClinicApp".</p>
+</div>
+<div class="paragraph">
+<p>See the git commit for more detail, but in outline, the renames required are:</p>
+</div>
+<div class="ulist">
+<ul>
+<li>
+<p>in the <code>dom</code> module&#8217;s production code</p>
+<div class="ulist">
+<ul>
+<li>
+<p><code>SimpleObject</code> -&gt; <code>Pet</code> (entity)</p>
+</li>
+<li>
+<p><code>SimpleObjects</code> -&gt; <code>Pets</code> (repository domain service)</p>
+</li>
+<li>
+<p><code>SimpleObject.layout.json</code> -&gt; <code>Pet.layout.json</code> (layout hints for the <code>Pet</code> entity)</p>
+</li>
+<li>
+<p>delete the <code>SimpleObject.png</code>, and add a new <code>Pet.png</code> (icon shown against all <code>Pet</code> instances).</p>
+</li>
+</ul>
+</div>
+</li>
+<li>
+<p>in the <code>dom</code> module&#8217;s unit test code</p>
+<div class="ulist">
+<ul>
+<li>
+<p><code>SimpleObjectTest</code> -&gt; <code>PetTest</code> (unit tests for <code>Pet</code> entity)</p>
+</li>
+<li>
+<p><code>SimpleObjectsTest</code> -&gt; <code>PetsTest</code> (unit tests for <code>Pets</code> domain service)</p>
+</li>
+</ul>
+</div>
+</li>
+<li>
+<p>in the <code>fixture</code> module:</p>
+<div class="ulist">
+<ul>
+<li>
+<p><code>SimpleObjectsFixturesService</code> -&gt; <code>PetClinicAppFixturesService</code> (rendered as the prototyping menu in the UI)</p>
+</li>
+<li>
+<p><code>SimpleObjectsTearDownService</code> -&gt; <code>PetClinicAppTearDownService</code> (tear down all objects between integration tests)</p>
+</li>
+<li>
+<p><code>SimpleObjectAbstract</code> -&gt; <code>PetAbstract</code> (abstract class for setting up a single pet object</p>
+<div class="ulist">
+<ul>
+<li>
+<p>and corresponding subclasses to set up sample data (eg <code>PetForFido</code>)</p>
+</li>
+</ul>
+</div>
+</li>
+<li>
+<p><code>SimpleObjectsFixture</code> -&gt; <code>PetsFixture</code> (tear downs system and then sets up all pets)</p>
+</li>
+</ul>
+</div>
+</li>
+<li>
+<p>in the <code>integtest</code> module:</p>
+<div class="ulist">
+<ul>
+<li>
+<p><code>SimpleAppSystemInitializer</code> -&gt; <code>PetClinicAppSystemInitializer</code> (bootstraps integration tests with domain service/repositories)</p>
+</li>
+<li>
+<p><code>SimpleAppIntegTest</code> -&gt; <code>PetClinicAppIntegTest</code> (base class for integration tests)</p>
+</li>
+<li>
+<p><code>SimpleObjectTest</code> -&gt; <code>PetTest</code> (integration test for <code>Pet</code> entity)</p>
+</li>
+<li>
+<p><code>SimpleObjectsTest</code> -&gt; <code>PetsTest</code> (integration test for <code>Pets</code> domain service)</p>
+</li>
+</ul>
+</div>
+</li>
+<li>
+<p>in the <code>webapp</code> module:</p>
+<div class="ulist">
+<ul>
+<li>
+<p><code>SimpleApplication</code> -&gt; <code>PetClinicApplication</code></p>
+</li>
+<li>
+<p>update <code>isis.properties</code></p>
+</li>
+<li>
+<p>update <code>web.xml</code></p>
+</li>
+</ul>
+</div>
+</li>
+</ul>
+</div>
+<div class="paragraph">
+<p>Note that <code>Pet</code> has both both Isis and JDO annotations:</p>
+</div>
+<div class="listingblock">
+<div class="content">
+<pre class="CodeRay highlight"><code data-lang="java"><span class="annotation">@javax</span>.jdo.annotations.PersistenceCapable(identityType=IdentityType.DATASTORE) <i class="conum" data-value="1"></i><b>(1)</b>
+<span class="annotation">@javax</span>.jdo.annotations.DatastoreIdentity(                                      <i class="conum" data-value="2"></i><b>(2)</b>
+        strategy=javax.jdo.annotations.IdGeneratorStrategy.IDENTITY,
+         column=<span class="string"><span class="delimiter">&quot;</span><span class="content">id</span><span class="delimiter">&quot;</span></span>)
+<span class="annotation">@javax</span>.jdo.annotations.Version(                                                <i class="conum" data-value="3"></i><b>(3)</b>
+        strategy=VersionStrategy.VERSION_NUMBER,
+        column=<span class="string"><span class="delimiter">&quot;</span><span class="content">version</span><span class="delimiter">&quot;</span></span>)
+<span class="annotation">@javax</span>.jdo.annotations.Unique(name=<span class="string"><span class="delimiter">&quot;</span><span class="content">Pet_name_UNQ</span><span class="delimiter">&quot;</span></span>, members = {<span class="string"><span class="delimiter">&quot;</span><span class="content">name</span><span class="delimiter">&quot;</span></span>})         <i class="conum" data-value="4"></i><b>(4)</b>
+<span class="annotation">@ObjectType</span>(<span class="string"><span class="delimiter">&quot;</span><span class="content">PET</span><span class="delimiter">&quot;</span></span>)                                                             <i class="conum" data-value="5"></i><b>(5)</b>
+<span class="annotation">@Bookmarkable</span>                                                                  <i class="conum" data-value="6"></i><b>(6)</b>
+<span class="directive">public</span> <span class="type">class</span> <span class="class">Pet</span> <span class="directive">implements</span> <span class="predefined-type">Comparable</span>&lt;Pet&gt; {
+    ...
+}</code></pre>
+</div>
+</div>
+<div class="paragraph">
+<p>where:</p>
+</div>
+<div class="colist arabic">
+<table>
+<tr>
+<td><i class="conum" data-value="1"></i><b>1</b></td>
+<td><code>@PersistenceCapable</code> and</td>
+</tr>
+<tr>
+<td><i class="conum" data-value="2"></i><b>2</b></td>
+<td><code>@DatastoreIdentity</code> specify a surrogate <code>Id</code> column to be used as the primary key</td>
+</tr>
+<tr>
+<td><i class="conum" data-value="3"></i><b>3</b></td>
+<td><code>@Version</code> provides support for optimistic locking</td>
+</tr>
+<tr>
+<td><i class="conum" data-value="4"></i><b>4</b></td>
+<td><code>@Unique</code> enforces a uniqueness constraint so that no two `Pet`s can have the same name (unrealistic, but can refactor later)</td>
+</tr>
+<tr>
+<td><i class="conum" data-value="5"></i><b>5</b></td>
+<td><code>@ObjectType</code> is used by Apache Isis for its own internal "OID" identifier; this also appears in the URL in Apache Isis' Wicket viewer and REST API</td>
+</tr>
+<tr>
+<td><i class="conum" data-value="6"></i><b>6</b></td>
+<td><code>@Bookmarkable</code> indicates that the object can be automatically bookmarked in Apache Isis' Wicket viewer</td>
+</tr>
+</table>
+</div>
+<div class="admonitionblock note">
+<table>
+<tr>
+<td class="icon">
+<i class="fa icon-note" title="Note"></i>
+</td>
+<td class="content">
+<div class="paragraph">
+<p>The <code>@ObjectType</code> and <code>@Bookmarkable</code> annotations have since been deprecated, replaced with <code>@DomainObject(objectType=&#8230;&#8203;)</code> and <code>@DomainObjectLayout(bookmarking=&#8230;&#8203;)</code></p>
+</div>
+</td>
+</tr>
+</table>
+</div>
+<div class="paragraph">
+<p>The <code>Pets</code> domain service also has Isis annotations:</p>
+</div>
+<div class="listingblock">
+<div class="content">
+<pre class="CodeRay highlight"><code data-lang="java"><span class="annotation">@DomainService</span>(repositoryFor = Pet.class)
+<span class="annotation">@DomainServiceLayout</span>(menuOrder = <span class="string"><span class="delimiter">&quot;</span><span class="content">10</span><span class="delimiter">&quot;</span></span>)
+<span class="directive">public</span> <span class="type">class</span> <span class="class">Pets</span> {
+    ...
+}</code></pre>
+</div>
+</div>
+<div class="paragraph">
+<p>where:</p>
+</div>
+<div class="ulist">
+<ul>
+<li>
+<p><code>DomainService</code> indicates that the service should be instantiated automatically (as a singleton)</p>
+</li>
+<li>
+<p><code>DomainServiceLayout</code> provides UI hints, in this case the positioning of the menu for the actions provided by the service</p>
+</li>
+</ul>
+</div>
+<div class="paragraph">
+<p>To run the application will require an update to the IDE configuration, for the changed name of the fixture class:</p>
+</div>
+<div class="imageblock">
+<div class="content">
+<a class="image" href="images/tutorials/pet-clinic/030-01-idea-configuration-updated.png"><img src="images/tutorials/pet-clinic/030-01-idea-configuration-updated.png" alt="030 01 idea configuration updated" width="600px"></a>
+</div>
+</div>
+<div class="paragraph">
+<p>Running the app should now show `Pet`s:</p>
+</div>
+<div class="imageblock">
+<div class="content">
+<a class="image" href="images/tutorials/pet-clinic/030-02-updated-app.png"><img src="images/tutorials/pet-clinic/030-02-updated-app.png" alt="030 02 updated app" width="600px"></a>
+</div>
+</div>
+</div>
+<div class="sect2">
+<h3 id="_update_package_names">Update package names</h3>
+<div class="admonitionblock tip">
+<table>
+<tr>
+<td class="icon">
+<i class="fa icon-tip" title="Tip"></i>
+</td>
+<td class="content">
+<div class="listingblock">
+<div class="content">
+<pre class="CodeRay highlight"><code data-lang="bash">git checkout https://github.com/danhaywood/isis-app-petclinic/commit/55ec36e520191f5fc8fe7f5b89956814eaf13317</code></pre>
+</div>
+</div>
+</td>
+</tr>
+</table>
+</div>
+<div class="paragraph">
+<p>The classes created by the simpleapp archetype are by default in the <code>simple</code> package. Move these classes to <code>pets</code> package instead. Also adjust package names where they appear as strings:</p>
+</div>
+<div class="ulist">
+<ul>
+<li>
+<p>in <code>PetClinicAppFixturesService</code>, change the package name from "fixture.simple" to "fixture.pets".</p>
+</li>
+<li>
+<p>in <code>PetClinicAppSystemInitializer</code>, change the package name "dom.simple" to "dom.pets", and similarly "fixture.simple" to "fixture.pets"</p>
+</li>
+<li>
+<p>in <code>WEB-INF/isis.properties</code>, similarly change the package name "dom.simple" to "dom.pets", and similarly "fixture.simple" to "fixture.pets"</p>
+</li>
+</ul>
+</div>
+<div class="paragraph">
+<p>To run the application will require a further update to the IDE configuration, for the changed package of the fixture class:</p>
+</div>
+<div class="imageblock">
+<div class="content">
+<a class="image" href="images/tutorials/pet-clinic/040-01-idea-configuration-updated.png"><img src="images/tutorials/pet-clinic/040-01-idea-configuration-updated.png" alt="040 01 idea configuration updated" width="600px"></a>
+</div>
+</div>
+</div>
+<div class="sect2">
+<h3 id="_add_code_petspecies_code_enum">Add <code>PetSpecies</code> enum</h3>
+<div class="admonitionblock tip">
+<table>
+<tr>
+<td class="icon">
+<i class="fa icon-tip" title="Tip"></i>
+</td>
+<td class="content">
+<div class="listingblock">
+<div class="content">
+<pre class="CodeRay highlight"><code data-lang="bash">git checkout https://github.com/danhaywood/isis-app-petclinic/commit/55c9cd28ff960220719b3dc7cb8abadace8d0829</code></pre>
+</div>
+</div>
+</td>
+</tr>
+</table>
+</div>
+<div class="paragraph">
+<p>Each <code>Pet</code> is of a particular species. Model these as an enum called <code>PetSpecies</code>:</p>
+</div>
+<div class="listingblock">
+<div class="content">
+<pre class="CodeRay highlight"><code data-lang="java"><span class="directive">public</span> <span class="type">enum</span> PetSpecies {
+    Cat,
+    Dog,
+    Budgie,
+    Hamster,
+    Tortoise
+}</code></pre>
+</div>
+</div>
+<div class="paragraph">
+<p>Introduce a new property on <code>Pet</code> of this type:</p>
+</div>
+<div class="listingblock">
+<div class="content">
+<pre class="CodeRay highlight"><code data-lang="java"><span class="directive">public</span> <span class="type">class</span> <span class="class">Pet</span> {
+    ...
+    private PetSpecies species;
+    <span class="annotation">@javax</span>.jdo.annotations.Column(allowsNull = <span class="string"><span class="delimiter">&quot;</span><span class="content">false</span><span class="delimiter">&quot;</span></span>)
+    <span class="directive">public</span> PetSpecies getSpecies() { <span class="keyword">return</span> species; }
+    <span class="directive">public</span> <span class="type">void</span> setSpecies(<span class="directive">final</span> PetSpecies species) { <span class="local-variable">this</span>.species = species; }
+    ...
+}</code></pre>
+</div>
+</div>
+<div class="paragraph">
+<p>Update fixtures, unit tests and integration tests.</p>
+</div>
+</div>
+<div class="sect2">
+<h3 id="_icon_to_reflect_pet_species">Icon to reflect pet species</h3>
+<div class="admonitionblock tip">
+<table>
+<tr>
+<td class="icon">
+<i class="fa icon-tip" title="Tip"></i>
+</td>
+<td class="content">
+<div class="listingblock">
+<div class="content">
+<pre class="CodeRay highlight"><code data-lang="bash">git checkout https://github.com/danhaywood/isis-app-petclinic/commit/2212765694693eb463f8fa88bab1bad154add0cb</code></pre>
+</div>
+</div>
+</td>
+</tr>
+</table>
+</div>
+<div class="paragraph">
+<p>Rather than using a single icon for a domain class, instead a different icon can be supplied for each instance. We can therefore have different icon files for each pet, reflecting that pet&#8217;s species.</p>
+</div>
+<div class="listingblock">
+<div class="content">
+<pre class="CodeRay highlight"><code data-lang="java"><span class="directive">public</span> <span class="type">class</span> <span class="class">Pet</span> {
+    ...
+    public <span class="predefined-type">String</span> iconName() {
+        <span class="keyword">return</span> getSpecies().name();
+    }
+    ...
+}</code></pre>
+</div>
+</div>
+<div class="paragraph">
+<p>Download corresponding icon files (<code>Dog.png</code>, <code>Cat.png</code> etc)</p>
+</div>
+<div class="paragraph">
+<p>Running the app shows the <code>Pet</code> and its associated icon:</p>
+</div>
+<div class="imageblock">
+<div class="content">
+<a class="image" href="images/tutorials/pet-clinic/050-01-list-all.png"><img src="images/tutorials/pet-clinic/050-01-list-all.png" alt="050 01 list all" width="600px"></a>
+</div>
+</div>
+<div class="paragraph">
+<p>with the corresponding view of the <code>Pet</code>:</p>
+</div>
+<div class="imageblock">
+<div class="content">
+<a class="image" href="images/tutorials/pet-clinic/050-02-view-pet.png"><img src="images/tutorials/pet-clinic/050-02-view-pet.png" alt="050 02 view pet" width="600px"></a>
+</div>
+</div>
+</div>
+<div class="sect2">
+<h3 id="_add_pet_s_code_owner_code">Add pet&#8217;s <code>Owner</code></h3>
+<div class="admonitionblock tip">
+<table>
+<tr>
+<td class="icon">
+<i class="fa icon-tip" title="Tip"></i>
+</td>
+<td class="content">
+<div class="listingblock">
+<div class="content">
+<pre class="CodeRay highlight"><code data-lang="bash">git checkout https://github.com/danhaywood/isis-app-petclinic/commit/6f92a8ee8e76696d005da2a8b7a746444d017546</code></pre>
+</div>
+</div>
+</td>
+</tr>
+</table>
+</div>
+<div class="paragraph">
+<p>Add the <code>Owner</code> entity and corresponding <code>Owners</code> domain service (repository). Add a query to find `Order`s by name:</p>
+</div>
+<div class="listingblock">
+<div class="content">
+<pre class="CodeRay highlight"><code data-lang="java">...
+<span class="annotation">@javax</span>.jdo.annotations.Queries( {
+        <span class="annotation">@javax</span>.jdo.annotations.Query(
+                name = <span class="string"><span class="delimiter">&quot;</span><span class="content">findByName</span><span class="delimiter">&quot;</span></span>, language = <span class="string"><span class="delimiter">&quot;</span><span class="content">JDOQL</span><span class="delimiter">&quot;</span></span>,
+                value = <span class="string"><span class="delimiter">&quot;</span><span class="content">SELECT </span><span class="delimiter">&quot;</span></span>
+                        + <span class="string"><span class="delimiter">&quot;</span><span class="content">FROM dom.owners.Owner </span><span class="delimiter">&quot;</span></span>
+                        + <span class="string"><span class="delimiter">&quot;</span><span class="content">WHERE name.matches(:name)</span><span class="delimiter">&quot;</span></span>)
+})
+<span class="directive">public</span> <span class="type">class</span> <span class="class">Owner</span> ... {
+    ...
+}</code></pre>
+</div>
+</div>
+<div class="paragraph">
+<p>and <code>findByName(&#8230;&#8203;)</code> in <code>Owners</code>:</p>
+</div>
+<div class="listingblock">
+<div class="content">
+<pre class="CodeRay highlight"><code data-lang="java"><span class="directive">public</span> <span class="type">class</span> <span class="class">Owners</span> {
+    ...
+    public <span class="predefined-type">List</span>&lt;<span class="predefined-type">Owner</span>&gt; findByName(
+            <span class="annotation">@ParameterLayout</span>(named = <span class="string"><span class="delimiter">&quot;</span><span class="content">Name</span><span class="delimiter">&quot;</span></span>)
+            <span class="directive">final</span> <span class="predefined-type">String</span> name) {
+        <span class="directive">final</span> <span class="predefined-type">String</span> nameArg = <span class="predefined-type">String</span>.format(<span class="string"><span class="delimiter">&quot;</span><span class="content">.*%s.*</span><span class="delimiter">&quot;</span></span>, name);
+        <span class="directive">final</span> <span class="predefined-type">List</span>&lt;<span class="predefined-type">Owner</span>&gt; owners = container.allMatches(
+                <span class="keyword">new</span> QueryDefault&lt;&gt;(
+                        <span class="predefined-type">Owner</span>.class,
+                        <span class="string"><span class="delimiter">&quot;</span><span class="content">findByName</span><span class="delimiter">&quot;</span></span>,
+                        <span class="string"><span class="delimiter">&quot;</span><span class="content">name</span><span class="delimiter">&quot;</span></span>, nameArg));
+        <span class="keyword">return</span> owners;
+    }
+    ...
+}</code></pre>
+</div>
+</div>
+<div class="paragraph">
+<p>Add an <code>owner</code> property to <code>Pet</code>, with supporting <code>autoCompleteXxx()</code> method (so that available owners are shown in a drop-down list box):</p>
+</div>
+<div class="listingblock">
+<div class="content">
+<pre class="CodeRay highlight"><code data-lang="java"><span class="directive">public</span> <span class="type">class</span> <span class="class">Pet</span> ... {
+    ...
+    private <span class="predefined-type">Owner</span> owner;
+    <span class="annotation">@javax</span>.jdo.annotations.Column(allowsNull = <span class="string"><span class="delimiter">&quot;</span><span class="content">false</span><span class="delimiter">&quot;</span></span>)
+    <span class="directive">public</span> <span class="predefined-type">Owner</span> getOwner() { <span class="keyword">return</span> owner; }
+    <span class="directive">public</span> <span class="type">void</span> setOwner(<span class="directive">final</span> <span class="predefined-type">Owner</span> owner) { <span class="local-variable">this</span>.owner = owner; }
+    <span class="directive">public</span> <span class="predefined-type">Collection</span>&lt;<span class="predefined-type">Owner</span>&gt; autoCompleteOwner(<span class="directive">final</span> <span class="annotation">@MinLength</span>(<span class="integer">1</span>) <span class="predefined-type">String</span> name) {
+        <span class="keyword">return</span> owners.findByName(name);
+    }
+    ...
+}</code></pre>
+</div>
+</div>
+<div class="paragraph">
+<p>Also updated fixture data to set up a number of <code>Owner`s, and associate each `Pet</code> with an <code>Owner</code>. Also add unit tests and integration tests for <code>Owner</code>/<code>Owners</code> and updated for <code>Pet</code>/<code>Pets</code>.</p>
+</div>
+<div class="paragraph">
+<p>When running the app, notice the new <code>Owners</code> menu:</p>
+</div>
+<div class="imageblock">
+<div class="content">
+<a class="image" href="images/tutorials/pet-clinic/060-01-owners-menu.png"><img src="images/tutorials/pet-clinic/060-01-owners-menu.png" alt="060 01 owners menu" width="600px"></a>
+</div>
+</div>
+<div class="paragraph">
+<p>which when invoked returns all <code>Owner</code> objects:</p>
+</div>
+<div class="imageblock">
+<div class="content">
+<a class="image" href="images/tutorials/pet-clinic/060-02-owners-list.png"><img src="images/tutorials/pet-clinic/060-02-owners-list.png" alt="060 02 owners list" width="600px"></a>
+</div>
+</div>
+<div class="paragraph">
+<p>Each <code>Pet</code> also indicates its corresponding <code>Owner</code>:</p>
+</div>
+<div class="imageblock">
+<div class="content">
+<a class="image" href="images/tutorials/pet-clinic/060-03-pets-list.png"><img src="images/tutorials/pet-clinic/060-03-pets-list.png" alt="060 03 pets list" width="600px"></a>
+</div>
+</div>
+<div class="paragraph">
+<p>And, on editing a <code>Pet</code>, a new <code>Owner</code> can be specified using the autoComplete:</p>
+</div>
+<div class="imageblock">
+<div class="content">
+<a class="image" href="images/tutorials/pet-clinic/060-04-pet-owner-autoComplete.png"><img src="images/tutorials/pet-clinic/060-04-pet-owner-autoComplete.png" alt="060 04 pet owner autoComplete" width="600px"></a>
+</div>
+</div>
+</div>
+</div>
+</div>
+<div class="sect1">
+<h2 id="_ug_tutorials_stop-scaffolding-start-coding">Stop scaffolding, start coding</h2>
+<div class="sectionbody">
+<div class="paragraph">
+<p>This is a half-day tutorial on developing domain-driven apps using Apache Isis.  Actually, you could probably spend a full day working through this tutorial if you wanted to, so pick and choose the bits that look interesting.</p>
+</div>
+<div class="paragraph">
+<p>There&#8217;s a bit of overlap with the <a href="ug.html#_ug_tutorials_pet-clinic">Pet Clinic</a> tutorial initially, but it then sets off on its own.</p>
+</div>
+<div class="sect2">
+<h3 id="_prerequisites_2">Prerequisites</h3>
+<div class="paragraph">
+<p>You&#8217;ll need:</p>
+</div>
+<div class="ulist">
+<ul>
+<li>
+<p>Java 7 JDK</p>
+</li>
+<li>
+<p><a href="http://maven.apache.org/">Maven</a> 3.2.x</p>
+</li>
+<li>
+<p>an IDE, such as <a href="http://www.eclipse.org/">Eclipse</a> or <a href="https://www.jetbrains.com/idea/">IntelliJ IDEA</a>.</p>
+</li>
+</ul>
+</div>
+</div>
+<div class="sect2">
+<h3 id="_run_the_archetype_2">Run the archetype</h3>
+<div class="paragraph">
+<p>Run the simpleapp archetype to build an empty Isis application:</p>
+</div>
+<div class="listingblock">
+<div class="content">
+<pre class="CodeRay highlight"><code data-lang="bash">mvn archetype:generate  \
+    -D archetypeGroupId=org.apache.isis.archetype \
+    -D archetypeArtifactId=simpleapp-archetype \
+    -D archetypeVersion=1.8.0 \
+    -D groupId=com.mycompany \
+    -D artifactId=myapp \
+    -D version=1.0-SNAPSHOT \
+    -D archetypeRepository=http://repository-estatio.forge.cloudbees.com/snapshot/ \
+    -B</code></pre>
+</div>
+</div>
+</div>
+<div class="sect2">
+<h3 id="_build_and_run_2">Build and run</h3>
+<div class="paragraph">
+<p>Start off by building the app from the command line:</p>
+</div>
+<div class="listingblock">
+<div class="content">
+<pre class="CodeRay highlight"><code data-lang="bash">cd myapp
+mvn clean install</code></pre>
+</div>
+</div>
+<div class="paragraph">
+<p>Once that&#8217;s built then run using:</p>
+</div>
+<div class="listingblock">
+<div class="content">
+<pre class="CodeRay highlight"><code data-lang="bash">mvn antrun:run -P self-host</code></pre>
+</div>
+</div>
+<div class="paragraph">
+<p>A splash screen should appear offering to start up the app. Go ahead and start; the web browser should be opened at <a href="http://localhost:8080">http://localhost:8080</a></p>
+</div>
+<div class="paragraph">
+<p>Alternatively, you can run using the mvn-jetty-plugin:</p>
+</div>
+<div class="listingblock">
+<div class="content">
+<pre class="CodeRay highlight"><code data-lang="bash">mvn jetty:run</code></pre>
+</div>
+</div>
+<div class="paragraph">
+<p>This will accomplish the same thing, though the webapp is mounted at a slightly different URL</p>
+</div>
+</div>
+<div class="sect2">
+<h3 id="_using_the_app_2">Using the app</h3>
+<div class="paragraph">
+<p>Navigate to the Wicket UI (eg <a href="http://localhost:8080/wicket">http://localhost:8080/wicket</a>), and login (sven/pass).</p>
+</div>
+<div class="paragraph">
+<p>Once at the home page:</p>
+</div>
+<div class="ulist">
+<ul>
+<li>
+<p>install fixtures</p>
+</li>
+<li>
+<p>list all objects</p>
+</li>
+<li>
+<p>create a new object</p>
+</li>
+<li>
+<p>list all objects</p>
+</li>
+</ul>
+</div>
+<div class="paragraph">
+<p>Go back to the splash screen, and quit the app. Note that the database runs in-memory (using HSQLDB) so any data created will be lost between runs.</p>
+</div>
+</div>
+<div class="sect2">
+<h3 id="_dev_environment_2">Dev environment</h3>
+<div class="paragraph">
+<p>Set up <a href="cg.html#_cg_ide">an IDE</a> and import the project to be able to run and debug the app.</p>
+</div>
+<div class="paragraph">
+<p>Then set up a launch configuration and check that you can:</p>
+</div>
+<div class="ulist">
+<ul>
+<li>
+<p>Run the app from within the IDE</p>
+</li>
+<li>
+<p>Run the app in debug mode</p>
+</li>
+<li>
+<p>Run with different deploymentTypes; note whether prototype actions (those annotated <a href="rg.html#_rg_annotations_manpage-Action_restrictTo"><code>@Action(restrictTo=PROTOTYPING</code></a>) are available or not:</p>
+</li>
+<li>
+<p><code>--type SERVER_PROTOTYPE</code></p>
+</li>
+<li>
+<p><code>--type SERVER</code></p>
+</li>
+</ul>
+</div>
+</div>
+<div class="sect2">
+<h3 id="_explore_codebase_2">Explore codebase</h3>
+<div class="paragraph">
+<p>Apache Isis applications are organized into several Maven modules. Within your IDE navigate to the various classes and correlate back to the generated UI:</p>
+</div>
+<div class="ulist">
+<ul>
+<li>
+<p><code>myapp</code> : parent module</p>
+</li>
+<li>
+<p><code>myapp-dom</code>: domain objects module</p>
+</li>
+<li>
+<p>entity: <code>dom.simple.SimpleObject</code></p>
+</li>
+<li>
+<p>repository: <code>dom.simple.SimpleObjects</code></p>
+</li>
+<li>
+<p><code>myapp-fixture</code>: fixtures module</p>
+</li>
+<li>
+<p>fixture script:`fixture.simple.SimpleObjectsFixture`</p>
+</li>
+<li>
+<p><code>myapp-integtests</code>: integration tests module</p>
+</li>
+<li>
+<p><code>myapp-webapp</code>: webapp module</p>
+</li>
+<li>
+<p>(builds the WAR file)</p>
+</li>
+</ul>
+</div>
+</div>
+<div class="sect2">
+<h3 id="_testing_2">Testing</h3>
+<div class="paragraph">
+<p>Testing is of course massively important, and Apache Isis makes both unit testing and (end-to-end) integration testing easy. Building the app from the Maven command line ("mvn clean install") will run all tests, but you should also run the tests from within the IDE.</p>
+</div>
+<div class="ulist">
+<ul>
+<li>
+<p><code>myapp-dom</code> unit tests</p>
+</li>
+<li>
+<p>run</p>
+</li>
+<li>
+<p>inspect, eg</p>
+<div class="ulist">
+<ul>
+<li>
+<p><code>SimpleObjectTest</code></p>
+</li>
+</ul>
+</div>
+</li>
+<li>
+<p><code>myapp-integtests</code> integration tests</p>
+</li>
+<li>
+<p>run</p>
+</li>
+<li>
+<p>inspect, eg:</p>
+<div class="ulist">
+<ul>
+<li>
+<p><code>integration.tests.smoke.SimpleObjectsTest</code></p>
+</li>
+<li>
+<p><code>integration.specs.simple.SimpleObjectSpec_listAllAndCreate.feature</code></p>
+</li>
+</ul>
+</div>
+</li>
+<li>
+<p>generated report, eg</p>
+<div class="ulist">
+<ul>
+<li>
+<p><code>myapp/integtests/target/cucumber-html-report/index.html</code></p>
+<div class="ulist">
+<ul>
+<li>
+<p>change test in IDE, re-run (in Maven)</p>
+</li>
+</ul>
+</div>
+</li>
+</ul>
+</div>
+</li>
+</ul>
+</div>
+<div class="paragraph">
+<p>If you have issues with the integration tests, make sure that the domain classes have been enhanced by the DataNucleus enhancer. (The exact mechanics depends on the IDE being used).</p>
+</div>
+</div>
+<div class="sect2">
+<h3 id="_prototyping">Prototyping</h3>
+<div class="paragraph">
+<p>Although testing is important, in this tutorial we want to concentrate on how to write features and to iterate quickly. So for now, exclude the <code>integtests</code> module. Later on in the tutorial we&#8217;ll add the tests back in so you can learn how to write automated tests for the features of your app.</p>
+</div>
+<div class="paragraph">
+<p>In the parent <code>pom.xml</code>:</p>
+</div>
+<div class="listingblock">
+<div class="content">
+<pre class="CodeRay highlight"><code data-lang="xml"><span class="tag">&lt;modules&gt;</span>
+    <span class="tag">&lt;module&gt;</span>dom<span class="tag">&lt;/module&gt;</span>
+    <span class="tag">&lt;module&gt;</span>fixture<span class="tag">&lt;/module&gt;</span>
+    <span class="tag">&lt;module&gt;</span>integtests<span class="tag">&lt;/module&gt;</span>
+    <span class="tag">&lt;module&gt;</span>webapp<span class="tag">&lt;/module&gt;</span>
+<span class="tag">&lt;/modules&gt;</span></code></pre>
+</div>
+</div>
+<div class="paragraph">
+<p>change to:</p>
+</div>
+<div class="listingblock">
+<div class="content">
+<pre class="CodeRay highlight"><code data-lang="xml"><span class="tag">&lt;modules&gt;</span>
+    <span class="tag">&lt;module&gt;</span>dom<span class="tag">&lt;/module&gt;</span>
+    <span class="tag">&lt;module&gt;</span>fixture<span class="tag">&lt;/module&gt;</span>
+    <span class="comment">&lt;!--
+    &lt;module&gt;integtests&lt;/module&gt;
+    --&gt;</span>
+    <span class="tag">&lt;module&gt;</span>webapp<span class="tag">&lt;/module&gt;</span>
+<span class="tag">&lt;/modules&gt;</span></code></pre>
+</div>
+</div>
+</div>
+<div class="sect2">
+<h3 id="_build_a_domain_app">Build a domain app</h3>
+<div class="paragraph">
+<p>The remainder of the tutorial provides guidance on building a domain application. We don&#8217;t mandate any particular design, but we suggest one with no more than 3 to 6 domain entities in the first instance. If you&#8217;re stuck for ideas, then how about:</p>
+</div>
+<div class="ulist">
+<ul>
+<li>
+<p>a todo app (<code>ToDoItem</code>s)</p>
+</li>
+<li>
+<p>a pet clinic (<code>Pet</code>, <code>Owner</code>, <code>PetSpecies</code>, <code>Visit</code>)</p>
+</li>
+<li>
+<p>a library (<code>Book</code>, <code>Title</code>, <code>LibraryMember</code>, <code>Loan</code>, <code>Reservation</code>)</p>
+</li>
+<li>
+<p>a holiday cottage rental system</p>
+</li>
+<li>
+<p>a scrum/kanban system (inspired by Trello)</p>
+</li>
+<li>
+<p>a meeting planner (inspired by Doodle)</p>
+</li>
+<li>
+<p>(the domain model for) a CI server (inspired by Travis/Jenkins)</p>
+</li>
+<li>
+<p>a shipping system (inspired by the example in the DDD "blue" book)</p>
+</li>
+<li>
+<p>a system for ordering coffee (inspired by Restbucks, the example in "Rest in Practice" book)</p>
+</li>
+</ul>
+</div>
+<div class="paragraph">
+<p>Hopefully one of those ideas appeals or sparks an idea for something of your own.</p>
+</div>
+</div>
+<div class="sect2">
+<h3 id="_domain_entity">Domain entity</h3>
+<div class="paragraph">
+<p>Most domain objects in Apache Isis applications are persistent entities. In the simpleapp archetype the <code>SimpleObject</code> is an example. We can start developing our app by refactoring that class:</p>
+</div>
+<div class="ulist">
+<ul>
+<li>
+<p>rename the <code>SimpleObject</code> class</p>
+<div class="ulist">
+<ul>
+<li>
+<p>eg rename to <code>Pet</code></p>
+</li>
+</ul>
+</div>
+</li>
+<li>
+<p>if required, rename the <code>SimpleObject</code> class' <code>name</code> property</p>
+<div class="ulist">
+<ul>
+<li>
+<p>for <code>Pet</code>, can leave <code>name</code> property as is</p>
+</li>
+</ul>
+</div>
+</li>
+<li>
+<p>specify a <a href="ug.html#_ug_how-tos_ui-hints_object-titles-and-icons">title</a></p>
+</li>
+<li>
+<p>specify an <a href="ug.html#_ug_how-tos_ui-hints_object-titles-and-icons">icon</a></p>
+</li>
+<li>
+<p>make the entity bookmarkable by adding the <a href="rg.html#_rg_annotations_manpage-DomainObjectLayout_bookmarking"><code>@DomainObjectLayout#bookmarking()</code></a> attribute.</p>
+</li>
+<li>
+<p>confirm is available from bookmark panel (top-left of Wicket UI)</p>
+</li>
+</ul>
+</div>
+</div>
+<div class="sect2">
+<h3 id="_domain_service">Domain service</h3>
+<div class="paragraph">
+<p>Domain services often act as factories or repositories to entities; more generally can be used to "bridge across" to other domains/bounded contexts. Most are application-scoped, but they can also be request-scoped if required.</p>
+</div>
+<div class="paragraph">
+<p>In the simpleapp archetype the <code>SimpleObjects</code> service is a factory/repository for the original <code>SimpleObject</code> entity. For our app it therefore makes sense to refactor that class into our own first service:</p>
+</div>
+<div class="ulist">
+<ul>
+<li>
+<p>rename the <code>SimpleObjects</code> class</p>
+<div class="ulist">
+<ul>
+<li>
+<p>eg rename to <code>Pets</code></p>
+</li>
+</ul>
+</div>
+</li>
+<li>
+<p>review <code>create</code> action (acting as a factory)</p>
+<div class="ulist">
+<ul>
+<li>
+<p>as per the docs describing <a href="ug.html#_ug_how-tos_crud">how to create or delete objects</a></p>
+</li>
+</ul>
+</div>
+</li>
+<li>
+<p>rename if you wish</p>
+<div class="ulist">
+<ul>
+<li>
+<p>eg <code>newPet(&#8230;&#8203;)</code> or <code>addPet(&#8230;&#8203;)</code></p>
+</li>
+</ul>
+</div>
+</li>
+<li>
+<p>review <code>listAll</code> action (acting as a repository)</p>
+</li>
+<li>
+<p>as per the docs describing <a href="ug.html#_ug_how-tos_crud">how to write a custom repository</a></p>
+</li>
+<li>
+<p>note the annotations on the corresponding domain class (originally called <code>SimpleObject</code>, though renamed by now, eg to <code>Pet</code>)</p>
+</li>
+<li>
+<p>rename if you wish</p>
+<div class="ulist">
+<ul>
+<li>
+<p>eg <code>listPets()</code></p>
+</li>
+</ul>
+</div>
+</li>
+<li>
+<p>note the <a href="rg.html#_rg_annotations_manpage-DomainService"><code>@DomainService</code></a> annotation</p>
+</li>
+<li>
+<p>optional: add an action to a return subset of objects</p>
+<div class="ulist">
+<ul>
+<li>
+<p>use the JDO <code>@Query</code> annotation</p>
+</li>
+<li>
+<p>see for example the Isisaddons example <a href="https://github.com/isisaddons/isis-app-todoapp">todoapp</a> (not ASF), see <a href="https://github.com/apache/isis/blob/b3e936c9aae28754fb46c2df52b1cb9b023f9ab8/example/application/todoapp/dom/src/main/java/dom/todo/ToDoItem.java#L93">here</a> and <a href="https://github.com/apache/isis/blob/b3e936c9aae28754fb46c2df52b1cb9b023f9ab8/example/application/todoapp/dom/src/main/java/dom/todo/ToDoItems.java#L63">here</a></p>
+</li>
+</ul>
+</div>
+</li>
+</ul>
+</div>
+</div>
+<div class="sect2">
+<h3 id="_fixture_scripts">Fixture scripts</h3>
+<div class="paragraph">
+<p>Fixture scripts are used to setup the app into a known state. They are great for demo&#8217;s and as a time-saver when implementing a feature, and they can also be reused in automated integration tests. We usually also have a fixture script to zap all the (non-reference) data (or some logical subset of the data)</p>
+</div>
+<div class="ulist">
+<ul>
+<li>
+<p>rename the <code>SimpleObjectsTearDownFixture</code> class</p>
+</li>
+<li>
+<p>and update to delete from the appropriate underlying database table(s)</p>
+</li>
+<li>
+<p>use the injected <a href="rg.html#_rg_services-api_manpage-IsisJdoSupport"><code>IsisJdoSupport</code></a> domain service.</p>
+</li>
+<li>
+<p>refactor/rename the fixture script classes that create instances your entity:</p>
+</li>
+<li>
+<p><code>RecreateSimpleObjects</code>, which sets up a set of objects for a given scenario</p>
+</li>
+<li>
+<p><code>SimpleObjectCreate</code> which creates a single object</p>
+</li>
+<li>
+<p>note that domain services can be injected into these fixture scripts</p>
+</li>
+</ul>
+</div>
+</div>
+<div class="sect2">
+<h3 id="_actions">Actions</h3>
+<div class="paragraph">
+<p>Most business functionality is implemented using actions� basically a <code>public</code> method accepting domain classes and primitives as its parameter types. The action can return a domain entity, or a collection of entities, or a primitive/String/value, or void. If a domain entity is returned then that object is rendered immediately; if a collection is returned then the Wicket viewer renders a table. Such collections are sometimes called "standalone" collections.</p>
+</div>
+<div class="ulist">
+<ul>
+<li>
+<p>write an action to update the domain property (originally called <code>SimpleObject#name</code>, though renamed by now)</p>
+</li>
+<li>
+<p>use the <a href="rg.html#_rg_annotations_manpage-ParameterLayout_named"><code>@ParameterLayout(named=&#8230;&#8203;)</code></a> annotation to specify the name of action parameters</p>
+</li>
+<li>
+<p>use the <a href="rg.html#_rg_annotations_manpage-Action_semantics"><code>@Action(semanticsOf=&#8230;&#8203;)</code></a>  annotation to indicate the semantics of the action (safe/query-only, idempotent or non-idempotent)</p>
+</li>
+<li>
+<p>annotate safe action as bookmarkable using <a href="rg.html#_rg_annotations_manpage-ActionLayout_bookmarking"><code>@ActionLayout(bookmarking=&#8230;&#8203;)</code></a></p>
+</li>
+<li>
+<p>confirm is available from bookmark panel (top-left of Wicket UI)</p>
+</li>
+<li>
+<p>optional: add an action to clone an object</p>
+</li>
+</ul>
+</div>
+</div>
+<div class="sect2">
+<h3 id="_rest_api">REST API</h3>
+<div class="paragraph">
+<p>As well as exposing the Wicket viewer, Isis also exposes a REST API (an implementation of the <a href="http://restfulobjects.org">Restful Objects spec</a>). All of the functionality of the domain object model is available through this REST API.</p>
+</div>
+<div class="ulist">
+<ul>
+<li>
+<p>add Chrome extensions</p>
+</li>
+<li>
+<p>install <a href="https://chrome.google.com/webstore/detail/postman-rest-client/fdmmgilgnpjigdojojpjoooidkmcomcm?hl=en">Postman</a></p>
+</li>
+<li>
+<p>install <a href="https://chrome.google.com/webstore/detail/jsonview/chklaanhfefbnpoihckbnefhakgolnmc?hl=en">JSON-View</a></p>
+</li>
+<li>
+<p>browse to Wicket viewer, install fixtures</p>
+</li>
+<li>
+<p>browse to the <a href="http://localhost:8080/restful">http://localhost:8080/restful</a> API</p>
+</li>
+<li>
+<p>invoke the service to list all objects</p>
+</li>
+<li>
+<p>services</p>
+</li>
+<li>
+<p>actions</p>
+</li>
+<li>
+<p>invoke (invoking 0-arg actions is easy; the Restful Objects spec defines how to invoke N-arg actions)</p>
+</li>
+</ul>
+</div>
+</div>
+<div class="sect2">
+<h3 id="_specify_action_semantics">Specify Action semantics</h3>
+<div class="paragraph">
+<p>The semantics of an action (whether it is safe/query only, whether it is idempotent, whether it is neither) can be specified for each action; if not specified then Isis assumes non-idempotent. In the Wicket viewer this matters in that only query-only actions can be bookmarked or used as contributed properties/collections. In the RESTful viewer this matters in that it determines the HTTP verb (GET, PUT or POST) that is used to invoke the action.</p>
+</div>
+<div class="ulist">
+<ul>
+<li>
+<p>experiment changing <a href="rg.html#_rg_annotations_manpage-Action_semantics"><code>@Action(semantics=&#8230;&#8203;)</code></a> on actions</p>
+</li>
+<li>
+<p>note the HTTP methods exposed in the REST API change</p>
+</li>
+<li>
+<p>note whether the non-safe actions are bookmarkable (assuming that it has been annotated with <code>@ActionLayout(bookmarking=&#8230;&#8203;)</code>, that is).</p>
+</li>
+</ul>
+</div>
+</div>
+<div class="sect2">
+<h3 id="_value_properties">Value properties</h3>
+<div class="paragraph">
+<p>Domain entities have state: either values (primitives, strings) or references to other entities. In this section we explore adding some value properties</p>
+</div>
+<div class="ulist">
+<ul>
+<li>
+<p>add some <a href="ug.html#_ug_how-tos_class-structure_properties">value properties</a>; also:</p>
+</li>
+<li>
+<p>for string properties</p>
+<div class="ulist">
+<ul>
+<li>
+<p>use the <a href="rg.html#_rg_annotations_manpage-PropertyLayout_multiLine"><code>@Property(multiLine=&#8230;&#8203;)</code></a> annotation to render a text area instead of a text box</p>
+</li>
+<li>
+<p>use the <a href="rg.html#_rg_annotations_manpage-Property_maxLength"><code>@Property(maxLength=&#8230;&#8203;)</code></a> annotation to specify the maximum number of characters allowable</p>
+</li>
+<li>
+<p>use joda date/time properties, bigdecimals and blob/clob properties</p>
+</li>
+</ul>
+</div>
+</li>
+<li>
+<p>use the <a href="rg.html#_rg_annotations_manpage-Property_optionality"><code>@Column(allowsNull=&#8230;&#8203;)</code></a> annotation specify whether a property is optional or mandatory</p>
+</li>
+<li>
+<p>use enums for properties (eg as used in the Isis addons example <a href="https://github.com/isisaddons/isis-app-todoapp">todoapp</a>, see <a href="https://github.com/apache/isis/blob/b3e936c9aae28754fb46c2df52b1cb9b023f9ab8/example/application/todoapp/dom/src/main/java/dom/todo/ToDoItem.java#L207">here</a> and <a href="https://github.com/apache/isis/blob/b3e936c9aae28754fb46c2df52b1cb9b023f9ab8/example/application/todoapp/dom/src/main/java/dom/todo/ToDoItem.java#L266">here</a>)</p>
+</li>
+<li>
+<p>update the corresponding domain service for creating new instances</p>
+</li>
+<li>
+<p>for all non-optional properties will either need to prompt for a value, or calculate some suitable default</p>
+</li>
+<li>
+<p>change the implementation of title, if need be</p>
+</li>
+<li>
+<p>revisit the title, consider whether to use the <a href="rg.html#_rg_annotations_manpage-Title"><code>@Title</code></a> annotation</p>
+<div class="ulist">
+<ul>
+<li>
+<p>rather than the <a href="rg.html#_rg_methods_reserved_manpage-title"><code>title()</code></a> <code>title()</code> method</p>
+</li>
+</ul>
+</div>
+</li>
+<li>
+<p>order the properties using the <a href="rg.html#_rg_annotations_manpage-MemberOrder"><code>@MemberOrder</code></a>, also <code>@MemberGroupLayout</code></p>
+<div class="ulist">
+<ul>
+<li>
+<p>see also the docs on <a href="rg.html#_rg_object-layout_static">static layouts</a></p>
+</li>
+</ul>
+</div>
+</li>
+<li>
+<p>use the <a href="rg.html#_rg_annotations_manpage-PropertyLayout"><code>@PropertyLayout</code></a> annotation to position property/action parameter labels either to the LEFT, TOP or NONE</p>
+<div class="ulist">
+<ul>
+<li>
+<p>do the same for parameters using <a href="rg.html#_rg_annotations_manpage-ParameterLayout"><code>@ParameterLayout</code></a></p>
+</li>
+</ul>
+</div>
+</li>
+</ul>
+</div>
+</div>
+<div class="sect2">
+<h3 id="_reference_properties">Reference properties</h3>
+<div class="paragraph">
+<p>Domain entities can also reference other domain entities. These references may be either scalar (single-valued) or vector (multi-valued). In this section we focus on scalar reference properties.</p>
+</div>
+<div class="ulist">
+<ul>
+<li>
+<p>add some <a href="ug.html#_ug_how-tos_class-structure_properties">reference properties</a></p>
+</li>
+<li>
+<p>update the corresponding domain service (for creation actoin)</p>
+</li>
+<li>
+<p>use different techniques to obtain references (shown in drop-down list box)</p>
+<div class="ulist">
+<ul>
+<li>
+<p>use the <a href="rg.html#_rg_annotations_manpage-DomainObject_bounded"><code>@DomainObjectLayout(bounded=&#8230;&#8203;)</code></a> annotation on the referenced type if there are only a small number (bounded) of instances</p>
+</li>
+<li>
+<p>use a <a href="rg.html#_rg_methods_prefixes_manpage-choices"><code>choices&#8230;&#8203;()</code></a> supporting method</p>
+<div class="ulist">
+<ul>
+<li>
+<p>on a property</p>
+</li>
+<li>
+<p>on an action parameter</p>
+</li>
+</ul>
+</div>
+</li>
+<li>
+<p>use a <a href="rg.html#_rg_methods_prefixes_manpage-autoComplete"><code>autoComplete&#8230;&#8203;()</code></a> supporting method</p>
+<div class="ulist">
+<ul>
+<li>
+<p>on a property</p>
+</li>
+<li>
+<p>on an action parameter</p>
+</li>
+</ul>
+</div>
+</li>
+</ul>
+</div>
+</li>
+</ul>
+</div>
+</div>
+<div class="sect2">
+<h3 id="_usability_defaults">Usability: Defaults</h3>
+<div class="paragraph">
+<p>Quick detour: often we want to set up defaults to go with choices. Sensible defaults for action parameters can really improve the usability of the app.</p>
+</div>
+<div class="ulist">
+<ul>
+<li>
+<p>Add <a href="ug.html#_ug_how-tos_drop-downs-and-defaults">defaults</a> for action parameters</p>
+</li>
+</ul>
+</div>
+</div>
+<div class="sect2">
+<h3 id="_collections">Collections</h3>
+<div class="paragraph">
+<p>Returning back to references, Isis also supports vector (multi-valued) references to another object instances� in other words collections. We sometimes called these "parented" collections (to distinguish from a "standalone" collection as returned from an action)</p>
+</div>
+<div class="ulist">
+<ul>
+<li>
+<p>Ensure that all domain classes implement <code>java.lang.Comparable</code></p>
+<div class="ulist">
+<ul>
+<li>
+<p>use the <a href="rg.html#_rg_classes_utility_manpage-ObjectContracts"><code>ObjectContracts</code></a> utility class to help implement <code>Comparable</code></p>
+<div class="ulist">
+<ul>
+<li>
+<p>you can also <code>equals()</code>, <code>hashCode()</code>, <code>toString()</code></p>
+</li>
+</ul>
+</div>
+</li>
+</ul>
+</div>
+</li>
+<li>
+<p>Add a <a href="ug.html#_ug_how-tos_class-structure_collections">collection</a> to one of the entities</p>
+<div class="ulist">
+<ul>
+<li>
+<p>Use <code>SortedSet</code> as the class</p>
+</li>
+<li>
+<p>Use the <a href="rg.html#_rg_annotations_manpage-CollectionLayout_render"><code>@CollectionLayout(render=&#8230;&#8203;)</code></a> annotation to indicate if the collection should be visible or hidden by default</p>
+</li>
+</ul>
+</div>
+</li>
+<li>
+<p>optional: use the <a href="rg.html#_rg_annotations_manpage-CollectionLayout_sortedBy"><code>@CollectionLayout(sortedBy=&#8230;&#8203;)</code></a> annotation to specify a different comparator than the natural ordering</p>
+</li>
+</ul>
+</div>
+</div>
+<div class="sect2">
+<h3 id="_actions_and_collections">Actions and Collections</h3>
+<div class="paragraph">
+<p>The Wicket UI doesn&#8217;t allow collections to be modified (added to/removed from). However, we can easily write actions to accomplish the same. Moreover, these actions can provide some additional business logic. For example: it probably shouldn&#8217;t be possible to add an object twice into a collection, so it should not be presented in the list of choices/autoComplete; conversely, only those objects in the collection should be offered as choices to be removed.</p>
+</div>
+<div class="ulist">
+<ul>
+<li>
+<p>Add domain actions to add/remove from the collection</p>
+</li>
+<li>
+<p>to create objects, <a href="ug.html#_ug_how-tos_class-structure_inject-services">inject</a> associated domain service</p>
+<div class="ulist">
+<ul>
+<li>
+<p>generally we recommend using the <a href="rg.html#_rg_annotations_manpage-Inject"><code>@Inject</code></a> annotation with either private or default visibility</p>
+</li>
+</ul>
+</div>
+</li>
+<li>
+<p>the service itself should use <a href="rg.html#_rg_services-api_manpage-DomainObjectContainer"><code>DomainObjectContainer</code></a></p>
+</li>
+<li>
+<p>use the <a href="rg.html#_rg_annotations_manpage-MemberOrder"><code>@MemberOrder(name=&#8230;&#8203;)</code></a> annotation to associate an action with a property or with a collection</p>
+</li>
+</ul>
+</div>
+</div>
+<div class="sect2">
+<h3 id="_css_ui_hints">CSS UI Hints</h3>
+<div class="paragraph">
+<p>CSS classes can be associated with any class member (property, collection, action). But for actions in particular:</p>
+</div>
+<div class="ulist">
+<ul>
+<li>
+<p>the bootstrap "btn" CSS classes can be used using the <a href="rg.html#_rg_annotations_manpage-ActionLayout_cssClass"><code>@ActionLayout(cssClass=&#8230;&#8203;)</code></a> annotation</p>
+</li>
+<li>
+<p>the <a href="http://fortawesome.github.io/Font-Awesome/icons/">Font Awesome</a> icons can be used using the <a href="rg.html#_rg_annotations_manpage-ActionLayout_cssClassFa"><code>@ActionLayout(cssClassFa=&#8230;&#8203;)</code></a></p>
+</li>
+</ul>
+</div>
+<div class="paragraph">
+<p>It&#8217;s also possible to use Font Awesome icons for the <a href="ug.html#_ug_how-tos_ui-hints_object-titles-and-icons">domain object icon</a>.</p>
+</div>
+<div class="paragraph">
+<p>So:
+- for some of the actions of your domain services or entities, annotate using <code>@ActionLayout(cssClass=&#8230;&#8203;)</code> or <code>@ActionLayout(cssClassFa=&#8230;&#8203;)</code></p>
+</div>
+</div>
+<div class="sect2">
+<h3 id="_dynamic_layout">Dynamic Layout</h3>
+<div class="paragraph">
+<p>Up to this point we&#8217;ve been using annotations (<code>@MemberOrder</code>, <code>@MemberGroupLayout</code>, <code>@Named</code>, <code>@PropertyLayout</code>, <code>@ParameterLayout</code>, <code>@ActionLayout</code> and so on) for UI hints. However, the feedback loop is not good: it requires us stopping the app, editing the code, recompiling and running again. So instead, all these UI hints (and more) can be specified dynamically, using a corresponding <code>.layout.json</code> file. If edited while the app is running, it will be reloaded automatically (in IntelliJ, use Run&gt;Reload Changed Classes):</p>
+</div>
+<div class="ulist">
+<ul>
+<li>
+<p>Delete the various hint annotations and instead specify layout hints using a <a href="rg.html#_rg_object-layout_dynamic">.layout.json</a> file.</p>
+</li>
+</ul>
+</div>
+</div>
+<div class="sect2">
+<h3 id="_business_rules">Business rules</h3>
+<div class="paragraph">
+<p>Apache Isis excels for domains where there are complex business rules to enforce. The UI tries not to constrain the user from navigating around freely, however the domain objects nevertheless ensure that they cannot change into an invalid state. Such rules can be enforced either declaratively (using annotations) or imperatively (using code). The objects can do this in one of three ways:</p>
+</div>
+<div class="ulist">
+<ul>
+<li>
+<p>visibility: preventing the user from even seeing a property/collection/action</p>
+</li>
+<li>
+<p>usability: allowing the user to view a property/collection/action but not allowing the user to change it</p>
+</li>
+<li>
+<p>validity: allowing the user to modify the property/invoke the action, but validating that the new value/action arguments are correct before hand.</p>
+</li>
+</ul>
+</div>
+<div class="paragraph">
+<p>Or, more pithily: "see it, use it, do it"</p>
+</div>
+<div class="sect3">
+<h4 id="_see_it">See it!</h4>
+<div class="ulist">
+<ul>
+<li>
+<p>Use the <a href="rg.html#_rg_annotations_manpage-Property_hidden"><code>Property(hidden=&#8230;&#8203;)</code></a> annotation to make properties invisible</p>
+<div class="ulist">
+<ul>
+<li>
+<p>likewise <a href="rg.html#_rg_annotations_manpage-Collection_hidden"><code>@Collection(hidden=&#8230;&#8203;)</code></a> for collections</p>
+</li>
+<li>
+<p>the <a href="rg.html#_rg_annotations_manpage-Programmatic"><code>@Programmatic</code></a>  annotation can also be used and in many cases is to be preferred; the difference is that the latter means the member is not part of the Apache Isis metamodel.</p>
+</li>
+</ul>
+</div>
+</li>
+<li>
+<p>Use the <a href="rg.html#_rg_methods_prefixes_manpage-hide"><code>hide&#8230;&#8203;()</code></a> supporting method on properties, collections and actions to make a property/collection/action invisible according to some imperative rule</p>
+</li>
+</ul>
+</div>
+</div>
+<div class="sect3">
+<h4 id="_use_it">Use it!</h4>
+<div class="ulist">
+<ul>
+<li>
+<p>Use the <a href="rg.html#_rg_annotations_manpage-Property_editing"><code>Property(editing=&#8230;&#8203;)</code></a> annotation to make property read-only</p>
+<div class="ulist">
+<ul>
+<li>
+<p>likewise <a href="rg.html#_rg_annotations_manpage-Collection_editing"><code>@Collection(editing=&#8230;&#8203;)</code></a> for collections</p>
+</li>
+<li>
+<p>alternatively, use <a href="rg.html#_rg_annotations_manpage-DomainObject_editing"><code>@DomainObject(editing=&#8230;&#8203;)</code></a> to disable editing for all properties/collections</p>
+</li>
+</ul>
+</div>
+</li>
+<li>
+<p>Use the <a href="rg.html#_rg_methods_prefixes_manpage-disable"><code>disable&#8230;&#8203;()</code></a> supporting method on properties and actions to make a property/action disabled according to some imperative rule</p>
+</li>
+</ul>
+</div>
+</div>
+<div class="sect3">
+<h4 id="_do_it">Do it!</h4>
+<div class="ulist">
+<ul>
+<li>
+<p>use the <a href="rg.html#_rg_annotations_manpage-Property_regexPattern"><code>@Property(regexPattern=&#8230;&#8203;)</code></a> annotation to specify a regex pattern for properties, and use <a href="rg.html#_rg_annotations_manpage-Parameter_regexPattern"><code>@Parameter(regexPattern=&#8230;&#8203;)</code></a> for parameters</p>
+</li>
+<li>
+<p>use the <a href="rg.html#_rg_annotations_manpage-Property_maxLength"><code>@Property(maxLength=&#8230;&#8203;)</code></a> annotation to indicate a maxmum number of characters, and <a href="rg.html#_rg_annotations_manpage-Parameter_maxLength"><code>@Parameter(maxLength=&#8230;&#8203;)</code></a> for parameters</p>
+</li>
+<li>
+<p>Use the <a href="rg.html#_rg_methods_prefixes_manpage-validate"><code>validate&#8230;&#8203;()</code></a> supporting method on properties or action parameter</p>
+</li>
+<li>
+<p>optional: for any data type:</p>
+<div class="ulist">
+<ul>
+<li>
+<p>use the <a href="rg.html#_rg_annotations_manpage-Property_mustSatisfy"><code>Property(mustSatisfy=&#8230;&#8203;)</code></a> and <a href="rg.html#_rg_annotations_manpage-Parameter_mustSatisfy"><code>Parameter(mustSatisfy=&#8230;&#8203;)</code></a> annotations to specify arbitrary constraints on properties and parameters</p>
+</li>
+</ul>
+</div>
+</li>
+</ul>
+</div>
+</div>
+</div>
+<div class="sect2">
+<h3 id="_home_page">Home page</h3>
+<div class="paragraph">
+<p>The Wicket UI will automatically invoke the "home page" action, if available. This is a no-arg action of one of the domain services, that can return either an object (eg representing the current user) or a standalone action.</p>
+</div>
+<div class="ulist">
+<ul>
+<li>
+<p>Add the <a href="rg.html#_rg_annotations_manpage-HomePage"><code>@HomePage</code></a> annotation to one (no more) of the domain services' no-arg actions</p>
+</li>
+</ul>
+</div>
+</div>
+<div class="sect2">
+<h3 id="_clock_service">Clock Service</h3>
+<div class="paragraph">
+<p>To ensure testability, there should be no dependencies on system time, for example usage of <code>LocalDate.now()</code>. Instead the domain objects should delegate to the provided <code>ClockService</code>.</p>
+</div>
+<div class="ulist">
+<ul>
+<li>
+<p>remove any dependencies on system time (eg defaults for date/time action parameters)</p>
+</li>
+<li>
+<p>inject <a href="rg.html#_rg_services-api_manpage-ClockService"><code>ClockService</code></a></p>
+</li>
+<li>
+<p>call <code>ClockService.now()</code> etc where required.</p>
+</li>
+</ul>
+</div>
+</div>
+<div class="sect2">
+<h3 id="_using_contributions">Using Contributions</h3>
+<div class="paragraph">
+<p>One of Apache Isis' most powerful features is the ability for the UI to combine functionality from domain services into the representation of an entity. The effect is similar to traits or mix-ins in other languages, however the "mixing in" is done at runtime, within the Apache Isis metamodel. In Apache Isis' terminology, we say that the domain service action is contributed to the entity.</p>
+</div>
+<div class="paragraph">
+<p>Any action of a domain service that has a domain entity type as one of its parameter types will (by default) be contributed. If the service action takes more than one argument, or does not have safe semantics, then it will be contributed as an entity action. If the service action has precisely one parameter type (that of the entity) and has safe semantics then it will be contributed either as a collection or as a property (dependent on whether it returns a collection of a scalar).</p>
+</div>
+<div class="paragraph">
+<p>Why are contributions so useful? Because the service action will match not on the entity type, but also on any of the entity&#8217;s supertypes (all the way up to <code>java.lang.Object</code>). That means that you can apply the <a href="http://en.wikipedia.org/wiki/Dependency_inversion_principle">dependency inversion principle</a> to ensure that the modules of your application have acyclic dependencies; but in the UI it can still appear as if there are bidirectional dependencies between those modules. The lack of bidirectional dependencies can help save your app degrading into a <a href="http://en.wikipedia.org/wiki/Big_ball_of_mud">big ball of mud</a>.</p>
+</div>
+<div class="paragraph">
+<p>Finally, note that the layout of contributed actions/collections/properties can be specified using the <code>.layout.json</code> file (and it is highly recommended that you do so).</p>
+</div>
+<div class="sect3">
+<h4 id="_contributed_actions">Contributed Actions</h4>
+<div class="ulist">
+<ul>
+<li>
+<p>Write a new domain service</p>
+<div class="ulist">
+<ul>
+<li>
+<p>by convention, called "XxxContributions"</p>
+</li>
+<li>
+<p>annotate with <a href="rg.html#_rg_annotations_manpage-DomainService_nature"><code>@DomainService(nature=NatureOfService.VIEW_CONTRIBUTIONS_ONLY)</code></a></p>
+<div class="ulist">
+<ul>
+<li>
+<p>indicates that all of the service&#8217;s actions should <em>not</em> be included in the main application menu bar</p>
+</li>
+<li>
+<p>should be rendered "as if" an action of the entity</p>
+</li>
+</ul>
+</div>
+</li>
+</ul>
+</div>
+</li>
+<li>
+<p>Write an action accepting &gt;1 args:</p>
+<div class="ulist">
+<ul>
+<li>
+<p>one being a domain entity</p>
+</li>
+<li>
+<p>other being a primitive or String</p>
+</li>
+</ul>
+</div>
+</li>
+</ul>
+</div>
+</div>
+<div class="sect3">
+<h4 id="_contributed_collections">Contributed Collections</h4>
+<div class="ulist">
+<ul>
+<li>
+<p>Write a new domain service (or update the one previously)</p>
+</li>
+<li>
+<p>Write a query-only action accepting exactly 1 arg (a domain entity)</p>
+</li>
+<li>
+<p>returning a collection, list or set</p>
+</li>
+<li>
+<p>For this action:</p>
+<div class="ulist">
+<ul>
+<li>
+<p>add the <a href="rg.html#_rg_annotations_manpage-ActionLayout_contributedAs"><code>@ActionLayout(contributedAs=ASSOCIATION)</code></a> annotation</p>
+</li>
+<li>
+<p>should be rendered in the UI "as if" a collection of the entity</p>
+</li>
+</ul>
+</div>
+</li>
+<li>
+<p>use <code>.layout.json</code> to position as required</p>
+</li>
+</ul>
+</div>
+</div>
+<div class="sect3">
+<h4 id="_contributed_properties">Contributed Properties</h4>
+<div class="ulist">
+<ul>
+<li>
+<p>As for contributed collections, write a new domain service with a query-only action accepting exactly 1 arg (a domain entity); except:</p>
+<div class="ulist">
+<ul>
+<li>
+<p>returning a scalar value rather than a collection</p>
+</li>
+</ul>
+</div>
+</li>
+<li>
+<p>For this action:</p>
+<div class="ulist">
+<ul>
+<li>
+<p>add the <a href="rg.html#_rg_annotations_manpage-ActionLayout_contributedAs"><code>@ActionLayout(contributedAs=ASSOCIATION)</code></a> annotation</p>
+</li>
+</ul>
+</div>
+</li>
+<li>
+<p>should be rendered in the UI "as if" a property of the entity</p>
+</li>
+<li>
+<p>use <code>.layout.json</code> to position as required</p>
+</li>
+</ul>
+</div>
+</div>
+</div>
+<div class="sect2">
+<h3 id="_using_the_event_bus">Using the Event Bus</h3>
+<div class="paragraph">
+<p>Another way in which Apache Isis helps you keep your application nicely modulariz

<TRUNCATED>