http://git-wip-us.apache.org/repos/asf/isis-site/blob/2f475bbf/content/versions/2.0.0-M1/guides/ugbtb/ugbtb.html
----------------------------------------------------------------------
diff --git a/content/versions/2.0.0-M1/guides/ugbtb/ugbtb.html 
b/content/versions/2.0.0-M1/guides/ugbtb/ugbtb.html
new file mode 100644
index 0000000..cb599b2
--- /dev/null
+++ b/content/versions/2.0.0-M1/guides/ugbtb/ugbtb.html
@@ -0,0 +1,4455 @@
+<!doctype html>
+<html>
+ <head> 
+  <!--
+        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.
+    --> 
+  <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> 
+  <meta charset="utf-8"> 
+  <meta name="viewport" content="width=device-width, initial-scale=1.0"> 
+  <!-- No caching headers --> 
+  <meta http-equiv="cache-control" content="no-cache"> 
+  <meta http-equiv="pragma" content="no-cache"> 
+  <meta http-equiv="expires" content="-1"> 
+  <title>Beyond the Basics</title> 
+  <link rel="icon" type="image/png" href="../../images/isis-favicon.png"> 
+  <!--
+        Based on DataNucleus' template,
+        that was in turn based on an earlier version of Apache Isis' template,
+        that was in turn based on Apache Deltaspike's template.
+
+        This template uses
+        * Bootstrap v3.3.7 (https://getbootstrap.com/) for navbar.
+        * Bootstrap TOC plugin v0.4.1 (https://afeld.github.io/bootstrap-toc/)
+          for the table of contents.
+        * jQuery (necessary for Bootstrap's JavaScript plugins)
+        * Font-Awesome for some icons used by Asciidoctor
+
+        Also:
+        * Bootswatch "flatly" theme for Bootstrap 
(https://bootswatch.com/flatly).
+        * slick.js (carousel)
+        * add a link to all headers (home-grown, adapted from blog posts)
+        * integration of elasticlunr.js (home-grown, adapted from blog posts)
+    --> 
+  <link 
href="https://cdnjs.cloudflare.com/ajax/libs/bootswatch/3.3.7/flatly/bootstrap.min.css";
 rel="stylesheet"> 
+  <link href="../../css/bootstrap-toc/0.4.1/bootstrap-toc.min.css" 
rel="stylesheet"> 
+  <link href="../../css/asciidoctor/foundation.css" rel="stylesheet"> 
+  <link 
href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.3.0/css/font-awesome.min.css";
 rel="stylesheet"> 
+  <link href="../../css/slick/1.5.0/slick.css" rel="stylesheet"> 
+  <link href="../../css/slick/1.5.0/slick-theme.css" rel="stylesheet"> 
+  <link href="../../css/search-panel/search-panel.css" rel="stylesheet"> 
+  <link href="../../css/header-links/header-links.css" rel="stylesheet"> 
+  <link href="../../css/sticky-header/sticky-header.css" rel="stylesheet"> 
+  <link href="../../css/customisations.css" rel="stylesheet"> 
+  <!-- Coderay syntax formatter --> 
+  <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{color:rgba(0,0,0,.4)}
+table.CodeRay{border-collapse:separate;border-spacing:0;margin-bottom:0;border:0;background:none}
+table.CodeRay td{vertical-align: top;line-height:1.45}
+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:#000}
+.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}
+    </style> 
+ </head> 
+ <body data-spy="scroll" data-target="#toc"> 
+  <div id="basedir" style="display:none;">
+   ../../
+  </div> 
+  <div id="docname" style="display:none;">
+   ugbtb
+  </div> 
+  <div id="filetype" style="display:none;">
+   html
+  </div> 
+  <!-- Navbar --> 
+  <nav class="navbar navbar-default navbar-static-top header"> 
+   <div class="container"> 
+    <div class="navbar-header"> 
+     <!-- Three line menu button for use on mobile screens --> 
+     <button type="button" class="navbar-toggle collapsed" 
data-toggle="collapse" data-target="#navbar" aria-expanded="false" 
aria-controls="navbar"> <span class="sr-only">Toggle navigation</span> <span 
class="icon-bar"></span> <span class="icon-bar"></span> <span 
class="icon-bar"></span> </button> 
+     <a class="navbar-brand" href="../../index.html"> <img alt="Brand" 
src="../../images/isis-logo-48x48.png"> </a> 
+     <a class="navbar-brand" href="../../index.html">Apache Isis</a> 
+    </div> 
+    <!-- Navbar that will collapse on mobile screens --> 
+    <div id="navbar" class="navbar-collapse collapse"> 
+     <ul class="nav navbar-nav"> 
+      <li class="dropdown"> <a href="#" class="dropdown-toggle" 
data-toggle="dropdown" role="button" aria-haspopup="true" 
aria-expanded="false">Documentation<span class="caret"></span></a> 
+       <ul class="dropdown-menu"> 
+        <li><a href="../../documentation.html">Table of Contents</a></li> 
+        <li role="separator" class="divider"></li> 
+        <li class="dropdown-header">User Guides</li> 
+        <li><a href="../../guides/ugfun/ugfun.html">Fundamentals</a></li> 
+        <li><a href="../../guides/ugvw/ugvw.html">Wicket Viewer</a></li> 
+        <li><a href="../../guides/ugvro/ugvro.html">Restful Objects 
Viewer</a></li> 
+        <li><a href="../../guides/ugodn/ugodn.html">DataNucleus Object 
Store</a></li> 
+        <li><a href="../../guides/ugsec/ugsec.html">Security</a></li> 
+        <li><a href="../../guides/ugtst/ugtst.html">Testing</a></li> 
+        <li><a href="../../guides/ugbtb/ugbtb.html">Beyond the Basics</a></li> 
+        <li role="separator" class="divider"></li> 
+        <li class="dropdown-header">Reference Guides</li> 
+        <li><a href="../../guides/rgant/rgant.html">Annotations</a></li> 
+        <li><a href="../../guides/rgsvc/rgsvc.html">Domain Services</a></li> 
+        <li><a href="../../guides/rgcfg/rgcfg.html">Core Config' 
Properties</a></li> 
+        <li><a href="../../guides/rgcms/rgcms.html">Classes, Methods and 
Schema</a></li> 
+        <li><a href="../../guides/rgmvn/rgmvn.html">Maven plugin</a></li> 
+        <li><a href="../../guides/rgfis/rgfis.html">Framework Internal 
Services</a></li> 
+        <li role="separator" class="divider"></li> 
+        <li class="dropdown-header">Javadoc</li> 
+        <li><a 
href="http://javadoc.io/doc/org.apache.isis.core/isis-core-applib";>Applib</a></li>
 
+       </ul> </li> 
+      <li class="dropdown  hidden-sm hidden-md"> <a href="#" 
class="dropdown-toggle" data-toggle="dropdown" role="button" 
aria-haspopup="true" aria-expanded="false">Downloads<span 
class="caret"></span></a> 
+       <ul class="dropdown-menu"> 
+        <li class="dropdown-header">Maven archetypes</li> 
+        <li><a 
href="../../guides/ugfun/ugfun.html#_ugfun_getting-started_helloworld-archetype">helloworld</a></li>
 
+        <li><a 
href="../../guides/ugfun/ugfun.html#_ugfun_getting-started_simpleapp-archetype">simpleapp</a></li>
 
+        <li role="separator" class="divider"></li> 
+        <li><a href="../../downloads.html">Downloads</a></li> 
+        <li><a href="../../release-notes/release-notes.html">Release 
Notes</a></li> 
+        <li><a href="../../migration-notes/migration-notes.html">Migration 
Notes</a></li> 
+        <li role="separator" class="divider"></li> 
+        <li><a href="https://github.com/apache/isis";>Github mirror</a></li> 
+       </ul> </li> 
+      <li class="dropdown  hidden-sm"> <a href="#" class="dropdown-toggle" 
data-toggle="dropdown" role="button" aria-haspopup="true" 
aria-expanded="false">Support<span class="caret"></span></a> 
+       <ul class="dropdown-menu"> 
+        <li class="dropdown-header">Guides</li> 
+        <li><a href="../../guides/dg/dg.html">Developers' Guide</a></li> 
+        <li><a href="../../guides/cgcom/cgcom.html">Committers' Guide</a></li> 
+        <li><a href="../../guides/htg.html">Hints-n-Tips Guide</a></li> 
+        <li role="separator" class="divider"></li> 
+        <li class="dropdown-header">Mailing Lists</li> 
+        <li><a href="../../support.html">How to subscribe</a></li> 
+        <li><a 
href="https://lists.apache.org/list.html?us...@isis.apache.org";>Archives (ASF 
Pony mail)</a></li> 
+        <li><a href="http://isis.markmail.org/search/?q=";>Archives 
(Markmail)</a></li> 
+        <li role="separator" class="divider"></li> 
+        <li class="dropdown-header">Other Resources</li> 
+        <li><a href="https://issues.apache.org/jira/browse/ISIS";>ASF 
JIRA</a></li> 
+        <li><a href="https://stackoverflow.com/questions/tagged/isis";>Stack 
Overflow</a></li> 
+        <li><a href="../../help.html">Wiki, Fisheye etc.</a></li> 
+       </ul> </li> 
+      <li class="dropdown hidden-sm hidden-md"> <a href="#" 
class="dropdown-toggle" data-toggle="dropdown" role="button" 
aria-haspopup="true" aria-expanded="false">@ASF<span class="caret"></span></a> 
+       <ul class="dropdown-menu"> 
+        <li><a href="https://www.apache.org/";>Apache Homepage</a></li> 
+        <li><a 
href="https://www.apache.org/events/current-event";>Events</a></li> 
+        <li><a href="https://www.apache.org/licenses/";>Licenses</a></li> 
+        <li><a href="https://www.apache.org/security/";>Security</a></li> 
+        <li><a 
href="https://www.apache.org/foundation/sponsorship.html";>Sponsorship</a></li> 
+        <li><a 
href="https://www.apache.org/foundation/thanks.html";>Thanks</a></li> 
+        <li role="separator" class="divider"></li> 
+        <li><a href="https://whimsy.apache.org/board/minutes/Isis.html";>PMC 
board minutes</a></li> 
+       </ul> </li> 
+     </ul> 
+     <div class="nav navbar-nav navbar-right"> 
+      <!-- 'style' added to fix height of input box. FIX THIS --> 
+      <form class="navbar-form" role="search" id="search-form" style="padding: 
1px 15px;"> 
+       <div class="form-group"> 
+        <input class="form-control" id="search-field" type="text" size="30" 
placeholder="Search"> 
+       </div> 
+      </form> 
+     </div> 
+     <p class="nav navbar-text navbar-right small">v2.0.0-M1</p> 
+    </div> 
+   </div> 
+  </nav> 
+  <div class="container"> 
+   <div class="row-fluid"> 
+    <div class="col-xs-12 col-sm-12 col-md-12 col-lg-9"> 
+     <div id="search-panel"> 
+      <div id="search-results"></div> 
+      <div> 
+       <br> 
+       <a href="#" id="search-results-clear">clear</a> 
+      </div> 
+     </div> 
+     <span class="pdf-link"><a href="ugbtb.pdf"><img 
src="../../images/PDF-50.png"></a></span> 
+     <div class="page-title"> 
+      <h1>Beyond the Basics</h1> 
+     </div> 
+     <div id="doc-content">
+      <div class="btn-group" style="float: right; font-size: small; padding: 
6px;  ">
+       <button type="button" class="btn btn-xs btn-default" 
onclick="window.location.href=&quot;https://github.com/apache/isis/edit/master/adocs/documentation/src/main/asciidoc/guides/ugbtb/ugbtb.adoc&quot;";><i
 class="fa fa-pencil-square-o"></i>&nbsp;Edit</button>
+       <button type="button" class="btn btn-xs btn-default dropdown-toggle" 
data-toggle="dropdown" aria-haspopup="true" aria-expanded="false"><span 
class="caret"></span><span class="sr-only">Toggle Dropdown</span></button>
+       <ul class="dropdown-menu">
+        <li><a 
href="https://github.com/apache/isis/edit/master/adocs/documentation/src/main/asciidoc/guides/ugbtb/ugbtb.adoc";
 target="_blank"><i class="fa fa-pencil-square-o fa-fw" 
aria-hidden="true"></i>&nbsp; Edit</a></li>
+        <li><a 
href="https://github.com/apache/isis/commits/master/adocs/documentation/src/main/asciidoc/guides/ugbtb/ugbtb.adoc";
 target="_blank"><i class="fa fa-clock-o fa-fw" aria-hidden="true"></i>&nbsp; 
History</a></li>
+        <li><a 
href="https://github.com/apache/isis/raw/master/adocs/documentation/src/main/asciidoc/guides/ugbtb/ugbtb.adoc";
 target="_blank"><i class="fa fa-file-text-o fa-fw" 
aria-hidden="true"></i>&nbsp; Raw</a></li>
+        <li><a 
href="https://github.com/apache/isis/blame/master/adocs/documentation/src/main/asciidoc/guides/ugbtb/ugbtb.adoc";
 target="_blank"><i class="fa fa-hand-o-right fa-fw" 
aria-hidden="true"></i>&nbsp; Blame</a></li>
+       </ul>
+      </div> 
+      <div class="sect1"> 
+       <h2 id="__ugbtb">1. Beyond the Basics</h2> 
+       <div class="sectionbody"> 
+        <div class="paragraph"> 
+         <p>This guide provides <a 
href="../ugbtb/ugbtb.html#_ugbtb_other-techniques">more advanced</a> guidance 
on writing maintainable larger applications.</p> 
+        </div> 
+        <div class="paragraph"> 
+         <p>Later chapters discuss how to <a 
href="../ugbtb/ugbtb.html#_ugbtb_deployment">deploy</a> your app, and discuss 
other ways in which you can <a href="../ugbtb/ugbtb.html">extend</a> or adapt 
the framework itself to your particular needs.</p> 
+        </div> 
+        <div class="sect2"> 
+         <h3 id="_other_guides">1.1. Other Guides</h3> 
+         <div class="paragraph"> 
+          <p>Apache Isis documentation is broken out into a number of user, 
reference and "supporting procedures" guides.</p> 
+         </div> 
+         <div class="paragraph"> 
+          <p>The user guides available are:</p> 
+         </div> 
+         <div class="ulist"> 
+          <ul> 
+           <li> <p><a href="../ugfun/ugfun.html">Fundamentals</a></p> </li> 
+           <li> <p><a href="../ugvw/ugvw.html">Wicket viewer</a></p> </li> 
+           <li> <p><a href="../ugvro/ugvro.html">Restful Objects 
viewer</a></p> </li> 
+           <li> <p><a href="../ugodn/ugodn.html">DataNucleus object 
store</a></p> </li> 
+           <li> <p><a href="../ugsec/ugsec.html">Security</a></p> </li> 
+           <li> <p><a href="../ugtst/ugtst.html">Testing</a></p> </li> 
+           <li> <p><a href="../ugbtb/ugbtb.html">Beyond the Basics</a> (this 
guide)</p> </li> 
+          </ul> 
+         </div> 
+         <div class="paragraph"> 
+          <p>The reference guides are:</p> 
+         </div> 
+         <div class="ulist"> 
+          <ul> 
+           <li> <p><a href="../rgant/rgant.html">Annotations</a></p> </li> 
+           <li> <p><a href="../rgsvc/rgsvc.html">Domain Services</a></p> </li> 
+           <li> <p><a href="../rgcfg/rgcfg.html">Configuration 
Properties</a></p> </li> 
+           <li> <p><a href="../rgcms/rgcms.html">Classes, Methods and 
Schema</a></p> </li> 
+           <li> <p><a href="../rgmvn/rgmvn.html">Apache Isis Maven 
plugin</a></p> </li> 
+           <li> <p><a href="../rgfis/rgfis.html">Framework Internal 
Services</a></p> </li> 
+          </ul> 
+         </div> 
+         <div class="paragraph"> 
+          <p>The remaining guides are:</p> 
+         </div> 
+         <div class="ulist"> 
+          <ul> 
+           <li> <p><a href="../dg/dg.html">Developers' Guide</a> (how to set 
up a development environment for Apache Isis and contribute back to the 
project)</p> </li> 
+           <li> <p><a href="../cgcom/cgcom.html">Committers' Guide</a> 
(release procedures and related practices)</p> </li> 
+          </ul> 
+         </div> 
+        </div> 
+       </div> 
+      </div> 
+      <div class="sect1"> 
+       <h2 id="_ugbtb_i18n">2. i18n</h2>
+       <div class="btn-group" style="float: right; font-size: small; padding: 
6px; margin-top: -55px; ">
+        <button type="button" class="btn btn-xs btn-default" 
onclick="window.location.href=&quot;https://github.com/apache/isis/edit/master/adocs/documentation/src/main/asciidoc/guides/ugbtb/_ugbtb_i18n.adoc&quot;";><i
 class="fa fa-pencil-square-o"></i>&nbsp;Edit</button>
+        <button type="button" class="btn btn-xs btn-default dropdown-toggle" 
data-toggle="dropdown" aria-haspopup="true" aria-expanded="false"><span 
class="caret"></span><span class="sr-only">Toggle Dropdown</span></button>
+        <ul class="dropdown-menu">
+         <li><a 
href="https://github.com/apache/isis/edit/master/adocs/documentation/src/main/asciidoc/guides/ugbtb/_ugbtb_i18n.adoc";
 target="_blank"><i class="fa fa-pencil-square-o fa-fw" 
aria-hidden="true"></i>&nbsp; Edit</a></li>
+         <li><a 
href="https://github.com/apache/isis/commits/master/adocs/documentation/src/main/asciidoc/guides/ugbtb/_ugbtb_i18n.adoc";
 target="_blank"><i class="fa fa-clock-o fa-fw" aria-hidden="true"></i>&nbsp; 
History</a></li>
+         <li><a 
href="https://github.com/apache/isis/raw/master/adocs/documentation/src/main/asciidoc/guides/ugbtb/_ugbtb_i18n.adoc";
 target="_blank"><i class="fa fa-file-text-o fa-fw" 
aria-hidden="true"></i>&nbsp; Raw</a></li>
+         <li><a 
href="https://github.com/apache/isis/blame/master/adocs/documentation/src/main/asciidoc/guides/ugbtb/_ugbtb_i18n.adoc";
 target="_blank"><i class="fa fa-hand-o-right fa-fw" 
aria-hidden="true"></i>&nbsp; Blame</a></li>
+        </ul>
+       </div> 
+       <div class="sectionbody"> 
+        <div class="paragraph"> 
+         <p>Apache Isis' support for internationlization (i18n) allows every 
element of the domain model (the class names, property names, action names, 
parameter names and so forth) to be translated.</p> 
+        </div> 
+        <div class="paragraph"> 
+         <p>It also supports translations of messages raised imperatively, by 
which we mean as the result of a call to <code>title()</code> to obtain an 
object’s title, or messages resulting from any business rule violations (eg 
<a 
href="../rgcms/rgcms.html#_rgcms_methods_prefixes_disable"><code>disable…​()</code></a>
 or <a 
href="../rgcms/rgcms.html#_rgcms_methods_prefixes_validate"><code>validate…​()</code></a>,
 and so on.</p> 
+        </div> 
+        <div class="paragraph"> 
+         <p>The <a href="../ugvw/ugvw.html">Wicket viewer</a> (that is, its 
labels and messages) is also internationalized using the same mechanism. If no 
translations are available, then the Wicket viewer falls back to using Wicket 
resource bundles.</p> 
+        </div> 
+        <div class="paragraph"> 
+         <p>Isis does not translate the values of your domain objects, though. 
So, if you have a domain concept such as <code>Country</code> whose name is 
intended to be localized according to the current user, you will need to model 
this yourself.</p> 
+        </div> 
+        <div class="sect2"> 
+         <h3 id="__ugbtb_i18n_implementation-approach">2.1. Implementation 
Approach</h3> 
+         <div class="paragraph"> 
+          <p>Most Java frameworks tackle i18n by using Java’s own 
<code>ResourceBundle</code> API. However, there are some serious drawbacks in 
this approach, including:</p> 
+         </div> 
+         <div class="ulist"> 
+          <ul> 
+           <li> <p>if a string appears more than once (eg "name" or 
"description") then it must be translated everywhere it appears in every 
resource bundle file</p> </li> 
+           <li> <p>there is no support for plural forms (see this <a 
href="http://stackoverflow.com/questions/14326653/java-internationalization-i18n-with-proper-plurals/14327683#14327683";>SO
 answer</a>)</p> </li> 
+           <li> <p>there is no tooling support for translators</p> </li> 
+          </ul> 
+         </div> 
+         <div class="paragraph"> 
+          <p>Apache Isis therefore takes a different approach, drawing 
inspiration from GNU’s <a 
href="https://www.gnu.org/software/gettext/manual/index.html";>gettext</a> API 
and specifically its <code>.pot</code> and <code>.po</code> files. These are 
intended to be used as follows:</p> 
+         </div> 
+         <div class="ulist"> 
+          <ul> 
+           <li> <p>the <code>.pot</code> (portable object template) file holds 
the message text to be translated</p> </li> 
+           <li> <p>this file is translated into multiple <code>.po</code> 
(portable object) files, one per supported locale</p> </li> 
+           <li> <p>these <code>.po</code> files are renamed according to their 
locale, and placed into the 'appropriate' location to be picked up by the 
runtime. The name of each <code>.po</code> resolved in a very similar way to 
resource bundles.</p> </li> 
+          </ul> 
+         </div> 
+         <div class="paragraph"> 
+          <p>The format of the <code>.pot</code> and <code>.po</code> files is 
identical; the only difference is that the <code>.po</code> file has 
translations for each of the message strings. These message strings can also 
have singular and plural forms.</p> 
+         </div> 
+         <div class="admonitionblock important"> 
+          <table> 
+           <tbody>
+            <tr> 
+             <td class="icon"> <i class="fa icon-important" 
title="Important"></i> </td> 
+             <td class="content"> 
+              <div class="paragraph"> 
+               <p>Although Apache Isis' implementation is modelled after 
GNU’s API, it does <em>not</em> use any GNU software. This is for two 
reasons: (a) to simplify the toolchain/developer experience, and (b) because 
GNU software is usually GPL, which would be incompatible with the Apache 
license.</p> 
+              </div> </td> 
+            </tr> 
+           </tbody>
+          </table> 
+         </div> 
+         <div class="paragraph"> 
+          <p>This design tackles all the issues of 
<code>ResourceBundle</code>s:</p> 
+         </div> 
+         <div class="ulist"> 
+          <ul> 
+           <li> <p>the <code>.po</code> message format is such that any given 
message text to translate need only be translated once, even if it appears in 
multiple places in the application (eg "Name")</p> </li> 
+           <li> <p>the <code>.po</code> message format includes translations 
for (optional) plural form as well as singular form</p> </li> 
+           <li> <p>there are lots of freely available editors <a 
href="https://www.google.co.uk/search?q=.po+file+editor";>to be found</a>, many 
summarized on this <a href="https://www.drupal.org/node/11131";>Drupal.org</a> 
webpage.<br></p> 
+            <div class="paragraph"> 
+             <p>In fact, there are also online communities/platforms of 
translators to assist with translating files. One such is <a 
href="https://crowdin.com/";>crowdin</a> (nb: this link does not imply 
endorsement).</p> 
+            </div> </li> 
+          </ul> 
+         </div> 
+         <div class="paragraph"> 
+          <p>In Apache Isis' implementation, if the translation is missing 
from the <code>.po</code> file then the original message text from the 
<code>.pot</code> file will be returned. In fact, it isn’t even necessary for 
there to be any <code>.po</code> files; <code>.po</code> translations can be 
added piecemeal as the need arises.</p> 
+         </div> 
+        </div> 
+        <div class="sect2"> 
+         <h3 id="__ugbtb_i18n_translation-service">2.2. 
<code>TranslationService</code></h3> 
+         <div class="paragraph"> 
+          <p>The cornerstone of Apache Isis' support for i18n is the 
<code>TranslationService</code> service. This is defined in the applib with the 
following API:</p> 
+         </div> 
+         <div class="listingblock"> 
+          <div class="content"> 
+           <pre class="CodeRay highlight"><code data-lang="java"><span 
class="directive">public</span> <span class="type">interface</span> <span 
class="class">TranslationService</span> {
+    <span class="directive">public</span> <span 
class="predefined-type">String</span> translate(      <i class="conum" 
data-value="1"></i><b>(1)</b>
+            <span class="directive">final</span> <span 
class="predefined-type">String</span> context,
+            <span class="directive">final</span> <span 
class="predefined-type">String</span> text);
+    <span class="directive">public</span> <span 
class="predefined-type">String</span> translate(      <i class="conum" 
data-value="2"></i><b>(2)</b>
+            <span class="directive">final</span> <span 
class="predefined-type">String</span> context,
+            <span class="directive">final</span> <span 
class="predefined-type">String</span> singularText,
+            <span class="directive">final</span> <span 
class="predefined-type">String</span> pluralText,
+            <span class="directive">final</span> <span class="type">int</span> 
num);
+    <span class="directive">public</span> <span class="type">enum</span> Mode {
+        READ,
+        WRITE;
+    }
+    Mode getMode();               <i class="conum" 
data-value="3"></i><b>(3)</b>
+}</code></pre> 
+          </div> 
+         </div> 
+         <div class="colist arabic"> 
+          <table> 
+           <tbody>
+            <tr> 
+             <td><i class="conum" data-value="1"></i><b>1</b></td> 
+             <td>is to translate the singular form of the text</td> 
+            </tr> 
+            <tr> 
+             <td><i class="conum" data-value="2"></i><b>2</b></td> 
+             <td>is to translate the plural form of the text</td> 
+            </tr> 
+            <tr> 
+             <td><i class="conum" data-value="3"></i><b>3</b></td> 
+             <td>indicates whether the translation service is in read or write 
mode.</td> 
+            </tr> 
+           </tbody>
+          </table> 
+         </div> 
+         <div class="paragraph"> 
+          <p>The <code>translate(…​)</code> methods are closely modelled 
on GNU’s gettext API. The first version is used when no translation is 
required, the second is when both a singular and plural form will be required, 
with the <code>num</code> parameter being used to select which is returned. In 
both cases the <code>context</code> parameter provides some contextual 
information for the translator; this generally corresponds to the class 
member.</p> 
+         </div> 
+         <div class="paragraph"> 
+          <p>The mode meanwhile determines the behaviour of the service. More 
on this below.</p> 
+         </div> 
+         <div class="sect3"> 
+          <h4 id="__code_translationservicepo_code">2.2.1. 
<code>TranslationServicePo</code></h4> 
+          <div class="paragraph"> 
+           <p>Isis provides a default implementation of 
<code>TranslationService</code>, namely <code>TranslationServicePo</code>.</p> 
+          </div> 
+          <div class="paragraph"> 
+           <p>If the service is running in the normal read mode, then it 
simply provides translations for the locale of the current user. This means 
locates the appropriate <code>.po</code> file (based on the requesting user’s 
locale), finds the translation and returns it.</p> 
+          </div> 
+          <div class="paragraph"> 
+           <p>If however the service is configured to run in write mode, then 
it instead records the fact that the message was requested to be translated (a 
little like a spy/mock in unit testing mock), and returns the original message. 
The service can then be queried to discover which messages need to be 
translated. All requested translations are written into the <code>.pot</code> 
file.</p> 
+          </div> 
+          <div class="paragraph"> 
+           <p>To make the service as convenient as possible to use, the 
service configures itself as follows:</p> 
+          </div> 
+          <div class="ulist"> 
+           <ul> 
+            <li> <p>if running in prototype mode <a 
href="../rgcfg/rgcfg.html#_rgcfg_deployment-types">deployment type</a> or 
during integration tests, then the service runs in <strong>write</strong> mode, 
in which case it records all translations into the <code>.pot</code> file. The 
<code>.pot</code> file is written out when the system is shutdown.</p> </li> 
+            <li> <p>if running in server (production) mode <a 
href="../rgcfg/rgcfg.html#_rgcfg_deployment-types">deployment type</a>, then 
the service runs in <strong>read</strong> mode. It is also possible to set a 
configuration setting in <code>isis.properties</code> to force read mode even 
if running in prototype mode (useful to manually test/demo the 
translations).</p> </li> 
+           </ul> 
+          </div> 
+          <div class="paragraph"> 
+           <p>When running in write mode the original text is returned to the 
caller untranslated. If in read mode, then the translated <code>.po</code> 
files are read and translations provided as required.</p> 
+          </div> 
+         </div> 
+        </div> 
+        <div class="sect2"> 
+         <h3 id="__ugbtb_i18n_imperative-messages">2.3. Imperative 
messages</h3> 
+         <div class="paragraph"> 
+          <p>The <code>TranslationService</code> is used internally by Apache 
Isis when building up the metamodel; the name and description of every class, 
property, collection, action and action parameter is automatically translated. 
Thus the simple act of bootstrapping Apache Isis will cause most of the 
messages requiring translation (that is: those for the Apache Isis metamodel) 
to be captured by the <code>TranslationService</code>.</p> 
+         </div> 
+         <div class="paragraph"> 
+          <p>However, for an application to be fully internationalized, any 
validation messages (from either <code>disableXxx()</code> or 
<code>validateXxx()</code> supporting methods) and also possibly an object’s 
title (from the <code>title()</code> method) will also require translation. 
Moreover, these messages must be captured in the <code>.pot</code> file such 
that they can be translated.</p> 
+         </div> 
+         <div class="sect3"> 
+          <h4 id="__code_translatablestring_code">2.3.1. 
<code>TranslatableString</code></h4> 
+          <div class="paragraph"> 
+           <p>The first part of the puzzle is tackled by an extension to 
Apache Isis' programming model. Whereas previously the 
<code>disableXxx()</code> / <code>validateXxx()</code> / <code>title()</code> 
methods could only return a <code>java.lang.String</code>, they may now 
optionally return a <code>TranslatableString</code> (defined in Isis applib) 
instead.</p> 
+          </div> 
+          <div class="paragraph"> 
+           <p>Here’s a (silly) example from the <a 
href="../ugfun/ugfun.html#_ugfun_getting-started_simpleapp-archetype">SimpleApp 
archetype</a>:</p> 
+          </div> 
+          <div class="listingblock"> 
+           <div class="content"> 
+            <pre class="CodeRay highlight"><code data-lang="java"><span 
class="directive">public</span> TranslatableString validateUpdateName(<span 
class="directive">final</span> <span class="predefined-type">String</span> 
name) {
+    <span class="keyword">return</span> name.contains(<span 
class="string"><span class="delimiter">"</span><span 
class="content">!</span><span class="delimiter">"</span></span>)? 
TranslatableString.tr(<span class="string"><span 
class="delimiter">"</span><span class="content">Exclamation mark is not 
allowed</span><span class="delimiter">"</span></span>): <span 
class="predefined-constant">null</span>;
+}</code></pre> 
+           </div> 
+          </div> 
+          <div class="paragraph"> 
+           <p>This corresponds to the following entry in the <code>.pot</code> 
file:</p> 
+          </div> 
+          <div class="listingblock"> 
+           <div class="content"> 
+            <pre class="CodeRay highlight"><code data-lang="ini">#: 
dom.simple.SimpleObject#updateName()
+msgid "Exclamation mark is not allowed"
+msgstr ""</code></pre> 
+           </div> 
+          </div> 
+          <div class="paragraph"> 
+           <p>The full API of <code>TranslatableString</code> is modelled on 
the design of GNU gettext (in particular the <a 
href="https://code.google.com/p/gettext-commons/wiki/Tutorial";>gettext-commons</a>
 library):</p> 
+          </div> 
+          <div class="listingblock"> 
+           <div class="content"> 
+            <pre class="CodeRay highlight"><code data-lang="java"><span 
class="directive">public</span> <span class="directive">final</span> <span 
class="type">class</span> <span class="class">TranslatableString</span> {
+    <span class="directive">public</span> <span 
class="directive">static</span> TranslatableString tr(       <i class="conum" 
data-value="1"></i><b>(1)</b>
+            <span class="directive">final</span> <span 
class="predefined-type">String</span> pattern,
+            <span class="directive">final</span> <span 
class="predefined-type">Object</span>... paramArgs) { ... }
+    <span class="directive">public</span> <span 
class="directive">static</span> TranslatableString trn(      <i class="conum" 
data-value="2"></i><b>(2)</b>
+            <span class="directive">final</span> <span 
class="predefined-type">String</span> singularPattern,
+            <span class="directive">final</span> <span 
class="predefined-type">String</span> pluralPattern,
+            <span class="directive">final</span> <span class="type">int</span> 
number,
+            <span class="directive">final</span> <span 
class="predefined-type">Object</span>... paramArgs) { ... }
+    <span class="directive">public</span> <span 
class="predefined-type">String</span> translate(                   <i 
class="conum" data-value="3"></i><b>(3)</b>
+            <span class="directive">final</span> TranslationService 
translationService,
+            <span class="directive">final</span> <span 
class="predefined-type">String</span> context) { ... }
+}</code></pre> 
+           </div> 
+          </div> 
+          <div class="colist arabic"> 
+           <table> 
+            <tbody>
+             <tr> 
+              <td><i class="conum" data-value="1"></i><b>1</b></td> 
+              <td>returns a translatable string with a single pattern for both 
singular and plural forms.</td> 
+             </tr> 
+             <tr> 
+              <td><i class="conum" data-value="2"></i><b>2</b></td> 
+              <td>returns a translatable string with different patterns for 
singular and plural forms; the one to use is determined by the 'number' 
argument</td> 
+             </tr> 
+             <tr> 
+              <td><i class="conum" data-value="3"></i><b>3</b></td> 
+              <td>translates the string using the provided 
<code>TranslationService</code>, using the appropriate singular/regular or 
plural form, and interpolating any arguments.</td> 
+             </tr> 
+            </tbody>
+           </table> 
+          </div> 
+          <div class="paragraph"> 
+           <p>The interpolation uses the format <code>{xxx}</code>, where the 
placeholder can occur multiple times.</p> 
+          </div> 
+          <div class="paragraph"> 
+           <p>For example:</p> 
+          </div> 
+          <div class="listingblock"> 
+           <div class="content"> 
+            <pre class="CodeRay highlight"><code data-lang="java"><span 
class="directive">final</span> TranslatableString ts = TranslatableString.tr(
+    <span class="string"><span class="delimiter">"</span><span 
class="content">My name is {lastName}, {firstName} {lastName}.</span><span 
class="delimiter">"</span></span>,
+    <span class="string"><span class="delimiter">"</span><span 
class="content">lastName</span><span class="delimiter">"</span></span>, <span 
class="string"><span class="delimiter">"</span><span 
class="content">Bond</span><span class="delimiter">"</span></span>, <span 
class="string"><span class="delimiter">"</span><span 
class="content">firstName</span><span class="delimiter">"</span></span>, <span 
class="string"><span class="delimiter">"</span><span 
class="content">James</span><span 
class="delimiter">"</span></span>);</code></pre> 
+           </div> 
+          </div> 
+          <div class="paragraph"> 
+           <p>would interpolate (for the English locale) as "My name is Bond, 
James Bond".</p> 
+          </div> 
+          <div class="paragraph"> 
+           <p>For a German user, on the other hand, if the translation in the 
corresponding <code>.po</code> file was:</p> 
+          </div> 
+          <div class="listingblock"> 
+           <div class="content"> 
+            <pre class="CodeRay highlight"><code data-lang="ini">#: 
xxx.yyy.Whatever#context()
+msgid "My name is {lastName}, {firstName} {lastName}."
+msgstr "Ich heisse {firstName} {lastName}."</code></pre> 
+           </div> 
+          </div> 
+          <div class="paragraph"> 
+           <p>then the translation would be: "Ich heisse James Bond".</p> 
+          </div> 
+          <div class="paragraph"> 
+           <p>The same class is used in <a 
href="../rgsvc/rgsvc.html#_rgsvc_core-domain-api_DomainObjectContainer"><code>DomainObjectContainer</code></a>
 so that you can raise translatable info, warning and error messages; each of 
the relevant methods are overloaded.</p> 
+          </div> 
+          <div class="paragraph"> 
+           <p>For example:</p> 
+          </div> 
+          <div class="listingblock"> 
+           <div class="content"> 
+            <pre class="CodeRay highlight"><code data-lang="java"><span 
class="directive">public</span> <span class="type">interface</span> <span 
class="class">DomainObjectContainer</span> {
+    <span class="type">void</span> informUser(<span 
class="predefined-type">String</span> message);
+    <span class="type">void</span> informUser(
+        TranslatableMessage message,
+        <span class="directive">final</span> <span 
class="predefined-type">Class</span>&lt;?&gt; contextClass, <span 
class="directive">final</span> <span class="predefined-type">String</span> 
contextMethod); <i class="conum" data-value="1"></i><b>(1)</b>
+    ...
+}</code></pre> 
+           </div> 
+          </div> 
+          <div class="colist arabic"> 
+           <table> 
+            <tbody>
+             <tr> 
+              <td><i class="conum" data-value="1"></i><b>1</b></td> 
+              <td>are concatenated together to form the context for the 
<code>.pot</code> file.</td> 
+             </tr> 
+            </tbody>
+           </table> 
+          </div> 
+         </div> 
+         <div class="sect3"> 
+          <h4 id="__code_translatableexception_code">2.3.2. 
<code>TranslatableException</code></h4> 
+          <div class="paragraph"> 
+           <p>Another mechanism by which messages can be rendered to the user 
are as the result of exception messages thrown and recognized by an <a 
href="../rgsvc/rgsvc.html#_rgsvc_presentation-layer-spi_ExceptionRecognizer"><code>ExceptionRecognizer</code></a>.</p>
 
+          </div> 
+          <div class="paragraph"> 
+           <p>In this case, if the exception implements 
<code>TranslatableException</code>, then the message will automatically be 
translated before being rendered. The <code>TranslatableException</code> itself 
takes the form:</p> 
+          </div> 
+          <div class="listingblock"> 
+           <div class="content"> 
+            <pre class="CodeRay highlight"><code data-lang="java"><span 
class="directive">public</span> <span class="type">interface</span> <span 
class="class">TranslatableException</span> {
+    TranslatableString getTranslatableMessage(); <i class="conum" 
data-value="1"></i><b>(1)</b>
+    <span class="predefined-type">String</span> getTranslationContext();       
       <i class="conum" data-value="2"></i><b>(2)</b>
+}</code></pre> 
+           </div> 
+          </div> 
+          <div class="colist arabic"> 
+           <table> 
+            <tbody>
+             <tr> 
+              <td><i class="conum" data-value="1"></i><b>1</b></td> 
+              <td>the message to translate. If returns <code>null</code>, then 
the <code>Exception#getMessage()</code> is used as a fallback</td> 
+             </tr> 
+             <tr> 
+              <td><i class="conum" data-value="2"></i><b>2</b></td> 
+              <td>the context to use when translating the message</td> 
+             </tr> 
+            </tbody>
+           </table> 
+          </div> 
+         </div> 
+        </div> 
+        <div class="sect2"> 
+         <h3 id="__ugbtb_i18n_wicket-viewer">2.4. Wicket Viewer</h3> 
+         <div class="paragraph"> 
+          <p>The <a href="../ugvw/ugvw.html">Wicket viewer</a> (its labels and 
messages) is also internationalized using the <code>TranslationService</code>. 
This is done through an Isis-specific implementation of the Wicket 
framework’s <code>org.apache.wicket.Localizer</code> class, namely 
<code>LocalizerForIsis</code>.</p> 
+         </div> 
+         <div class="paragraph"> 
+          <p>The Wicket <code>Localizer</code> defines the following API:</p> 
+         </div> 
+         <div class="listingblock"> 
+          <div class="content"> 
+           <pre class="CodeRay highlight"><code data-lang="java"><span 
class="directive">public</span> <span class="predefined-type">String</span> 
getString(
+        <span class="directive">final</span> <span 
class="predefined-type">String</span> key,               <i class="conum" 
data-value="1"></i><b>(1)</b>
+        <span class="directive">final</span> <span 
class="predefined-type">Component</span> component,      <i class="conum" 
data-value="2"></i><b>(2)</b>
+        <span class="directive">final</span> IModel&lt;?&gt; model,
+        <span class="directive">final</span> <span 
class="predefined-type">Locale</span> locale,
+        <span class="directive">final</span> <span 
class="predefined-type">String</span> style,
+        <span class="directive">final</span> <span 
class="predefined-type">String</span> defaultValue)
+    <span class="directive">throws</span> <span 
class="exception">MissingResourceException</span> { ... }</code></pre> 
+          </div> 
+         </div> 
+         <div class="colist arabic"> 
+          <table> 
+           <tbody>
+            <tr> 
+             <td><i class="conum" data-value="1"></i><b>1</b></td> 
+             <td>The key to obtain the resource for</td> 
+            </tr> 
+            <tr> 
+             <td><i class="conum" data-value="2"></i><b>2</b></td> 
+             <td>The component to get the resource for (if any)</td> 
+            </tr> 
+           </tbody>
+          </table> 
+         </div> 
+         <div class="paragraph"> 
+          <p>For example, <code>key</code> might be a value such as "okLabel", 
while <code>component</code> an internal class of the Wicket viewer, such as 
<code>EntityPropertiesForm</code>.</p> 
+         </div> 
+         <div class="paragraph"> 
+          <p>The <code>LocalizerForIsis</code> implementation uses the 
<code>key</code> as the <code>msgId</code>, while the fully qualified class 
name of the <code>component</code> is used as a context. There is one exception 
to this: if the component is the third-party select2 component (used for 
drop-downs), then that class name is used directly.</p> 
+         </div> 
+         <div class="paragraph"> 
+          <p>In the main, using Isis' i18n support means simply adding the 
appropriate translations to the <code>translation.po</code> file, for each 
locale that you require. If the translations are missing then the original 
translations from the Wicket resource bundles will be used instead.</p> 
+         </div> 
+         <div class="sect3"> 
+          <h4 id="_commonly_used">2.4.1. Commonly used</h4> 
+          <div class="paragraph"> 
+           <p>Most of the translation requirements can be covered by adding in 
the following <code>msgId</code>s:</p> 
+          </div> 
+          <div class="listingblock"> 
+           <div class="content"> 
+            <pre class="CodeRay highlight"><code data-lang="properties">#: 
org.apache.isis.viewer.wicket.ui.pages.entity.EntityPage
+msgid "CollectionContentsAsAjaxTablePanelFactory.Table"
+msgstr "Table"
+
+#: org.apache.isis.viewer.wicket.ui.pages.entity.EntityPage
+msgid "CollectionContentsAsUnresolvedPanel.Hide"
+msgstr "Hide"
+
+#: org.apache.isis.viewer.wicket.ui.pages.entity.EntityPage
+msgid "aboutLabel"
+msgstr "About"
+
+#: org.apache.isis.viewer.wicket.ui.pages.entity.EntityPage
+msgid "cancelLabel"
+msgstr "Cancel"
+
+#: org.apache.isis.viewer.wicket.ui.pages.entity.EntityPage
+msgid "datatable.no-records-found"
+msgstr "No Records Found"
+
+#: org.apache.isis.viewer.wicket.ui.pages.entity.EntityPage
+msgid "editLabel"
+msgstr "Edit"
+
+#: org.wicketstuff.select2.Select2Choice
+msgid "inputTooShortPlural"
+msgstr "Please enter {number} more characters"
+
+#: org.wicketstuff.select2.Select2Choice
+msgid "inputTooShortSingular"
+msgstr "Please enter 1 more character"
+
+#: org.wicketstuff.select2.Select2Choice
+msgid "loadMore"
+msgstr "Load more"
+
+#: org.apache.isis.viewer.wicket.ui.pages.entity.EntityPage
+msgid "logoutLabel"
+msgstr "Logout"
+
+#: org.wicketstuff.select2.Select2Choice
+msgid "noMatches"
+msgstr "No matches"
+
+#: org.apache.isis.viewer.wicket.ui.pages.entity.EntityPage
+msgid "okLabel"
+msgstr "OK"
+
+#: org.wicketstuff.select2.Select2Choice
+msgid "searching"
+msgstr "Searching..."
+
+#: org.wicketstuff.select2.Select2Choice
+msgid "selectionTooBigPlural"
+msgstr "You can only select {limit} items"
+
+#: org.wicketstuff.select2.Select2Choice
+msgid "selectionTooBigSingular"
+msgstr "You can only select 1 item"</code></pre> 
+           </div> 
+          </div> 
+         </div> 
+         <div class="sect3"> 
+          <h4 id="_login_self_sign_up">2.4.2. Login/self-sign-up</h4> 
+          <div class="paragraph"> 
+           <p>In addition, there are a reasonably large number of messages 
that are used for both login and the <a 
href="../ugvw/ugvw.html#_ugvw_features_user-registration">user registration</a> 
(self sign-up) and password reset features.</p> 
+          </div> 
+          <div class="paragraph"> 
+           <p>These are:</p> 
+          </div> 
+          <div class="listingblock"> 
+           <div class="content"> 
+            <pre class="CodeRay highlight"><code data-lang="properties">#: 
org.apache.isis.viewer.wicket.ui.pages.login.WicketSignInPage
+msgid "AutoLabel.CSS.required"
+msgstr "Required"
+
+#: org.apache.isis.viewer.wicket.ui.pages.accmngt.signup.RegistrationFormPage
+#: org.apache.isis.viewer.wicket.ui.pages.accmngt.register.RegisterPage
+#: 
org.apache.isis.viewer.wicket.ui.pages.accmngt.password_reset.PasswordResetPage
+msgid "confirmPasswordLabel"
+msgstr "Confirm password"
+
+#: org.apache.isis.viewer.wicket.ui.pages.accmngt.signup.RegistrationFormPage
+#: org.apache.isis.viewer.wicket.ui.pages.accmngt.register.RegisterPage
+msgid "emailIsNotAvailable"
+msgstr "The given email is already in use"
+
+#: 
org.apache.isis.viewer.wicket.ui.pages.accmngt.password_reset.PasswordResetPage
+msgid "emailPlaceholder"
+msgstr "Enter your email"
+
+#: org.apache.isis.viewer.wicket.ui.pages.accmngt.signup.RegistrationFormPage
+#: org.apache.isis.viewer.wicket.ui.pages.accmngt.register.RegisterPage
+msgid "emailPlaceholder"
+msgstr "Enter an email for the new account"
+
+#: org.apache.isis.viewer.wicket.ui.pages.accmngt.signup.RegistrationFormPage
+#: org.apache.isis.viewer.wicket.ui.pages.accmngt.register.RegisterPage
+#: 
org.apache.isis.viewer.wicket.ui.pages.accmngt.password_reset.PasswordResetPage
+msgid "emailLabel"
+msgstr "Email"
+
+#: org.apache.isis.viewer.wicket.ui.pages.accmngt.signup.RegistrationFormPage
+#: org.apache.isis.viewer.wicket.ui.pages.accmngt.register.RegisterPage
+#: 
org.apache.isis.viewer.wicket.ui.pages.accmngt.password_reset.PasswordResetPage
+msgid "emailSentMessage"
+msgstr "An email has been sent to '${email}' for verification."
+
+#: org.apache.isis.viewer.wicket.ui.pages.login.WicketSignInPage
+msgid "forgotPasswordLinkLabel"
+msgstr "Forgot your password?"
+
+#: org.apache.isis.viewer.wicket.ui.pages.login.WicketSignInPage
+msgid "loginHeader"
+msgstr "Login"
+
+#: 
org.apache.isis.viewer.wicket.ui.pages.accmngt.password_reset.PasswordResetPage
+msgid "noSuchUserByEmail"
+msgstr "There is no account with this email"
+
+#: 
org.apache.isis.viewer.wicket.ui.pages.accmngt.password_reset.PasswordResetPage
+msgid "noUserForAnEmailValidToken"
+msgstr "The account seems to be either already deleted or has changed its 
email address. Please try again."
+
+#: 
org.apache.isis.viewer.wicket.ui.pages.accmngt.password_reset.PasswordResetPage
+msgid "passwordChangeSuccessful"
+msgstr "The password has been changed successfully. You can &lt;a 
class=\"alert-success\" style=\"text-decoration:underline;\" 
href=\"${signInUrl}\"&gt;login&lt;/a&gt; now."
+
+#: 
org.apache.isis.viewer.wicket.ui.pages.accmngt.password_reset.PasswordResetPage
+msgid "passwordChangeUnsuccessful"
+msgstr "There was a problem while updating the password. Please try again."
+
+#: org.apache.isis.viewer.wicket.ui.pages.accmngt.signup.RegistrationFormPage
+#: org.apache.isis.viewer.wicket.ui.pages.accmngt.register.RegisterPage
+#: org.apache.isis.viewer.wicket.ui.pages.login.WicketSignInPage
+#: 
org.apache.isis.viewer.wicket.ui.pages.accmngt.password_reset.PasswordResetPage
+msgid "passwordLabel"
+msgstr "Password"
+
+#: org.apache.isis.viewer.wicket.ui.pages.accmngt.signup.RegistrationFormPage
+#: org.apache.isis.viewer.wicket.ui.pages.accmngt.register.RegisterPage
+#: org.apache.isis.viewer.wicket.ui.pages.login.WicketSignInPage
+#: 
org.apache.isis.viewer.wicket.ui.pages.accmngt.password_reset.PasswordResetPage
+msgid "passwordPlaceholder"
+msgstr "Enter password"
+
+#: 
org.apache.isis.viewer.wicket.ui.pages.accmngt.password_reset.PasswordResetPage
+msgid "passwordResetExpiredOrInvalidToken"
+msgstr "You are trying to reset the password for an expired or invalid token"
+
+#: 
org.apache.isis.viewer.wicket.ui.pages.accmngt.password_reset.PasswordResetPage
+msgid "passwordResetHeader"
+msgstr "Forgot password"
+
+#: 
org.apache.isis.viewer.wicket.ui.pages.accmngt.password_reset.PasswordResetPage
+msgid "passwordResetSubmitLabel"
+msgstr "Submit"
+
+#: org.apache.isis.viewer.wicket.ui.pages.login.WicketSignInPage
+msgid "registerButtonLabel"
+msgstr "Register"
+
+#: org.apache.isis.viewer.wicket.ui.pages.accmngt.register.RegisterPage
+msgid "registerHeader"
+msgstr "Register"
+
+#: org.apache.isis.viewer.wicket.ui.pages.login.WicketSignInPage
+msgid "rememberMeLabel"
+msgstr "Remember Me"
+
+#: org.apache.isis.viewer.wicket.ui.pages.login.WicketSignInPage
+msgid "resetButtonLabel"
+msgstr "Reset"
+
+#: org.apache.isis.viewer.wicket.ui.pages.login.WicketSignInPage
+msgid "signInButtonLabel"
+msgstr "Sign in"
+
+#: org.apache.isis.viewer.wicket.ui.pages.login.WicketSignInPage
+msgid "signUpButtonLabel"
+msgstr "Don't have an account? Sign up now."
+
+#: org.apache.isis.viewer.wicket.ui.pages.accmngt.signup.RegistrationFormPage
+#: org.apache.isis.viewer.wicket.ui.pages.accmngt.register.RegisterPage
+#: 
org.apache.isis.viewer.wicket.ui.pages.accmngt.password_reset.PasswordResetPage
+msgid "signUpButtonLabel"
+msgstr "Verify email"
+
+#: org.apache.isis.viewer.wicket.ui.pages.accmngt.signup.RegistrationFormPage
+msgid "signUpHeader"
+msgstr "Sign Up"
+
+#: org.apache.isis.viewer.wicket.ui.pages.accmngt.signup.RegistrationFormPage
+#: org.apache.isis.viewer.wicket.ui.pages.accmngt.register.RegisterPage
+#: 
org.apache.isis.viewer.wicket.ui.pages.accmngt.password_reset.PasswordResetPage
+msgid "usernameIsNotAvailable"
+msgstr "The provided username is already in use"
+
+#: org.apache.isis.viewer.wicket.ui.pages.accmngt.signup.RegistrationFormPage
+#: org.apache.isis.viewer.wicket.ui.pages.accmngt.register.RegisterPage
+#: org.apache.isis.viewer.wicket.ui.pages.login.WicketSignInPage
+#: 
org.apache.isis.viewer.wicket.ui.pages.accmngt.password_reset.PasswordResetPage
+msgid "usernameLabel"
+msgstr "Username"
+
+#: org.apache.isis.viewer.wicket.ui.pages.accmngt.signup.RegistrationFormPage
+#: org.apache.isis.viewer.wicket.ui.pages.accmngt.register.RegisterPage
+#: org.apache.isis.viewer.wicket.ui.pages.login.WicketSignInPage
+#: 
org.apache.isis.viewer.wicket.ui.pages.accmngt.password_reset.PasswordResetPage
+msgid "usernamePlaceholder"
+msgstr "Username"</code></pre> 
+           </div> 
+          </div> 
+         </div> 
+        </div> 
+        <div class="sect2"> 
+         <h3 id="__ugbtb_i18n_integration-testing">2.5. Integration 
Testing</h3> 
+         <div class="paragraph"> 
+          <p>So much for the API; but as noted, it is also necessary to ensure 
that the required translations are recorded (by the 
<code>TranslationService</code>) into the <code>.pot</code> file.</p> 
+         </div> 
+         <div class="paragraph"> 
+          <p>For this, we recommend that you ensure that all such methods are 
tested through an <a 
href="../ugtst/ugtst.html#_ugtst_integ-test-support">integration test</a> (not 
unit test).</p> 
+         </div> 
+         <div class="paragraph"> 
+          <p>For example, here’s the corresponding integration test for the 
"Exclamation mark" example from the simpleapp (above):</p> 
+         </div> 
+         <div class="listingblock"> 
+          <div class="content"> 
+           <pre class="CodeRay highlight"><code data-lang="java"><span 
class="annotation">@Rule</span>
+<span class="directive">public</span> ExpectedException expectedException = 
ExpectedException.none();
+
+<span class="annotation">@Inject</span>
+FixtureScripts fixtureScripts;
+
+<span class="annotation">@Test</span>
+<span class="directive">public</span> <span class="type">void</span> 
failsValidation() <span class="directive">throws</span> <span 
class="exception">Exception</span> {
+    <span class="comment">// given</span>
+    RecreateSimpleObjects fs = <span class="keyword">new</span> 
RecreateSimpleObjects().setNumber(<span class="integer">1</span>);
+    fixtureScripts.runFixtureScript(fs, <span 
class="predefined-constant">null</span>);
+    SimpleObject simpleObjectWrapped = wrap(fs.getSimpleObjects().get(<span 
class="integer">0</span>));
+
+    <span class="comment">// expect</span>
+    expectedExceptions.expect(InvalidException.class);
+    expectedExceptions.expectMessage(<span class="string"><span 
class="delimiter">"</span><span class="content">Exclamation mark is not 
allowed</span><span class="delimiter">"</span></span>);
+
+    <span class="comment">// when</span>
+    simpleObjectWrapped.updateName(<span class="string"><span 
class="delimiter">"</span><span class="content">new name!</span><span 
class="delimiter">"</span></span>);
+}</code></pre> 
+          </div> 
+         </div> 
+         <div class="paragraph"> 
+          <p>Running this test will result in the framework calling the 
<code>validateUpdateName(…​)</code> method, and thus to record that a 
translation is required in the <code>.pot</code> file.</p> 
+         </div> 
+         <div class="paragraph"> 
+          <p>When the integration tests are complete (that is, when Apache 
Isis is shutdown), the <code>TranslationServicePo</code> will write out all 
captured translations to its log (more on this below). This will include all 
the translations captured from the Apache Isis metamodel, along with all 
translations as exercised by the integration tests.</p> 
+         </div> 
+         <div class="paragraph"> 
+          <p>To ensure your app is fully internationalized app, you must 
therefore:</p> 
+         </div> 
+         <div class="ulist"> 
+          <ul> 
+           <li> <p>use <code>TranslatableString</code> rather than 
<code>String</code> for all validation/disable and title methods.</p> </li> 
+           <li> <p>ensure that (at a minimum) all validation messages and 
title methods are integration tested.</p> </li> 
+          </ul> 
+         </div> 
+         <div class="admonitionblock note"> 
+          <table> 
+           <tbody>
+            <tr> 
+             <td class="icon"> <i class="fa icon-note" title="Note"></i> </td> 
+             <td class="content"> 
+              <div class="paragraph"> 
+               <p>We make no apologies for this requirement: one of the 
reasons that we decided to implement Apache Isis' i18n support in this way is 
because it encourages/requires the app to be properly tested.</p> 
+              </div> 
+              <div class="paragraph"> 
+               <p>Behind the scenes Apache Isis uses a JUnit rule 
(<code>ExceptionRecognizerTranslate</code>) to intercept any exceptions that 
are thrown. These are simply passed through to the registered <a 
href="../rgsvc/rgsvc.html#_rgsvc_presentation-layer-spi_ExceptionRecognizer"><code>ExceptionRecognizer</code></a>s
 so that any messages are recorded as requiring translation.</p> 
+              </div> </td> 
+            </tr> 
+           </tbody>
+          </table> 
+         </div> 
+        </div> 
+        <div class="sect2"> 
+         <h3 id="_escaped_strings">2.6. Escaped strings</h3> 
+         <div class="paragraph"> 
+          <p>Translated messages can be escaped if required, eg to include 
embedded markup.</p> 
+         </div> 
+         <div class="listingblock"> 
+          <div class="content"> 
+           <pre class="CodeRay highlight"><code data-lang="ini">#: 
com.mycompany.myapp.OrderItem#quantity
+msgid "&lt;i&gt;Quantity&lt;/i&gt;"
+msgstr "&lt;i&gt;Quantité&lt;/i&gt;"</code></pre> 
+          </div> 
+         </div> 
+         <div class="paragraph"> 
+          <p>For this to work, the <code>namedEscaped()</code> attribute must 
be specified using either the <a 
href="../ugvw/ugvw.html#_ugvw_layout_file-based">layout file</a>, or using an 
annotation such as <a 
href="../rgant/rgant.html#_rgant-PropertyLayout"><code>@PropertyLayout</code></a>
 or <a 
href="../rgant/rgant.html#_rgant-ParameterLayout"><code>@ParameterLayout</code></a>.</p>
 
+         </div> 
+         <div class="paragraph"> 
+          <p>For example:</p> 
+         </div> 
+         <div class="listingblock"> 
+          <div class="content"> 
+           <pre class="CodeRay highlight"><code data-lang="java"><span 
class="annotation">@ParameterLayout</span>(
+    named=<span class="string"><span class="delimiter">"</span><span 
class="content">&lt;i&gt;Quantity&lt;/i&gt;</span><span 
class="delimiter">"</span></span>,      <i class="conum" 
data-value="1"></i><b>(1)</b>
+    namedEscaped=<span class="predefined-constant">false</span>
+)
+<span class="directive">public</span> <span 
class="predefined-type">Integer</span> getQuantity() { ... }</code></pre> 
+          </div> 
+         </div> 
+         <div class="colist arabic"> 
+          <table> 
+           <tbody>
+            <tr> 
+             <td><i class="conum" data-value="1"></i><b>1</b></td> 
+             <td>required (even though it won’t be used when a translation 
is read; otherwise the escaped flag is ignored)</td> 
+            </tr> 
+           </tbody>
+          </table> 
+         </div> 
+        </div> 
+        <div class="sect2"> 
+         <h3 id="__ugbtb_i18n_configuration">2.7. Configuration</h3> 
+         <div class="paragraph"> 
+          <p>There are several different aspects of the translation service 
that can be configured.</p> 
+         </div> 
+         <div class="sect3"> 
+          <h4 id="_logging">2.7.1. Logging</h4> 
+          <div class="paragraph"> 
+           <p>To configure the <code>TranslationServicePo</code> to write to 
out the <code>translations.pot</code> file, add the following to the 
<em>integtests</em> <code>logging.properties</code> file:</p> 
+          </div> 
+          <div class="listingblock"> 
+           <div class="content"> 
+            <pre class="CodeRay highlight"><code 
data-lang="ini">log4j.appender.translations-po=org.apache.log4j.FileAppender
+log4j.appender.translations-po.File=./translations.pot
+log4j.appender.translations-po.Append=false
+log4j.appender.translations-po.layout=org.apache.log4j.PatternLayout
+log4j.appender.translations-po.layout.ConversionPattern=%m%n
+
+log4j.logger.org.apache.isis.core.runtime.services.i18n.po.PoWriter=INFO,translations-po
+log4j.additivity.org.apache.isis.core.runtime.services.i18n.po.PotWriter=false</code></pre>
 
+           </div> 
+          </div> 
+          <div class="paragraph"> 
+           <p>Just to repeat, this is <em>not</em> the 
<code>WEB-INF/logging.properties</code> file, it should instead be added to the 
<code>integtests/logging.properties</code> file.</p> 
+          </div> 
+         </div> 
+         <div class="sect3"> 
+          <h4 id="_location_of_the_code_po_code_files">2.7.2. Location of the 
<code>.po</code> files</h4> 
+          <div class="paragraph"> 
+           <p>The default location of the translated <code>.po</code> files is 
in the <code>WEB-INF</code> directory. These are named and searched for 
similarly to regular Java resource bundles.</p> 
+          </div> 
+          <div class="paragraph"> 
+           <p>For example, assuming these translations:</p> 
+          </div> 
+          <div class="listingblock"> 
+           <div class="content"> 
+            <pre class="CodeRay highlight"><code 
data-lang="ini">/WEB-INF/translations-en-US.po
+        /translations-en.po
+        /translations-fr-FR.po
+        /translations.po</code></pre> 
+           </div> 
+          </div> 
+          <div class="paragraph"> 
+           <p>then:</p> 
+          </div> 
+          <div class="ulist"> 
+           <ul> 
+            <li> <p>a user with <code>en-US</code> locale will use 
<code>translations-en-US.po</code></p> </li> 
+            <li> <p>a user with <code>en-GB</code> locale will use 
<code>translations-en.po</code></p> </li> 
+            <li> <p>a user with <code>fr-FR</code> locale will use 
<code>translations-fr-FR.po</code></p> </li> 
+            <li> <p>a user with <code>fr-CA</code> locale will use 
<code>translations.po</code></p> </li> 
+           </ul> 
+          </div> 
+          <div class="paragraph"> 
+           <p>The basename for translation files is always 
<code>translations</code>; this cannot be altered.</p> 
+          </div> 
+         </div> 
+         <div class="sect3"> 
+          <h4 id="_externalized_translation_files">2.7.3. Externalized 
translation files</h4> 
+          <div class="paragraph"> 
+           <p>Normally Apache Isis configuration files are read from the 
<code>WEB-INF</code> file. However, Apache Isis can be configured to read 
config files from an <a 
href="../ugbtb/ugbtb.html#_ugbtb_deployment_externalized-configuration">external
 directory</a>; this is also supported for translations.</p> 
+          </div> 
+          <div class="paragraph"> 
+           <p>Thus, if in <code>web.xml</code> the external configuration 
directory has been set:</p> 
+          </div> 
+          <div class="listingblock"> 
+           <div class="content"> 
+            <pre class="CodeRay highlight"><code data-lang="xml"><span 
class="tag">&lt;context-param&gt;</span>
+    <span class="tag">&lt;param-name&gt;</span>isis.config.dir<span 
class="tag">&lt;/param-name&gt;</span>
+    <span class="tag">&lt;param-value&gt;</span>location of external config 
directory<span class="tag">&lt;/param-value&gt;</span>
+<span class="tag">&lt;/context-param&gt;</span></code></pre> 
+           </div> 
+          </div> 
+          <div class="paragraph"> 
+           <p>Then this directory will be used as the base for searching for 
translations (rather than the default 'WEB-INF/' directory).</p> 
+          </div> 
+         </div> 
+         <div class="sect3"> 
+          <h4 id="_force_read_mode">2.7.4. Force read mode</h4> 
+          <div class="paragraph"> 
+           <p>As noted above, if running in prototype mode then 
<code>TranslationServicePo</code> will be in write mode, if in production mode 
then will be in read mode. To force read mode (ie use translations) even if in 
prototype mode, add the following configuration property to 
<code>isis.properties</code>:</p> 
+          </div> 
+          <div class="listingblock"> 
+           <div class="content"> 
+            <pre class="CodeRay highlight"><code 
data-lang="ini">isis.services.translation.po.mode=read</code></pre> 
+           </div> 
+          </div> 
+         </div> 
+        </div> 
+        <div class="sect2"> 
+         <h3 id="_supporting_services">2.8. Supporting services</h3> 
+         <div class="paragraph"> 
+          <p>The <code>TranslationServicePo</code> has a number of 
supporting/related services.</p> 
+         </div> 
+         <div class="sect3"> 
+          <h4 id="__code_localeprovider_code">2.8.1. 
<code>LocaleProvider</code></h4> 
+          <div class="paragraph"> 
+           <p>The <code>LocaleProvider</code> API is used by the 
<code>TranslationServicePo</code> implementation to obtain the locale of the 
"current user".</p> 
+          </div> 
+          <div class="paragraph"> 
+           <p>A default implementation is provided by the Wicket viewer.</p> 
+          </div> 
+          <div class="admonitionblock note"> 
+           <table> 
+            <tbody>
+             <tr> 
+              <td class="icon"> <i class="fa icon-note" title="Note"></i> 
</td> 
+              <td class="content"> 
+               <div class="paragraph"> 
+                <p>Note that this default implementation does not support 
requests made through the Restful Objects viewer (there is no Wicket 
'application' object available); the upshot is that requests through Restful 
Objects are never translated. Registering a different implementation of 
<code>LocaleProvider</code> that taps into appropriate REST (RestEasy?) APIs 
would be the way to address this.</p> 
+               </div> </td> 
+             </tr> 
+            </tbody>
+           </table> 
+          </div> 
+         </div> 
+         <div class="sect3"> 
+          <h4 id="__code_translationsresolver_code">2.8.2. 
<code>TranslationsResolver</code></h4> 
+          <div class="paragraph"> 
+           <p>The <code>TranslationResolver</code> is used by the 
<code>TranslationService</code> implementation to lookup translations for a 
specified locale. It is this service that reads from the <code>WEB-INF/</code> 
(or externalized directory).</p> 
+          </div> 
+         </div> 
+         <div class="sect3"> 
+          <h4 id="__code_translationservicepomenu_code">2.8.3. 
<code>TranslationServicePoMenu</code></h4> 
+          <div class="paragraph"> 
+           <p>The <code>TranslationServicePoMenu</code> provides a couple of 
menu actions in the UI (prototype mode only) that interacts with the underlying 
<code>TranslationServicePo</code>:</p> 
+          </div> 
+          <div class="ulist"> 
+           <ul> 
+            <li> <p>the <code>downloadTranslationsFile()</code> action - 
available only in write mode - allows the current <code>.pot</code> file to be 
downloaded.<br></p> 
+             <div class="admonitionblock note"> 
+              <table> 
+               <tbody>
+                <tr> 
+                 <td class="icon"> <i class="fa icon-note" title="Note"></i> 
</td> 
+                 <td class="content"> 
+                  <div class="paragraph"> 
+                   <p>While this will contain all the translations from the 
metamodel, it will not necessarily contain all translations for all imperative 
methods returning <code>TranslatableString</code> instances; which are present 
and which are missing will depend on which imperative methods have been called 
(recorded by the service) prior to downloading.</p> 
+                  </div> </td> 
+                </tr> 
+               </tbody>
+              </table> 
+             </div> </li> 
+            <li> <p>the <code>clearTranslationsCache()</code> action - 
available only in read mode - will clear the cache so that new translations can 
be loaded.<br></p> 
+             <div class="paragraph"> 
+              <p>This allows a translator to edit the appropriate 
<code>translations-xx-XX.po</code> file and check the translation is correct 
without having to restart the app.</p> 
+             </div> </li> 
+           </ul> 
+          </div> 
+         </div> 
+        </div> 
+       </div> 
+      </div> 
+      <div class="sect1"> 
+       <h2 id="_ugbtb_headless-access">3. Headless access</h2>
+       <div class="btn-group" style="float: right; font-size: small; padding: 
6px; margin-top: -55px; ">
+        <button type="button" class="btn btn-xs btn-default" 
onclick="window.location.href=&quot;https://github.com/apache/isis/edit/master/adocs/documentation/src/main/asciidoc/guides/ugbtb/_ugbtb_headless-access.adoc&quot;";><i
 class="fa fa-pencil-square-o"></i>&nbsp;Edit</button>
+        <button type="button" class="btn btn-xs btn-default dropdown-toggle" 
data-toggle="dropdown" aria-haspopup="true" aria-expanded="false"><span 
class="caret"></span><span class="sr-only">Toggle Dropdown</span></button>
+        <ul class="dropdown-menu">
+         <li><a 
href="https://github.com/apache/isis/edit/master/adocs/documentation/src/main/asciidoc/guides/ugbtb/_ugbtb_headless-access.adoc";
 target="_blank"><i class="fa fa-pencil-square-o fa-fw" 
aria-hidden="true"></i>&nbsp; Edit</a></li>
+         <li><a 
href="https://github.com/apache/isis/commits/master/adocs/documentation/src/main/asciidoc/guides/ugbtb/_ugbtb_headless-access.adoc";
 target="_blank"><i class="fa fa-clock-o fa-fw" aria-hidden="true"></i>&nbsp; 
History</a></li>
+         <li><a 
href="https://github.com/apache/isis/raw/master/adocs/documentation/src/main/asciidoc/guides/ugbtb/_ugbtb_headless-access.adoc";
 target="_blank"><i class="fa fa-file-text-o fa-fw" 
aria-hidden="true"></i>&nbsp; Raw</a></li>
+         <li><a 
href="https://github.com/apache/isis/blame/master/adocs/documentation/src/main/asciidoc/guides/ugbtb/_ugbtb_headless-access.adoc";
 target="_blank"><i class="fa fa-hand-o-right fa-fw" 
aria-hidden="true"></i>&nbsp; Blame</a></li>
+        </ul>
+       </div> 
+       <div class="sectionbody"> 
+        <div class="paragraph"> 
+         <p>This section tackles the topic of enabling access to an Isis 
application directly, or at least, not through either the <a 
href="../ugvw/ugvw.html">Wicket</a> or <a 
href="../ugvro/ugvro.html">Restful</a> viewers.</p> 
+        </div> 
+        <div class="paragraph"> 
+         <p>There are several main use-cases:</p> 
+        </div> 
+        <div class="ulist"> 
+         <ul> 
+          <li> <p>enabling background execution, eg of a thread managed by 
Quartz scheduler and running within the webapp</p> </li> 
+          <li> <p>integration from other systems, eg for a subscriber on a 
pub/sub mechanism such as Camel, pushing changes through an Apache Isis domain 
model.</p> </li> 
+          <li> <p>leveraging an Isis application within a batch process</p> 
</li> 
+         </ul> 
+        </div> 
+        <div class="paragraph"> 
+         <p>Note that the calling thread runs in the same process space as the 
Apache Isis domain object model (must be physically linked to the JAR files 
containing the domain classes). For use cases where the calling thread runs in 
some other process space (eg migrating data from a legacy system), then the <a 
href="../ugvro/ugvro.html">Restful Objects viewer</a> is usually the way to 
go.</p> 
+        </div> 
+        <div class="paragraph"> 
+         <p>The API described in this chapter is reasonably low-level, 
allowing code to interact very directly with the Apache Isis metamodel and 
runtime. Such callers should be considered trusted: they do not (by default) 
honour any business rules eg implicit in the Isis annotations or 
hide/disable/validate methods. However the <a 
href="../rgsvc/rgsvc.html#_rgsvc_application-layer-api_WrapperFactory"><code>WrapperFactory</code></a>
 service could be used to enforce such business rules if required.</p> 
+        </div> 
+        <div class="sect2"> 
+         <h3 id="_ugbtb_headless-access_AbstractIsisSessionTemplate">3.1. 
AbstractIsisSessionTemplate</h3>
+         <div class="btn-group" style="float: right; font-size: small; 
padding: 6px; margin-top: -55px; ">
+          <button type="button" class="btn btn-xs btn-default" 
onclick="window.location.href=&quot;https://github.com/apache/isis/edit/master/adocs/documentation/src/main/asciidoc/guides/ugbtb/_ugbtb_headless-access_AbstractIsisSessionTemplate.adoc&quot;";><i
 class="fa fa-pencil-square-o"></i>&nbsp;Edit</button>
+          <button type="button" class="btn btn-xs btn-default dropdown-toggle" 
data-toggle="dropdown" aria-haspopup="true" aria-expanded="false"><span 
class="caret"></span><span class="sr-only">Toggle Dropdown</span></button>
+          <ul class="dropdown-menu">
+           <li><a 
href="https://github.com/apache/isis/edit/master/adocs/documentation/src/main/asciidoc/guides/ugbtb/_ugbtb_headless-access_AbstractIsisSessionTemplate.adoc";
 target="_blank"><i class="fa fa-pencil-square-o fa-fw" 
aria-hidden="true"></i>&nbsp; Edit</a></li>
+           <li><a 
href="https://github.com/apache/isis/commits/master/adocs/documentation/src/main/asciidoc/guides/ugbtb/_ugbtb_headless-access_AbstractIsisSessionTemplate.adoc";
 target="_blank"><i class="fa fa-clock-o fa-fw" aria-hidden="true"></i>&nbsp; 
History</a></li>
+           <li><a 
href="https://github.com/apache/isis/raw/master/adocs/documentation/src/main/asciidoc/guides/ugbtb/_ugbtb_headless-access_AbstractIsisSessionTemplate.adoc";
 target="_blank"><i class="fa fa-file-text-o fa-fw" 
aria-hidden="true"></i>&nbsp; Raw</a></li>
+           <li><a 
href="https://github.com/apache/isis/blame/master/adocs/documentation/src/main/asciidoc/guides/ugbtb/_ugbtb_headless-access_AbstractIsisSessionTemplate.adoc";
 target="_blank"><i class="fa fa-hand-o-right fa-fw" 
aria-hidden="true"></i>&nbsp; Blame</a></li>
+          </ul>
+         </div> 
+         <div class="paragraph"> 
+          <p>The <code>AbstractIsisSessionTemplate</code> class (whose name is 
inspired by the Spring framework’s naming convention for similar classes that 
query <a 
href="http://docs.spring.io/spring/docs/2.5.x/reference/jdbc.html#jdbc-JdbcTemplate";>JDBC</a>,
 <a 
href="http://docs.spring.io/spring/docs/2.5.x/reference/jms.html#jms-jmstemplate";>JMS</a>,
 <a 
href="http://docs.spring.io/spring/docs/2.5.x/reference/orm.html#orm-jpa-template";>JPA</a>
 etc.) provides the mechanism to open up a 'session' within the Apache Isis 
framework, in order to resolve and interact with entities.</p> 
+         </div> 
+         <div class="paragraph"> 
+          <p>The class itself is intended to be subclassed:</p> 
+         </div> 
+         <div class="listingblock"> 
+          <div class="content"> 
+           <pre class="CodeRay highlight"><code data-lang="java"><span 
class="directive">public</span> <span class="directive">abstract</span> <span 
class="type">class</span> <span 
class="class">AbstractIsisSessionTemplate</span> {
+
+    <span class="directive">public</span> <span class="type">void</span> 
execute(<span class="directive">final</span> AuthenticationSession authSession, 
<span class="directive">final</span> <span 
class="predefined-type">Object</span> context) { ... } <i class="conum" 
data-value="1"></i><b>(1)</b>
+    <span class="directive">protected</span> <span 
class="directive">abstract</span> <span class="type">void</span> 
doExecute(<span class="predefined-type">Object</span> context); <i 
class="conum" data-value="2"></i><b>(2)</b>
+
+    <span class="directive">protected</span> ObjectAdapter adapterFor(<span 
class="directive">final</span> <span class="predefined-type">Object</span> 
targetObject) { ... }
+    <span class="directive">protected</span> ObjectAdapter adapterFor(<span 
class="directive">final</span> RootOid rootOid) { ... }
+
+    <span class="directive">protected</span> PersistenceSession 
getPersistenceSession() { ... }
+    <span class="directive">protected</span> IsisTransactionManager 
getTransactionManager() { ... }
+    <span class="directive">protected</span> AdapterManager 
getAdapterManager() { ... }
+}</code></pre> 
+          </div> 
+         </div> 
+         <div class="colist arabic"> 
+          <table> 
+           <tbody>
+            <tr> 
+             <td><i class="conum" data-value="1"></i><b>1</b></td> 
+             <td><code>execute(…​)</code> sets up the 
<code>IsisSession</code> and delegates to …​</td> 
+            </tr> 
+            <tr> 
+             <td><i class="conum" data-value="2"></i><b>2</b></td> 
+             <td><code>doExecute(…​)</code>, the mandatory hook method for 
subclasses to implement. The passed object represents passes a context from the 
caller (eg the scheduler, cron job, JMS etc) that instantiated and executed the 
class.</td> 
+            </tr> 
+           </tbody>
+          </table> 
+         </div> 
+         <div class="paragraph"> 
+          <p>The <code>protected</code> methods expose key internal APIs 
within Apache Isis, for the subclass to use as necessary.</p> 
+         </div> 
+         <div class="admonitionblock tip"> 
+          <table> 
+           <tbody>
+            <tr> 
+             <td class="icon"> <i class="fa icon-tip" title="Tip"></i> </td> 
+             <td class="content"> 
+              <div class="paragraph"> 
+               <p>One notable feature of 
<code>AbstractIsisSessionTemplate</code> is that it will automatically inject 
any domain services into itself. Thus, it is relatively easy for the subclass 
to "reach into" the domain, through injected repository services.</p> 
+              </div> </td> 
+            </tr> 
+           </tbody>
+          </table> 
+         </div> 
+        </div> 
+        <div class="sect2"> 
+         <h3 id="_ugbtb_headless-access_BackgroundCommandExecution">3.2. 
BackgroundCommandExecution</h3>
+         <div class="btn-group" style="float: right; font-size: small; 
padding: 6px; margin-top: -55px; ">
+          <button type="button" class="btn btn-xs btn-default" 
onclick="window.location.href=&quot;https://github.com/apache/isis/edit/master/adocs/documentation/src/main/asciidoc/guides/ugbtb/_ugbtb_headless-access_BackgroundCommandExecution.adoc&quot;";><i
 class="fa fa-pencil-square-o"></i>&nbsp;Edit</button>
+          <button type="button" class="btn btn-xs btn-default dropdown-toggle" 
data-toggle="dropdown" aria-haspopup="true" aria-expanded="false"><span 
class="caret"></span><span class="sr-only">Toggle Dropdown</span></button>
+          <ul class="dropdown-menu">
+           <li><a 
href="https://github.com/apache/isis/edit/master/adocs/documentation/src/main/asciidoc/guides/ugbtb/_ugbtb_headless-access_BackgroundCommandExecution.adoc";
 target="_blank"><i class="fa fa-pencil-square-o fa-fw" 
aria-hidden="true"></i>&nbsp; Edit</a></li>
+           <li><a 
href="https://github.com/apache/isis/commits/master/adocs/documentation/src/main/asciidoc/guides/ugbtb/_ugbtb_headless-access_BackgroundCommandExecution.adoc";
 target="_blank"><i class="fa fa-clock-o fa-fw" aria-hidden="true"></i>&nbsp; 
History</a></li>
+           <li><a 
href="https://github.com/apache/isis/raw/master/adocs/documentation/src/main/asciidoc/guides/ugbtb/_ugbtb_headless-access_BackgroundCommandExecution.adoc";
 target="_blank"><i class="fa fa-file-text-o fa-fw" 
aria-hidden="true"></i>&nbsp; Raw</a></li>
+           <li><a 
href="https://github.com/apache/isis/blame/master/adocs/documentation/src/main/asciidoc/guides/ugbtb/_ugbtb_headless-access_BackgroundCommandExecution.adoc";
 target="_blank"><i class="fa fa-hand-o-right fa-fw" 
aria-hidden="true"></i>&nbsp; Blame</a></li>
+          </ul>
+         </div> 
+         <div class="paragraph"> 
+          <p>The <code>BackgroundCommandExecution</code> class (a subclass of 
<a 
href="../ugbtb/ugbtb.html#_ugbtb_headless-access_AbstractIsisSessionTemplate">AbstractIsisSessionTemplate</a>)
 is intended to simplify the execution of background <code>Command</code>s 
persisted by way of the <a 
href="../rgsvc/rgsvc.html#_rgsvc_application-layer-spi_CommandService"><code>CommandService</code></a>
 and the <a 
href="../rgsvc/rgsvc.html#_rgsvc_application-layer-spi_BackgroundCommandService"><code>BackgroundCommandService</code></a>.</p>
 
+         </div> 
+         <div class="paragraph"> 
+          <p>Its signature is:</p> 
+         </div> 
+         <div class="listingblock"> 
+          <div class="content"> 
+           <pre class="CodeRay highlight"><code data-lang="java"><span 
class="directive">public</span> <span class="directive">abstract</span> <span 
class="type">class</span> <span class="class">BackgroundCommandExecution</span> 
<span class="directive">extends</span> AbstractIsisSessionTemplate {
+    <span class="directive">protected</span> <span class="type">void</span> 
doExecute(<span class="predefined-type">Object</span> context) { ... }
+    <span class="directive">protected</span> <span 
class="directive">abstract</span> <span 
class="predefined-type">List</span>&lt;? <span class="directive">extends</span> 
Command&gt; findBackgroundCommandsToExecute(); <i class="conum" 
data-value="1"></i><b>(1)</b>
+}</code></pre> 
+          </div> 
+         </div> 
+         <div class="colist arabic"> 
+          <table> 
+           <tbody>
+            <tr> 
+             <td><i class="conum" data-value="1"></i><b>1</b></td> 
+             <td><code>findBackgroundCommandsToExecute()</code> is a mandatory 
hook method for subclasses to implement.</td> 
+            </tr> 
+           </tbody>
+          </table> 
+         </div> 
+         <div class="paragraph"> 
+          <p>This allows for different implementations of the 
<code>CommandService</code> and <code>BackgroundCommandService</code> to 
persist to wherever.</p> 
+         </div> 
+         <div class="paragraph"> 
+          <p>The diagram below (<a 
href="http://yuml.me/edit/363b335f";>yuml.me/363b335f</a>) shows the 
dependencies between these various classes:</p> 
+         </div> 
+         <div class="imageblock"> 
+          <div class="content"> 
+           <a class="image" 
href="images/headless-access/BackgroundCommandExecution.png"><img 
src="images/headless-access/BackgroundCommandExecution.png" 
alt="BackgroundCommandExecution" width="400px"></a> 
+          </div> 
+          <div class="title">
+           Figure 1. Inheritance Hierarchy for 
+           <code>BackgroundCommandExecution</code>
+          </div> 
+         </div> 
+         <div class="sect3"> 
+          <h4 id="_background_execution">3.2.1. Background Execution</h4> 
+          <div class="paragraph"> 
+           <p>The 
<code>BackgroundCommandExecutionFromBackgroundCommandServiceJdo</code> is a 
concrete subclass of <code>BackgroundCommandExecution</code> (see the <a 
href="../rgsvc/rgsvc.html#_rgsvc_application-layer-api_BackgroundService"><code>BackgroundCommandService</code></a>),
 the intended use being for the class to be instantiated regularly (eg every 10 
seconds) by a scheduler such as <a 
href="http://quartz-scheduler.org";>Quartz</a>) to poll for 
<code>Command</code>s to be executed, and then execute them.</p> 
+          </div> 
+          <div class="paragraph"> 
+           <p>This implementation queries for <code>Command</code>s persisted 
by the (non-ASF) <a href="http://platform.incode.org"; target="_blank">Incode 
Platform</a>'s command module’s implementations of <a 
href="../rgsvc/rgsvc.html#_rgsvc_application-layer-spi_CommandService"><code>CommandService</code></a>
 and <a 
href="../rgsvc/rgsvc.html#_rgsvc_application-layer-spi_BackgroundCommandService"><code>BackgroundCommandService</code></a>
 using the <code>BackgroundCommandServiceJdoRepository</code>.</p> 
+          </div> 
+          <div class="paragraph"> 
+           <p>The diagram below (<a 
href="http://yuml.me/edit/25343da1";>yuml.me/25343da1</a>) shows the inheritance 
hierarchy for this class:</p> 
+          </div> 
+          <div class="imageblock"> 
+           <div class="content"> 
+            <img 
src="images/headless-access/BackgroundCommandExecutionFromBackgroundCommandServiceJdo.png"
 alt="BackgroundCommandExecutionFromBackgroundCommandServiceJdo" width="500px"> 
+           </div> 
+           <div class="title">
+            Figure 2. Inheritance Hierarchy for 
+            
<code>BackgroundCommandExecutionFromBackgroundCommandServiceJdo</code>
+           </div> 
+          </div> 
+         </div> 
+        </div> 
+       </div> 
+      </div> 
+      <div class="sect1"> 
+       <h2 id="_ugbtb_hints-and-tips">4. Hints and Tips</h2>
+       <div class="btn-group" style="float: right; font-size: small; padding: 
6px; margin-top: -55px; ">
+        <button type="button" class="btn btn-xs btn-default" 
onclick="window.location.href=&quot;https://github.com/apache/isis/edit/master/adocs/documentation/src/main/asciidoc/guides/ugbtb/_ugbtb_hints-and-tips.adoc&quot;";><i
 class="fa fa-pencil-square-o"></i>&nbsp;Edit</button>
+        <button type="button" class="btn btn-xs btn-default dropdown-toggle" 
data-toggle="dropdown" aria-haspopup="true" aria-expanded="false"><span 
class="caret"></span><span class="sr-only">Toggle Dropdown</span></button>
+        <ul class="dropdown-menu">
+         <li><a 
href="https://github.com/apache/isis/edit/master/adocs/documentation/src/main/asciidoc/guides/ugbtb/_ugbtb_hints-and-tips.adoc";
 target="_blank"><i class="fa fa-pencil-square-o fa-fw" 
aria-hidden="true"></i>&nbsp; Edit</a></li>
+         <li><a 
href="https://github.com/apache/isis/commits/master/adocs/documentation/src/main/asciidoc/guides/ugbtb/_ugbtb_hints-and-tips.adoc";
 target="_blank"><i class="fa fa-clock-o fa-fw" aria-hidden="true"></i>&nbsp; 
History</a></li>
+         <li><a 
href="https://github.com/apache/isis/raw/master/adocs/documentation/src/main/asciidoc/guides/ugbtb/_ugbtb_hints-and-tips.adoc";
 target="_blank"><i class="fa fa-file-text-o fa-fw" 
aria-hidden="true"></i>&nbsp; Raw</a></li>
+         <li><a 
href="https://github.com/apache/isis/blame/master/adocs/documentation/src/main/asciidoc/guides/ugbtb/_ugbtb_hints-and-tips.adoc";
 target="_blank"><i class="fa fa-hand-o-right fa-fw" 
aria-hidden="true"></i>&nbsp; Blame</a></li>
+        </ul>
+       </div> 
+       <div class="sectionbody"> 
+        <div class="paragraph"> 
+         <p>This chapter provides some solutions for problems we’ve 
encountered ourselves or have been raised on the Apache Isis mailing lists.</p> 
+        </div> 
+        <div class="paragraph"> 
+         <p>See also hints-n-tips chapters in the:</p> 
+        </div> 
+        <div class="ulist"> 
+         <ul> 
+          <li> <p>the <a 
href="../dg/dg.html#_dg_hints-and-tips">Developers'</a> guide</p> </li> 
+          

<TRUNCATED>

Reply via email to