content/versions/1.14.0/guides/rgant.html (12,712 lines of code) (raw):
<!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>Annotations</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">
pre code {
background-color: inherit;
border-style: none;
}
pre code > span:first-child {
margin-left: -5px;
}
<style>
<!--
<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}
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;
padding-top: 30px;
}
div.documentation-page table.frame-all {
border-left: none;
border-right: none;
}
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>
<style>
.tocify {
margin-top: 80px;
}
</style>
</head>
<body>
<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™</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">
<button type="button" class="button secondary" onclick="window.location.href="https://github.com/apache/isis/edit/master/adocs/documentation/src/main/asciidoc/guides/rgant.adoc"" style="float: right; font-size: small; padding: 6px; "><i class="fa fa-pencil-square-o"></i> Edit</button>
<div class="sect1">
<h2 id="_rgant">1. Annotations</h2>
<button type="button" class="button secondary" onclick="window.location.href="https://github.com/apache/isis/edit/master/adocs/documentation/src/main/asciidoc/guides/_rgant.adoc"" style="float: right; font-size: small; padding: 6px; margin-top: -55px; "><i class="fa fa-pencil-square-o"></i> Edit</button>
<div class="sectionbody">
<div class="paragraph">
<p>This guide describes the various annotations used by Apache Isis to provide additional metadata about the domain objects. Most of these are defined by Isis itself, but some are from other libraries. It also identifies a number of annotations that are now deprecated, and indicates their replacement.</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.html">Fundamentals</a></p> </li>
<li> <p><a href="ugvw.html">Wicket viewer</a></p> </li>
<li> <p><a href="ugvro.html">Restful Objects viewer</a></p> </li>
<li> <p><a href="ugdno.html">DataNucleus object store</a></p> </li>
<li> <p><a href="ugsec.html">Security</a></p> </li>
<li> <p><a href="ugtst.html">Testing</a></p> </li>
<li> <p><a href="ugbtb.html">Beyond the Basics</a></p> </li>
</ul>
</div>
<div class="paragraph">
<p>The reference guides are:</p>
</div>
<div class="ulist">
<ul>
<li> <p><a href="#">Annotations</a> (this guide)</p> </li>
<li> <p><a href="rgsvc.html">Domain Services</a></p> </li>
<li> <p><a href="rgcfg.html">Configuration Properties</a></p> </li>
<li> <p><a href="rgcms.html">Classes, Methods and Schema</a></p> </li>
<li> <p><a href="rgmvn.html">Apache Isis Maven plugin</a></p> </li>
<li> <p><a href="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.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.html">Committers' Guide</a> (release procedures and related practices)</p> </li>
</ul>
</div>
</div>
<div class="sect2">
<h3 id="_examples">1.2. Examples</h3>
<div class="paragraph">
<p>To give just a few examples of annotations supported by Apache Isis:</p>
</div>
<div class="ulist">
<ul>
<li> <p>if a property is read-only, then this can be annotated with <code>@Property(editing=EditingDISABLED)</code>.</p> </li>
<li> <p>if a class has a small fixed set of instances (eg a picklist), then it can be annotated using <code>@DomainObject(bounded=true)</code></p> </li>
<li> <p>if a class is a domain service and should be automatically instantiated as a singleton, then it can be annotated using <code>@DomainService</code></p> </li>
<li> <p>if an action is idempotent, then it can be annotated using <code>@Action(semantics=SemanticsOf.IDEMPOTENT)</code>.</p> </li>
<li> <p>if an action parameter is optional, it can be annotated using <code>@Parameter(optionality=Optionality.OPTIONAL)</code></p> </li>
</ul>
</div>
<div class="paragraph">
<p>Some annotations act as UI hints, for example:</p>
</div>
<div class="ulist">
<ul>
<li> <p>if a collection should be rendered "open" rather than collapsed, it can be annotated using <code>@CollectionLayout(render=RenderType.EAGERLY)</code></p> </li>
<li> <p>if an action has a tooltip, it can be annotated using <code>@ActionLayout(describedAs=…)</code></p> </li>
<li> <p>if a domain object is bookmarkable, it can be annotated using <code>@DomainObjectLayout(bookmarking=BookmarkPolicy.AS_ROOT</code>).</p> </li>
</ul>
</div>
</div>
</div>
</div>
<div class="sect1">
<h2 id="_rgant_aaa">2. Summary</h2>
<button type="button" class="button secondary" onclick="window.location.href="https://github.com/apache/isis/edit/master/adocs/documentation/src/main/asciidoc/guides/_rgant_aaa.adoc"" style="float: right; font-size: small; padding: 6px; margin-top: -55px; "><i class="fa fa-pencil-square-o"></i> Edit</button>
<div class="sectionbody">
<div class="paragraph">
<p>This section summarizes the various annotations supported by Apache Isis. They break out into five categories.</p>
</div>
<div class="sect2">
<h3 id="_rgant_aaa_main">2.1. Core annotations</h3>
<button type="button" class="button secondary" onclick="window.location.href="https://github.com/apache/isis/edit/master/adocs/documentation/src/main/asciidoc/guides/_rgant_aaa_main.adoc"" style="float: right; font-size: small; padding: 6px; margin-top: -55px; "><i class="fa fa-pencil-square-o"></i> Edit</button>
<div class="paragraph">
<p>In Apache Isis every domain object is either a domain entity, a view model or a domain service. And each of these are made up of properties, collections and actions (domain services only have actions).</p>
</div>
<div class="paragraph">
<p>For each of these domain types and members there are two annotations. One covers the semantics intrinsic to the domain (eg whether an action parameter is optional or not), then other (suffix <code>…Layout</code>) captures semantics relating to the UI/presentation layer.</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>Most UI semantics can also be specified using <a href="ugfun.html#_ugfun_object-layout_dynamic">dynamic object layout</a>.</p>
</div> </td>
</tr>
</tbody>
</table>
</div>
<div class="paragraph">
<p>The table below summarizes these most commonly used annotations in Apache Isis.</p>
</div>
<table class="tableblock frame-all grid-all spread">
<caption class="title">
Table 1. Core annotations for domain objects, services and members (as of 1.8.0)
</caption>
<colgroup>
<col style="width: 25%;">
<col style="width: 50%;">
<col style="width: 12.5%;">
<col style="width: 12.5%;">
</colgroup>
<thead>
<tr>
<th class="tableblock halign-left valign-top">Annotation</th>
<th class="tableblock halign-left valign-top">Purpose</th>
<th class="tableblock halign-left valign-top">Layer</th>
<th class="tableblock halign-left valign-top"><a href="ugfun.html#_ugfun_object-layout_dynamic">Dynamic layout</a>?</th>
</tr>
</thead>
<tbody>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="#_rgant-Action"><code>@Action</code></a></p></td>
<td class="tableblock halign-left valign-top">
<div>
<div class="paragraph">
<p>Domain semantics for actions</p>
</div>
</div></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Domain</p></td>
<td class="tableblock halign-left valign-top"></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="#_rgant-ActionLayout"><code>@ActionLayout</code></a></p></td>
<td class="tableblock halign-left valign-top">
<div>
<div class="paragraph">
<p>User interface hints for actions</p>
</div>
</div></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">UI</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Yes</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="#_rgant-Collection"><code>@Collection</code></a></p></td>
<td class="tableblock halign-left valign-top">
<div>
<div class="paragraph">
<p>Domain semantics for collections</p>
</div>
</div></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Domain</p></td>
<td class="tableblock halign-left valign-top"></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="#_rgant-CollectionLayout"><code>@CollectionLayout</code></a></p></td>
<td class="tableblock halign-left valign-top">
<div>
<div class="paragraph">
<p>User interface hints for collections</p>
</div>
</div></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">UI</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Yes</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="#_rgant-DomainObject"><code>@DomainObject</code></a></p></td>
<td class="tableblock halign-left valign-top">
<div>
<div class="paragraph">
<p>Domain semantics for domain object (entities and optionally view models, see also <code>@ViewModel)</code></p>
</div>
</div></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Domain</p></td>
<td class="tableblock halign-left valign-top"></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="#_rgant-DomainObjectLayout"><code>@DomainObjectLayout</code></a></p></td>
<td class="tableblock halign-left valign-top">
<div>
<div class="paragraph">
<p>User interface hints for domain object (entities and optionally view models, see also <code>@ViewModelLayout)</code></p>
</div>
</div></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">UI</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Yes</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="#_rgant-DomainService"><code>@DomainService</code></a></p></td>
<td class="tableblock halign-left valign-top">
<div>
<div class="paragraph">
<p>Class is a domain service (rather than an entity or view model)</p>
</div>
</div></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Domain</p></td>
<td class="tableblock halign-left valign-top"></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="#_rgant-DomainServiceLayout"><code>@DomainServiceLayout</code></a></p></td>
<td class="tableblock halign-left valign-top">
<div>
<div class="paragraph">
<p>User interface hints for domain services</p>
</div>
</div></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">UI</p></td>
<td class="tableblock halign-left valign-top"></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="#_rgant-Parameter"><code>@Parameter</code></a></p></td>
<td class="tableblock halign-left valign-top">
<div>
<div class="paragraph">
<p>Domain semantics for action parameters</p>
</div>
</div></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Domain</p></td>
<td class="tableblock halign-left valign-top"></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="#_rgant-ParameterLayout"><code>@ParameterLayout</code></a></p></td>
<td class="tableblock halign-left valign-top">
<div>
<div class="paragraph">
<p>Layout hints for an action parameter (currently: its label position either to top or the left).</p>
</div>
</div></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">UI</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Yes</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="#_rgant-Property"><code>@Property</code></a></p></td>
<td class="tableblock halign-left valign-top">
<div>
<div class="paragraph">
<p>Domain semantics for properties</p>
</div>
</div></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Domain</p></td>
<td class="tableblock halign-left valign-top"></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="#_rgant-PropertyLayout"><code>@PropertyLayout</code></a></p></td>
<td class="tableblock halign-left valign-top">
<div>
<div class="paragraph">
<p>Layout hints for a property</p>
</div>
</div></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">UI</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Yes</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="#_rgant-ViewModel"><code>@ViewModel</code></a></p></td>
<td class="tableblock halign-left valign-top">
<div>
<div class="paragraph">
<p>Specify that a class is a view model (as opposed to an entity or domain service); equivalent to <code>@DomainObject(nature</code>=VIEW_MODEL).</p>
</div>
</div></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Domain, Persistence</p></td>
<td class="tableblock halign-left valign-top"></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="#_rgant-ViewModelLayout"><code>@ViewModelLayout</code></a></p></td>
<td class="tableblock halign-left valign-top">
<div>
<div class="paragraph">
<p>User interface hints for view models. For use with <code>@ViewModel</code>. If specifying view models using <code>@DomainObject(nature=VIEW_MODEL)</code> then use <code>@DomainObjectLayout</code>)</p>
</div>
</div></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">UI</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Yes</p></td>
</tr>
</tbody>
</table>
</div>
<div class="sect2">
<h3 id="_rgant_aaa_other">2.2. Other Isis Annotations</h3>
<button type="button" class="button secondary" onclick="window.location.href="https://github.com/apache/isis/edit/master/adocs/documentation/src/main/asciidoc/guides/_rgant_aaa_other.adoc"" style="float: right; font-size: small; padding: 6px; margin-top: -55px; "><i class="fa fa-pencil-square-o"></i> Edit</button>
<div class="paragraph">
<p>These annotations are also commonly used, but relate <em>not</em> to objects or object members but instead to other aspects of the Apache Isis metamodel.</p>
</div>
<table class="tableblock frame-all grid-all spread">
<caption class="title">
Table 2. Other Isis Annotations
</caption>
<colgroup>
<col style="width: 25%;">
<col style="width: 50%;">
<col style="width: 12.5%;">
<col style="width: 12.5%;">
</colgroup>
<thead>
<tr>
<th class="tableblock halign-left valign-top">Annotation</th>
<th class="tableblock halign-left valign-top">Purpose</th>
<th class="tableblock halign-left valign-top">Layer</th>
<th class="tableblock halign-left valign-top"><a href="ugfun.html#_ugfun_object-layout_dynamic">Dynamic layout</a>?</th>
</tr>
</thead>
<tbody>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="#_rgant-Facets"><code>@Facets</code></a></p></td>
<td class="tableblock halign-left valign-top">
<div>
<div class="paragraph">
<p>Install arbitrary facets within the Apache Isis metamodel.</p>
</div>
</div></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">(any)</p></td>
<td class="tableblock halign-left valign-top"></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="#_rgant-HomePage"><code>@HomePage</code></a></p></td>
<td class="tableblock halign-left valign-top">
<div>
<div class="paragraph">
<p>Query-only action (on domain service) to be invoked, result of which is rendered as the user’s home page.</p>
</div>
</div></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">UI</p></td>
<td class="tableblock halign-left valign-top"></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="#_rgant-MemberOrder"><code>@MemberOrder</code></a></p></td>
<td class="tableblock halign-left valign-top">
<div>
<div class="paragraph">
<p>Ordering of properties, collections and actions, and also associating actions with either a property or a collection.</p>
</div>
</div></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">UI</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Yes</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="#_rgant-MinLength"><code>@MinLength</code></a></p></td>
<td class="tableblock halign-left valign-top">
<div>
<div class="paragraph">
<p>Minimum number of characters required for an auto-complete search argument.</p>
</div>
</div></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">UI</p></td>
<td class="tableblock halign-left valign-top"></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="#_rgant-Programmatic"><code>@Programmatic</code></a></p></td>
<td class="tableblock halign-left valign-top">
<div>
<div class="paragraph">
<p>Ignore a public method, excluded from the Apache Isis metamodel.</p>
</div>
</div></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Domain</p></td>
<td class="tableblock halign-left valign-top"></td>
</tr>
</tbody>
</table>
</div>
<div class="sect2">
<h3 id="_rgant_aaa_jee">2.3. JDO Annotations</h3>
<button type="button" class="button secondary" onclick="window.location.href="https://github.com/apache/isis/edit/master/adocs/documentation/src/main/asciidoc/guides/_rgant_aaa_jee.adoc"" style="float: right; font-size: small; padding: 6px; margin-top: -55px; "><i class="fa fa-pencil-square-o"></i> Edit</button>
<div class="paragraph">
<p>Apache Isis uses JDO/DataNucleus as its ORM, and infers some of its own metadata from the JDO annotations.</p>
</div>
<div class="admonitionblock warning">
<table>
<tbody>
<tr>
<td class="icon"> <i class="fa icon-warning" title="Warning"></i> </td>
<td class="content">
<div class="paragraph">
<p>Isis (currently) builds up metadata by parsing the JDO annotations from source, <em>not</em> by querying the JDO metamodel. The upshot is that, for the annotations documented here at least, your domain entities must use JDO annotations rather than XML.</p>
</div>
<div class="paragraph">
<p>Furthermore, note that although JDO (the property-related) annotations to be placed on either the field or on the getter, Apache Isis requires that annotations are placed on the getter.</p>
</div> </td>
</tr>
</tbody>
</table>
</div>
<div class="paragraph">
<p>The table below lists the JDO annotations currently recognized by Apache Isis.</p>
</div>
<table class="tableblock frame-all grid-all spread">
<caption class="title">
Table 3. JDO Annotations
</caption>
<colgroup>
<col style="width: 25%;">
<col style="width: 50%;">
<col style="width: 12.5%;">
<col style="width: 12.5%;">
</colgroup>
<thead>
<tr>
<th class="tableblock halign-left valign-top">Annotation</th>
<th class="tableblock halign-left valign-top">Purpose</th>
<th class="tableblock halign-left valign-top">Layer</th>
<th class="tableblock halign-left valign-top">Applies to</th>
</tr>
</thead>
<tbody>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="#_rgant-Column"><code>@javax.jdo.annotations.</code><br> <code>Column</code></a></p></td>
<td class="tableblock halign-left valign-top">
<div>
<div class="paragraph">
<p>Used to determine whether a property is mandatory or optional. For <code>String</code> and <code>BigDecimal</code> properties, used to determine length/precision/scale.</p>
</div>
</div></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Domain / persistence</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Property</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="#_rgant-Discriminator"><code>@javax.jdo.annotations.</code><br> <code>Discriminator</code></a></p></td>
<td class="tableblock halign-left valign-top">
<div>
<div class="paragraph">
<p>Override for the object type, as used in `Bookmark`s, URLs for <a href="ugvro.html">RestfulObjects viewer</a> and elsewhere.<br></p>
</div>
<div class="paragraph">
<p>Note that the discriminator overrides the object type that may otherwise be inferred from the <a href="#_rgant-PersistenceCapable"><code>@PersistenceCapable</code></a> annotation.</p>
</div>
</div></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Domain / persistence</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Class</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="#_rgant-NotPersistent"><code>@javax.jdo.annotations.</code><br> <code>NotPersistent</code></a></p></td>
<td class="tableblock halign-left valign-top">
<div>
<div class="paragraph">
<p>Used to determine whether to enforce or skip some <a href="ugbtb.html#_ugbtb_programming-model_custom-validator">metamodel validation</a> for <code>@Column</code> versus equivalent Isis annotations.</p>
</div>
</div></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Domain / persistence</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Property</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="#_rgant-PersistenceCapable"><code>@javax.jdo.annotations.</code><br> <code>PersistenceCapable</code></a></p></td>
<td class="tableblock halign-left valign-top">
<div>
<div class="paragraph">
<p>Used to build Apache Isis' own internal identifier for objects.<br></p>
</div>
<div class="paragraph">
<p>If the <code>schema()</code> attribute is specified (and if <a href="#<em>rgant-Discriminator"><code>@Discriminator</code></a> _hasn’t been specified), is also used to derive the object type, as used in `Bookmark`s, URLs for <a href="ugvro.html">RestfulObjects viewer</a> and elsewhere.</p>
</div>
</div></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Domain / persistence</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Class</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="#_rgant-PrimaryKey"><code>@javax.jdo.annotations.</code><br> <code>PrimaryKey</code></a></p></td>
<td class="tableblock halign-left valign-top">
<div>
<div class="paragraph">
<p>Used to ensure Apache Isis does not overwrite application-defined primary keys, and to ensure is read-only in the UI.</p>
</div>
</div></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Domain / persistence</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Property</p></td>
</tr>
</tbody>
</table>
<div class="paragraph">
<p>Isis also parses the following JDO annotations, but the metadata is currently unused.</p>
</div>
<table class="tableblock frame-all grid-all spread">
<caption class="title">
Table 4. JDO Annotations (unused within Apache Isis)
</caption>
<colgroup>
<col style="width: 25%;">
<col style="width: 50%;">
<col style="width: 12.5%;">
<col style="width: 12.5%;">
</colgroup>
<thead>
<tr>
<th class="tableblock halign-left valign-top">Annotation</th>
<th class="tableblock halign-left valign-top">Purpose</th>
<th class="tableblock halign-left valign-top">Layer</th>
<th class="tableblock halign-left valign-top">Applies to</th>
</tr>
</thead>
<tbody>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>@javax.jdo.annotations.</code><br> <code>DataStoreIdentity</code></p></td>
<td class="tableblock halign-left valign-top">
<div>
<div class="paragraph">
<p>Unused</p>
</div>
</div></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Persistence</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Class</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>@javax.jdo.annotations.</code><br> <code>EmbeddedOnly</code></p></td>
<td class="tableblock halign-left valign-top">
<div>
<div class="paragraph">
<p>Unused</p>
</div>
</div></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Persistence</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Class</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>@javax.jdo.annotations.</code><br> <code>Query</code></p></td>
<td class="tableblock halign-left valign-top">
<div>
<div class="paragraph">
<p>Unused</p>
</div>
</div></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Persistence</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Class</p></td>
</tr>
</tbody>
</table>
</div>
<div class="sect2">
<h3 id="_rgant_aaa_jee">2.4. Java EE Annotations</h3>
<button type="button" class="button secondary" onclick="window.location.href="https://github.com/apache/isis/edit/master/adocs/documentation/src/main/asciidoc/guides/_rgant_aaa_jee.adoc"" style="float: right; font-size: small; padding: 6px; margin-top: -55px; "><i class="fa fa-pencil-square-o"></i> Edit</button>
<div class="paragraph">
<p>While Apache Isis does, as of today, define a good number of its own annotations, the policy is to reuse standard Java/JEE annotations wherever they exist or are added to the Java platform.</p>
</div>
<div class="paragraph">
<p>The table below lists the JEE annotations currently recognized. Expect to see more added in future releases of Apache Isis.</p>
</div>
<table class="tableblock frame-all grid-all spread">
<caption class="title">
Table 5. Java EE Annotations
</caption>
<colgroup>
<col style="width: 25%;">
<col style="width: 50%;">
<col style="width: 12.5%;">
<col style="width: 12.5%;">
</colgroup>
<thead>
<tr>
<th class="tableblock halign-left valign-top">Annotation</th>
<th class="tableblock halign-left valign-top">Purpose</th>
<th class="tableblock halign-left valign-top">Layer</th>
<th class="tableblock halign-left valign-top"><a href="ugfun.html#_ugfun_object-layout_dynamic">Dynamic layout</a>?</th>
</tr>
</thead>
<tbody>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="#_rgant-Digits"><code>@javax.validation.</code><br> <code>constraints.</code><br> <code>Digits</code></a></p></td>
<td class="tableblock halign-left valign-top">
<div>
<div class="paragraph">
<p>Precision/scale for BigDecimal values.</p>
</div>
</div></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Domain</p></td>
<td class="tableblock halign-left valign-top"></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="#_rgant-Inject"><code>@javax.inject.</code><br> <code>Inject</code></a></p></td>
<td class="tableblock halign-left valign-top">
<div>
<div class="paragraph">
<p>Inject domain service into a domain object (entity or view model) or another domain service.</p>
</div>
</div></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Domain</p></td>
<td class="tableblock halign-left valign-top"></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="#_rgant-Digits"><code>@javax.annotation.</code><br> <code>Nullable</code></a></p></td>
<td class="tableblock halign-left valign-top">
<div>
<div class="paragraph">
<p>Specify that a property/parameter is optional.</p>
</div>
</div></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Domain</p></td>
<td class="tableblock halign-left valign-top"></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="#_rgant-PostConstruct"><code>@javax.annotation.</code><br> <code>PostConstruct</code></a></p></td>
<td class="tableblock halign-left valign-top">
<div>
<div class="paragraph">
<p>Callback for domain services (either singleton or <a href="#_rgant-RequestScoped">request-scoped</a>) to initialize themselves once instantiated.</p>
</div>
</div></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Domain</p></td>
<td class="tableblock halign-left valign-top"></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="#_rgant-PreDestroy"><code>@javax.annotation.</code><br> <code>PreDestroy</code></a></p></td>
<td class="tableblock halign-left valign-top">
<div>
<div class="paragraph">
<p>Callback for domain services (either singleton or <a href="#_rgant-RequestScoped">request-scoped</a>) to clean up resources prior to destruction.</p>
</div>
</div></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Domain</p></td>
<td class="tableblock halign-left valign-top"></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="#_rgant-RequestScoped"><code>@javax.enterprise.</code><br> <code>context.</code><br> <code>RequestScoped</code></a></p></td>
<td class="tableblock halign-left valign-top">
<div>
<div class="paragraph">
<p>Specify that a domain service has request-scope (rather than a singleton).</p>
</div>
</div></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Domain</p></td>
<td class="tableblock halign-left valign-top"></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="#_rgant-XmlRootElement"><code>javax.xml.bind</code><br> <code>.annotation</code><br> <code>XmlRootElement</code></a></p></td>
<td class="tableblock halign-left valign-top">
<div>
<div class="paragraph">
<p>JAXB annotation indicating the XML root element when serialized to XML; also used by the framework for view models (whose memento is the XML), often also acting as a DTO.</p>
</div>
</div></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Application</p></td>
<td class="tableblock halign-left valign-top"></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="#_rgant-XmlJavaTypeAdapter"><code>javax.xml.bind</code><br> <code>.annotation</code><br> <code>XmlJavaTypeAdapter</code></a></p></td>
<td class="tableblock halign-left valign-top">
<div>
<div class="paragraph">
<p>JAXB annotation defining how to serialize an entity. Used in conjunction with the (framework provided) <code>PersistentEntityAdapter</code> class to serialize persistent entities into a canonical OID (equivalent to the <code>Bookmark</code> provided by the <a href="rgsvc.html#_rgsvc_api_BookmarkService"><code>BookmarkService</code></a>).</p>
</div>
</div></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Domain</p></td>
<td class="tableblock halign-left valign-top"></td>
</tr>
</tbody>
</table>
</div>
<div class="sect2">
<h3 id="_rgant_aaa_deprecated">2.5. Deprecated Annotations</h3>
<button type="button" class="button secondary" onclick="window.location.href="https://github.com/apache/isis/edit/master/adocs/documentation/src/main/asciidoc/guides/_rgant_aaa_deprecated.adoc"" style="float: right; font-size: small; padding: 6px; margin-top: -55px; "><i class="fa fa-pencil-square-o"></i> Edit</button>
<div class="paragraph">
<p>As Apache Isis has evolved and grown, we found ourselves adding more and more annotations; but most of these related to either an object type (entity, view model, service) or an object member (property, collection, action). Over time it became harder and harder for end programmers to discover these new features.</p>
</div>
<div class="paragraph">
<p>Accordingly, (in v1.8.0) we decided to unify the semantics into the main (core) annotations listed <a href="#_rgant-aaa_main">above</a>.</p>
</div>
<div class="paragraph">
<p>The annotations listed in the table below are still supported by Apache Isis, but will be retired in Apache Isis v2.0.</p>
</div>
<table class="tableblock frame-all grid-all spread">
<caption class="title">
Table 6. Deprecated Annotations
</caption>
<colgroup>
<col style="width: 18.1818%;">
<col style="width: 36.3636%;">
<col style="width: 27.2727%;">
<col style="width: 9.0909%;">
<col style="width: 9.091%;">
</colgroup>
<thead>
<tr>
<th class="tableblock halign-left valign-top">Annotation</th>
<th class="tableblock halign-left valign-top">Purpose</th>
<th class="tableblock halign-left valign-top">Use instead</th>
<th class="tableblock halign-left valign-top">Layer</th>
<th class="tableblock halign-left valign-top"><a href="ugfun.html#_ugfun_object-layout_dynamic">Dynamic layout</a>?</th>
</tr>
</thead>
<tbody>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>@ActionOrder</code></p></td>
<td class="tableblock halign-left valign-top">
<div>
<div class="paragraph">
<p>Order of buttons and menu items representing actions.</p>
</div>
</div></td>
<td class="tableblock halign-left valign-top">
<div>
<div class="paragraph">
<p><a href="#_rgant-MemberOrder"><code>@MemberOrder</code></a></p>
</div>
</div></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">UI</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Yes</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>@ActionInteraction</code></p></td>
<td class="tableblock halign-left valign-top">
<div>
<div class="paragraph">
<p>Enable subscribers on the Event Bus Service to either veto, validate or take further steps before/after an action has been invoked.</p>
</div>
</div></td>
<td class="tableblock halign-left valign-top">
<div>
<div class="paragraph">
<p><a href="#_rgant-Action_domainEvent"><code>@Action#domainEvent()</code></a></p>
</div>
</div></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Domain</p></td>
<td class="tableblock halign-left valign-top"></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>@ActionSemantics</code></p></td>
<td class="tableblock halign-left valign-top">
<div>
<div class="paragraph">
<p>Query-only, idempotent or non-idempotent.</p>
</div>
</div></td>
<td class="tableblock halign-left valign-top">
<div>
<div class="paragraph">
<p><a href="#_rgant-Action_semantics"><code>@Action#semantics()</code></a></p>
</div>
</div></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Domain</p></td>
<td class="tableblock halign-left valign-top"></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>@Audited</code></p></td>
<td class="tableblock halign-left valign-top">
<div>
<div class="paragraph">
<p>Audit changes to an object.</p>
</div>
</div></td>
<td class="tableblock halign-left valign-top">
<div>
<div class="paragraph">
<p><a href="#_rgant-DomainObject_auditing"><code>@DomainObject#</code><br> <code>auditing()</code></a></p>
</div>
</div></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Domain</p></td>
<td class="tableblock halign-left valign-top"></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>@AutoComplete</code></p></td>
<td class="tableblock halign-left valign-top">
<div>
<div class="paragraph">
<p>Repository method to search for entities</p>
</div>
</div></td>
<td class="tableblock halign-left valign-top">
<div>
<div class="paragraph">
<p><a href="#_rgant-DomainObject_autoCompleteRepository"><code>@DomainObject</code><br> <code>#autoCompleteRepository()</code></a></p>
</div>
</div></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">UI/Domain</p></td>
<td class="tableblock halign-left valign-top"></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>@Bookmarkable</code></p></td>
<td class="tableblock halign-left valign-top">
<div>
<div class="paragraph">
<p>Whether (and how) to create a bookmark for visited object.</p>
</div>
</div></td>
<td class="tableblock halign-left valign-top">
<div>
<div class="paragraph">
<p><a href="#_rgant-DomainObjectLayout_bookmarking"><code>@DomainObjectLayout</code><br> <code>#bookmarking()</code></a></p>
</div>
</div></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">UI</p></td>
<td class="tableblock halign-left valign-top"></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>@Bounded</code></p></td>
<td class="tableblock halign-left valign-top">
<div>
<div class="paragraph">
<p>Bounded (and limited) number of instances of an entity type, translates into a drop-down for any property of that type.</p>
</div>
</div></td>
<td class="tableblock halign-left valign-top">
<div>
<div class="paragraph">
<p><a href="#_rgant-DomainObject_bounded"><code>@DomainObject#bounded()</code></a></p>
</div>
</div></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Domain</p></td>
<td class="tableblock halign-left valign-top"></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>@Bulk</code></p></td>
<td class="tableblock halign-left valign-top">
<div>
<div class="paragraph">
<p>Indicates an action is a bulk action, can be applied to multiple instances.</p>
</div>
</div></td>
<td class="tableblock halign-left valign-top">
<div>
<div class="paragraph">
<p><a href="#_rgant-Action_invokeOn"><code>@Action#invokeOn()</code></a></p>
</div>
</div></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">UI, Domain</p></td>
<td class="tableblock halign-left valign-top"></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>@CollectionInteraction</code></p></td>
<td class="tableblock halign-left valign-top">
<div>
<div class="paragraph">
<p>Enable subscribers on the Event Bus Service to either veto, validate or take further steps before/after a collection has been added to or removed from.</p>
</div>
</div></td>
<td class="tableblock halign-left valign-top">
<div>
<div class="paragraph">
<p><a href="#_rgant-Collection_domainEvent"><code>@Collection#domainEvent()</code></a></p>
</div>
</div></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Domain</p></td>
<td class="tableblock halign-left valign-top"></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>@Command</code></p></td>
<td class="tableblock halign-left valign-top">
<div>
<div class="paragraph">
<p>Action invocation should be reified as a command object, optionally persistable for profiling and enhanced auditing, and background/async support.</p>
</div>
</div></td>
<td class="tableblock halign-left valign-top">
<div>
<div class="paragraph">
<p><a href="#_rgant-Action_command"><code>@Action#command()</code></a></p>
</div>
</div></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Domain</p></td>
<td class="tableblock halign-left valign-top"></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>@CssClass</code></p></td>
<td class="tableblock halign-left valign-top">
<div>
<div class="paragraph">
<p>Allow visual representation of individual objects or object members layout to be customized by application-specific CSS.</p>
</div>
</div></td>
<td class="tableblock halign-left valign-top">
<div>
<div class="paragraph">
<p><code>#cssClass()</code> attribute for: <a href="#_rgant-DomainObjectLayout_cssClass"><code>@DomainObjectLayout</code></a>, <a href="#_rgant-PropertyLayout_cssClass"><code>@PropertyLayout</code></a>, <a href="#_rgant-CollectionLayout_cssClass"><code>@CollectionLayout</code></a>, <a href="#_rgant-ActionLayout_cssClass"><code>@ActionLayout</code></a> and <a href="#_rgant-ParameterLayout_cssClass"><code>@ParameterLayout</code></a></p>
</div>
</div></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">UI</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Yes</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>@CssClassFa</code></p></td>
<td class="tableblock halign-left valign-top">
<div>
<div class="paragraph">
<p>So that font awesome icons can be applied to action buttons/menu items and optionally as an object icon.</p>
</div>
</div></td>
<td class="tableblock halign-left valign-top">
<div>
<div class="paragraph">
<p><code>cssClassFa()</code> attribute for: <a href="#_rgant-ActionLayout_cssClassFa"><code>@ActionLayout</code></a>, <a href="#_rgant-DomainObjectLayout_cssClassFa"><code>DomainObjectLayout</code></a> and <a href="#_rgant-ViewModelLayout_cssClassFa"><code>ViewModelLayout</code></a></p>
</div>
</div></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">UI</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Yes</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>@Debug</code></p></td>
<td class="tableblock halign-left valign-top">
<div>
<div class="paragraph">
<p>Action only invokable in debug mode.</p>
</div>
</div></td>
<td class="tableblock halign-left valign-top">
<div>
<div class="paragraph">
<p>Not supported by either the <a href="ugvw.html">Wicket viewer</a> or the <a href="ugvro.html">RestfulObjects viewer</a>; use prototype mode instead (<a href="#_rgant-Action_restrictTo"><code>@Action#restrictTo()</code></a>)</p>
</div>
</div></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">UI</p></td>
<td class="tableblock halign-left valign-top"></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>@DescribedAs</code></p></td>
<td class="tableblock halign-left valign-top">
<div>
<div class="paragraph">
<p>Provide a longer description/tool-tip of an object or object member.</p>
</div>
</div></td>
<td class="tableblock halign-left valign-top">
<div>
<div class="paragraph">
<p><code>#describedAs()</code> attribute for <a href="#_rgant-DomainObject_describedAs"><code>@DomainObjectLayout</code></a>, <a href="#_rgant-PropertyLayout_describedAs"><code>@PropertyLayout</code></a>, <a href="#_rgant-CollectionLayout_describedAs"><code>@CollectionLayout</code></a>, <a href="#_rgant-ActionLayout_describedAs"><code>@ActionLayout</code></a> and <a href="#_rgant-ParameterLayout_describedAs"><code>@ParameterLayout</code></a></p>
</div>
</div></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">UI</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Yes</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>@Disabled</code></p></td>
<td class="tableblock halign-left valign-top">
<div>
<div class="paragraph">
<p>Object property cannot be edited, an object collection cannot be added to/removed from, or an object action cannot be invoked.</p>
</div>
</div></td>
<td class="tableblock halign-left valign-top">
<div>
<div class="paragraph">
<p><code>#editing()</code> attribute for <a href="#_rgant-Property_editing"><code>@Property</code></a>, <a href="#_rgant-Collection_editing"><code>@Collection</code></a> and <a href="#_rgant-DomainObject_editing"><code>@DomainObject</code></a></p>
</div>
</div></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">UI, Domain</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Yes</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>@Exploration</code></p></td>
<td class="tableblock halign-left valign-top">
<div>
<div class="paragraph">
<p>Action available in special 'exploration' mode.</p>
</div>
</div></td>
<td class="tableblock halign-left valign-top">
<div>
<div class="paragraph">
<p>Not supported by either the <a href="ugvw.html">Wicket viewer</a> or the <a href="ugvro.html">RestfulObjects viewer</a>; use prototype mode instead (<a href="#_rgant-Action_restrictTo"><code>@Action#restrictTo()</code></a>)</p>
</div>
</div></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">UI</p></td>
<td class="tableblock halign-left valign-top"></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>@FieldOrder</code></p></td>
<td class="tableblock halign-left valign-top">
<div>
<div class="paragraph">
<p>Order of properties and collections.</p>
</div>
</div></td>
<td class="tableblock halign-left valign-top">
<div>
<div class="paragraph">
<p><a href="#_rgant-MemberOrder"><code>@MemberOrder</code></a></p>
</div>
</div></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">UI</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Yes</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>@Hidden</code></p></td>
<td class="tableblock halign-left valign-top">
<div>
<div class="paragraph">
<p>Object member is not visible, or on domain service (to indicate that none of its actions are visible).</p>
</div>
</div></td>
<td class="tableblock halign-left valign-top">
<div>
<div class="paragraph">
<p>For domain object members, use <code>#hidden()</code> attribute of <a href="#_rgant-Action_hidden"><code>Action</code></a>, <a href="#_rgant-Property_hidden"><code>Property</code></a> or <a href="#_rgant-Collection_hidden"><code>Collection</code></a>. <br> For domain service, use <a href="#_rgant-DomainService_nature"><code>@DomainService(</code><br> <code>nature=DOMAIN)</code></a></p>
</div>
</div></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">UI, Domain</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Yes</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>@Idempotent</code></p></td>
<td class="tableblock halign-left valign-top">
<div>
<div class="paragraph">
<p>Whether an action is idempotent (can be invoked multiple times with same post-condition).</p>
</div>
</div></td>
<td class="tableblock halign-left valign-top">
<div>
<div class="paragraph">
<p><a href="#_rgant-Action_semantics"><code>@Action#semantics</code></a></p>
</div>
</div></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Domain</p></td>
<td class="tableblock halign-left valign-top"></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>@Ignore</code></p></td>
<td class="tableblock halign-left valign-top">
<div>
<div class="paragraph">
<p>Exclude this method from the metamodel.</p>
</div>
</div></td>
<td class="tableblock halign-left valign-top">
<div>
<div class="paragraph">
<p><a href="#_rgant-Programmatic"><code>@Programmatic</code></a>.<br></p>
</div>
<div class="paragraph">
<p><code>@Ignore</code> was deprecated because it can easily clash with <code>@org.junit.Ignore</code>.</p>
</div>
</div></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Domain</p></td>
<td class="tableblock halign-left valign-top"></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>@Immutable</code></p></td>
<td class="tableblock halign-left valign-top">
<div>
<div class="paragraph">
<p>An object’s state cannot be changed (properties cannot be edited, collections cannot be added to or removed from). Actions can still be invoked.</p>
</div>
</div></td>
<td class="tableblock halign-left valign-top">
<div>
<div class="paragraph">
<p><a href="#_rgant-DomainObject_editing"><code>@DomainObject#editing()</code></a></p>
</div>
</div></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Domain</p></td>
<td class="tableblock halign-left valign-top"></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>@Mask</code></p></td>
<td class="tableblock halign-left valign-top">
<div>
<div class="paragraph">
<p>How to parse/render values (never properly supported)</p>
</div>
</div></td>
<td class="tableblock halign-left valign-top">
<div>
<div class="paragraph">
<p>(None)</p>
</div>
</div></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">UI/domain</p></td>
<td class="tableblock halign-left valign-top"></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>@MaxLength</code></p></td>
<td class="tableblock halign-left valign-top">
<div>
<div class="paragraph">
<p>Maximum length of a property value (strings).</p>
</div>
</div></td>
<td class="tableblock halign-left valign-top">
<div>
<div class="paragraph">
<p><code>#maxLength()</code> attribute for <a href="#_rgant-Property_maxLength"><code>@Property</code></a> or <a href="#_rgant-Parameter_maxLength"><code>@Parameter</code></a></p>
</div>
</div></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Domain</p></td>
<td class="tableblock halign-left valign-top"></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>@MemberGroups</code></p></td>
<td class="tableblock halign-left valign-top">
<div>
<div class="paragraph">
<p>Layout of properties and collections of a domain object or view model object.</p>
</div>
</div></td>
<td class="tableblock halign-left valign-top">
<div>
<div class="paragraph">
<p><a href="ugfun.html#_ugfun_object-layout_dynamic_xml">dynamic <code>.layout.xml</code></a> files</p>
</div>
</div></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">UI</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Yes</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">@MemberGroupLayout`</p></td>
<td class="tableblock halign-left valign-top">
<div>
<div class="paragraph">
<p>Grouping of properties into groups, and organizing of properties, collections into columns.</p>
</div>
</div></td>
<td class="tableblock halign-left valign-top">
<div>
<div class="paragraph">
<p><a href="ugfun.html#_ugfun_object-layout_dynamic_xml">dynamic <code>.layout.xml</code></a> files</p>
</div>
</div></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">UI</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Yes</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>@MultiLine</code></p></td>
<td class="tableblock halign-left valign-top">
<div>
<div class="paragraph">
<p>Render string property over multiple lines (a textarea rather than a textbox).</p>
</div>
</div></td>
<td class="tableblock halign-left valign-top">
<div>
<div class="paragraph">
<p><code>#multiLine()</code> attribute for <a href="#_rgant-Property_multiLine"><code>@Property</code></a> or <a href="#_rgant-Parameter_multiLine"><code>@Parameter</code></a></p>
</div>
</div></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">UI</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Yes</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>@MustSatisfy</code></p></td>
<td class="tableblock halign-left valign-top">
<div>
<div class="paragraph">
<p>Specify arbitrary specification constraints on a property or action parameter.</p>
</div>
</div></td>
<td class="tableblock halign-left valign-top">
<div>
<div class="paragraph">
<p><code>#mustSatisfy()</code> attribute for <a href="#_rgant-Property_mustSatisfy"><code>@Property</code></a> or <a href="#_rgant-Parameter_mustSatisfy"><code>@Parameter</code></a></p>
</div>
</div></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Domain</p></td>
<td class="tableblock halign-left valign-top"></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>@Named</code></p></td>
<td class="tableblock halign-left valign-top">
<div>
<div class="paragraph">
<p>Override name inferred from class. Required for parameter names (prior to Java8).</p>
</div>
</div></td>
<td class="tableblock halign-left valign-top">
<div>
<div class="paragraph">
<p><code>#named()</code> attribute for <a href="#_rgant-DomainServiceLayout_named"><code>@DomainServiceLayout</code></a>, <a href="#_rgant-DomainObjectLayout_named"><code>@DomainObjectLayout</code></a>, <a href="#_rgant-PropertyLayout_named"><code>@PropertyLayout</code></a>, <a href="#_rgant-CollectionLayout_named"><code>@CollectionLayout</code></a>, <a href="#_rgant-ActionLayout_named"><code>@ActionLayout</code></a> and <a href="#_rgant-ParameterLayout_named"><code>@ParameterLayout</code></a></p>
</div>
</div></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">UI</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Yes</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>@NotContributed</code></p></td>
<td class="tableblock halign-left valign-top">
<div>
<div class="paragraph">
<p>Indicates that a domain service action is not rendered as an action on the (entity) types of its parameters. For 1-arg query-only actions, controls whether the domain service action is rendered as a property or collection on the entity type of its parameter.</p>
</div>
</div></td>
<td class="tableblock halign-left valign-top">
<div>
<div class="paragraph">
<p>Use <a href="#_rgant-DomainService_nature"><code>@DomainService#nature()</code></a> to specify whether any of the actions in a domain service should appear in the menu bars (applies at type level, not action level). For individual actions, use <a href="#_rgant-ActionLayout_contributedAs"><code>@ActionLayout#</code><br> <code>contributedAs()</code></a> to specify whether any individual action should be contributed only as an action or as an association (property or collection).</p>
</div>
</div></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">UI</p></td>
<td class="tableblock halign-left valign-top"></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>@NotInServiceMenu</code></p></td>
<td class="tableblock halign-left valign-top">
<div>
<div class="paragraph">
<p>Indicates that a domain service should not be rendered in the application menu (at top of page in Wicket viewer).</p>
</div>
</div></td>
<td class="tableblock halign-left valign-top">
<div>
<div class="paragraph">
<p><a href="#_rgant-DomainService_nature"><code>@DomainService#nature()</code></a> to signify that none of the actions in a domain service should appear in the menu bars</p>
</div>
</div></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">UI</p></td>
<td class="tableblock halign-left valign-top"></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>@NotPersisted</code></p></td>
<td class="tableblock halign-left valign-top">
<div>
<div class="paragraph">
<p>Indicates that an object property is not persisted (meaning it is excluded from view model mementos, and should not be audited).</p>
</div>
</div></td>
<td class="tableblock halign-left valign-top">
<div>
<div class="paragraph">
<p><code>#notPersisted()</code> attribute of <a href="#_rgant-Property_notPersisted"><code>@Property</code></a> and <a href="#_rgant-Collection_notPersisted"><code>@Collection</code></a></p>
</div>
</div></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Domain, Persistence</p></td>
<td class="tableblock halign-left valign-top"></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>@ObjectType</code></p></td>
<td class="tableblock halign-left valign-top">
<div>
<div class="paragraph">
<p>For constructing the external identifier (URI) of an entity instance (part of its URL in both Wicket viewer and Restful Objects viewer). Also part of the toString representation of bookmarks, if using the Bookmark Service</p>
</div>
</div></td>
<td class="tableblock halign-left valign-top">
<div>
<div class="paragraph">
<p><a href="#_rgant-DomainObject_objectType"><code>@DomainObject#objectType()</code></a></p>
</div>
</div></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Domain</p></td>
<td class="tableblock halign-left valign-top"></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>@Optional</code></p></td>
<td class="tableblock halign-left valign-top">
<div>
<div class="paragraph">
<p>Specifies that a property or action parameter is not mandatory.</p>
</div>
</div></td>
<td class="tableblock halign-left valign-top">
<div>
<div class="paragraph">
<p><code>#optionality()</code> attribute for <a href="#_rgant-Property_optionality"><code>@Property</code></a> or <a href="#_rgant-Parameter_optionality"><code>@Parameter</code></a></p>
</div>
</div></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Domain</p></td>
<td class="tableblock halign-left valign-top"></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>@Paged</code></p></td>
<td class="tableblock halign-left valign-top">
<div>
<div class="paragraph">
<p>Number of instances to display in tables representing (standalone or parented) collections.</p>
</div>
</div></td>
<td class="tableblock halign-left valign-top">
<div>
<div class="paragraph">
<p><code>#paged()</code> attribute for <a href="#_rgant-DomainObjectLayout_paged"><code>@DomainObjectLayout</code></a> or <a href="#_rgant-CollectionLayout_paged"><code>@CollectionLayout</code></a></p>
</div>
</div></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">UI</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Yes</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>@Plural</code></p></td>
<td class="tableblock halign-left valign-top">
<div>
<div class="paragraph">
<p>For the irregular plural form of an entity type.</p>
</div>
</div></td>
<td class="tableblock halign-left valign-top">
<div>
<div class="paragraph">
<p><a href="#_rgant-DomainObject_plural"><code>@DomainObjectLayout</code><br> <code>#plural()</code></a></p>
</div>
</div></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">UI</p></td>
<td class="tableblock halign-left valign-top"></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>@PostsAction</code><br> <code>InvokedEvent</code></p></td>
<td class="tableblock halign-left valign-top">
<div>
<div class="paragraph">
<p>Post a domain event to the Event Bus Service indicating that an action has been invoked.</p>
</div>
</div></td>
<td class="tableblock halign-left valign-top">
<div>
<div class="paragraph">
<p><a href="#_rgant-Action_domainEvent"><code>@Action#domainEvent()</code></a></p>
</div>
</div></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Domain</p></td>
<td class="tableblock halign-left valign-top"></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>@PostsCollection</code><br> <code>AddedToEvent</code></p></td>
<td class="tableblock halign-left valign-top">
<div>
<div class="paragraph">
<p>Post a domain event to the Event Bus Service indicating that an element has been added to a collection.</p>
</div>
</div></td>
<td class="tableblock halign-left valign-top">
<div>
<div class="paragraph">
<p><a href="#_rgant-Collection_domainEvent"><code>@Collection#domainEvent()</code></a></p>
</div>
</div></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Domain</p></td>
<td class="tableblock halign-left valign-top"></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>@PostsCollection</code><br> <code>RemovedFromEvent</code></p></td>
<td class="tableblock halign-left valign-top">
<div>
<div class="paragraph">
<p>Post a domain event to the Event Bus Service indicating that an element has been removed from a collection.</p>
</div>
</div></td>
<td class="tableblock halign-left valign-top">
<div>
<div class="paragraph">
<p><a href="#_rgant-Collection_domainEvent"><code>@Collection#domainEvent()</code></a></p>
</div>
</div></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Domain</p></td>
<td class="tableblock halign-left valign-top"></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>@PostsProperty</code><br> <code>ChangedEvent</code></p></td>
<td class="tableblock halign-left valign-top">
<div>
<div class="paragraph">
<p>Post a domain event to the Event Bus Service indicating that the value of a property has changed.</p>
</div>
</div></td>
<td class="tableblock halign-left valign-top">
<div>
<div class="paragraph">
<p><a href="#_rgant-Property_domainEvent"><code>@Property#domainEvent()</code></a></p>
</div>
</div></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Domain</p></td>
<td class="tableblock halign-left valign-top"></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>@PropertyInteraction</code></p></td>
<td class="tableblock halign-left valign-top">
<div>
<div class="paragraph">
<p>Enable subscribers on the Event Bus Service to either veto, validate or take further steps before/after a property has been modified or cleared.</p>
</div>
</div></td>
<td class="tableblock halign-left valign-top">
<div>
<div class="paragraph">
<p><a href="#_rgant-Property_domainEvent"><code>@Property#domainEvent()</code></a></p>
</div>
</div></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Domain</p></td>
<td class="tableblock halign-left valign-top"></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>@Prototype</code></p></td>
<td class="tableblock halign-left valign-top">
<div>
<div class="paragraph">
<p>Indicates that an action should only be visible in 'prototype' mode.</p>
</div>
</div></td>
<td class="tableblock halign-left valign-top">
<div>
<div class="paragraph">
<p><a href="#_rgant-Action_restrictTo"><code>@Action#restrictTo()</code></a></p>
</div>
</div></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">UI</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Yes</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>@PublishedAction</code></p></td>
<td class="tableblock halign-left valign-top">
<div>
<div class="paragraph">
<p>Action invocation should be serialized and published by configured PublishingService (if any), eg to other systems.</p>
</div>
</div></td>
<td class="tableblock halign-left valign-top">
<div>
<div class="paragraph">
<p><a href="#_rgant-Action_publishing"><code>@Action#publishing()</code></a></p>
</div>
</div></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Domain</p></td>
<td class="tableblock halign-left valign-top"></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>@PublishedObject</code></p></td>
<td class="tableblock halign-left valign-top">
<div>
<div class="paragraph">
<p>Change to object should be serialized and published by configured PublishingService (if any), eg to other systems.</p>
</div>
</div></td>
<td class="tableblock halign-left valign-top">
<div>
<div class="paragraph">
<p><a href="#_rgant-DomainObject_publishing"><code>@DomainObject#publishing()</code></a></p>
</div>
</div></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Domain</p></td>
<td class="tableblock halign-left valign-top"></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>@QueryOnly</code></p></td>
<td class="tableblock halign-left valign-top">
<div>
<div class="paragraph">
<p>Whether an action is query-only (has no side-effects).</p>
</div>
</div></td>
<td class="tableblock halign-left valign-top">
<div>
<div class="paragraph">
<p><a href="#_rgant-Action_semantics"><code>@Action#semantics()</code></a></p>
</div>
</div></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Domain</p></td>
<td class="tableblock halign-left valign-top"></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>@RegEx</code></p></td>
<td class="tableblock halign-left valign-top">
<div>
<div class="paragraph">
<p>Validate change to value of string property.</p>
</div>
</div></td>
<td class="tableblock halign-left valign-top">
<div>
<div class="paragraph">
<p><code>#regexPattern()</code> for <a href="#_rgant-Property_regexPattern"><code>@Property</code></a> or <a href="#_rgant-Property_regexPattern"><code>@Parameter</code></a>.</p>
</div>
</div></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Domain</p></td>
<td class="tableblock halign-left valign-top"></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>@Render</code></p></td>
<td class="tableblock halign-left valign-top">
<div>
<div class="paragraph">
<p>Eagerly (or lazily) render the contents of a collection.</p>
</div>
</div></td>
<td class="tableblock halign-left valign-top">
<div>
<div class="paragraph">
<p><a href="#_rgant-CollectionLayout_render"><code>@CollectionLayout</code><br> <code>#render()</code></a></p>
</div>
</div></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">UI</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Yes</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>@RenderedAsDayBefore</code></p></td>
<td class="tableblock halign-left valign-top">
<div>
<div class="paragraph">
<p>Render dates as the day before; ie store [a,b) internally but render [a,b-1]) to end-user.</p>
</div>
</div></td>
<td class="tableblock halign-left valign-top">
<div>
<div class="paragraph">
<p><code>#renderedAsDayBefore()</code> attribute for <a href="#_rgant-PropertyLayout_renderedAsDayBefore"><code>@PropertyLayout</code></a> and <a href="#_rgant-ParameterLayout_renderedAsDayBefore"><code>@ParameterLayout</code></a>.</p>
</div>
</div></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">UI</p></td>
<td class="tableblock halign-left valign-top"></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>@Resolve</code></p></td>
<td class="tableblock halign-left valign-top">
<div>
<div class="paragraph">
<p>Eagerly (or lazily) render the contents of a collection (same as <code>@Render)</code></p>
</div>
</div></td>
<td class="tableblock halign-left valign-top">
<div>
<div class="paragraph">
<p><a href="#_rgant-CollectionLayout_render"><code>@CollectionLayout</code><br> <code>#render()</code></a></p>
</div>
</div></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">UI</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Yes</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>@SortedBy</code></p></td>
<td class="tableblock halign-left valign-top">
<div>
<div class="paragraph">
<p>Display instances in collections in the order determined by the provided Comparator.</p>
</div>
</div></td>
<td class="tableblock halign-left valign-top">
<div>
<div class="paragraph">
<p><a href="#_rgant-CollectionLayout_sortedBy"><code>@CollectionLayout</code><br> <code>#sortedBy()</code></a></p>
</div>
</div></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">UI</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Yes</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>@TypeOf</code></p></td>
<td class="tableblock halign-left valign-top">
<div>
<div class="paragraph">
<p>The type of entity stored within a collection, or as the result of invoking an action, if cannot be otherwise inferred, eg from generics.</p>
</div>
</div></td>
<td class="tableblock halign-left valign-top">
<div>
<div class="paragraph">
<p><code>#typeOf()</code> attribute for <a href="#_rgant-Collection_typeOf"><code>@Collection</code></a> and <a href="#_rgant-Action_typeOf"><code>@Action</code></a></p>
</div>
</div></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Domain</p></td>
<td class="tableblock halign-left valign-top"></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>@TypicalLength</code></p></td>
<td class="tableblock halign-left valign-top">
<div>
<div class="paragraph">
<p>The typical length of a string property, eg to determine a sensible length for a textbox.</p>
</div>
</div></td>
<td class="tableblock halign-left valign-top">
<div>
<div class="paragraph">
<p><code>#typicalLength()</code> attribute for <a href="#_rgant-PropertyLayout_typicalLength"><code>@PropertyLayout</code></a> and <a href="#_rgant-ParameterLayout_typicalLength"><code>@ParameterLayout</code></a></p>
</div>
</div></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">UI</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Yes</p></td>
</tr>
</tbody>
</table>
</div>
<div class="sect2">
<h3 id="_rgant_aaa_partial">2.6. Incomplete/partial support</h3>
<button type="button" class="button secondary" onclick="window.location.href="https://github.com/apache/isis/edit/master/adocs/documentation/src/main/asciidoc/guides/_rgant_aaa_partial.adoc"" style="float: right; font-size: small; padding: 6px; margin-top: -55px; "><i class="fa fa-pencil-square-o"></i> Edit</button>
<div class="paragraph">
<p>These annotations have only incomplete/partial support, primarily relating to the management of value types. We recommend that you do not use them for now. Future versions of Apache Isis may either formally deprecate/retire them, or we may go the other way and properly support them. This will depend in part on the interactions between the Apache Isis runtime, its two viewer implementations, and DataNucleus persistence.</p>
</div>
<table class="tableblock frame-all grid-all spread">
<caption class="title">
Table 7. Annotations with incomplete/partial support
</caption>
<colgroup>
<col style="width: 28.5714%;">
<col style="width: 57.1428%;">
<col style="width: 14.2858%;">
</colgroup>
<thead>
<tr>
<th class="tableblock halign-left valign-top">Annotation</th>
<th class="tableblock halign-left valign-top">Purpose</th>
<th class="tableblock halign-left valign-top">Layer</th>
</tr>
</thead>
<tbody>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>@Aggregated</code></p></td>
<td class="tableblock halign-left valign-top">
<div>
<div class="paragraph">
<p>Indicates that the object is aggregated, or wholly owned, by a root object.<br></p>
</div>
<div class="paragraph">
<p>This information could in theory provide useful semantics for some object store implementations, eg to store the aggregated objects "inline". <br></p>
</div>
<div class="paragraph">
<p>Currently neither the JDO ObjectStore nor any of the viewers exploit this metadata.</p>
</div>
</div></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Domain, Persistence</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>@Defaulted</code></p></td>
<td class="tableblock halign-left valign-top">
<div>
<div class="paragraph">
<p>Indicates that a (value) class has a default value.<br></p>
</div>
<div class="paragraph">
<p>The concept of "defaulted" means being able to provide a default value for the type by way of the <code>o.a.i.applib.adapters.DefaultsProvider</code> interface. Generally this only applies to value types, where the <code>@Value</code> annotation implies encodability through the <code>ValueSemanticsProvider</code> interface.<br></p>
</div>
<div class="paragraph">
<p>For these reasons the <code>@Defaulted</code> annotation is generally never applied directly, but can be thought of as a placeholder for future enhancements whereby non-value types might also have a default value provided for them.</p>
</div>
</div></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Domain</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>@Encodable</code></p></td>
<td class="tableblock halign-left valign-top">
<div>
<div class="paragraph">
<p>Indicates that a (value) class can be serialized/encoded.<br></p>
</div>
<div class="paragraph">
<p>Encodability means the ability to convert an object to-and-from a string, by way of the <code>o.a.i.applib.adapters.EncoderDecoder</code> interface. Generally this only applies to value types, where the <code>@Value</code> annotation implies encodability through the <code>ValueSemanticsProvider</code> interface.</p>
</div>
<div class="paragraph">
<p>For these reasons the <code>@Encodable</code> annotation is generally never applied directly, but can be thought of as a placeholder for future enhancements whereby non-value types might also be directly encoded.</p>
</div>
<div class="paragraph">
<p>Currently neither the Wicket viewer nor the RO viewer use this API. The Wicket viewer uses Wicket APIs, while RO viewer has its own mechanisms (parsing data from input JSON representations, etc.)</p>
</div>
</div></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Persistence</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>@NotPersistable</code></p></td>
<td class="tableblock halign-left valign-top">
<div>
<div class="paragraph">
<p>Indicates that a domain object may not be programmatically persisted.<br></p>
</div>
<div class="paragraph">
<p>+ This annotation indicates that transient instances of this class may be created but may not be persisted. The framework will not provide the user with an option to 'save' the object, and attempting to persist such an object programmatically would be an error.</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">@NotPersistable</span>(By.USER)
<span class="directive">public</span> <span class="type">class</span> <span class="class">InputForm</span> {
...
}</code></pre>
</div>
</div>
<div class="paragraph">
<p>By default the annotated object is effectively transient (ie default to <code>By.USER_OR_PROGRAM</code>).</p>
</div>
<div class="paragraph">
<p>This annotation is not supported by: Wicket viewer (which does not support transient objects). See also <a href="https://issues.apache.org/jira/browse/ISIS-743">ISIS-743</a> contemplating the removal of this annotation.</p>
</div>
</div></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Domain, Persistence</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>@Parseable</code></p></td>
<td class="tableblock halign-left valign-top">
<div>
<div class="paragraph">
<p>Indicates that a (value) class can be reconstructed from a string.<br></p>
</div>
<div class="paragraph">
<p>Parseability means being able to parse a string representation into an object by way of the <code>o.a.i.applib.adapters.Parser</code> interface. Generally this only applies to value types, where the <code>@Value</code> annotation implies encodability through the <code>ValueSemanticsProvider</code> interface.<br></p>
</div>
<div class="paragraph">
<p>For these reasons the <code>@Parser</code> annotation is generally never applied directly, but can be thought of as a placeholder for future enhancements whereby non-value types might also have be able to be parsed.<br></p>
</div>
<div class="paragraph">
<p>Note that the Wicket viewer uses Apache Wicket’s Converter API instead.</p>
</div>
</div></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">UI, Domain</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>@Value</code></p></td>
<td class="tableblock halign-left valign-top">
<div>
<div class="paragraph">
<p>Specify that a class has value-semantics.<br></p>
</div>
<div class="paragraph">
<p>The <code>@Value</code> annotation indicates that a class should be treated as a value type rather than as a reference (or entity) type. It does this providing an implementation of a <code>o.a.i.applib.adapters.ValueSemanticsProvider</code>.<br></p>
</div>
<div class="paragraph">
<p>For example:<br></p>
</div>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code data-lang="java"><span class="annotation">@Value</span>(semanticsProviderClass=
ComplexNumberValueSemanticsProvider.class)
<span class="directive">public</span> <span class="type">class</span> <span class="class">ComplexNumber</span> {
...
}</code></pre>
</div>
</div>
<div class="paragraph">
<p>The <code>ValueSemanticsProvider</code> allows the framework to interact with the value, parsing strings and displaying as text, and encoding/decoding (for serialization).</p>
</div>
</div></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Domain</p></td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
<div class="sect1">
<h2 id="_rgant-Action">3. <code>@Action</code></h2>
<button type="button" class="button secondary" onclick="window.location.href="https://github.com/apache/isis/edit/master/adocs/documentation/src/main/asciidoc/guides/_rgant-Action.adoc"" style="float: right; font-size: small; padding: 6px; margin-top: -55px; "><i class="fa fa-pencil-square-o"></i> Edit</button>
<div class="sectionbody">
<div class="paragraph">
<p>The <code>@Action</code> annotation groups together all domain-specific metadata for an invokable action on a domain object or domain service.</p>
</div>
<div class="paragraph">
<p>The table below summarizes the annotation’s attributes.</p>
</div>
<table class="tableblock frame-all grid-all spread">
<caption class="title">
Table 8.
<code>@Action</code> attributes
</caption>
<colgroup>
<col style="width: 25%;">
<col style="width: 25%;">
<col style="width: 50%;">
</colgroup>
<thead>
<tr>
<th class="tableblock halign-left valign-top">Attribute</th>
<th class="tableblock halign-left valign-top">Values (default)</th>
<th class="tableblock halign-left valign-top">Description</th>
</tr>
</thead>
<tbody>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="#_rgant-Action_command"><code>command()</code></a></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>AS_CONFIGURED</code>, <code>ENABLED</code>, <code>DISABLED</code><br> (<code>AS_CONFIGURED</code>)</p></td>
<td class="tableblock halign-left valign-top">
<div>
<div class="paragraph">
<p>whether the action invocation should be reified into a <code>o.a.i.applib.</code><br> <code>services.command.Command</code> object through the <a href="rgsvc.html#_rgsvc_api_CommandContext"><code>CommandContext</code></a> service.</p>
</div>
</div></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>commandExecuteIn()</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>FOREGROUND</code>,<code>BACKGROUND</code><br> (<code>FOREGROUND</code>)</p></td>
<td class="tableblock halign-left valign-top">
<div>
<div class="paragraph">
<p>whether to execute the command immediately, or to persist it (assuming that an appropriate implementation of <a href="rgsvc.html#_rgsvc_spi_CommandService"><code>CommandService</code></a> has been configured) such that a background scheduler can execute the command asynchronously</p>
</div>
</div></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>commandPersistence()</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>PERSISTED</code>, <code>NOT_PERSISTED</code>, <code>IF_HINTED</code><br> (<code>PERSISTED</code>)</p></td>
<td class="tableblock halign-left valign-top">
<div>
<div class="paragraph">
<p>whether the reified <code>Command</code> (as provided by the <code>CommandContext</code> domain service) should actually be persisted (assuming an appropriate implementation of <a href="rgsvc.html#_rgsvc_spi_CommandService"><code>CommandService</code></a> has been configured).</p>
</div>
</div></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="#_rgant-Action_domainEvent"><code>domainEvent()</code></a></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">subtype of <code>ActionDomainEvent</code><br> (<code>ActionDomainEvent.Default</code>)</p></td>
<td class="tableblock halign-left valign-top">
<div>
<div class="paragraph">
<p>the event type to be posted to the <a href="rgsvc.html#_rgsvc_api_EventBusService"><code>EventBusService</code></a> to broadcast the action’s business rule checking (hide, disable, validate) and its invocation (pre-execute and post-execute).</p>
</div>
</div></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="#_rgant-Action_hidden"><code>hidden()</code></a></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>EVERYWHERE</code>, <code>NOWHERE</code><br> (<code>NOWHERE</code>)</p></td>
<td class="tableblock halign-left valign-top">
<div>
<div class="paragraph">
<p>indicates where (in the UI) the action should be hidden from the user.</p>
</div>
</div></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="#_rgant-Action_invokeOn"><code>invokeOn()</code></a></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>OBJECT_ONLY</code>, <code>COLLECTION_ONLY</code>, <code>OBJECT_AND_COLLECTION</code><br> (<code>OBJECT_ONLY</code>)</p></td>
<td class="tableblock halign-left valign-top">
<div>
<div class="paragraph">
<p>whether an action can be invoked on a single object and/or on many objects in a collection.</p>
</div>
<div class="paragraph">
<p>Currently this is only supported for no-arg actions.</p>
</div>
</div></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="#_rgant-Action_publishing"><code>publishing()</code></a></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>AS_CONFIGURED</code>, <code>ENABLED</code>, <code>DISABLED</code><br> (<code>AS_CONFIGURED</code>)</p></td>
<td class="tableblock halign-left valign-top">
<div>
<div class="paragraph">
<p>whether the action invocation should be published to the registered <a href="rgsvc.html#_rgsvc_spi_PublishingService"><code>PublishingService</code></a>.</p>
</div>
</div></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>publishing-</code><br> <code>PayloadFactory()</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">subtype of <code>PublishingPayloadFactory-</code> <code>ForAction</code> (none)</p></td>
<td class="tableblock halign-left valign-top">
<div>
<div class="paragraph">
<p>specifies that a custom implementation of <code>PublishingPayloadFactoryForAction</code> be used to create the (payload of the) published event representing the action invocation</p>
</div>
</div></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="#_rgant-Action_restrictTo"><code>restrictTo()</code></a></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>NO_RESTRICTIONS</code>,<code>PROTOTYPING</code><br> (<code>NO_RESTRICTIONS</code>)</p></td>
<td class="tableblock halign-left valign-top">
<div>
<div class="paragraph">
<p>whether the action is only available in prototyping mode, or whether it is available also in production mode.</p>
</div>
</div></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="#_rgant-Action_semantics"><code>semantics()</code></a></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>SAFE_AND_REQUEST_CACHEABLE</code>, <code>SAFE</code>,<br> <code>IDEMPOTENT</code>, <code>IDEMPOTENT_ARE_YOU_SURE</code><br> <code>NON_IDEMPOTENT</code>, <code>NON_IDEMPOTENT_ARE_YOU_SURE</code> +<br> (<code>NON_IDEMPOTENT</code>)</p></td>
<td class="tableblock halign-left valign-top">
<div>
<div class="paragraph">
<p>the action’s semantics (ie whether objects are modified as the result of invoking this action, and if so whether reinvoking the action would result in no further change; if not whether the results can be cached for the remainder of the request).</p>
</div>
<div class="paragraph">
<p>The <code>…ARE_YOU_SURE</code> variants cause a confirmation dialog to be displayed in the <a href="ugvw.html">Wicket viewer</a>.</p>
</div>
</div></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="#_rgant-Action_typeOf"><code>typeOf()</code></a></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">(none)</p></td>
<td class="tableblock halign-left valign-top">
<div>
<div class="paragraph">
<p>if the action returns a collection, hints as to the run-time type of the objects within that collection (as a fallback)</p>
</div>
</div></td>
</tr>
</tbody>
</table>
<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">class</span> <span class="class">ToDoItem</span> {
<span class="directive">public</span> <span class="directive">static</span> <span class="type">class</span> <span class="class">CompletedEvent</span> <span class="directive">extends</span> ActionDomainEvent<ToDoItem> { }
<span class="annotation">@Action</span>(
command=CommandReification.ENABLED,
commandExecuteIn=CommandExecuteIn.FOREGROUND, <i class="conum" data-value="1"></i><b>(1)</b>
commandPersistence=CommandPersistence.NOT_PERSISTED, <i class="conum" data-value="2"></i><b>(2)</b>
domainEvent=CompletedEvent.class,
hidden = Where.NOWHERE, <i class="conum" data-value="3"></i><b>(3)</b>
invokeOn = InvokeOn.OBJECT_ONLY, <i class="conum" data-value="4"></i><b>(4)</b>
publishing = Publishing.ENABLED,
semantics = SemanticsOf.IDEMPOTENT
)
<span class="directive">public</span> ToDoItem completed() { ... }
}</code></pre>
</div>
</div>
<div class="colist arabic">
<table>
<tbody>
<tr>
<td><i class="conum" data-value="1"></i><b>1</b></td>
<td>default value, so could be omitted</td>
</tr>
<tr>
<td><i class="conum" data-value="2"></i><b>2</b></td>
<td>default value, so could be omitted</td>
</tr>
<tr>
<td><i class="conum" data-value="3"></i><b>3</b></td>
<td>default value, so could be omitted</td>
</tr>
<tr>
<td><i class="conum" data-value="4"></i><b>4</b></td>
<td>default value, so could be omitted</td>
</tr>
</tbody>
</table>
</div>
<div class="sect2">
<h3 id="_rgant-Action_command">3.1. <code>command()</code></h3>
<button type="button" class="button secondary" onclick="window.location.href="https://github.com/apache/isis/edit/master/adocs/documentation/src/main/asciidoc/guides/_rgant-Action_command.adoc"" style="float: right; font-size: small; padding: 6px; margin-top: -55px; "><i class="fa fa-pencil-square-o"></i> Edit</button>
<div class="paragraph">
<p>The <code>@Action(command=…)</code> attribute (and the related <code>@Action(commandPersistence=…)</code> and <code>@Action(commandExecuteIn=…)</code> attributes) allows an action invocation to be made into a concrete object such that it can be inspected and persisted. The primary use case for this is enhanced profiling/auditing, and it also supports the deferring the execution of the action such that it can be invoked in the background.</p>
</div>
<div class="paragraph">
<p>The annotation works with (and is influenced by the behaviour of) a number of domain services:</p>
</div>
<div class="ulist">
<ul>
<li> <p><a href="rgsvc.html#_rgsvc_api_CommandContext"><code>CommandContext</code></a></p> </li>
<li> <p><a href="rgsvc.html#_rgsvc_spi_CommandService"><code>CommandService</code></a></p> </li>
<li> <p><a href="rgsvc.html#_rgsvc_spi_BackgroundService"><code>BackgroundService</code></a> and</p> </li>
<li> <p><a href="rgsvc.html#_rgsvc_spi_BackgroundCommandService"><code>BackgroundCommandService</code></a></p> </li>
</ul>
</div>
<div class="paragraph">
<p>Each action invocation is reified by the <a href="rgsvc.html#_rgsvc_api_CommandContext"><code>CommandContext</code></a> service into a <code>Command</code> object, capturing details of the target object, the action, the parameter arguments, the user, a timestamp and so on.</p>
</div>
<div class="paragraph">
<p>If an appropriate <code>CommandService</code> is configured (for example using (non-ASF) <a href="http://github.com/isisaddons/isis-module-command">Isis addons' command</a> module), then the <code>Command</code> itself is persisted.</p>
</div>
<div class="paragraph">
<p>By default, actions are invoked in directly in the thread of the invocation. If there is an implementation of <code>BackgroundCommandService</code> (as the <a href="http://github.com/isisaddons/isis-module-command">Isis addons' command</a> module does provide), then this means in turn that the <code>BackgroundService</code> can be used by the domain object code to programmatically create background <code>Command</code>s.</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>If background <code>Command</code>s are used, then an external scheduler, using <a href="ugbtb.html#_ugbtb_headless-access_BackgroundCommandExecution">headless access</a>, must also be configured.</p>
</div> </td>
</tr>
</tbody>
</table>
</div>
<div class="paragraph">
<p>The <code>command()</code> attribute determines whether the action invocation should be reified into a <code>Command</code> object (by the <a href="rgsvc.html#_rgsvc_api_CommandContext"><code>CommandContext</code></a> service).</p>
</div>
<div class="paragraph">
<p>The default is <code>AS_CONFIGURED</code>, meaning that the <a href="rgcfg.html#_rgcfg_configuring-core">configuration property</a> <code>isis.services.command.actions</code> is used to determine the whether the action is reified:</p>
</div>
<div class="ulist">
<ul>
<li> <p><code>all</code><br></p>
<div class="paragraph">
<p>all actions are reified</p>
</div> </li>
<li> <p><code>ignoreSafe</code> (or <code>ignoreQueryOnly</code>)<br></p>
<div class="paragraph">
<p>actions with safe (read-only) semantics are ignored, but actions which may modify data are not ignored</p>
</div> </li>
<li> <p><code>none</code><br></p>
<div class="paragraph">
<p>no actions are reified.</p>
</div> </li>
</ul>
</div>
<div class="paragraph">
<p>If there is no configuration property in <code>isis.properties</code> then all actions are reified into <code>Command</code>s.</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: <code>Command</code> reification does not necessarily imply that <code>Command</code> objects will be persisted; that depends on whether there is a <a href="rgsvc.html#_rgsvc_spi_CommandService"><code>CommandService</code></a> configured that will persist said <code>Command</code>s.</p>
</div> </td>
</tr>
</tbody>
</table>
</div>
<div class="paragraph">
<p>This default can be overridden on an action-by-action basis; if <code>command()</code> is set to <code>ENABLED</code> then the action is reified irrespective of the configured value; if set to <code>DISABLED</code> then the action is NOT reified irrespective of the configured value.</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">class</span> <span class="class">Order</span> {
<span class="annotation">@Action</span>(command=CommandReification.ENABLED)
<span class="directive">public</span> Invoice generateInvoice(...) { ... }
}</code></pre>
</div>
</div>
<div class="paragraph">
<p>corresponds to the behaviour described above; the <code>Command</code> object is persisted (assuming an appropriate <code>CommandService</code> is defined, and executed immediately in the foreground).</p>
</div>
<div class="sect3">
<h4 id="__code_commandpersistence_code">3.1.1. <code>commandPersistence()</code></h4>
<div class="paragraph">
<p>If the action has been reified, then the <code>commandPersistence()</code> attribute determines whether that <code>Command</code> object should then also be persisted (the default), or not persisted, or only if hinted.</p>
</div>
<div class="paragraph">
<p>To explain this last alternative:</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">Order</span> {
<span class="annotation">@Action</span>(
command=CommandReification.ENABLED,
commandPersistence=CommandPersistence.IF_HINTED
)
<span class="directive">public</span> Invoice generateInvoice(...) { ... }
}</code></pre>
</div>
</div>
<div class="paragraph">
<p>will suppress the persistence of the <code>Command</code> object <em>unless</em> a child background <code>Command</code> has been created in the body of the action by way of the <a href="rgsvc.html#_rgsvc_api_BackgroundService"><code>BackgroundService</code></a>.</p>
</div>
<div class="paragraph">
<p>On the other hand:</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">Order</span> {
<span class="annotation">@Action</span>(
command=CommandReification.ENABLED,
commandExecuteIn=CommandExecuteIn.FOREGROUND,
commandPersistence=CommandPersistence.NOT_PERSISTED
)
<span class="directive">public</span> Invoice generateInvoice(...) { ... }
}</code></pre>
</div>
</div>
<div class="paragraph">
<p>will prevent the parent <code>Command</code> object from being persisted, <em>even if</em> a child background <code>Command</code> is created.</p>
</div>
</div>
<div class="sect3">
<h4 id="__code_commandexecutein_code">3.1.2. <code>commandExecuteIn()</code></h4>
<div class="paragraph">
<p>For persisted commands, the <code>commandExecuteIn()</code> attribute determines whether the <code>Command</code> should be executed in the foreground (the default) or executed in the background.</p>
</div>
<div class="paragraph">
<p>Background execution means that the command is not executed immediately, but is available for a configured <a href="rgsvc.html#_rgsvc_spi_BackgroundCommandService"><code>BackgroundCommandService</code></a> to execute, eg by way of an in-memory scheduler such as Quartz. See <a href="ugbtb.html#_ugbtb_headless-access_BackgroundCommandExecution">here</a> for further information on this topic.</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">class</span> <span class="class">Order</span> {
<span class="annotation">@Action</span>(
command=CommandReification.ENABLED,
commandExecuteIn=CommandExecuteIn.BACKGROUND)
<span class="directive">public</span> Invoice generateInvoice(...) { ... }
}</code></pre>
</div>
</div>
<div class="paragraph">
<p>will result in the <code>Command</code> being persisted but its execution deferred to a background execution mechanism. The returned object from this action is the persisted <code>Command</code> itself.</p>
</div>
</div>
</div>
<div class="sect2">
<h3 id="_rgant-Action_domainEvent">3.2. domainEvent()</h3>
<button type="button" class="button secondary" onclick="window.location.href="https://github.com/apache/isis/edit/master/adocs/documentation/src/main/asciidoc/guides/_rgant-Action_domainEvent.adoc"" style="float: right; font-size: small; padding: 6px; margin-top: -55px; "><i class="fa fa-pencil-square-o"></i> Edit</button>
<div class="paragraph">
<p>Whenever a domain object (or list of domain objects) is to be rendered, the framework fires off multiple domain events for every property, collection and action of the domain object. In the cases of the domain object’s actions, the events that are fired are:</p>
</div>
<div class="ulist">
<ul>
<li> <p>hide phase: to check that the action is visible (has not been hidden)</p> </li>
<li> <p>disable phase: to check that the action is usable (has not been disabled)</p> </li>
<li> <p>validate phase: to check that the action’s arguments are valid</p> </li>
<li> <p>pre-execute phase: before the invocation of the action</p> </li>
<li> <p>post-execute: after the invocation of the action</p> </li>
</ul>
</div>
<div class="paragraph">
<p>Subscribers subscribe through the <a href="rgsvc.html#_rgsvc_api_EventBusService"><code>EventBusService</code></a> using either <a href="https://github.com/google/guava">Guava</a> or <a href="http://www.axonframework.org/">Axon Framework</a> annotations and can influence each of these phases.</p>
</div>
<div class="paragraph">
<p>By default the event raised is <code>ActionDomainEvent.Default</code>. 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">class</span> <span class="class">ToDoItem</span> {
<span class="annotation">@Action</span>()
<span class="directive">public</span> ToDoItem completed() { ... }
...
}</code></pre>
</div>
</div>
<div class="paragraph">
<p>The <code>domainEvent()</code> attribute allows a custom subclass to be emitted allowing more precise subscriptions (to those subclasses) to be defined instead. This attribute is also supported for <a href="#_rgant-Collection_domainEvent">collections</a> and <a href="#_rgant-Property_domainEvent">properties</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="directive">public</span> <span class="type">class</span> <span class="class">ToDoItem</span> {
<span class="directive">public</span> <span class="directive">static</span> <span class="type">class</span> <span class="class">CompletedEvent</span> <span class="directive">extends</span> ActionDomainEvent<ToDoItem> { } <i class="conum" data-value="1"></i><b>(1)</b>
<span class="annotation">@Action</span>(domainEvent=CompletedEvent.class)
<span class="directive">public</span> ToDoItem completed() { ... }
}</code></pre>
</div>
</div>
<div class="paragraph">
<p>The benefit is that subscribers can be more targeted as to the events that they subscribe to.</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>As of <code>1.10.0</code> the framework provides no-arg constructor and will initialize the domain event using (non-API) setters rather than through the constructor. This substantially reduces the boilerplate.</p>
</div> </td>
</tr>
</tbody>
</table>
</div>
<div class="sect3">
<h4 id="_subscribers">3.2.1. Subscribers</h4>
<div class="paragraph">
<p>Subscribers (which must be domain services) subscribe using either the <a href="https://github.com/google/guava">Guava</a> API or (if the <a href="rgsvc.html#_rgsvc_api_EventBusService"><code>EventBusService</code></a> has been appropriately configured) using the <a href="http://www.axonframework.org/">Axon Framework</a> API. The examples below use the Guava API.</p>
</div>
<div class="paragraph">
<p>Subscribers can be either coarse-grained (if they subscribe to the top-level event type):</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code data-lang="java"><span class="annotation">@DomainService</span>(nature=NatureOfService.DOMAIN)
<span class="directive">public</span> <span class="type">class</span> <span class="class">SomeSubscriber</span> <span class="directive">extends</span> AbstractSubscriber {
<span class="annotation">@com</span>.google.common.eventbus.Subscribe
<span class="directive">public</span> <span class="type">void</span> on(ActionDomainEvent ev) {
...
}
}</code></pre>
</div>
</div>
<div class="paragraph">
<p>or can be fine-grained (by subscribing to specific event subtypes):</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code data-lang="java"><span class="annotation">@DomainService</span>(nature=NatureOfService.DOMAIN)
<span class="directive">public</span> <span class="type">class</span> <span class="class">SomeSubscriber</span> <span class="directive">extends</span> AbstractSubscriber {
<span class="annotation">@com</span>.google.common.eventbus.Subscribe
<span class="directive">public</span> <span class="type">void</span> on(ToDoItem.CompletedEvent ev) {
...
}
}</code></pre>
</div>
</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>If the AxonFramework is being used, replace <code>@com.google.common.eventbus.Subscribe</code> with <code>@org.axonframework.eventhandling.annotation.EventHandler</code>.</p>
</div> </td>
</tr>
</tbody>
</table>
</div>
<div class="paragraph">
<p>The subscriber’s method is called (up to) 5 times:</p>
</div>
<div class="ulist">
<ul>
<li> <p>whether to veto visibility (hide)</p> </li>
<li> <p>whether to veto usability (disable)</p> </li>
<li> <p>whether to veto execution (validate)</p> </li>
<li> <p>steps to perform prior to the action being invoked.</p> </li>
<li> <p>steps to perform after the action has been invoked.</p> </li>
</ul>
</div>
<div class="paragraph">
<p>The subscriber can distinguish these by calling <code>ev.getEventPhase()</code>. Thus the general form is:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code data-lang="java"><span class="annotation">@Programmatic</span>
<span class="annotation">@com</span>.google.common.eventbus.Subscribe
<span class="directive">public</span> <span class="type">void</span> on(ActionDomainEvent ev) {
<span class="keyword">switch</span>(ev.getEventPhase()) {
<span class="keyword">case</span> HIDE:
<span class="comment">// call ev.hide() or ev.veto("") to hide the action</span>
<span class="keyword">break</span>;
<span class="keyword">case</span> DISABLE:
<span class="comment">// call ev.disable("...") or ev.veto("...") to disable the action</span>
<span class="keyword">break</span>;
<span class="keyword">case</span> VALIDATE:
<span class="comment">// call ev.invalidate("...") or ev.veto("...")</span>
<span class="comment">// if action arguments are invalid</span>
<span class="keyword">break</span>;
<span class="keyword">case</span> EXECUTING:
<span class="keyword">break</span>;
<span class="keyword">case</span> EXECUTED:
<span class="keyword">break</span>;
}
}</code></pre>
</div>
</div>
<div class="paragraph">
<p>It is also possible to abort the transaction during the executing or executed phases by throwing an exception. If the exception is a subtype of <code>RecoverableException</code> then the exception will be rendered as a user-friendly warning (eg Growl/toast) rather than an error.</p>
</div>
</div>
<div class="sect3">
<h4 id="_default_doop_and_noop_events">3.2.2. Default, Doop and Noop events</h4>
<div class="paragraph">
<p>If the <code>domainEvent</code> attribute is not explicitly specified (is left as its default value, <code>ActionDomainEvent.Default</code>), then the framework will, by default, post an event.</p>
</div>
<div class="paragraph">
<p>If this is not required, then the <code>isis.reflector.facet.actionAnnotation.domainEvent.postForDefault</code> configuration property can be set to "false"; this will disable posting.</p>
</div>
<div class="paragraph">
<p>On the other hand, if the <code>domainEvent</code> has been explicitly specified to some subclass, then an event will be posted. The framework provides <code>ActionDomainEvent.Doop</code> as such a subclass, so setting the <code>domainEvent</code> attribute to this class will ensure that the event to be posted, irrespective of the configuration property setting.</p>
</div>
<div class="paragraph">
<p>And, conversely, the framework also provides <code>ActionDomainEvent.Noop</code>; if <code>domainEvent</code> attribute is set to this class, then no event will be posted.</p>
</div>
</div>
<div class="sect3">
<h4 id="_raising_events_programmatically">3.2.3. Raising events programmatically</h4>
<div class="paragraph">
<p>Normally events are only raised for interactions through the UI. However, events can be raised programmatically either by calling the <a href="rgsvc.html#_rgsvc_api_EventBusService"><code>EventBusService</code></a> API directly, or by emulating the UI by wrapping the target object using the <a href="rgsvc.html#_rgsvc_api_WrapperFactory"><code>WrapperFactory</code></a> domain service.</p>
</div>
</div>
</div>
<div class="sect2">
<h3 id="_rgant-Action_hidden">3.3. <code>hidden()</code></h3>
<button type="button" class="button secondary" onclick="window.location.href="https://github.com/apache/isis/edit/master/adocs/documentation/src/main/asciidoc/guides/_rgant-Action_hidden.adoc"" style="float: right; font-size: small; padding: 6px; margin-top: -55px; "><i class="fa fa-pencil-square-o"></i> Edit</button>
<div class="paragraph">
<p>Actions can be hidden at the domain-level, indicating that they are not visible to the end-user. This attribute can also be applied to <a href="#_rgant-Property_hidden">properties</a> and <a href="#_rgant-Collection_hidden">collections</a>.</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>It is also possible to use <a href="#_rgant-ActionLayout_hidden"><code>@ActionLayout#hidden()</code></a> or <a href="ugfun.html#_ugfun_object-layout_dynamic">dynamic layouts</a> such that the action can be hidden at the view layer. Both options are provided with a view that in the future the view-layer semantics may be under the control of (expert) users, whereas domain-layer semantics should never be overridden or modified by the user.</p>
</div> </td>
</tr>
</tbody>
</table>
</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">class</span> <span class="class">Customer</span> {
<span class="annotation">@Action</span>(hidden=Where.EVERYWHERE)
<span class="directive">public</span> <span class="type">void</span> updateStatus() { ... }
...
}</code></pre>
</div>
</div>
<div class="paragraph">
<p>The acceptable values for the <code>where</code> parameter are:</p>
</div>
<div class="ulist">
<ul>
<li> <p><code>Where.EVERYWHERE</code> or <code>Where.ANYWHERE</code><br></p>
<div class="paragraph">
<p>The action should be hidden at all times.</p>
</div> </li>
<li> <p><code>Where.NOWHERE</code><br></p>
<div class="paragraph">
<p>The action should not be hidden.</p>
</div> </li>
</ul>
</div>
<div class="paragraph">
<p>The other values of the <code>Where</code> enum have no meaning for a collection.</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>For actions of domain services the visibility is dependent upon its <a href="#_rgant-DomainService_nature"><code>@DomainService#nature()</code></a> and also on whether it is contributed (as per <a href="#_rgant-ActionLayout_contributedAs"><code>@ActionLayout#contributedAs()</code></a>).</p>
</div> </td>
</tr>
</tbody>
</table>
</div>
</div>
<div class="sect2">
<h3 id="_rgant-Action_invokeOn">3.4. <code>invokeOn()</code></h3>
<button type="button" class="button secondary" onclick="window.location.href="https://github.com/apache/isis/edit/master/adocs/documentation/src/main/asciidoc/guides/_rgant-Action_invokeOn.adoc"" style="float: right; font-size: small; padding: 6px; margin-top: -55px; "><i class="fa fa-pencil-square-o"></i> Edit</button>
<div class="paragraph">
<p>The <code>invokeOn()</code> attribute indicates whether the an action can be invoked on a single object (the default) and/or on many objects in a collection.</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">class</span> <span class="class">ToDoItem</span> {
<span class="annotation">@Action</span>(invokeOn=InvokeOn.OBJECT_AND_COLLECTION)
<span class="directive">public</span> <span class="type">void</span> markAsCompleted() {
setCompleted(<span class="predefined-constant">true</span>);
}
...
}</code></pre>
</div>
</div>
<div class="paragraph">
<p>Actions to be invoked on collection (currently) have a number of constraints. It:</p>
</div>
<div class="ulist">
<ul>
<li> <p>must take no arguments</p> </li>
<li> <p>cannot be hidden (any annotations or supporting methods to that effect will be ignored)</p> </li>
<li> <p>cannot be disabled (any annotations or supporting methods to that effect will be ignored).</p> </li>
</ul>
</div>
<div class="paragraph">
<p>The example given above is probably ok, because <code>setCompleted()</code> is most likely idempotent. However, if the action also called some other method, then we should add a guard.</p>
</div>
<div class="paragraph">
<p>For example, for this non-idempotent action:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code data-lang="java"><span class="annotation">@Action</span>(invokeOn=InvokeOn.OBJECT_AND_COLLECTION)
<span class="directive">public</span> <span class="type">void</span> markAsCompleted() {
setCompleted(<span class="predefined-constant">true</span>);
todoTotalizer.incrementNumberCompleted();
}</code></pre>
</div>
</div>
<div class="paragraph">
<p>we should instead write it as:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code data-lang="java"><span class="annotation">@Action</span>(invokeOn=InvokeOn.OBJECT_AND_COLLECTION)
<span class="directive">public</span> <span class="type">void</span> markAsCompleted() {
<span class="keyword">if</span>(isCompleted()) {
<span class="keyword">return</span>;
}
setCompleted(<span class="predefined-constant">true</span>);
todoTotalizer.incrementNumberCompleted();
}</code></pre>
</div>
</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>This attribute has no meaning if annotated on an action of a domain service.</p>
</div> </td>
</tr>
</tbody>
</table>
</div>
</div>
<div class="sect2">
<h3 id="_rgant-Action_publishing">3.5. <code>publishing()</code></h3>
<button type="button" class="button secondary" onclick="window.location.href="https://github.com/apache/isis/edit/master/adocs/documentation/src/main/asciidoc/guides/_rgant-Action_publishing.adoc"" style="float: right; font-size: small; padding: 6px; margin-top: -55px; "><i class="fa fa-pencil-square-o"></i> Edit</button>
<div class="paragraph">
<p>The <code>publishing()</code> attribute determines whether and how an action invocation is published via the registered implementation of a <a href="rgsvc.html#_rgsvc_spi_PublishingService"><code>PublishingService</code></a>) or <a href="rgsvc.html#_rgsvc_spi_PublisherService"><code>PublisherService</code></a>. This attribute is also supported for <a href="#_rgant-DomainObject_publishing">domain objects</a>, where it controls whether changed objects are published as events, and for <a href="#_rgant_Property_publishing"><code>@Property#publishing()</code></a>, where it controls whether property edits are published as events.</p>
</div>
<div class="paragraph">
<p>A common use case is to notify external "downstream" systems of changes in the state of the Isis application. The default value for the attribute is <code>AS_CONFIGURED</code>, meaning that the <a href="rgcfg.html#_rgcfg_configuring-core">configuration property</a> <code>isis.services.publish.actions</code> is used to determine the whether the action is published:</p>
</div>
<div class="ulist">
<ul>
<li> <p><code>all</code><br></p>
<div class="paragraph">
<p>all action invocations are published</p>
</div> </li>
<li> <p><code>ignoreSafe</code> (or <code>ignoreQueryOnly</code>)<br></p>
<div class="paragraph">
<p>invocations of actions with safe (read-only) semantics are ignored, but actions which may modify data are not ignored</p>
</div> </li>
<li> <p><code>none</code><br></p>
<div class="paragraph">
<p>no action invocations are published</p>
</div> </li>
</ul>
</div>
<div class="paragraph">
<p>If there is no configuration property in <code>isis.properties</code> then publishing is automatically enabled.</p>
</div>
<div class="paragraph">
<p>This default can be overridden on an action-by-action basis; if <code>publishing()</code> is set to <code>ENABLED</code> then the action invocation is published irrespective of the configured value; if set to <code>DISABLED</code> then the action invocation is <em>not</em> published, again irrespective of the configured value.</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">class</span> <span class="class">Order</span> {
<span class="annotation">@Action</span>(publishing=Publishing.ENABLED) <i class="conum" data-value="1"></i><b>(1)</b>
<span class="directive">public</span> Invoice generateInvoice(...) { ... }
}</code></pre>
</div>
</div>
<div class="colist arabic">
<table>
<tbody>
<tr>
<td><i class="conum" data-value="1"></i><b>1</b></td>
<td>because set to enabled, will be published irrespective of the configured value.</td>
</tr>
</tbody>
</table>
</div>
<div class="sect3">
<h4 id="__code_publishingpayloadfactory_code">3.5.1. <code>publishingPayloadFactory()</code></h4>
<div class="paragraph">
<p>The (optional) related <code>publishingPayloadFactory()</code> specifies the class to use to create the (payload of the) event to be published by the publishing factory.</p>
</div>
<div class="paragraph">
<p>Rather than simply broadcast that the action was invoked, the payload factory allows a "fatter" payload to be instantiated that can eagerly push commonly-required information to all subscribers. For at least some subscribers this should avoid the necessity to query back for additional information.</p>
</div>
<div class="admonitionblock warning">
<table>
<tbody>
<tr>
<td class="icon"> <i class="fa icon-warning" title="Warning"></i> </td>
<td class="content">
<div class="paragraph">
<p>Be aware that this attribute is only honoured by the (deprecated) <a href="rgsvc.html#_rgsvc_spi_PublishingService"><code>PublishingService</code></a>, so should itself be considered as deprecated. It is ignored by the replacement <a href="rgsvc.html#_rgsvc_spi_PublisherService"><code>PublisherService</code></a>,</p>
</div> </td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
<div class="sect2">
<h3 id="_rgant-Action_restrictTo">3.6. <code>restrictTo()</code></h3>
<button type="button" class="button secondary" onclick="window.location.href="https://github.com/apache/isis/edit/master/adocs/documentation/src/main/asciidoc/guides/_rgant-Action_restrictTo.adoc"" style="float: right; font-size: small; padding: 6px; margin-top: -55px; "><i class="fa fa-pencil-square-o"></i> Edit</button>
<div class="paragraph">
<p>By default actions are available irrespective of the <a href="rgcfg.html#_rgcfg_deployment-types">deployment mode</a>. The <code>restrictTo()</code> attribute specifies whether the action should instead be restricted to only available in prototyping mode.</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">class</span> <span class="class">Customer</span> {
<span class="directive">public</span> Order placeNewOrder() { ... }
<span class="directive">public</span> <span class="predefined-type">List</span><Order> listRecentOrders() { ... }
<span class="annotation">@Action</span>(restrictTo=RestrictTo.PROTOTYPING)
<span class="directive">public</span> <span class="predefined-type">List</span><Order> listAllOrders() { ... }
...
}</code></pre>
</div>
</div>
<div class="paragraph">
<p>In this case the listing of all orders (in the <code>listAllOrders()</code> action) probably doesn’t make sense for production; there could be thousands or millions. However, it would be useful to disaply how for a test or demo system where there are only a handful of orders.</p>
</div>
</div>
<div class="sect2">
<h3 id="_rgant-Action_semantics">3.7. <code>semantics()</code></h3>
<button type="button" class="button secondary" onclick="window.location.href="https://github.com/apache/isis/edit/master/adocs/documentation/src/main/asciidoc/guides/_rgant-Action_semantics.adoc"" style="float: right; font-size: small; padding: 6px; margin-top: -55px; "><i class="fa fa-pencil-square-o"></i> Edit</button>
<div class="paragraph">
<p>The <code>semantics()</code> attribute describes whether the invocation modifies state of the system, and if so whether it does so idempotently. If the action invocation does <em>not</em> modify the state of the system, in other words is safe, then it also can beused to specify whether the results of the action can be cached automatically for the remainder of the request.</p>
</div>
<div class="paragraph">
<p>The attribute was originally introduced for the <a href="ugvro.html">RestfulObjects viewer</a> in order that action invocations could be using the appropriate <code>HTTP</code> verb (<code>GET</code>, <code>PUT</code> and <code>POST</code>).</p>
</div>
<div class="paragraph">
<p>The table below summarizes the semantics:</p>
</div>
<table class="tableblock frame-all grid-all spread">
<colgroup>
<col style="width: 28.5714%;">
<col style="width: 14.2857%;">
<col style="width: 42.8571%;">
<col style="width: 14.2858%;">
</colgroup>
<thead>
<tr>
<th class="tableblock halign-left valign-top">Semantic</th>
<th class="tableblock halign-left valign-top">Changes state</th>
<th class="tableblock halign-left valign-top">Effect of multiple calls</th>
<th class="tableblock halign-left valign-top">HTTP verb<br> (Restful Objects)</th>
</tr>
</thead>
<tbody>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>SAFE_AND_REQUEST_CACHEABLE</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">No</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Will always return the same result each time invoked (within a given request scope)</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>GET</code></p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>SAFE</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">No</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Might result in different results each invocation</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>GET</code></p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>IDEMPOTENT</code><br> <code>IDEMPOTENT_ARE_YOU_SURE</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Yes</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Will make no further changes if called multiple times (eg sets a property or adds to a <code>Set</code>).<br> The "are you sure" variant requires that the user must explicitly confirm the action.</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>PUT</code></p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>NON_IDEMPOTENT</code><br> <code>NON_IDEMPOTENT_ARE_YOU_SURE</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Yes</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Might change the state of the system each time called (eg increments a counter or adds to a <code>List</code>).<br> The "are you sure" variant requires that the user must explicitly confirm the action.</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>POST</code></p></td>
</tr>
</tbody>
</table>
<div class="paragraph">
<p>The actions' semantics are also used by the core runtime as part of the in-built concurrency checkng; invocation of a safe action (which includes request-cacheable) does <em>not</em> perform a concurrency check, whereas non-safe actions <em>do</em> perform a concurrency check.</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">class</span> <span class="class">Customer</span> {
<span class="annotation">@Action</span>(semantics=SemanticsOf.SAFE_AND_REQUEST_CACHEABLE)
<span class="directive">public</span> CreditRating checkCredit() { ... }
<span class="annotation">@Action</span>(semantics=SemanticsOf.IDEMPOTENT)
<span class="directive">public</span> <span class="type">void</span> changeOfAddress(Address address) { ... }
<span class="annotation">@Action</span>(semantics=SemanticsOf.NON_IDEMPOTENT)
<span class="directive">public</span> Order placeNewOrder() { ... }
...
}</code></pre>
</div>
</div>
<div class="paragraph">
<p>Actions that are safe and request-cacheable automatically use the <a href="rgsvc.html#_rgsvc_api_QueryResultsCache"><code>QueryResultsCache</code></a> service to cache the result of the method. Note though that the results of this caching will only be apparent if the action is invoked from another method using the <a href="rgsvc.html#_rgsvc_api_WrapperFactory"><code>WrapperFactory</code></a> service.</p>
</div>
<div class="paragraph">
<p>Continuing the example above, imagine code that loops over a set of <code>Order</code>s where each <code>Order</code> has an associated <code>Customer</code>. We want to check the credit rating of each <code>Customer</code> (a potentially expensive operation) but we don’t want to do it more than once per <code>Customer</code>. Invoking through the <code>WrapperFactory</code> will allow us to accomplish this by exploiting the semantics of <code>checkCredit()</code> action:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code data-lang="java"><span class="directive">public</span> <span class="type">void</span> dispatchToCreditWorthyCustomers(<span class="directive">final</span> <span class="predefined-type">List</span><Order> orders) {
<span class="keyword">for</span>(Order order: orders) {
Customer customer = order.getCustomer();
CreditRating creditRating = wrapperFactory.wrapSkipRules(customer).checkCredit(); <i class="conum" data-value="1"></i><b>(1)</b>
<span class="keyword">if</span>(creditRating.isWorthy()) {
order.dispatch();
}
}
}
<span class="annotation">@Inject</span>
WrapperFactory wrapperFactory;</code></pre>
</div>
</div>
<div class="colist arabic">
<table>
<tbody>
<tr>
<td><i class="conum" data-value="1"></i><b>1</b></td>
<td>wrap the customer to dispatch.</td>
</tr>
</tbody>
</table>
</div>
<div class="paragraph">
<p>In the above example we’ve used <code>wrapSkipRules(…)</code> but if we wanted to enforce any business rules associated with the <code>checkCredit()</code> method, we would have used <code>wrap(…)</code>.</p>
</div>
</div>
<div class="sect2">
<h3 id="_rgant-Action_typeOf">3.8. <code>typeOf()</code></h3>
<button type="button" class="button secondary" onclick="window.location.href="https://github.com/apache/isis/edit/master/adocs/documentation/src/main/asciidoc/guides/_rgant-Action_typeOf.adoc"" style="float: right; font-size: small; padding: 6px; margin-top: -55px; "><i class="fa fa-pencil-square-o"></i> Edit</button>
<div class="paragraph">
<p>The <code>typeOf()</code> attribute specifies the expected type of an element returned by the action (returning a collection), when for whatever reason the type cannot be inferred from the generic type, or to provide a hint about the actual run-time (as opposed to compile-time) type. This attribute can also be specified for <a href="#_rgant-Collection_typeOf">collections</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="directive">public</span> <span class="type">void</span> AccountService {
<span class="annotation">@Action</span>(typeOf=Customer.class)
<span class="directive">public</span> <span class="predefined-type">List</span> errantAccounts() {
<span class="keyword">return</span> customers.allNewCustomers();
}
...
<span class="annotation">@Inject</span>
CustomerRepository customers;
}</code></pre>
</div>
</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>In general we recommend that you use generics instead, eg <code>List<Customer></code>.</p>
</div> </td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
</div>
<div class="sect1">
<h2 id="_rgant-ActionLayout">4. <code>@ActionLayout</code></h2>
<button type="button" class="button secondary" onclick="window.location.href="https://github.com/apache/isis/edit/master/adocs/documentation/src/main/asciidoc/guides/_rgant-ActionLayout.adoc"" style="float: right; font-size: small; padding: 6px; margin-top: -55px; "><i class="fa fa-pencil-square-o"></i> Edit</button>
<div class="sectionbody">
<div class="paragraph">
<p>The <code>@ActionLayout</code> annotation applies to actions, collecting together all UI hints within a single annotation.</p>
</div>
<div class="paragraph">
<p>The table below summarizes the annotation’s attributes.</p>
</div>
<table class="tableblock frame-all grid-all spread">
<caption class="title">
Table 9.
<code>@ActionLayout</code> attributes
</caption>
<colgroup>
<col style="width: 25%;">
<col style="width: 25%;">
<col style="width: 50%;">
</colgroup>
<thead>
<tr>
<th class="tableblock halign-left valign-top">Attribute</th>
<th class="tableblock halign-left valign-top">Values (default)</th>
<th class="tableblock halign-left valign-top">Description</th>
</tr>
</thead>
<tbody>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="#_rgant-ActionLayout_bookmarking"><code>bookmarking()</code></a></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>AS_ROOT</code>, <code>NEVER</code><br> (<code>NEVER</code>)</p></td>
<td class="tableblock halign-left valign-top">
<div>
<div class="paragraph">
<p>indicates if an action (with safe <a href="#_rgant-Action_semantics">action semantics</a>) is automatically bookmarked.</p>
</div>
</div></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="#_rgant-ActionLayout_contributedAs"><code>contributedAs()</code></a></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>AS_BOTH</code>, <code>AS_ACTION</code>, <code>AS_ASSOCIATION</code>, <code>AS_NEITHER</code><br> (<code>AS_BOTH</code>)</p></td>
<td class="tableblock halign-left valign-top">
<div>
<div class="paragraph">
<p>for a domain service action that can be contributed, whether to contribute as an action or as an association (ie a property or collection).<br></p>
</div>
<div class="paragraph">
<p>For a domain service action to be contributed, the domain services must have a <a href="#_rgant-DomainService_nature">nature</a> nature of either <code>VIEW</code> or <code>VIEW_CONTRIBUTIONS_ONLY</code>, and the action must have <a href="#_rgant-Action_semantics">safe action semantics</a>, and takes a single argument, namely the contributee domain object.</p>
</div>
</div></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="#_rgant-ActionLayout_cssClass"><code>cssClass()</code></a></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Any string valid as a CSS class</p></td>
<td class="tableblock halign-left valign-top">
<div>
<div class="paragraph">
<p>an additional CSS class around the HTML that represents for the action, to allow targetted styling in <a href="rgcfg.html#_rgcfg_application-specific_application-css"><code>application.css</code></a>.<br></p>
</div>
<div class="paragraph">
<p>Supported by the <a href="ugvw.html">Wicket viewer</a> but currently ignored by the <a href="ugvro.html">RestfulObjects viewer</a>.</p>
</div>
</div></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="#_rgant-ActionLayout_cssClassFa"><code>cssClassFa()</code></a></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Any valid <a href="http://fortawesome.github.io/Font-Awesome/">Font awesome</a> icon name</p></td>
<td class="tableblock halign-left valign-top">
<div>
<div class="paragraph">
<p>specify a font awesome icon for the action’s menu link or icon.<br></p>
</div>
</div></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>cssClassFaPosition()</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>LEFT</code>, <code>RIGHT</code><br> (<code>LEFT</code>)</p></td>
<td class="tableblock halign-left valign-top">
<div>
<div class="paragraph">
<p>Positioning of the icon on the button/menu item.</p>
</div>
</div></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="#_rgant-ActionLayout_describedAs"><code>describedAs()</code></a></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">String.</p></td>
<td class="tableblock halign-left valign-top">
<div>
<div class="paragraph">
<p>provides a short description of the action, eg for rendering as a 'tool tip'.</p>
</div>
</div></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="#_rgant-ActionLayout_hidden"><code>hidden()</code></a></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>EVERYWHERE</code>, <code>NOWHERE</code><br> (<code>NOWHERE</code>)</p></td>
<td class="tableblock halign-left valign-top">
<div>
<div class="paragraph">
<p>indicates where (in the UI) the action should be hidden from the user.</p>
</div>
</div></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="#_rgant-ActionLayout_named"><code>named()</code></a></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">String.</p></td>
<td class="tableblock halign-left valign-top">
<div>
<div class="paragraph">
<p>to override the name inferred from the action’s name in code.<br></p>
</div>
<div class="paragraph">
<p>A typical use case is if the desired name is a reserved Java keyword, such as <code>default</code> or <code>package</code>.</p>
</div>
</div></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="#_rgant-ActionLayout_position"><code>position()</code></a></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>BELOW</code>, <code>RIGHT</code>, <code>PANEL</code>, <code>PANEL_DROPDOWN</code> (<code>BELOW</code>)</p></td>
<td class="tableblock halign-left valign-top">
<div>
<div class="paragraph">
<p>for actions associated (using <a href="#_rgant-MemberOrder"><code>@MemberOrder#named()</code></a>) with properties, the positioning of the action’s button with respect to the property</p>
</div>
</div></td>
</tr>
</tbody>
</table>
<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">class</span> <span class="class">ToDoItems</span> {
<span class="annotation">@Action</span>(semantics=SemanticsOf.SAFE) <i class="conum" data-value="1"></i><b>(1)</b>
<span class="annotation">@ActionLayout</span>(
bookmarking=BookmarkPolicy.AS_ROOT,
cssClass=<span class="string"><span class="delimiter">"</span><span class="content">x-key</span><span class="delimiter">"</span></span>,
cssClassFa=<span class="string"><span class="delimiter">"</span><span class="content">fa-checkbox</span><span class="delimiter">"</span></span>,
describedAs=<span class="string"><span class="delimiter">"</span><span class="content">Mark the todo item as not complete after all</span><span class="delimiter">"</span></span>,
hidden=Where.NOWHERE <i class="conum" data-value="2"></i><b>(2)</b>
)
<span class="annotation">@MemberOrder</span>(sequence = <span class="string"><span class="delimiter">"</span><span class="content">1</span><span class="delimiter">"</span></span>)
<span class="directive">public</span> <span class="predefined-type">List</span><ToDoItem> notYetComplete() {
...
}
}</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 for bookmarkable actions</td>
</tr>
<tr>
<td><i class="conum" data-value="2"></i><b>2</b></td>
<td>default value, so could be omitted</td>
</tr>
</tbody>
</table>
</div>
<div class="paragraph">
<p>As an alternative to using the <code>@ActionLayout</code> annotation, a dynamic layout using <a href="ugfun.html#_ugfun_object-layout_dynamic"><code>.layout.json</code></a> file can be specified; for example:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code data-lang="javascript"><span class="string"><span class="delimiter">"</span><span class="content">notYetComplete</span><span class="delimiter">"</span></span>: {
<span class="key"><span class="delimiter">"</span><span class="content">actionLayout</span><span class="delimiter">"</span></span>: {
<span class="key"><span class="delimiter">"</span><span class="content">bookmarking</span><span class="delimiter">"</span></span>: <span class="string"><span class="delimiter">"</span><span class="content">AS_ROOT</span><span class="delimiter">"</span></span>,
<span class="key"><span class="delimiter">"</span><span class="content">cssClass</span><span class="delimiter">"</span></span>: <span class="string"><span class="delimiter">"</span><span class="content">x-key</span><span class="delimiter">"</span></span>,
<span class="key"><span class="delimiter">"</span><span class="content">cssClassFa</span><span class="delimiter">"</span></span>: <span class="string"><span class="delimiter">"</span><span class="content">fa-checkbox</span><span class="delimiter">"</span></span>,
<span class="key"><span class="delimiter">"</span><span class="content">describedAs</span><span class="delimiter">"</span></span>: <span class="string"><span class="delimiter">"</span><span class="content">Mark the todo item as not complete after all</span><span class="delimiter">"</span></span>,
<span class="key"><span class="delimiter">"</span><span class="content">hidden</span><span class="delimiter">"</span></span>: <span class="string"><span class="delimiter">"</span><span class="content">NOWHERE</span><span class="delimiter">"</span></span>
}
}</code></pre>
</div>
</div>
<div class="sect2">
<h3 id="_rgant-ActionLayout_bookmarking">4.1. <code>bookmarking()</code></h3>
<button type="button" class="button secondary" onclick="window.location.href="https://github.com/apache/isis/edit/master/adocs/documentation/src/main/asciidoc/guides/_rgant-ActionLayout_bookmarking.adoc"" style="float: right; font-size: small; padding: 6px; margin-top: -55px; "><i class="fa fa-pencil-square-o"></i> Edit</button>
<div class="paragraph">
<p>The <code>bookmarking()</code> attribute indicates if an action (with safe <a href="#_rgant-Action_semantics">action semantics</a>) is automatically bookmarked. This attribute is also supported for <a href="#_rgant-DomainObjectLayout_bookmarking">domain objects</a>.</p>
</div>
<div class="paragraph">
<p>In the <a href="ugvw.html">Wicket viewer</a>, a link to a bookmarked object is shown in the bookmarks panel:</p>
</div>
<div class="imageblock">
<div class="content">
<a class="image" href="images/reference-annotations/ActionLayout/bookmarking.png"><img src="images/reference-annotations/ActionLayout/bookmarking.png" alt="bookmarking" width="720px"></a>
</div>
</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 screenshot shows an earlier version of the <a href="ugvw.html">Wicket viewer</a> UI (specifically, pre 1.8.0).</p>
</div> </td>
</tr>
</tbody>
</table>
</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>The <a href="ugvw.html">Wicket viewer</a> supports <code>alt-[</code> as a shortcut for opening the bookmark panel. <code>Esc</code> will close.</p>
</div> </td>
</tr>
</tbody>
</table>
</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">class</span> <span class="class">ToDoItems</span> {
<span class="annotation">@Action</span>(semantics=SemanticsOf.SAFE)
<span class="annotation">@ActionLayout</span>(bookmarking=BookmarkPolicy.AS_ROOT)
<span class="annotation">@MemberOrder</span>(sequence = <span class="string"><span class="delimiter">"</span><span class="content">1</span><span class="delimiter">"</span></span>)
<span class="directive">public</span> <span class="predefined-type">List</span><ToDoItem> notYetComplete() {
...
}
}</code></pre>
</div>
</div>
<div class="paragraph">
<p>indicates that the <code>notYetComplete()</code> action is bookmarkable.</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>The enum value <code>AS_CHILD</code> has no meaning for actions; it relates only to bookmarked <a href="#_rgant-DomainObject_bookmarking">domain object</a>s.</p>
</div> </td>
</tr>
</tbody>
</table>
</div>
<div class="paragraph">
<p>As an alternative to using the annotation, the dynamic <a href="ugfun.html#_ugfun_object-layout_dynamic"><code>.layout.json</code></a> can be used instead, eg:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code data-lang="javascript"><span class="string"><span class="delimiter">"</span><span class="content">notYetComplete</span><span class="delimiter">"</span></span>: {
<span class="key"><span class="delimiter">"</span><span class="content">actionLayout</span><span class="delimiter">"</span></span>: { <span class="key"><span class="delimiter">"</span><span class="content">bookmarking</span><span class="delimiter">"</span></span>: <span class="string"><span class="delimiter">"</span><span class="content">AS_ROOT</span><span class="delimiter">"</span></span> }
}</code></pre>
</div>
</div>
</div>
<div class="sect2">
<h3 id="_rgant-ActionLayout_contributedAs">4.2. <code>contributedAs()</code></h3>
<button type="button" class="button secondary" onclick="window.location.href="https://github.com/apache/isis/edit/master/adocs/documentation/src/main/asciidoc/guides/_rgant-ActionLayout_contributedAs.adoc"" style="float: right; font-size: small; padding: 6px; margin-top: -55px; "><i class="fa fa-pencil-square-o"></i> Edit</button>
<div class="paragraph">
<p>For a domain service action that <em>can</em> be contributed, the <code>contributedAs()</code> attribute determines how it is contributed: as an action or as an association (ie a property or collection).</p>
</div>
<div class="paragraph">
<p>The distinction between property or collection is automatic: if the action returns a <code>java.util.Collection</code> (or subtype) then the action is contributed as a collection; otherwise it is contributed as a property.</p>
</div>
<div class="paragraph">
<p>For a domain service action to be contributed, the domain services must have a <a href="#_rgant-DomainService_nature">nature</a> nature of either <code>VIEW</code> or <code>VIEW_CONTRIBUTIONS_ONLY</code>, and the action must have <a href="#_rgant-Action_semantics">safe action semantics</a>, and takes a single argument, namely the contributee domain object.</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">@DomainService</span>(nature=NatureOfService.VIEW_CONTRIBUTIONS_ONLY)
<span class="directive">public</span> <span class="type">class</span> <span class="class">CustomerContributions</span> {
<span class="annotation">@Action</span>(semantics=SemanticsOf.SAFE)
<span class="annotation">@ActionLayout</span>(contributedAs=Contributed.AS_ASSOCIATION)
<span class="directive">public</span> <span class="predefined-type">List</span><Order> mostRecentOrders(Customer customer) { ... }
...
}</code></pre>
</div>
</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>The <code>@ActionLayout</code> is not required if the action does not have safe semantics, or if the action takes more than one argument; in these cases the action can only be contributed <em>as</em> an action.</p>
</div> </td>
</tr>
</tbody>
</table>
</div>
<div class="paragraph">
<p>It’s also possible to use the attribute to suppress the action completely:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code data-lang="java"><span class="annotation">@DomainService</span>(nature=NatureOfService.VIEW)
<span class="directive">public</span> <span class="type">class</span> <span class="class">OrderContributions</span> {
<span class="annotation">@ActionLayout</span>(contributedAs=Contributed.AS_NEITHER)
<span class="directive">public</span> <span class="type">void</span> cancel(Order order);
...
}</code></pre>
</div>
</div>
<div class="paragraph">
<p>In such cases, though, it would probably make more sense to annotate the action as either <a href="#_rgant-Action_hidden">hidden</a> or indeed <a href="#_rgant-Programmatic"><code>@Programmatic</code></a>.</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>Unlike other <code>@ActionLayout</code> attributes, this attribute <em>cannot</em> be specified dynamically in the <code>.layout.json</code> <a href="ugfun.html#_ugfun_object-layout_dynamic">dynamic layout file</a> because it relates to the contributor domain service, not the contributee domain object.</p>
</div> </td>
</tr>
</tbody>
</table>
</div>
</div>
<div class="sect2">
<h3 id="_rgant-ActionLayout_cssClass">4.3. <code>cssClass()</code></h3>
<button type="button" class="button secondary" onclick="window.location.href="https://github.com/apache/isis/edit/master/adocs/documentation/src/main/asciidoc/guides/_rgant-ActionLayout_cssClass.adoc"" style="float: right; font-size: small; padding: 6px; margin-top: -55px; "><i class="fa fa-pencil-square-o"></i> Edit</button>
<div class="paragraph">
<p>The <code>cssClass()</code> attribute can be used to render additional CSS classes in the HTML (a wrapping <code><div></code>) that represents the action. <a href="rgcfg.html#_rgcfg_application-specific_application-css">Application-specific CSS</a> can then be used to target and adjust the UI representation of that particular element.</p>
</div>
<div class="paragraph">
<p>This attribute can also be applied to <a href="#_rgant-DomainObjectLayout_cssClass">domain objects</a>, <a href="#_rgant-ViewModelLayout_cssClass">view models</a>, <a href="#_rgant-PropertyLayout_cssClass">properties</a>, <a href="#_rgant-CollectionLayout_cssClass">collections</a> and <a href="#_rgant-ParameterLayout_cssClass">parameters</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="directive">public</span> <span class="type">class</span> <span class="class">ToDoItem</span> {
<span class="annotation">@ActionLayout</span>(cssClass=<span class="string"><span class="delimiter">"</span><span class="content">x-key</span><span class="delimiter">"</span></span>)
<span class="directive">public</span> ToDoItem postpone(LocalDate until) { ... }
...
}</code></pre>
</div>
</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>The similar <a href="#_rgant-ActionLayout_cssClassFa"><code>@ActionLayout#cssClassFa()</code></a> annotation attribute is also used as a hint to apply CSS, specifically to add <a href="http://fortawesome.github.io/Font-Awesome/icons/">Font Awesome icons</a> on action menu items or buttons.</p>
</div> </td>
</tr>
</tbody>
</table>
</div>
<div class="paragraph">
<p>As an alternative to using the annotation, the dynamic <a href="ugfun.html#_ugfun_object-layout_dynamic"><code>.layout.json</code></a> can be used instead, eg:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code data-lang="javascript"><span class="string"><span class="delimiter">"</span><span class="content">postpone</span><span class="delimiter">"</span></span>: {
<span class="key"><span class="delimiter">"</span><span class="content">actionLayout</span><span class="delimiter">"</span></span>: { <span class="key"><span class="delimiter">"</span><span class="content">cssClass</span><span class="delimiter">"</span></span>: <span class="string"><span class="delimiter">"</span><span class="content">x-key</span><span class="delimiter">"</span></span> }
}</code></pre>
</div>
</div>
</div>
<div class="sect2">
<h3 id="_rgant-ActionLayout_cssClassFa">4.4. <code>cssClassFa()</code></h3>
<button type="button" class="button secondary" onclick="window.location.href="https://github.com/apache/isis/edit/master/adocs/documentation/src/main/asciidoc/guides/_rgant-ActionLayout_cssClassFa.adoc"" style="float: right; font-size: small; padding: 6px; margin-top: -55px; "><i class="fa fa-pencil-square-o"></i> Edit</button>
<div class="paragraph">
<p>The <code>cssClassFa()</code> attribute is used to specify the name of a <a href="http://fortawesome.github.io/Font-Awesome/icons/">Font Awesome icon</a> name, to be rendered on the action’s representation as a button or menu item. The related <code>cssClassFaPosition()</code> attribute specifies the positioning of the icon, to the left or the right of the text.</p>
</div>
<div class="paragraph">
<p>These attributes can also be applied to <a href="#_rgant-DomainObjectLayout_cssClassFa">domain objects</a> and to <a href="#_rgant-ViewModelLayout_cssClassFa">view models</a> to specify the object’s icon.</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">class</span> <span class="class">ToDoItem</span> {
<span class="annotation">@ActionLayout</span>(
cssClassFa=<span class="string"><span class="delimiter">"</span><span class="content">fa-step-backward</span><span class="delimiter">"</span></span>
)
<span class="directive">public</span> ToDoItem previous() { ... }
<span class="annotation">@ActionLayout</span>(
cssClassFa=<span class="string"><span class="delimiter">"</span><span class="content">fa-step-forward</span><span class="delimiter">"</span></span>,
cssClassFaPosition=ActionLayout.CssClassFaPosition.RIGHT
)
<span class="directive">public</span> ToDoItem next() { ... }
}</code></pre>
</div>
</div>
<div class="paragraph">
<p>There can be multiple "fa-" classes, eg to mirror or rotate the icon. There is no need to include the mandatory <code>fa</code> "marker" CSS class; it will be automatically added to the list. The <code>fa-</code> prefix can also be omitted from the class names; it will be prepended to each if required.</p>
</div>
<div class="paragraph">
<p>As an alternative to using the annotation, the dynamic <a href="ugfun.html#_ugfun_object-layout_dynamic"><code>.layout.json</code></a> can be used instead, eg:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code data-lang="javascript"><span class="string"><span class="delimiter">"</span><span class="content">previous</span><span class="delimiter">"</span></span>: {
<span class="key"><span class="delimiter">"</span><span class="content">actionLayout</span><span class="delimiter">"</span></span>: {
<span class="key"><span class="delimiter">"</span><span class="content">cssClassFa</span><span class="delimiter">"</span></span>: <span class="string"><span class="delimiter">"</span><span class="content">fa-step-backward</span><span class="delimiter">"</span></span>,
<span class="key"><span class="delimiter">"</span><span class="content">cssClassFaPosition</span><span class="delimiter">"</span></span>: <span class="string"><span class="delimiter">"</span><span class="content">LEFT</span><span class="delimiter">"</span></span>
}
},
<span class="key"><span class="delimiter">"</span><span class="content">next</span><span class="delimiter">"</span></span>: {
<span class="key"><span class="delimiter">"</span><span class="content">actionLayout</span><span class="delimiter">"</span></span>: {
<span class="key"><span class="delimiter">"</span><span class="content">cssClassFa</span><span class="delimiter">"</span></span>: <span class="string"><span class="delimiter">"</span><span class="content">fa-step-forward</span><span class="delimiter">"</span></span>,
<span class="key"><span class="delimiter">"</span><span class="content">cssClassFaPosition</span><span class="delimiter">"</span></span>: <span class="string"><span class="delimiter">"</span><span class="content">RIGHT</span><span class="delimiter">"</span></span>
}
}</code></pre>
</div>
</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>The similar <a href="#_rgant-ActionLayout_cssClass"><code>@ActionLayout#cssClass()</code></a> annotation attribute is also used as a hint to apply CSS, but for wrapping the representation of an object or object member so that it can be styled in an application-specific way.</p>
</div> </td>
</tr>
</tbody>
</table>
</div>
</div>
<div class="sect2">
<h3 id="_rgant-ActionLayout_describedAs">4.5. <code>describedAs()</code></h3>
<button type="button" class="button secondary" onclick="window.location.href="https://github.com/apache/isis/edit/master/adocs/documentation/src/main/asciidoc/guides/_rgant-ActionLayout_describedAs.adoc"" style="float: right; font-size: small; padding: 6px; margin-top: -55px; "><i class="fa fa-pencil-square-o"></i> Edit</button>
<div class="paragraph">
<p>The <code>describedAs()</code> attribute is used to provide a short description of the action to the user. In the <a href="ugvw.html">Wicket viewer</a> it is displayed as a 'tool tip'.</p>
</div>
<div class="paragraph">
<p>This attribute can also be specified for <a href="#_rgant-CollectionLayout_describedAs">collections</a>, <a href="#_rgant-PropertyLayout_describedAs">properties</a>, <a href="#_rgant-ParameterLayout_describedAs">parameters</a>, <a href="#_rgant-DomainObjectLayout_describedAs">domain objects</a> and <a href="#_rgant-ViewModelLayout_describedAs">view models</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="directive">public</span> <span class="type">class</span> <span class="class">Customer</span> {
<span class="annotation">@ActionLayout</span>(describedAs=<span class="string"><span class="delimiter">"</span><span class="content">Place a repeat order of the last (most recently placed) order</span><span class="delimiter">"</span></span>)
<span class="directive">public</span> Order placeRepeatOrder(...) { ... }
}</code></pre>
</div>
</div>
<div class="paragraph">
<p>As an alternative to using the annotation, the dynamic <a href="ugfun.html#_ugfun_object-layout_dynamic"><code>.layout.json</code></a> can be used instead, eg:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code data-lang="javascript"><span class="string"><span class="delimiter">"</span><span class="content">postpone</span><span class="delimiter">"</span></span>: {
<span class="key"><span class="delimiter">"</span><span class="content">actionLayout</span><span class="delimiter">"</span></span>: { <span class="key"><span class="delimiter">"</span><span class="content">describedAs</span><span class="delimiter">"</span></span>: <span class="string"><span class="delimiter">"</span><span class="content">Place a repeat order of the last (most recently placed) order</span><span class="delimiter">"</span></span> }
}</code></pre>
</div>
</div>
</div>
<div class="sect2">
<h3 id="_rgant-ActionLayout_hidden">4.6. <code>hidden()</code></h3>
<button type="button" class="button secondary" onclick="window.location.href="https://github.com/apache/isis/edit/master/adocs/documentation/src/main/asciidoc/guides/_rgant-ActionLayout_hidden.adoc"" style="float: right; font-size: small; padding: 6px; margin-top: -55px; "><i class="fa fa-pencil-square-o"></i> Edit</button>
<div class="paragraph">
<p>The <code>hidden()</code> attribute indicates where (in the UI) the action should be hidden from the user. This attribute can also be applied to <a href="#_rgant-PropertyLayout_hidden">properties</a> and <a href="#_rgant-CollectionLayout_hidden">collections</a>.</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>It is also possible to use <a href="#_rgant-Action_hidden"><code>@Action#hidden()</code></a> to hide an action at the domain layer. Both options are provided with a view that in the future the view-layer semantics may be under the control of (expert) users, whereas domain-layer semantics should never be overridden or modified by the user.</p>
</div> </td>
</tr>
</tbody>
</table>
</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">class</span> <span class="class">Customer</span> {
<span class="annotation">@ActionLayout</span>(hidden=Where.EVERYWHERE)
<span class="directive">public</span> <span class="type">void</span> updateStatus() { ... }
...
}</code></pre>
</div>
</div>
<div class="paragraph">
<p>The acceptable values for the <code>where</code> parameter are:</p>
</div>
<div class="ulist">
<ul>
<li> <p><code>Where.EVERYWHERE</code> or <code>Where.ANYWHERE</code><br></p>
<div class="paragraph">
<p>The action should be hidden at all times.</p>
</div> </li>
<li> <p><code>Where.NOWHERE</code><br></p>
<div class="paragraph">
<p>The action should not be hidden.</p>
</div> </li>
</ul>
</div>
<div class="paragraph">
<p>The other values of the <code>Where</code> enum have no meaning for a collection.</p>
</div>
<div class="paragraph">
<p>As an alternative to using the annotation, the dynamic <a href="ugfun.html#_ugfun_object-layout_dynamic"><code>.layout.json</code></a> can be used instead, eg:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code data-lang="javascript"><span class="string"><span class="delimiter">"</span><span class="content">updateStatus</span><span class="delimiter">"</span></span>: {
<span class="key"><span class="delimiter">"</span><span class="content">actionLayout</span><span class="delimiter">"</span></span>: { <span class="key"><span class="delimiter">"</span><span class="content">hidden</span><span class="delimiter">"</span></span>: <span class="string"><span class="delimiter">"</span><span class="content">EVERYWHERE</span><span class="delimiter">"</span></span> }
}</code></pre>
</div>
</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>For actions of domain services the visibility is dependent upon its <a href="#_rgant-DomainService_nature"><code>@DomainService#nature()</code></a> and also on whether it is contributed (as per <a href="#_rgant-ActionLayout_contributedAs"><code>@ActionLayout#contributedAs()</code></a>).</p>
</div> </td>
</tr>
</tbody>
</table>
</div>
</div>
<div class="sect2">
<h3 id="_rgant-ActionLayout_named">4.7. <code>named()</code></h3>
<button type="button" class="button secondary" onclick="window.location.href="https://github.com/apache/isis/edit/master/adocs/documentation/src/main/asciidoc/guides/_rgant-ActionLayout_named.adoc"" style="float: right; font-size: small; padding: 6px; margin-top: -55px; "><i class="fa fa-pencil-square-o"></i> Edit</button>
<div class="paragraph">
<p>The <code>named()</code> attribute explicitly specifies the action’s name, overriding the name that would normally be inferred from the Java source code. This attribute can also be specified for <a href="#_rgant-CollectionLayout_named">collections</a>, <a href="#_rgant-PropertyLayout_named">properties</a>, <a href="#_rgant-ParameterLayout_named">parameters</a>, <a href="#_rgant-DomainObjectLayout_named">domain objects</a>, <a href="#_rgant-ViewModelLayout_named">view models</a> and <a href="#_rgant-DomainServiceLayout_named">domain services</a>.</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>Following the <a href="http://en.wikipedia.org/wiki/Don%27t_repeat_yourself">don’t repeat yourself</a> principle, we recommend that you only use this attribute when the desired name cannot be used in Java source code. Examples of that include a name that would be a reserved Java keyword (eg "package"), or a name that has punctuation, eg apostrophes.</p>
</div> </td>
</tr>
</tbody>
</table>
</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">class</span> <span class="class">Customer</span> {
<span class="annotation">@ActionLayout</span>(named=<span class="string"><span class="delimiter">"</span><span class="content">Get credit rating</span><span class="delimiter">"</span></span>)
<span class="directive">public</span> CreditRating obtainCreditRating() { ... }
}</code></pre>
</div>
</div>
<div class="paragraph">
<p>As an alternative to using the annotation, the dynamic <a href="ugfun.html#_ugfun_object-layout_dynamic"><code>.layout.json</code></a> can be used instead, eg:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code data-lang="javascript"><span class="string"><span class="delimiter">"</span><span class="content">obtainCreditRating</span><span class="delimiter">"</span></span>: {
<span class="key"><span class="delimiter">"</span><span class="content">actionLayout</span><span class="delimiter">"</span></span>: { <span class="key"><span class="delimiter">"</span><span class="content">named</span><span class="delimiter">"</span></span>: <span class="string"><span class="delimiter">"</span><span class="content">Get credit rating</span><span class="delimiter">"</span></span> }
}</code></pre>
</div>
</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>The framework also provides a separate, powerful mechanism for <a href="ugbtb.html#_ugbtb_i18n">internationalization</a>.</p>
</div> </td>
</tr>
</tbody>
</table>
</div>
</div>
<div class="sect2">
<h3 id="_rgant-ActionLayout_position">4.8. <code>position()</code></h3>
<button type="button" class="button secondary" onclick="window.location.href="https://github.com/apache/isis/edit/master/adocs/documentation/src/main/asciidoc/guides/_rgant-ActionLayout_position.adoc"" style="float: right; font-size: small; padding: 6px; margin-top: -55px; "><i class="fa fa-pencil-square-o"></i> Edit</button>
<div class="paragraph">
<p>The <code>position()</code> attribute pertains only to actions that have been associated with properties using <a href="#_rgant-MemberOrder"><code>@MemberOrder#named()</code></a>. For these actions, it specifies the positioning of the action’s button with respect to the field representing the object property.</p>
</div>
<div class="paragraph">
<p>The attribute can take one of four values: <code>BELOW</code>, <code>RIGHT</code>, <code>PANEL</code> or <code>PANEL_DROPDOWN</code>.</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">class</span> <span class="class">Customer</span> {
<span class="annotation">@Property</span>(
editing=Editing.DISABLED <i class="conum" data-value="1"></i><b>(1)</b>
)
<span class="directive">public</span> CustomerStatus getStatus() { ... }
<span class="directive">public</span> <span class="type">void</span> setStatus(CustomerStatus customerStatus) { ... }
<span class="annotation">@MemberOrder</span>(
named=<span class="string"><span class="delimiter">"</span><span class="content">status</span><span class="delimiter">"</span></span>, <i class="conum" data-value="2"></i><b>(2)</b>
sequence=<span class="string"><span class="delimiter">"</span><span class="content">1</span><span class="delimiter">"</span></span>
)
<span class="annotation">@ActionLayout</span>(
named=<span class="string"><span class="delimiter">"</span><span class="content">Update</span><span class="delimiter">"</span></span>, <i class="conum" data-value="3"></i><b>(3)</b>
position=<span class="predefined-type">Position</span>.BELOW
)
<span class="directive">public</span> CreditRating updateStatus(Customer ) { ... }
}</code></pre>
</div>
</div>
<div class="colist arabic">
<table>
<tbody>
<tr>
<td><i class="conum" data-value="1"></i><b>1</b></td>
<td>indicate the property as read-only, such that it can only be updated using an action</td>
</tr>
<tr>
<td><i class="conum" data-value="2"></i><b>2</b></td>
<td>associate the "updateStatus" action with the "status" property</td>
</tr>
<tr>
<td><i class="conum" data-value="3"></i><b>3</b></td>
<td>give the action an abbreviated name, because the fact that the "status" property is to be updated is implied by its positioning</td>
</tr>
</tbody>
</table>
</div>
<div class="paragraph">
<p>The default is <code>BELOW</code>, which is rendered (by the <a href="ugvw.html">Wicket viewer</a>) as shown below:</p>
</div>
<div class="imageblock">
<div class="content">
<a class="image" href="images/reference-annotations/ActionLayout/position-BELOW.png"><img src="images/reference-annotations/ActionLayout/position-BELOW.png" alt="position BELOW" width="720px"></a>
</div>
</div>
<div class="paragraph">
<p>If the action is positioned as <code>RIGHT</code>, then the action’s button is rendered to the right of the property’s field, in a compact drop-down. This is ideal if there are many actions associated with a property:</p>
</div>
<div class="imageblock">
<div class="content">
<a class="image" href="images/reference-annotations/ActionLayout/position-RIGHT.png"><img src="images/reference-annotations/ActionLayout/position-RIGHT.png" alt="position RIGHT" width="720px"></a>
</div>
</div>
<div class="paragraph">
<p>If the action is positioned as <code>PANEL</code>, then the action’s button is rendered on the header of the panel that contains the property:</p>
</div>
<div class="imageblock">
<div class="content">
<a class="image" href="images/reference-annotations/ActionLayout/position-PANEL.png"><img src="images/reference-annotations/ActionLayout/position-PANEL.png" alt="position PANEL" width="720px"></a>
</div>
</div>
<div class="paragraph">
<p>And finally, if the action is positioned as <code>PANEL_DROPDOWN</code>, then the action’s button is again rendered on the panel header, but as a drop-down:</p>
</div>
<div class="imageblock">
<div class="content">
<a class="image" href="images/reference-annotations/ActionLayout/position-PANEL_DROPDOWN.png"><img src="images/reference-annotations/ActionLayout/position-PANEL_DROPDOWN.png" alt="position PANEL DROPDOWN" width="720px"></a>
</div>
</div>
<div class="paragraph">
<p>If there are multiple actions associated with a single property then the positioning can be mix’ed-and-match’ed as required. If the <code>PANEL</code> or <code>PANEL_DROPDOWN</code> are used, then (as the screenshots above show) the actions from potentially multiple properties grouped by that panel will be shown together.</p>
</div>
<div class="paragraph">
<p>As an alternative to using the annotation, the dynamic <a href="ugfun.html#_ugfun_object-layout_dynamic"><code>.layout.json</code></a> can be used instead, eg:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code data-lang="javascript"><span class="string"><span class="delimiter">"</span><span class="content">obtainCreditRating</span><span class="delimiter">"</span></span>: {
<span class="key"><span class="delimiter">"</span><span class="content">actionLayout</span><span class="delimiter">"</span></span>: { <span class="key"><span class="delimiter">"</span><span class="content">named</span><span class="delimiter">"</span></span>: <span class="string"><span class="delimiter">"</span><span class="content">Get credit rating</span><span class="delimiter">"</span></span> }
}</code></pre>
</div>
</div>
<div class="paragraph">
<p>The fact that the layout is dynamic (does not require a rebuild/restart) is particularly useful in that the look-n-feel can be easily experimented with and adjusted.</p>
</div>
</div>
</div>
</div>
<div class="sect1">
<h2 id="_rgant-Collection">5. <code>@Collection</code></h2>
<button type="button" class="button secondary" onclick="window.location.href="https://github.com/apache/isis/edit/master/adocs/documentation/src/main/asciidoc/guides/_rgant-Collection.adoc"" style="float: right; font-size: small; padding: 6px; margin-top: -55px; "><i class="fa fa-pencil-square-o"></i> Edit</button>
<div class="sectionbody">
<div class="paragraph">
<p>The <code>@Collection</code> annotation applies to collections collecting together all domain semantics within a single annotation.</p>
</div>
<div class="paragraph">
<p>The table below summarizes the annotation’s attributes.</p>
</div>
<table class="tableblock frame-all grid-all spread">
<caption class="title">
Table 10.
<code>@Collection</code> attributes
</caption>
<colgroup>
<col style="width: 25%;">
<col style="width: 25%;">
<col style="width: 50%;">
</colgroup>
<thead>
<tr>
<th class="tableblock halign-left valign-top">Attribute</th>
<th class="tableblock halign-left valign-top">Values (default)</th>
<th class="tableblock halign-left valign-top">Description</th>
</tr>
</thead>
<tbody>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="#_rgant-Collection_domainEvent"><code>domainEvent()</code></a></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">subtype of <code>CollectionDomainEvent</code><br> (<code>CollectionDomainEvent.Default</code>)</p></td>
<td class="tableblock halign-left valign-top">
<div>
<div class="paragraph">
<p>the event type to be posted to the <a href="rgsvc.html#_rgsvc_api_EventBusService"><code>EventBusService</code></a> to broadcast the collection’s business rule checking (hide, disable, validate) and its modification (before and after).</p>
</div>
</div></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="#_rgant-Collection_editing"><code>editing()</code></a></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>ENABLED</code>, <code>DISABLED</code>, <code>AS_CONFIGURED</code><br> (<code>AS_CONFIGURED</code>)</p></td>
<td class="tableblock halign-left valign-top">
<div>
<div class="paragraph">
<p>whether a collection can be added to or removed from within the UI</p>
</div>
</div></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>editingDisabledReason()</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">String value</p></td>
<td class="tableblock halign-left valign-top">
<div>
<div class="paragraph">
<p>if <code>editing()</code> is <code>DISABLED</code>, provides a reason as to why.</p>
</div>
</div></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="#_rgant-Collection_hidden"><code>hidden()</code></a></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>EVERYWHERE</code>, <code>OBJECT_FORMS</code>, <code>NOWHERE</code><br> (<code>NOWHERE</code>)</p></td>
<td class="tableblock halign-left valign-top">
<div>
<div class="paragraph">
<p>indicates where (in the UI) the collection should be hidden from the user.</p>
</div>
</div></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="#_rgant-Collection_notPersisted"><code>notPersisted()</code></a></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>true</code>, <code>false</code><br> (<code>false</code>)</p></td>
<td class="tableblock halign-left valign-top">
<div>
<div class="paragraph">
<p>whether to exclude from snapshots.<br></p>
</div>
<div class="admonitionblock warning">
<table>
<tbody>
<tr>
<td class="icon"> <i class="fa icon-warning" title="Warning"></i> </td>
<td class="content">
<div class="paragraph">
<p>Collection must also be annotated with <code>@javax.jdo.annotations.NotPersistent</code> in order to not be persisted.</p>
</div> </td>
</tr>
</tbody>
</table>
</div>
</div></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="#_rgant-Collection_typeOf"><code>typeOf()</code></a></p></td>
<td class="tableblock halign-left valign-top"></td>
<td class="tableblock halign-left valign-top">
<div>
<div class="paragraph">
<p>hints as to the run-time type of the objects within that collection (as a fallback)</p>
</div>
</div></td>
</tr>
</tbody>
</table>
<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">class</span> <span class="class">ToDoItem</span> {
<span class="directive">public</span> <span class="directive">static</span> <span class="type">class</span> <span class="class">DependenciesChangedEvent</span>
<span class="directive">extends</span> CollectionDomainEvent<ToDoItem, ToDoItem> { } <i class="conum" data-value="1"></i><b>(1)</b>
<span class="annotation">@Collection</span>(
domainEvent=DependenciesChangedEvent.class,
editing = Editing.ENABLED,
hidden = Where.NOWHERE, <i class="conum" data-value="2"></i><b>(2)</b>
notPersisted = <span class="predefined-constant">false</span>, <i class="conum" data-value="3"></i><b>(3)</b>
typeOf = ToDoItem.class <i class="conum" data-value="4"></i><b>(4)</b>
)
<span class="directive">public</span> <span class="predefined-type">SortedSet</span><ToDoItem> getDependencies() { ... }
...
}</code></pre>
</div>
</div>
<div class="colist arabic">
<table>
<tbody>
<tr>
<td><i class="conum" data-value="1"></i><b>1</b></td>
<td>as of <code>1.10.0</code>, can use no-arg constructor.</td>
</tr>
<tr>
<td><i class="conum" data-value="2"></i><b>2</b></td>
<td>default value, so could be omitted</td>
</tr>
<tr>
<td><i class="conum" data-value="3"></i><b>3</b></td>
<td>default value, so could be omitted</td>
</tr>
<tr>
<td><i class="conum" data-value="4"></i><b>4</b></td>
<td>default value, so could be omitted</td>
</tr>
</tbody>
</table>
</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>The annotation is one of a handful (others including <a href="#_rgant-CollectionLayout"><code>@CollectionLayout</code></a>, <a href="#_rgant-Property"><code>@Property</code></a> and <a href="#_rgant-PropertyLayout"><code>@PropertyLayout</code></a>) that can also be applied to the field, rather than the getter method. This is specifically so that boilerplate-busting tools such as <a href="https://projectlombok.org/">Project Lombok</a> can be used.</p>
</div> </td>
</tr>
</tbody>
</table>
</div>
<div class="sect2">
<h3 id="_rgant-Collection_domainEvent">5.1. <code>domainEvent()</code></h3>
<button type="button" class="button secondary" onclick="window.location.href="https://github.com/apache/isis/edit/master/adocs/documentation/src/main/asciidoc/guides/_rgant-Collection_domainEvent.adoc"" style="float: right; font-size: small; padding: 6px; margin-top: -55px; "><i class="fa fa-pencil-square-o"></i> Edit</button>
<div class="paragraph">
<p>Whenever a domain object (or list of domain objects) is to be rendered, the framework fires off multiple domain events for every property, collection and action of the domain object. In the cases of the domain object’s collections, the events that are fired are:</p>
</div>
<div class="ulist">
<ul>
<li> <p>hide phase: to check that the collection is visible (has not been hidden)</p> </li>
<li> <p>disable phase: to check that the collection is usable (has not been disabled)</p> </li>
<li> <p>validate phase: to check that the collection’s arguments are valid (to add or remove an element)</p> </li>
<li> <p>pre-execute phase: before the modification of the collection</p> </li>
<li> <p>post-execute: after the modification of the collection</p> </li>
</ul>
</div>
<div class="paragraph">
<p>Subscribers subscribe through the <a href="rgsvc.html#_rgsvc_api_EventBusService"><code>EventBusService</code></a> using either <a href="https://github.com/google/guava">Guava</a> or <a href="http://www.axonframework.org/">Axon Framework</a> annotations and can influence each of these phases.</p>
</div>
<div class="admonitionblock warning">
<table>
<tbody>
<tr>
<td class="icon"> <i class="fa icon-warning" title="Warning"></i> </td>
<td class="content">
<div class="paragraph">
<p>The <a href="ugvw.html">Wicket viewer</a> does <em>not</em> currently support the modification of collections; they are rendered read-only. However, domain events are still relevant to determine if such collections should be hidden.</p>
</div>
<div class="paragraph">
<p>The workaround is to create add/remove actions and use <a href="#_rgant-MemberOrder">UI hints</a> to render them close to the collection.</p>
</div> </td>
</tr>
</tbody>
</table>
</div>
<div class="paragraph">
<p>By default the event raised is <code>CollectionDomainEvent.Default</code>. 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">class</span> <span class="class">ToDoItem</span> {
<span class="annotation">@Collection</span>()
<span class="directive">public</span> <span class="predefined-type">SortedSet</span><ToDoItem> getDependencies() { ... }
...
}</code></pre>
</div>
</div>
<div class="paragraph">
<p>The <code>domainEvent()</code> attribute allows a custom subclass to be emitted allowing more precise subscriptions (to those subclasses) to be defined instead. This attribute is also supported for <a href="#_rgant-Action_domainEvent">actions</a> and <a href="#_rgant-Property_domainEvent">properties</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="directive">public</span> <span class="type">class</span> <span class="class">ToDoItem</span> {
<span class="directive">public</span> <span class="directive">static</span> <span class="type">class</span> <span class="class">DependenciesChangedEvent</span>
<span class="directive">extends</span> CollectionDomainEvent<ToDoItem, ToDoItem> { } <i class="conum" data-value="1"></i><b>(1)</b>
<span class="annotation">@Collection</span>(
domainEvent=DependenciesChangedEvent.class
)
<span class="directive">public</span> <span class="predefined-type">SortedSet</span><ToDoItem> getDependencies() { ... }
...
}</code></pre>
</div>
</div>
<div class="colist arabic">
<table>
<tbody>
<tr>
<td><i class="conum" data-value="1"></i><b>1</b></td>
<td>inherit from <code>CollectionDomainEvent<T,E></code> where <code>T</code> is the type of the domain object being interacted with, and <code>E</code> is the type of the element in the collection (both <code>ToDoItem</code> in this example)</td>
</tr>
</tbody>
</table>
</div>
<div class="paragraph">
<p>The benefit is that subscribers can be more targetted as to the events that they subscribe to.</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>As of <code>1.10.0</code> the framework provides no-arg constructor and will initialize the domain event using (non-API) setters rather than through the constructor. This substantially reduces the boilerplate.</p>
</div> </td>
</tr>
</tbody>
</table>
</div>
<div class="sect3">
<h4 id="_subscribers_2">5.1.1. Subscribers</h4>
<div class="paragraph">
<p>Subscribers (which must be domain services) subscribe using either the <a href="https://github.com/google/guava">Guava</a> API or (if the <a href="rgsvc.html#_rgsvc_api_EventBusService"><code>EventBusService</code></a> has been appropriately configured) using the <a href="http://www.axonframework.org/">Axon Framework</a> API. The examples below use the Guava API.</p>
</div>
<div class="paragraph">
<p>Subscribers can be either coarse-grained (if they subscribe to the top-level event type):</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code data-lang="java"><span class="annotation">@DomainService</span>(nature=NatureOfService.DOMAIN)
<span class="directive">public</span> <span class="type">class</span> <span class="class">SomeSubscriber</span> <span class="directive">extends</span> AbstractSubscriber {
<span class="annotation">@com</span>.google.common.eventbus.Subscribe
<span class="directive">public</span> <span class="type">void</span> on(CollectionDomainEvent ev) {
...
}
}</code></pre>
</div>
</div>
<div class="paragraph">
<p>or can be fine-grained (by subscribing to specific event subtypes):</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code data-lang="java"><span class="annotation">@DomainService</span>(nature=NatureOfService.DOMAIN)
<span class="directive">public</span> <span class="type">class</span> <span class="class">SomeSubscriber</span> <span class="directive">extends</span> AbstractSubscriber {
<span class="annotation">@com</span>.google.common.eventbus.Subscribe
<span class="directive">public</span> <span class="type">void</span> on(ToDoItem.DependenciesChangedEvent ev) {
...
}
}</code></pre>
</div>
</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>If the AxonFramework is being used, replace <code>@com.google.common.eventbus.Subscribe</code> with <code>@org.axonframework.eventhandling.annotation.EventHandler</code>.</p>
</div> </td>
</tr>
</tbody>
</table>
</div>
<div class="paragraph">
<p>The subscriber’s method is called (up to) 5 times:</p>
</div>
<div class="ulist">
<ul>
<li> <p>whether to veto visibility (hide)</p> </li>
<li> <p>whether to veto usability (disable)</p> </li>
<li> <p>whether to veto execution (validate) the element being added to/removed from the collection</p> </li>
<li> <p>steps to perform prior to the collection being added to/removed from</p> </li>
<li> <p>steps to perform after the collection has been added to/removed from.</p> </li>
</ul>
</div>
<div class="paragraph">
<p>The subscriber can distinguish these by calling <code>ev.getEventPhase()</code>. Thus the general form is:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code data-lang="java"><span class="annotation">@Programmatic</span>
<span class="annotation">@com</span>.google.common.eventbus.Subscribe
<span class="directive">public</span> <span class="type">void</span> on(CollectionDomainEvent ev) {
<span class="keyword">switch</span>(ev.getEventPhase()) {
<span class="keyword">case</span> HIDE:
<span class="comment">// call ev.hide() or ev.veto("") to hide the collection</span>
<span class="keyword">break</span>;
<span class="keyword">case</span> DISABLE:
<span class="comment">// call ev.disable("...") or ev.veto("...") to disable the collection</span>
<span class="keyword">break</span>;
<span class="keyword">case</span> VALIDATE:
<span class="comment">// call ev.invalidate("...") or ev.veto("...")</span>
<span class="comment">// if object being added/removed to collection is invalid</span>
<span class="keyword">break</span>;
<span class="keyword">case</span> EXECUTING:
<span class="keyword">break</span>;
<span class="keyword">case</span> EXECUTED:
<span class="keyword">break</span>;
}
}</code></pre>
</div>
</div>
<div class="paragraph">
<p>It is also possible to abort the transaction during the executing or executed phases by throwing an exception. If the exception is a subtype of <code>RecoverableException</code> then the exception will be rendered as a user-friendly warning (eg Growl/toast) rather than an error.</p>
</div>
</div>
<div class="sect3">
<h4 id="_default_doop_and_noop_events_2">5.1.2. Default, Doop and Noop events</h4>
<div class="paragraph">
<p>If the <code>domainEvent</code> attribute is not explicitly specified (is left as its default value, <code>CollectionDomainEvent.Default</code>), then the framework will, by default, post an event.</p>
</div>
<div class="paragraph">
<p>If this is not required, then the <code>isis.reflector.facet.collectionAnnotation.domainEvent.postForDefault</code> configuration collection can be set to "false"; this will disable posting.</p>
</div>
<div class="paragraph">
<p>On the other hand, if the <code>domainEvent</code> has been explicitly specified to some subclass, then an event will be posted. The framework provides <code>CollectionDomainEvent.Doop</code> as such a subclass, so setting the <code>domainEvent</code> attribute to this class will ensure that the event to be posted, irrespective of the configuration collection setting.</p>
</div>
<div class="paragraph">
<p>And, conversely, the framework also provides <code>CollectionDomainEvent.Noop</code>; if <code>domainEvent</code> attribute is set to this class, then no event will be posted.</p>
</div>
</div>
<div class="sect3">
<h4 id="_raising_events_programmatically_2">5.1.3. Raising events programmatically</h4>
<div class="paragraph">
<p>Normally events are only raised for interactions through the UI. However, events can be raised programmatically either by calling the <a href="rgsvc.html#_rgsvc_api_EventBusService"><code>EventBusService</code></a> API directly, or by emulating the UI by wrapping the target object using the <a href="rgsvc.html#_rgsvc_api_WrapperFactory"><code>WrapperFactory</code></a> domain service.</p>
</div>
</div>
</div>
<div class="sect2">
<h3 id="_rgant-Collection_editing">5.2. <code>editing()</code></h3>
<button type="button" class="button secondary" onclick="window.location.href="https://github.com/apache/isis/edit/master/adocs/documentation/src/main/asciidoc/guides/_rgant-Collection_editing.adoc"" style="float: right; font-size: small; padding: 6px; margin-top: -55px; "><i class="fa fa-pencil-square-o"></i> Edit</button>
<div class="paragraph">
<p>The <code>editing()</code> annotation indicates whether a collection can be added to or removed from within the UI. This attribute can also be specified for <a href="#_rgant-Property_editing">properties</a>, and can also be specified for the <a href="#_rgant-DomainObject_editing">domain object</a></p>
</div>
<div class="paragraph">
<p>The related <code>editingDisabledReason()</code> attribute specifies the a hard-coded reason why the collection cannot be modified directly.</p>
</div>
<div class="admonitionblock warning">
<table>
<tbody>
<tr>
<td class="icon"> <i class="fa icon-warning" title="Warning"></i> </td>
<td class="content">
<div class="paragraph">
<p>The <a href="ugvw.html">Wicket viewer</a> does <strong>not</strong> currently support the modification of collections; they are rendered read-only.</p>
</div>
<div class="paragraph">
<p>The workaround is to create add/remove actions and use <a href="#_rgant-MemberOrder">UI hints</a> to render them close to the collection.</p>
</div> </td>
</tr>
</tbody>
</table>
</div>
<div class="paragraph">
<p>Whether a collection is enabled or disabled depends upon these factors:</p>
</div>
<div class="ulist">
<ul>
<li> <p>whether the domain object has been configured as immutable through the <a href="#_rgant-DomainObject_editing"><code>@DomainObject#editing()</code></a> attribute</p> </li>
<li> <p>else (that is, if the domain object’s editability is specified as being <code>AS_CONFIGURED</code>), then the value of the <a href="rgcfg.html#_rgcfg_configuring-core">configuration property</a> <code>isis.objects.editing</code>. If set to <code>false</code>, then the object’s collections (and properties) are <strong>not</strong> editable</p> </li>
<li> <p>else, then the value of the <code>@Collection(editing=…)</code> attribute itself.</p> </li>
<li> <p>else, the result of invoking any supporting <a href="rgcms.html#_rgcms_methods_prefixes_disable"><code>disable…()</code></a> supporting methods</p> </li>
</ul>
</div>
<div class="paragraph">
<p>Thus, to make a collection read-only even if the object would otherwise be editable, use:</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">ToDoItem</span> {
<span class="annotation">@Collection</span>(
editing=Editing.DISABLED,
editingDisabledReason=<span class="string"><span class="delimiter">"</span><span class="content">Use the add and remove actions to modify</span><span class="delimiter">"</span></span>
)
<span class="directive">public</span> <span class="predefined-type">SortedSet</span><ToDoItem> getDependencies() { ... }
}</code></pre>
</div>
</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>To reiterate, it is <em>not</em> possible to enable editing for a collection if editing has been disabled at the object-level.</p>
</div> </td>
</tr>
</tbody>
</table>
</div>
</div>
<div class="sect2">
<h3 id="_rgant-Collection_hidden">5.3. <code>hidden()</code></h3>
<button type="button" class="button secondary" onclick="window.location.href="https://github.com/apache/isis/edit/master/adocs/documentation/src/main/asciidoc/guides/_rgant-Collection_hidden.adoc"" style="float: right; font-size: small; padding: 6px; margin-top: -55px; "><i class="fa fa-pencil-square-o"></i> Edit</button>
<div class="paragraph">
<p>Collections can be hidden at the domain-level, indicating that they are not visible to the end-user. This attribute can also be applied to <a href="#_rgant-Action_hidden">actions</a> and <a href="#_rgant-Property_hidden">properties</a>.</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>It is also possible to use <a href="#_rgant-CollectionLayout_hidden"><code>@CollectionLayout#hidden()</code></a> or <a href="ugfun.html#_ugfun_object-layout_dynamic">dynamic layouts</a> such that the collection can be hidden at the view layer. Both options are provided with a view that in the future the view-layer semantics may be under the control of (expert) users, whereas domain-layer semantics should never be overridden or modified by the user.</p>
</div> </td>
</tr>
</tbody>
</table>
</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">class</span> <span class="class">Customer</span> {
<span class="annotation">@Collection</span>(where=Where.EVERYWHERE)
<span class="directive">public</span> <span class="predefined-type">SortedSet</span><Address> getAddresses() { ... }
}</code></pre>
</div>
</div>
<div class="paragraph">
<p>The acceptable values for the <code>where</code> parameter are:</p>
</div>
<div class="ulist">
<ul>
<li> <p><code>Where.EVERYWHERE</code> or <code>Where.ANYWHERE</code><br></p>
<div class="paragraph">
<p>The collection should be hidden everywhere.</p>
</div> </li>
<li> <p><code>Where.ANYWHERE</code><br></p>
<div class="paragraph">
<p>Synonym for everywhere.</p>
</div> </li>
<li> <p><code>Where.OBJECT_FORMS</code><br></p>
<div class="paragraph">
<p>The collection should be hidden when displayed within an object form.</p>
</div> </li>
<li> <p><code>Where.NOWHERE</code><br></p>
<div class="paragraph">
<p>The collection should not be hidden.</p>
</div> </li>
</ul>
</div>
<div class="paragraph">
<p>The other values of the <code>Where</code> enum have no meaning for a collection.</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>The <a href="ugvw.html">Wicket viewer</a> suppresses collections when displaying lists of objects.</p>
</div>
<div class="paragraph">
<p>The <a href="ugvro.html">RestfulObjects viewer</a> by default suppress collections when rendering a domain object.</p>
</div> </td>
</tr>
</tbody>
</table>
</div>
</div>
<div class="sect2">
<h3 id="_rgant-Collection_notPersisted">5.4. <code>notPersisted()</code></h3>
<button type="button" class="button secondary" onclick="window.location.href="https://github.com/apache/isis/edit/master/adocs/documentation/src/main/asciidoc/guides/_rgant-Collection_notPersisted.adoc"" style="float: right; font-size: small; padding: 6px; margin-top: -55px; "><i class="fa fa-pencil-square-o"></i> Edit</button>
<div class="paragraph">
<p>The (somewhat misnamed) <code>notPersisted()</code> attribute indicates that the collection should be excluded from any snapshots generated by the <a href="rgsvc.html#_rgsvc_api_XmlSnapshotService"><code>XmlSnapshotService</code></a>. This attribute is also supported for <a href="#_rgant-Property_notPersisted">properties</a>.</p>
</div>
<div class="admonitionblock warning">
<table>
<tbody>
<tr>
<td class="icon"> <i class="fa icon-warning" title="Warning"></i> </td>
<td class="content">
<div class="paragraph">
<p>This annotation does <em>not</em> specify that a collection is not persisted in the JDO/DataNucleus objectstore. See below for details as to how to additionally annotate the collection for this.</p>
</div> </td>
</tr>
</tbody>
</table>
</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">class</span> <span class="class">Customer</span> {
<span class="annotation">@Collection</span>(notPersisted=<span class="predefined-constant">true</span>)
<span class="directive">public</span> <span class="predefined-type">SortedSet</span><Order> getPreviousOrders() {...}
<span class="directive">public</span> <span class="type">void</span> setPreviousOrder(<span class="predefined-type">SortedSet</span><Order> previousOrders) {...}
...
}</code></pre>
</div>
</div>
<div class="paragraph">
<p>Historically this annotation also hinted as to whether the collection’s contents should be persisted in the object store. However, the JDO/DataNucleus objectstore does not recognize this annotation. Thus, to ensure that a collection is actually not persisted, it should <strong>also</strong> be annotated with <code>@javax.jdo.annotations.NotPersistent</code>.</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">class</span> <span class="class">Customer</span> {
<span class="annotation">@Collection</span>(notPersisted=<span class="predefined-constant">true</span>) <i class="conum" data-value="1"></i><b>(1)</b>
<span class="annotation">@javax</span>.jdo.annotations.NotPersistent <i class="conum" data-value="2"></i><b>(2)</b>
<span class="directive">public</span> <span class="predefined-type">SortedSet</span><Order> getPreviousOrders() {...}
<span class="directive">public</span> <span class="type">void</span> setPreviousOrder(<span class="predefined-type">SortedSet</span><Order> previousOrders) {...}
...
}</code></pre>
</div>
</div>
<div class="colist arabic">
<table>
<tbody>
<tr>
<td><i class="conum" data-value="1"></i><b>1</b></td>
<td>ignored by Apache Isis</td>
</tr>
<tr>
<td><i class="conum" data-value="2"></i><b>2</b></td>
<td>ignored by JDO/DataNucleus</td>
</tr>
</tbody>
</table>
</div>
<div class="paragraph">
<p>Alternatively, if the collection is derived, then providing only a "getter" will also work:</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">Customer</span> {
<span class="directive">public</span> <span class="predefined-type">SortedSet</span><Order> getPreviousOrders() {...}
...
}</code></pre>
</div>
</div>
</div>
<div class="sect2">
<h3 id="_rgant-Collection_typeOf">5.5. <code>typeOf()</code></h3>
<button type="button" class="button secondary" onclick="window.location.href="https://github.com/apache/isis/edit/master/adocs/documentation/src/main/asciidoc/guides/_rgant-Collection_typeOf.adoc"" style="float: right; font-size: small; padding: 6px; margin-top: -55px; "><i class="fa fa-pencil-square-o"></i> Edit</button>
<div class="paragraph">
<p>The <code>typeOf()</code> attribute specifies the expected type of an element contained within a collection when for whatever reason the type cannot be inferred from the generic type, or to provide a hint about the actual run-time (as opposed to compile-time) type. This attribute can also be specified for <a href="#_rgant-Action_typeOf">actions</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="directive">public</span> <span class="type">void</span> Customer {
<span class="annotation">@TypeOf</span>(Order.class)
<span class="directive">public</span> <span class="predefined-type">SortedSet</span> getOutstandingOrders() { ... }
...
}</code></pre>
</div>
</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>In general we recommend that you use generics instead, eg <code>SortedSet<Order></code>.</p>
</div> </td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
</div>
<div class="sect1">
<h2 id="_rgant-CollectionLayout">6. <code>@CollectionLayout</code></h2>
<button type="button" class="button secondary" onclick="window.location.href="https://github.com/apache/isis/edit/master/adocs/documentation/src/main/asciidoc/guides/_rgant-CollectionLayout.adoc"" style="float: right; font-size: small; padding: 6px; margin-top: -55px; "><i class="fa fa-pencil-square-o"></i> Edit</button>
<div class="sectionbody">
<div class="paragraph">
<p>The <code>@CollectionLayout</code> annotation applies to collections, collecting together all UI hints within a single annotation. It is also possible to apply the annotation to actions of domain services that are acting as contributed collections.</p>
</div>
<div class="paragraph">
<p>The table below summarizes the annotation’s attributes.</p>
</div>
<table class="tableblock frame-all grid-all spread">
<caption class="title">
Table 11.
<code>@CollectionLayout</code> attributes
</caption>
<colgroup>
<col style="width: 25%;">
<col style="width: 25%;">
<col style="width: 50%;">
</colgroup>
<thead>
<tr>
<th class="tableblock halign-left valign-top">Attribute</th>
<th class="tableblock halign-left valign-top">Values (default)</th>
<th class="tableblock halign-left valign-top">Description</th>
</tr>
</thead>
<tbody>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="#_rgant-CollectionLayout_cssClass"><code>cssClass()</code></a></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Any string valid as a CSS class</p></td>
<td class="tableblock halign-left valign-top">
<div>
<div class="paragraph">
<p>the css class that a collection should have, to allow more targetted styling in <a href="rgcfg.html#_rgcfg_application-specific_application-css"><code>application.css</code></a></p>
</div>
</div></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="#_rgant-CollectionLayout_defaultView"><code>defaultView()</code></a></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>table</code>, <code>excel</code>, <code>calendar</code>, <code>map</code>, …</p></td>
<td class="tableblock halign-left valign-top">
<div>
<div class="paragraph">
<p>Which view is selected by default, if multiple views are available.</p>
</div>
<div class="paragraph">
<p>See (non-ASF) <a href="http://isisaddons.org">Isis Addons</a> for further views.</p>
</div>
</div></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="#_rgant-CollectionLayout_describedAs"><code>describedAs()</code></a></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">String.</p></td>
<td class="tableblock halign-left valign-top">
<div>
<div class="paragraph">
<p>description of this collection, eg to be rendered in a tooltip.</p>
</div>
</div></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="#_rgant-CollectionLayout_hidden"><code>hidden()</code></a></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>EVERYWHERE</code>, <code>OBJECT_FORMS</code>, <code>NOWHERE</code><br> (<code>NOWHERE</code>)</p></td>
<td class="tableblock halign-left valign-top">
<div>
<div class="paragraph">
<p>indicates where (in the UI) the collection should be hidden from the user.</p>
</div>
</div></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="#_rgant-CollectionLayout_named">named()</a></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">String.</p></td>
<td class="tableblock halign-left valign-top">
<div>
<div class="paragraph">
<p>to override the name inferred from the collection’s name in code.<br></p>
</div>
<div class="paragraph">
<p>A typical use case is if the desired name is a reserved Java keyword, such as <code>default</code> or <code>package</code>.</p>
</div>
</div></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">namedEscaped()</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>true</code>,<code>false</code> (<code>true</code>)</p></td>
<td class="tableblock halign-left valign-top">
<div>
<div class="paragraph">
<p>whether to HTML escape the name of this property.</p>
</div>
</div></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="#_rgant-CollectionLayout_paged"><code>paged()</code></a></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Positive integer</p></td>
<td class="tableblock halign-left valign-top">
<div>
<div class="paragraph">
<p>the page size for instances of this class when rendered within a table.</p>
</div>
</div></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="#_rgant-CollectionLayout_render"><code>render()</code></a></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>EAGERLY</code>, <code>LAZILY</code><br> (<code>LAZILY</code>)</p></td>
<td class="tableblock halign-left valign-top">
<div>
<div class="paragraph">
<p>whether the collection should be (eagerly) rendered open or (lazily) rendered closed</p>
</div>
</div></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="#_rgant-CollectionLayout_sortedBy"><code>sortedBy()</code></a></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Subclass of <code>java.util.Comparator</code> for element type</p></td>
<td class="tableblock halign-left valign-top">
<div>
<div class="paragraph">
<p>indicates that the elements in the <code>java.util.SortedSet</code> collection should be sorted according to a specified <code>Comparator</code> rather than their natural sort order.</p>
</div>
</div></td>
</tr>
</tbody>
</table>
<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">class</span> <span class="class">ToDoItem</span> {
<span class="annotation">@CollectionLayout</span>(
cssClass=<span class="string"><span class="delimiter">"</span><span class="content">x-key</span><span class="delimiter">"</span></span>,
named=<span class="string"><span class="delimiter">"</span><span class="content">Todo items that are <i>dependencies</i> of this item.</span><span class="delimiter">"</span></span>,
namedEscaped=<span class="predefined-constant">false</span>,
describedAs=<span class="string"><span class="delimiter">"</span><span class="content">Other todo items that must be completed before this one</span><span class="delimiter">"</span></span>,
labelPosition=LabelPosition.LEFT,
render=EAGERLY)
<span class="directive">public</span> <span class="predefined-type">SortedSet</span><ToDoItem> getDependencies() { ... }
...
}</code></pre>
</div>
</div>
<div class="paragraph">
<p>As an alternative to using the <code>@CollectionLayout</code> annotation, a dynamic layout using <a href="ugfun.html#_ugfun_object-layout_dynamic"><code>.layout.json</code></a> file can be specified; for example:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code data-lang="javascript"><span class="string"><span class="delimiter">"</span><span class="content">dependencies</span><span class="delimiter">"</span></span>: {
<span class="key"><span class="delimiter">"</span><span class="content">collectionLayout</span><span class="delimiter">"</span></span>: {
<span class="key"><span class="delimiter">"</span><span class="content">cssClass</span><span class="delimiter">"</span></span>: <span class="string"><span class="delimiter">"</span><span class="content">x-key</span><span class="delimiter">"</span></span>,
<span class="key"><span class="delimiter">"</span><span class="content">named</span><span class="delimiter">"</span></span>: <span class="string"><span class="delimiter">"</span><span class="content">Todo items that are <i>dependencies</i> of this item.</span><span class="delimiter">"</span></span>,
<span class="key"><span class="delimiter">"</span><span class="content">namedEscaped</span><span class="delimiter">"</span></span>: <span class="predefined-constant">false</span>,
<span class="key"><span class="delimiter">"</span><span class="content">describedAs</span><span class="delimiter">"</span></span>: <span class="string"><span class="delimiter">"</span><span class="content">Other todo items that must be completed before this one</span><span class="delimiter">"</span></span>,
<span class="key"><span class="delimiter">"</span><span class="content">labelPosition</span><span class="delimiter">"</span></span>: <span class="string"><span class="delimiter">"</span><span class="content">LEFT</span><span class="delimiter">"</span></span>,
<span class="key"><span class="delimiter">"</span><span class="content">render</span><span class="delimiter">"</span></span>: <span class="string"><span class="delimiter">"</span><span class="content">EAGERLY</span><span class="delimiter">"</span></span>
}
}</code></pre>
</div>
</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>The annotation is one of a handful (others including <a href="#_rgant-Collection"><code>@Collection</code></a>, <a href="#_rgant-Property"><code>@Property</code></a> and <a href="#_rgant-PropertyLayout"><code>@PropertyLayout</code></a>) that can also be applied to the field, rather than the getter method. This is specifically so that boilerplate-busting tools such as <a href="https://projectlombok.org/">Project Lombok</a> can be used.</p>
</div> </td>
</tr>
</tbody>
</table>
</div>
<div class="sect2">
<h3 id="_rgant-CollectionLayout_cssClass">6.1. <code>cssClass()</code></h3>
<button type="button" class="button secondary" onclick="window.location.href="https://github.com/apache/isis/edit/master/adocs/documentation/src/main/asciidoc/guides/_rgant-CollectionLayout_cssClass.adoc"" style="float: right; font-size: small; padding: 6px; margin-top: -55px; "><i class="fa fa-pencil-square-o"></i> Edit</button>
<div class="paragraph">
<p>The <code>cssClass()</code> attribute can be used to render additional CSS classes in the HTML (a wrapping <code><div></code>) that represents the collection. <a href="rgcfg.html#_rgcfg_application-specific_application-css">Application-specific CSS</a> can then be used to target and adjust the UI representation of that particular element.</p>
</div>
<div class="paragraph">
<p>This attribute can also be applied to <a href="#_rgant-DomainObjectLayout_cssClass">domain objects</a>, <a href="#_rgant-ViewModelLayout_cssClass">view models</a>, <a href="#_rgant-ActionLayout_cssClass">actions</a>, <a href="#_rgant-PropertyLayout_cssClass">properties</a> and <a href="#_rgant-ParameterLayout_cssClass">parameters</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="directive">public</span> <span class="type">class</span> <span class="class">ToDoItem</span> {
<span class="annotation">@CollectionLayout</span>(
cssClass=<span class="string"><span class="delimiter">"</span><span class="content">x-important</span><span class="delimiter">"</span></span>
)
<span class="directive">public</span> <span class="predefined-type">SortedSet</span><ToDoItem> getDependencies() { ... }
...
}</code></pre>
</div>
</div>
<div class="paragraph">
<p>As an alternative to using the annotation, the dynamic <a href="ugfun.html#_ugfun_object-layout_dynamic"><code>.layout.json</code></a> can be used instead, eg:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code data-lang="javascript"><span class="string"><span class="delimiter">"</span><span class="content">dependencies</span><span class="delimiter">"</span></span>: {
<span class="key"><span class="delimiter">"</span><span class="content">collectionLayout</span><span class="delimiter">"</span></span>: { <span class="key"><span class="delimiter">"</span><span class="content">cssClass</span><span class="delimiter">"</span></span>: <span class="string"><span class="delimiter">"</span><span class="content">x-important</span><span class="delimiter">"</span></span> }
}</code></pre>
</div>
</div>
</div>
<div class="sect2">
<h3 id="_rgant-CollectionLayout_defaultView">6.2. <code>defaultView()</code></h3>
<button type="button" class="button secondary" onclick="window.location.href="https://github.com/apache/isis/edit/master/adocs/documentation/src/main/asciidoc/guides/_rgant-CollectionLayout_defaultView.adoc"" style="float: right; font-size: small; padding: 6px; margin-top: -55px; "><i class="fa fa-pencil-square-o"></i> Edit</button>
<div class="paragraph">
<p>The <a href="ugvw.html">Wicket viewer</a> allows additional views to be configured to render collections of objects; at the time of writing thesee include the (non-ASF) (non-ASF) <a href="http://isisaddons.org">Isis Addons</a>' (non-ASF) <a href="http://github.com/isisaddons/isis-wicket-excel">excel</a> view, the <a href="http://github.com/isisaddons/isis-wicket-fullcalendar2">fullcalendar2</a> view, and the <a href="http://github.com/isisaddons/isis-wicket-gmap3">gmap3</a> view. If the objects to be rendered have the correct "shape", then the appropriate view will be made available. For example, objects with a date can be rendered using <code>calendar</code>; objects with locations can be rendered using <code>map</code>.</p>
</div>
<div class="paragraph">
<p>The <code>defaultView()</code> attribute is used to select which of these views should be used by default for a given collection.</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">class</span> <span class="class">BusRoute</span> {
<span class="annotation">@CollectionLayout</span>(
defaultView=<span class="string"><span class="delimiter">"</span><span class="content">map</span><span class="delimiter">"</span></span>
)
<span class="directive">public</span> <span class="predefined-type">SortedSet</span><BusStop> getStops() { ... }
...
}</code></pre>
</div>
</div>
<div class="paragraph">
<p>As an alternative to using the annotation, the dynamic <a href="ugfun.html#_ugfun_object-layout_dynamic"><code>.layout.json</code></a> can be used instead, eg:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code data-lang="javascript"><span class="string"><span class="delimiter">"</span><span class="content">dependencies</span><span class="delimiter">"</span></span>: {
<span class="key"><span class="delimiter">"</span><span class="content">collectionLayout</span><span class="delimiter">"</span></span>: {
<span class="key"><span class="delimiter">"</span><span class="content">defaultView</span><span class="delimiter">"</span></span>: <span class="string"><span class="delimiter">"</span><span class="content">map</span><span class="delimiter">"</span></span>
}
}</code></pre>
</div>
</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>This attribute takes precedence over any value for the <a href="#_rgant-CollectionLayout_render"><code>@CollectionLayout#render()</code></a> attribute. For example, if the <code>defaultView</code> attribute is defined to "table", then the table will be show even if <code>render</code> is set to <code>LAZILY</code>.</p>
</div> </td>
</tr>
</tbody>
</table>
</div>
</div>
<div class="sect2">
<h3 id="_rgant-CollectionLayout_describedAs">6.3. <code>describedAs()</code></h3>
<button type="button" class="button secondary" onclick="window.location.href="https://github.com/apache/isis/edit/master/adocs/documentation/src/main/asciidoc/guides/_rgant-CollectionLayout_describedAs.adoc"" style="float: right; font-size: small; padding: 6px; margin-top: -55px; "><i class="fa fa-pencil-square-o"></i> Edit</button>
<div class="paragraph">
<p>The <code>describedAs()</code> attribute is used to provide a short description of the collection to the user. In the <a href="ugvw.html">Wicket viewer</a> it is displayed as a 'tool tip'.</p>
</div>
<div class="paragraph">
<p>The <code>describedAs()</code> attribute can also be specified for <a href="#_rgant-PropertyLayout_describedAs">properties</a>, <a href="#_rgant-ActionLayout_describedAs">actions</a>, <a href="#_rgant-ParameterLayout_describedAs">parameters</a>, <a href="#_rgant-DomainObjectLayout_describedAs">domain objects</a> and <a href="#_rgant-ViewModelLayout_describedAs">view models</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="directive">public</span> <span class="type">class</span> <span class="class">ToDoItem</span> {
<span class="annotation">@CollectionLayout</span>(
describedAs=<span class="string"><span class="delimiter">"</span><span class="content">Other todo items that must be completed before this one</span><span class="delimiter">"</span></span>
)
<span class="directive">public</span> <span class="predefined-type">SortedSet</span><ToDoItem> getDependencies() { ... }
...
}</code></pre>
</div>
</div>
<div class="paragraph">
<p>As an alternative to using the annotation, the dynamic <a href="ugfun.html#_ugfun_object-layout_dynamic"><code>.layout.json</code></a> can be used instead, eg:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code data-lang="javascript"><span class="string"><span class="delimiter">"</span><span class="content">dependencies</span><span class="delimiter">"</span></span>: {
<span class="key"><span class="delimiter">"</span><span class="content">collectionLayout</span><span class="delimiter">"</span></span>: {
<span class="key"><span class="delimiter">"</span><span class="content">describedAs</span><span class="delimiter">"</span></span>: <span class="string"><span class="delimiter">"</span><span class="content">Other todo items that must be completed before this one</span><span class="delimiter">"</span></span>
}
}</code></pre>
</div>
</div>
</div>
<div class="sect2">
<h3 id="_rgant-CollectionLayout_hidden">6.4. <code>hidden()</code></h3>
<button type="button" class="button secondary" onclick="window.location.href="https://github.com/apache/isis/edit/master/adocs/documentation/src/main/asciidoc/guides/_rgant-CollectionLayout_hidden.adoc"" style="float: right; font-size: small; padding: 6px; margin-top: -55px; "><i class="fa fa-pencil-square-o"></i> Edit</button>
<div class="paragraph">
<p>The <code>hidden()</code> attribute indicates where (in the UI) the collection should be hidden from the user. This attribute can also be applied to <a href="#_rgant-ActionLayout_hidden">actions</a> and <a href="#_rgant-PropertyLayout_hidden">properties</a>.</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>It is also possible to use <a href="#_rgant-Collection_hidden"><code>@Collection#hidden()</code></a> to hide an action at the domain layer. Both options are provided with a view that in the future the view-layer semantics may be under the control of (expert) users, whereas domain-layer semantics should never be overridden or modified by the user.</p>
</div> </td>
</tr>
</tbody>
</table>
</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">class</span> <span class="class">ToDoItem</span> {
<span class="annotation">@CollectionLayout</span>(
hidden=Where.EVERYWHERE
<span class="directive">public</span> <span class="predefined-type">SortedSet</span><ToDoItem> getDependencies() { ... }
...
}</code></pre>
</div>
</div>
<div class="paragraph">
<p>The acceptable values for the <code>where</code> parameter are:</p>
</div>
<div class="ulist">
<ul>
<li> <p><code>Where.EVERYWHERE</code> or <code>Where.ANYWHERE</code><br></p>
<div class="paragraph">
<p>The collection should be hidden everywhere.</p>
</div> </li>
<li> <p><code>Where.ANYWHERE</code><br></p>
<div class="paragraph">
<p>Synonym for everywhere.</p>
</div> </li>
<li> <p><code>Where.OBJECT_FORMS</code><br></p>
<div class="paragraph">
<p>The collection should be hidden when displayed within an object form.</p>
</div> </li>
<li> <p><code>Where.NOWHERE</code><br></p>
<div class="paragraph">
<p>The collection should not be hidden.</p>
</div> </li>
</ul>
</div>
<div class="paragraph">
<p>The other values of the <code>Where</code> enum have no meaning for a collection.</p>
</div>
<div class="paragraph">
<p>As an alternative to using the annotation, the dynamic <a href="ugfun.html#_ugfun_object-layout_dynamic"><code>.layout.json</code></a> can be used instead, eg:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code data-lang="javascript"><span class="string"><span class="delimiter">"</span><span class="content">dependencies</span><span class="delimiter">"</span></span>: {
<span class="key"><span class="delimiter">"</span><span class="content">collectionLayout</span><span class="delimiter">"</span></span>: { <span class="key"><span class="delimiter">"</span><span class="content">hidden</span><span class="delimiter">"</span></span>: <span class="string"><span class="delimiter">"</span><span class="content">EVERYWHERE</span><span class="delimiter">"</span></span> }
}</code></pre>
</div>
</div>
</div>
<div class="sect2">
<h3 id="_rgant-CollectionLayout_named">6.5. <code>named()</code></h3>
<button type="button" class="button secondary" onclick="window.location.href="https://github.com/apache/isis/edit/master/adocs/documentation/src/main/asciidoc/guides/_rgant-CollectionLayout_named.adoc"" style="float: right; font-size: small; padding: 6px; margin-top: -55px; "><i class="fa fa-pencil-square-o"></i> Edit</button>
<div class="paragraph">
<p>The <code>named()</code> attribute explicitly specifies the collection’s name, overriding the name that would normally be inferred from the Java source code. This attribute can also be specified for <a href="#_rgant-ActionLayout_named">actions</a>, <a href="#_rgant-PropertyLayout_named">properties</a>, <a href="#_rgant-ParameterLayout_named">parameters</a>, <a href="#_rgant-DomainObjectLayout_named">domain objects</a>, <a href="#_rgant-ViewModelLayout_named">view models</a> and <a href="#_rgant-DomainServiceLayout_named">domain services</a>.</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>Following the <a href="http://en.wikipedia.org/wiki/Don%27t_repeat_yourself">don’t repeat yourself</a> principle, we recommend that you only use this attribute when the desired name cannot be used in Java source code. Examples of that include a name that would be a reserved Java keyword (eg "package"), or a name that has punctuation, eg apostrophes.</p>
</div> </td>
</tr>
</tbody>
</table>
</div>
<div class="paragraph">
<p>By default the name is HTML escaped. To allow HTML markup, set the related <code>namedEscaped()</code> attribute to <code>false</code>.</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">class</span> <span class="class">ToDoItem</span> {
<span class="annotation">@CollectionLayout</span>(
named=<span class="string"><span class="delimiter">"</span><span class="content">Todo items that are <i>dependencies</i> of this item</span><span class="delimiter">"</span></span>,
namedEscaped=<span class="predefined-constant">false</span>
)
<span class="directive">public</span> <span class="predefined-type">SortedSet</span><ToDoItem getDependencies() { ... }
...
}</code></pre>
</div>
</div>
<div class="paragraph">
<p>As an alternative to using the annotation, the dynamic <a href="ugfun.html#_ugfun_object-layout_dynamic"><code>.layout.json</code></a> can be used instead, eg:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code data-lang="javascript"><span class="string"><span class="delimiter">"</span><span class="content">dependencies</span><span class="delimiter">"</span></span>: {
<span class="key"><span class="delimiter">"</span><span class="content">collectionLayout</span><span class="delimiter">"</span></span>: {
<span class="key"><span class="delimiter">"</span><span class="content">named</span><span class="delimiter">"</span></span>: <span class="string"><span class="delimiter">"</span><span class="content">Todo items that are <i>dependencies</i> of this item</span><span class="delimiter">"</span></span>,
<span class="key"><span class="delimiter">"</span><span class="content">namedEscaped</span><span class="delimiter">"</span></span>: <span class="predefined-constant">false</span>,
}
}</code></pre>
</div>
</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>The framework also provides a separate, powerful mechanism for <a href="ugbtb.html#_ugbtb_i18n">internationalization</a>.</p>
</div> </td>
</tr>
</tbody>
</table>
</div>
</div>
<div class="sect2">
<h3 id="_rgant-CollectionLayout_paged">6.6. <code>paged()</code></h3>
<button type="button" class="button secondary" onclick="window.location.href="https://github.com/apache/isis/edit/master/adocs/documentation/src/main/asciidoc/guides/_rgant-CollectionLayout_paged.adoc"" style="float: right; font-size: small; padding: 6px; margin-top: -55px; "><i class="fa fa-pencil-square-o"></i> Edit</button>
<div class="paragraph">
<p>The <code>paged()</code> attribute specifies the number of rows to display in a (parented) collection. This attribute can also be applied to <a href="#_rgant-DomainObjectLayout_paged">domain objects</a> and <a href="#_rgant-ViewModelLayout_paged">view models</a>.</p>
</div>
<div class="admonitionblock warning">
<table>
<tbody>
<tr>
<td class="icon"> <i class="fa icon-warning" title="Warning"></i> </td>
<td class="content">
<div class="paragraph">
<p>The <a href="ugvro.html">RestfulObjects viewer</a> currently does not support paging. The <a href="ugvw.html">Wicket viewer</a> <em>does</em> support paging, but note that the paging is performed client-side rather than server-side.</p>
</div>
<div class="paragraph">
<p>We therefore recommend that large collections should instead be modelled as actions (to allow filtering to be applied to limit the number of rows).</p>
</div> </td>
</tr>
</tbody>
</table>
</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">class</span> <span class="class">Order</span> {
<span class="annotation">@CollectionLayout</span>(paged=<span class="integer">15</span>)
<span class="directive">public</span> <span class="predefined-type">SortedSet</span><OrderLine> getDetails() {...}
}</code></pre>
</div>
</div>
<div class="paragraph">
<p>It is also possible to specify a global default for the page size of standalone collections, using the <a href="rgcfg.html#_rgcfg_configuring-core">configuration property</a> <code>isis.viewer.paged.parented</code>.</p>
</div>
<div class="paragraph">
<p>As an alternative to using the annotation, the dynamic <a href="ugfun.html#_ugfun_object-layout_dynamic"><code>.layout.json</code></a> can be used instead, eg:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code data-lang="javascript"><span class="string"><span class="delimiter">"</span><span class="content">details</span><span class="delimiter">"</span></span>: {
<span class="key"><span class="delimiter">"</span><span class="content">collectionLayout</span><span class="delimiter">"</span></span>: {
<span class="key"><span class="delimiter">"</span><span class="content">paged</span><span class="delimiter">"</span></span>: <span class="integer">15</span>
}
}</code></pre>
</div>
</div>
</div>
<div class="sect2">
<h3 id="_rgant-CollectionLayout_render">6.7. <code>render()</code></h3>
<button type="button" class="button secondary" onclick="window.location.href="https://github.com/apache/isis/edit/master/adocs/documentation/src/main/asciidoc/guides/_rgant-CollectionLayout_render.adoc"" style="float: right; font-size: small; padding: 6px; margin-top: -55px; "><i class="fa fa-pencil-square-o"></i> Edit</button>
<div class="paragraph">
<p>The <code>render()</code> attribute specifies that the collection be rendered either "eagerly" (shown open, displaying its contents) or "lazily" (shown closed, hiding its contents). The terminology here is based on the similar concept of lazy loading of collections in the domain/persistence layer boundary (except that the rendering relates to the presentation/domain layer boundary).</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">class</span> <span class="class">Order</span> {
<span class="annotation">@CollectionLayout</span>(render=RenderType.EAGERLY)
<span class="directive">public</span> <span class="predefined-type">SortedSet</span><LineItem> getDetails() { ... }
...
}</code></pre>
</div>
</div>
<div class="paragraph">
<p>As an alternative to using the annotation, the dynamic <a href="ugfun.html#_ugfun_object-layout_dynamic"><code>.layout.json</code></a> can be used instead, eg:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code data-lang="javascript"><span class="string"><span class="delimiter">"</span><span class="content">details</span><span class="delimiter">"</span></span>: {
<span class="key"><span class="delimiter">"</span><span class="content">collectionLayout</span><span class="delimiter">"</span></span>: {
<span class="key"><span class="delimiter">"</span><span class="content">render</span><span class="delimiter">"</span></span>: <span class="string"><span class="delimiter">"</span><span class="content">EAGERLY</span><span class="delimiter">"</span></span>
}
}</code></pre>
</div>
</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 <a href="ugfun.html#_ugfun_how-tos_contributed-members">contributed collections</a> (which, under the covers are just action invocations against a domain service) are always rendered eagerly.</p>
</div>
<div class="paragraph">
<p>Also, if a <a href="#_rgant-CollectionLayout_defaultView"><code>@CollectionLayout#defaultView()</code></a> attribute has been specified then that will take precedence over the value of the <code>render()</code> attribute.</p>
</div> </td>
</tr>
</tbody>
</table>
</div>
</div>
<div class="sect2">
<h3 id="_rgant-CollectionLayout_sortedBy">6.8. <code>sortedBy()</code></h3>
<button type="button" class="button secondary" onclick="window.location.href="https://github.com/apache/isis/edit/master/adocs/documentation/src/main/asciidoc/guides/_rgant-CollectionLayout_sortedBy.adoc"" style="float: right; font-size: small; padding: 6px; margin-top: -55px; "><i class="fa fa-pencil-square-o"></i> Edit</button>
<div class="paragraph">
<p>The <code>sortedBy()</code> attribute specifies that the collection be ordered using the specified comparator, rather than the natural ordering of the entity (as would usually be the case).</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">class</span> <span class="class">ToDoItem</span> <span class="directive">implements</span> <span class="predefined-type">Comparable</span><ToDoItem> { <i class="conum" data-value="1"></i><b>(1)</b>
<span class="directive">public</span> <span class="directive">static</span> <span class="type">class</span> <span class="class">DependenciesComparator</span> <i class="conum" data-value="2"></i><b>(2)</b>
<span class="directive">implements</span> <span class="predefined-type">Comparator</span><ToDoItem> {
<span class="annotation">@Override</span>
<span class="directive">public</span> <span class="type">int</span> compare(ToDoItem p, ToDoItem q) {
<span class="keyword">return</span> ORDERING_BY_DESCRIPTION <i class="conum" data-value="3"></i><b>(3)</b>
.compound(Ordering.<ToDoItem>natural())
.compare(p, q);
}
}
<span class="annotation">@CollectionLayout</span>(sortedBy=DependenciesComparator.class) <i class="conum" data-value="4"></i><b>(4)</b>
<span class="directive">public</span> <span class="predefined-type">SortedSet</span><ToDoItem> getDependencies() { ... }
...
}</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 class has a natural ordering (implementation not shown)</td>
</tr>
<tr>
<td><i class="conum" data-value="2"></i><b>2</b></td>
<td>declaration of the comparator class</td>
</tr>
<tr>
<td><i class="conum" data-value="3"></i><b>3</b></td>
<td>ordering defined as being by the object’s <code>description</code> property (not shown), and then by the natural ordering of the class</td>
</tr>
<tr>
<td><i class="conum" data-value="4"></i><b>4</b></td>
<td>specify the comparator to use</td>
</tr>
</tbody>
</table>
</div>
<div class="paragraph">
<p>When the <code>dependencies</code> collection is rendered, the elements are sorted by the <code>description</code> property first:</p>
</div>
<div class="imageblock">
<div class="content">
<a class="image" href="images/reference-annotations/CollectionLayout/sortedby-dependencies.png"><img src="images/reference-annotations/CollectionLayout/sortedby-dependencies.png" alt="sortedby dependencies" width="720px"></a>
</div>
</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 screenshot shows an earlier version of the <a href="ugvw.html">Wicket viewer</a> UI (specifically, pre 1.8.0).</p>
</div> </td>
</tr>
</tbody>
</table>
</div>
<div class="paragraph">
<p>Without this annotation, the order would have been inverted (because the natural ordering places items not completed before those items that have been completed.</p>
</div>
<div class="paragraph">
<p>As an alternative to using the annotation, the dynamic <a href="ugfun.html#_ugfun_object-layout_dynamic"><code>.layout.json</code></a> can be used instead, eg:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code data-lang="javascript"><span class="string"><span class="delimiter">"</span><span class="content">dependencies</span><span class="delimiter">"</span></span>: {
<span class="key"><span class="delimiter">"</span><span class="content">collectionLayout</span><span class="delimiter">"</span></span>: {
<span class="key"><span class="delimiter">"</span><span class="content">sortedBy</span><span class="delimiter">"</span></span>: <span class="string"><span class="delimiter">"</span><span class="content">com.mycompany.myapp.dom.ToDoItem.DependenciesComparator</span><span class="delimiter">"</span></span>
}
}</code></pre>
</div>
</div>
</div>
</div>
</div>
<div class="sect1">
<h2 id="_rgant-Column">7. <code>@Column</code> (<code>javax.jdo</code>)</h2>
<button type="button" class="button secondary" onclick="window.location.href="https://github.com/apache/isis/edit/master/adocs/documentation/src/main/asciidoc/guides/_rgant-Column.adoc"" style="float: right; font-size: small; padding: 6px; margin-top: -55px; "><i class="fa fa-pencil-square-o"></i> Edit</button>
<div class="sectionbody">
<div class="paragraph">
<p>The JDO <code>@javax.jdo.annotation.Column</code> provides metadata describing how JDO/DataNucleus should persist the property to a database RDBMS table column (or equivalent concept for other persistence stores).</p>
</div>
<div class="paragraph">
<p>Apache Isis also parses and interprets this annotation in order to build up aspects of its metamodel.</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>Isis parses the <code>@Column</code> annotation from the Java source code; it does not query the JDO metamodel. This means that it the <code>@Column</code> annotation must be used rather than the equivalent <code><column></code> <a href="http://www.datanucleus.org/products/accessplatform_4_0/jdo/orm/schema_mapping.html">XML metadata</a>.</p>
</div>
<div class="paragraph">
<p>Moreover, while JDO/DataNucleus will recognize annotations on either the field or the getter method, Apache Isis (currently) only inspects the getter method. Therefore ensure that the annotation is placed there.</p>
</div> </td>
</tr>
</tbody>
</table>
</div>
<div class="paragraph">
<p>This section identifies which attributes of <code>@Column</code> are recognized and used by Apache Isis.</p>
</div>
<div class="sect2">
<h3 id="_nullability">7.1. Nullability</h3>
<div class="paragraph">
<p>The <code>allowsNull()</code> attribute is used to specify if a property is mandatory or is optional.</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">class</span> <span class="class">Customer</span> {
<span class="annotation">@javax</span>.jdo.annotations.Column(allowsNull=<span class="string"><span class="delimiter">"</span><span class="content">true</span><span class="delimiter">"</span></span>)
<span class="directive">public</span> <span class="predefined-type">String</span> getMiddleInitial() { ... }
<span class="directive">public</span> <span class="type">void</span> setMiddleInitial(<span class="predefined-type">String</span> middleInitial) { ... }</code></pre>
</div>
</div>
<div class="paragraph">
<p>Isis also provides <a href="#_rgant-Property_optionality"><code>@Property#optionality()</code></a> attribute. If both are specified, Apache Isis will check when it initializes for any contradictions, and will fail-fast with an appropriate error message in the log if there are.</p>
</div>
<div class="paragraph">
<p>You should also be aware that in the lack of either the <code>@Column#allowsNull()</code> or the <code>@Property#optionality()</code> attributes, that the JDO and Apache Isis defaults differ. Apache Isis rule is straight-forward: properties are assumed to be required. JDO on the other hand specifies that only primitive types are mandatory; everything else is assumed to be optional. Therefore a lack of either annotation can also trigger the fail-fast validation check.</p>
</div>
<div class="paragraph">
<p>In the vast majority of cases you should be fine just to add the <code>@Column#allowsNull()</code> attribute to the getter. But see the documentation for <a href="#_rgant-Property_optionality"><code>@Property#optionality()</code></a> attribute for discussion on one or two minor edge cases.</p>
</div>
</div>
<div class="sect2">
<h3 id="_length_for_code_string_code_s">7.2. Length for <code>String</code>s</h3>
<div class="paragraph">
<p>The <code>length()</code> attribute is used to specify the length of <code>java.lang.String</code> property types as they map to <code>varchar(n)</code> columns.</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">class</span> <span class="class">Customer</span> {
<span class="annotation">@javax</span>.jdo.annotations.Column(length=<span class="integer">20</span>)
<span class="directive">public</span> <span class="predefined-type">String</span> getFirstName() { ... }
<span class="directive">public</span> <span class="type">void</span> setFirstName(<span class="predefined-type">String</span> firstName) { ... }
<span class="annotation">@javax</span>.jdo.annotations.Column(allowsNull=<span class="string"><span class="delimiter">"</span><span class="content">true</span><span class="delimiter">"</span></span>, length=<span class="integer">1</span>)
<span class="directive">public</span> <span class="predefined-type">String</span> getMiddleInitial() { ... }
<span class="directive">public</span> <span class="type">void</span> setMiddleInitial(<span class="predefined-type">String</span> middleInitial) { ... }
<span class="annotation">@javax</span>.jdo.annotations.Column(length=<span class="integer">30</span>)
<span class="directive">public</span> <span class="predefined-type">String</span> getLastName() { ... }
<span class="directive">public</span> <span class="type">void</span> setLastName(<span class="predefined-type">String</span> lastName) { ... }</code></pre>
</div>
</div>
<div class="paragraph">
<p>Isis also provides <a href="#_rgant-Property_maxLength"><code>@Property#maxLength()</code></a> attribute. If both are specified, Apache Isis will check when it initializes for any contradictions, and will fail-fast with an appropriate error message in the log if there are.</p>
</div>
</div>
<div class="sect2">
<h3 id="_length_scale_for_code_bigdecimal_code_s">7.3. Length/scale for <code>BigDecimal</code>s</h3>
<div class="paragraph">
<p>The <code>length()</code> and <code>scale()</code> attributes are used to infer the precision/scale of <code>java.math.BigDecimal</code> property types as they map to <code>decimal(n,p)</code> columns.</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">class</span> <span class="class">Customer</span> {
<span class="annotation">@javax</span>.jdo.annotations.Column(length=<span class="integer">10</span>, scale=<span class="integer">2</span>)
<span class="directive">public</span> <span class="predefined-type">BigDecimal</span> getTotalOrdersToDate() { ... }
<span class="directive">public</span> <span class="type">void</span> setTotalOrdersToDate(<span class="predefined-type">BigDecimal</span> totalOrdersToDate) { ... }</code></pre>
</div>
</div>
<div class="paragraph">
<p>For <code>BigDecimal</code>s it is also possible to specify the <a href="#<em>rgant-Digits"><code>@Digits</code></a> annotation, whose form is <code>@Digits(integer, fraction)</code>. There is a subtle difference here: while <code>@Column#scale()</code> corresponds to <code>@Digits#fraction()</code>, the value of <code>@Column#length()</code> (ie the precision) is actually the _sum of the <code>@Digits’ `integer()</code> and <code>fraction()</code> parts.</p>
</div>
<div class="paragraph">
<p>If both are specified, Apache Isis will check when it initializes for any contradictions, and will fail-fast with an appropriate error message in the log if there are.</p>
</div>
</div>
<div class="sect2">
<h3 id="_hints_and_tips">7.4. Hints and Tips</h3>
<div class="paragraph">
<p>This seems to be a good place to describe some additional common mappings that use <code>@Column</code>. Unlike the sections above, the attributes specified in these hints and tips aren’t actually part of Apache Isis metamodel.</p>
</div>
<div class="sect3">
<h4 id="_mapping_foreign_keys">7.4.1. Mapping foreign keys</h4>
<div class="paragraph">
<p>The <code>name()</code> attribute can be used to override the name of the column. References to other objects are generally mapped as foreign key columns. If there are multiple references to a given type, then you will want to override the name that JDO/DataNucleus would otherwise default.</p>
</div>
<div class="paragraph">
<p>For example (taken from <a href="http://github.com/estatio/estatio">estatio</a> app):</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">PartyRelationship</span> {
<span class="annotation">@Column</span>(name = <span class="string"><span class="delimiter">"</span><span class="content">fromPartyId</span><span class="delimiter">"</span></span>, allowsNull = <span class="string"><span class="delimiter">"</span><span class="content">false</span><span class="delimiter">"</span></span>)
<span class="directive">public</span> Party getFrom() { ... }
<span class="directive">public</span> <span class="type">void</span> setFrom(Party from) { ... }
<span class="annotation">@Column</span>(name = <span class="string"><span class="delimiter">"</span><span class="content">toPartyId</span><span class="delimiter">"</span></span>, allowsNull = <span class="string"><span class="delimiter">"</span><span class="content">false</span><span class="delimiter">"</span></span>)
<span class="directive">public</span> Party getTo() { ... }
<span class="directive">public</span> <span class="type">void</span> setTo(Party to) { ... }
...
}</code></pre>
</div>
</div>
</div>
</div>
<div class="sect2">
<h3 id="_mapping_code_blob_code_s_and_code_clob_code_s">7.5. Mapping <code>Blob</code>s and <code>Clob</code>s</h3>
<div class="paragraph">
<p>Isis provides custom value types for <a href="rgcms.html#_rgcms_classes_value-types_Blob"><code>Blob</code></a>s and <a href="rgcms.html#_rgcms_classes_value-types_Clob"><code>Clob</code></a>s. These value types have multiple internal fields, meaning that they corresponding to multiple columns in the database. Mapping this correctly requires using <code>@Column</code> within JDO’s <code>@Persistent</code> annotation.</p>
</div>
<div class="paragraph">
<p>For example, here’s how to map a <code>Blob</code> (taken from (non-ASF) <a href="http://github.com/isisaddons/isis-app-todoapp">Isis addons' todoapp</a>):</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code data-lang="java"><span class="directive">private</span> <span class="predefined-type">Blob</span> attachment;
<span class="annotation">@javax</span>.jdo.annotations.Persistent(defaultFetchGroup=<span class="string"><span class="delimiter">"</span><span class="content">false</span><span class="delimiter">"</span></span>, columns = {
<span class="annotation">@javax</span>.jdo.annotations.Column(name = <span class="string"><span class="delimiter">"</span><span class="content">attachment_name</span><span class="delimiter">"</span></span>),
<span class="annotation">@javax</span>.jdo.annotations.Column(name = <span class="string"><span class="delimiter">"</span><span class="content">attachment_mimetype</span><span class="delimiter">"</span></span>),
<span class="annotation">@javax</span>.jdo.annotations.Column(name = <span class="string"><span class="delimiter">"</span><span class="content">attachment_bytes</span><span class="delimiter">"</span></span>, jdbcType = <span class="string"><span class="delimiter">"</span><span class="content">BLOB</span><span class="delimiter">"</span></span>, sqlType = <span class="string"><span class="delimiter">"</span><span class="content">LONGVARBINARY</span><span class="delimiter">"</span></span>)
})
<span class="annotation">@Property</span>(
domainEvent = AttachmentDomainEvent.class,
optionality = Optionality.OPTIONAL
)
<span class="directive">public</span> <span class="predefined-type">Blob</span> getAttachment() { ... }
<span class="directive">public</span> <span class="type">void</span> setAttachment(<span class="predefined-type">Blob</span> attachment) { ... }</code></pre>
</div>
</div>
<div class="paragraph">
<p>And here’s how to map a <code>Clob</code> (also taken from the todoapp):</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code data-lang="java"><span class="directive">private</span> <span class="predefined-type">Clob</span> doc;
<span class="annotation">@javax</span>.jdo.annotations.Persistent(defaultFetchGroup=<span class="string"><span class="delimiter">"</span><span class="content">false</span><span class="delimiter">"</span></span>, columns = {
<span class="annotation">@javax</span>.jdo.annotations.Column(name = <span class="string"><span class="delimiter">"</span><span class="content">doc_name</span><span class="delimiter">"</span></span>),
<span class="annotation">@javax</span>.jdo.annotations.Column(name = <span class="string"><span class="delimiter">"</span><span class="content">doc_mimetype</span><span class="delimiter">"</span></span>),
<span class="annotation">@javax</span>.jdo.annotations.Column(name = <span class="string"><span class="delimiter">"</span><span class="content">doc_chars</span><span class="delimiter">"</span></span>, jdbcType = <span class="string"><span class="delimiter">"</span><span class="content">CLOB</span><span class="delimiter">"</span></span>, sqlType = <span class="string"><span class="delimiter">"</span><span class="content">LONGVARCHAR</span><span class="delimiter">"</span></span>)
})
<span class="annotation">@Property</span>(
optionality = Optionality.OPTIONAL
)
<span class="directive">public</span> <span class="predefined-type">Clob</span> getDoc() { ... }
<span class="directive">public</span> <span class="type">void</span> setDoc(<span class="directive">final</span> <span class="predefined-type">Clob</span> doc) { ... }</code></pre>
</div>
</div>
</div>
</div>
</div>
<div class="sect1">
<h2 id="_rgant-Digits">8. <code>@Digits</code> (<code>javax</code>)</h2>
<button type="button" class="button secondary" onclick="window.location.href="https://github.com/apache/isis/edit/master/adocs/documentation/src/main/asciidoc/guides/_rgant-Digits.adoc"" style="float: right; font-size: small; padding: 6px; margin-top: -55px; "><i class="fa fa-pencil-square-o"></i> Edit</button>
<div class="sectionbody">
<div class="paragraph">
<p>The <code>@javax.validation.constraints.Digits</code> annotation is recognized by Apache Isis as a means to specify the precision for properties and action parameters of type <code>java.math.BigDecimal</code>.</p>
</div>
<div class="paragraph">
<p>For example (taken from the (non-ASF) <a href="http://github.com/isisaddons/isis-app-todoapp">Isis addons' todoapp</a>):</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code data-lang="java"><span class="annotation">@javax</span>.jdo.annotations.Column(
scale=<span class="integer">2</span> <i class="conum" data-value="1"></i><b>(1)</b>
)
<span class="annotation">@javax</span>.validation.constraints.Digits(
integer=<span class="integer">10</span>,
fraction=<span class="integer">2</span> <i class="conum" data-value="2"></i><b>(2)</b>
)
<span class="directive">public</span> <span class="predefined-type">BigDecimal</span> getCost() {
<span class="keyword">return</span> cost;
}
<span class="directive">public</span> <span class="type">void</span> setCost(<span class="directive">final</span> <span class="predefined-type">BigDecimal</span> cost) {
<span class="local-variable">this</span>.cost = cost!=<span class="predefined-constant">null</span>
? cost.setScale(<span class="integer">2</span>, <span class="predefined-type">BigDecimal</span>.ROUND_HALF_EVEN) <i class="conum" data-value="3"></i><b>(3)</b>
:<span class="predefined-constant">null</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 <a href="#_rgant-Column"><code>@Column#scale()</code></a> attribute must be …</td>
</tr>
<tr>
<td><i class="conum" data-value="2"></i><b>2</b></td>
<td>… consistent with <code>@Digits#fraction()</code></td>
</tr>
<tr>
<td><i class="conum" data-value="3"></i><b>3</b></td>
<td>the correct idiom when setting a new value is to normalized to the correct scale</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
<div class="sect1">
<h2 id="_rgant-Discriminator">9. <code>@Discriminator</code> (<code>javax.jdo</code>)</h2>
<button type="button" class="button secondary" onclick="window.location.href="https://github.com/apache/isis/edit/master/adocs/documentation/src/main/asciidoc/guides/_rgant-Discriminator.adoc"" style="float: right; font-size: small; padding: 6px; margin-top: -55px; "><i class="fa fa-pencil-square-o"></i> Edit</button>
<div class="sectionbody">
<div class="paragraph">
<p>The <code>@javax.jdo.annotation.Discriminator</code> is used by JDO/DataNucleus to specify how to discriminate between subclasses of an inheritance hierarchy.</p>
</div>
<div class="paragraph">
<p>It is valid to add a <code>@Discriminator</code> for any class, even those not part of an explicitly mapped inheritance hierarchy. Apache Isis also checks for this annotation, and if present will use the <code>@Discriminator#value()</code> as the object type, a unique alias for the object’s class name.</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>Isis parses the <code>@Discriminator</code> annotation from the Java source code; it does not query the JDO metamodel. This means that it the <code>@Discriminator</code> annotation must be used rather than the equivalent <code><discriminator></code> <a href="http://www.datanucleus.org/products/accessplatform_4_0/jdo/orm/inheritance.html">XML metadata</a>.</p>
</div>
<div class="paragraph">
<p>Moreover, while JDO/DataNucleus will recognize annotations on either the field or the getter method, Apache Isis (currently) only inspects the getter method. Therefore ensure that the annotation is placed there.</p>
</div> </td>
</tr>
</tbody>
</table>
</div>
<div class="paragraph">
<p>This value is used internally to generate a string representation of an objects identity (the <code>Oid</code>). This can appear in several contexts, including:</p>
</div>
<div class="ulist">
<ul>
<li> <p>as the value of <code>Bookmark#getObjectType()</code> and in the <code>toString()</code> value of <code>Bookmark</code> (see <a href="rgsvc.html#_rgsvc_api_BookmarkService"><code>BookmarkService</code></a>)</p>
<div class="ulist">
<ul>
<li> <p>and thus in the "table-of-two-halves" pattern, as per (non-ASF) <a href="http://github.com/isisaddons/isis-module-poly">Isis addons' poly</a> module</p> </li>
</ul>
</div> </li>
<li> <p>in the serialization of <code>OidDto</code> in the <a href="rgcms.html#_rgcms_schema-cmd">command</a> and <a href="rgcms.html#_rgcms_schema-ixn">interaction</a> schemas</p> </li>
<li> <p>in the URLs of the <a href="ugvro.html">RestfulObjects viewer</a></p> </li>
<li> <p>in the URLs of the <a href="ugvw.html">Wicket viewer</a> (in general and in particular if <a href="ugvw.html#_ugvw_features_hints-and-copy-url">copying URLs</a>)</p> </li>
<li> <p>in XML snapshots generated by the <a href="rgsvc.html#_rgsvc_api_XmlSnapshotService"><code>XmlSnapshotService</code></a></p> </li>
</ul>
</div>
<div class="sect2">
<h3 id="_examples_2">9.1. Examples</h3>
<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">@javax</span>.jdo.annotations.Discriminator(value=<span class="string"><span class="delimiter">"</span><span class="content">custmgmt.Customer</span><span class="delimiter">"</span></span>)
<span class="directive">public</span> <span class="type">class</span> <span class="class">Customer</span> {
...
}</code></pre>
</div>
</div>
<div class="paragraph">
<p>has an object type of <code>custmgmt.Customer</code>.</p>
</div>
</div>
<div class="sect2">
<h3 id="_precedence">9.2. Precedence</h3>
<div class="paragraph">
<p>The rules of precedence for determining a domain object’s object type are:</p>
</div>
<div class="olist arabic">
<ol class="arabic">
<li> <p><a href="#_rgant_Discriminator"><code>@Discriminator</code></a></p> </li>
<li> <p><code>@DomainObject#objectType</code></p> </li>
<li> <p><a href="#_rgant_PersistenceCapable"><code>@PersistenceCapable</code></a>, if at least the <code>schema</code> attribute is defined. <br></p>
<div class="paragraph">
<p>If both <code>schema</code> and <code>table</code> are defined, then the value is “schema.table�?. If only <code>schema</code> is defined, then the value is “schema.className�?.</p>
</div> </li>
<li> <p>Fully qualified class name of the entity.</p> </li>
</ol>
</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>This might be obvious, but to make explicit: we recommend that you always specify an object type for your domain objects.</p>
</div>
<div class="paragraph">
<p>Otherwise, if you refactor your code (change class name or move package), then any externally held references to the OID of the object will break. At best this will require a data migration in the database; at worst it could cause external clients accessing data through the <a href="ugvro.html">Restful Objects</a> viewer to break.</p>
</div> </td>
</tr>
</tbody>
</table>
</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>If the object type is not unique across all domain classes then the framework will fail-fast and fail to boot. An error message will be printed in the log to help you determine which classes have duplicate object tyoes.</p>
</div> </td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
</div>
<div class="sect1">
<h2 id="_rgant-DomainObject">10. <code>@DomainObject</code></h2>
<button type="button" class="button secondary" onclick="window.location.href="https://github.com/apache/isis/edit/master/adocs/documentation/src/main/asciidoc/guides/_rgant-DomainObject.adoc"" style="float: right; font-size: small; padding: 6px; margin-top: -55px; "><i class="fa fa-pencil-square-o"></i> Edit</button>
<div class="sectionbody">
<div class="paragraph">
<p>The <code>@DomainObject</code> annotation applies to domain objects, collecting together all domain semantics within a single annotation.</p>
</div>
<div class="paragraph">
<p>The table below summarizes the annotation’s attributes.</p>
</div>
<table class="tableblock frame-all grid-all spread">
<caption class="title">
Table 12.
<code>@DomainObject</code> attributes
</caption>
<colgroup>
<col style="width: 25%;">
<col style="width: 25%;">
<col style="width: 50%;">
</colgroup>
<thead>
<tr>
<th class="tableblock halign-left valign-top">Attribute</th>
<th class="tableblock halign-left valign-top">Values (default)</th>
<th class="tableblock halign-left valign-top">Description</th>
</tr>
</thead>
<tbody>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="#_rgant-DomainObject_auditing"><code>auditing()</code></a></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>AS_CONFIGURED</code>, <code>ENABLED</code>, <code>DISABLED</code><br> (<code>AS_CONFIGURED</code>)</p></td>
<td class="tableblock halign-left valign-top">
<div>
<div class="paragraph">
<p>indicates whether each of the changed properties of an object should be submitted to the registered <a href="rgsvc.html#_rgsvc_spi_AuditingService"><code>AuditingService</code></a> (deprecated) or (its replacement) <a href="rgsvc.html#_rgsvc_spi_AuditerService"><code>AuditerService</code></a></p>
</div>
</div></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="#_rgant-DomainObject_autoCompleteRepository"><code>autoCompleteRepository()</code></a></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Domain service class</p></td>
<td class="tableblock halign-left valign-top">
<div>
<div class="paragraph">
<p>nominate a method on a domain service to be used for looking up instances of the domain object</p>
</div>
</div></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>autoCompleteAction()</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Method name<br> (<code>autoComplete()</code>)</p></td>
<td class="tableblock halign-left valign-top">
<div>
<div class="paragraph">
<p>override the method name to use on the auto-complete repository</p>
</div>
</div></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="#_rgant-DomainObject_bounded"><code>bounded()</code></a></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>true</code>, <code>false</code><br> (<code>false</code>)</p></td>
<td class="tableblock halign-left valign-top">
<div>
<div class="paragraph">
<p>Whether the number of instances of this domain class is relatively small (a "bounded" set), such that instances could be selected from a drop-down list box or similar.</p>
</div>
</div></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="#_rgant-DomainObject_createdLifecycleEvent"><code>created-</code><br> <code>LifecycleEvent()</code></a></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">subtype of <code>ObjectCreatedEvent</code><br> (<code>ObjectCreatedEvent.Default</code>)</p></td>
<td class="tableblock halign-left valign-top">
<div>
<div class="paragraph">
<p>the event type to be posted to the <a href="rgsvc.html#_rgsvc_api_EventBusService"><code>EventBusService</code></a> whenever an instance is created</p>
</div>
</div></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="#_rgant-DomainObject_editing"><code>editing()</code></a></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>AS_CONFIGURED</code>, <code>ENABLED</code>, <code>DISABLED</code><br> (<code>AS_CONFIGURED</code>)</p></td>
<td class="tableblock halign-left valign-top">
<div>
<div class="paragraph">
<p>whether the object’s properties and collections can be edited or not (ie whether the instance should be considered to be immutable)</p>
</div>
</div></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="#_rgant-DomainObject_mixinMethod"><code>mixinMethod()</code></a></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Method name within the mixin</p></td>
<td class="tableblock halign-left valign-top">
<div>
<div class="paragraph">
<p>How to recognize the "reserved" method name, meaning that the mixin’s own name will be inferred from the mixin type. Typical examples are "exec", "execute", "invoke", "apply" and so on. The default "reserved" method name is <code>$$</code>.</p>
</div>
</div></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="#_rgant-DomainObject_nature"><code>nature()</code></a></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>NOT_SPECIFIED</code>, <code>JDO_ENTITY</code>, <code>EXTERNAL_ENTITY</code>, <code>INMEMORY_ENTITY</code>, <code>MIXIN</code>, <code>VIEW_MODEL</code> (<code>NOT_SPECIFIED</code>)</p></td>
<td class="tableblock halign-left valign-top">
<div>
<div class="paragraph">
<p>whether the domain object logically is an entity (part of the domain layer) or is a view model (part of the application layer); or is a mixin. If an entity, indicates how its persistence is managed.</p>
</div>
</div></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="#_rgant-DomainObject_objectType"><code>objectType()</code></a></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">(none, which implies fully qualified class name)</p></td>
<td class="tableblock halign-left valign-top">
<div>
<div class="paragraph">
<p>specify an alias for the domain class used to uniquely identify the object both within the Apache Isis runtime and externally</p>
</div>
</div></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="#_rgant-DomainObject_persistedLifecycleEvent"><code>persisted-</code><br> <code>LifecycleEvent()</code></a></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">subtype of <code>ObjectPersistedEvent</code><br> (<code>ObjectPersistedEvent.Default</code>)</p></td>
<td class="tableblock halign-left valign-top">
<div>
<div class="paragraph">
<p>the event type to be posted to the <a href="rgsvc.html#_rgsvc_api_EventBusService"><code>EventBusService</code></a> whenever an instance has just been persisted</p>
</div>
</div></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="#_rgant-DomainObject_persistingLifecycleEvent"><code>persisting-</code><br> <code>LifecycleEvent()</code></a></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">subtype of <code>ObjectPersistingEvent</code><br> (<code>ObjectPersistingEvent.Default</code>)</p></td>
<td class="tableblock halign-left valign-top">
<div>
<div class="paragraph">
<p>the event type to be posted to the <a href="rgsvc.html#_rgsvc_api_EventBusService"><code>EventBusService</code></a> whenever an instance is about to be persisted</p>
</div>
</div></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="#_rgant-DomainObject_publishing"><code>publishing()</code></a></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>AS_CONFIGURED</code>, <code>ENABLED</code>, <code>DISABLED</code><br> (<code>AS_CONFIGURED</code>)</p></td>
<td class="tableblock halign-left valign-top">
<div>
<div class="paragraph">
<p>whether changes to the object should be published to the registered <a href="rgsvc.html#_rgsvc_spi_PublishingService"><code>PublishingService</code></a>.</p>
</div>
</div></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>publishing-</code><br> <code>PayloadFactory()</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">subtype of <code>PublishingPayloadFactory-</code> <code>ForObject</code> (none)</p></td>
<td class="tableblock halign-left valign-top">
<div>
<div class="paragraph">
<p>specifies that a custom implementation of <code>PublishingPayloadFactoryForObject</code> be used to create the (payload of the) published event representing the change to the object</p>
</div>
</div></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="#_rgant-DomainObject_removingLifecycleEvent"><code>removing-</code><br> <code>LifecycleEvent()</code></a></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">subtype of <code>ObjectRemovingEvent</code><br> (<code>ObjectRemovingEvent.Default</code>)</p></td>
<td class="tableblock halign-left valign-top">
<div>
<div class="paragraph">
<p>the event type to be posted to the <a href="rgsvc.html#_rgsvc_api_EventBusService"><code>EventBusService</code></a> whenever an instance is about to be deleted</p>
</div>
</div></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="#_rgant-DomainObject_updatedLifecycleEvent"><code>updated-</code><br> <code>LifecycleEvent()</code></a></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">subtype of <code>ObjectUpdatedEvent</code><br> (<code>ObjectUpdatedEvent.Default</code>)</p></td>
<td class="tableblock halign-left valign-top">
<div>
<div class="paragraph">
<p>the event type to be posted to the <a href="rgsvc.html#_rgsvc_api_EventBusService"><code>EventBusService</code></a> whenever an instance has just been updated</p>
</div>
</div></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="#_rgant-DomainObject_updatingLifecycleEvent"><code>updating-</code><br> <code>LifecycleEvent()</code></a></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">subtype of <code>ObjectUpdatingEvent</code><br> (<code>ObjectUpdatingEvent.Default</code>)</p></td>
<td class="tableblock halign-left valign-top">
<div>
<div class="paragraph">
<p>the event type to be posted to the <a href="rgsvc.html#_rgsvc_api_EventBusService"><code>EventBusService</code></a> whenever an instance is about to be updated</p>
</div>
</div></td>
</tr>
</tbody>
</table>
<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">@DomainObject</span>(
auditing=Auditing.ENABLED,
autoCompleteRepository=CustomerRepository.class
editing=Editing.ENABLED, <i class="conum" data-value="1"></i><b>(1)</b>
updatedLifecycleEvent=Customer.UpdatedEvent.class
)
<span class="directive">public</span> <span class="type">class</span> <span class="class">Customer</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>default value, so could be omitted</td>
</tr>
</tbody>
</table>
</div>
<div class="sect2">
<h3 id="_rgant-DomainObject_auditing">10.1. <code>auditing()</code></h3>
<button type="button" class="button secondary" onclick="window.location.href="https://github.com/apache/isis/edit/master/adocs/documentation/src/main/asciidoc/guides/_rgant-DomainObject_auditing.adoc"" style="float: right; font-size: small; padding: 6px; margin-top: -55px; "><i class="fa fa-pencil-square-o"></i> Edit</button>
<div class="paragraph">
<p>The <code>auditing()</code> attribute indicates that if the object is modified, then each of its changed properties should be submitted to the <a href="rgsvc.html#_rgsvc_spi_AuditingService"><code>AuditingService</code></a> (if one has been configured), or to any</p>
</div>
<div class="paragraph">
<p>The default value for the attribute is <code>AS_CONFIGURED</code>, meaning that the <a href="rgcfg.html#_rgcfg_configuring-core">configuration property</a> <code>isis.services.audit.objects</code> is used to determine the whether the action is audited:</p>
</div>
<div class="ulist">
<ul>
<li> <p><code>all</code><br></p>
<div class="paragraph">
<p>all changed properties of objects are audited</p>
</div> </li>
<li> <p><code>none</code><br></p>
<div class="paragraph">
<p>no changed properties of objects are audited</p>
</div> </li>
</ul>
</div>
<div class="paragraph">
<p>If there is no configuration property in <code>isis.properties</code> then auditing is automatically enabled for domain objects.</p>
</div>
<div class="paragraph">
<p>This default can be overridden on an object-by-object basis; if <code>auditing()</code> is set to <code>ENABLED</code> then changed properties of instances of the domain class are audited irrespective of the configured value; if set to <code>DISABLED</code> then the changed properties of instances are <em>not</em> audited, again irrespective of the configured value.</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">@DomainObject</span>(
auditing=Auditing.ENABLED <i class="conum" data-value="1"></i><b>(1)</b>
)
<span class="directive">public</span> <span class="type">class</span> <span class="class">Customer</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>because set to enabled, will be audited irrespective of the configured value.</td>
</tr>
</tbody>
</table>
</div>
</div>
<div class="sect2">
<h3 id="_rgant-DomainObject_autoCompleteRepository">10.2. <code>autoCompleteRepository()</code></h3>
<button type="button" class="button secondary" onclick="window.location.href="https://github.com/apache/isis/edit/master/adocs/documentation/src/main/asciidoc/guides/_rgant-DomainObject_autoCompleteRepository.adoc"" style="float: right; font-size: small; padding: 6px; margin-top: -55px; "><i class="fa fa-pencil-square-o"></i> Edit</button>
<div class="paragraph">
<p>The <code>autoCompleteRepository()</code> attribute nominates a single method on a domain service as the fallback means for looking up instances of the domain object using a simple string.</p>
</div>
<div class="paragraph">
<p>For example, this might search for a customer by their name or number. Or it could search for a country based on its ISO-3 code or user-friendly name.</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>If you require additional control - for example restricting the returned results based on the object being interacted with - then use the <a href="rgcms.html#_rgcms_methods_prefixes_autoComplete"><code>autoComplete…()</code></a> supporting method instead.</p>
</div> </td>
</tr>
</tbody>
</table>
</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">@DomainObject</span>(
autoCompleteRepository=CustomerRepository.class
)
<span class="directive">public</span> <span class="type">class</span> <span class="class">Customer</span> {
....
}</code></pre>
</div>
</div>
<div class="paragraph">
<p>where:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code data-lang="java"><span class="annotation">@DomainService</span>
<span class="directive">public</span> <span class="type">class</span> <span class="class">CustomerRepository</span> {
<span class="predefined-type">List</span><Customer> autoComplete(<span class="predefined-type">String</span> search); <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>is assumed to be called "autoComplete", and accepts a single string</td>
</tr>
</tbody>
</table>
</div>
<div class="sect3">
<h4 id="__code_autocompleteaction_code">10.2.1. <code>autoCompleteAction()</code></h4>
<div class="paragraph">
<p>As noted above, by default the method invoked on the repository is assumed to be called "autoComplete". The optional <code>autoCompleteAction()</code> attribute allows the method on the repository to be overridden.</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">@DomainObject</span>(
autoCompleteRepository=Customers.class,
autoCompleteAction=<span class="string"><span class="delimiter">"</span><span class="content">findByName</span><span class="delimiter">"</span></span>
)
<span class="directive">public</span> <span class="type">class</span> <span class="class">Customer</span> {
....
}</code></pre>
</div>
</div>
<div class="paragraph">
<p>where in this case <code>findByName</code> might be an existing action already defined:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code data-lang="java"><span class="annotation">@DomainService</span>(natureOfService=VIEW_MENU_ONLY)
<span class="directive">public</span> <span class="type">class</span> <span class="class">Customers</span> {
<span class="annotation">@Action</span>(semantics=SemanticsOf.SAFE)
<span class="directive">public</span> <span class="predefined-type">List</span><Customer> findByName(
<span class="annotation">@Parameter</span>(minLength=<span class="integer">3</span>) <i class="conum" data-value="1"></i><b>(1)</b>
<span class="annotation">@ParameterLayout</span>(named=<span class="string"><span class="delimiter">"</span><span class="content">name</span><span class="delimiter">"</span></span>)
<span class="predefined-type">String</span> name);
...
}</code></pre>
</div>
</div>
<div class="colist arabic">
<table>
<tbody>
<tr>
<td><i class="conum" data-value="1"></i><b>1</b></td>
<td>end-user must enter minimum number of characters to trigger the query</td>
</tr>
</tbody>
</table>
</div>
<div class="paragraph">
<p>The autocomplete action can also be a regular method, annotated using <a href="#_rgant_Programmatic"><code>@Programmatic</code></a>:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code data-lang="java"><span class="annotation">@DomainService</span>(natureOfService=VIEW_MENU_ONLY)
<span class="directive">public</span> <span class="type">class</span> <span class="class">Customers</span> {
<span class="annotation">@Programmatic</span>
<span class="directive">public</span> <span class="predefined-type">List</span><Customer> findByName(
<span class="annotation">@Parameter</span>(minLength=<span class="integer">3</span>)
<span class="predefined-type">String</span> name);
...
}</code></pre>
</div>
</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>The method specified must be an action, that is, part of the Isis metamodel. Said another way: it must not be annotated with <a href="#_rgant-Programmatic"><code>@Programmatic</code></a>. However, it <strong>can</strong> be hidden or placed on a domain service with <a href="#_rgant-DomainService_nature">nature</a> of <code>DOMAIN</code>, such that the action would not be rendered otherwise in the UI. Also, the action cannot be <a href="#_rgant-Action_restrictTo">restricted to</a> prototyping only.</p>
</div> </td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
<div class="sect2">
<h3 id="_rgant-DomainObject_bounded">10.3. <code>bounded()</code></h3>
<button type="button" class="button secondary" onclick="window.location.href="https://github.com/apache/isis/edit/master/adocs/documentation/src/main/asciidoc/guides/_rgant-DomainObject_bounded.adoc"" style="float: right; font-size: small; padding: 6px; margin-top: -55px; "><i class="fa fa-pencil-square-o"></i> Edit</button>
<div class="paragraph">
<p>Some domain classes are immutable to the user, and moreover have only a fixed number of instances. Often these are "reference" ("standing") data, or lookup data/pick lists. Typical examples could include categories, countries, states, and tax or interest rate tables.</p>
</div>
<div class="paragraph">
<p>Where the number of instances is relatively small, ie bounded, then the <code>bounded()</code> attribute can be used as a hint. For such domain objects the framework will automatically allow instances to be selected; <a href="ugvw.html">Wicket viewer</a> displays these as a drop-down list.</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">@DomainObject</span>(
bounded=<span class="predefined-constant">true</span>,
editing=Editing.DISABLED <i class="conum" data-value="1"></i><b>(1)</b>
)
<span class="directive">public</span> <span class="type">class</span> <span class="class">Currency</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>This attribute is commonly combined with <code>editing=DISABLED</code> to enforce the fact that reference data is immutable</td>
</tr>
</tbody>
</table>
</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>There is nothing to prevent you from using this attribute for regular mutable entities, and indeed this is sometimes worth doing during early prototyping. However, if there is no realistic upper bound to the number of instances of an entity that might be created, generally you should use <a href="rgcms.html#_rgcms_methods_prefixes_autoComplete"><code>autoComplete…()</code></a> supporting method or the <a href="#_rgant-DomainObject_autoCompleteRepository"><code>@DomainObject#autoCompleteRepository()</code></a> attribute instead.</p>
</div> </td>
</tr>
</tbody>
</table>
</div>
</div>
<div class="sect2">
<h3 id="_rgant-DomainObject_createdLifecycleEvent">10.4. createdLifecycleEvent()</h3>
<button type="button" class="button secondary" onclick="window.location.href="https://github.com/apache/isis/edit/master/adocs/documentation/src/main/asciidoc/guides/_rgant-DomainObject_createdLifecycleEvent.adoc"" style="float: right; font-size: small; padding: 6px; margin-top: -55px; "><i class="fa fa-pencil-square-o"></i> Edit</button>
<div class="paragraph">
<p>Whenever a domain object is instantiated or otherwise becomes known to the framework, a "created" lifecycle event is fired. This is typically when the <a href="rgsvc.html#_rgsvc_api_DomainObjectContainer"><code>DomainObjectContainer</code></a>'s <a href="rgsvc.html#_rgsvc_api_DomainObjectContainer_object-creation-api"><code>newTransientInstance()</code></a> is called; it will also happen if the object is simply instantiated with <code>new(…)</code>, and then the container’s <a href="rgsvc.html#_rgsvc_api_DomainObjectContainer_services-api"><code>injectServicesInto(…)</code></a> method is called.</p>
</div>
<div class="paragraph">
<p>Subscribers subscribe through the <a href="rgsvc.html#_rgsvc_api_EventBusService"><code>EventBusService</code></a> and can use the event to obtain a reference to the object just created. The subscriber could then, for example, update the object, eg looking up state from some external datastore.</p>
</div>
<div class="paragraph">
<p>By default the event raised is <code>ObjectCreatedEvent.Default</code>. For example:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code data-lang="java"><span class="annotation">@DomainObject</span>
<span class="directive">public</span> <span class="type">class</span> <span class="class">ToDoItemDto</span> {
...
}</code></pre>
</div>
</div>
<div class="paragraph">
<p>The purpose of the <code>createdLifecycleEvent()</code> attribute is to allows a custom subclass to be emitted instead. A similar attribute is available for other lifecycle events.</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">@DomainObjectLayout</span>(
createdLifecycleEvent=ToDoItem.CreatedEvent.class
)
<span class="directive">public</span> <span class="type">class</span> <span class="class">ToDoItem</span> {
<span class="directive">public</span> <span class="directive">static</span> <span class="type">class</span> <span class="class">CreatedEvent</span>
<span class="directive">extends</span> org.apache.isis.applib.services.eventbus.ObjectCreatedEvent<ToDoItem> { }
...
}</code></pre>
</div>
</div>
<div class="paragraph">
<p>The benefit is that subscribers can be more targeted as to the events that they subscribe to.</p>
</div>
<div class="sect3">
<h4 id="_subscribers_3">10.4.1. Subscribers</h4>
<div class="paragraph">
<p>Subscribers (which must be domain services) subscribe using either the <a href="https://github.com/google/guava">Guava</a> API or (if the <a href="rgsvc.html#_rgsvc_api_EventBusService"><code>EventBusService</code></a> has been appropriately configured) using the <a href="http://www.axonframework.org/">Axon Framework</a> API. The examples below use the Guava API.</p>
</div>
<div class="paragraph">
<p>Subscribers can be either coarse-grained (if they subscribe to the top-level event type):</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code data-lang="java"><span class="annotation">@DomainService</span>(nature=NatureOfService.DOMAIN)
<span class="directive">public</span> <span class="type">class</span> <span class="class">SomeSubscriber</span> <span class="directive">extends</span> AbstractSubscriber {
<span class="annotation">@com</span>.google.common.eventbus.Subscribe
<span class="directive">public</span> <span class="type">void</span> on(ObjectCreatedEvent ev) {
<span class="keyword">if</span>(ev.getSource() <span class="keyword">instanceof</span> ToDoItem) { ... }
}
}</code></pre>
</div>
</div>
<div class="paragraph">
<p>or can be fine-grained (by subscribing to specific event subtypes):</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code data-lang="java"><span class="annotation">@DomainService</span>(nature=NatureOfService.DOMAIN)
<span class="directive">public</span> <span class="type">class</span> <span class="class">SomeSubscriber</span> <span class="directive">extends</span> AbstractSubscriber {
<span class="annotation">@com</span>.google.common.eventbus.Subscribe
<span class="directive">public</span> <span class="type">void</span> on(ToDoItem.ObjectCreatedEvent ev) {
...
}
}</code></pre>
</div>
</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>If the AxonFramework is being used, replace <code>@com.google.common.eventbus.Subscribe</code> with <code>@org.axonframework.eventhandling.annotation.EventHandler</code>.</p>
</div> </td>
</tr>
</tbody>
</table>
</div>
</div>
<div class="sect3">
<h4 id="_default_doop_and_noop_events_3">10.4.2. Default, Doop and Noop events</h4>
<div class="paragraph">
<p>If the <code>createdLifecycleEvent</code> attribute is not explicitly specified (is left as its default value, <code>ObjectCreatedEvent.Default</code>), then the framework will, by default, post an event.</p>
</div>
<div class="paragraph">
<p>If this is not required, then the <code>isis.reflector.facet.domainObjectAnnotation.createdLifecycleEvent.postForDefault</code> configuration property can be set to "false"; this will disable posting.</p>
</div>
<div class="paragraph">
<p>On the other hand, if the <code>createdLifecycleEvent</code> has been explicitly specified to some subclass, then an event will be posted. The framework provides <code>ObjectCreatedEvent.Doop</code> as such a subclass, so setting the <code>createdLifecycleEvent</code> attribute to this class will ensure that the event to be posted, irrespective of the configuration property setting.</p>
</div>
<div class="paragraph">
<p>And, conversely, the framework also provides <code>ObjectCreatedEvent.Noop</code>; if <code>createdLifecycleEvent</code> attribute is set to this class, then no event will be posted.</p>
</div>
</div>
</div>
<div class="sect2">
<h3 id="_rgant-DomainObject_editing">10.5. <code>editing()</code></h3>
<button type="button" class="button secondary" onclick="window.location.href="https://github.com/apache/isis/edit/master/adocs/documentation/src/main/asciidoc/guides/_rgant-DomainObject_editing.adoc"" style="float: right; font-size: small; padding: 6px; margin-top: -55px; "><i class="fa fa-pencil-square-o"></i> Edit</button>
<div class="paragraph">
<p>The <code>editing()</code> attribute determines whether a domain object’s properties and collections are not editable (are read-only).</p>
</div>
<div class="paragraph">
<p>The default is <code>AS_CONFIGURED</code>, meaning that the <a href="rgcfg.html#_rgcfg_configuring-core">configuration property</a> <code>isis.objects.editing</code> is used to determine the whether the object is modifiable:</p>
</div>
<div class="ulist">
<ul>
<li> <p><code>true</code><br></p>
<div class="paragraph">
<p>the object’s properties and collections are modifiable.</p>
</div> </li>
<li> <p><code>false</code><br></p>
<div class="paragraph">
<p>the object’s properties and collections are read-only, ie <em>not</em> modifiable.</p>
</div> </li>
</ul>
</div>
<div class="paragraph">
<p>If there is no configuration property in <code>isis.properties</code> then object are assumed to be modifiable.</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>In other words, editing can be disabled globally for an application by setting:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code data-lang="ini">isis.objects.editing=false</code></pre>
</div>
</div>
<div class="paragraph">
<p>We recommend enabling this feature; it will help drive out the underlying business operations (processes and procedures) that require objects to change; these can then be captured as business actions.</p>
</div> </td>
</tr>
</tbody>
</table>
</div>
<div class="paragraph">
<p>The related <code>editingDisabledReason()</code> attribute specifies the a hard-coded reason why the object’s properties and collections cannot be modified directly.</p>
</div>
<div class="paragraph">
<p>This default can be overridden on an object-by-object basis; if <code>editing()</code> is set to <code>ENABLED</code> then the object’s properties and collections are editable irrespective of the configured value; if set to <code>DISABLED</code> then the object’s properties and collections are not editable irrespective of the configured value.</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">@DomainObject</span>(
editing=Editing.DISABLED,
editingDisabledReason=<span class="string"><span class="delimiter">"</span><span class="content">Reference data, so cannot be modified</span><span class="delimiter">"</span></span>
)
<span class="directive">public</span> <span class="type">class</span> <span class="class">Country</span> {
...
}</code></pre>
</div>
</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>Another interesting example of immutable reference data is to define an entity to represent individual dates; after all, for a system with an expected lifetime of 20 years that equates to only 7,300 days, a comparatively tiny number of rows to hold in a database.</p>
</div> </td>
</tr>
</tbody>
</table>
</div>
</div>
<div class="sect2">
<h3 id="_rgant-DomainObject_loadedLifecycleEvent">10.6. loadedLifecycleEvent()</h3>
<button type="button" class="button secondary" onclick="window.location.href="https://github.com/apache/isis/edit/master/adocs/documentation/src/main/asciidoc/guides/_rgant-DomainObject_loadedLifecycleEvent.adoc"" style="float: right; font-size: small; padding: 6px; margin-top: -55px; "><i class="fa fa-pencil-square-o"></i> Edit</button>
<div class="paragraph">
<p>Whenever a persistent domain object is loaded from the database, a "loaded" lifecycle event is fired.</p>
</div>
<div class="paragraph">
<p>Subscribers subscribe through the <a href="rgsvc.html#_rgsvc_api_EventBusService"><code>EventBusService</code></a> and can use the event to obtain a reference to the domain object just loaded. The subscriber could then, for example, update or default values on the object (eg to support on-the-fly migration scenarios).</p>
</div>
<div class="paragraph">
<p>By default the event raised is <code>ObjectLoadedEvent.Default</code>. For example:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code data-lang="java"><span class="annotation">@DomainObject</span>
<span class="directive">public</span> <span class="type">class</span> <span class="class">ToDoItemDto</span> {
...
}</code></pre>
</div>
</div>
<div class="paragraph">
<p>The purpose of the <code>loadedLifecycleEvent()</code> attribute is to allows a custom subclass to be emitted instead. A similar attribute is available for other lifecycle events.</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">@DomainObjectLayout</span>(
loadedLifecycleEvent=ToDoItem.LoadedEvent.class
)
<span class="directive">public</span> <span class="type">class</span> <span class="class">ToDoItem</span> {
<span class="directive">public</span> <span class="directive">static</span> <span class="type">class</span> <span class="class">LoadedEvent</span>
<span class="directive">extends</span> org.apache.isis.applib.services.eventbus.ObjectLoadedEvent<ToDoItem> { }
...
}</code></pre>
</div>
</div>
<div class="paragraph">
<p>The benefit is that subscribers can be more targeted as to the events that they subscribe to.</p>
</div>
<div class="sect3">
<h4 id="_subscribers_4">10.6.1. Subscribers</h4>
<div class="paragraph">
<p>Subscribers (which must be domain services) subscribe using either the <a href="https://github.com/google/guava">Guava</a> API or (if the <a href="rgsvc.html#_rgsvc_api_EventBusService"><code>EventBusService</code></a> has been appropriately configured) using the <a href="http://www.axonframework.org/">Axon Framework</a> API. The examples below use the Guava API.</p>
</div>
<div class="paragraph">
<p>Subscribers can be either coarse-grained (if they subscribe to the top-level event type):</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code data-lang="java"><span class="annotation">@DomainService</span>(nature=NatureOfService.DOMAIN)
<span class="directive">public</span> <span class="type">class</span> <span class="class">SomeSubscriber</span> <span class="directive">extends</span> AbstractSubscriber {
<span class="annotation">@com</span>.google.common.eventbus.Subscribe
<span class="directive">public</span> <span class="type">void</span> on(ObjectLoadedEvent ev) {
<span class="keyword">if</span>(ev.getSource() <span class="keyword">instanceof</span> ToDoItem) { ... }
}
}</code></pre>
</div>
</div>
<div class="paragraph">
<p>or can be fine-grained (by subscribing to specific event subtypes):</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code data-lang="java"><span class="annotation">@DomainService</span>(nature=NatureOfService.DOMAIN)
<span class="directive">public</span> <span class="type">class</span> <span class="class">SomeSubscriber</span> <span class="directive">extends</span> AbstractSubscriber {
<span class="annotation">@com</span>.google.common.eventbus.Subscribe
<span class="directive">public</span> <span class="type">void</span> on(ToDoItem.ObjectLoadedEvent ev) {
...
}
}</code></pre>
</div>
</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>If the AxonFramework is being used, replace <code>@com.google.common.eventbus.Subscribe</code> with <code>@org.axonframework.eventhandling.annotation.EventHandler</code>.</p>
</div> </td>
</tr>
</tbody>
</table>
</div>
</div>
<div class="sect3">
<h4 id="_default_doop_and_noop_events_4">10.6.2. Default, Doop and Noop events</h4>
<div class="paragraph">
<p>If the <code>loadedLifecycleEvent</code> attribute is not explicitly specified (is left as its default value, <code>ObjectLoadedEvent.Default</code>), then the framework will, by default, post an event.</p>
</div>
<div class="paragraph">
<p>If this is not required, then the <code>isis.reflector.facet.domainObjectAnnotation.loadedLifecycleEvent.postForDefault</code> configuration property can be set to "false"; this will disable posting.</p>
</div>
<div class="paragraph">
<p>On the other hand, if the <code>loadedLifecycleEvent</code> has been explicitly specified to some subclass, then an event will be posted. The framework provides <code>ObjectLoadedEvent.Doop</code> as such a subclass, so setting the <code>loadedLifecycleEvent</code> attribute to this class will ensure that the event to be posted, irrespective of the configuration property setting.</p>
</div>
<div class="paragraph">
<p>And, conversely, the framework also provides <code>ObjectLoadedEvent.Noop</code>; if <code>loadedLifecycleEvent</code> attribute is set to this class, then no event will be posted.</p>
</div>
</div>
</div>
<div class="sect2">
<h3 id="_rgant-DomainObject_mixinMethod">10.7. <code>mixinMethod()</code></h3>
<button type="button" class="button secondary" onclick="window.location.href="https://github.com/apache/isis/edit/master/adocs/documentation/src/main/asciidoc/guides/_rgant-DomainObject_mixinMethod.adoc"" style="float: right; font-size: small; padding: 6px; margin-top: -55px; "><i class="fa fa-pencil-square-o"></i> Edit</button>
<div class="paragraph">
<p>The <code>mixinMethod()</code> attribute specifies the name of the method to be treated as a "reserved" method name, meaning that the mixin’s name should instead be inferred from the mixin’s type.</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">@DomainObject</span>
<span class="directive">public</span> <span class="type">class</span> <span class="class">Customer</span> {
<span class="annotation">@DomainObject</span>(nature=Nature.MIXIN, mixinMethod=<span class="string"><span class="delimiter">"</span><span class="content">execute</span><span class="delimiter">"</span></span>)
<span class="directive">public</span> <span class="directive">static</span> <span class="type">class</span> <span class="class">placeOrder</span> {
Customer customer;
<span class="directive">public</span> placeOrder(Customer customer) { <span class="local-variable">this</span>.customer = customer; }
<span class="directive">public</span> Customer execute(Product p, <span class="type">int</span> quantity) { ... }
<span class="directive">public</span> <span class="predefined-type">String</span> disableExecute() { ... }
<span class="directive">public</span> <span class="predefined-type">String</span> validate0Execute() { ... }
}
...
)</code></pre>
</div>
</div>
<div class="paragraph">
<p>This allows all mixins to follow a similar convention, with the name of the mixin inferred entirely from its type ("placeOrder").</p>
</div>
<div class="paragraph">
<p>When invoked programmatically, the code reads:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code data-lang="java">mixin(Customer.placeOrder.class, someCustomer).execute(someProduct, <span class="integer">3</span>);</code></pre>
</div>
</div>
</div>
<div class="sect2">
<h3 id="_rgant-DomainObject_nature">10.8. <code>nature()</code></h3>
<button type="button" class="button secondary" onclick="window.location.href="https://github.com/apache/isis/edit/master/adocs/documentation/src/main/asciidoc/guides/_rgant-DomainObject_nature.adoc"" style="float: right; font-size: small; padding: 6px; margin-top: -55px; "><i class="fa fa-pencil-square-o"></i> Edit</button>
<div class="paragraph">
<p>The <code>nature()</code> attribute is used to characterize the domain object as either an entity (part of the domain layer) or as a view model (part of the application layer). If the domain object should be thought of as an entity, it also captures how the persistence of that entity is managed.</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">@DomainObject</span>(nature=Nature.VIEW_MODEL)
<span class="directive">public</span> <span class="type">class</span> <span class="class">PieChartAnalysis</span> {
...
}</code></pre>
</div>
</div>
<div class="paragraph">
<p>Specifically, the nature must be one of:</p>
</div>
<div class="ulist">
<ul>
<li> <p><code>NOT_SPECIFIED,</code><br></p>
<div class="paragraph">
<p>(the default); specifies no paricular semantics for the domain class.</p>
</div> </li>
<li> <p><code>JDO_ENTITY</code><br></p>
<div class="paragraph">
<p>indicates that the domain object is an entity whose persistence is managed internally by Apache Isis, using the JDO/DataNucleus objectstore.</p>
</div> </li>
<li> <p><code>EXTERNAL_ENTITY</code><br></p>
<div class="paragraph">
<p>indicates that the domain objecct is a wrapper/proxy/stub (choose your term) to an entity that is managed by some related external system. For example, the domain object may hold just the URI to a RESTful resource of some third party REST service, or the id of some system accessible over SOAP.<br></p>
</div>
<div class="paragraph">
<p>The identity of an external entity is determined solely by the state of entity’s properties. The framework will automatically recreate the domain object each time it is interacted with.</p>
</div> </li>
<li> <p><code>INMEMORY_ENTITY</code><br></p>
<div class="paragraph">
<p>indicates that the domain object is a wrapper/proxy/stub to a "synthetic" entity, for example one that is constructed from some sort of internal memory data structure.<br></p>
</div>
<div class="paragraph">
<p>The identity of an inmemory entity is determined solely by the state of entity’s properties. The framework will automatically recreate the domain object each time it is interacted with.</p>
</div> </li>
<li> <p><code>MIXIN</code><br></p>
<div class="paragraph">
<p>indicates that the domain object is part of the domain layer, and is contributing behaviour to objects of some other type as a mixin (also known as a trait).</p>
</div> </li>
</ul>
</div>
<div class="paragraph">
<p>Equivalent to annotating with <a href="#_rgant-Mixin"><code>@Mixin</code></a>. For further discussion on using mixins, see <a href="ugbtb.html#_ugbtb_decoupling_mixins">mixins</a> in the user guide.</p>
</div>
<div class="ulist">
<ul>
<li> <p><code>VIEW_MODEL</code><br></p>
<div class="paragraph">
<p>indicates that the domain object is conceptually part of the application layer, and exists to surfaces behaviour and/or state that is aggregate of one or more domain entities.</p>
</div> </li>
</ul>
</div>
<div class="paragraph">
<p>The identity of an inmemory entity is determined solely by the state of entity’s properties. The framework will automatically recreate the domain object each time it is interacted with.</p>
</div>
<div class="paragraph">
<p>Those natures that indicate the domain object is an entity (of some sort or another) mean then that the domain object is considered to be part of the domain model layer. As such the domain object’s class cannot be annotated with <a href="#_rgant-ViewModel"><code>@ViewModel</code></a> or implement the <a href="rgcms.html#_rgcms_classes_super_ViewModel"><code>ViewModel</code></a> interface.</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>Under the covers Apache Isis' support for <code>VIEW_MODEL</code>, <code>EXTERNAL_ENTITY</code> and <code>INMEMORY_ENTITY</code> domain objects is identical; the state of the object is encoded into its internal OID (represented ultimately as its URL), and is recreated directly from that URL.</p>
</div>
<div class="paragraph">
<p>Because this particular implementation was originally added to Apache Isis in support of view models, the term was also used for the logically different external entities and inmemory entities.</p>
</div>
<div class="paragraph">
<p>The benefit of <code>nature()</code> is that it allows the developer to properly characterize the layer (domain vs application) that an entity lives, thus avoiding confusion as "view model" (the implementation technique) and "view model" (the application layer concept).</p>
</div> </td>
</tr>
</tbody>
</table>
</div>
</div>
<div class="sect2">
<h3 id="_rgant-DomainObject_persistedLifecycleEvent">10.9. persistedLifecycleEvent()</h3>
<button type="button" class="button secondary" onclick="window.location.href="https://github.com/apache/isis/edit/master/adocs/documentation/src/main/asciidoc/guides/_rgant-DomainObject_persistedLifecycleEvent.adoc"" style="float: right; font-size: small; padding: 6px; margin-top: -55px; "><i class="fa fa-pencil-square-o"></i> Edit</button>
<div class="paragraph">
<p>Whenever a (just created, still transient) domain object has been saved (INSERTed in)to the database, a "persisted" lifecycle event is fired.</p>
</div>
<div class="paragraph">
<p>Subscribers subscribe through the <a href="rgsvc.html#_rgsvc_api_EventBusService"><code>EventBusService</code></a> and can use the event to obtain a reference to the domain object. The subscriber could then, for example, maintain an external datastore.</p>
</div>
<div class="admonitionblock warning">
<table>
<tbody>
<tr>
<td class="icon"> <i class="fa icon-warning" title="Warning"></i> </td>
<td class="content">
<div class="paragraph">
<p>The object should <em>not</em> be modified during the persisted callback.</p>
</div> </td>
</tr>
</tbody>
</table>
</div>
<div class="paragraph">
<p>By default the event raised is <code>ObjectPersistedEvent.Default</code>. For example:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code data-lang="java"><span class="annotation">@DomainObject</span>
<span class="directive">public</span> <span class="type">class</span> <span class="class">ToDoItemDto</span> {
...
}</code></pre>
</div>
</div>
<div class="paragraph">
<p>The purpose of the <code>persistedLifecycleEvent()</code> attribute is to allows a custom subclass to be emitted instead. A similar attribute is available for other lifecycle events.</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">@DomainObjectLayout</span>(
persistedLifecycleEvent=ToDoItem.PersistedEvent.class
)
<span class="directive">public</span> <span class="type">class</span> <span class="class">ToDoItem</span> {
<span class="directive">public</span> <span class="directive">static</span> <span class="type">class</span> <span class="class">PersistedEvent</span>
<span class="directive">extends</span> org.apache.isis.applib.services.eventbus.ObjectPersistedEvent<ToDoItem> { }
...
}</code></pre>
</div>
</div>
<div class="paragraph">
<p>The benefit is that subscribers can be more targeted as to the events that they subscribe to.</p>
</div>
<div class="sect3">
<h4 id="_subscribers_5">10.9.1. Subscribers</h4>
<div class="paragraph">
<p>Subscribers (which must be domain services) subscribe using either the <a href="https://github.com/google/guava">Guava</a> API or (if the <a href="rgsvc.html#_rgsvc_api_EventBusService"><code>EventBusService</code></a> has been appropriately configured) using the <a href="http://www.axonframework.org/">Axon Framework</a> API. The examples below use the Guava API.</p>
</div>
<div class="paragraph">
<p>Subscribers can be either coarse-grained (if they subscribe to the top-level event type):</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code data-lang="java"><span class="annotation">@DomainService</span>(nature=NatureOfService.DOMAIN)
<span class="directive">public</span> <span class="type">class</span> <span class="class">SomeSubscriber</span> <span class="directive">extends</span> AbstractSubscriber {
<span class="annotation">@com</span>.google.common.eventbus.Subscribe
<span class="directive">public</span> <span class="type">void</span> on(ObjectPersistedEvent ev) {
<span class="keyword">if</span>(ev.getSource() <span class="keyword">instanceof</span> ToDoItem) { ... }
}
}</code></pre>
</div>
</div>
<div class="paragraph">
<p>or can be fine-grained (by subscribing to specific event subtypes):</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code data-lang="java"><span class="annotation">@DomainService</span>(nature=NatureOfService.DOMAIN)
<span class="directive">public</span> <span class="type">class</span> <span class="class">SomeSubscriber</span> <span class="directive">extends</span> AbstractSubscriber {
<span class="annotation">@com</span>.google.common.eventbus.Subscribe
<span class="directive">public</span> <span class="type">void</span> on(ToDoItem.ObjectPersistedEvent ev) {
...
}
}</code></pre>
</div>
</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>If the AxonFramework is being used, replace <code>@com.google.common.eventbus.Subscribe</code> with <code>@org.axonframework.eventhandling.annotation.EventHandler</code>.</p>
</div> </td>
</tr>
</tbody>
</table>
</div>
</div>
<div class="sect3">
<h4 id="_default_doop_and_noop_events_5">10.9.2. Default, Doop and Noop events</h4>
<div class="paragraph">
<p>If the <code>persistedLifecycleEvent</code> attribute is not explicitly specified (is left as its default value, <code>ObjectPersistedEvent.Default</code>), then the framework will, by default, post an event.</p>
</div>
<div class="paragraph">
<p>If this is not required, then the <code>isis.reflector.facet.domainObjectAnnotation.persistedLifecycleEvent.postForDefault</code> configuration property can be set to "false"; this will disable posting.</p>
</div>
<div class="paragraph">
<p>On the other hand, if the <code>persistedLifecycleEvent</code> has been explicitly specified to some subclass, then an event will be posted. The framework provides <code>ObjectPersistedEvent.Doop</code> as such a subclass, so setting the <code>persistedLifecycleEvent</code> attribute to this class will ensure that the event to be posted, irrespective of the configuration property setting.</p>
</div>
<div class="paragraph">
<p>And, conversely, the framework also provides <code>ObjectPersistedEvent.Noop</code>; if <code>persistedLifecycleEvent</code> attribute is set to this class, then no event will be posted.</p>
</div>
</div>
</div>
<div class="sect2">
<h3 id="_rgant-DomainObject_persistingLifecycleEvent">10.10. persistingLifecycleEvent()</h3>
<button type="button" class="button secondary" onclick="window.location.href="https://github.com/apache/isis/edit/master/adocs/documentation/src/main/asciidoc/guides/_rgant-DomainObject_persistingLifecycleEvent.adoc"" style="float: right; font-size: small; padding: 6px; margin-top: -55px; "><i class="fa fa-pencil-square-o"></i> Edit</button>
<div class="paragraph">
<p>Whenever a (just created, still transient) domain object is about to be saved (INSERTed in)to the database, a "persisting" lifecycle event is fired.</p>
</div>
<div class="paragraph">
<p>Subscribers subscribe through the <a href="rgsvc.html#_rgsvc_api_EventBusService"><code>EventBusService</code></a> and can use the event to obtain a reference to the domain object. The subscriber could then, for example, update the object, or it could use it maintain an external datastore. One possible application is to maintain a full-text search database using <a href="https://lucene.apache.org/">Apache Lucene</a> or similar.</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>Another use case is to maintain "last updated by"/"last updated at" properties. While you can roll your own, note that the framework provides built-in support for this use case through the <a href="rgcms.html#_rgcms_classes_roles_Timestampable"><code>Timestampable</code></a> role interface.</p>
</div> </td>
</tr>
</tbody>
</table>
</div>
<div class="paragraph">
<p>By default the event raised is <code>ObjectPersistingEvent.Default</code>. For example:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code data-lang="java"><span class="annotation">@DomainObject</span>
<span class="directive">public</span> <span class="type">class</span> <span class="class">ToDoItemDto</span> {
...
}</code></pre>
</div>
</div>
<div class="paragraph">
<p>The purpose of the <code>persistingLifecycleEvent()</code> attribute is to allows a custom subclass to be emitted instead. A similar attribute is available for other lifecycle events.</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">@DomainObjectLayout</span>(
persistingLifecycleEvent=ToDoItem.PersistingEvent.class
)
<span class="directive">public</span> <span class="type">class</span> <span class="class">ToDoItem</span> {
<span class="directive">public</span> <span class="directive">static</span> <span class="type">class</span> <span class="class">PersistingEvent</span>
<span class="directive">extends</span> org.apache.isis.applib.services.eventbus.ObjectPersistingEvent<ToDoItem> { }
...
}</code></pre>
</div>
</div>
<div class="paragraph">
<p>The benefit is that subscribers can be more targeted as to the events that they subscribe to.</p>
</div>
<div class="sect3">
<h4 id="_subscribers_6">10.10.1. Subscribers</h4>
<div class="paragraph">
<p>Subscribers (which must be domain services) subscribe using either the <a href="https://github.com/google/guava">Guava</a> API or (if the <a href="rgsvc.html#_rgsvc_api_EventBusService"><code>EventBusService</code></a> has been appropriately configured) using the <a href="http://www.axonframework.org/">Axon Framework</a> API. The examples below use the Guava API.</p>
</div>
<div class="paragraph">
<p>Subscribers can be either coarse-grained (if they subscribe to the top-level event type):</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code data-lang="java"><span class="annotation">@DomainService</span>(nature=NatureOfService.DOMAIN)
<span class="directive">public</span> <span class="type">class</span> <span class="class">SomeSubscriber</span> <span class="directive">extends</span> AbstractSubscriber {
<span class="annotation">@com</span>.google.common.eventbus.Subscribe
<span class="directive">public</span> <span class="type">void</span> on(ObjectPersistingEvent ev) {
<span class="keyword">if</span>(ev.getSource() <span class="keyword">instanceof</span> ToDoItem) { ... }
}
}</code></pre>
</div>
</div>
<div class="paragraph">
<p>or can be fine-grained (by subscribing to specific event subtypes):</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code data-lang="java"><span class="annotation">@DomainService</span>(nature=NatureOfService.DOMAIN)
<span class="directive">public</span> <span class="type">class</span> <span class="class">SomeSubscriber</span> <span class="directive">extends</span> AbstractSubscriber {
<span class="annotation">@com</span>.google.common.eventbus.Subscribe
<span class="directive">public</span> <span class="type">void</span> on(ToDoItem.ObjectPersistingEvent ev) {
...
}
}</code></pre>
</div>
</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>If the AxonFramework is being used, replace <code>@com.google.common.eventbus.Subscribe</code> with <code>@org.axonframework.eventhandling.annotation.EventHandler</code>.</p>
</div> </td>
</tr>
</tbody>
</table>
</div>
</div>
<div class="sect3">
<h4 id="_default_doop_and_noop_events_6">10.10.2. Default, Doop and Noop events</h4>
<div class="paragraph">
<p>If the <code>persistingLifecycleEvent</code> attribute is not explicitly specified (is left as its default value, <code>ObjectPersistingEvent.Default</code>), then the framework will, by default, post an event.</p>
</div>
<div class="paragraph">
<p>If this is not required, then the <code>isis.reflector.facet.domainObjectAnnotation.persistingLifecycleEvent.postForDefault</code> configuration property can be set to "false"; this will disable posting.</p>
</div>
<div class="paragraph">
<p>On the other hand, if the <code>persistingLifecycleEvent</code> has been explicitly specified to some subclass, then an event will be posted. The framework provides <code>ObjectPersistingEvent.Doop</code> as such a subclass, so setting the <code>persistingLifecycleEvent</code> attribute to this class will ensure that the event to be posted, irrespective of the configuration property setting.</p>
</div>
<div class="paragraph">
<p>And, conversely, the framework also provides <code>ObjectPersistingEvent.Noop</code>; if <code>persistingLifecycleEvent</code> attribute is set to this class, then no event will be posted.</p>
</div>
</div>
</div>
<div class="sect2">
<h3 id="_rgant-DomainObject_objectType">10.11. <code>objectType()</code></h3>
<button type="button" class="button secondary" onclick="window.location.href="https://github.com/apache/isis/edit/master/adocs/documentation/src/main/asciidoc/guides/_rgant-DomainObject_objectType.adoc"" style="float: right; font-size: small; padding: 6px; margin-top: -55px; "><i class="fa fa-pencil-square-o"></i> Edit</button>
<div class="paragraph">
<p>The <code>objectType()</code> attribute is used to provide a unique alias for the object’s class name.</p>
</div>
<div class="paragraph">
<p>This value is used internally to generate a string representation of an objects identity (the <code>Oid</code>). This can appear in several contexts, including:</p>
</div>
<div class="ulist">
<ul>
<li> <p>as the value of <code>Bookmark#getObjectType()</code> and in the <code>toString()</code> value of <code>Bookmark</code> (see <a href="rgsvc.html#_rgsvc_api_BookmarkService"><code>BookmarkService</code></a>)</p>
<div class="ulist">
<ul>
<li> <p>and thus in the "table-of-two-halves" pattern, as per (non-ASF) <a href="http://github.com/isisaddons/isis-module-poly">Isis addons' poly</a> module</p> </li>
</ul>
</div> </li>
<li> <p>in the serialization of <code>OidDto</code> in the <a href="rgcms.html#_rgcms_schema-cmd">command</a> and <a href="rgcms.html#_rgcms_schema-ixn">interaction</a> schemas</p> </li>
<li> <p>in the URLs of the <a href="ugvro.html">RestfulObjects viewer</a></p> </li>
<li> <p>in the URLs of the <a href="ugvw.html">Wicket viewer</a> (in general and in particular if <a href="ugvw.html#_ugvw_features_hints-and-copy-url">copying URLs</a>)</p> </li>
<li> <p>in XML snapshots generated by the <a href="rgsvc.html#_rgsvc_api_XmlSnapshotService"><code>XmlSnapshotService</code></a></p> </li>
</ul>
</div>
<div class="sect3">
<h4 id="_examples_3">10.11.1. Examples</h4>
<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">@DomainObject</span>(
objectType=<span class="string"><span class="delimiter">"</span><span class="content">orders.Order</span><span class="delimiter">"</span></span>
)
<span class="directive">public</span> <span class="type">class</span> <span class="class">Order</span> {
...
}</code></pre>
</div>
</div>
</div>
<div class="sect3">
<h4 id="_precedence_2">10.11.2. Precedence</h4>
<div class="paragraph">
<p>The rules of precedence are:</p>
</div>
<div class="olist arabic">
<ol class="arabic">
<li> <p><a href="#_rgant_Discriminator"><code>@Discriminator</code></a></p> </li>
<li> <p><code>@DomainObject#objectType</code>, or <a href="#_rgant_aaa_deprecated"><code>@ObjectType</code></a> (deprecated)</p> </li>
<li> <p><a href="#_rgant_PersistenceCapable"><code>@PersistenceCapable</code></a>, if at least the <code>schema</code> attribute is defined. <br></p>
<div class="paragraph">
<p>If both <code>schema</code> and <code>table</code> are defined, then the value is “schema.table�?. If only <code>schema</code> is defined, then the value is “schema.className�?.</p>
</div> </li>
<li> <p>Fully qualified class name of the entity.</p> </li>
</ol>
</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>This might be obvious, but to make explicit: we recommend that you always specify an object type for your domain objects.</p>
</div>
<div class="paragraph">
<p>Otherwise, if you refactor your code (change class name or move package), then any externally held references to the OID of the object will break. At best this will require a data migration in the database; at worst it could cause external clients accessing data through the <a href="ugvro.html">Restful Objects</a> viewer to break.</p>
</div> </td>
</tr>
</tbody>
</table>
</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>If the object type is not unique across all domain classes then the framework will fail-fast and fail to boot. An error message will be printed in the log to help you determine which classes have duplicate object tyoes.</p>
</div> </td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
<div class="sect2">
<h3 id="_rgant-DomainObject_publishing">10.12. <code>publishing()</code></h3>
<button type="button" class="button secondary" onclick="window.location.href="https://github.com/apache/isis/edit/master/adocs/documentation/src/main/asciidoc/guides/_rgant-DomainObject_publishing.adoc"" style="float: right; font-size: small; padding: 6px; margin-top: -55px; "><i class="fa fa-pencil-square-o"></i> Edit</button>
<div class="paragraph">
<p>The <code>publishing()</code> attribute determines whether and how a modified object instance is published via the registered implementation of a <a href="rgsvc.html#_rgsvc_spi_PublishingService"><code>PublishingService</code></a>) or <a href="rgsvc.html#_rgsvc_spi_PublisherService"><code>PublisherService</code></a>. This attribute is also supported for <a href="#_rgant-Action_publishing">actions</a>, where it controls whether action invocations are published as events, and for <a href="#_rgant_Property_publishing"><code>@Property#publishing()</code></a>, where it controls whether property edits are published as events.</p>
</div>
<div class="paragraph">
<p>A common use case is to notify external "downstream" systems of changes in the state of the Isis application.</p>
</div>
<div class="paragraph">
<p>The default value for the attribute is <code>AS_CONFIGURED</code>, meaning that the <a href="rgcfg.html#_rgcfg_configuring-core">configuration property</a> <code>isis.services.publish.objects</code> is used to determine the whether the action is published:</p>
</div>
<div class="ulist">
<ul>
<li> <p><code>all</code><br></p>
<div class="paragraph">
<p>all changed objects are published</p>
</div> </li>
<li> <p><code>none</code><br></p>
<div class="paragraph">
<p>no changed objects are published</p>
</div> </li>
</ul>
</div>
<div class="paragraph">
<p>If there is no configuration property in <code>isis.properties</code> then publishing is automatically enabled for domain objects.</p>
</div>
<div class="paragraph">
<p>This default can be overridden on an object-by-object basis; if <code>publishing()</code> is set to <code>ENABLED</code> then changed instances of the domain class are published irrespective of the configured value; if set to <code>DISABLED</code> then the changed instances are <em>not</em> published, again irrespective of the configured value.</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">@DomainObject</span>(
publishing=Publishing.ENABLED <i class="conum" data-value="1"></i><b>(1)</b>
)
<span class="directive">public</span> <span class="type">class</span> <span class="class">InterestRate</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>because set to enabled, will be published irrespective of the configured value.</td>
</tr>
</tbody>
</table>
</div>
<div class="sect3">
<h4 id="__code_publishingpayloadfactory_code_2">10.12.1. <code>publishingPayloadFactory()</code></h4>
<div class="paragraph">
<p>The (optional) related <code>publishingPayloadFactory()</code> specifies the class to use to create the (payload of the) event to be published by the publishing factory.</p>
</div>
<div class="paragraph">
<p>Rather than simply broadcast that the object was changed, the payload factory allows a "fatter" payload to be instantiated that can eagerly push commonly-required information to all subscribers. For at least some subscribers this should avoid the necessity to query back for additional information.</p>
</div>
<div class="admonitionblock warning">
<table>
<tbody>
<tr>
<td class="icon"> <i class="fa icon-warning" title="Warning"></i> </td>
<td class="content">
<div class="paragraph">
<p>Be aware that this attribute is only honoured by the (deprecated) <a href="rgsvc.html#_rgsvc_spi_PublishingService"><code>PublishingService</code></a>, so should itself be considered as deprecated. It is ignored by the replacement <a href="rgsvc.html#_rgsvc_spi_PublisherService"><code>PublisherService</code></a>,</p>
</div> </td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
<div class="sect2">
<h3 id="_rgant-DomainObject_removingLifecycleEvent">10.13. removingLifecycleEvent()</h3>
<button type="button" class="button secondary" onclick="window.location.href="https://github.com/apache/isis/edit/master/adocs/documentation/src/main/asciidoc/guides/_rgant-DomainObject_removingLifecycleEvent.adoc"" style="float: right; font-size: small; padding: 6px; margin-top: -55px; "><i class="fa fa-pencil-square-o"></i> Edit</button>
<div class="paragraph">
<p>Whenever a (persistent) domain object is about to be removed (DELETEd) from the database, a "removing" lifecycle event is fired.</p>
</div>
<div class="paragraph">
<p>Subscribers subscribe through the <a href="rgsvc.html#_rgsvc_api_EventBusService"><code>EventBusService</code></a> and can use the event to obtain a reference to the domain object. The subscriber could then, for example, could use it maintain an external datastore. One possible application is to maintain a full-text search database using <a href="https://lucene.apache.org/">Apache Lucene</a> or similar.</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>Another use case is to maintain "last updated by"/"last updated at" properties. While you can roll your own, note that the framework provides built-in support for this use case through the <a href="rgcms.html#_rgcms_classes_roles_Timestampable"><code>Timestampable</code></a> role interface.</p>
</div> </td>
</tr>
</tbody>
</table>
</div>
<div class="paragraph">
<p>By default the event raised is <code>ObjectRemovingEvent.Default</code>. For example:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code data-lang="java"><span class="annotation">@DomainObject</span>
<span class="directive">public</span> <span class="type">class</span> <span class="class">ToDoItemDto</span> {
...
}</code></pre>
</div>
</div>
<div class="paragraph">
<p>The purpose of the <code>removingLifecycleEvent()</code> attribute is to allows a custom subclass to be emitted instead. A similar attribute is available for other lifecycle events.</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">@DomainObjectLayout</span>(
removingLifecycleEvent=ToDoItem.RemovingEvent.class
)
<span class="directive">public</span> <span class="type">class</span> <span class="class">ToDoItem</span> {
<span class="directive">public</span> <span class="directive">static</span> <span class="type">class</span> <span class="class">RemovingEvent</span>
<span class="directive">extends</span> org.apache.isis.applib.services.eventbus.ObjectRemovingEvent<ToDoItem> { }
...
}</code></pre>
</div>
</div>
<div class="paragraph">
<p>The benefit is that subscribers can be more targeted as to the events that they subscribe to.</p>
</div>
<div class="sect3">
<h4 id="_subscribers_7">10.13.1. Subscribers</h4>
<div class="paragraph">
<p>Subscribers (which must be domain services) subscribe using either the <a href="https://github.com/google/guava">Guava</a> API or (if the <a href="rgsvc.html#_rgsvc_api_EventBusService"><code>EventBusService</code></a> has been appropriately configured) using the <a href="http://www.axonframework.org/">Axon Framework</a> API. The examples below use the Guava API.</p>
</div>
<div class="paragraph">
<p>Subscribers can be either coarse-grained (if they subscribe to the top-level event type):</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code data-lang="java"><span class="annotation">@DomainService</span>(nature=NatureOfService.DOMAIN)
<span class="directive">public</span> <span class="type">class</span> <span class="class">SomeSubscriber</span> <span class="directive">extends</span> AbstractSubscriber {
<span class="annotation">@com</span>.google.common.eventbus.Subscribe
<span class="directive">public</span> <span class="type">void</span> on(ObjectRemovingEvent ev) {
<span class="keyword">if</span>(ev.getSource() <span class="keyword">instanceof</span> ToDoItem) { ... }
}
}</code></pre>
</div>
</div>
<div class="paragraph">
<p>or can be fine-grained (by subscribing to specific event subtypes):</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code data-lang="java"><span class="annotation">@DomainService</span>(nature=NatureOfService.DOMAIN)
<span class="directive">public</span> <span class="type">class</span> <span class="class">SomeSubscriber</span> <span class="directive">extends</span> AbstractSubscriber {
<span class="annotation">@com</span>.google.common.eventbus.Subscribe
<span class="directive">public</span> <span class="type">void</span> on(ToDoItem.ObjectRemovingEvent ev) {
...
}
}</code></pre>
</div>
</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>If the AxonFramework is being used, replace <code>@com.google.common.eventbus.Subscribe</code> with <code>@org.axonframework.eventhandling.annotation.EventHandler</code>.</p>
</div> </td>
</tr>
</tbody>
</table>
</div>
</div>
<div class="sect3">
<h4 id="_default_doop_and_noop_events_7">10.13.2. Default, Doop and Noop events</h4>
<div class="paragraph">
<p>If the <code>removingLifecycleEvent</code> attribute is not explicitly specified (is left as its default value, <code>ObjectRemovingEvent.Default</code>), then the framework will, by default, post an event.</p>
</div>
<div class="paragraph">
<p>If this is not required, then the <code>isis.reflector.facet.domainObjectAnnotation.removingLifecycleEvent.postForDefault</code> configuration property can be set to "false"; this will disable posting.</p>
</div>
<div class="paragraph">
<p>On the other hand, if the <code>removingLifecycleEvent</code> has been explicitly specified to some subclass, then an event will be posted. The framework provides <code>ObjectRemovingEvent.Doop</code> as such a subclass, so setting the <code>removingLifecycleEvent</code> attribute to this class will ensure that the event to be posted, irrespective of the configuration property setting.</p>
</div>
<div class="paragraph">
<p>And, conversely, the framework also provides <code>ObjectRemovingEvent.Noop</code>; if <code>removingLifecycleEvent</code> attribute is set to this class, then no event will be posted.</p>
</div>
</div>
</div>
<div class="sect2">
<h3 id="_rgant-DomainObject_updatingLifecycleEvent">10.14. updatingLifecycleEvent()</h3>
<button type="button" class="button secondary" onclick="window.location.href="https://github.com/apache/isis/edit/master/adocs/documentation/src/main/asciidoc/guides/_rgant-DomainObject_updatingLifecycleEvent.adoc"" style="float: right; font-size: small; padding: 6px; margin-top: -55px; "><i class="fa fa-pencil-square-o"></i> Edit</button>
<div class="paragraph">
<p>Whenever a (persistent) domain object has been modified and is about to be updated to the database, an "updating" lifecycle event is fired.</p>
</div>
<div class="paragraph">
<p>Subscribers subscribe through the <a href="rgsvc.html#_rgsvc_api_EventBusService"><code>EventBusService</code></a> and can use the event to obtain a reference to the domain object. The subscriber could then, for example, update the object, or it could use it maintain an external datastore. One possible application is to maintain a full-text search database using <a href="https://lucene.apache.org/">Apache Lucene</a> or similar.</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>Another use case is to maintain "last updated by"/"last updated at" properties. While you can roll your own, note that the framework provides built-in support for this use case through the <a href="rgcms.html#_rgcms_classes_roles_Timestampable"><code>Timestampable</code></a> role interface.</p>
</div> </td>
</tr>
</tbody>
</table>
</div>
<div class="paragraph">
<p>By default the event raised is <code>ObjectUpdatingEvent.Default</code>. For example:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code data-lang="java"><span class="annotation">@DomainObject</span>
<span class="directive">public</span> <span class="type">class</span> <span class="class">ToDoItemDto</span> {
...
}</code></pre>
</div>
</div>
<div class="paragraph">
<p>The purpose of the <code>updatingLifecycleEvent()</code> attribute is to allows a custom subclass to be emitted instead. A similar attribute is available for other lifecycle events.</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">@DomainObjectLayout</span>(
updatingLifecycleEvent=ToDoItem.UpdatingEvent.class
)
<span class="directive">public</span> <span class="type">class</span> <span class="class">ToDoItem</span> {
<span class="directive">public</span> <span class="directive">static</span> <span class="type">class</span> <span class="class">UpdatingEvent</span>
<span class="directive">extends</span> org.apache.isis.applib.services.eventbus.ObjectUpdatingEvent<ToDoItem> { }
...
}</code></pre>
</div>
</div>
<div class="paragraph">
<p>The benefit is that subscribers can be more targeted as to the events that they subscribe to.</p>
</div>
<div class="sect3">
<h4 id="_subscribers_8">10.14.1. Subscribers</h4>
<div class="paragraph">
<p>Subscribers (which must be domain services) subscribe using either the <a href="https://github.com/google/guava">Guava</a> API or (if the <a href="rgsvc.html#_rgsvc_api_EventBusService"><code>EventBusService</code></a> has been appropriately configured) using the <a href="http://www.axonframework.org/">Axon Framework</a> API. The examples below use the Guava API.</p>
</div>
<div class="paragraph">
<p>Subscribers can be either coarse-grained (if they subscribe to the top-level event type):</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code data-lang="java"><span class="annotation">@DomainService</span>(nature=NatureOfService.DOMAIN)
<span class="directive">public</span> <span class="type">class</span> <span class="class">SomeSubscriber</span> <span class="directive">extends</span> AbstractSubscriber {
<span class="annotation">@com</span>.google.common.eventbus.Subscribe
<span class="directive">public</span> <span class="type">void</span> on(ObjectUpdatingEvent ev) {
<span class="keyword">if</span>(ev.getSource() <span class="keyword">instanceof</span> ToDoItem) { ... }
}
}</code></pre>
</div>
</div>
<div class="paragraph">
<p>or can be fine-grained (by subscribing to specific event subtypes):</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code data-lang="java"><span class="annotation">@DomainService</span>(nature=NatureOfService.DOMAIN)
<span class="directive">public</span> <span class="type">class</span> <span class="class">SomeSubscriber</span> <span class="directive">extends</span> AbstractSubscriber {
<span class="annotation">@com</span>.google.common.eventbus.Subscribe
<span class="directive">public</span> <span class="type">void</span> on(ToDoItem.ObjectUpdatingEvent ev) {
...
}
}</code></pre>
</div>
</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>If the AxonFramework is being used, replace <code>@com.google.common.eventbus.Subscribe</code> with <code>@org.axonframework.eventhandling.annotation.EventHandler</code>.</p>
</div> </td>
</tr>
</tbody>
</table>
</div>
</div>
<div class="sect3">
<h4 id="_default_doop_and_noop_events_8">10.14.2. Default, Doop and Noop events</h4>
<div class="paragraph">
<p>If the <code>updatingLifecycleEvent</code> attribute is not explicitly specified (is left as its default value, <code>ObjectUpdatingEvent.Default</code>), then the framework will, by default, post an event.</p>
</div>
<div class="paragraph">
<p>If this is not required, then the <code>isis.reflector.facet.domainObjectAnnotation.updatingLifecycleEvent.postForDefault</code> configuration property can be set to "false"; this will disable posting.</p>
</div>
<div class="paragraph">
<p>On the other hand, if the <code>updatingLifecycleEvent</code> has been explicitly specified to some subclass, then an event will be posted. The framework provides <code>ObjectUpdatingEvent.Doop</code> as such a subclass, so setting the <code>updatingLifecycleEvent</code> attribute to this class will ensure that the event to be posted, irrespective of the configuration property setting.</p>
</div>
<div class="paragraph">
<p>And, conversely, the framework also provides <code>ObjectUpdatingEvent.Noop</code>; if <code>updatingLifecycleEvent</code> attribute is set to this class, then no event will be posted.</p>
</div>
</div>
</div>
<div class="sect2">
<h3 id="_rgant-DomainObject_updatedLifecycleEvent">10.15. updatedLifecycleEvent()</h3>
<button type="button" class="button secondary" onclick="window.location.href="https://github.com/apache/isis/edit/master/adocs/documentation/src/main/asciidoc/guides/_rgant-DomainObject_updatedLifecycleEvent.adoc"" style="float: right; font-size: small; padding: 6px; margin-top: -55px; "><i class="fa fa-pencil-square-o"></i> Edit</button>
<div class="paragraph">
<p>Whenever a (persistent) domain object has been modified and has been updated in the database, an "updated" lifecycle event is fired.</p>
</div>
<div class="paragraph">
<p>Subscribers subscribe through the <a href="rgsvc.html#_rgsvc_api_EventBusService"><code>EventBusService</code></a> and can use the event to obtain a reference to the domain object.</p>
</div>
<div class="admonitionblock warning">
<table>
<tbody>
<tr>
<td class="icon"> <i class="fa icon-warning" title="Warning"></i> </td>
<td class="content">
<div class="paragraph">
<p>The object should <em>not</em> be modified during the updated callback.</p>
</div> </td>
</tr>
</tbody>
</table>
</div>
<div class="paragraph">
<p>By default the event raised is <code>ObjectUpdatedEvent.Default</code>. For example:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code data-lang="java"><span class="annotation">@DomainObject</span>
<span class="directive">public</span> <span class="type">class</span> <span class="class">ToDoItemDto</span> {
...
}</code></pre>
</div>
</div>
<div class="paragraph">
<p>The purpose of the <code>updatedLifecycleEvent()</code> attribute is to allows a custom subclass to be emitted instead. A similar attribute is available for other lifecycle events.</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">@DomainObjectLayout</span>(
updatedLifecycleEvent=ToDoItem.UpdatedEvent.class
)
<span class="directive">public</span> <span class="type">class</span> <span class="class">ToDoItem</span> {
<span class="directive">public</span> <span class="directive">static</span> <span class="type">class</span> <span class="class">UpdatedEvent</span>
<span class="directive">extends</span> org.apache.isis.applib.services.eventbus.ObjectUpdatedEvent<ToDoItem> { }
...
}</code></pre>
</div>
</div>
<div class="paragraph">
<p>The benefit is that subscribers can be more targeted as to the events that they subscribe to.</p>
</div>
<div class="sect3">
<h4 id="_subscribers_9">10.15.1. Subscribers</h4>
<div class="paragraph">
<p>Subscribers (which must be domain services) subscribe using either the <a href="https://github.com/google/guava">Guava</a> API or (if the <a href="rgsvc.html#_rgsvc_api_EventBusService"><code>EventBusService</code></a> has been appropriately configured) using the <a href="http://www.axonframework.org/">Axon Framework</a> API. The examples below use the Guava API.</p>
</div>
<div class="paragraph">
<p>Subscribers can be either coarse-grained (if they subscribe to the top-level event type):</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code data-lang="java"><span class="annotation">@DomainService</span>(nature=NatureOfService.DOMAIN)
<span class="directive">public</span> <span class="type">class</span> <span class="class">SomeSubscriber</span> <span class="directive">extends</span> AbstractSubscriber {
<span class="annotation">@com</span>.google.common.eventbus.Subscribe
<span class="directive">public</span> <span class="type">void</span> on(ObjectUpdatedEvent ev) {
<span class="keyword">if</span>(ev.getSource() <span class="keyword">instanceof</span> ToDoItem) { ... }
}
}</code></pre>
</div>
</div>
<div class="paragraph">
<p>or can be fine-grained (by subscribing to specific event subtypes):</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code data-lang="java"><span class="annotation">@DomainService</span>(nature=NatureOfService.DOMAIN)
<span class="directive">public</span> <span class="type">class</span> <span class="class">SomeSubscriber</span> <span class="directive">extends</span> AbstractSubscriber {
<span class="annotation">@com</span>.google.common.eventbus.Subscribe
<span class="directive">public</span> <span class="type">void</span> on(ToDoItem.ObjectUpdatedEvent ev) {
...
}
}</code></pre>
</div>
</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>If the AxonFramework is being used, replace <code>@com.google.common.eventbus.Subscribe</code> with <code>@org.axonframework.eventhandling.annotation.EventHandler</code>.</p>
</div> </td>
</tr>
</tbody>
</table>
</div>
</div>
<div class="sect3">
<h4 id="_default_doop_and_noop_events_9">10.15.2. Default, Doop and Noop events</h4>
<div class="paragraph">
<p>If the <code>updatedLifecycleEvent</code> attribute is not explicitly specified (is left as its default value, <code>ObjectUpdatedEvent.Default</code>), then the framework will, by default, post an event.</p>
</div>
<div class="paragraph">
<p>If this is not required, then the <code>isis.reflector.facet.domainObjectAnnotation.updatedLifecycleEvent.postForDefault</code> configuration property can be set to "false"; this will disable posting.</p>
</div>
<div class="paragraph">
<p>On the other hand, if the <code>updatedLifecycleEvent</code> has been explicitly specified to some subclass, then an event will be posted. The framework provides <code>ObjectUpdatedEvent.Doop</code> as such a subclass, so setting the <code>updatedLifecycleEvent</code> attribute to this class will ensure that the event to be posted, irrespective of the configuration property setting.</p>
</div>
<div class="paragraph">
<p>And, conversely, the framework also provides <code>ObjectUpdatedEvent.Noop</code>; if <code>updatedLifecycleEvent</code> attribute is set to this class, then no event will be posted.</p>
</div>
</div>
</div>
</div>
</div>
<div class="sect1">
<h2 id="_rgant-DomainObjectLayout">11. <code>@DomainObjectLayout</code></h2>
<button type="button" class="button secondary" onclick="window.location.href="https://github.com/apache/isis/edit/master/adocs/documentation/src/main/asciidoc/guides/_rgant-DomainObjectLayout.adoc"" style="float: right; font-size: small; padding: 6px; margin-top: -55px; "><i class="fa fa-pencil-square-o"></i> Edit</button>
<div class="sectionbody">
<div class="paragraph">
<p>The <code>@DomainObjectLayout</code> annotation applies to domain classes, collecting together all UI hints within a single annotation.</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>For view models that have been annotated with <code>@ViewModel</code> the equivalent <a href="#_rgant-ViewModelLayout"><code>@ViewModelLayout</code></a> can be used.</p>
</div> </td>
</tr>
</tbody>
</table>
</div>
<div class="paragraph">
<p>The table below summarizes the annotation’s attributes.</p>
</div>
<table class="tableblock frame-all grid-all spread">
<caption class="title">
Table 13.
<code>@DomainObjectLayout</code> attributes
</caption>
<colgroup>
<col style="width: 25%;">
<col style="width: 25%;">
<col style="width: 50%;">
</colgroup>
<thead>
<tr>
<th class="tableblock halign-left valign-top">Attribute</th>
<th class="tableblock halign-left valign-top">Values (default)</th>
<th class="tableblock halign-left valign-top">Description</th>
</tr>
</thead>
<tbody>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="#_rgant-DomainObjectLayout_bookmarking"><code>bookmarking()</code></a></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>AS_ROOT</code>, <code>AS_CHILD</code>, <code>NEVER</code><br> (<code>NEVER</code>)</p></td>
<td class="tableblock halign-left valign-top">
<div>
<div class="paragraph">
<p>whether (and how) this domain object should be automatically bookmarked</p>
</div>
</div></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="#_rgant-DomainObjectLayout_cssclass"><code>cssClass()</code></a></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Any string valid as a CSS class</p></td>
<td class="tableblock halign-left valign-top">
<div>
<div class="paragraph">
<p>the css class that a domain class (type) should have, to allow more targetted styling in <a href="rgcfg.html#_rgcfg_application-specific_application-css"><code>application.css</code></a></p>
</div>
</div></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="#_rgant-DomainObjectLayout_cssClassFa"><code>cssClassFa()</code></a></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Any valid <a href="http://fortawesome.github.io/Font-Awesome/">Font awesome</a> icon name</p></td>
<td class="tableblock halign-left valign-top">
<div>
<div class="paragraph">
<p>specify a font awesome icon for the action’s menu link or icon.<br></p>
</div>
</div></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>cssClassFaPosition()</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>LEFT</code>, <code>RIGHT</code><br> (<code>LEFT</code>)</p></td>
<td class="tableblock halign-left valign-top">
<div>
<div class="paragraph">
<p>Currently unused.</p>
</div>
</div></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="#_rgant-DomainObjectLayout_cssClassUiEvent"><code>cssClassUiEvent()</code></a></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">subtype of <code>CssClassUiEvent</code><br> (<code>CssClassUiEvent.Default</code>)</p></td>
<td class="tableblock halign-left valign-top">
<div>
<div class="paragraph">
<p>the event type to be posted to the <a href="rgsvc.html#_rgsvc_api_EventBusService"><code>EventBusService</code></a> to obtain a CSS class for the domain object.</p>
</div>
</div></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="#_rgant-DomainObjectLayout_describedAs"><code>describedAs()</code></a></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">String.</p></td>
<td class="tableblock halign-left valign-top">
<div>
<div class="paragraph">
<p>description of this class, eg to be rendered in a tooltip.</p>
</div>
</div></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="#_rgant-DomainObjectLayout_iconUiEvent"><code>iconUiEvent()</code></a></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">subtype of <code>IconUiEvent</code><br> (<code>IconUiEvent.Default</code>)</p></td>
<td class="tableblock halign-left valign-top">
<div>
<div class="paragraph">
<p>the event type to be posted to the <a href="rgsvc.html#_rgsvc_api_EventBusService"><code>EventBusService</code></a> to obtain the icon (name) for the domain object.</p>
</div>
</div></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="#_rgant-DomainObjectLayout_named"><code>named()</code></a></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">String.</p></td>
<td class="tableblock halign-left valign-top">
<div>
<div class="paragraph">
<p>to override the name inferred from the action’s name in code.<br></p>
</div>
<div class="paragraph">
<p>A typical use case is if the desired name is a reserved Java keyword, such as <code>default</code> or <code>package</code>.</p>
</div>
</div></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="#_rgant-DomainObjectLayout_paged"><code>paged()</code></a></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Positive integer</p></td>
<td class="tableblock halign-left valign-top">
<div>
<div class="paragraph">
<p>the page size for instances of this class when rendered within a table (as returned from an action invocation)</p>
</div>
</div></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="#_rgant-DomainObjectLayout_plural"><code>plural()</code></a></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">String.</p></td>
<td class="tableblock halign-left valign-top">
<div>
<div class="paragraph">
<p>the plural name of the class</p>
</div>
</div></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="#_rgant-DomainObjectLayout_titleUiEvent"><code>titleUiEvent()</code></a></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">subtype of <code>TitleUiEvent</code><br> (<code>TitleUiEvent.Default</code>)</p></td>
<td class="tableblock halign-left valign-top">
<div>
<div class="paragraph">
<p>the event type to be posted to the <a href="rgsvc.html#_rgsvc_api_EventBusService"><code>EventBusService</code></a> to obtain the title for the domain object.</p>
</div>
</div></td>
</tr>
</tbody>
</table>
<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">@DomainObjectLayout</span>(
cssClass=<span class="string"><span class="delimiter">"</span><span class="content">x-key</span><span class="delimiter">"</span></span>,
cssClassFa=<span class="string"><span class="delimiter">"</span><span class="content">fa-checklist</span><span class="delimiter">"</span></span>,
describedAs=<span class="string"><span class="delimiter">"</span><span class="content">Capture a task that you need to do</span><span class="delimiter">"</span></span>,
named=<span class="string"><span class="delimiter">"</span><span class="content">ToDo</span><span class="delimiter">"</span></span>,
paged=<span class="integer">30</span>,
plural=<span class="string"><span class="delimiter">"</span><span class="content">ToDo List</span><span class="delimiter">"</span></span>)
)
<span class="directive">public</span> <span class="type">class</span> <span class="class">ToDoItem</span> {
...
}</code></pre>
</div>
</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 there is (currently) no support for specifying UI hints for domain objects through the dynamic <a href="ugfun.html#_ugfun_object-layout_dynamic"><code>.layout.json</code></a> file (only for properties, collections and actions are supported).</p>
</div> </td>
</tr>
</tbody>
</table>
</div>
<div class="sect2">
<h3 id="_rgant-DomainObjectLayout_bookmarking">11.1. <code>bookmarking()</code></h3>
<button type="button" class="button secondary" onclick="window.location.href="https://github.com/apache/isis/edit/master/adocs/documentation/src/main/asciidoc/guides/_rgant-DomainObjectLayout_bookmarking.adoc"" style="float: right; font-size: small; padding: 6px; margin-top: -55px; "><i class="fa fa-pencil-square-o"></i> Edit</button>
<div class="paragraph">
<p>The <code>bookmarking()</code> attribute indicates that an entity is automatically bookmarked. This attribute is also supported for <a href="#_rgant-Action_bookmarking">domain objects</a>.</p>
</div>
<div class="paragraph">
<p>(In the Wicket viewer), a link to a bookmarked object is shown in the bookmarks panel:</p>
</div>
<div class="imageblock">
<div class="content">
<a class="image" href="images/reference-annotations/DomainObjectLayout/bookmarking.png"><img src="images/reference-annotations/DomainObjectLayout/bookmarking.png" alt="bookmarking" width="720px"></a>
</div>
</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 screenshot shows an earlier version of the <a href="ugvw.html">Wicket viewer</a> UI (specifically, pre 1.8.0).</p>
</div> </td>
</tr>
</tbody>
</table>
</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">@DomainObject</span>(bookmarking=BookmarkPolicy.AS_ROOT)
<span class="directive">public</span> <span class="type">class</span> <span class="class">ToDoItem</span> ... {
...
}</code></pre>
</div>
</div>
<div class="paragraph">
<p>indicates that the <code>ToDoItem</code> class is bookmarkable:</p>
</div>
<div class="paragraph">
<p>It is also possible to nest bookmarkable entities. For example, this screenshot is taken from <a href="http://github.com/estatio/estatio">Estatio</a>:</p>
</div>
<div class="imageblock">
<div class="content">
<a class="image" href="images/reference-annotations/DomainObjectLayout/bookmarking-nested.png"><img src="images/reference-annotations/DomainObjectLayout/bookmarking-nested.png" alt="bookmarking nested" width="720px"></a>
</div>
</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 screenshot shows an earlier version of the <a href="ugvw.html">Wicket viewer</a> UI (specifically, pre 1.8.0).</p>
</div> </td>
</tr>
</tbody>
</table>
</div>
<div class="paragraph">
<p>For example, the <code>Property</code> entity "[OXF] Oxford Super Mall" is a root bookmark, but the <code>Unit</code> child entity "[OXF-001] Unit 1" only appears as a bookmark <em>but only if</em> its parent <code>Property</code> has already been bookmarked.</p>
</div>
<div class="paragraph">
<p>This is accomplished with the following annotations:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code data-lang="java"><span class="annotation">@DomainObject</span>(bookmarking=BookmarkPolicy.AS_ROOT)
<span class="directive">public</span> <span class="type">class</span> <span class="class">Property</span> { ... }</code></pre>
</div>
</div>
<div class="paragraph">
<p>and</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code data-lang="java"><span class="annotation">@DomainObject</span>(bookmarking=BookmarkPolicy.AS_CHILD)
<span class="directive">public</span> <span class="directive">abstract</span> <span class="type">class</span> <span class="class">Unit</span> { ... }</code></pre>
</div>
</div>
<div class="paragraph">
<p>The nesting can be done to any level; the Estatio screenshot also shows a bookmark nesting <code>Lease</code> > <code>LeaseItem</code> > <code>LeaseTerm</code> (3 levels deep).</p>
</div>
</div>
<div class="sect2">
<h3 id="_rgant-DomainObjectLayout_cssClass">11.2. <code>cssClass()</code></h3>
<button type="button" class="button secondary" onclick="window.location.href="https://github.com/apache/isis/edit/master/adocs/documentation/src/main/asciidoc/guides/_rgant-DomainObjectLayout_cssClass.adoc"" style="float: right; font-size: small; padding: 6px; margin-top: -55px; "><i class="fa fa-pencil-square-o"></i> Edit</button>
<div class="paragraph">
<p>The <code>cssClass()</code> attribute can be used to render additional CSS classes in the HTML (a wrapping <code><div></code>) that represents the domain object. <a href="rgcfg.html#_rgcfg_application-specific_application-css">Application-specific CSS</a> can then be used to target and adjust the UI representation of that particular element.</p>
</div>
<div class="paragraph">
<p>This attribute can also be applied to <a href="#_rgant-DomainObjectLayout_cssClass">domain objects</a>, <a href="#_rgant-ViewModelLayout_cssClass">view models</a>, <a href="#_rgant-ActionLayout_cssClass">actions</a> <a href="#_rgant-PropertyLayout_cssClass">properties</a>, <a href="#_rgant-CollectionLayout_cssClass">collections</a> and <a href="#_rgant-ParameterLayout_cssClass">parameters</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">@DomainObject</span>(
cssClass=<span class="string"><span class="delimiter">"</span><span class="content">x-core-entity</span><span class="delimiter">"</span></span>
)
<span class="directive">public</span> <span class="type">class</span> <span class="class">ToDoItem</span> { ... }</code></pre>
</div>
</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>The similar <a href="#_rgant-DomainObjectLayout_cssClassFa"><code>@DomainObjectLayout#cssClassFa()</code></a> annotation attribute is also used as a hint to apply CSS, but in particular to allow <a href="http://fortawesome.github.io/Font-Awesome/icons/">Font Awesome icons</a> to be rendered as the icon for classes.</p>
</div> </td>
</tr>
</tbody>
</table>
</div>
</div>
<div class="sect2">
<h3 id="_rgant-DomainObjectLayout_cssClassFa">11.3. <code>cssClassFa()</code></h3>
<button type="button" class="button secondary" onclick="window.location.href="https://github.com/apache/isis/edit/master/adocs/documentation/src/main/asciidoc/guides/_rgant-DomainObjectLayout_cssClassFa.adoc"" style="float: right; font-size: small; padding: 6px; margin-top: -55px; "><i class="fa fa-pencil-square-o"></i> Edit</button>
<div class="paragraph">
<p>The <code>cssClassFa()</code> attribute is used to specify the name of a <a href="http://fortawesome.github.io/Font-Awesome/icons/">Font Awesome icon</a> name, to be rendered as the domain object’s icon.</p>
</div>
<div class="paragraph">
<p>These attributes can also be applied to <a href="#_rgant-ViewModelLayout_cssClassFa">view models</a> to specify the object’s icon, and to <a href="#_rgant-ActionLayout_cssClassFa">actions</a> to specify an icon for the action’s representation as a button or menu item.</p>
</div>
<div class="paragraph">
<p>If necessary the icon specified can be overridden by a particular object instance using the <a href="rgcms.html#_rgcms_methods_reserved_iconName"><code>iconName()</code></a> method.</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">@DomainObjectLayout</span>(
cssClassFa=<span class="string"><span class="delimiter">"</span><span class="content">fa-check-circle</span><span class="delimiter">"</span></span>
)
<span class="directive">public</span> <span class="type">class</span> <span class="class">ToDoItem</span> { ... }</code></pre>
</div>
</div>
<div class="paragraph">
<p>There can be multiple "fa-" classes, eg to mirror or rotate the icon. There is no need to include the mandatory <code>fa</code> "marker" CSS class; it will be automatically added to the list. The <code>fa-</code> prefix can also be omitted from the class names; it will be prepended to each if required.</p>
</div>
<div class="paragraph">
<p>The related <code>cssClassFaPosition()</code> attribute is currently unused for domain objects; the icon is always rendered to the left.</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>The similar <a href="#_rgant-DomainObjectLayout_cssClass"><code>@DomainObjectLayout#cssClass()</code></a> annotation attribute is also used as a hint to apply CSS, but for wrapping the representation of an object or object member so that it can be styled in an application-specific way.</p>
</div> </td>
</tr>
</tbody>
</table>
</div>
</div>
<div class="sect2">
<h3 id="_rgant-DomainObjectLayout_cssClassUiEvent">11.4. cssClassUiEvent()</h3>
<button type="button" class="button secondary" onclick="window.location.href="https://github.com/apache/isis/edit/master/adocs/documentation/src/main/asciidoc/guides/_rgant-DomainObjectLayout_cssClassUiEvent.adoc"" style="float: right; font-size: small; padding: 6px; margin-top: -55px; "><i class="fa fa-pencil-square-o"></i> Edit</button>
<div class="paragraph">
<p>Whenever a domain object is to be rendered, the framework fires off an CSS class UI event to obtain a CSS class to use in any wrapping <code><div></code>s and <code><span></code>s that render the domain object. This is as an alternative to implementing <a href="rgcms.html#_rgcms_methods_reserved_cssClass"><code>cssClass()</code></a> reserved method. (If <code>cssClass()</code> is present, then it will take precedence).</p>
</div>
<div class="paragraph">
<p>Subscribers subscribe through the <a href="rgsvc.html#_rgsvc_api_EventBusService"><code>EventBusService</code></a> and can use obtain a reference to the domain object from the event. From this they can, if they wish, specify a CSS class for the domain object using the event’s API.</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>The feature was originally introduced so that <a href="#_rgant-XmlRootElement"><code>@XmlRootElement</code></a>-annotated <a href="ugbtb.html#_ugbtb_view-models">view model</a>s could be kept as minimal as possible, just defining the data. UI events allow subscribers to provide UI hints, while <a href="ugbtb.html#_ugbtb_decoupling_mixins">mixin</a>s can be used to provide the behaviour.</p>
</div> </td>
</tr>
</tbody>
</table>
</div>
<div class="paragraph">
<p>By default the event raised is <code>CssClassUiEvent.Default</code>. For example:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code data-lang="java"><span class="annotation">@DomainObjectLayout</span>
<span class="directive">public</span> <span class="type">class</span> <span class="class">ToDoItemDto</span> {
...
}</code></pre>
</div>
</div>
<div class="paragraph">
<p>The purpose of the <code>cssClassUiEvent()</code> attribute is to allows a custom subclass to be emitted instead. A similar attribute is available for titles and icons.</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">@DomainObjectLayout</span>(
iconUiEvent=ToDoItemDto.CssClassUiEvent.class
)
<span class="directive">public</span> <span class="type">class</span> <span class="class">ToDoItemDto</span> {
<span class="directive">public</span> <span class="directive">static</span> <span class="type">class</span> <span class="class">CssClassUiEvent</span>
<span class="directive">extends</span> org.apache.isis.applib.services.eventbus.CssClassUiEvent<ToDoItemDto> { }
...
}</code></pre>
</div>
</div>
<div class="paragraph">
<p>The benefit is that subscribers can be more targeted as to the events that they subscribe to.</p>
</div>
<div class="sect3">
<h4 id="_subscribers_10">11.4.1. Subscribers</h4>
<div class="paragraph">
<p>Subscribers (which must be domain services) subscribe using either the <a href="https://github.com/google/guava">Guava</a> API or (if the <a href="rgsvc.html#_rgsvc_api_EventBusService"><code>EventBusService</code></a> has been appropriately configured) using the <a href="http://www.axonframework.org/">Axon Framework</a> API. The examples below use the Guava API.</p>
</div>
<div class="paragraph">
<p>Subscribers can be either coarse-grained (if they subscribe to the top-level event type):</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code data-lang="java"><span class="annotation">@DomainService</span>(nature=NatureOfService.DOMAIN)
<span class="directive">public</span> <span class="type">class</span> <span class="class">SomeSubscriber</span> <span class="directive">extends</span> AbstractSubscriber {
<span class="annotation">@com</span>.google.common.eventbus.Subscribe
<span class="directive">public</span> <span class="type">void</span> on(CssClassUiEvent ev) {
<span class="keyword">if</span>(ev.getSource() <span class="keyword">instanceof</span> ToDoItemDto) { ... }
}
}</code></pre>
</div>
</div>
<div class="paragraph">
<p>or can be fine-grained (by subscribing to specific event subtypes):</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code data-lang="java"><span class="annotation">@DomainService</span>(nature=NatureOfService.DOMAIN)
<span class="directive">public</span> <span class="type">class</span> <span class="class">SomeSubscriber</span> <span class="directive">extends</span> AbstractSubscriber {
<span class="annotation">@com</span>.google.common.eventbus.Subscribe
<span class="directive">public</span> <span class="type">void</span> on(ToDoItemDto.CssClassUiEvent ev) {
...
}
}</code></pre>
</div>
</div>
<div class="paragraph">
<p>The subscriber should then use <code>CssClassUiEvent#setCssClass(…)</code> to actually specify the CSS class to be used.</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>If the AxonFramework is being used, replace <code>@com.google.common.eventbus.Subscribe</code> with <code>@org.axonframework.eventhandling.annotation.EventHandler</code>.</p>
</div> </td>
</tr>
</tbody>
</table>
</div>
</div>
<div class="sect3">
<h4 id="_default_doop_and_noop_events_10">11.4.2. Default, Doop and Noop events</h4>
<div class="paragraph">
<p>If the <code>cssClassUiEvent</code> attribute is not explicitly specified (is left as its default value, <code>CssClassUiEvent.Default</code>), then the framework will, by default, post an event.</p>
</div>
<div class="paragraph">
<p>If this is not required, then the <code>isis.reflector.facet.domainObjectLayoutAnnotation.cssClassUiEvent.postForDefault</code> configuration property can be set to "false"; this will disable posting.</p>
</div>
<div class="paragraph">
<p>On the other hand, if the <code>cssClassUiEvent</code> has been explicitly specified to some subclass, then an event will be posted. The framework provides <code>CssClassUiEvent.Doop</code> as such a subclass, so setting the <code>cssClassUiEvent</code> attribute to this class will ensure that the event to be posted, irrespective of the configuration property setting.</p>
</div>
<div class="paragraph">
<p>And, conversely, the framework also provides <code>CssClassUiEvent.Noop</code>; if <code>cssClassUiEvent</code> attribute is set to this class, then no event will be posted.</p>
</div>
</div>
<div class="sect3">
<h4 id="_raising_events_programmatically_3">11.4.3. Raising events programmatically</h4>
<div class="paragraph">
<p>Normally events are only raised for interactions through the UI. However, events can be raised programmatically either by calling the <a href="rgsvc.html#_rgsvc_api_EventBusService"><code>EventBusService</code></a> API directly, or as a result of calling the <a href="rgsvc.html#_rgsvc_api_DomainObjectContainer"><code>DomainObjectContainer</code></a>'s <code>cssClassOf(…)</code> method.</p>
</div>
</div>
</div>
<div class="sect2">
<h3 id="_rgant-DomainObjectLayout_describedAs">11.5. <code>describedAs()</code></h3>
<button type="button" class="button secondary" onclick="window.location.href="https://github.com/apache/isis/edit/master/adocs/documentation/src/main/asciidoc/guides/_rgant-DomainObjectLayout_describedAs.adoc"" style="float: right; font-size: small; padding: 6px; margin-top: -55px; "><i class="fa fa-pencil-square-o"></i> Edit</button>
<div class="paragraph">
<p>The <code>describedAs()</code> attribute is used to provide a short description of the domain object to the user. In the <a href="ugvw.html">Wicket viewer</a> it is displayed as a 'tool tip'. The attribute can also be specified for <a href="#_rgant-CollectionLayout_describedAs">collections</a>, <a href="#_rgant-PropertyLayout_describedAs">properties</a>, <a href="#_rgant-ActionLayout_describedAs">actions</a>, <a href="#_rgant-ParameterLayout_describedAs">parameters</a> and <a href="#_rgant-ViewModelLayout_describedAs">view models</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">@DescribedAs</span>(<span class="string"><span class="delimiter">"</span><span class="content">A customer who may have originally become known to us via </span><span class="delimiter">"</span></span> +
<span class="string"><span class="delimiter">"</span><span class="content">the marketing system or who may have contacted us directly.</span><span class="delimiter">"</span></span>)
<span class="directive">public</span> <span class="type">class</span> <span class="class">ProspectiveSale</span> {
...
}</code></pre>
</div>
</div>
</div>
<div class="sect2">
<h3 id="_rgant-DomainObjectLayout_iconUiEvent">11.6. iconUiEvent()</h3>
<button type="button" class="button secondary" onclick="window.location.href="https://github.com/apache/isis/edit/master/adocs/documentation/src/main/asciidoc/guides/_rgant-DomainObjectLayout_iconUiEvent.adoc"" style="float: right; font-size: small; padding: 6px; margin-top: -55px; "><i class="fa fa-pencil-square-o"></i> Edit</button>
<div class="paragraph">
<p>Whenever a domain object is to be rendered, the framework fires off an icon UI event to obtain an icon (name) for the object (if possible). This is as an alternative to implementing <a href="rgcms.html#_rgcms_methods_reserved_iconName"><code>iconName()</code></a> reserved method. (If <code>iconName()</code> is present, then it will take precedence).</p>
</div>
<div class="paragraph">
<p>Subscribers subscribe through the <a href="rgsvc.html#_rgsvc_api_EventBusService"><code>EventBusService</code></a> and can use obtain a reference to the domain object from the event. From this they can, if they wish, specify an icon name for the domain object using the event’s API.</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>The feature was originally introduced so that <a href="#_rgant-XmlRootElement"><code>@XmlRootElement</code></a>-annotated <a href="ugbtb.html#_ugbtb_view-models">view model</a>s could be kept as minimal as possible, just defining the data. UI events allow subscribers to provide UI hints, while <a href="ugbtb.html#_ugbtb_decoupling_mixins">mixin</a>s can be used to provide the behaviour.</p>
</div> </td>
</tr>
</tbody>
</table>
</div>
<div class="paragraph">
<p>By default the event raised is <code>IconUiEvent.Default</code>. For example:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code data-lang="java"><span class="annotation">@DomainObjectLayout</span>
<span class="directive">public</span> <span class="type">class</span> <span class="class">ToDoItemDto</span> {
...
}</code></pre>
</div>
</div>
<div class="paragraph">
<p>The purpose of the <code>iconUiEvent()</code> attribute is to allows a custom subclass to be emitted instead. A similar attribute is available for titles and CSS classes.</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">@DomainObjectLayout</span>(
iconUiEvent=ToDoItemDto.IconUiEvent.class
)
<span class="directive">public</span> <span class="type">class</span> <span class="class">ToDoItemDto</span> {
<span class="directive">public</span> <span class="directive">static</span> <span class="type">class</span> <span class="class">IconUiEvent</span>
<span class="directive">extends</span> org.apache.isis.applib.services.eventbus.IconUiEvent<ToDoItemDto> { }
...
}</code></pre>
</div>
</div>
<div class="paragraph">
<p>The benefit is that subscribers can be more targeted as to the events that they subscribe to.</p>
</div>
<div class="sect3">
<h4 id="_subscribers_11">11.6.1. Subscribers</h4>
<div class="paragraph">
<p>Subscribers (which must be domain services) subscribe using either the <a href="https://github.com/google/guava">Guava</a> API or (if the <a href="rgsvc.html#_rgsvc_api_EventBusService"><code>EventBusService</code></a> has been appropriately configured) using the <a href="http://www.axonframework.org/">Axon Framework</a> API. The examples below use the Guava API.</p>
</div>
<div class="paragraph">
<p>Subscribers can be either coarse-grained (if they subscribe to the top-level event type):</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code data-lang="java"><span class="annotation">@DomainService</span>(nature=NatureOfService.DOMAIN)
<span class="directive">public</span> <span class="type">class</span> <span class="class">SomeSubscriber</span> <span class="directive">extends</span> AbstractSubscriber {
<span class="annotation">@com</span>.google.common.eventbus.Subscribe
<span class="directive">public</span> <span class="type">void</span> on(IconUiEvent ev) {
<span class="keyword">if</span>(ev.getSource() <span class="keyword">instanceof</span> ToDoItemDto) { ... }
}
}</code></pre>
</div>
</div>
<div class="paragraph">
<p>or can be fine-grained (by subscribing to specific event subtypes):</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code data-lang="java"><span class="annotation">@DomainService</span>(nature=NatureOfService.DOMAIN)
<span class="directive">public</span> <span class="type">class</span> <span class="class">SomeSubscriber</span> <span class="directive">extends</span> AbstractSubscriber {
<span class="annotation">@com</span>.google.common.eventbus.Subscribe
<span class="directive">public</span> <span class="type">void</span> on(ToDoItemDto.IconUiEvent ev) {
...
}
}</code></pre>
</div>
</div>
<div class="paragraph">
<p>The subscriber should then use <code>IconUiEvent#setIconName(…)</code> to actually specify the icon name to be used.</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>If the AxonFramework is being used, replace <code>@com.google.common.eventbus.Subscribe</code> with <code>@org.axonframework.eventhandling.annotation.EventHandler</code>.</p>
</div> </td>
</tr>
</tbody>
</table>
</div>
</div>
<div class="sect3">
<h4 id="_default_doop_and_noop_events_11">11.6.2. Default, Doop and Noop events</h4>
<div class="paragraph">
<p>If the <code>iconUiEvent</code> attribute is not explicitly specified (is left as its default value, <code>IconUiEvent.Default</code>), then the framework will, by default, post an event.</p>
</div>
<div class="paragraph">
<p>If this is not required, then the <code>isis.reflector.facet.domainObjectLayoutAnnotation.iconUiEvent.postForDefault</code> configuration property can be set to "false"; this will disable posting.</p>
</div>
<div class="paragraph">
<p>On the other hand, if the <code>iconUiEvent</code> has been explicitly specified to some subclass, then an event will be posted. The framework provides <code>IconUiEvent.Doop</code> as such a subclass, so setting the <code>iconUiEvent</code> attribute to this class will ensure that the event to be posted, irrespective of the configuration property setting.</p>
</div>
<div class="paragraph">
<p>And, conversely, the framework also provides <code>IconUiEvent.Noop</code>; if <code>iconUiEvent</code> attribute is set to this class, then no event will be posted.</p>
</div>
</div>
<div class="sect3">
<h4 id="_raising_events_programmatically_4">11.6.3. Raising events programmatically</h4>
<div class="paragraph">
<p>Normally events are only raised for interactions through the UI. However, events can be raised programmatically either by calling the <a href="rgsvc.html#_rgsvc_api_EventBusService"><code>EventBusService</code></a> API directly, or as a result of calling the <a href="rgsvc.html#_rgsvc_api_DomainObjectContainer"><code>DomainObjectContainer</code></a>'s <code>iconNameOf(…)</code> method.</p>
</div>
</div>
</div>
<div class="sect2">
<h3 id="_rgant-DomainObjectLayout_named">11.7. <code>named()</code></h3>
<button type="button" class="button secondary" onclick="window.location.href="https://github.com/apache/isis/edit/master/adocs/documentation/src/main/asciidoc/guides/_rgant-DomainObjectLayout_named.adoc"" style="float: right; font-size: small; padding: 6px; margin-top: -55px; "><i class="fa fa-pencil-square-o"></i> Edit</button>
<div class="paragraph">
<p>The <code>named()</code> attribute explicitly specifies the domain object’s name, overriding the name that would normally be inferred from the Java source code. The attribute can also be specified for <a href="#_rgant-ActionLayout_named">actions</a>, <a href="#_rgant-CollectionLayout_named">collections</a>, <a href="#_rgant-PropertyLayout_named">properties</a>, <a href="#_rgant-ParameterLayout_named">parameters</a>, <a href="#_rgant-ViewModelLayout_named">view models</a> and <a href="#_rgant-DomainServiceLayout_named">domain services</a>.</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>Following the <a href="http://en.wikipedia.org/wiki/Don%27t_repeat_yourself">don’t repeat yourself</a> principle, we recommend that you only use this attribute when the desired name cannot be used in Java source code. Examples of that include a name that would be a reserved Java keyword (eg "package"), or a name that has punctuation, eg apostrophes.</p>
</div> </td>
</tr>
</tbody>
</table>
</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">@DomainObjectLayout</span>(
named=<span class="string"><span class="delimiter">"</span><span class="content">Customer</span><span class="delimiter">"</span></span>
)
<span class="directive">public</span> <span class="type">class</span> <span class="class">CustomerImpl</span> <span class="directive">implements</span> Customer{
...
}</code></pre>
</div>
</div>
<div class="paragraph">
<p>It’s also possible to specify a <a href="#_rgant-DomainObjectLayout_plural">plural form</a> of the name, used by the framework when rendering a standalone collection of the domain object.</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>The framework also provides a separate, powerful mechanism for <a href="ugbtb.html#_ugbtb_i18n">internationalization</a>.</p>
</div> </td>
</tr>
</tbody>
</table>
</div>
</div>
<div class="sect2">
<h3 id="_rgant-DomainObjectLayout_paged">11.8. <code>paged()</code></h3>
<button type="button" class="button secondary" onclick="window.location.href="https://github.com/apache/isis/edit/master/adocs/documentation/src/main/asciidoc/guides/_rgant-DomainObjectLayout_paged.adoc"" style="float: right; font-size: small; padding: 6px; margin-top: -55px; "><i class="fa fa-pencil-square-o"></i> Edit</button>
<div class="paragraph">
<p>The <code>paged()</code> attribute specifies the number of rows to display in a standalone collection, as returned from an action invocation. This attribute can also be applied to <a href="#_rgant-CollectionLayout_paged">collections</a> and <a href="#_rgant-ViewModelLayout_paged">view models</a>.</p>
</div>
<div class="admonitionblock warning">
<table>
<tbody>
<tr>
<td class="icon"> <i class="fa icon-warning" title="Warning"></i> </td>
<td class="content">
<div class="paragraph">
<p>The <a href="ugvro.html">RestfulObjects viewer</a> currently does not support paging. The <a href="ugvw.html">Wicket viewer</a> <em>does</em> support paging, but note that the paging is performed client-side rather than server-side.</p>
</div>
<div class="paragraph">
<p>We therefore recommend that large collections should instead be modelled as actions (to allow filtering to be applied to limit the number of rows).</p>
</div> </td>
</tr>
</tbody>
</table>
</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">@DomainObjectLayout</span>(paged=<span class="integer">15</span>)
<span class="directive">public</span> <span class="type">class</span> <span class="class">Order</span> {
...
}</code></pre>
</div>
</div>
<div class="paragraph">
<p>It is also possible to specify a global default for the page size of standalone collections, using the <a href="rgcfg.html#_rgcfg_configuring-core">configuration property</a> <code>isis.viewer.paged.standalone</code>.</p>
</div>
</div>
<div class="sect2">
<h3 id="_rgant-DomainObjectLayout_plural">11.9. <code>plural()</code></h3>
<button type="button" class="button secondary" onclick="window.location.href="https://github.com/apache/isis/edit/master/adocs/documentation/src/main/asciidoc/guides/_rgant-DomainObjectLayout_plural.adoc"" style="float: right; font-size: small; padding: 6px; margin-top: -55px; "><i class="fa fa-pencil-square-o"></i> Edit</button>
<div class="paragraph">
<p>When Apache Isis displays a standalone collection of several objects, it will label the collection using the plural form of the object type.</p>
</div>
<div class="paragraph">
<p>By default the plural name will be derived from the end of the singular name, with support for some basic English language defaults (eg using "ies" for names ending with a "y").</p>
</div>
<div class="paragraph">
<p>The <code>plural()</code> attribute allows the plural form of the class name to be specified explicitly. This attribute is also supported for <a href="#_rgant-ViewModelLayout_plural">view models</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">@DomainObjectLayout</span>(plural=<span class="string"><span class="delimiter">"</span><span class="content">Children</span><span class="delimiter">"</span></span>)
<span class="directive">public</span> <span class="type">class</span> <span class="class">Child</span> {
...
}</code></pre>
</div>
</div>
</div>
<div class="sect2">
<h3 id="_rgant-DomainObjectLayout_titleUiEvent">11.10. titleUiEvent()</h3>
<button type="button" class="button secondary" onclick="window.location.href="https://github.com/apache/isis/edit/master/adocs/documentation/src/main/asciidoc/guides/_rgant-DomainObjectLayout_titleUiEvent.adoc"" style="float: right; font-size: small; padding: 6px; margin-top: -55px; "><i class="fa fa-pencil-square-o"></i> Edit</button>
<div class="paragraph">
<p>Whenever a domain object is to be rendered, the framework fires off a title UI event to obtain a title for the object. This is as an alternative to implementing <a href="rgcms.html#_rgcms_methods_reserved_title"><code>title()</code></a> reserved method, or using the <a href="#_rgant-Title"><code>@Title</code></a> annotation, within the class itself. (If either <code>title()</code> or <code>@Title</code> are present, then they will take precedence).</p>
</div>
<div class="paragraph">
<p>Subscribers subscribe through the <a href="rgsvc.html#_rgsvc_api_EventBusService"><code>EventBusService</code></a> and can use obtain a reference to the domain object from the event. From this they can, if they wish, specify a title for the domain object using the event’s API.</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>The feature was originally introduced so that <a href="#_rgant-XmlRootElement"><code>@XmlRootElement</code></a>-annotated <a href="ugbtb.html#_ugbtb_view-models">view model</a>s could be kept as minimal as possible, just defining the data. UI events allow subscribers to provide UI hints, while <a href="ugbtb.html#_ugbtb_decoupling_mixins">mixin</a>s can be used to provide the behaviour.</p>
</div> </td>
</tr>
</tbody>
</table>
</div>
<div class="paragraph">
<p>By default the event raised is <code>TitleUiEvent.Default</code>. For example:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code data-lang="java"><span class="annotation">@DomainObjectLayout</span>
<span class="directive">public</span> <span class="type">class</span> <span class="class">ToDoItemDto</span> {
...
}</code></pre>
</div>
</div>
<div class="paragraph">
<p>The purpose of the <code>titleUiEvent()</code> attribute is to allows a custom subclass to be emitted instead. A similar attribute is available for icon names and CSS classes.</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">@DomainObjectLayout</span>(
titleUiEvent=ToDoItemDto.TitleUiEvent.class
)
<span class="directive">public</span> <span class="type">class</span> <span class="class">ToDoItemDto</span> {
<span class="directive">public</span> <span class="directive">static</span> <span class="type">class</span> <span class="class">TitleUiEvent</span>
<span class="directive">extends</span> org.apache.isis.applib.services.eventbus.TitleUiEvent<ToDoItemDto> { }
...
}</code></pre>
</div>
</div>
<div class="paragraph">
<p>The benefit is that subscribers can be more targeted as to the events that they subscribe to.</p>
</div>
<div class="sect3">
<h4 id="_subscribers_12">11.10.1. Subscribers</h4>
<div class="paragraph">
<p>Subscribers (which must be domain services) subscribe using either the <a href="https://github.com/google/guava">Guava</a> API or (if the <a href="rgsvc.html#_rgsvc_api_EventBusService"><code>EventBusService</code></a> has been appropriately configured) using the <a href="http://www.axonframework.org/">Axon Framework</a> API. The examples below use the Guava API.</p>
</div>
<div class="paragraph">
<p>Subscribers can be either coarse-grained (if they subscribe to the top-level event type):</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code data-lang="java"><span class="annotation">@DomainService</span>(nature=NatureOfService.DOMAIN)
<span class="directive">public</span> <span class="type">class</span> <span class="class">SomeSubscriber</span> <span class="directive">extends</span> AbstractSubscriber {
<span class="annotation">@com</span>.google.common.eventbus.Subscribe
<span class="directive">public</span> <span class="type">void</span> on(TitleUiEvent ev) {
<span class="keyword">if</span>(ev.getSource() <span class="keyword">instanceof</span> ToDoItemDto) { ... }
}
}</code></pre>
</div>
</div>
<div class="paragraph">
<p>or can be fine-grained (by subscribing to specific event subtypes):</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code data-lang="java"><span class="annotation">@DomainService</span>(nature=NatureOfService.DOMAIN)
<span class="directive">public</span> <span class="type">class</span> <span class="class">SomeSubscriber</span> <span class="directive">extends</span> AbstractSubscriber {
<span class="annotation">@com</span>.google.common.eventbus.Subscribe
<span class="directive">public</span> <span class="type">void</span> on(ToDoItemDto.TitleUiEvent ev) {
...
}
}</code></pre>
</div>
</div>
<div class="paragraph">
<p>The subscriber should then use either <code>TitleUiEvent#setTranslatableTitle(…)</code> or <code>TitleUiEvent#setTitle(…)</code> to actually specify the title to be used.</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>If the AxonFramework is being used, replace <code>@com.google.common.eventbus.Subscribe</code> with <code>@org.axonframework.eventhandling.annotation.EventHandler</code>.</p>
</div> </td>
</tr>
</tbody>
</table>
</div>
</div>
<div class="sect3">
<h4 id="_default_doop_and_noop_events_12">11.10.2. Default, Doop and Noop events</h4>
<div class="paragraph">
<p>If the <code>titleUiEvent</code> attribute is not explicitly specified (is left as its default value, <code>TitleUiEvent.Default</code>), then the framework will, by default, post an event.</p>
</div>
<div class="paragraph">
<p>If this is not required, then the <code>isis.reflector.facet.domainObjectLayoutAnnotation.titleUiEvent.postForDefault</code> configuration property can be set to "false"; this will disable posting.</p>
</div>
<div class="paragraph">
<p>On the other hand, if the <code>titleUiEvent</code> has been explicitly specified to some subclass, then an event will be posted. The framework provides <code>TitleUiEvent.Doop</code> as such a subclass, so setting the <code>titleUiEvent</code> attribute to this class will ensure that the event to be posted, irrespective of the configuration property setting.</p>
</div>
<div class="paragraph">
<p>And, conversely, the framework also provides <code>TitleUiEvent.Noop</code>; if <code>titleUiEvent</code> attribute is set to this class, thn no event will be posted.</p>
</div>
</div>
<div class="sect3">
<h4 id="_raising_events_programmatically_5">11.10.3. Raising events programmatically</h4>
<div class="paragraph">
<p>Normally events are only raised for interactions through the UI. However, events can be raised programmatically either by calling the <a href="rgsvc.html#_rgsvc_api_EventBusService"><code>EventBusService</code></a> API directly, or as a result of calling the <a href="rgsvc.html#_rgsvc_api_DomainObjectContainer"><code>DomainObjectContainer</code></a>'s <code>titleOf(…)</code> method.</p>
</div>
</div>
</div>
</div>
</div>
<div class="sect1">
<h2 id="_rgant-DomainService">12. <code>@DomainService</code></h2>
<button type="button" class="button secondary" onclick="window.location.href="https://github.com/apache/isis/edit/master/adocs/documentation/src/main/asciidoc/guides/_rgant-DomainService.adoc"" style="float: right; font-size: small; padding: 6px; margin-top: -55px; "><i class="fa fa-pencil-square-o"></i> Edit</button>
<div class="sectionbody">
<div class="paragraph">
<p>The <code>@DomainService</code> annotation indicates that the (concrete) class should be automatically instantiated as a domain service.</p>
</div>
<div class="paragraph">
<p>Domain services with this annotation do NOT need to be registered explicitly in <code>isis.properties</code>; they will be discovered automatically on the CLASSPATH.</p>
</div>
<div class="paragraph">
<p>The table below summarizes the annotation’s attributes.</p>
</div>
<table class="tableblock frame-all grid-all spread">
<caption class="title">
Table 14.
<code>@DomainService</code> attributes
</caption>
<colgroup>
<col style="width: 25%;">
<col style="width: 25%;">
<col style="width: 50%;">
</colgroup>
<thead>
<tr>
<th class="tableblock halign-left valign-top">Attribute</th>
<th class="tableblock halign-left valign-top">Values (default)</th>
<th class="tableblock halign-left valign-top">Description</th>
</tr>
</thead>
<tbody>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="#_rgant-DomainService_nature"><code>nature()</code></a></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>VIEW</code>, <code>VIEW_MENU_ONLY</code>, <code>VIEW_CONTRIBUTIONS_ONLY</code>, <code>VIEW_REST_ONLY</code>, <code>DOMAIN</code> (<code>VIEW</code>)</p></td>
<td class="tableblock halign-left valign-top">
<div>
<div class="paragraph">
<p>the nature of this service: providing actions for menus, or as contributed actions, or for the <a href="ugvro.html">RestfulObjects REST API</a>, or neither</p>
</div>
</div></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="#_rgant-DomainService_objectType"><code>objectType()</code></a></p></td>
<td class="tableblock halign-left valign-top"></td>
<td class="tableblock halign-left valign-top">
<div>
<div class="paragraph">
<p>equivalent to <a href="#_rgant_DomainObject_objectType"><code>@DomainObject#objectType()</code></a>, specifies the objectType of the service.</p>
</div>
<div class="paragraph">
<p>The instanceId for services is always "1".</p>
</div>
</div></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="#_rgant-DomainService_repositoryFor"><code>repositoryFor()</code></a></p></td>
<td class="tableblock halign-left valign-top"></td>
<td class="tableblock halign-left valign-top">
<div>
<div class="paragraph">
<p>if this domain service acts as a repository for an entity type, specify that entity type. This is used to determine an icon to use for the service (eg as shown in action prompts).</p>
</div>
</div></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>menuOrder()</code></p></td>
<td class="tableblock halign-left valign-top"></td>
<td class="tableblock halign-left valign-top">
<div>
<div class="paragraph">
<p>Deprecated in 1.8.0; use instead <a href="#_rgant-DomainServiceLayout_menuOrder"><code>@DomainServiceLayout#menuOrder()</code></a></p>
</div>
</div></td>
</tr>
</tbody>
</table>
<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">@DomainService</span>(
nature=NatureOfService.DOMAIN,
repositoryFor=Loan.class
)
<span class="directive">public</span> <span class="type">class</span> <span class="class">LoanRepository</span> {
<span class="annotation">@Programmatic</span>
<span class="directive">public</span> <span class="predefined-type">List</span><Loan> findLoansFor(Borrower borrower) { ... }
}</code></pre>
</div>
</div>
<div class="sect2">
<h3 id="_rgant-DomainService_nature">12.1. <code>nature()</code></h3>
<button type="button" class="button secondary" onclick="window.location.href="https://github.com/apache/isis/edit/master/adocs/documentation/src/main/asciidoc/guides/_rgant-DomainService_nature.adoc"" style="float: right; font-size: small; padding: 6px; margin-top: -55px; "><i class="fa fa-pencil-square-o"></i> Edit</button>
<div class="paragraph">
<p>By default, a domain service’s actions will be rendered in the application menu bar <em>and</em> be contributed <em>and</em> appear in the REST API <em>and</em> (of course) be available to invoke programmatically wherever that domain service is injected. This is great for initial prototyping, but later on you may prefer to add a little more structure. This is the purpose of the <code>nature()</code> attribute: to indicates the intent of (all of) the actions defined within the domain service.</p>
</div>
<div class="paragraph">
<p>The values of the enum are:</p>
</div>
<div class="ulist">
<ul>
<li> <p><code>VIEW</code><br></p>
<div class="paragraph">
<p>The default; the service’s actions appear on menu bars, can be contributed, appear in the REST API</p>
</div> </li>
<li> <p><code>VIEW_MENU_ONLY</code><br></p>
<div class="paragraph">
<p>The service’s actions appear on menus and in the REST API, but are not contributed to domain objects or view models</p>
</div> </li>
<li> <p><code>VIEW_CONTRIBUTIONS_ONLY</code><br></p>
<div class="paragraph">
<p>The service’s actions are intended only to be used as contributed actions/associations to domain objects and view models.<br></p>
</div>
<div class="paragraph">
<p>The related <a href="#_rgant-ActionLayout_contributedAs"><code>@ActionLayout#contributedAs()</code></a> determines whether any given (1-arg) action is contributed as an association rather than an action.</p>
</div> </li>
<li> <p><code>VIEW_REST_ONLY</code><br></p>
<div class="paragraph">
<p>The service’s actions are intended only to be listed in the REST API exposed by the <a href="ugvro.html">RestfulObjects viewer</a>.</p>
</div> </li>
<li> <p><code>DOMAIN</code><br></p>
<div class="paragraph">
<p>The service and its actions are only intended to be invoked programmatically; they are a domain layer responsibility.</p>
</div> </li>
</ul>
</div>
<div class="paragraph">
<p>The actual class name of the domain service is only rendered for the <code>VIEW</code>, <code>VIEW_MENU_ONLY</code> and <code>VIEW_REST_ONLY</code> natures. Thus, you might also want to adopt naming conventions for your domain classes so you can infer the nature from the class. For example, the naming convention adopted (by and large) by the (non-ASF) <a href="http://isisaddons.org">Isis Addons</a> is <code>ProgrammaticServices</code> or <code>Repository</code> as a suffix for <code>DOMAIN</code> services, and <code>Contributions</code> as a suffix for <code>VIEW_CONTRIBUTIONS_ONLY</code> services.</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">@DomainService</span>(
nature=NatureOfService.VIEW_CONTRIBUTIONS_ONLY
)
<span class="directive">public</span> <span class="type">class</span> <span class="class">LoanContributions</span> { <i class="conum" data-value="1"></i><b>(1)</b>
<span class="annotation">@Action</span>(semantics=SemanticsOf.SAFE) <i class="conum" data-value="2"></i><b>(2)</b>
<span class="annotation">@ActionLayout</span>(contributed=Contributed.AS_ASSOCIATION )
<span class="directive">public</span> <span class="predefined-type">List</span><Loan> currentLoans(Borrower borrower) { ... }
<span class="directive">public</span> Borrower newLoan(Borrower borrower, <span class="predefined-type">Book</span> book) { ... }
}</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>Contributions</code> as a suffix for a domain service that contributes a number of actions to <code>Borrower</code>s. Note that <code>Borrower</code> could be a (marker) interface, so this functionality is "mixed in" merely by the class (eg <code>LibraryMember</code>) implementing this interface</td>
</tr>
<tr>
<td><i class="conum" data-value="2"></i><b>2</b></td>
<td>actions contibuted as associations (a collection in this case) must have safe semantics</td>
</tr>
</tbody>
</table>
</div>
<div class="paragraph">
<p>Another example:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code data-lang="java"><span class="annotation">@DomainService</span>(
nature=NatureOfService.DOMAIN
)
<span class="directive">public</span> <span class="type">class</span> <span class="class">LoanRepository</span> { <i class="conum" data-value="1"></i><b>(1)</b>
<span class="annotation">@Programmatic</span> <i class="conum" data-value="2"></i><b>(2)</b>
<span class="directive">public</span> <span class="predefined-type">List</span><Loan> findLoansFor(Borrower borrower) { ... }
}</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>Repository</code> as a suffix for a domain-layer service</td>
</tr>
<tr>
<td><i class="conum" data-value="2"></i><b>2</b></td>
<td>methods on <code>DOMAIN</code> services are often <a href="#_rgant-Programmatic"><code>@Programmatic</code></a>; they will never be exposed in the UI, so there’s little point in including them in Apache Isis' metamodel</td>
</tr>
</tbody>
</table>
</div>
<div class="paragraph">
<p>A final example:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code data-lang="java"><span class="annotation">@DomainService</span>(
nature=NatureOfService.VIEW_MENU_ONLY
)
<span class="directive">public</span> <span class="type">class</span> <span class="class">Loans</span> { <i class="conum" data-value="1"></i><b>(1)</b>
<span class="annotation">@Action</span>(semantics=SemanticsOf.SAFE)
<span class="directive">public</span> <span class="predefined-type">List</span><Loan> findOverdueLoans() { ... }
<span class="annotation">@Inject</span>
LoanRepository loanRepository; <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>name is intended to be rendered in the UI</td>
</tr>
<tr>
<td><i class="conum" data-value="2"></i><b>2</b></td>
<td>it’s common for domain-layer domain services to be injected into presentation layer services (such as <code>VIEW_MENU_ONLY</code> and <code>VIEW_CONTRIBUTIONS_ONLY</code>).</td>
</tr>
</tbody>
</table>
</div>
</div>
<div class="sect2">
<h3 id="_rgant-DomainService_objectType">12.2. <code>objectType()</code></h3>
<button type="button" class="button secondary" onclick="window.location.href="https://github.com/apache/isis/edit/master/adocs/documentation/src/main/asciidoc/guides/_rgant-DomainService_objectType.adoc"" style="float: right; font-size: small; padding: 6px; margin-top: -55px; "><i class="fa fa-pencil-square-o"></i> Edit</button>
<div class="paragraph">
<p>The <code>objectType()</code> attribute is used to provide a unique alias for the domain service’s class name.</p>
</div>
<div class="paragraph">
<p>This value is used internally to generate a string representation of an service identity (the <code>Oid</code>). This can appear in several contexts, including:</p>
</div>
<div class="ulist">
<ul>
<li> <p>as the value of <code>Bookmark#getObjectType()</code> and in the <code>toString()</code> value of <code>Bookmark</code> (see <a href="rgsvc.html#_rgsvc_api_BookmarkService"><code>BookmarkService</code></a>)</p> </li>
<li> <p>in the serialization of <code>OidDto</code> in the <a href="rgcms.html#_rgcms_schema-cmd">command</a> and <a href="rgcms.html#_rgcms_schema-ixn">interaction</a> schemas</p> </li>
<li> <p>in the URLs of the <a href="ugvro.html">RestfulObjects viewer</a></p> </li>
<li> <p>in the URLs of the <a href="ugvw.html">Wicket viewer</a> (specifically, for bookmarked actions)</p> </li>
</ul>
</div>
<div class="sect3">
<h4 id="_example">12.2.1. Example</h4>
<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">@DomainService</span>(
objectType=<span class="string"><span class="delimiter">"</span><span class="content">orders.OrderMenu</span><span class="delimiter">"</span></span>
)
<span class="directive">public</span> <span class="type">class</span> <span class="class">OrderMenu</span> {
...
}</code></pre>
</div>
</div>
</div>
<div class="sect3">
<h4 id="_precedence_3">12.2.2. Precedence</h4>
<div class="paragraph">
<p>The rules of precedence are:</p>
</div>
<div class="olist arabic">
<ol class="arabic">
<li> <p><code>@DomainService#objectType</code></p> </li>
<li> <p><a href="rgcms.html#_rgcms_methods_reserved_getId"><code>getId()</code></a></p> </li>
<li> <p>The fully qualified class name.</p> </li>
</ol>
</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>This might be obvious, but to make explicit: we recommend that you always specify an object type for your domain services.</p>
</div>
<div class="paragraph">
<p>Otherwise, if you refactor your code (change class name or move package), then any externally held references to the OID of the service will break. At best this will require a data migration in the database; at worst it could cause external clients accessing data through the <a href="ugvro.html">Restful Objects</a> viewer to break.</p>
</div> </td>
</tr>
</tbody>
</table>
</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>If the object type is not unique across all domain classes then the framework will fail-fast and fail to boot. An error message will be printed in the log to help you determine which classes have duplicate object tyoes.</p>
</div> </td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
<div class="sect2">
<h3 id="_rgant-DomainService_repositoryFor">12.3. <code>repositoryFor()</code></h3>
<button type="button" class="button secondary" onclick="window.location.href="https://github.com/apache/isis/edit/master/adocs/documentation/src/main/asciidoc/guides/_rgant-DomainService_repositoryFor.adoc"" style="float: right; font-size: small; padding: 6px; margin-top: -55px; "><i class="fa fa-pencil-square-o"></i> Edit</button>
<div class="paragraph">
<p>The <code>repositoryFor()</code> attribute is intended for domain services (probably with a <a href="#_rgant-DomainService_nature"><code>nature=DOMAIN</code></a>) that are intended to act as repositories for domain entities.</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">@DomainService</span>(
nature=NatureOfService.DOMAIN,
repositoryFor=Loan.class
)
<span class="directive">public</span> <span class="type">class</span> <span class="class">LoanRepository</span> {
<span class="annotation">@Programmatic</span>
<span class="directive">public</span> <span class="predefined-type">List</span><Loan> findLoansFor(Borrower borrower) { ... }
}</code></pre>
</div>
</div>
<div class="paragraph">
<p>Currently the metadata is unused; one planned use is to infer the icon for the domain service from the icon of the nominated entity.</p>
</div>
</div>
</div>
</div>
<div class="sect1">
<h2 id="_rgant-DomainServiceLayout">13. <code>@DomainServiceLayout</code></h2>
<button type="button" class="button secondary" onclick="window.location.href="https://github.com/apache/isis/edit/master/adocs/documentation/src/main/asciidoc/guides/_rgant-DomainServiceLayout.adoc"" style="float: right; font-size: small; padding: 6px; margin-top: -55px; "><i class="fa fa-pencil-square-o"></i> Edit</button>
<div class="sectionbody">
<div class="paragraph">
<p>The <code>@DomainServiceLayout</code> annotation applies to domain services, collecting together all view layout semantics within a single annotation.</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>You will also find some additional material in the <a href="ugfun.html#_ugfun_object-layout_application-menu">object layout</a> chapter.</p>
</div> </td>
</tr>
</tbody>
</table>
</div>
<div class="paragraph">
<p>The table below summarizes the annotation’s attributes.</p>
</div>
<table class="tableblock frame-all grid-all spread">
<caption class="title">
Table 15.
<code>@DomainServiceLayout</code> attributes
</caption>
<colgroup>
<col style="width: 25%;">
<col style="width: 25%;">
<col style="width: 50%;">
</colgroup>
<thead>
<tr>
<th class="tableblock halign-left valign-top">Attribute</th>
<th class="tableblock halign-left valign-top">Values (default)</th>
<th class="tableblock halign-left valign-top">Description</th>
</tr>
</thead>
<tbody>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="#_rgant-DomainServiceLayout_menuBar"><code>menuBar()</code></a></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>PRIMARY</code>, <code>SECONDARY</code>, <code>TERTIARY</code> (<code>PRIMARY</code>).</p></td>
<td class="tableblock halign-left valign-top">
<div>
<div class="paragraph">
<p>the menubar in which the menu that holds this service’s actions should reside.</p>
</div>
</div></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="#_rgant-DomainServiceLayout_menuOrder"><code>menuOrder()</code></a></p></td>
<td class="tableblock halign-left valign-top"></td>
<td class="tableblock halign-left valign-top">
<div>
<div class="paragraph">
<p>the order of the service’s menu with respect to other service’s.</p>
</div>
</div></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="#_rgant-DomainServiceLayout_named"><code>named()</code></a></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">string, eg "Customers"</p></td>
<td class="tableblock halign-left valign-top">
<div>
<div class="paragraph">
<p>name of this class (overriding the name derived from its name in code)</p>
</div>
</div></td>
</tr>
</tbody>
</table>
<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">@DomainService</span>
<span class="annotation">@DomainServiceLayout</span>(
menuBar=<span class="predefined-type">MenuBar</span>.PRIMARY,
menuOrder=<span class="string"><span class="delimiter">"</span><span class="content">100</span><span class="delimiter">"</span></span>,
named=<span class="string"><span class="delimiter">"</span><span class="content">ToDos</span><span class="delimiter">"</span></span>
)
<span class="directive">public</span> <span class="type">class</span> <span class="class">ToDoItems</span> {
...
}</code></pre>
</div>
</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 there is (currently) no support for specifying UI hints for domain services through the dynamic <a href="ugfun.html#_ugfun_object-layout_dynamic"><code>.layout.json</code></a> file (only for properties, collections and actions are supported).</p>
</div> </td>
</tr>
</tbody>
</table>
</div>
<div class="sect2">
<h3 id="_rgant-DomainServiceLayout_menuBar">13.1. <code>menuBar()</code></h3>
<button type="button" class="button secondary" onclick="window.location.href="https://github.com/apache/isis/edit/master/adocs/documentation/src/main/asciidoc/guides/_rgant-DomainServiceLayout_menuBar.adoc"" style="float: right; font-size: small; padding: 6px; margin-top: -55px; "><i class="fa fa-pencil-square-o"></i> Edit</button>
<div class="paragraph">
<p>The <code>menuBar()</code> attribute is a hint to specify where on the application menu a domain service’s actions should be rendered.</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">@DomainService</span>
<span class="annotation">@DomainServiceLayout</span>(menuBar=<span class="predefined-type">MenuBar</span>.PRIMARY)
<span class="directive">public</span> <span class="type">class</span> <span class="class">ToDoItems</span> {
...
}</code></pre>
</div>
</div>
<div class="paragraph">
<p>In the <a href="ugvw.html">Wicket viewer</a>, domain services placed on the <code>PRIMARY</code> menu bar appears to the left:</p>
</div>
<div class="imageblock">
<div class="content">
<a class="image" href="images/reference-annotations/DomainServiceLayout/menuBar-primary.png"><img src="images/reference-annotations/DomainServiceLayout/menuBar-primary.png" alt="menuBar primary" width="720px"></a>
</div>
</div>
<div class="paragraph">
<p>Domain services placed on the <code>SECONDARY</code> menu bar appear to the right:</p>
</div>
<div class="imageblock">
<div class="content">
<a class="image" href="images/reference-annotations/DomainServiceLayout/menuBar-secondary.png"><img src="images/reference-annotations/DomainServiceLayout/menuBar-secondary.png" alt="menuBar secondary" width="720px"></a>
</div>
</div>
<div class="paragraph">
<p>Domain services placed on the <code>TERTIARY</code> appear in the menu bar associated with the user’s name (far top-right)</p>
</div>
<div class="imageblock">
<div class="content">
<a class="image" href="images/reference-annotations/DomainServiceLayout/menuBar-tertiary.png"><img src="images/reference-annotations/DomainServiceLayout/menuBar-tertiary.png" alt="menuBar tertiary" width="720px"></a>
</div>
</div>
<div class="paragraph">
<p>The grouping of multiple domain services actions within a single drop-down is managed by the <a href="#_rgant-DomainServiceLayout_menuOrder"><code>@DomainServiceLayout#menuOrder()</code></a> attribute.</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>The <a href="ugvro.html">RestfulObjects viewer</a> does not support this attribute.</p>
</div> </td>
</tr>
</tbody>
</table>
</div>
</div>
<div class="sect2">
<h3 id="_rgant-DomainServiceLayout_menuOrder">13.2. <code>menuOrder()</code></h3>
<button type="button" class="button secondary" onclick="window.location.href="https://github.com/apache/isis/edit/master/adocs/documentation/src/main/asciidoc/guides/_rgant-DomainServiceLayout_menuOrder.adoc"" style="float: right; font-size: small; padding: 6px; margin-top: -55px; "><i class="fa fa-pencil-square-o"></i> Edit</button>
<div class="paragraph">
<p>The <code>menuOrder()</code> attribute determines the ordering of a domain service’s actions as menu items within a specified menu bar and top-level menu.</p>
</div>
<div class="paragraph">
<p>The algorithm works as follows:</p>
</div>
<div class="ulist">
<ul>
<li> <p>first, the <a href="#_rgant-DomainServiceLayout_menuBar"><code>menuBar()</code></a> determines which of the three menu bars the service’s actions should be rendered</p> </li>
<li> <p>then, the domain service’s top-level name (typically explicitly specified using <a href="#_rgant-DomainServiceLayout_named"><code>named()</code></a>) is used to determine the top-level menu item to be rendered on the menu bar</p> </li>
<li> <p>finally, if there is more than domain service that has the same name, then the <code>menuOrder</code> attribute is used to order those actions on the menu item drop-down.</p> </li>
</ul>
</div>
<div class="paragraph">
<p>For example, the screenshot below shows the "prototyping" menu from the (non-ASF) <a href="http://github.com/isisaddons/isis-app-todoapp">Isis addons' todoapp</a>:</p>
</div>
<div class="imageblock">
<div class="content">
<a class="image" href="images/reference-annotations/DomainServiceLayout/menuOrder.png"><img src="images/reference-annotations/DomainServiceLayout/menuOrder.png" alt="menuOrder" width="500px"></a>
</div>
</div>
<div class="paragraph">
<p>The <a href="ugvw.html">Wicket viewer</a> automatically places separators between actions from different domain services. From this we can infer that there are actually five different domain services that are all rendered on the "prototyping" top-level menu.</p>
</div>
<div class="paragraph">
<p>One of these is the todoapp’s <code>DemoDomainEventSubscriptions</code> service:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code data-lang="java"><span class="annotation">@DomainService</span>(
nature = NatureOfService.VIEW_MENU_ONLY
)
<span class="annotation">@DomainServiceLayout</span>(
menuBar = <span class="predefined-type">MenuBar</span>.SECONDARY,
named = <span class="string"><span class="delimiter">"</span><span class="content">Prototyping</span><span class="delimiter">"</span></span>, <i class="conum" data-value="1"></i><b>(1)</b>
menuOrder = <span class="string"><span class="delimiter">"</span><span class="content">500.20</span><span class="delimiter">"</span></span>) <i class="conum" data-value="2"></i><b>(2)</b>
<span class="directive">public</span> <span class="type">class</span> <span class="class">DemoDomainEventSubscriptions</span> {
<span class="annotation">@ActionLayout</span>(named=<span class="string"><span class="delimiter">"</span><span class="content">Set subscriber behaviour</span><span class="delimiter">"</span></span>)
<span class="annotation">@MemberOrder</span>(sequence = <span class="string"><span class="delimiter">"</span><span class="content">500.20.1</span><span class="delimiter">"</span></span>) <i class="conum" data-value="3"></i><b>(3)</b>
<span class="directive">public</span> <span class="type">void</span> subscriberBehaviour(...) { ... }
...
}</code></pre>
</div>
</div>
<div class="colist arabic">
<table>
<tbody>
<tr>
<td><i class="conum" data-value="1"></i><b>1</b></td>
<td>render on the "Prototyping" menu</td>
</tr>
<tr>
<td><i class="conum" data-value="2"></i><b>2</b></td>
<td>positioning relative to other service’s on the "Prototyping" menu</td>
</tr>
<tr>
<td><i class="conum" data-value="3"></i><b>3</b></td>
<td>by convention (nothing more) the <code>@MemberOrder#sequence()</code> attribute continues the same Dewey decimal sequence format (a simple string "1" could in fact have been used instead)</td>
</tr>
</tbody>
</table>
</div>
<div class="paragraph">
<p>while another comes from the (non-ASF) <a href="http://github.com/isisaddons/isis-module-devutils">Isis addons' devutils</a> module:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code data-lang="java"><span class="annotation">@DomainServiceLayout</span>(
menuBar = <span class="predefined-type">MenuBar</span>.SECONDARY,
named = <span class="string"><span class="delimiter">"</span><span class="content">Prototyping</span><span class="delimiter">"</span></span>, <i class="conum" data-value="1"></i><b>(1)</b>
menuOrder = <span class="string"><span class="delimiter">"</span><span class="content">500.600</span><span class="delimiter">"</span></span> <i class="conum" data-value="2"></i><b>(2)</b>
)
<span class="directive">public</span> <span class="type">class</span> <span class="class">DeveloperUtilitiesServiceMenu</span> {
<span class="annotation">@MemberOrder</span>( sequence = <span class="string"><span class="delimiter">"</span><span class="content">500.600.1</span><span class="delimiter">"</span></span> ) <i class="conum" data-value="3"></i><b>(3)</b>
<span class="directive">public</span> <span class="predefined-type">Clob</span> downloadMetaModel() { ... }
<span class="annotation">@MemberOrder</span>( sequence = <span class="string"><span class="delimiter">"</span><span class="content">500.600.2</span><span class="delimiter">"</span></span> )
<span class="directive">public</span> <span class="predefined-type">Blob</span> downloadLayouts() { ... }
<span class="annotation">@ActionLayout</span>(named = <span class="string"><span class="delimiter">"</span><span class="content">Rebuild Services Meta Model</span><span class="delimiter">"</span></span>)
<span class="annotation">@MemberOrder</span>( sequence = <span class="string"><span class="delimiter">"</span><span class="content">500.600.3</span><span class="delimiter">"</span></span>)
<span class="directive">public</span> <span class="type">void</span> refreshServices() { ... }
...
}</code></pre>
</div>
</div>
<div class="colist arabic">
<table>
<tbody>
<tr>
<td><i class="conum" data-value="1"></i><b>1</b></td>
<td>render on the "Prototyping" menu</td>
</tr>
<tr>
<td><i class="conum" data-value="2"></i><b>2</b></td>
<td>positioning relative to other service’s on the "Prototyping" menu; this appears after the <code>DemoDomainEventSubscriptions</code> service shown above</td>
</tr>
<tr>
<td><i class="conum" data-value="3"></i><b>3</b></td>
<td>by convention (nothing more) the <code>@MemberOrder#sequence()</code> attribute continues the same Dewey decimal sequence format (a simple string "1", "2", "3", … could in fact have been used instead)</td>
</tr>
</tbody>
</table>
</div>
</div>
<div class="sect2">
<h3 id="_rgant-DomainServiceLayout_named">13.3. <code>named()</code></h3>
<button type="button" class="button secondary" onclick="window.location.href="https://github.com/apache/isis/edit/master/adocs/documentation/src/main/asciidoc/guides/_rgant-DomainServiceLayout_named.adoc"" style="float: right; font-size: small; padding: 6px; margin-top: -55px; "><i class="fa fa-pencil-square-o"></i> Edit</button>
<div class="paragraph">
<p>The <code>named()</code> attribute explicitly specifies the domain service’s name, overriding the name that would normally be inferred from the Java source code. This attribute can also be specified for <a href="#_rgant-ActionLayout_named">actions</a>, <a href="#_rgant-CollectionLayout_named">collections</a>, <a href="#_rgant-PropertyLayout_named">properties</a>, <a href="#_rgant-ParameterLayout_named">parameters</a>, <a href="#_rgant-DomainObjectLayout_named">domain objects</a> and <a href="#_rgant-ViewModelLayout_named">view models</a>.</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>The value of this attribute also has an important role to play in the positioning of the domain service’s actions relative to the actions of other domain services. See <a href="#_rgant-DomainServiceLayout_menuOrder"><code>menuOrder()</code></a> for a full discussion with examples.</p>
</div> </td>
</tr>
</tbody>
</table>
</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">@DomainService</span>
<span class="annotation">@DomainServiceLayout</span>(
named=<span class="string"><span class="delimiter">"</span><span class="content">Customers</span><span class="delimiter">"</span></span>
)
<span class="directive">public</span> <span class="type">class</span> <span class="class">CustomerRepository</span> {
...
}</code></pre>
</div>
</div>
</div>
</div>
</div>
<div class="sect1">
<h2 id="_rgant-Facets">14. <code>@Facets</code></h2>
<button type="button" class="button secondary" onclick="window.location.href="https://github.com/apache/isis/edit/master/adocs/documentation/src/main/asciidoc/guides/_rgant-Facets.adoc"" style="float: right; font-size: small; padding: 6px; margin-top: -55px; "><i class="fa fa-pencil-square-o"></i> Edit</button>
<div class="sectionbody">
<div class="paragraph">
<p>The <code>@Facets</code> annotation allows <code>FacetFactory</code> implementations and so can be used to run install arbitrary <code>Facet`s for a type. Generally this is not needed, but can be useful for overriding a custom programming model where a `FacetFactory</code> is not typically included.</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><code>FacetFactory</code> is an important internal API that is used by Apache Isis to</p>
</div> </td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
<div class="sect1">
<h2 id="_rgant-HomePage">15. <code>@HomePage</code></h2>
<button type="button" class="button secondary" onclick="window.location.href="https://github.com/apache/isis/edit/master/adocs/documentation/src/main/asciidoc/guides/_rgant-HomePage.adoc"" style="float: right; font-size: small; padding: 6px; margin-top: -55px; "><i class="fa fa-pencil-square-o"></i> Edit</button>
<div class="sectionbody">
<div class="paragraph">
<p>The <code>@HomePage</code> annotation allows a <em>single</em> (no-arg, query-only) action on a <em>single</em> domain service to be nominated as the action to invoke for the default home page. This often returns a view model that acts as some sort of dashboard, presenting key information and makeing the most commonly used actions easy to invoke.</p>
</div>
<div class="paragraph">
<p>For example, the (non-ASF) <a href="http://github.com/isisaddons/isis-app-todoapp">Isis addons' todoapp</a> uses <code>@HomePage</code> to return a dashboard of todo items to complete:</p>
</div>
<div class="imageblock">
<div class="content">
<a class="image" href="images/reference-annotations/HomePage/HomePage.png"><img src="images/reference-annotations/HomePage/HomePage.png" alt="HomePage" width="800px"></a>
</div>
</div>
<div class="paragraph">
<p>The corresponding code is:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code data-lang="java"><span class="annotation">@DomainService</span>(nature = NatureOfService.DOMAIN)
<span class="directive">public</span> <span class="type">class</span> <span class="class">ToDoAppDashboardService</span> {
<span class="annotation">@Action</span>(
semantics = SemanticsOf.SAFE
)
<span class="annotation">@HomePage</span>
<span class="directive">public</span> ToDoAppDashboard lookup() {
<span class="keyword">return</span> container.injectServicesInto(<span class="keyword">new</span> ToDoAppDashboard());
}
<span class="annotation">@Inject</span>
<span class="directive">private</span> DomainObjectContainer container;
}</code></pre>
</div>
</div>
<div class="paragraph">
<p>where <code>ToDoAppDashboard</code> is:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code data-lang="java"><span class="annotation">@DomainObject</span>(nature = Nature.VIEW_MODEL)
<span class="directive">public</span> <span class="type">class</span> <span class="class">ToDoAppDashboard</span> {
<span class="directive">public</span> <span class="predefined-type">String</span> title() { <span class="keyword">return</span> <span class="string"><span class="delimiter">"</span><span class="content">Dashboard</span><span class="delimiter">"</span></span>; }
<span class="directive">public</span> <span class="predefined-type">List</span><ToDoItem> getNotYetComplete() { ... }
<span class="directive">public</span> <span class="predefined-type">List</span><ToDoItem> getComplete() { ... }
<span class="directive">public</span> <span class="predefined-type">Blob</span> exportToWordDoc() { ... } <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>associated using <a href="ugfun.html#_ugfun_object-layout_dynamic">dynamic layouts</a> with the <code>notYetComplete</code> collection.</td>
</tr>
</tbody>
</table>
</div>
<div class="paragraph">
<p>The other two actions shown in the above screenshot — <code>exportAsXml</code> and <code>downloadLayout</code> — are actually contributed to the <code>ToDoAppDashboard</code> through various domain services, as is the <code>downloadLayout</code> action.</p>
</div>
</div>
</div>
<div class="sect1">
<h2 id="_rgant-Inject">16. <code>@Inject</code> (<code>javax</code>)</h2>
<button type="button" class="button secondary" onclick="window.location.href="https://github.com/apache/isis/edit/master/adocs/documentation/src/main/asciidoc/guides/_rgant-Inject.adoc"" style="float: right; font-size: small; padding: 6px; margin-top: -55px; "><i class="fa fa-pencil-square-o"></i> Edit</button>
<div class="sectionbody">
<div class="paragraph">
<p>Apache Isis automatically injects domain services into other domain services and also into domain objects and view models. In fact, it also injects domain services into <a href="ugtst.html#_ugtst_integ-test-support">integration tests</a> and <a href="ugtst.html#_ugtst_fixture-scripts">fixture scripts</a>.</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>One omission: Apache Isis (currently) does not inject services into <code>o.a.i.applib.spec.Specification</code> instances (as used by <a href="#_rgant-Property_mustSatisfy"><code>@Property#mustSatisfy()</code></a> and <a href="#_rgant-Parameter_mustSatisfy"><code>@Parameter#mustSatisfy()</code></a> annotations.</p>
</div> </td>
</tr>
</tbody>
</table>
</div>
<div class="paragraph">
<p>Isis supports several syntaxes for injecting domain services. The simplest uses the <code>@javax.inject.Inject</code> annotation on the field, as defined in <a href="https://jcp.org/en/jsr/detail?id=330">JSR-330</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="directive">public</span> <span class="type">class</span> <span class="class">Customer</span> {
<span class="directive">public</span> <span class="predefined-type">List</span><Order> findRecentOrders() { <i class="conum" data-value="1"></i><b>(1)</b>
<span class="keyword">return</span> orders.recentOrdersFor(<span class="local-variable">this</span>);
}
<span class="annotation">@javax</span>.inject.Inject
OrderRepository orders; <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>an alternative implementation would be to implement <code>findRecentOrders()</code> as a <a href="ugfun.html#_ugfun_how-tos_contributed-members">contributed action</a>.</td>
</tr>
<tr>
<td><i class="conum" data-value="2"></i><b>2</b></td>
<td>we recommend default (rather than <code>private</code>) visibility so that unit tests can easily mock out the service</td>
</tr>
</tbody>
</table>
</div>
<div class="sect2">
<h3 id="_alternative_syntaxes">16.1. Alternative syntaxes</h3>
<div class="paragraph">
<p>Isis also supports setter-based injection:</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">Customer</span> {
...
public <span class="type">void</span> setOrderRepository(OrderRepository orderRepository) { ... }
}</code></pre>
</div>
</div>
<div class="paragraph">
<p>and also supports an additional syntax of using <code>inject…</code> as the prefix:</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">Customer</span> {
...
public <span class="type">void</span> injectOrderRepository(OrderRepository orderRepository) { ... }
}</code></pre>
</div>
</div>
<div class="paragraph">
<p>Generally we recommend using <code>@javax.inject.Inject</code>; it involves less code, and is more immediately familiar to most Java developers.</p>
</div>
</div>
<div class="sect2">
<h3 id="_injecting_collection_of_services">16.2. Injecting collection of services</h3>
<div class="paragraph">
<p>It can sometimes be useful to have declared multiple implementations of a particular domain service. For example, you may have a module that defines an SPI service, where multiple other modules might provide implementations of that SPI (akin to the chain of responsibility pattern). To support these scenarios, it is possible to annotate a <code>List</code> or <code>Collection</code>.</p>
</div>
<div class="paragraph">
<p>For example, suppose that we provide an SPI service to veto the placing of <code>Order</code>s for certain <code>Customer</code>s:</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">CustomerOrderAdvisorService</span> {
<span class="annotation">@Programmatic</span>
<span class="predefined-type">String</span> vetoPlaceOrder(Customer c);</code></pre>
</div>
</div>
<div class="paragraph">
<p>We could then inject a collection of these services:</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">Customer</span> {
<span class="directive">public</span> Order placeOrder(Product p, <span class="type">int</span> quantity) { ... }
<span class="directive">public</span> <span class="predefined-type">String</span> disablePlaceOrder(Product p, <span class="type">int</span> quantity) {
<span class="keyword">for</span>(CustomerOrderAdvisorService advisor: advisors) {
<span class="predefined-type">String</span> reason = advisor.vetoPlaceOrder(<span class="local-variable">this</span>);
<span class="keyword">if</span>(reason != <span class="predefined-constant">null</span>) { <span class="keyword">return</span> reason; }
}
<span class="keyword">return</span> <span class="predefined-constant">null</span>;
}
<span class="annotation">@Inject</span>
<span class="predefined-type">Collection</span><CustomerOrderAdvisorService> advisors; <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>inject a collection of the services.</td>
</tr>
</tbody>
</table>
</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>An alternative and almost equivalent design would be to publish an event using the <a href="rgsvc.html#_rgsvc_api_EventBusService"><code>EventBusService</code></a> and implement the domain services as subscribers to the event. This alternative design is used in the (non-ASF) <a href="http://github.com/isisaddons/isis-module-poly">Isis addons' poly</a> module, for example.</p>
</div> </td>
</tr>
</tbody>
</table>
</div>
</div>
<div class="sect2">
<h3 id="_manually_injecting_services">16.3. Manually injecting services</h3>
<div class="paragraph">
<p>Isis performs dependency injection when domain entities are recreated. It will also perform dependency injection if an object is created through the <code>DomainObjectContainer</code>.</p>
</div>
<div class="paragraph">
<p>For example, to create a new (transient) domain object, the idiom is:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code data-lang="java">Customer cust = container.newTransientInstance(Customer.class); <i class="conum" data-value="1"></i><b>(1)</b>
<span class="comment">// initialize state of "cust"</span>
container.persist(cust);</code></pre>
</div>
</div>
<div class="colist arabic">
<table>
<tbody>
<tr>
<td><i class="conum" data-value="1"></i><b>1</b></td>
<td>where <code>container</code> is an instance of <a href="rgsvc.html#_rgsvc_api_DomainObjectContainer"><code>DomainObjectContainer</code></a>.</td>
</tr>
</tbody>
</table>
</div>
<div class="paragraph">
<p>View models are created similarly:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code data-lang="java">ToDoAppDashboard dashboard = container.newViewModelInstance(ToDoAppDashboard.class);</code></pre>
</div>
</div>
<div class="paragraph">
<p>If you prefer, though, you can simply instantiate domain objects using "new" and then inject domain services manually:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code data-lang="java">Customer cust = <span class="keyword">new</span> Customer();
container.injectServicesInto(cust);
<span class="comment">// initialize state of "cust"</span>
container.persist(cust);</code></pre>
</div>
</div>
<div class="paragraph">
<p>or if you prefer:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code data-lang="java">Customer cust = container.injectServicesInto(<span class="keyword">new</span> Customer());
<span class="comment">// initialize state of "cust"</span>
container.persist(cust);</code></pre>
</div>
</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>There is one subtle difference between using <code>DomainObjectContainer#newTransientInstance(…)</code> and <code>DomainObjectContainer#injectServicesInto(…)</code>, in that with the former Apache Isis will automatically initialize all fields to their default values.</p>
</div>
<div class="paragraph">
<p>This isn’t a particular useful feature (and indeed can sometimes be rather confusing) so you may well wish to standardize on using <code>injectServicesInto(…)</code> throughout.</p>
</div> </td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
</div>
<div class="sect1">
<h2 id="_rgant-MemberGroupLayout">17. <code>@MemberGroupLayout</code></h2>
<button type="button" class="button secondary" onclick="window.location.href="https://github.com/apache/isis/edit/master/adocs/documentation/src/main/asciidoc/guides/_rgant-MemberGroupLayout.adoc"" style="float: right; font-size: small; padding: 6px; margin-top: -55px; "><i class="fa fa-pencil-square-o"></i> Edit</button>
<div class="sectionbody">
<div class="paragraph">
<p>The <code>@MemberGroupLayout</code> annotation specifies how an object’s properties and collections are grouped together into columns, also specifying the relative positioning of those columns. It works in conjunction with the <a href="#_rgant-MemberOrder"><code>@MemberOrder</code></a> annotation.</p>
</div>
<div class="paragraph">
<p>The <code>@MemberOrder</code> annotation is used to specify the relative order of domain object members, that is: properties, collections and actions. It works in conjunction with the <a href="#_rgant-MemberGroupLayout"><code>@MemberGroupLayout</code></a> annotation.</p>
</div>
<div class="paragraph">
<p>The annotation defines two attributes, <code>name()</code> and <code>sequence()</code>. Broadly speaking the <code>name()</code> attribute is used to group or associate members together, while the <code>sequence()</code> attribute orders members once they have been grouped.</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>As this is an important topic, there is a <a href="ugfun.html#_ugfun_object-layout">separate chapter</a> that discussed object layout in full.</p>
</div> </td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
<div class="sect1">
<h2 id="_rgant-MemberOrder">18. <code>@MemberOrder</code></h2>
<button type="button" class="button secondary" onclick="window.location.href="https://github.com/apache/isis/edit/master/adocs/documentation/src/main/asciidoc/guides/_rgant-MemberOrder.adoc"" style="float: right; font-size: small; padding: 6px; margin-top: -55px; "><i class="fa fa-pencil-square-o"></i> Edit</button>
<div class="sectionbody">
<div class="paragraph">
<p>The <code>@MemberOrder</code> annotation is used to specify the relative order of domain object members, that is: properties, collections and actions. It works in conjunction with the <a href="#_rgant-MemberGroupLayout"><code>@MemberGroupLayout</code></a> annotation.</p>
</div>
<div class="paragraph">
<p>The annotation defines four attributes:</p>
</div>
<div class="ulist">
<ul>
<li> <p><code>columnSpans()</code> — of type <code>int[]</code> — which specifies the relative column sizes of the three columns that render properties as well as a fourth column that renders only collections</p> </li>
<li> <p><code>left()</code> — of type <code>String[]</code> - that specifies the order of the property groups (inferred from <code>@MemberOrder#name()</code>) as applied to properties) in the left-most column</p> </li>
<li> <p><code>middle()</code> — of type <code>String[]</code> - that specifies the order of the property groups (if any) as applied to properties) in the middle column</p> </li>
<li> <p><code>right()</code> — of type <code>String[]</code> - that specifies the order of the property groups (if any) as applied to properties) in the right-most column</p> </li>
</ul>
</div>
<div class="paragraph">
<p>Collections are always rendered in the "last" column. This can appear either below the columns holding properties (if their column spans = 12), or can be rendered to the right of the property columns (if the spans of the property columns come to <12 leaving enough room for the span of the collection column).</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>As this is an important topic, there is a <a href="ugfun.html#_ugfun_object-layout">separate chapter</a> that discussed object layout in full.</p>
</div> </td>
</tr>
</tbody>
</table>
</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>The annotation is one of a handful (others including <a href="#_rgant-Collection"><code>@Collection</code></a>, <a href="#_rgant-CollectionLayout"><code>@CollectionLayout</code></a>, <a href="#_rgant-Property"><code>@Property</code></a>) and <a href="#_rgant-PropertyLayout"><code>@PropertyLayout</code></a> that can also be applied to the field, rather than the getter method. This is specifically so that boilerplate-busting tools such as <a href="https://projectlombok.org/">Project Lombok</a> can be used.</p>
</div> </td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
<div class="sect1">
<h2 id="_rgant-Mixin">19. <code>@Mixin</code></h2>
<button type="button" class="button secondary" onclick="window.location.href="https://github.com/apache/isis/edit/master/adocs/documentation/src/main/asciidoc/guides/_rgant-Mixin.adoc"" style="float: right; font-size: small; padding: 6px; margin-top: -55px; "><i class="fa fa-pencil-square-o"></i> Edit</button>
<div class="sectionbody">
<div class="paragraph">
<p>The <code>@Mixin</code> annotation indicates that the class acts as a mixin, contributing behaviour - actions, (derived) properties and (derived) collections - to another domain object.</p>
</div>
<div class="paragraph">
<p>Mixins were originally introduced as a means of allowing contributions from one module to the types of another module; in such cases the mixin type is often an interface type (eg <code>DocumentHolder</code>) that might be implemented by numerous different concrete types. However, mixins are also a convenient mechanism for grouping functionality even for a concrete type.</p>
</div>
<div class="paragraph">
<p>For further discussion on using mixins, see <a href="ugbtb.html#_ugbtb_decoupling_mixins">mixins</a> in the user guide.</p>
</div>
<div class="paragraph">
<p>The table below summarizes the annotation’s attributes.</p>
</div>
<table class="tableblock frame-all grid-all spread">
<caption class="title">
Table 16.
<code>@Mixin</code> attributes
</caption>
<colgroup>
<col style="width: 25%;">
<col style="width: 25%;">
<col style="width: 50%;">
</colgroup>
<thead>
<tr>
<th class="tableblock halign-left valign-top">Attribute</th>
<th class="tableblock halign-left valign-top">Values (default)</th>
<th class="tableblock halign-left valign-top">Description</th>
</tr>
</thead>
<tbody>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="#_rgant-Mixin_method"><code>method()</code></a></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Method name within the mixin</p></td>
<td class="tableblock halign-left valign-top">
<div>
<div class="paragraph">
<p>How to recognize the "reserved" method name, meaning that the mixin’s own name will be inferred from the mixin type. Typical examples are "exec", "execute", "invoke", "apply" and so on. The default "reserved" method name is <code>$$</code>.</p>
</div>
</div></td>
</tr>
</tbody>
</table>
<div class="paragraph">
<p>An alternative and equivalent approach is to use the <a href="#_rgant-DomainObject_nature"><code>@DomainObject#nature()</code></a> annotation with a nature of <code>MIXIN</code>.</p>
</div>
<div class="sect2">
<h3 id="_rgant-Mixin_method">19.1. <code>method()</code></h3>
<button type="button" class="button secondary" onclick="window.location.href="https://github.com/apache/isis/edit/master/adocs/documentation/src/main/asciidoc/guides/_rgant-Mixin_method.adoc"" style="float: right; font-size: small; padding: 6px; margin-top: -55px; "><i class="fa fa-pencil-square-o"></i> Edit</button>
<div class="paragraph">
<p>The <code>method()</code> attribute specifies the name of the method to be treated as a "reserved" method name, meaning that the mixin’s name should instead be inferred from the mixin’s type.</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">@DomainObject</span>
<span class="directive">public</span> <span class="type">class</span> <span class="class">Customer</span> {
<span class="annotation">@Mixin</span>(method=<span class="string"><span class="delimiter">"</span><span class="content">execute</span><span class="delimiter">"</span></span>)
<span class="directive">public</span> <span class="directive">static</span> <span class="type">class</span> <span class="class">placeOrder</span> {
Customer customer;
<span class="directive">public</span> placeOrder(Customer customer) { <span class="local-variable">this</span>.customer = customer; }
<span class="directive">public</span> Customer execute(Product p, <span class="type">int</span> quantity) { ... }
<span class="directive">public</span> <span class="predefined-type">String</span> disableExecute() { ... }
<span class="directive">public</span> <span class="predefined-type">String</span> validate0Execute() { ... }
}
...
)</code></pre>
</div>
</div>
<div class="paragraph">
<p>This allows all mixins to follow a similar convention, with the name of the mixin inferred entirely from its type ("placeOrder").</p>
</div>
<div class="paragraph">
<p>When invoked programmatically, the code reads:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code data-lang="java">mixin(Customer.placeOrder.class, someCustomer).execute(someProduct, <span class="integer">3</span>);</code></pre>
</div>
</div>
</div>
</div>
</div>
<div class="sect1">
<h2 id="_rgant-Nullable">20. <code>@Nullable</code> (<code>javax</code>)</h2>
<button type="button" class="button secondary" onclick="window.location.href="https://github.com/apache/isis/edit/master/adocs/documentation/src/main/asciidoc/guides/_rgant-Nullable.adoc"" style="float: right; font-size: small; padding: 6px; margin-top: -55px; "><i class="fa fa-pencil-square-o"></i> Edit</button>
<div class="sectionbody">
<div class="paragraph">
<p>Apache Isis' defaults for properties and parameters is that they are mandatory unless otherwise stated. The <code>@javax.annotation.Nullable</code> annotation is recognized by Apache Isis for both properties and parameters as means to indicate that the property/parameter is not mandatory.</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">@javax</span>.annotation.Nullable
<span class="directive">public</span> <span class="predefined-type">String</span> getName() {
<span class="keyword">return</span> name;
}
<span class="directive">public</span> <span class="type">void</span> setName(<span class="directive">final</span> <span class="predefined-type">String</span> name) {
<span class="local-variable">this</span>.name = name;
}</code></pre>
</div>
</div>
<div class="paragraph">
<p>or:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code data-lang="java"><span class="directive">public</span> Customer updateName(<span class="annotation">@javax</span>.annotation.Nullable <span class="directive">final</span> <span class="predefined-type">String</span> name) {
setName(name);
<span class="keyword">return</span> <span class="local-variable">this</span>;
}</code></pre>
</div>
</div>
<div class="paragraph">
<p>Apache Isis does provide several other ways to specify optionality: using the <a href="#_rgant_Property_optionality"><code>@Property#optionality()</code></a> / <a href="#_rgant_Parameter_optionality"><code>@Parameter#optionality()</code></a> annotation. For properties, the optionality can also be inferred from the <a href="#_rgant_Column_allowsNull"><code>@Column#allowsNull()</code></a> attribute.</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>See the <a href="#_rgant_Property_optionality"><code>@Property#optionality()</code></a> documentation for a much fuller discussion on the relationship between using the Apache Isis annotations vs <a href="#_rgant_Column_allowsNull"><code>@Column#allowsNull()</code></a>.</p>
</div> </td>
</tr>
</tbody>
</table>
</div>
<div class="paragraph">
<p>If more than one method is specified then the framework will validate that there are no incompatibilities (and fail to boot otherwise). This can also be verified using the <a href="rgmvn.html#_rgmvn_validate">validate goal</a> of the Apache Isis Maven plugin.</p>
</div>
</div>
</div>
<div class="sect1">
<h2 id="_rgant-NotPersistent">21. <code>@NotPersistent</code> (<code>javax.jdo</code>)</h2>
<button type="button" class="button secondary" onclick="window.location.href="https://github.com/apache/isis/edit/master/adocs/documentation/src/main/asciidoc/guides/_rgant-NotPersistent.adoc"" style="float: right; font-size: small; padding: 6px; margin-top: -55px; "><i class="fa fa-pencil-square-o"></i> Edit</button>
<div class="sectionbody">
<div class="paragraph">
<p>The <code>@javax.jdo.annotation.NotPersistent</code> annotation is used by JDO/DataNucleus to indicate that a property should not be persisted to the database.</p>
</div>
<div class="paragraph">
<p>Apache Isis also uses this annotation, though (currently) only in the very minimal way to suppress checking of inconsistent metadata between JDO and Isis annotations (eg <code>@Column#allowsNull()</code> vs <code>@Property#optionality()</code>, or <code>@Column#length()</code> and <code>@Property#maxLength()</code>).</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>Isis parses the <code>@NotPersistent</code> annotation from the Java source code; it does not query the JDO metamodel. This means that it the <code>@NotPersistent</code> annotation must be used rather than the equivalent <code><field></code> <a href="http://www.datanucleus.org/products/accessplatform_4_0/jdo/fields_properties.html">XML metadata</a>.</p>
</div>
<div class="paragraph">
<p>Moreover, while JDO/DataNucleus will recognize annotations on either the field or the getter method, Apache Isis (currently) only inspects the getter method. Therefore ensure that the annotation is placed there.</p>
</div> </td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
<div class="sect1">
<h2 id="_rgant-MinLength">22. <code>@MinLength</code></h2>
<button type="button" class="button secondary" onclick="window.location.href="https://github.com/apache/isis/edit/master/adocs/documentation/src/main/asciidoc/guides/_rgant-MinLength.adoc"" style="float: right; font-size: small; padding: 6px; margin-top: -55px; "><i class="fa fa-pencil-square-o"></i> Edit</button>
<div class="sectionbody">
<div class="paragraph">
<p>The <code>@MinLength</code> annotation is used to specify the minimum number of characters in a search of an <a href="rgcms.html#_rgcms_methods_prefixes_autoComplete"><code>autoComplete…()</code></a> supporting method.</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> ToDoItem add(
<span class="annotation">@TypicalLength</span>(<span class="integer">20</span>)
<span class="directive">final</span> ToDoItem toDoItem) {
getDependencies().add(toDoItem);
<span class="keyword">return</span> <span class="local-variable">this</span>;
}
<span class="directive">public</span> <span class="predefined-type">List</span><ToDoItem> autoComplete0Add(
<span class="directive">final</span> <span class="annotation">@MinLength</span>(<span class="integer">2</span>)
<span class="predefined-type">String</span> search) {
<span class="directive">final</span> <span class="predefined-type">List</span><ToDoItem> list = toDoItems.autoComplete(search);
list.removeAll(getDependencies());
list.remove(<span class="local-variable">this</span>);
<span class="keyword">return</span> list;
}</code></pre>
</div>
</div>
<div class="paragraph">
<p>The `@Parameter(minLength=…)`e can also be used (even though strictly speaking the search argument is not a parameter of the action).</p>
</div>
</div>
</div>
<div class="sect1">
<h2 id="_rgant-Parameter">23. <code>@Parameter</code></h2>
<button type="button" class="button secondary" onclick="window.location.href="https://github.com/apache/isis/edit/master/adocs/documentation/src/main/asciidoc/guides/_rgant-Parameter.adoc"" style="float: right; font-size: small; padding: 6px; margin-top: -55px; "><i class="fa fa-pencil-square-o"></i> Edit</button>
<div class="sectionbody">
<div class="paragraph">
<p>The <code>@Parameter</code> annotation applies to action parameters collecting together all domain semantics within a single annotation.</p>
</div>
<div class="paragraph">
<p>The table below summarizes the annotation’s attributes.</p>
</div>
<table class="tableblock frame-all grid-all spread">
<caption class="title">
Table 17.
<code>@Paramter</code> attributes
</caption>
<colgroup>
<col style="width: 25%;">
<col style="width: 25%;">
<col style="width: 50%;">
</colgroup>
<thead>
<tr>
<th class="tableblock halign-left valign-top">Attribute</th>
<th class="tableblock halign-left valign-top">Values (default)</th>
<th class="tableblock halign-left valign-top">Description</th>
</tr>
</thead>
<tbody>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="#_rgant-Parameter_fileAccept"><code>fileAccept()</code></a></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Media type or file extension</p></td>
<td class="tableblock halign-left valign-top">
<div>
<div class="paragraph">
<p>Hints the file type to be uploaded for <a href="rgcms.html#_rgcms_classes_value-types_Blob"><code>Blob</code></a> or <a href="rgcms.html#_rgcms_classes_value-types_Clob"><code>Clob</code></a>.<br> <br> Note that this does not prevent the user from uploading some other file type; rather it merely defaults the file type in the file open dialog.</p>
</div>
</div></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="#_rgant-Parameter_maxLength"><code>maxLength()</code></a></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Positive integer</p></td>
<td class="tableblock halign-left valign-top">
<div>
<div class="paragraph">
<p>maximum number of characters for string parameters; ignored otherwise</p>
</div>
</div></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>minLength()</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Positive integer</p></td>
<td class="tableblock halign-left valign-top">
<div>
<div class="paragraph">
<p>Deprecated; use <a href="#_rgant_minLength"><code>@MinLength</code></a> instead.<br></p>
</div>
<div class="paragraph">
<p>Can be used to specify the minimum length for <a href="rgcms.html#<em>rgcms_methods_prefixes_autoComplete"><code>autoComplete…()</code></a> supporting method; but because this _is a supporting method rather than the action method itself, we now feel it is misleading to use the <code>@Parameter</code> annotation in this situation.</p>
</div>
</div></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="#_rgant-Parameter_mustSatisfy"><code>mustSatisfy()</code></a></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">implementation of <code>o.a.i.applib.spec.Specification</code></p></td>
<td class="tableblock halign-left valign-top">
<div>
<div class="paragraph">
<p>allows arbitrary validation to be applied</p>
</div>
</div></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="#_rgant-Parameter_optionality"><code>optionality()</code></a></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>MANDATORY</code>, <code>OPTIONAL</code> (<code>MANDATORY</code>)</p></td>
<td class="tableblock halign-left valign-top">
<div>
<div class="paragraph">
<p>specifies a parameter is optional rather than mandatory</p>
</div>
</div></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="#_rgant-Parameter_regexPattern">regexPattern()</a></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">regular expression</p></td>
<td class="tableblock halign-left valign-top">
<div>
<div class="paragraph">
<p>validates the contents of a string parameter against the regular expression pattern</p>
</div>
</div></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>regexPatternFlags()</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">value of flags as normally passed to <code>java.util.regex.</code><br> <code>Pattern#compile(…)</code></p></td>
<td class="tableblock halign-left valign-top">
<div>
<div class="paragraph">
<p>modifies the compilation of the regular expression</p>
</div>
</div></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>regexPatternReplacement()</code></p></td>
<td class="tableblock halign-left valign-top"></td>
<td class="tableblock halign-left valign-top">
<div>
<div class="paragraph">
<p>Unused.</p>
</div>
</div></td>
</tr>
</tbody>
</table>
<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">class</span> <span class="class">Customer</span> {
<span class="directive">public</span> <span class="directive">static</span> <span class="type">class</span> <span class="class">EmailSpecification</span> <span class="directive">extends</span> AbstractSpecification<<span class="predefined-type">String</span>> {
<span class="directive">public</span> <span class="predefined-type">String</span> satisfiesSafely(<span class="predefined-type">String</span> proposed) {
<span class="keyword">return</span> EmailUtil.ensureValidEmail(proposed); <i class="conum" data-value="1"></i><b>(1)</b>
}
}
<span class="annotation">@Action</span>(semantics=SemanticsOf.IDEMPOTENT)
<span class="directive">public</span> Customer updateEmail(
<span class="annotation">@Parameter</span>(
maxLength=<span class="integer">30</span>,
mustSatisfy=EmailSpecification.class,
optionality=Optionality.OPTIONAL,
regexPattern = <span class="string"><span class="delimiter">"</span><span class="content">(</span><span class="char">\\</span><span class="content">w+</span><span class="char">\\</span><span class="content">.)*</span><span class="char">\\</span><span class="content">w+@(</span><span class="char">\\</span><span class="content">w+</span><span class="char">\\</span><span class="content">.)+[A-Za-z]+</span><span class="delimiter">"</span></span>,
regexPatternFlags=<span class="predefined-type">Pattern</span>.CASE_INSENSITIVE
)
<span class="annotation">@ParameterLayout</span>(named=<span class="string"><span class="delimiter">"</span><span class="content">New Email Address</span><span class="delimiter">"</span></span>)
<span class="directive">final</span> <span class="predefined-type">String</span> newEmailAddress
...
}
}</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 (fictitious) <code>EmailUtil.ensureValid(…)</code> (omitted for brevity) returns a string explaining if an email is invalid</td>
</tr>
</tbody>
</table>
</div>
<div class="sect2">
<h3 id="_rgant-Parameter_fileAccept">23.1. <code>fileAccept()</code></h3>
<button type="button" class="button secondary" onclick="window.location.href="https://github.com/apache/isis/edit/master/adocs/documentation/src/main/asciidoc/guides/_rgant-Parameter_fileAccept.adoc"" style="float: right; font-size: small; padding: 6px; margin-top: -55px; "><i class="fa fa-pencil-square-o"></i> Edit</button>
<div class="paragraph">
<p>The <code>fileAccept()</code> attribute applies only to <a href="rgcms.html#_rgcms_classes_value-types_Blob"><code>Blob</code></a> or <a href="rgcms.html#_rgcms_classes_value-types_Clob"><code>Clob</code></a> parameters, indicating the type of file to accept when uploading a new value. The attribute is also supported on <a href="#_rgant-Property_fileAccept">properties</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="directive">public</span> <span class="type">class</span> <span class="class">Scanner</span> {
<span class="directive">public</span> ScannedDocument newScan(
<span class="annotation">@Parameter</span>(fileAccept=<span class="string"><span class="delimiter">"</span><span class="content">image/*</span><span class="delimiter">"</span></span>) <i class="conum" data-value="1"></i><b>(1)</b>
<span class="annotation">@ParameterLayout</span>(named=<span class="string"><span class="delimiter">"</span><span class="content">Scanned image</span><span class="delimiter">"</span></span>) <i class="conum" data-value="2"></i><b>(2)</b>
<span class="directive">final</span> <span class="predefined-type">Blob</span> scannedImage) {
...
}
}</code></pre>
</div>
</div>
<div class="colist arabic">
<table>
<tbody>
<tr>
<td><i class="conum" data-value="1"></i><b>1</b></td>
<td>as per <a href="http://www.w3schools.com/tags/att_input_accept.asp">reference docs</a>, either a media type (such as <code>image/*</code>) or a file type extension (such as <code>.png</code>).</td>
</tr>
<tr>
<td><i class="conum" data-value="2"></i><b>2</b></td>
<td>the <code>@ParameterLayout(named=…)</code> attribute is required for Java 7; for Java 8 it can be omitted if the (non-ASF) <a href="http://github.com/isisaddons/isis-metamodel-paraname8">Isis addons' paraname8</a> metamodel extension is used.</td>
</tr>
</tbody>
</table>
</div>
</div>
<div class="sect2">
<h3 id="_rgant-Parameter_maxLength">23.2. <code>maxLength()</code></h3>
<button type="button" class="button secondary" onclick="window.location.href="https://github.com/apache/isis/edit/master/adocs/documentation/src/main/asciidoc/guides/_rgant-Parameter_maxLength.adoc"" style="float: right; font-size: small; padding: 6px; margin-top: -55px; "><i class="fa fa-pencil-square-o"></i> Edit</button>
<div class="paragraph">
<p>The <code>maxLength()</code> attribute applies only to <code>String</code> parameters, indicating the maximum number of characters that the user may enter (for example in a text field in the UI). It is ignored if applied to parameters of any other type. This attribute can also be applied to <a href="#_rgant-Property_maxLength">properties</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="directive">public</span> <span class="type">class</span> <span class="class">CustomerRepository</span> {
<span class="directive">public</span> Customer newCustomer(
<span class="annotation">@Parameter</span>(maxLength=<span class="integer">30</span>)
<span class="annotation">@ParameterLayout</span>(named=<span class="string"><span class="delimiter">"</span><span class="content">First Name</span><span class="delimiter">"</span></span>) <i class="conum" data-value="1"></i><b>(1)</b>
<span class="directive">final</span> <span class="predefined-type">String</span> firstName,
<span class="annotation">@Parameter</span>(maxLength=<span class="integer">50</span>)
<span class="annotation">@ParameterLayout</span>(named=<span class="string"><span class="delimiter">"</span><span class="content">Last Name</span><span class="delimiter">"</span></span>)
<span class="directive">final</span> <span class="predefined-type">String</span> lastName) {
...
}
}</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 <code>@ParameterLayout(named=…)</code> attribute is required for Java 7; for Java 8 it can be omitted if the (non-ASF) <a href="http://github.com/isisaddons/isis-metamodel-paraname8">Isis addons' paraname8</a> metamodel extension is used.</td>
</tr>
</tbody>
</table>
</div>
</div>
<div class="sect2">
<h3 id="_rgant-Parameter_mustSatisfy">23.3. <code>mustSatisfy()</code></h3>
<button type="button" class="button secondary" onclick="window.location.href="https://github.com/apache/isis/edit/master/adocs/documentation/src/main/asciidoc/guides/_rgant-Parameter_mustSatisfy.adoc"" style="float: right; font-size: small; padding: 6px; margin-top: -55px; "><i class="fa fa-pencil-square-o"></i> Edit</button>
<div class="paragraph">
<p>The <code>mustSatisfy()</code> attribute allows arbitrary validation to be applied to parameters using an (implementation of a) <code>org.apache.isis.applib.spec.Specification</code> object. The attribute is also supported on <a href="#_rgant-Property_mustSatisfy">properties</a>.</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>The specification implementations can (of course) be reused between parameters and <a href="#_rgant-Property_mustSatisfy">properties</a>.</p>
</div> </td>
</tr>
</tbody>
</table>
</div>
<div class="paragraph">
<p>The <code>Specification</code> is consulted during validation, being passed the proposed value. If the proposed value fails, then the value returned is the used as the invalidity reason.</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">class</span> <span class="class">StartWithCapitalLetterSpecification</span>
<span class="directive">extends</span> AbstractSpecification<<span class="predefined-type">String</span>> { <i class="conum" data-value="1"></i><b>(1)</b>
<span class="directive">public</span> <span class="predefined-type">String</span> satisfiesSafely(<span class="predefined-type">String</span> proposed) {
<span class="keyword">return</span> <span class="string"><span class="delimiter">"</span><span class="delimiter">"</span></span>.equals(proposed)
? <span class="string"><span class="delimiter">"</span><span class="content">Empty string</span><span class="delimiter">"</span></span>
: !<span class="predefined-type">Character</span>.isUpperCase(proposed.charAt(<span class="integer">0</span>))
? <span class="string"><span class="delimiter">"</span><span class="content">Does not start with a capital letter</span><span class="delimiter">"</span></span>
: <span class="predefined-constant">null</span>;
}
}
<span class="directive">public</span> <span class="type">class</span> <span class="class">CustomerRepository</span> {
<span class="directive">public</span> Customer newCustomer(
<span class="annotation">@Parameter</span>(
mustSatisfy=StartWithCapitalLetterSpecification.class
)
<span class="annotation">@ParameterLayout</span>(named=<span class="string"><span class="delimiter">"</span><span class="content">First Name</span><span class="delimiter">"</span></span>)
<span class="directive">final</span> <span class="predefined-type">String</span> firstName,
<span class="annotation">@Parameter</span>(
mustSatisfy=StartWithCapitalLetterSpecification.class
)
<span class="annotation">@ParameterLayout</span>(named=<span class="string"><span class="delimiter">"</span><span class="content">Last Name</span><span class="delimiter">"</span></span>)
<span class="directive">final</span> <span class="predefined-type">String</span> lastName) {
...
}
...
}</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 <code>AbstractSpecification</code> class conveniently handles type-safety and dealing with null values. The applib also provides <code>SpecificationAnd</code> and <code>SpecificationOr</code> to allow specifications to be combined "algebraically".</td>
</tr>
</tbody>
</table>
</div>
<div class="paragraph">
<p>It is also possible to provide translatable reasons. Rather than implement <code>Specification</code>, instead implement <code>Specification2</code> which defines the 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">Specification2</span> <span class="directive">extends</span> Specification {
<span class="directive">public</span> TranslatableString satisfiesTranslatable(<span class="predefined-type">Object</span> obj); <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>Return <code>null</code> if specification satisfied, otherwise the reason as a translatable string</td>
</tr>
</tbody>
</table>
</div>
<div class="paragraph">
<p>With <code>Specification2</code> there is no need to implement the inherited <code>satifies(Object)</code>; that method will never be called.</p>
</div>
</div>
<div class="sect2">
<h3 id="_rgant-Parameter_optionality">23.4. <code>optionality()</code></h3>
<button type="button" class="button secondary" onclick="window.location.href="https://github.com/apache/isis/edit/master/adocs/documentation/src/main/asciidoc/guides/_rgant-Parameter_optionality.adoc"" style="float: right; font-size: small; padding: 6px; margin-top: -55px; "><i class="fa fa-pencil-square-o"></i> Edit</button>
<div class="paragraph">
<p>By default, Apache Isis assumes that all parameters of an action are required (mandatory). The <code>optionality()</code> attribute allows this to be relaxed. The attribute is also supported for <a href="#_rgant-Property_optionality">properties</a>.</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>The attribute has no meaning for a primitive type such as <code>int</code>: primitives will always have a default value (e.g. zero). If optionality is required, then use the corresponding wrapper class (e.g. <code>java.lang.Integer</code>) and annotate with <code>Parameter#optionality()</code> as required.</p>
</div> </td>
</tr>
</tbody>
</table>
</div>
<div class="paragraph">
<p>The values for the attribute are simply <code>OPTIONAL</code> or <code>MANDATORY</code>.</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">class</span> <span class="class">Customer</span> {
<span class="directive">public</span> Order placeOrder(
<span class="directive">final</span> Product product,
<span class="annotation">@ParameterLayout</span>(named = <span class="string"><span class="delimiter">"</span><span class="content">Quantity</span><span class="delimiter">"</span></span>)
<span class="directive">final</span> <span class="type">int</span> quantity,
<span class="annotation">@Parameter</span>(optionality = Optionality.OPTIONAL)
<span class="annotation">@ParameterLayout</span>(named = <span class="string"><span class="delimiter">"</span><span class="content">Special Instructions</span><span class="delimiter">"</span></span>)
<span class="directive">final</span> <span class="predefined-type">String</span> instr) {
...
}
...
}</code></pre>
</div>
</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>It is also possible to specify optionality using <a href="#_rgant_Nullable"><code>@Nullable</code></a> annotation.</p>
</div> </td>
</tr>
</tbody>
</table>
</div>
</div>
<div class="sect2">
<h3 id="_rgant-Parameter_regexPattern">23.5. <code>regexPattern()</code></h3>
<button type="button" class="button secondary" onclick="window.location.href="https://github.com/apache/isis/edit/master/adocs/documentation/src/main/asciidoc/guides/_rgant-Parameter_regexPattern.adoc"" style="float: right; font-size: small; padding: 6px; margin-top: -55px; "><i class="fa fa-pencil-square-o"></i> Edit</button>
<div class="paragraph">
<p>There are three attributes related to enforcing regular expressions:</p>
</div>
<div class="ulist">
<ul>
<li> <p>The <code>regexPattern()</code> attribute validates the contents of any string parameter with respect to a regular expression pattern. It is ignored if applied to parameters of any other type. This attribute can also be specified for <a href="#_rgant-Property_regexPattern">properties</a>.</p> </li>
<li> <p>The <code>regexPatternFlags()</code> attribute specifies flags that modify the handling of the pattern. The values are those that would normally be passed to <code>java.util.regex.Pattern#compile(String,int)</code>.</p> </li>
<li> <p>The related <code>regexPatternReplacement()</code> attribute specifies the error message to show if the provided argument does not match the regex pattern.</p> </li>
</ul>
</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">class</span> <span class="class">Customer</span> {
<span class="directive">public</span> <span class="type">void</span> updateEmail(
<span class="annotation">@Parameter</span>(
regexPattern = <span class="string"><span class="delimiter">"</span><span class="content">(</span><span class="char">\\</span><span class="content">w+</span><span class="char">\\</span><span class="content">.)*</span><span class="char">\\</span><span class="content">w+@(</span><span class="char">\\</span><span class="content">w+</span><span class="char">\\</span><span class="content">.)+[A-Za-z]+</span><span class="delimiter">"</span></span>,
regexPatternFlags = <span class="predefined-type">Pattern</span>.CASE_INSENSITIVE,
regexPatternReplacement = <span class="string"><span class="delimiter">"</span><span class="content">Must be valid email address (containing a '@') symbol</span><span class="delimiter">"</span></span> <i class="conum" data-value="1"></i><b>(1)</b>
)
<span class="annotation">@ParameterLayout</span>(named = <span class="string"><span class="delimiter">"</span><span class="content">Email</span><span class="delimiter">"</span></span>)
<span class="directive">final</span> <span class="predefined-type">String</span> email) {
...
}
)</code></pre>
</div>
</div>
<div class="colist arabic">
<table>
<tbody>
<tr>
<td><i class="conum" data-value="1"></i><b>1</b></td>
<td>Note that there is currently no i18n support for this phrase.</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
</div>
<div class="sect1">
<h2 id="_rgant-ParameterLayout">24. <code>@ParameterLayout</code></h2>
<button type="button" class="button secondary" onclick="window.location.href="https://github.com/apache/isis/edit/master/adocs/documentation/src/main/asciidoc/guides/_rgant-ParameterLayout.adoc"" style="float: right; font-size: small; padding: 6px; margin-top: -55px; "><i class="fa fa-pencil-square-o"></i> Edit</button>
<div class="sectionbody">
<div class="paragraph">
<p>The <code>@ParameterLayout</code> annotation applies to action parameters, collecting together all UI hints within a single annotation.</p>
</div>
<div class="paragraph">
<p>The table below summarizes the annotation’s attributes.</p>
</div>
<table class="tableblock frame-all grid-all spread">
<caption class="title">
Table 18.
<code>@ParameterLayout</code> attributes
</caption>
<colgroup>
<col style="width: 25%;">
<col style="width: 25%;">
<col style="width: 50%;">
</colgroup>
<thead>
<tr>
<th class="tableblock halign-left valign-top">Attribute</th>
<th class="tableblock halign-left valign-top">Values (default)</th>
<th class="tableblock halign-left valign-top">Description</th>
</tr>
</thead>
<tbody>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="#_rgant-ParameterLayout_cssClass"><code>cssClass()</code></a></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Any string valid as a CSS class</p></td>
<td class="tableblock halign-left valign-top">
<div>
<div class="paragraph">
<p>the css class that a parameter should have, to allow more targetted styling in <a href="rgcfg.html#_rgcfg_application-specific_application-css"><code>application.css</code></a></p>
</div>
</div></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="#_rgant-ParameterLayout_describedAs"><code>describedAs()</code></a></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">String</p></td>
<td class="tableblock halign-left valign-top">
<div>
<div class="paragraph">
<p>description of this parameter, eg to be rendered in a tooltip.</p>
</div>
</div></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="#_rgant-ParameterLayout_labelPosition"><code>labelPosition()</code></a></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>LEFT</code>, <code>TOP</code>, <code>RIGHT</code>, <code>NONE</code><br> (<code>LEFT</code>)</p></td>
<td class="tableblock halign-left valign-top">
<div>
<div class="paragraph">
<p>in forms, the positioning of the label relative to the property value.<br></p>
</div>
<div class="paragraph">
<p>Default is <code>LEFT</code>, unless <a href="#_rgant-ParameterLayout_multiLine"><code>multiLine</code></a> in which case <code>TOP</code>. The value <code>RIGHT</code> is only supported for boolean parameters.</p>
</div>
</div></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="#_rgant-ParameterLayout_multiLine"><code>multiLine()</code></a></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Positive integer</p></td>
<td class="tableblock halign-left valign-top">
<div>
<div class="paragraph">
<p>for string parameters, render as a text area over multiple lines.<br></p>
</div>
<div class="paragraph">
<p>If set > 1, then then <a href="#_rgant-ParameterLayout_labelPosition"><code>labelPosition</code></a> defaults to <code>TOP</code>.</p>
</div>
</div></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="#_rgant-ParameterLayout_named"><code>named()</code></a></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">String</p></td>
<td class="tableblock halign-left valign-top">
<div>
<div class="paragraph">
<p>the name of this parameter.<br></p>
</div>
<div class="paragraph">
<p>For Java 7 this is generally required. For Java 8, the name can often be inferred from the code so this attribute allows the name to be overridden. A typical use case is if the desired name is a reserved Java keyword, such as <code>default</code> or <code>package</code>.</p>
</div>
</div></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>namedEscaped()</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>true</code>, <code>false</code> (<code>true</code>)</p></td>
<td class="tableblock halign-left valign-top">
<div>
<div class="paragraph">
<p>whether to HTML escape the name of this parameter.</p>
</div>
</div></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="#_rgant-ParameterLayout_renderedAsDayBefore"><code>renderedAsDayBefore()</code></a></p></td>
<td class="tableblock halign-left valign-top"></td>
<td class="tableblock halign-left valign-top">
<div>
<div class="paragraph">
<p>for date parameters only, render the date as one day prior to the actually stored date (eg the end date of an open interval into a closed interval)</p>
</div>
</div></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="#_rgant-ParameterLayout_typicalLength"><code>typicalLength()</code></a></p></td>
<td class="tableblock halign-left valign-top"></td>
<td class="tableblock halign-left valign-top">
<div>
<div class="paragraph">
<p>the typical entry length of a field, use to determine the optimum width for display</p>
</div>
</div></td>
</tr>
</tbody>
</table>
<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">class</span> <span class="class">ToDoItem</span> {
<span class="directive">public</span> ToDoItem updateDescription(
<span class="annotation">@ParameterLayout</span>(
cssClass=<span class="string"><span class="delimiter">"</span><span class="content">x-key</span><span class="delimiter">"</span></span>,
describedAs=<span class="string"><span class="delimiter">"</span><span class="content">What needs to be done</span><span class="delimiter">"</span></span>,
labelPosition=LabelPosition.LEFT,
named=<span class="string"><span class="delimiter">"</span><span class="content">Description of this <i>item</i></span><span class="delimiter">"</span></span>,
namedEscaped=<span class="predefined-constant">false</span>,
typicalLength=<span class="integer">80</span>)
<span class="directive">final</span> <span class="predefined-type">String</span> description) {
setDescription(description);
<span class="keyword">return</span> <span class="local-variable">this</span>;
}
...
}</code></pre>
</div>
</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 there is (currently) no support for specifying UI hints for domain services through the dynamic <a href="ugfun.html#_ugfun_object-layout_dynamic"><code>.layout.json</code></a> file (only for properties, collections and actions are supported).</p>
</div> </td>
</tr>
</tbody>
</table>
</div>
<div class="sect2">
<h3 id="_rgant-ParameterLayout_cssClass">24.1. <code>cssClass()</code></h3>
<button type="button" class="button secondary" onclick="window.location.href="https://github.com/apache/isis/edit/master/adocs/documentation/src/main/asciidoc/guides/_rgant-ParameterLayout_cssClass.adoc"" style="float: right; font-size: small; padding: 6px; margin-top: -55px; "><i class="fa fa-pencil-square-o"></i> Edit</button>
<div class="paragraph">
<p>The <code>cssClass()</code> attribute can be used to render additional CSS classes in the HTML (a wrapping <code><div></code>) that represents the action parameter. <a href="rgcfg.html#_rgcfg_application-specific_application-css">Application-specific CSS</a> can then be used to target and adjust the UI representation of that particular element.</p>
</div>
<div class="paragraph">
<p>This attribute can also be applied to <a href="#_rgant-DomainObjectLayout_cssClass">domain objects</a>, <a href="#_rgant-ViewModelLayout_cssClass">view models</a>, <a href="#_rgant-ActionLayout_cssClass">actions</a> <a href="#_rgant-PropertyLayout_cssClass">properties</a>, <a href="#_rgant-CollectionLayout_cssClass">collections</a> and <a href="#_rgant-ParameterLayout_cssClass">parameters</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="directive">public</span> <span class="type">class</span> <span class="class">ToDoItem</span> {
<span class="directive">public</span> ToDoItem postpone(
<span class="annotation">@ParameterLayout</span>(
named=<span class="string"><span class="delimiter">"</span><span class="content">until</span><span class="delimiter">"</span></span>,
cssClass=<span class="string"><span class="delimiter">"</span><span class="content">x-key</span><span class="delimiter">"</span></span>
)
LocalDate until
) { ... }
...
}</code></pre>
</div>
</div>
</div>
<div class="sect2">
<h3 id="_rgant-ParameterLayout_describedAs">24.2. <code>describedAs()</code></h3>
<button type="button" class="button secondary" onclick="window.location.href="https://github.com/apache/isis/edit/master/adocs/documentation/src/main/asciidoc/guides/_rgant-ParameterLayout_describedAs.adoc"" style="float: right; font-size: small; padding: 6px; margin-top: -55px; "><i class="fa fa-pencil-square-o"></i> Edit</button>
<div class="paragraph">
<p>The <code>describedAs()</code> attribute is used to provide a short description of the action parameter to the user. In the <a href="ugvw.html">Wicket viewer</a> it is displayed as a 'tool tip'. The <code>describedAs()</code> attribute can also be specified for <a href="#_rgant-CollectionLayout_describedAs">collections</a>, <a href="#_rgant-PropertyLayout_describedAs">properties</a>, <a href="#_rgant-ActionLayout_describedAs">actions</a>, <a href="#_rgant-DomainObjectLayout_describedAs">domain objects</a> and <a href="#_rgant-ViewModelLayout_describedAs">view models</a>.</p>
</div>
<div class="paragraph">
<p>Descriptions may be provided for objects, members (properties, collections and actions), and for individual parameters within an action method. <code>@DescribedAs</code> therefore works in a very similar manner to <code>@Named</code> <!--(see ?)-→.</p>
</div>
<div class="paragraph">
<p>To provide a description for an individual action parameter, use the <code>@DescribedAs</code> annotation in-line i.e. immediately before the parameter declaration.</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">class</span> <span class="class">Customer</span> {
<span class="directive">public</span> Order placeOrder(
Product product,
<span class="annotation">@ParameterLayout</span>(
named=<span class="string"><span class="delimiter">"</span><span class="content">Quantity</span><span class="delimiter">"</span></span>,
describedAs=<span class="string"><span class="delimiter">"</span><span class="content">The quantity of the product being ordered</span><span class="delimiter">"</span></span>
)
<span class="type">int</span> quantity) {
...
}
...
}</code></pre>
</div>
</div>
</div>
<div class="sect2">
<h3 id="_rgant-ParameterLayout_labelPosition">24.3. <code>labelPosition()</code></h3>
<button type="button" class="button secondary" onclick="window.location.href="https://github.com/apache/isis/edit/master/adocs/documentation/src/main/asciidoc/guides/_rgant-ParameterLayout_labelPosition.adoc"" style="float: right; font-size: small; padding: 6px; margin-top: -55px; "><i class="fa fa-pencil-square-o"></i> Edit</button>
<div class="paragraph">
<p>The <code>labelPosition()</code> attribute determines the positioning of labels for parameters. This attribute can also be specified for <a href="#_rgant-PropertyLayout_labelPosition">properties</a>.</p>
</div>
<div class="paragraph">
<p>The positioning of labels is typically <code>LEFT</code>, but can be positioned to the <code>TOP</code>. The one exception is <a href="#_rgant-ParameterLayout_multiLine"><code>multiLine()</code></a> string parameters, where the label defaults to <code>TOP</code> automatically (to provide as much real-estate for the multiline text field as possible).</p>
</div>
<div class="paragraph">
<p>For boolean parameters a positioning of <code>RIGHT</code> is also allowed; this is ignored for all other types.</p>
</div>
<div class="paragraph">
<p>It is also possible to suppress the label altogether, using <code>NONE</code>.</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">class</span> <span class="class">Order</span> {
<span class="directive">public</span> Order changeStatus(
OrderStatus newStatus
<span class="annotation">@Parameter</span>(
optionality=Optionality.OPTIONAL
)
<span class="annotation">@ParameterLayout</span>(
named=<span class="string"><span class="delimiter">"</span><span class="content">Reason</span><span class="delimiter">"</span></span>,
labelPosition=LabelPosition.TOP
)
<span class="predefined-type">String</span> reason) {
...
}
...
}</code></pre>
</div>
</div>
<div class="paragraph">
<p>To get an idea of how these are rendered (in the <a href="ugvw.html">Wicket viewer</a>), see <a href="#_rgant-PropertyLayout_labelPosition">PropertyLayout#labelPosition()</a>.</p>
</div>
</div>
<div class="sect2">
<h3 id="_rgant-ParameterLayout_multiLine">24.4. <code>multiLine()</code></h3>
<button type="button" class="button secondary" onclick="window.location.href="https://github.com/apache/isis/edit/master/adocs/documentation/src/main/asciidoc/guides/_rgant-ParameterLayout_multiLine.adoc"" style="float: right; font-size: small; padding: 6px; margin-top: -55px; "><i class="fa fa-pencil-square-o"></i> Edit</button>
<div class="paragraph">
<p>The <code>multiLine()</code> attribute specifies that the text field for a string parameter should span multiple lines. It is ignored for other parameter types. The attribute is also supported for <a href="#_rgant-PropertyLayout_multiLine">properties</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="directive">public</span> <span class="type">class</span> <span class="class">BugReport</span> {
<span class="directive">public</span> BugReport updateStepsToReproduce(
<span class="annotation">@Parameter</span>(named=<span class="string"><span class="delimiter">"</span><span class="content">Steps</span><span class="delimiter">"</span></span>)
<span class="annotation">@ParameterLayout</span>(
numberOfLines=<span class="integer">10</span>
)
<span class="directive">final</span> <span class="predefined-type">String</span> steps) {
...
}
...
}</code></pre>
</div>
</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>If set > 1 (as would normally be the case), then the default <a href="#_rgant-ParameterLayout_labelPosition"><code>labelPosition</code></a> defaults to <code>TOP</code> (rather than <code>LEFT</code>, as would normally be the case).</p>
</div> </td>
</tr>
</tbody>
</table>
</div>
</div>
<div class="sect2">
<h3 id="_rgant-ParameterLayout_named">24.5. <code>named()</code></h3>
<button type="button" class="button secondary" onclick="window.location.href="https://github.com/apache/isis/edit/master/adocs/documentation/src/main/asciidoc/guides/_rgant-ParameterLayout_named.adoc"" style="float: right; font-size: small; padding: 6px; margin-top: -55px; "><i class="fa fa-pencil-square-o"></i> Edit</button>
<div class="paragraph">
<p>The <code>named()</code> attribute explicitly specifies the action parameter’s name. This attribute can also be specified for <a href="#_rgant-ActionLayout_named">actions</a>, <a href="#_rgant-CollectionLayout_named">collections</a>, <a href="#_rgant-PropertyLayout_named">properties</a>, <a href="#_rgant-DomainObjectLayout_named">domain objects</a>, <a href="#_rgant-ViewModelLayout_named">view models</a> and <a href="#_rgant-DomainServiceLayout_named">domain services</a>.</p>
</div>
<div class="paragraph">
<p>Unlike most other aspects of the Apache Isis metamodel, the name of method parameters cannot (prior to Java 8, at least) be inferred from the Java source code. Without other information, Apache Isis uses the object’s type (<code>int</code>, <code>String</code> etc) as the name instead. This can be sufficient for application-specific reference types (eg <code>ToDoItem</code>) but is generally not sufficient for primitives and other value types.</p>
</div>
<div class="paragraph">
<p>The <code>named()</code> attribute (or the <a href="#_rgant-aaa_deprecated">deprecated <code>@Named</code></a> annotation) is therefore often required to specify the parameter name.</p>
</div>
<div class="paragraph">
<p>As of Java 8, the Java reflection API has been extended. The (non-ASF) <a href="http://github.com/isisaddons/isis-metamodel-paraname8">Isis addons' paraname8</a> metamodel extension provides support for this. Note that your application must (obviously) be running on Java 8, and be compiled with the <code>-parameters</code> compile flag for javac.</p>
</div>
<div class="paragraph">
<p>By default the name is HTML escaped. To allow HTML markup, set the related <code>namedEscaped()</code> attribute to <code>false</code>.</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">class</span> <span class="class">Customer</span> {
<span class="directive">public</span> Order placeOrder(
<span class="directive">final</span> Product product
,<span class="annotation">@ParameterLayout</span>(named=<span class="string"><span class="delimiter">"</span><span class="content">Quantity</span><span class="delimiter">"</span></span>)
<span class="directive">final</span> <span class="type">int</span> quantity) {
Order order = newTransientInstance(Order.class);
order.modifyCustomer(<span class="local-variable">this</span>);
order.modifyProduct(product);
order.setQuantity(quantity);
<span class="keyword">return</span> order;
}
...
}</code></pre>
</div>
</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>The framework also provides a separate, powerful mechanism for <a href="ugbtb.html#_ugbtb_i18n">internationalization</a>.</p>
</div> </td>
</tr>
</tbody>
</table>
</div>
</div>
<div class="sect2">
<h3 id="_rgant-ParameterLayout_renderedAsDayBefore">24.6. <code>renderedAsDayBefore()</code></h3>
<button type="button" class="button secondary" onclick="window.location.href="https://github.com/apache/isis/edit/master/adocs/documentation/src/main/asciidoc/guides/_rgant-ParameterLayout_renderedAsDayBefore.adoc"" style="float: right; font-size: small; padding: 6px; margin-top: -55px; "><i class="fa fa-pencil-square-o"></i> Edit</button>
<div class="paragraph">
<p>The <code>renderedAsDayBefore()</code> attribute applies only to date parameters whereby the date will be rendered as the day before the value actually held in the domain object. It is ignored for parameters of other types. This attribute is also supported for <a href="#_rgant-PropertyLayout_renderedAsDayBefore">properties</a>.</p>
</div>
<div class="paragraph">
<p>This behaviour might at first glance appear odd, but the rationale is to support the use case of a sequence of instances that represent adjacent intervals of time. In such cases there would typically be <code>startDate</code> and <code>endDate</code> properties, eg for all of Q2. Storing this as a half-closed interval — eg <code>[1-Apr-2015, 1-July-2015)</code> — can substantially simplify internal algorithms; the <code>endDate</code> of one interval will correspond to the <code>startDate</code> of the next.</p>
</div>
<div class="paragraph">
<p>However, from an end-user perspective the requirement may be to render the interval as a fully closed interval; eg the end date should be shown as <code>30-Jun-2015</code>.</p>
</div>
<div class="paragraph">
<p>This attribute therefore bridges the gap; it presents the information in a way that makes sense to an end-user, but also stores the domain object in a way that is easy work with internally.</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">class</span> <span class="class">Tenancy</span> {
<span class="directive">public</span> <span class="type">void</span> changeDates(
<span class="annotation">@ParameterLayout</span>(named=<span class="string"><span class="delimiter">"</span><span class="content">Start Date</span><span class="delimiter">"</span></span>)
LocalDate startDate,
<span class="annotation">@ParameterLayout</span>(
named=<span class="string"><span class="delimiter">"</span><span class="content">End Date</span><span class="delimiter">"</span></span>,
renderedAsDayBefore=<span class="predefined-constant">true</span>
)
LocalDate endDate) {
...
}
}</code></pre>
</div>
</div>
</div>
<div class="sect2">
<h3 id="_rgant-ParameterLayout_typicalLength">24.7. <code>typicalLength()</code></h3>
<button type="button" class="button secondary" onclick="window.location.href="https://github.com/apache/isis/edit/master/adocs/documentation/src/main/asciidoc/guides/_rgant-ParameterLayout_typicalLength.adoc"" style="float: right; font-size: small; padding: 6px; margin-top: -55px; "><i class="fa fa-pencil-square-o"></i> Edit</button>
<div class="paragraph">
<p>The <code>typicalLength()</code> attribute indicates the typical length of a string parameter. It is ignored for parameters of other types. The attribute is also supported for <a href="#_rgant-PropertyLayout_typicalLength">properties</a>.</p>
</div>
<div class="paragraph">
<p>The information is intended as a hint to the UI to determine the space that should be given to render a particular string parameter. That said, note that the <a href="ugvw.html">Wicket viewer</a> uses the maximum space available for all fields, so in effect ignores this attribute.</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">class</span> <span class="class">Customer</span> {
<span class="directive">public</span> Customer updateName(
<span class="annotation">@Parameter</span>(maxLength=<span class="integer">30</span>)
<span class="annotation">@ParameterLayout</span>(
named=<span class="string"><span class="delimiter">"</span><span class="content">First name</span><span class="delimiter">"</span></span>,
typicalLength=<span class="integer">20</span>
)
<span class="directive">final</span> <span class="predefined-type">String</span> firstName,
<span class="annotation">@Parameter</span>(maxLength=<span class="integer">30</span>)
<span class="annotation">@ParameterLayout</span>(
named=<span class="string"><span class="delimiter">"</span><span class="content">Last name</span><span class="delimiter">"</span></span>,
typicalLength=<span class="integer">20</span>
)
<span class="directive">final</span> <span class="predefined-type">String</span> lastName) {
...
}
...
}</code></pre>
</div>
</div>
</div>
</div>
</div>
<div class="sect1">
<h2 id="_rgant-PersistenceCapable">25. <code>@PersistenceCapable</code> (<code>javax.jdo</code>)</h2>
<button type="button" class="button secondary" onclick="window.location.href="https://github.com/apache/isis/edit/master/adocs/documentation/src/main/asciidoc/guides/_rgant-PersistenceCapable.adoc"" style="float: right; font-size: small; padding: 6px; margin-top: -55px; "><i class="fa fa-pencil-square-o"></i> Edit</button>
<div class="sectionbody">
<div class="paragraph">
<p>The <code>@javax.jdo.annotation.PersistenceCapable</code> is used by JDO/DataNucleus to indicate that a class is a domain entity to be persisted to the database.</p>
</div>
<div class="paragraph">
<p>Apache Isis also checks for this annotation, and if the <code>@PersistenceCapable#schema()</code> attribute is present will use it to form the object type.</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>Isis parses the <code>@PersistenceCapable</code> annotation from the Java source code; it does not query the JDO metamodel. This means that it the <code>@PersistenceCapable</code> annotation must be used rather than the equivalent <code><class></code> <a href="http://www.datanucleus.org/products/accessplatform_4_0/jdo/class_mapping.html">XML metadata</a>.</p>
</div>
<div class="paragraph">
<p>Moreover, while JDO/DataNucleus will recognize annotations on either the field or the getter method, Apache Isis (currently) only inspects the getter method. Therefore ensure that the annotation is placed there.</p>
</div> </td>
</tr>
</tbody>
</table>
</div>
<div class="paragraph">
<p>This value is used internally to generate a string representation of an objects identity (the <code>Oid</code>). This can appear in several contexts, including:</p>
</div>
<div class="ulist">
<ul>
<li> <p>as the value of <code>Bookmark#getObjectType()</code> and in the <code>toString()</code> value of <code>Bookmark</code> (see <a href="rgsvc.html#_rgsvc_api_BookmarkService"><code>BookmarkService</code></a>)</p>
<div class="ulist">
<ul>
<li> <p>and thus in the "table-of-two-halves" pattern, as per (non-ASF) <a href="http://github.com/isisaddons/isis-module-poly">Isis addons' poly</a> module</p> </li>
</ul>
</div> </li>
<li> <p>in the serialization of <code>OidDto</code> in the <a href="rgcms.html#_rgcms_schema-cmd">command</a> and <a href="rgcms.html#_rgcms_schema-ixn">interaction</a> schemas</p> </li>
<li> <p>in the URLs of the <a href="ugvro.html">RestfulObjects viewer</a></p> </li>
<li> <p>in the URLs of the <a href="ugvw.html">Wicket viewer</a> (in general and in particular if <a href="ugvw.html#_ugvw_features_hints-and-copy-url">copying URLs</a>)</p> </li>
<li> <p>in XML snapshots generated by the <a href="rgsvc.html#_rgsvc_api_XmlSnapshotService"><code>XmlSnapshotService</code></a></p> </li>
</ul>
</div>
<div class="paragraph">
<p>The actual format of the object type used by Apache Isis for the concatenation of <code>schema()</code> and <code>@PersistenceCapable#table()</code>. If the <code>table()</code> is not present, then the class' simple name is used instead.</p>
</div>
<div class="sect2">
<h3 id="_examples_4">25.1. Examples</h3>
<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">@javax</span>.jdo.annotations.PersistenceCapable(schema=<span class="string"><span class="delimiter">"</span><span class="content">custmgmt</span><span class="delimiter">"</span></span>)
<span class="directive">public</span> <span class="type">class</span> <span class="class">Customer</span> {
...
}</code></pre>
</div>
</div>
<div class="paragraph">
<p>has an object type of <code>custmgmt.Customer</code>, while:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code data-lang="java"><span class="annotation">@javax</span>.jdo.annotations.PersistenceCapable(schema=<span class="string"><span class="delimiter">"</span><span class="content">custmgmt</span><span class="delimiter">"</span></span>, table=<span class="string"><span class="delimiter">"</span><span class="content">Address</span><span class="delimiter">"</span></span>)
<span class="directive">public</span> <span class="type">class</span> <span class="class">AddressImpl</span> {
...
}</code></pre>
</div>
</div>
<div class="paragraph">
<p>has an object type of <code>custmgmt.Address</code>.</p>
</div>
<div class="paragraph">
<p>On the other hand:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code data-lang="java"><span class="annotation">@javax</span>.jdo.annotations.PersistenceCapable(table=<span class="string"><span class="delimiter">"</span><span class="content">Address</span><span class="delimiter">"</span></span>)
<span class="directive">public</span> <span class="type">class</span> <span class="class">AddressImpl</span> {
...
}</code></pre>
</div>
</div>
<div class="paragraph">
<p>does <em>not</em> correspond to an object type, because the <code>schema()</code> attribute is missing.</p>
</div>
</div>
<div class="sect2">
<h3 id="_precedence_4">25.2. Precedence</h3>
<div class="paragraph">
<p>The rules of precedence for determining a domain object’s object type are:</p>
</div>
<div class="olist arabic">
<ol class="arabic">
<li> <p><a href="#_rgant_Discriminator"><code>@Discriminator</code></a></p> </li>
<li> <p><code>@DomainObject#objectType</code></p> </li>
<li> <p><a href="#_rgant_PersistenceCapable"><code>@PersistenceCapable</code></a>, if at least the <code>schema</code> attribute is defined. <br></p>
<div class="paragraph">
<p>If both <code>schema</code> and <code>table</code> are defined, then the value is “schema.table�?. If only <code>schema</code> is defined, then the value is “schema.className�?.</p>
</div> </li>
<li> <p>Fully qualified class name of the entity.</p> </li>
</ol>
</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>This might be obvious, but to make explicit: we recommend that you always specify an object type for your domain objects.</p>
</div>
<div class="paragraph">
<p>Otherwise, if you refactor your code (change class name or move package), then any externally held references to the OID of the object will break. At best this will require a data migration in the database; at worst it could cause external clients accessing data through the <a href="ugvro.html">Restful Objects</a> viewer to break.</p>
</div> </td>
</tr>
</tbody>
</table>
</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>If the object type is not unique across all domain classes then the framework will fail-fast and fail to boot. An error message will be printed in the log to help you determine which classes have duplicate object tyoes.</p>
</div> </td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
</div>
<div class="sect1">
<h2 id="_rgant-PostConstruct">26. <code>@PostConstruct</code> (<code>javax</code>)</h2>
<button type="button" class="button secondary" onclick="window.location.href="https://github.com/apache/isis/edit/master/adocs/documentation/src/main/asciidoc/guides/_rgant-PostConstruct.adoc"" style="float: right; font-size: small; padding: 6px; margin-top: -55px; "><i class="fa fa-pencil-square-o"></i> Edit</button>
<div class="sectionbody">
<div class="paragraph">
<p>The <code>@javax.annotation.PostConstruct</code> annotation, as defined in <a href="https://jcp.org/en/jsr/detail?id=250">JSR-250</a>, is recognized by Apache Isis as a callback method on domain services to be called just after they have been constructed, in order that they initialize themselves.</p>
</div>
<div class="paragraph">
<p>It is also recognized for <a href="ugbtb.html#_ugbtb_view-models">view models</a> (eg annotated with <a href="#_rgant-ViewModel"><code>@ViewModel</code></a>).</p>
</div>
<div class="paragraph">
<p>For the default application-scoped (singleton) domain services, this means that the method, if present, is called during the bootstrapping of the application. For <a href="#_rgant-RequestScoped"><code>@RequestScoped</code></a> domain services, the method is called at the beginning of the request.</p>
</div>
<div class="paragraph">
<p>The signature of the method is:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code data-lang="java"><span class="annotation">@PostConstruct</span> <i class="conum" data-value="1"></i><b>(1)</b>
<span class="directive">public</span> <span class="type">void</span> init() { ... } <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>It is not necessary to annotate the method with <a href="#_rgant-Programmatic"><code>@Programmatic</code></a>; it will be automatically excluded from the Apache Isis metamodel.</td>
</tr>
<tr>
<td><i class="conum" data-value="2"></i><b>2</b></td>
<td>the method can have any name, but must have <code>public</code> visibility.</td>
</tr>
</tbody>
</table>
</div>
<div class="paragraph">
<p>In the form shown above the method accepts no arguments. Alternatively - for domain services only, not view models - the method can accept a parameter of type <code>Map<String,String></code>:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code data-lang="java"><span class="annotation">@PostConstruct</span>
<span class="annotation">@Programmatic</span>
<span class="directive">public</span> <span class="type">void</span> init(<span class="predefined-type">Map</span><<span class="predefined-type">String</span>,<span class="predefined-type">String</span>> properties) { ... }</code></pre>
</div>
</div>
<div class="paragraph">
<p>Isis uses argument to pass in the configuration properties read from all <a href="rgcfg.html#_rgcfg_configuration-files">configuration files</a>:</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>Alternatively, you could inject <a href="rgsvc.html#_rgsvc_api_DomainObjectContainer"><code>DomainObjectContainer</code></a> into the service and read configuration properties using <code>DomainObjectContainer#getProperty(…)</code> and related methods. Note that when using this latter API only those configuration properties prefixes <code>application.</code> key are provided.</p>
</div> </td>
</tr>
</tbody>
</table>
</div>
<div class="paragraph">
<p>A common use case is for domain services that interact with the <a href="rgsvc.html#_rgsvc_api_EventBusService"><code>EventBusService</code></a>. For example:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code data-lang="java"><span class="annotation">@DomainService</span>(nature=NatureOfService.DOMAIN)
<span class="directive">public</span> <span class="type">class</span> <span class="class">MySubscribingService</span> {
<span class="annotation">@PostConstruct</span>
<span class="directive">public</span> <span class="type">void</span> postConstruct() {
eventBusService.register(<span class="local-variable">this</span>);
}
<span class="annotation">@PreDestroy</span>
<span class="directive">public</span> <span class="type">void</span> preDestroy() {
eventBusService.unregister(<span class="local-variable">this</span>);
}
...
<span class="annotation">@javax</span>.inject.Inject
EventBusService eventBusService;
}</code></pre>
</div>
</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>In this particular use case, it is generally simpler to just subclass from <a href="rgcms.html#_rgcms_classes_super_AbstractSubscriber"><code>AbstractSubscriber</code></a>.</p>
</div> </td>
</tr>
</tbody>
</table>
</div>
<div class="paragraph">
<p>Other use cases include obtaining connections to external datasources, eg subscribing to an ActiveMQ router, say, or initializing/cleaning up a background scheduler such as Quartz.</p>
</div>
<div class="paragraph">
<p>See also <a href="#_rgant-PreDestroy"><code>@PreDestroy</code></a></p>
</div>
</div>
</div>
<div class="sect1">
<h2 id="_rgant-PreDestroy">27. <code>@PreDestroy</code> (<code>javax</code>)</h2>
<button type="button" class="button secondary" onclick="window.location.href="https://github.com/apache/isis/edit/master/adocs/documentation/src/main/asciidoc/guides/_rgant-PreDestroy.adoc"" style="float: right; font-size: small; padding: 6px; margin-top: -55px; "><i class="fa fa-pencil-square-o"></i> Edit</button>
<div class="sectionbody">
<div class="paragraph">
<p>The <code>@javax.annotation.PreDestroy</code> annotation, as defined in <a href="https://jcp.org/en/jsr/detail?id=250">JSR-250</a>, recognized by Apache Isis as a callback method on domain services to be called just as they go out of scope.</p>
</div>
<div class="paragraph">
<p>For the default application-scoped (singleton) domain services, this means that the method, if present, is called just prior to the termination of the application. For <a href="#_rgant-RequestScoped"><code>@RequestScoped</code></a> domain services, the method is called at the end of the request.</p>
</div>
<div class="paragraph">
<p>The signature of the method is:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code data-lang="java"><span class="annotation">@PreDestroy</span> <i class="conum" data-value="1"></i><b>(1)</b>
<span class="directive">public</span> <span class="type">void</span> deinit() { ... } <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>It is not necessary to annotate the method with <a href="#_rgant-Programmatic"><code>@Programmatic</code></a>; it will be automatically excluded from the Apache Isis metamodel.</td>
</tr>
<tr>
<td><i class="conum" data-value="2"></i><b>2</b></td>
<td>the method can have any name, but must have <code>public</code> visibility, and accept no arguments.</td>
</tr>
</tbody>
</table>
</div>
<div class="paragraph">
<p>A common use case is for domain services that interact with the <a href="rgsvc.html#_rgsvc_api_EventBusService"><code>EventBusService</code></a>. For example:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code data-lang="java"><span class="annotation">@DomainService</span>(nature=NatureOfService.DOMAIN)
<span class="directive">public</span> <span class="type">class</span> <span class="class">MySubscribingService</span> {
<span class="annotation">@PostConstruct</span>
<span class="directive">public</span> <span class="type">void</span> init() {
eventBusService.register(<span class="local-variable">this</span>);
}
<span class="annotation">@PreDestroy</span>
<span class="directive">public</span> <span class="type">void</span> deinit() {
eventBusService.unregister(<span class="local-variable">this</span>);
}
...
<span class="annotation">@javax</span>.inject.Inject
EventBusService eventBusService;
}</code></pre>
</div>
</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>In this particular use case, it is generally simpler to just subclass from <a href="rgcms.html#_rgcms_classes_super_AbstractSubscriber"><code>AbstractSubscriber</code></a>.</p>
</div> </td>
</tr>
</tbody>
</table>
</div>
<div class="paragraph">
<p>Other use cases include obtaining connections to external datasources, eg subscribing to an ActiveMQ router, say, or initializing/cleaning up a background scheduler such as Quartz.</p>
</div>
<div class="paragraph">
<p>See also <a href="#_rgant-PostConstruct"><code>@PostConstruct</code></a></p>
</div>
</div>
</div>
<div class="sect1">
<h2 id="_rgant-PrimaryKey">28. <code>@PrimaryKey</code> (<code>javax.jdo</code>)</h2>
<button type="button" class="button secondary" onclick="window.location.href="https://github.com/apache/isis/edit/master/adocs/documentation/src/main/asciidoc/guides/_rgant-PrimaryKey.adoc"" style="float: right; font-size: small; padding: 6px; margin-top: -55px; "><i class="fa fa-pencil-square-o"></i> Edit</button>
<div class="sectionbody">
<div class="paragraph">
<p>The <code>@javax.jdo.annotation.PrimaryKey</code> annotation is used by JDO/DataNucleus to indicate that a property is used as the primary key for an entity with application-managed identity.</p>
</div>
<div class="paragraph">
<p>Apache Isis also uses this annotation in a very minimal way: to ensure that the framework’s own logic to initialize newly instantiated objects (eg using <a href="rgsvc.html#_rgsvc_api_DomainObjectContainer"><code>DomainObjectContainer#newTransientInstance(…)</code></a> does not touch the primary key, and also to ensure that the primary key property is always disabled (read-only).</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>Isis parses the <code>@NotPersistent</code> annotation from the Java source code; it does not query the JDO metamodel. This means that it the <code>@NotPersistent</code> annotation must be used rather than the equivalent <code><field></code> <a href="http://www.datanucleus.org/products/accessplatform_4_0/jdo/application_identity.html">XML metadata</a>.</p>
</div>
<div class="paragraph">
<p>Moreover, while JDO/DataNucleus will recognize annotations on either the field or the getter method, Apache Isis (currently) only inspects the getter method. Therefore ensure that the annotation is placed there.</p>
</div> </td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
<div class="sect1">
<h2 id="_rgant-Programmatic">29. <code>@Programmatic</code></h2>
<button type="button" class="button secondary" onclick="window.location.href="https://github.com/apache/isis/edit/master/adocs/documentation/src/main/asciidoc/guides/_rgant-Programmatic.adoc"" style="float: right; font-size: small; padding: 6px; margin-top: -55px; "><i class="fa fa-pencil-square-o"></i> Edit</button>
<div class="sectionbody">
<div class="paragraph">
<p>The <code>@Programmatic</code> annotation causes the method to be excluded completely from the Apache Isis metamodel. This means it won’t appear in any UI, and it won’t appear in any <a href="rgsvc.html#_rgsvc_api_MementoService">memento</a>s or <a href="rgsvc.html#_rgsvc_api_XmlSnapshotService">snapshot</a>s.</p>
</div>
<div class="paragraph">
<p>A common use-case is to ignore implementation-level artifacts. 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">class</span> <span class="class">Customer</span> <span class="directive">implements</span> <span class="predefined-type">Comparable</span><Customer> {
...
<span class="annotation">@Programmatic</span>
<span class="directive">public</span> <span class="type">int</span> compareTo(Customer c) {
<span class="keyword">return</span> getSalary() - c.getSalary();
}
...
}</code></pre>
</div>
</div>
<div class="paragraph">
<p>Note that <code>@Programmatic</code> does not simply imply <code>@Hidden</code>; it actually means that the class member will not be part of the Apache Isis metamodel.</p>
</div>
</div>
</div>
<div class="sect1">
<h2 id="_rgant-Property">30. <code>@Property</code></h2>
<button type="button" class="button secondary" onclick="window.location.href="https://github.com/apache/isis/edit/master/adocs/documentation/src/main/asciidoc/guides/_rgant-Property.adoc"" style="float: right; font-size: small; padding: 6px; margin-top: -55px; "><i class="fa fa-pencil-square-o"></i> Edit</button>
<div class="sectionbody">
<div class="paragraph">
<p>The <code>@Property</code> annotation applies to properties collecting together all domain semantics within a single annotation.</p>
</div>
<div class="paragraph">
<p>It is also possible to apply the annotation to actions of domain services that are acting as <a href="../../more-advanced-topics/how-to-01-062-How-to-decouple-dependencies-using-contributions.html">contributed properties</a>.</p>
</div>
<table class="tableblock frame-all grid-all spread">
<caption class="title">
Table 19.
<code>@Property</code> attributes
</caption>
<colgroup>
<col style="width: 25%;">
<col style="width: 25%;">
<col style="width: 50%;">
</colgroup>
<thead>
<tr>
<th class="tableblock halign-left valign-top">Attribute</th>
<th class="tableblock halign-left valign-top">Values (default)</th>
<th class="tableblock halign-left valign-top">Description</th>
</tr>
</thead>
<tbody>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="#_rgant-Property_domainEvent"><code>domainEvent()</code></a></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">subtype of <code>PropertyDomainEvent</code><br> (<code>PropertyDomainEvent.Default</code>)</p></td>
<td class="tableblock halign-left valign-top">
<div>
<div class="paragraph">
<p>the event type to be posted to the <a href="rgsvc.html#_rgsvc_api_EventBusService"><code>EventBusService</code></a> to broadcast the property’s business rule checking (hide, disable, validate) and its modification (before and after).</p>
</div>
</div></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="#_rgant-Property_editing"><code>editing()</code></a></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>ENABLED</code>, <code>DISABLED</code>, <code>AS_CONFIGURED</code><br> (<code>AS_CONFIGURED</code>)</p></td>
<td class="tableblock halign-left valign-top">
<div>
<div class="paragraph">
<p>whether a property can be modified or cleared from within the UI</p>
</div>
</div></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="#_rgant-Property_fileAccept"><code>fileAccept()</code></a></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Media type or file extension</p></td>
<td class="tableblock halign-left valign-top">
<div>
<div class="paragraph">
<p>Hints the files to be uploaded to a <a href="rgcms.html#_rgcms_classes_value-types_Blob"><code>Blob</code></a> or <a href="rgcms.html#_rgcms_classes_value-types_Clob"><code>Clob</code></a>.<br> <br> Note that this does not prevent the user from uploading some other file type; rather it merely defaults the file type in the file open dialog.</p>
</div>
</div></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="#_rgant-Property_hidden"><code>hidden()</code></a></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>EVERYWHERE</code>, <code>OBJECT_FORMS</code>, <code>PARENTED_TABLES</code>, <code>STANDALONE_TABLES</code>, <code>ALL_TABLES</code>, <code>NOWHERE</code><br> (<code>NOWHERE</code>)</p></td>
<td class="tableblock halign-left valign-top">
<div>
<div class="paragraph">
<p>indicates where (in the UI) the property should be hidden from the user.</p>
</div>
</div></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="#_rgant-Property_maxLength"><code>maxLength()</code></a></p></td>
<td class="tableblock halign-left valign-top"></td>
<td class="tableblock halign-left valign-top">
<div>
<div class="paragraph">
<p>maximum number of characters for string parameters; ignored otherwise<br></p>
</div>
<div class="paragraph">
<p>In many/most cases you should however use <a href="#_rgant-Column"><code>@Column#length()</code></a></p>
</div>
</div></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="#_rgant-Property_mustSatisfy"><code>mustSatisfy()</code></a></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">implementation of <code>o.a.i.applib.spec.Specification</code></p></td>
<td class="tableblock halign-left valign-top">
<div>
<div class="paragraph">
<p>allows arbitrary validation to be applied</p>
</div>
</div></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="#_rgant-Property_notPersisted"><code>notPersisted()</code></a></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>true</code>, <code>false</code><br> (<code>false</code>)</p></td>
<td class="tableblock halign-left valign-top">
<div>
<div class="paragraph">
<p>whether to exclude from snapshots.<br></p>
</div>
<div class="admonitionblock warning">
<table>
<tbody>
<tr>
<td class="icon"> <i class="fa icon-warning" title="Warning"></i> </td>
<td class="content">
<div class="paragraph">
<p>Property must also be annotated with <code>@javax.jdo.annotations.NotPersistent</code> in order to not be persisted.</p>
</div> </td>
</tr>
</tbody>
</table>
</div>
</div></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="#_rgant-Property_optionality"><code>optionality()</code></a></p></td>
<td class="tableblock halign-left valign-top"></td>
<td class="tableblock halign-left valign-top">
<div>
<div class="paragraph">
<p>specifies a property is optional rather than mandatory<br></p>
</div>
<div class="paragraph">
<p>In many/most cases you should however use <a href="#_rgant-Column"><code>@Column#allowsNull()</code></a></p>
</div>
</div></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="#_rgant-Property_regexPattern"><code>regexPattern()</code></a></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">regular expression</p></td>
<td class="tableblock halign-left valign-top">
<div>
<div class="paragraph">
<p>validates the contents of a string parameter against the regular expression pattern</p>
</div>
</div></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>regexPatternFlags()</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">value of flags as normally passed to <code>java.util.regex.</code><br> <code>Pattern#compile(…)</code></p></td>
<td class="tableblock halign-left valign-top">
<div>
<div class="paragraph">
<p>modifies the compilation of the regular expression</p>
</div>
</div></td>
</tr>
</tbody>
</table>
<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">@DomainObject</span>
<span class="directive">public</span> <span class="type">class</span> <span class="class">Customer</span> {
<span class="directive">public</span> <span class="directive">static</span> <span class="type">class</span> <span class="class">EmailSpecification</span> <span class="directive">extends</span> AbstractSpecification<<span class="predefined-type">String</span>> {
<span class="directive">public</span> <span class="predefined-type">String</span> satisfiesSafely(<span class="predefined-type">String</span> proposed) {
<span class="keyword">return</span> EmailUtil.ensureValidEmail(proposed); <i class="conum" data-value="1"></i><b>(1)</b>
}
}
<span class="annotation">@javax</span>.jdo.annotations.Column(allowsNull=<span class="string"><span class="delimiter">"</span><span class="content">true</span><span class="delimiter">"</span></span>) <i class="conum" data-value="2"></i><b>(2)</b>
<span class="annotation">@Property</span>(
maxLength=<span class="integer">30</span>,
minLength=<span class="integer">5</span>,
mustSatisfy=EmailSpecification.class,
regexPattern = <span class="string"><span class="delimiter">"</span><span class="content">(</span><span class="char">\\</span><span class="content">w+</span><span class="char">\\</span><span class="content">.)*</span><span class="char">\\</span><span class="content">w+@(</span><span class="char">\\</span><span class="content">w+</span><span class="char">\\</span><span class="content">.)+[A-Za-z]+</span><span class="delimiter">"</span></span>,
regexPatternFlags=<span class="predefined-type">Pattern</span>.CASE_INSENSITIVE
)
<span class="directive">public</span> <span class="predefined-type">String</span> getEmailAddress() { ... }
<span class="directive">public</span> <span class="type">void</span> setEmailAddress(<span class="predefined-type">String</span> emailAddress) { ... }
...
}</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 (fictitious) <code>EmailUtil.ensureValid(…)</code> (omitted for brevity) returns a string explaining if an email is invalid</td>
</tr>
<tr>
<td><i class="conum" data-value="2"></i><b>2</b></td>
<td>generally use instead of the <code>@Property#optionality()</code> attribute</td>
</tr>
</tbody>
</table>
</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>The annotation is one of a handful (others including <a href="#_rgant-Collection"><code>@Collection</code></a>, <a href="#_rgant-CollectionLayout"><code>@CollectionLayout</code></a> and <a href="#_rgant-PropertyLayout"><code>@PropertyLayout</code></a>) that can also be applied to the field, rather than the getter method. This is specifically so that boilerplate-busting tools such as <a href="https://projectlombok.org/">Project Lombok</a> can be used.</p>
</div> </td>
</tr>
</tbody>
</table>
</div>
<div class="sect2">
<h3 id="_rgant-Property_domainEvent">30.1. <code>domainEvent()</code></h3>
<button type="button" class="button secondary" onclick="window.location.href="https://github.com/apache/isis/edit/master/adocs/documentation/src/main/asciidoc/guides/_rgant-Property_domainEvent.adoc"" style="float: right; font-size: small; padding: 6px; margin-top: -55px; "><i class="fa fa-pencil-square-o"></i> Edit</button>
<div class="paragraph">
<p>Whenever a domain object (or list of domain objects) is to be rendered, the framework fires off multiple domain events for every property, collection and action of the domain object. In the cases of the domain object’s properties, the events that are fired are:</p>
</div>
<div class="ulist">
<ul>
<li> <p>hide phase: to check that the property is visible (has not been hidden)</p> </li>
<li> <p>disable phase: to check that the property is usable (has not been disabled)</p> </li>
<li> <p>validate phase: to check that the property’s arguments are valid (to modify/clear its value)</p> </li>
<li> <p>pre-execute phase: before the modification of the property</p> </li>
<li> <p>post-execute: after the modification of the property</p> </li>
</ul>
</div>
<div class="paragraph">
<p>Subscribers subscribe through the <a href="rgsvc.html#_rgsvc_api_EventBusService"><code>EventBusService</code></a> using either <a href="https://github.com/google/guava">Guava</a> or <a href="http://www.axonframework.org/">Axon Framework</a> annotations and can influence each of these phases.</p>
</div>
<div class="paragraph">
<p>By default the event raised is <code>PropertyDomainEvent.Default</code>. 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">class</span> <span class="class">ToDoItem</span> {
<span class="annotation">@Property</span>()
<span class="directive">public</span> LocalDate getDueBy() { ... }
...
}</code></pre>
</div>
</div>
<div class="paragraph">
<p>The <code>domainEvent()</code> attribute allows a custom subclass to be emitted allowing more precise subscriptions (to those subclasses) to be defined instead. This attribute is also supported for <a href="#_rgant-Action_domainEvent">actions</a> and <a href="#_rgant-Property_domainEvent">properties</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="directive">public</span> <span class="type">class</span> <span class="class">ToDoItem</span> {
<span class="directive">public</span> <span class="directive">static</span> <span class="type">class</span> <span class="class">DueByChangedEvent</span> <span class="directive">extends</span> PropertyDomainEvent<ToDoItem, LocalDate> { } <i class="conum" data-value="1"></i><b>(1)</b>
<span class="annotation">@Property</span>(domainEvent=ToDoItem.DueByChangedEvent)
<span class="directive">public</span> LocalDate getDueBy() { ... }
...
}</code></pre>
</div>
</div>
<div class="colist arabic">
<table>
<tbody>
<tr>
<td><i class="conum" data-value="1"></i><b>1</b></td>
<td>inherit from <code>PropertyDomainEvent<T,P></code> where <code>T</code> is the type of the domain object being interacted with, and <code>P</code> is the type of the property (<code>LocalDate</code> in this example)</td>
</tr>
</tbody>
</table>
</div>
<div class="paragraph">
<p>The benefit is that subscribers can be more targetted as to the events that they subscribe to.</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>As of <code>1.10.0</code> the framework provides no-arg constructor and will initialize the domain event using (non-API) setters rather than through the constructor. This substantially reduces the boilerplate.</p>
</div> </td>
</tr>
</tbody>
</table>
</div>
<div class="sect3">
<h4 id="_subscribers_13">30.1.1. Subscribers</h4>
<div class="paragraph">
<p>Subscribers (which must be domain services) subscribe using either the <a href="https://github.com/google/guava">Guava</a> API or (if the <a href="rgsvc.html#_rgsvc_api_EventBusService"><code>EventBusService</code></a> has been appropriately configured) using the <a href="http://www.axonframework.org/">Axon Framework</a> API. The examples below use the Guava API.</p>
</div>
<div class="paragraph">
<p>Subscribers can be either coarse-grained (if they subscribe to the top-level event type):</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code data-lang="java"><span class="annotation">@DomainService</span>(nature=NatureOfService.DOMAIN)
<span class="directive">public</span> <span class="type">class</span> <span class="class">SomeSubscriber</span> <span class="directive">extends</span> AbstractSubscriber {
<span class="annotation">@com</span>.google.common.eventbus.Subscribe
<span class="directive">public</span> <span class="type">void</span> on(PropertyDomainEvent ev) {
...
}
}</code></pre>
</div>
</div>
<div class="paragraph">
<p>or can be fine-grained (by subscribing to specific event subtypes):</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code data-lang="java"><span class="annotation">@DomainService</span>(nature=NatureOfService.DOMAIN)
<span class="directive">public</span> <span class="type">class</span> <span class="class">SomeSubscriber</span> <span class="directive">extends</span> AbstractSubscriber {
<span class="annotation">@com</span>.google.common.eventbus.Subscribe
<span class="directive">public</span> <span class="type">void</span> on(ToDoItem.DueByChangedEvent ev) {
...
}
}</code></pre>
</div>
</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>If the AxonFramework is being used, replace <code>@com.google.common.eventbus.Subscribe</code> with <code>@org.axonframework.eventhandling.annotation.EventHandler</code>.</p>
</div> </td>
</tr>
</tbody>
</table>
</div>
<div class="paragraph">
<p>The subscriber’s method is called (up to) 5 times:</p>
</div>
<div class="ulist">
<ul>
<li> <p>whether to veto visibility (hide)</p> </li>
<li> <p>whether to veto usability (disable)</p> </li>
<li> <p>whether to veto execution (validate)</p> </li>
<li> <p>steps to perform prior to the property being modified</p> </li>
<li> <p>steps to perform after the property has been modified.</p> </li>
</ul>
</div>
<div class="paragraph">
<p>The subscriber can distinguish these by calling <code>ev.getEventPhase()</code>. Thus the general form is:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code data-lang="java"><span class="annotation">@Programmatic</span>
<span class="annotation">@com</span>.google.common.eventbus.Subscribe
<span class="directive">public</span> <span class="type">void</span> on(PropertyDomainEvent ev) {
<span class="keyword">switch</span>(ev.getEventPhase()) {
<span class="keyword">case</span> HIDE:
<span class="comment">// call ev.hide() or ev.veto("") to hide the property</span>
<span class="keyword">break</span>;
<span class="keyword">case</span> DISABLE:
<span class="comment">// call ev.disable("...") or ev.veto("...") to disable the property</span>
<span class="keyword">break</span>;
<span class="keyword">case</span> VALIDATE:
<span class="comment">// call ev.invalidate("...") or ev.veto("...")</span>
<span class="comment">// if proposed property value is invalid</span>
<span class="keyword">break</span>;
<span class="keyword">case</span> EXECUTING:
<span class="keyword">break</span>;
<span class="keyword">case</span> EXECUTED:
<span class="keyword">break</span>;
}
}</code></pre>
</div>
</div>
<div class="paragraph">
<p>It is also possible to abort the transaction during the executing or executed phases by throwing an exception. If the exception is a subtype of <code>RecoverableException</code> then the exception will be rendered as a user-friendly warning (eg Growl/toast) rather than an error.</p>
</div>
</div>
<div class="sect3">
<h4 id="_default_doop_and_noop_events_13">30.1.2. Default, Doop and Noop events</h4>
<div class="paragraph">
<p>If the <code>domainEvent</code> attribute is not explicitly specified (is left as its default value, <code>PropertyDomainEvent.Default</code>), then the framework will, by default, post an event.</p>
</div>
<div class="paragraph">
<p>If this is not required, then the <code>isis.reflector.facet.propertyAnnotation.domainEvent.postForDefault</code> configuration property can be set to "false"; this will disable posting.</p>
</div>
<div class="paragraph">
<p>On the other hand, if the <code>domainEvent</code> has been explicitly specified to some subclass, then an event will be posted. The framework provides <code>PropertyDomainEvent.Doop</code> as such a subclass, so setting the <code>domainEvent</code> attribute to this class will ensure that the event to be posted, irrespective of the configuration property setting.</p>
</div>
<div class="paragraph">
<p>And, conversely, the framework also provides <code>PropertyDomainEvent.Noop</code>; if <code>domainEvent</code> attribute is set to this class, then no event will be posted.</p>
</div>
</div>
<div class="sect3">
<h4 id="_raising_events_programmatically_6">30.1.3. Raising events programmatically</h4>
<div class="paragraph">
<p>Normally events are only raised for interactions through the UI. However, events can be raised programmatically by wrapping the target object using the <a href="rgsvc.html#_rgsvc_api_WrapperFactory"><code>WrapperFactory</code></a> service.</p>
</div>
</div>
</div>
<div class="sect2">
<h3 id="_rgant-Property_editing">30.2. <code>editing()</code></h3>
<button type="button" class="button secondary" onclick="window.location.href="https://github.com/apache/isis/edit/master/adocs/documentation/src/main/asciidoc/guides/_rgant-Property_editing.adoc"" style="float: right; font-size: small; padding: 6px; margin-top: -55px; "><i class="fa fa-pencil-square-o"></i> Edit</button>
<div class="paragraph">
<p>The <code>editing()</code> attribute can be used to prevent a property from being modified or cleared, ie to make it read-only. This attribute can also be specified for <a href="#_rgant-Collection_editing">collections</a>, and can also be specified for the <a href="#_rgant-DomainObject_editing">domain object</a>.</p>
</div>
<div class="paragraph">
<p>The related <code>editingDisabledReason()</code> attribute specifies the a hard-coded reason why the property cannot be modified directly.</p>
</div>
<div class="paragraph">
<p>Whether a property is enabled or disabled depends upon these factors:</p>
</div>
<div class="ulist">
<ul>
<li> <p>whether the domain object has been configured as immutable through the <a href="#_rgant-DomainObject_editing"><code>@DomainObject#editing()</code></a> attribute</p> </li>
<li> <p>else (that is, if the domain object’s editability is specified as being <code>AS_CONFIGURED</code>), then the value of the <a href="rgcfg.html#<em>rgcfg_configuring-core">configuration property</a> <code>isis.objects.editing</code>. If set to <code>false</code>, then the object’s properties (and collections) are _not editable</p> </li>
<li> <p>else, then the value of the <code>@Property(editing=…)</code> attribute itself</p> </li>
<li> <p>else, the result of invoking any supporting <a href="rgcms.html#_rgcms_methods_prefixes_disable"><code>disable…()</code></a> supporting methods</p> </li>
</ul>
</div>
<div class="paragraph">
<p>Thus, to make a property read-only even if the object would otherwise be editable, use:</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">Customer</span> {
<span class="annotation">@Property</span>(
editing=Editing.DISABLED,
editingDisabledReason=<span class="string"><span class="delimiter">"</span><span class="content">The credit rating is derived from multiple factors</span><span class="delimiter">"</span></span>
)
<span class="directive">public</span> <span class="type">int</span> getInitialCreditRating(){ ... }
<span class="directive">public</span> <span class="type">void</span> setInitialCreditRating(<span class="type">int</span> initialCreditRating) { ... }
}</code></pre>
</div>
</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>To reiterate, it is <em>not</em> possible to enable editing for a property if editing has been disabled at the object-level.</p>
</div> </td>
</tr>
</tbody>
</table>
</div>
</div>
<div class="sect2">
<h3 id="_rgant-Property_fileAccept">30.3. <code>fileAccept()</code></h3>
<button type="button" class="button secondary" onclick="window.location.href="https://github.com/apache/isis/edit/master/adocs/documentation/src/main/asciidoc/guides/_rgant-Property_fileAccept.adoc"" style="float: right; font-size: small; padding: 6px; margin-top: -55px; "><i class="fa fa-pencil-square-o"></i> Edit</button>
<div class="paragraph">
<p>The <code>fileAccept()</code> attribute applies only to <a href="rgcms.html#_rgcms_classes_value-types_Blob"><code>Blob</code></a> or <a href="rgcms.html#_rgcms_classes_value-types_Clob"><code>Clob</code></a> parameters, indicating the type of file to accept when uploading a new value. The attribute is also supported on <a href="#_rgant-Parameter_fileAccept">parameters</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="directive">public</span> <span class="type">class</span> <span class="class">ScannedDocument</span> {
<span class="annotation">@Property</span>(fileAccept=<span class="string"><span class="delimiter">"</span><span class="content">image/*</span><span class="delimiter">"</span></span>) <i class="conum" data-value="1"></i><b>(1)</b>
<span class="directive">private</span> <span class="predefined-type">Blob</span> scannedImage;
<span class="comment">// getters and setters omitted</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>as per <a href="http://www.w3schools.com/tags/att_input_accept.asp">reference docs</a>, either a media type (such as <code>image/*</code>) or a file type extension (such as <code>.png</code>).</td>
</tr>
</tbody>
</table>
</div>
</div>
<div class="sect2">
<h3 id="_rgant-Property_hidden">30.4. <code>hidden()</code></h3>
<button type="button" class="button secondary" onclick="window.location.href="https://github.com/apache/isis/edit/master/adocs/documentation/src/main/asciidoc/guides/_rgant-Property_hidden.adoc"" style="float: right; font-size: small; padding: 6px; margin-top: -55px; "><i class="fa fa-pencil-square-o"></i> Edit</button>
<div class="paragraph">
<p>Properties can be hidden at the domain-level, indicating that they are not visible to the end-user. This attribute can also be applied to <a href="#_rgant-ActionLayout_hidden">actions</a> and <a href="#_rgant-CollectionLayout_hidden">collections</a>.</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>It is also possible to use <a href="#_rgant-Property_hidden"><code>@Property#hidden()</code></a> to hide an action at the domain layer. Both options are provided with a view that in the future the view-layer semantics may be under the control of (expert) users, whereas domain-layer semantics should never be overridden or modified by the user.</p>
</div> </td>
</tr>
</tbody>
</table>
</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">class</span> <span class="class">Customer</span> {
<span class="annotation">@Property</span>(hidden=Where.EVERYWHERE)
<span class="directive">public</span> <span class="type">int</span> getInternalId() { ... }
<span class="annotation">@Property</span>(hidden=Where.ALL_TABLES)
<span class="directive">public</span> <span class="type">void</span> updateStatus() { ... }
...
}</code></pre>
</div>
</div>
<div class="paragraph">
<p>The acceptable values for the <code>where</code> parameter are:</p>
</div>
<div class="ulist">
<ul>
<li> <p><code>Where.EVERYWHERE</code> or <code>Where.ANYWHERE</code><br></p>
<div class="paragraph">
<p>The property should be hidden everywhere.</p>
</div> </li>
<li> <p><code>Where.ANYWHERE</code><br></p>
<div class="paragraph">
<p>Synonym for everywhere.</p>
</div> </li>
<li> <p><code>Where.OBJECT_FORMS</code><br></p>
<div class="paragraph">
<p>The property should be hidden when displayed within an object form.</p>
</div> </li>
<li> <p><code>Where.PARENTED_TABLES</code><br></p>
<div class="paragraph">
<p>The property should be hidden when displayed as a column of a table within a parent object’s collection.</p>
</div> </li>
<li> <p><code>Where.STANDALONE_TABLES</code><br></p>
<div class="paragraph">
<p>The property should be hidden when displayed as a column of a table showing a standalone list of objects, for example as returned by a repository query.</p>
</div> </li>
<li> <p><code>Where.ALL_TABLES</code><br></p>
<div class="paragraph">
<p>The property should be hidden when displayed as a column of a table, either an object’s * collection or a standalone list. This combines <code>PARENTED_TABLES</code> and <code>STANDALONE_TABLES</code>.</p>
</div> </li>
<li> <p><code>Where.NOWHERE</code><br></p>
<div class="paragraph">
<p>The property should not be hidden, overriding any other metadata/conventions that would normally cause the property to be hidden.<br></p>
</div> </li>
</ul>
</div>
<div class="paragraph">
<p>For example, if a property is annotated with <a href="#_rgant-Title"><code>@Title</code></a>, then normally this should be hidden from all tables. Annotating with <code>@Property(where=Where.NOWHERE)</code> overrides this.</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>The <a href="ugvro.html">RestfulObjects viewer</a> has only partial support for these <code>Where</code> enums.</p>
</div> </td>
</tr>
</tbody>
</table>
</div>
</div>
<div class="sect2">
<h3 id="_rgant-Property_maxLength">30.5. <code>maxLength()</code></h3>
<button type="button" class="button secondary" onclick="window.location.href="https://github.com/apache/isis/edit/master/adocs/documentation/src/main/asciidoc/guides/_rgant-Property_maxLength.adoc"" style="float: right; font-size: small; padding: 6px; margin-top: -55px; "><i class="fa fa-pencil-square-o"></i> Edit</button>
<div class="paragraph">
<p>The <code>maxLength()</code> attribute applies only to <code>String</code> properties, indicating the maximum number of characters that the user may enter (for example in a text field in the UI). The attribute It is ignored if applied to properties of any other type. This attribute can also be applied to <a href="#_rgant-Parameter_maxLength">parameters</a>.</p>
</div>
<div class="paragraph">
<p>That said, properties are most commonly defined on persistent domain objects (entities), in which case the JDO <a href="#_rgant-Column"><code>@Column</code></a> will in any case need to be specified. Apache Isis can infer the <code>maxLength</code> semantic directly from the equivalent <code>@Column#length()</code> annotation/attribute.</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">class</span> <span class="class">Customer</span> {
<span class="annotation">@javax</span>.jdo.annotations.Column(length=<span class="integer">30</span>)
<span class="directive">public</span> <span class="predefined-type">String</span> getFirstName() { ... }
<span class="directive">public</span> <span class="type">void</span> setFirstName(<span class="predefined-type">String</span> firstName) { ... }
...
}</code></pre>
</div>
</div>
<div class="paragraph">
<p>In this case there is therefore no need for the <code>@Property#maxLength()</code> attribute.</p>
</div>
<div class="sect3">
<h4 id="_non_persistent_properties">30.5.1. Non-persistent properties</h4>
<div class="paragraph">
<p>Of course, not every property is persistent (it could instead be derived), and neither is every domain object an entity (it could be a view model). For these non persistable properties the <code>maxLength()</code> attribute is still required.</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">class</span> <span class="class">Customer</span> {
<span class="annotation">@javax</span>.jdo.annotation.NotPersistent <i class="conum" data-value="1"></i><b>(1)</b>
<span class="annotation">@Property</span>(maxLength=<span class="integer">100</span>)
<span class="directive">public</span> <span class="predefined-type">String</span> getFullName() { ... } <i class="conum" data-value="2"></i><b>(2)</b>
<span class="directive">public</span> <span class="type">void</span> setFullName(<span class="predefined-type">String</span> fullName) { ... } <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>a non persisted (derived) property</td>
</tr>
<tr>
<td><i class="conum" data-value="2"></i><b>2</b></td>
<td>implementation would most likely derive full name from constituent parts (eg first name, middle initial, last name)</td>
</tr>
<tr>
<td><i class="conum" data-value="3"></i><b>3</b></td>
<td>implementation would most likely parse the input and update the constituent parts</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
<div class="sect2">
<h3 id="_rgant-Property_mustSatisfy">30.6. <code>mustSatisfy()</code></h3>
<button type="button" class="button secondary" onclick="window.location.href="https://github.com/apache/isis/edit/master/adocs/documentation/src/main/asciidoc/guides/_rgant-Property_mustSatisfy.adoc"" style="float: right; font-size: small; padding: 6px; margin-top: -55px; "><i class="fa fa-pencil-square-o"></i> Edit</button>
<div class="paragraph">
<p>The <code>mustSatisfy()</code> attribute allows arbitrary validation to be applied to properties using an (implementation of a) <code>org.apache.isis.applib.spec.Specification</code> object. The attribute is also supported on <a href="#_rgant-Parameter_mustSatisfy">parameters</a>.</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>The specification implementations can (of course) be reused between properties and <a href="#_rgant-Parameter_mustSatisfy">parameters</a>.</p>
</div> </td>
</tr>
</tbody>
</table>
</div>
<div class="paragraph">
<p>The <code>Specification</code> is consulted during validation, being passed the proposed value. If the proposed value fails, then the value returned is the used as the invalidity reason.</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">class</span> <span class="class">StartWithCapitalLetterSpecification</span>
<span class="directive">extends</span> AbstractSpecification<<span class="predefined-type">String</span>> { <i class="conum" data-value="1"></i><b>(1)</b>
<span class="directive">public</span> <span class="predefined-type">String</span> satisfiesSafely(<span class="predefined-type">String</span> proposed) {
<span class="keyword">return</span> <span class="string"><span class="delimiter">"</span><span class="delimiter">"</span></span>.equals(proposed)
? <span class="string"><span class="delimiter">"</span><span class="content">Empty string</span><span class="delimiter">"</span></span>
: !<span class="predefined-type">Character</span>.isUpperCase(proposed.charAt(<span class="integer">0</span>))
? <span class="string"><span class="delimiter">"</span><span class="content">Does not start with a capital letter</span><span class="delimiter">"</span></span>
: <span class="predefined-constant">null</span>;
}
}
<span class="directive">public</span> <span class="type">class</span> <span class="class">Customer</span> {
<span class="annotation">@Property</span>(mustSatisfy=StartWithCapitalLetterSpecification.class)
<span class="directive">public</span> <span class="predefined-type">String</span> getFirstName() { ... }
...
}</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 <code>AbstractSpecification</code> class conveniently handles type-safety and dealing with null values. The applib also provides <code>SpecificationAnd</code> and <code>SpecificationOr</code> to allow specifications to be combined "algebraically".</td>
</tr>
</tbody>
</table>
</div>
<div class="paragraph">
<p>It is also possible to provide translatable reasons. Rather than implement <code>Specification</code>, instead implement <code>Specification2</code> which defines the 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">Specification2</span> <span class="directive">extends</span> Specification {
<span class="directive">public</span> TranslatableString satisfiesTranslatable(<span class="predefined-type">Object</span> obj); <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>Return <code>null</code> if specification satisfied, otherwise the reason as a translatable string</td>
</tr>
</tbody>
</table>
</div>
<div class="paragraph">
<p>With <code>Specification2</code> there is no need to implement the inherited <code>satifies(Object)</code>; that method will never be called.</p>
</div>
</div>
<div class="sect2">
<h3 id="_rgant-Property_notPersisted">30.7. <code>notPersisted()</code></h3>
<button type="button" class="button secondary" onclick="window.location.href="https://github.com/apache/isis/edit/master/adocs/documentation/src/main/asciidoc/guides/_rgant-Property_notPersisted.adoc"" style="float: right; font-size: small; padding: 6px; margin-top: -55px; "><i class="fa fa-pencil-square-o"></i> Edit</button>
<div class="paragraph">
<p>The (somewhat misnamed) <code>notPersisted()</code> attribute indicates that the collection should be excluded from any snapshots generated by the <a href="rgsvc.html#_rgsvc_api_XmlSnapshotService"><code>XmlSnapshotService</code></a>. This attribute is also supported for <a href="#_rgant-Collection_notPersisted">collections</a>.</p>
</div>
<div class="admonitionblock warning">
<table>
<tbody>
<tr>
<td class="icon"> <i class="fa icon-warning" title="Warning"></i> </td>
<td class="content">
<div class="paragraph">
<p>This annotation does <em>not</em> specify that a property is not persisted in the JDO/DataNucleus objectstore. See below for details as to how to additionally annotate the property for this.</p>
</div> </td>
</tr>
</tbody>
</table>
</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">class</span> <span class="class">Order</span> {
<span class="annotation">@Property</span>(notPersisted=<span class="predefined-constant">true</span>)
<span class="directive">public</span> Order getPreviousOrder() {...}
<span class="directive">public</span> <span class="type">void</span> setPreviousOrder(Order previousOrder) {...}
...
}</code></pre>
</div>
</div>
<div class="paragraph">
<p>Historically this annotation also hinted as to whether the property’s value contents should be persisted in the object store. However, the JDO/DataNucleus objectstore does not recognize this annotation. Thus, to ensure that a property is actually not persisted, it should <strong>also</strong> be annotated with <code>@javax.jdo.annotations.NotPersistent</code>.</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">class</span> <span class="class">Order</span> {
<span class="annotation">@Property</span>(notPersisted=<span class="predefined-constant">true</span>) <i class="conum" data-value="1"></i><b>(1)</b>
<span class="annotation">@javax</span>.jdo.annotations.NotPersistent <i class="conum" data-value="2"></i><b>(2)</b>
<span class="directive">public</span> Order getPreviousOrder() {...}
<span class="directive">public</span> <span class="type">void</span> setPreviousOrder(Order previousOrder) {...}
...
}</code></pre>
</div>
</div>
<div class="colist arabic">
<table>
<tbody>
<tr>
<td><i class="conum" data-value="1"></i><b>1</b></td>
<td>ignored by Apache Isis</td>
</tr>
<tr>
<td><i class="conum" data-value="2"></i><b>2</b></td>
<td>ignored by JDO/DataNucleus</td>
</tr>
</tbody>
</table>
</div>
<div class="paragraph">
<p>Alternatively, if the property is derived, then providing only a "getter" will also work:</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">Order</span> {
<span class="directive">public</span> Order getPreviousOrder() {...}
...
}</code></pre>
</div>
</div>
</div>
<div class="sect2">
<h3 id="_rgant-Property_optionality">30.8. <code>optionality()</code></h3>
<button type="button" class="button secondary" onclick="window.location.href="https://github.com/apache/isis/edit/master/adocs/documentation/src/main/asciidoc/guides/_rgant-Property_optionality.adoc"" style="float: right; font-size: small; padding: 6px; margin-top: -55px; "><i class="fa fa-pencil-square-o"></i> Edit</button>
<div class="paragraph">
<p>By default, Apache Isis assumes that all properties of an domain object or view model are required (mandatory). The <code>optionality()</code> attribute allows this to be relaxed. The attribute is also supported for <a href="#_rgant-Parameter_optionality">parameters</a>.</p>
</div>
<div class="paragraph">
<p>That said, properties are most commonly defined on persistent domain objects (entities), in which case the JDO <a href="#_rgant-Column"><code>@Column</code></a> should be specified. Apache Isis can infer the maxLength directly from the equivalent @Column#length() annotation.</p>
</div>
<div class="paragraph">
<p>That said, properties are most commonly defined on persistent domain objects (entities), in which case the JDO <a href="#_rgant-Column"><code>@Column</code></a> will in any case need to be specified. Apache Isis can infer the <code>optionality</code> semantic directly from the equivalent <code>@Column#allowsNull()</code> annotation/attribute.</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">class</span> <span class="class">Customer</span> {
<span class="annotation">@javax</span>.jdo.annotations.Column(allowsNull=<span class="string"><span class="delimiter">"</span><span class="content">true</span><span class="delimiter">"</span></span>)
<span class="directive">public</span> <span class="predefined-type">String</span> getMiddleInitial() { ... }
<span class="directive">public</span> <span class="type">void</span> setMiddleInitial(<span class="predefined-type">String</span> middleInitial) { ... }
...
}</code></pre>
</div>
</div>
<div class="paragraph">
<p>In this case there is no need for the <code>@Property#optionality()</code> attribute.</p>
</div>
<div class="sect3">
<h4 id="_mismatched_defaults">30.8.1. Mismatched defaults</h4>
<div class="paragraph">
<p>If the <code>@Column#allowsNull()</code> attribute is omitted and the `@Property#optionality() attribute is also omitted, then note that Isis' defaults and JDO’s defaults differ. Specifically, Isis always assumes properties are mandatory, whereas JDO specifies that primitives are mandatory, but all reference types are optional.</p>
</div>
<div class="paragraph">
<p>When Apache Isis initializes it checks for these mismatches during its metamodel validation phase, and will fail to boot ("fail-fast") if there is a mismatch. The fix is usually to add the <code>@Column#allowsNull()</code> annotation/attribute.</p>
</div>
</div>
<div class="sect3">
<h4 id="_superclass_inheritance_type">30.8.2. Superclass inheritance type</h4>
<div class="paragraph">
<p>There is one case (at least) it may be necessary to annotate the property with both <code>@Column#allowsNull</code> and also <code>@Property#optionality()</code>. If the property is logically mandatory and is in a subclass, but the mapping of the class hierarchy is to store both the superclass and subclass(es) into a single table (ie a "roll-up" mapping using <code>javax.jdo.annotations.InheritanceStrategy#SUPERCLASS_TABLE</code>), then JDO requires that the property is annotated as <code>@Column#allowsNull="true"</code>: its value will be not defined for other subclasses.</p>
</div>
<div class="paragraph">
<p>In this case we therefore require both 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
<span class="annotation">@javax</span>.jdo.annotations.Inheritance(strategy = InheritanceStrategy.NEW_TABLE)
<span class="directive">public</span> <span class="directive">abstract</span> <span class="type">class</span> <span class="class">PaymentMethod</span> {
...
}
<span class="annotation">@javax</span>.jdo.annotations.PersistenceCapable
<span class="annotation">@javax</span>.jdo.annotations.Inheritance(strategy = InheritanceStrategy.SUPERCLASS_TABLE)
<span class="directive">public</span> <span class="type">class</span> <span class="class">CreditCardPaymentMethod</span> <span class="directive">extends</span> PaymentMethod {
<span class="directive">private</span> <span class="predefined-type">String</span> cardNumber;
<span class="annotation">@javax</span>.jdo.annotations.Column(allowsNull=<span class="string"><span class="delimiter">"</span><span class="content">true</span><span class="delimiter">"</span></span>)
<span class="annotation">@Property</span>(optionality=Optionality.MANDATORY)
<span class="directive">public</span> <span class="predefined-type">String</span> getCardNumber() { <span class="keyword">return</span> <span class="local-variable">this</span>.cardNumber; }
<span class="directive">public</span> <span class="type">void</span> setCardNumber(<span class="predefined-type">String</span> cardNumber) { <span class="local-variable">this</span>.cardNumber = cardNumber; }
...
}</code></pre>
</div>
</div>
<div class="paragraph">
<p>Alternatively, you could rely on the fact that Apache Isis never looks at fields (whereas JDO does) and move the JDO annotation to the field:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code data-lang="java"><span class="annotation">@javax</span>.jdo.annotations.PersistenceCapable
<span class="annotation">@javax</span>.jdo.annotations.Inheritance(strategy = InheritanceStrategy.SUPERCLASS_TABLE)
<span class="directive">public</span> <span class="type">class</span> <span class="class">CreditCardPaymentMethod</span> <span class="directive">extends</span> PaymentMethod {
<span class="annotation">@javax</span>.jdo.annotations.Column(allowsNull=<span class="string"><span class="delimiter">"</span><span class="content">true</span><span class="delimiter">"</span></span>)
<span class="directive">private</span> <span class="predefined-type">String</span> cardNumber;
<span class="directive">public</span> <span class="predefined-type">String</span> getCardNumber() { <span class="keyword">return</span> <span class="local-variable">this</span>.cardNumber; }
<span class="directive">public</span> <span class="type">void</span> setCardNumber(<span class="predefined-type">String</span> cardNumber) { <span class="local-variable">this</span>.cardNumber = cardNumber; }
...
}</code></pre>
</div>
</div>
<div class="paragraph">
<p>However this at first glance this might be read as eing that the property is optional whereas Isis' default (required) applies. Also, in the future Apache Isis may be extended to support reading annotations from fields.</p>
</div>
</div>
<div class="sect3">
<h4 id="_non_persistent_properties_2">30.8.3. Non-persistent properties</h4>
<div class="paragraph">
<p>Of course, not every property is persistent (it could instead be derived), and neither is every domain object an entity (it could be a view model). For these non persistable properties the <code>optionality()</code> attribute is still required.</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">class</span> <span class="class">Customer</span> {
<span class="annotation">@javax</span>.jdo.annotation.NotPersistent <i class="conum" data-value="1"></i><b>(1)</b>
<span class="annotation">@Property</span>(optionality=Optionality.OPTIONAL)
<span class="directive">public</span> <span class="predefined-type">String</span> getFullName() { ... } <i class="conum" data-value="2"></i><b>(2)</b>
<span class="directive">public</span> <span class="type">void</span> setFullName(<span class="predefined-type">String</span> fullName) { ... } <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>a non persisted (derived) property</td>
</tr>
<tr>
<td><i class="conum" data-value="2"></i><b>2</b></td>
<td>implementation would most likely derive full name from constituent parts (eg first name, middle initial, last name)</td>
</tr>
<tr>
<td><i class="conum" data-value="3"></i><b>3</b></td>
<td>implementation would most likely parse the input and update the constituent parts</td>
</tr>
</tbody>
</table>
</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>The attribute has no meaning for a primitive type such as <code>int</code>: primitives will always have a default value (e.g. zero). If optionality is required, then use the corresponding wrapper class (e.g. <code>java.lang.Integer</code>) and annotate with <code>Parameter#optionality()</code> as required.</p>
</div> </td>
</tr>
</tbody>
</table>
</div>
<div class="paragraph">
<p>The values for the attribute are simply <code>OPTIONAL</code> or <code>MANDATORY</code>.</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">class</span> <span class="class">Customer</span> {
<span class="directive">public</span> Order placeOrder(
<span class="directive">final</span> Product product,
<span class="annotation">@ParameterLayout</span>(named = <span class="string"><span class="delimiter">"</span><span class="content">Quantity</span><span class="delimiter">"</span></span>)
<span class="directive">final</span> <span class="type">int</span> quantity,
<span class="annotation">@Parameter</span>(optionality = Optionality.OPTIONAL)
<span class="annotation">@ParameterLayout</span>(named = <span class="string"><span class="delimiter">"</span><span class="content">Special Instructions</span><span class="delimiter">"</span></span>)
<span class="directive">final</span> <span class="predefined-type">String</span> instr) {
...
}
...
}</code></pre>
</div>
</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>It is also possible to specify optionality using <a href="#_rgant_Nullable"><code>@Nullable</code></a> annotation.</p>
</div> </td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
<div class="sect2">
<h3 id="_rgant-Property_regexPattern">30.9. <code>regexPattern()</code></h3>
<button type="button" class="button secondary" onclick="window.location.href="https://github.com/apache/isis/edit/master/adocs/documentation/src/main/asciidoc/guides/_rgant-Property_regexPattern.adoc"" style="float: right; font-size: small; padding: 6px; margin-top: -55px; "><i class="fa fa-pencil-square-o"></i> Edit</button>
<div class="paragraph">
<p>There are three attributes related to enforcing regular expressions:</p>
</div>
<div class="ulist">
<ul>
<li> <p>The <code>regexPattern()</code> attribute validates the contents of any string property with respect to a regular expression pattern. It is ignored if applied to properties of any other type. This attribute can also be specified for <a href="#_rgant-Parameter_regexPattern">parameters</a>.</p> </li>
<li> <p>The <code>regexPatternFlags()</code> attribute specifies flags that modify the handling of the pattern. The values are those that would normally be passed to <code>java.util.regex.Pattern#compile(String,int)</code>.</p> </li>
<li> <p>The related <code>regexPatternReplacement()</code> attribute specifies the error message to show if the provided argument does not match the regex pattern.</p> </li>
</ul>
</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">class</span> <span class="class">Customer</span> {
<span class="annotation">@Property</span>(
regexPattern = <span class="string"><span class="delimiter">"</span><span class="content">(</span><span class="char">\\</span><span class="content">w+</span><span class="char">\\</span><span class="content">.)*</span><span class="char">\\</span><span class="content">w+@(</span><span class="char">\\</span><span class="content">w+</span><span class="char">\\</span><span class="content">.)+[A-Za-z]+</span><span class="delimiter">"</span></span>,
regexPatternFlags=<span class="predefined-type">Pattern</span>.CASE_INSENSITIVE,
regexPatternReplacement = <span class="string"><span class="delimiter">"</span><span class="content">Must be valid email address (containing a '@') symbol</span><span class="delimiter">"</span></span> <i class="conum" data-value="1"></i><b>(1)</b>
)
<span class="directive">public</span> <span class="predefined-type">String</span> getEmail() { ... }
}</code></pre>
</div>
</div>
<div class="colist arabic">
<table>
<tbody>
<tr>
<td><i class="conum" data-value="1"></i><b>1</b></td>
<td>Note that there is currently no i18n support for this phrase.</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
</div>
<div class="sect1">
<h2 id="_rgant-PropertyLayout">31. <code>@PropertyLayout</code></h2>
<button type="button" class="button secondary" onclick="window.location.href="https://github.com/apache/isis/edit/master/adocs/documentation/src/main/asciidoc/guides/_rgant-PropertyLayout.adoc"" style="float: right; font-size: small; padding: 6px; margin-top: -55px; "><i class="fa fa-pencil-square-o"></i> Edit</button>
<div class="sectionbody">
<div class="paragraph">
<p>The <code>@PropertyLayout</code> annotation applies to properties collecting together all UI hints within a single annotation.</p>
</div>
<div class="paragraph">
<p>The table below summarizes the annotation’s attributes.</p>
</div>
<table class="tableblock frame-all grid-all spread">
<caption class="title">
Table 20.
<code>@PropertyLayout</code> attributes
</caption>
<colgroup>
<col style="width: 25%;">
<col style="width: 25%;">
<col style="width: 50%;">
</colgroup>
<thead>
<tr>
<th class="tableblock halign-left valign-top">Attribute</th>
<th class="tableblock halign-left valign-top">Values (default)</th>
<th class="tableblock halign-left valign-top">Description</th>
</tr>
</thead>
<tbody>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="#_rgant-PropertyLayout_cssClass"><code>cssClass()</code></a></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Any string valid as a CSS class</p></td>
<td class="tableblock halign-left valign-top">
<div>
<div class="paragraph">
<p>the css class that a property should have, to allow more targetted styling in <a href="rgcfg.html#_rgcfg_application-specific_application-css"><code>application.css</code></a></p>
</div>
</div></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="#_rgant-PropertyLayout_describedAs"><code>describedAs()</code></a></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">String</p></td>
<td class="tableblock halign-left valign-top">
<div>
<div class="paragraph">
<p>description of this property, eg to be rendered in a tooltip.</p>
</div>
</div></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="#_rgant-PropertyLayout_hidden"><code>hidden()</code></a></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>EVERYWHERE</code>, <code>OBJECT_FORMS</code>, <code>PARENTED_TABLES</code>, <code>STANDALONE_TABLES</code>, <code>ALL_TABLES</code>, <code>NOWHERE</code><br> (<code>NOWHERE</code>)</p></td>
<td class="tableblock halign-left valign-top">
<div>
<div class="paragraph">
<p>indicates where (in the UI) the property should be hidden from the user.</p>
</div>
</div></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="#_rgant-PropertyLayout_labelPosition"><code>labelPosition()</code></a></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>LEFT</code>, <code>TOP</code>, <code>RIGHT</code>, <code>NONE</code><br> (<code>LEFT</code>)</p></td>
<td class="tableblock halign-left valign-top">
<div>
<div class="paragraph">
<p>in forms, the positioning of the label relative to the property value.<br></p>
</div>
<div class="paragraph">
<p>Defaults is <code>LEFT</code>, unless <a href="#_rgant-PropertyLayout_multiLine"><code>multiLine</code></a> in which case <code>TOP</code>. The value <code>RIGHT</code> is only supported for boolean properties.<br></p>
</div>
<div class="paragraph">
<p>It is also possible to change the default through a <a href="rgcfg.html#__rgcfg_configuring-core_isis-viewers-propertyLayout-labelPosition">configuration property</a></p>
</div>
</div></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="#_rgant-PropertyLayout_multiLine"><code>multiLine()</code></a></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Positive integer</p></td>
<td class="tableblock halign-left valign-top">
<div>
<div class="paragraph">
<p>for string properties, render as a text area over multiple lines. <br></p>
</div>
<div class="paragraph">
<p>If set > 1, then <a href="#_rgant-PropertyLayout_labelPosition"><code>labelPosition</code></a> defaults to TOP.</p>
</div>
</div></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="#_rgant-PropertyLayout_named"><code>named()</code></a></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">String</p></td>
<td class="tableblock halign-left valign-top">
<div>
<div class="paragraph">
<p>to override the name inferred from the collection’s name in code.<br></p>
</div>
<div class="paragraph">
<p>A typical use case is if the desired name is a reserved Java keyword, such as <code>default</code> or <code>package</code>.</p>
</div>
</div></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>namedEscaped()</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>true</code>, <code>false</code><br> (<code>true</code>)</p></td>
<td class="tableblock halign-left valign-top">
<div>
<div class="paragraph">
<p>whether to HTML escape the name of this property.</p>
</div>
</div></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="#_rgant-PropertyLayout_renderedAsDayBefore"><code>renderedAsDayBefore()</code></a></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>true</code>, <code>false</code><br> (<code>false</code>)</p></td>
<td class="tableblock halign-left valign-top">
<div>
<div class="paragraph">
<p>for date properties only, render the date as one day prior to the actually stored date.</p>
</div>
</div></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="#_rgant-PropertyLayout_typicalLength"><code>typicalLength()</code></a></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Positive integer.</p></td>
<td class="tableblock halign-left valign-top">
<div>
<div class="paragraph">
<p>the typical entry length of a field, use to determine the optimum width for display</p>
</div>
</div></td>
</tr>
</tbody>
</table>
<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">class</span> <span class="class">ToDoItem</span> {
<span class="annotation">@PropertyLayout</span>(
cssClass=<span class="string"><span class="delimiter">"</span><span class="content">x-key</span><span class="delimiter">"</span></span>,
named=<span class="string"><span class="delimiter">"</span><span class="content">Description of this <i>item</i></span><span class="delimiter">"</span></span>,
namedEscaped=<span class="predefined-constant">false</span>,
describedAs=<span class="string"><span class="delimiter">"</span><span class="content">What needs to be done</span><span class="delimiter">"</span></span>,
labelPosition=LabelPosition.LEFT,
typicalLength=<span class="integer">80</span>
)
<span class="directive">public</span> <span class="predefined-type">String</span> getDescription() { ... }
...
}</code></pre>
</div>
</div>
<div class="paragraph">
<p>It is also possible to apply the annotation to actions of domain services that are acting as <a href="../../more-advanced-topics/how-to-01-062-How-to-decouple-dependencies-using-contributions.html">contributed properties</a>.</p>
</div>
<div class="paragraph">
<p>As an alternative to using the <code>@PropertyLayout</code> annotation, a dynamic layout using <a href="ugfun.html#_ugfun_object-layout_dynamic"><code>.layout.json</code></a> file can be specified; for example:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code data-lang="javascript"><span class="string"><span class="delimiter">"</span><span class="content">description</span><span class="delimiter">"</span></span>: {
<span class="key"><span class="delimiter">"</span><span class="content">propertyLayout</span><span class="delimiter">"</span></span>: {
<span class="key"><span class="delimiter">"</span><span class="content">cssClass</span><span class="delimiter">"</span></span>: <span class="string"><span class="delimiter">"</span><span class="content">x-key</span><span class="delimiter">"</span></span>,
<span class="key"><span class="delimiter">"</span><span class="content">describedAs</span><span class="delimiter">"</span></span>: <span class="string"><span class="delimiter">"</span><span class="content">What needs to be done</span><span class="delimiter">"</span></span>,
<span class="key"><span class="delimiter">"</span><span class="content">labelPosition</span><span class="delimiter">"</span></span>: <span class="string"><span class="delimiter">"</span><span class="content">LEFT</span><span class="delimiter">"</span></span>,
<span class="key"><span class="delimiter">"</span><span class="content">typicalLength</span><span class="delimiter">"</span></span>: <span class="integer">80</span>
}
}</code></pre>
</div>
</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>The annotation is one of a handful (others including <a href="#_rgant-Collection"><code>@Collection</code></a>, <a href="#_rgant-CollectionLayout"><code>@CollectionLayout</code></a> and <a href="#_rgant-Property"><code>@Property</code></a>) that can also be applied to the field, rather than the getter method. This is specifically so that boilerplate-busting tools such as <a href="https://projectlombok.org/">Project Lombok</a> can be used.</p>
</div> </td>
</tr>
</tbody>
</table>
</div>
<div class="sect2">
<h3 id="_rgant-PropertyLayout_cssClass">31.1. <code>cssClass()</code></h3>
<button type="button" class="button secondary" onclick="window.location.href="https://github.com/apache/isis/edit/master/adocs/documentation/src/main/asciidoc/guides/_rgant-PropertyLayout_cssClass.adoc"" style="float: right; font-size: small; padding: 6px; margin-top: -55px; "><i class="fa fa-pencil-square-o"></i> Edit</button>
<div class="paragraph">
<p>The <code>cssClass()</code> attribute can be used to render additional CSS classes in the HTML (a wrapping <code><div></code>) that represents the property. <a href="rgcfg.html#_rgcfg_application-specific_application-css">Application-specific CSS</a> can then be used to target and adjust the UI representation of that particular element.</p>
</div>
<div class="paragraph">
<p>This attribute can also be applied to <a href="#_rgant-DomainObjectLayout_cssClass">domain objects</a>, <a href="#_rgant-ViewModelLayout_cssClass">view models</a>, <a href="#_rgant-ActionLayout_cssClass">actions</a> <a href="#_rgant-CollectionLayout_cssClass">collections</a> and <a href="#_rgant-ParameterLayout_cssClass">parameters</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="directive">public</span> <span class="type">class</span> <span class="class">ToDoItem</span> {
<span class="annotation">@PropertyLayout</span>(cssClass=<span class="string"><span class="delimiter">"</span><span class="content">x-key</span><span class="delimiter">"</span></span>)
<span class="directive">public</span> LocalDate getDueBy() { ... }
}</code></pre>
</div>
</div>
<div class="paragraph">
<p>As an alternative to using the annotation, the dynamic <a href="ugfun.html#_ugfun_object-layout_dynamic"><code>.layout.json</code></a> can be used instead, eg:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code data-lang="javascript"><span class="string"><span class="delimiter">"</span><span class="content">dueBy</span><span class="delimiter">"</span></span>: {
<span class="key"><span class="delimiter">"</span><span class="content">propertyLayout</span><span class="delimiter">"</span></span>: { <span class="key"><span class="delimiter">"</span><span class="content">cssClass</span><span class="delimiter">"</span></span>: <span class="string"><span class="delimiter">"</span><span class="content">x-key</span><span class="delimiter">"</span></span> }
}</code></pre>
</div>
</div>
</div>
<div class="sect2">
<h3 id="_rgant-PropertyLayout_describedAs">31.2. <code>describedAs()</code></h3>
<button type="button" class="button secondary" onclick="window.location.href="https://github.com/apache/isis/edit/master/adocs/documentation/src/main/asciidoc/guides/_rgant-PropertyLayout_describedAs.adoc"" style="float: right; font-size: small; padding: 6px; margin-top: -55px; "><i class="fa fa-pencil-square-o"></i> Edit</button>
<div class="paragraph">
<p>The <code>describedAs()</code> attribute is used to provide a short description of the property to the user. In the <a href="ugvw.html">Wicket viewer</a> it is displayed as a 'tool tip'. The attribute can also be specified for <a href="#_rgant-CollectionLayout_describedAs">collections</a>, <a href="#_rgant-ActionLayout_describedAs">actions</a>, <a href="#_rgant-ParameterLayout_describedAs">parameters</a>, <a href="#_rgant-DomainObjectLayout_describedAs">domain objects</a> and <a href="#_rgant-ViewModelLayout_describedAs">view models</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="directive">public</span> <span class="type">class</span> <span class="class">Customer</span> {
<span class="annotation">@DescribedAs</span>(<span class="string"><span class="delimiter">"</span><span class="content">The name that the customer has indicated that they wish to be </span><span class="delimiter">"</span></span> +
<span class="string"><span class="delimiter">"</span><span class="content">addressed as (e.g. Johnny rather than Jonathan)</span><span class="delimiter">"</span></span>)
<span class="directive">public</span> <span class="predefined-type">String</span> getFirstName() { ... }
}</code></pre>
</div>
</div>
<div class="paragraph">
<p>As an alternative to using the annotation, the dynamic <a href="ugfun.html#_ugfun_object-layout_dynamic"><code>.layout.json</code></a> can be used instead, eg:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code data-lang="javascript"><span class="string"><span class="delimiter">"</span><span class="content">firstName:</span><span class="delimiter">"</span></span> {
<span class="key"><span class="delimiter">"</span><span class="content">propertyLayout</span><span class="delimiter">"</span></span>: {
<span class="key"><span class="delimiter">"</span><span class="content">describedAs</span><span class="delimiter">"</span></span>: <span class="string"><span class="delimiter">"</span><span class="content">The name that the customer has indicated that they wish to be addressed as (e.g. Johnny rather than Jonathan)</span><span class="delimiter">"</span></span>
}
}</code></pre>
</div>
</div>
</div>
<div class="sect2">
<h3 id="_rgant-PropertyLayout_labelPosition">31.3. <code>labelPosition()</code></h3>
<button type="button" class="button secondary" onclick="window.location.href="https://github.com/apache/isis/edit/master/adocs/documentation/src/main/asciidoc/guides/_rgant-PropertyLayout_labelPosition.adoc"" style="float: right; font-size: small; padding: 6px; margin-top: -55px; "><i class="fa fa-pencil-square-o"></i> Edit</button>
<div class="paragraph">
<p>The <code>labelPosition()</code> attribute determines the positioning of labels for properties. This attribute can also be specified for <a href="#_rgant-ParameterLayout_labelPosition">parameters</a>.</p>
</div>
<div class="paragraph">
<p>The positioning of labels is typically <code>LEFT</code>, but can be positioned to the <code>TOP</code>. The one exception is <a href="#_rgant-ParameterLayout_multiLine"><code>multiLine()</code></a> string properties, where the label defaults to <code>TOP</code> automatically (to provide as much real-estate for the multiline text field as possible).</p>
</div>
<div class="paragraph">
<p>For boolean properties a positioning of <code>RIGHT</code> is also allowed; this is ignored for all other types.</p>
</div>
<div class="paragraph">
<p>It is also possible to suppress the label altogether, using <code>NONE</code>.</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">class</span> <span class="class">ToDoItem</span> {
<span class="annotation">@PropertyLayout</span>(
labelPosition=LabelPosition.TOP
)
<span class="directive">public</span> <span class="predefined-type">String</span> getDescription() { ... }
<span class="directive">public</span> <span class="type">void</span> setDescription(<span class="predefined-type">String</span> description) { ... }
...
}</code></pre>
</div>
</div>
<div class="paragraph">
<p>To get an idea of how these are rendered (in the <a href="ugvw.html">Wicket viewer</a>), we can look at the (non-ASF) <a href="http://github.com/isisaddons/isis-app-todoapp">Isis addons' todoapp</a> that happens to have examples of most of these various label positions.</p>
</div>
<div class="paragraph">
<p>The default <code>LEFT</code> label positioning is used by the <code>cost</code> property:</p>
</div>
<div class="imageblock">
<div class="content">
<a class="image" href="images/reference-annotations/PropertyLayout/labelPosition-LEFT.png"><img src="images/reference-annotations/PropertyLayout/labelPosition-LEFT.png" alt="labelPosition LEFT" width="720px"></a>
</div>
</div>
<div class="paragraph">
<p>The <code>TOP</code> label positioning is used by the <code>category</code> property:</p>
</div>
<div class="imageblock">
<div class="content">
<a class="image" href="images/reference-annotations/PropertyLayout/labelPosition-TOP.png"><img src="images/reference-annotations/PropertyLayout/labelPosition-TOP.png" alt="labelPosition TOP" width="720px"></a>
</div>
</div>
<div class="paragraph">
<p>Labels are suppressed, using <code>NONE</code>, for the <code>subcategory</code> property:</p>
</div>
<div class="imageblock">
<div class="content">
<a class="image" href="images/reference-annotations/PropertyLayout/labelPosition-NONE.png"><img src="images/reference-annotations/PropertyLayout/labelPosition-NONE.png" alt="labelPosition NONE" width="720px"></a>
</div>
</div>
<div class="paragraph">
<p>The todoapp’s <code>complete</code> (boolean) property renders the label to the LEFT (the default):</p>
</div>
<div class="imageblock">
<div class="content">
<a class="image" href="images/reference-annotations/PropertyLayout/labelPosition-boolean-LEFT.png"><img src="images/reference-annotations/PropertyLayout/labelPosition-boolean-LEFT.png" alt="labelPosition boolean LEFT" width="720px"></a>
</div>
</div>
<div class="paragraph">
<p>Moving the label to the <code>RIGHT</code> looks like:</p>
</div>
<div class="imageblock">
<div class="content">
<a class="image" href="images/reference-annotations/PropertyLayout/labelPosition-boolean-RIGHT.png"><img src="images/reference-annotations/PropertyLayout/labelPosition-boolean-RIGHT.png" alt="labelPosition boolean RIGHT" width="720px"></a>
</div>
</div>
<div class="paragraph">
<p>As an alternative to using the annotation, the dynamic <a href="ugfun.html#_ugfun_object-layout_dynamic"><code>.layout.json</code></a> can be used instead, eg:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code data-lang="javascript"><span class="string"><span class="delimiter">"</span><span class="content">description</span><span class="delimiter">"</span></span>: {
<span class="key"><span class="delimiter">"</span><span class="content">propertyLayout</span><span class="delimiter">"</span></span>: {
<span class="key"><span class="delimiter">"</span><span class="content">labelPosition</span><span class="delimiter">"</span></span>: <span class="string"><span class="delimiter">"</span><span class="content">TOP</span><span class="delimiter">"</span></span>
}
}</code></pre>
</div>
</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="title">
Specifying a default setting for label positions
</div>
<div class="paragraph">
<p>If you want a consistent look-n-feel throughout the app, eg all property labels to the top, then it’d be rather frustrating to have to annotate every property.</p>
</div>
<div class="paragraph">
<p>Instead, a default can be specified using a <a href="rgcfg.html#_rgcfg_configuring-core">configuration property</a> in <code>isis.properties</code>:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code data-lang="ini">isis.viewers.propertyLayout.labelPosition=TOP</code></pre>
</div>
</div>
<div class="paragraph">
<p>or</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code data-lang="ini">isis.viewers.propertyLayout.labelPosition=LEFT</code></pre>
</div>
</div>
<div class="paragraph">
<p>If these are not present then Apache Isis will render according to internal defaults. At the time of writing, this means labels are to the left for all datatypes except multiline strings.</p>
</div> </td>
</tr>
</tbody>
</table>
</div>
</div>
<div class="sect2">
<h3 id="_rgant-PropertyLayout_multiLine">31.4. <code>multiLine()</code></h3>
<button type="button" class="button secondary" onclick="window.location.href="https://github.com/apache/isis/edit/master/adocs/documentation/src/main/asciidoc/guides/_rgant-PropertyLayout_multiLine.adoc"" style="float: right; font-size: small; padding: 6px; margin-top: -55px; "><i class="fa fa-pencil-square-o"></i> Edit</button>
<div class="paragraph">
<p>The <code>multiLine()</code> attribute specifies that the text field for a string property should span multiple lines. It is ignored for other property types. The attribute is also supported for <a href="#_rgant-ParameterLayout_multiLine">parameters</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="directive">public</span> <span class="type">class</span> <span class="class">BugReport</span> {
<span class="annotation">@PropertyLayout</span>(
numberOfLines=<span class="integer">10</span>
)
<span class="directive">public</span> <span class="predefined-type">String</span> getStepsToReproduce() { ... }
<span class="directive">public</span> <span class="type">void</span> setStepsToReproduce(<span class="predefined-type">String</span> stepsToReproduce) { ... }
...
}</code></pre>
</div>
</div>
<div class="paragraph">
<p>Here the <code>stepsToReproduce</code> will be displayed in a text area of 10 rows.</p>
</div>
<div class="paragraph">
<p>As an alternative to using the annotation, the dynamic <a href="ugfun.html#_ugfun_object-layout_dynamic"><code>.layout.json</code></a> can be used instead, eg:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code data-lang="javascript"><span class="string"><span class="delimiter">"</span><span class="content">stepsToReproduce</span><span class="delimiter">"</span></span>: {
<span class="key"><span class="delimiter">"</span><span class="content">propertyLayout</span><span class="delimiter">"</span></span>: {
<span class="key"><span class="delimiter">"</span><span class="content">numberOfLines</span><span class="delimiter">"</span></span>: <span class="integer">10</span>
}
}</code></pre>
</div>
</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>If set > 1 (as would normally be the case), then the default <a href="#_rgant-PropertyLayout_labelPosition"><code>labelPosition</code></a> defaults to <code>TOP</code> (rather than <code>LEFT</code>, as would normally be the case).</p>
</div> </td>
</tr>
</tbody>
</table>
</div>
</div>
<div class="sect2">
<h3 id="_rgant-PropertyLayout_named">31.5. named()</h3>
<button type="button" class="button secondary" onclick="window.location.href="https://github.com/apache/isis/edit/master/adocs/documentation/src/main/asciidoc/guides/_rgant-PropertyLayout_named.adoc"" style="float: right; font-size: small; padding: 6px; margin-top: -55px; "><i class="fa fa-pencil-square-o"></i> Edit</button>
<div class="paragraph">
<p>The <code>named()</code> attribute explicitly specifies the property’s name, overriding the name that would normally be inferred from the Java source code. This attribute can also be specified for <a href="#_rgant-ActionLayout_named">actions</a>, <a href="#_rgant-CollectionLayout_named">collections</a>, <a href="#_rgant-ParameterLayout_named">parameters</a>, <a href="#_rgant-DomainObjectLayout_named">domain objects</a>, <a href="#_rgant-ViewModelLayout_named">view models</a> and <a href="#_rgant-DomainServiceLayout_named">domain services</a>.</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>Following the <a href="http://en.wikipedia.org/wiki/Don%27t_repeat_yourself">don’t repeat yourself</a> principle, we recommend that you only use this attribute when the desired name cannot be used in Java source code. Examples of that include a name that would be a reserved Java keyword (eg "package"), or a name that has punctuation, eg apostrophes.</p>
</div> </td>
</tr>
</tbody>
</table>
</div>
<div class="paragraph">
<p>By default the name is HTML escaped. To allow HTML markup, set the related <code>namedEscaped()</code> attribute to <code>false</code>.</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">class</span> <span class="class">ToDoItem</span> {
<span class="annotation">@PropertyLayout</span>(
named=<span class="string"><span class="delimiter">"</span><span class="content">Description of this <i>item</i></span><span class="delimiter">"</span></span>,
namedEscaped=<span class="predefined-constant">false</span>
)
<span class="directive">public</span> <span class="predefined-type">String</span> getDescription() { ... }
...
}</code></pre>
</div>
</div>
<div class="paragraph">
<p>As an alternative to using the annotation, the dynamic <a href="ugfun.html#_ugfun_object-layout_dynamic"><code>.layout.json</code></a> can be used instead, eg:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code data-lang="javascript"><span class="string"><span class="delimiter">"</span><span class="content">description</span><span class="delimiter">"</span></span>: {
<span class="key"><span class="delimiter">"</span><span class="content">propertyLayout</span><span class="delimiter">"</span></span>: {
<span class="key"><span class="delimiter">"</span><span class="content">named</span><span class="delimiter">"</span></span>: <span class="string"><span class="delimiter">"</span><span class="content">Description of this <i>item</i></span><span class="delimiter">"</span></span>,
<span class="key"><span class="delimiter">"</span><span class="content">namedEscaped</span><span class="delimiter">"</span></span>: <span class="predefined-constant">false</span>
}
}</code></pre>
</div>
</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>The framework also provides a separate, powerful mechanism for <a href="ugbtb.html#_ugbtb_i18n">internationalization</a>.</p>
</div> </td>
</tr>
</tbody>
</table>
</div>
</div>
<div class="sect2">
<h3 id="_rgant-PropertyLayout_renderedAsDayBefore">31.6. <code>renderedAsDayBefore()</code></h3>
<button type="button" class="button secondary" onclick="window.location.href="https://github.com/apache/isis/edit/master/adocs/documentation/src/main/asciidoc/guides/_rgant-PropertyLayout_renderedAsDayBefore.adoc"" style="float: right; font-size: small; padding: 6px; margin-top: -55px; "><i class="fa fa-pencil-square-o"></i> Edit</button>
<div class="paragraph">
<p>The <code>renderedAsDayBefore()</code> attribute applies only to date properties whereby the date will be rendered as the day before the value actually held in the domain object. It is ignored for properties of other types. This attribute is also supported for <a href="#_rgant-ParameterLayout_renderedAsDayBefore">parameters</a>.</p>
</div>
<div class="paragraph">
<p>This behaviour might at first glance appear odd, but the rationale is to support the use case of a sequence of instances that represent adjacent intervals of time. In such cases there would typically be <code>startDate</code> and <code>endDate</code> properties, eg for all of Q2. Storing this as a half-closed interval — eg <code>[1-Apr-2015, 1-July-2015)</code> — can substantially simplify internal algorithms; the <code>endDate</code> of one interval will correspond to the <code>startDate</code> of the next.</p>
</div>
<div class="paragraph">
<p>However, from an end-user perspective the requirement may be to render the interval as a fully closed interval; eg the end date should be shown as <code>30-Jun-2015</code>.</p>
</div>
<div class="paragraph">
<p>This attribute therefore bridges the gap; it presents the information in a way that makes sense to an end-user, but also stores the domain object in a way that is easy work with internally.</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">class</span> <span class="class">Tenancy</span> {
<span class="directive">public</span> LocalDate getStartDate() { ... }
<span class="directive">public</span> <span class="type">void</span> setStartDate(LocalDate startDate) { ... }
<span class="annotation">@PropertyLayout</span>(
renderedAsDayBefore=<span class="predefined-constant">true</span>
)
<span class="directive">public</span> LocalDate getEndDate() { ... }
<span class="directive">public</span> <span class="type">void</span> setEndDate(LocalDate EndDate) { ... }
...
}</code></pre>
</div>
</div>
<div class="paragraph">
<p>As an alternative to using the annotation, the dynamic <a href="ugfun.html#_ugfun_object-layout_dynamic"><code>.layout.json</code></a> can be used instead, eg:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code data-lang="javascript"><span class="string"><span class="delimiter">"</span><span class="content">endDate</span><span class="delimiter">"</span></span>: {
<span class="key"><span class="delimiter">"</span><span class="content">propertyLayout</span><span class="delimiter">"</span></span>: {
<span class="key"><span class="delimiter">"</span><span class="content">renderedAsDayBefore</span><span class="delimiter">"</span></span>: <span class="predefined-constant">true</span>
}
}</code></pre>
</div>
</div>
</div>
<div class="sect2">
<h3 id="_rgant-PropertyLayout_typicalLength">31.7. <code>typicalLength()</code></h3>
<button type="button" class="button secondary" onclick="window.location.href="https://github.com/apache/isis/edit/master/adocs/documentation/src/main/asciidoc/guides/_rgant-PropertyLayout_typicalLength.adoc"" style="float: right; font-size: small; padding: 6px; margin-top: -55px; "><i class="fa fa-pencil-square-o"></i> Edit</button>
<div class="paragraph">
<p>The <code>typicalLength()</code> attribute indicates the typical length of a string property. It is ignored for properties of other types. The attribute is also supported for <a href="#_rgant-ParameterLayout_typicalLength">parameters</a>.</p>
</div>
<div class="paragraph">
<p>The information is intended as a hint to the UI to determine the space that should be given to render a particular string property. That said, note that the <a href="ugvw.html">Wicket viewer</a> uses the maximum space available for all fields, so in effect ignores this attribute.</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">class</span> <span class="class">Customer</span> {
<span class="annotation">@javax</span>.jdo.annotations.Column(length=<span class="integer">30</span>)
<span class="annotation">@ParameterLayout</span>(typicalLength=<span class="integer">20</span>)
<span class="directive">public</span> <span class="predefined-type">String</span> getFirstName() { ... }
<span class="directive">public</span> <span class="type">void</span> setFirstName(<span class="predefined-type">String</span> firstName) { ... }
...
}</code></pre>
</div>
</div>
</div>
</div>
</div>
<div class="sect1">
<h2 id="_rgant-RequestScoped">32. <code>@RequestScoped</code> (<code>javax</code>)</h2>
<button type="button" class="button secondary" onclick="window.location.href="https://github.com/apache/isis/edit/master/adocs/documentation/src/main/asciidoc/guides/_rgant-RequestScoped.adoc"" style="float: right; font-size: small; padding: 6px; margin-top: -55px; "><i class="fa fa-pencil-square-o"></i> Edit</button>
<div class="sectionbody">
<div class="paragraph">
<p>The <code>@javax.enterprise.context.RequestScoped</code> <a href="https://jcp.org/en/jsr/detail?id=299">JSR-299</a> CDI annotation is used to specify that a <a href="#_rgant-DomainService">domain service</a> should be request-scoped rather than a singleton.</p>
</div>
<div class="paragraph">
<p>Although Apache Isis does not (currently) leverage CDI, the semantics are the same as request-scoped service; a new instance is created for each HTTP request, reserved for the exclusive use of all objects interacted with during that request.</p>
</div>
<div class="paragraph">
<p>One of the built-in domain services that uses this annotation is <a href="rgsvc.html#_rgsvc_api_Scratchpad"><code>Scratchpad</code></a>, intended to allow the arbitrary sharing of data between objects. Here is the full source code of this service is:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code data-lang="java"><span class="annotation">@DomainService</span>(
nature = NatureOfService.DOMAIN
)
<span class="annotation">@RequestScoped</span>
<span class="directive">public</span> <span class="type">class</span> <span class="class">Scratchpad</span> {
<span class="directive">private</span> <span class="directive">final</span> <span class="predefined-type">Map</span><<span class="predefined-type">Object</span>, <span class="predefined-type">Object</span>> userData = Maps.newHashMap(); <i class="conum" data-value="1"></i><b>(1)</b>
<span class="annotation">@Programmatic</span>
<span class="directive">public</span> <span class="predefined-type">Object</span> get(<span class="predefined-type">Object</span> key) {
<span class="keyword">return</span> userData.get(key); <i class="conum" data-value="2"></i><b>(2)</b>
}
<span class="annotation">@Programmatic</span>
<span class="directive">public</span> <span class="type">void</span> put(<span class="predefined-type">Object</span> key, <span class="predefined-type">Object</span> value) {
userData.put(key, value); <i class="conum" data-value="3"></i><b>(3)</b>
}
<span class="annotation">@Programmatic</span>
<span class="directive">public</span> <span class="type">void</span> clear() {
userData.clear(); <i class="conum" data-value="4"></i><b>(4)</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>Provides a mechanism for each object being acted upon to pass data to the next object.</td>
</tr>
<tr>
<td><i class="conum" data-value="2"></i><b>2</b></td>
<td>Obtain user-data, as set by a previous object being acted upon.</td>
</tr>
<tr>
<td><i class="conum" data-value="3"></i><b>3</b></td>
<td>Set user-data, for the use of a subsequent object being acted upon.</td>
</tr>
<tr>
<td><i class="conum" data-value="4"></i><b>4</b></td>
<td>Clear any user data.</td>
</tr>
</tbody>
</table>
</div>
<div class="paragraph">
<p>The vast majority of domain services in Apache Isis tend to be singletons (which requires no special annotation); but as you can see setting up request-scoped services is very straightforward.</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>Behind the covers Apache Isis creates a (singleton) wrapper for the domain service; the individual request-scoped instances are held in a thread-local of this wrapper. One consequence of this implementation is that request-scoped methods should not be marked as <code>final</code>.</p>
</div> </td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
<div class="sect1">
<h2 id="_rgant-Title">33. <code>@Title</code></h2>
<button type="button" class="button secondary" onclick="window.location.href="https://github.com/apache/isis/edit/master/adocs/documentation/src/main/asciidoc/guides/_rgant-Title.adoc"" style="float: right; font-size: small; padding: 6px; margin-top: -55px; "><i class="fa fa-pencil-square-o"></i> Edit</button>
<div class="sectionbody">
<div class="paragraph">
<p>The <code>@Title</code> annotation is used to indicate which property or properties make up the object title. If more than one property is used, the order can be specified (using the same Dewey-decimal notation as used by <code>@MemberOrder</code>) and the string to use between the components can also be specified.</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">void</span> Customer {
<span class="annotation">@Title</span>(sequence=<span class="string"><span class="delimiter">"</span><span class="content">1.0</span><span class="delimiter">"</span></span>)
<span class="directive">public</span> <span class="predefined-type">String</span> getLastName() { ... } <i class="conum" data-value="1"></i><b>(1)</b>
...
<span class="annotation">@Title</span>(sequence=<span class="string"><span class="delimiter">"</span><span class="content">1.5</span><span class="delimiter">"</span></span>, prepend=<span class="string"><span class="delimiter">"</span><span class="content">, </span><span class="delimiter">"</span></span>)
<span class="directive">public</span> <span class="predefined-type">String</span> getFirstName() { ... }
...
<span class="annotation">@Title</span>(sequence=<span class="string"><span class="delimiter">"</span><span class="content">1.7</span><span class="delimiter">"</span></span>, append=<span class="string"><span class="delimiter">"</span><span class="content">.</span><span class="delimiter">"</span></span>)
<span class="directive">public</span> <span class="predefined-type">String</span> getMidInitial() { ... }
...
}</code></pre>
</div>
</div>
<div class="colist arabic">
<table>
<tbody>
<tr>
<td><i class="conum" data-value="1"></i><b>1</b></td>
<td>backing field and setters omitted</td>
</tr>
</tbody>
</table>
</div>
<div class="paragraph">
<p>could be used to create names of the style "Bloggs, Joe K."</p>
</div>
<div class="paragraph">
<p>It is also possible to annotate reference properties; in this case the title will return the title of the referenced object (rather than, say, its string representation).</p>
</div>
<div class="paragraph">
<p>An additional convention for <code>@Title</code> properties is that they are hidden in tables (in other words, it implies <code>@Hidden(where=Where.ALL_TABLES)</code>. For viewers that support this annotation (for example, the Wicket viewer), this convention excludes any properties whose value is already present in the title column. This convention can be overridden using <code>@Hidden(where=Where.NOWHERE)</code>.</p>
</div>
<div class="sect2">
<h3 id="_lombok_support">33.1. Lombok support</h3>
<div class="paragraph">
<p>If <a href="dg.html#_dg_ide_project-lombok">Project Lombok</a> is being used, then <code>@Title</code> can be specified on the backing field.</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">void</span> Customer {
<span class="annotation">@Title</span>(sequence=<span class="string"><span class="delimiter">"</span><span class="content">1.0</span><span class="delimiter">"</span></span>)
<span class="annotation">@Getter</span> <span class="annotation">@Setter</span>
<span class="directive">private</span> <span class="predefined-type">String</span> name;
<span class="annotation">@Title</span>(sequence=<span class="string"><span class="delimiter">"</span><span class="content">1.5</span><span class="delimiter">"</span></span>, prepend=<span class="string"><span class="delimiter">"</span><span class="content">, </span><span class="delimiter">"</span></span>)
<span class="annotation">@Getter</span> <span class="annotation">@Setter</span>
<span class="directive">private</span> <span class="predefined-type">String</span> firstName;
<span class="annotation">@Title</span>(sequence=<span class="string"><span class="delimiter">"</span><span class="content">1.7</span><span class="delimiter">"</span></span>, append=<span class="string"><span class="delimiter">"</span><span class="content">.</span><span class="delimiter">"</span></span>)
<span class="annotation">@Getter</span> <span class="annotation">@Setter</span>
<span class="directive">private</span> <span class="predefined-type">String</span> midInitial;
}</code></pre>
</div>
</div>
</div>
</div>
</div>
<div class="sect1">
<h2 id="_rgant-ViewModel">34. <code>@ViewModel</code></h2>
<button type="button" class="button secondary" onclick="window.location.href="https://github.com/apache/isis/edit/master/adocs/documentation/src/main/asciidoc/guides/_rgant-ViewModel.adoc"" style="float: right; font-size: small; padding: 6px; margin-top: -55px; "><i class="fa fa-pencil-square-o"></i> Edit</button>
<div class="sectionbody">
<div class="paragraph">
<p>The <code>@ViewModel</code> annotation, applied to a class, is the simplest way to indicate that the class is a view model.</p>
</div>
<div class="paragraph">
<p>View models are not persisted to the database, instead their state is encoded within their identity (ultimately represented in the URL). As such, view models are immutable.</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">@ViewModel</span>
<span class="directive">public</span> <span class="type">class</span> <span class="class">MyViewModel</span> {
<span class="directive">public</span> MyViewModel() {} <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>must have a no-arg constructor for subsequent "recreation" by the framework.</td>
</tr>
</tbody>
</table>
</div>
<div class="paragraph">
<p>To instantiate a view model, you can either instantiate directly using its constructor, or indirectly using <code>DomainObjectContainer#newTransientInstance()</code>. If you use the former, also programmatically call <code>DomainObjectContainer#injectServicesInto(…)</code> to ensure that any dependencies are injected into the service.</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>Note that there is a <code>DomainObjectContainer#newViewModelInstance(.)</code>; this is for view models that implement <code>ViewModel</code> interface and can be safely ignored.</p>
</div> </td>
</tr>
</tbody>
</table>
</div>
<div class="paragraph">
<p>The view model’s memento will be derived from the value of the view model object’s properties. Any <a href="#<em>rgant-Property_notPersisted"><code>@Property#notPersisted()</code></a> properties will be excluded from the memento, as will any <a href="#_rgant-Programmatic"><code>@Programmatic</code></a> properties. Properties that are merely <a href="#_rgant-Property_hidden">hidden</a> _are included in the memento.</p>
</div>
<div class="paragraph">
<p>Only properties supported by the configured <a href="rgsvc.html#_rgsvc_api_MementoService"><code>MementoService</code></a> can be used. The default implementation supports all the value types and persisted entities.</p>
</div>
<div class="paragraph">
<p>(As of 1.8.0) there are some limitations: * view models cannot hold collections other view models (simple properties <em>are</em> supported, though) * collections (of either view models or entities) are ignored.</p>
</div>
<div class="admonitionblock warning">
<table>
<tbody>
<tr>
<td class="icon"> <i class="fa icon-warning" title="Warning"></i> </td>
<td class="content">
<div class="paragraph">
<p>The <code>@ViewModel</code> does not allow the objectType to be specified, meaning that it is incompatible with the metamodel validation check ennabled by the <a href="rgcfg.html#__rgcfg_configuring-core_metamodel-validation"><code>explicitObjectType</code></a> configuration property.</p>
</div>
<div class="paragraph">
<p>Instead, use <a href="#_rgant_DomainObject_nature"><code>@DomainObject#nature()</code></a> with <code>Nature.VIEW_MODEL</code>, and specify <a href="#_rgant_DomainObject_objectType"><code>@DomainObject#objectType()</code></a>.</p>
</div> </td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
<div class="sect1">
<h2 id="_rgant-ViewModelLayout">35. <code>@ViewModelLayout</code></h2>
<button type="button" class="button secondary" onclick="window.location.href="https://github.com/apache/isis/edit/master/adocs/documentation/src/main/asciidoc/guides/_rgant-ViewModelLayout.adoc"" style="float: right; font-size: small; padding: 6px; margin-top: -55px; "><i class="fa fa-pencil-square-o"></i> Edit</button>
<div class="sectionbody">
<div class="paragraph">
<p>The <code>@ViewModelLayout</code> annotation is identical to the <a href="#_rgant-DomainObjectLayout"><code>@DomainObjectLayout</code></a>, but is provided for symmetry with domain objects that have been annotated using <a href="#_rgant-ViewModel"><code>@ViewModel</code></a> (rather than <a href="#_rgant-DomainObject_nature"><code>@DomainObject(nature=VIEW_MODEL)</code></a>).</p>
</div>
<div class="paragraph">
<p>The table below summarizes the annotation’s attributes.</p>
</div>
<table class="tableblock frame-all grid-all spread">
<caption class="title">
Table 21.
<code>@ViewModel</code> attributes
</caption>
<colgroup>
<col style="width: 25%;">
<col style="width: 25%;">
<col style="width: 50%;">
</colgroup>
<thead>
<tr>
<th class="tableblock halign-left valign-top">Attribute</th>
<th class="tableblock halign-left valign-top">Values (default)</th>
<th class="tableblock halign-left valign-top">Description</th>
</tr>
</thead>
<tbody>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="#_rgant-ViewModelLayout_cssclass"><code>cssClass()</code></a></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Any string valid as a CSS class</p></td>
<td class="tableblock halign-left valign-top">
<div>
<div class="paragraph">
<p>the css class that a domain class (type) should have, to allow more targetted styling in <a href="rgcfg.html#_rgcfg_application-specific_application-css"><code>application.css</code></a></p>
</div>
</div></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="#_rgant-ViewModelLayout_cssClassFa"><code>cssClassFa()</code></a></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Any valid <a href="http://fortawesome.github.io/Font-Awesome/">Font awesome</a> icon name</p></td>
<td class="tableblock halign-left valign-top">
<div>
<div class="paragraph">
<p>specify a font awesome icon for the action’s menu link or icon.<br></p>
</div>
</div></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>cssClassFaPosition()</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>LEFT</code>, <code>RIGHT</code><br> (<code>LEFT</code>)</p></td>
<td class="tableblock halign-left valign-top">
<div>
<div class="paragraph">
<p>Currently unused.</p>
</div>
</div></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="#_rgant-ViewModelLayout_describedAs"><code>describedAs()</code></a></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">String.</p></td>
<td class="tableblock halign-left valign-top">
<div>
<div class="paragraph">
<p>description of this class, eg to be rendered in a tooltip.</p>
</div>
</div></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="#_rgant-ViewModelLayout_named"><code>named()</code></a></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">String.</p></td>
<td class="tableblock halign-left valign-top">
<div>
<div class="paragraph">
<p>to override the name inferred from the action’s name in code.<br></p>
</div>
<div class="paragraph">
<p>A typical use case is if the desired name is a reserved Java keyword, such as <code>default</code> or <code>package</code>.</p>
</div>
</div></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="#_rgant-ViewModelLayout_paged"><code>paged()</code></a></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Positive integer</p></td>
<td class="tableblock halign-left valign-top">
<div>
<div class="paragraph">
<p>the page size for instances of this class when rendered within a table (as returned from an action invocation)</p>
</div>
</div></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="#_rgant-ViewModelLayout_plural"><code>plural()</code></a></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">String.</p></td>
<td class="tableblock halign-left valign-top">
<div>
<div class="paragraph">
<p>the plural name of the class</p>
</div>
</div></td>
</tr>
</tbody>
</table>
<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">@ViewModel</span> <i class="conum" data-value="1"></i><b>(1)</b>
<span class="annotation">@ViewModelLayout</span>(
cssClass=<span class="string"><span class="delimiter">"</span><span class="content">x-analysis</span><span class="delimiter">"</span></span>,
cssClassFa=<span class="string"><span class="delimiter">"</span><span class="content">fa-piechart</span><span class="delimiter">"</span></span>,
describedAs=<span class="string"><span class="delimiter">"</span><span class="content">Analysis of todo items by category</span><span class="delimiter">"</span></span>
)
<span class="directive">public</span> <span class="type">class</span> <span class="class">CategoryPieChart</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>this annotation is intended for use with <code>@ViewModel</code>. If a view model has been specified using the equivalent <a href="#_rgant-DomainObject_nature"><code>@DomainObject(nature=Nature.VIEW_MODEL)</code></a>, then we recommend you use <a href="#_rgant-DomainObjectLayout"><code>@DomainObjectLayout</code></a> instead.</td>
</tr>
</tbody>
</table>
</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 there is (currently) no support for specifying UI hints for view models through the dynamic <a href="ugfun.html#_ugfun_object-layout_dynamic"><code>.layout.json</code></a> file (only for properties, collections and actions are supported).</p>
</div> </td>
</tr>
</tbody>
</table>
</div>
<div class="sect2">
<h3 id="_rgant-ViewModelLayout_cssClass">35.1. <code>cssClass()</code></h3>
<button type="button" class="button secondary" onclick="window.location.href="https://github.com/apache/isis/edit/master/adocs/documentation/src/main/asciidoc/guides/_rgant-ViewModelLayout_cssClass.adoc"" style="float: right; font-size: small; padding: 6px; margin-top: -55px; "><i class="fa fa-pencil-square-o"></i> Edit</button>
<div class="paragraph">
<p>The <code>cssClass()</code> attribute can be used to render additional CSS classes in the HTML (a wrapping <code><div></code>) that represents the view model. <a href="rgcfg.html#_rgcfg_application-specific_application-css">Application-specific CSS</a> can then be used to target and adjust the UI representation of that particular element.</p>
</div>
<div class="paragraph">
<p>This attribute can also be applied to <a href="#_rgant-DomainObjectLayout_cssClass">domain objects</a>, <a href="#_rgant-ActionLayout_cssClass">actions</a> <a href="#_rgant-PropertyLayout_cssClass">properties</a>, <a href="#_rgant-CollectionLayout_cssClass">collections</a> and <a href="#_rgant-ParameterLayout_cssClass">parameters</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">@ViewModel</span>
<span class="annotation">@ViewModelLayout</span>(cssClass=<span class="string"><span class="delimiter">"</span><span class="content">x-analysis</span><span class="delimiter">"</span></span>)
<span class="directive">public</span> <span class="type">class</span> <span class="class">CategoryPieChart</span> { ... }</code></pre>
</div>
</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>The similar <a href="#_rgant-ViewModelLayout_cssClassFa"><code>@ViewModelLayout#cssClassFa()</code></a> annotation attribute is also used as a hint to apply CSS, but in particular to allow <a href="http://fortawesome.github.io/Font-Awesome/icons/">Font Awesome icons</a> to be rendered as the icon for classes.</p>
</div> </td>
</tr>
</tbody>
</table>
</div>
</div>
<div class="sect2">
<h3 id="_rgant-ViewModelLayout_cssClassFa">35.2. <code>cssClassFa()</code></h3>
<button type="button" class="button secondary" onclick="window.location.href="https://github.com/apache/isis/edit/master/adocs/documentation/src/main/asciidoc/guides/_rgant-ViewModelLayout_cssClassFa.adoc"" style="float: right; font-size: small; padding: 6px; margin-top: -55px; "><i class="fa fa-pencil-square-o"></i> Edit</button>
<div class="paragraph">
<p>The <code>cssClassFa()</code> attribute is used to specify the name of a <a href="http://fortawesome.github.io/Font-Awesome/icons/">Font Awesome icon</a> name, to be rendered as the domain object’s icon.</p>
</div>
<div class="paragraph">
<p>These attribute can also be applied to <a href="#_rgant-DomainObjectLayout_cssClassFa">domain objects</a> to specify the object’s icon, and to <a href="#_rgant-ActionLayout_cssClassFa">actions</a> to specify an icon for the action’s representation as a button or menu item.</p>
</div>
<div class="paragraph">
<p>If necessary the icon specified can be overridden by a particular object instance using the <a href="rgcms.html#_rgcms_methods_reserved_iconName"><code>iconName()</code></a> method.</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">@ViewModel</span>
<span class="annotation">@ViewModelLayout</span>(
cssClassFa=<span class="string"><span class="delimiter">"</span><span class="content">fa-piechart</span><span class="delimiter">"</span></span>
)
<span class="directive">public</span> <span class="type">class</span> <span class="class">CategoryPieChart</span> { ... }</code></pre>
</div>
</div>
<div class="paragraph">
<p>There can be multiple "fa-" classes, eg to mirror or rotate the icon. There is no need to include the mandatory <code>fa</code> "marker" CSS class; it will be automatically added to the list. The <code>fa-</code> prefix can also be omitted from the class names; it will be prepended to each if required.</p>
</div>
<div class="paragraph">
<p>The related <code>cssClassFaPosition()</code> attribute is currently unused for domain objects; the icon is always rendered to the left.</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>The similar <a href="#_rgant-ViewModelLayout_cssClass"><code>@ViewModelLayout#cssClass()</code></a> annotation attribute is also used as a hint to apply CSS, but for wrapping the representation of an object or object member so that it can be styled in an application-specific way.</p>
</div> </td>
</tr>
</tbody>
</table>
</div>
</div>
<div class="sect2">
<h3 id="_rgant-ViewModelLayout_describedAs">35.3. <code>describedAs()</code></h3>
<button type="button" class="button secondary" onclick="window.location.href="https://github.com/apache/isis/edit/master/adocs/documentation/src/main/asciidoc/guides/_rgant-ViewModelLayout_describedAs.adoc"" style="float: right; font-size: small; padding: 6px; margin-top: -55px; "><i class="fa fa-pencil-square-o"></i> Edit</button>
<div class="paragraph">
<p>The <code>describedAs()</code> attribute is used to provide a short description of the view model to the user. In the <a href="ugvw.html">Wicket viewer</a> it is displayed as a 'tool tip'. The <code>describedAs()</code> attribute can also be specified for <a href="#_rgant-CollectionLayout_describedAs">collections</a>, <a href="#_rgant-PropertyLayout_describedAs">properties</a>, <a href="#_rgant-ActionLayout_describedAs">actions</a>, <a href="#_rgant-ParameterLayout_describedAs">parameters</a> and <a href="#_rgant-DomainObjectLayout_describedAs">domain objects</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">@ViewModel</span>
<span class="annotation">@ViewModelLayout</span>(
cssClass=<span class="string"><span class="delimiter">"</span><span class="content">x-analysis</span><span class="delimiter">"</span></span>,
cssClassFa=<span class="string"><span class="delimiter">"</span><span class="content">fa-piechart</span><span class="delimiter">"</span></span>,
describedAs=<span class="string"><span class="delimiter">"</span><span class="content">Analysis of todo items by category</span><span class="delimiter">"</span></span>
)
<span class="directive">public</span> <span class="type">class</span> <span class="class">CategoryPieChart</span> { ... }</code></pre>
</div>
</div>
</div>
<div class="sect2">
<h3 id="_rgant-ViewModelLayout_named">35.4. <code>named()</code></h3>
<button type="button" class="button secondary" onclick="window.location.href="https://github.com/apache/isis/edit/master/adocs/documentation/src/main/asciidoc/guides/_rgant-ViewModelLayout_named.adoc"" style="float: right; font-size: small; padding: 6px; margin-top: -55px; "><i class="fa fa-pencil-square-o"></i> Edit</button>
<div class="paragraph">
<p>The <code>named()</code> attribute explicitly specifies the view model’s name, overriding the name that would normally be inferred from the Java source code. This attribute can also be specified for <a href="#_rgant-ActionLayout_named">actions</a>, <a href="#_rgant-CollectionLayout_named">collections</a>, <a href="#_rgant-PropertyLayout_named">properties</a>, <a href="#_rgant-ParameterLayout_named">parameters</a>, <a href="#_rgant-DomainObjectLayout_named">domain objects</a> and <a href="#_rgant-DomainServiceLayout_named">domain services</a>.</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>Following the <a href="http://en.wikipedia.org/wiki/Don%27t_repeat_yourself">don’t repeat yourself</a> principle, we recommend that you only use this attribute when the desired name cannot be used in Java source code. Examples of that include a name that would be a reserved Java keyword (eg "package"), or a name that has punctuation, eg apostrophes.</p>
</div> </td>
</tr>
</tbody>
</table>
</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">@ViewModel</span>
<span class="annotation">@ViewModelLayout</span>(
named=<span class="string"><span class="delimiter">"</span><span class="content">PieChartAnalysis</span><span class="delimiter">"</span></span>
)
<span class="directive">public</span> <span class="type">class</span> <span class="class">PieChartAnalysisViewModel</span> {
...
}</code></pre>
</div>
</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>The framework also provides a separate, powerful mechanism for <a href="ugbtb.html#_ugbtb_i18n">internationalization</a>.</p>
</div> </td>
</tr>
</tbody>
</table>
</div>
</div>
<div class="sect2">
<h3 id="_rgant-ViewModelLayout_paged">35.5. <code>paged()</code></h3>
<button type="button" class="button secondary" onclick="window.location.href="https://github.com/apache/isis/edit/master/adocs/documentation/src/main/asciidoc/guides/_rgant-ViewModelLayout_paged.adoc"" style="float: right; font-size: small; padding: 6px; margin-top: -55px; "><i class="fa fa-pencil-square-o"></i> Edit</button>
<div class="paragraph">
<p>The <code>paged()</code> attribute specifies the number of rows to display in a standalone collection, as returned from an action invocation. This attribute can also be applied to <a href="#_rgant-CollectionLayout_paged">collections</a> and <a href="#_rgant-DomainObjectLayout_paged">domain objects</a>.</p>
</div>
<div class="admonitionblock warning">
<table>
<tbody>
<tr>
<td class="icon"> <i class="fa icon-warning" title="Warning"></i> </td>
<td class="content">
<div class="paragraph">
<p>The <a href="ugvro.html">RestfulObjects viewer</a> currently does not support paging. The <a href="ugvw.html">Wicket viewer</a> <em>does</em> support paging, but note that the paging is performed client-side rather than server-side.</p>
</div>
<div class="paragraph">
<p>We therefore recommend that large collections should instead be modelled as actions (to allow filtering to be applied to limit the number of rows).</p>
</div> </td>
</tr>
</tbody>
</table>
</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">@ViewModel</span>
<span class="annotation">@ViewModelLayout</span>(paged=<span class="integer">15</span>)
<span class="directive">public</span> <span class="type">class</span> <span class="class">OrderAnalysis</span> {
...
}</code></pre>
</div>
</div>
<div class="paragraph">
<p>It is also possible to specify a global default for the page size of standalone collections, using the <a href="rgcfg.html#_rgcfg_configuring-core">configuration property</a> <code>isis.viewer.paged.standalone</code>.</p>
</div>
</div>
<div class="sect2">
<h3 id="_rgant-ViewModelLayout_plural">35.6. <code>plural()</code></h3>
<button type="button" class="button secondary" onclick="window.location.href="https://github.com/apache/isis/edit/master/adocs/documentation/src/main/asciidoc/guides/_rgant-ViewModelLayout_plural.adoc"" style="float: right; font-size: small; padding: 6px; margin-top: -55px; "><i class="fa fa-pencil-square-o"></i> Edit</button>
<div class="paragraph">
<p>When Apache Isis displays a standalone collection of several objects, it will label the collection using the plural form of the object type.</p>
</div>
<div class="paragraph">
<p>By default the plural name will be derived from the end of the singular name, with support for some basic English language defaults (eg using "ies" for names ending with a "y").</p>
</div>
<div class="paragraph">
<p>The <code>plural()</code> attribute allows the plural form of the class name to be specified explicitly. This attribute is also supported for <a href="#_rgant-DomainObjectLayout_plural">domain objects</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">@ViewModel</span>
<span class="annotation">@ViewModelLayout</span>(plural=<span class="string"><span class="delimiter">"</span><span class="content">Children</span><span class="delimiter">"</span></span>)
<span class="directive">public</span> <span class="type">class</span> <span class="class">Child</span> {
...
}</code></pre>
</div>
</div>
</div>
</div>
</div>
<div class="sect1">
<h2 id="_rgant-XmlJavaTypeAdapter">36. <code>@XmlJavaTypeAdapter</code> (<code>jaxb</code>)</h2>
<button type="button" class="button secondary" onclick="window.location.href="https://github.com/apache/isis/edit/master/adocs/documentation/src/main/asciidoc/guides/_rgant-XmlJavaTypeAdapter.adoc"" style="float: right; font-size: small; padding: 6px; margin-top: -55px; "><i class="fa fa-pencil-square-o"></i> Edit</button>
<div class="sectionbody">
<div class="paragraph">
<p>The JAXB <code>@XmlJavaTypeAdapter</code> annotation is used with the framework-provided <code>PersistentEntityAdapter</code> to instruct JAXB to serialize references to persistent entities using the canonical <code>OidDto</code> complex type: the object’s type and its identifier. This is the formal XML equivalent to the <code>Bookmark</code> provided by the <a href="rgsvc.html#_rgsvc_api_BookmarkService"><code>BookmarkService</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">@XmlJavaTypeAdapter</span>(PersistentEntityAdapter.class)
<span class="directive">public</span> <span class="type">class</span> <span class="class">ToDoItem</span> ... {
...
}</code></pre>
</div>
</div>
<div class="paragraph">
<p>This annotation therefore allows view models/DTOs to have references to persistent entities; a common idiom.</p>
</div>
<div class="paragraph">
<p>For a more complete discussion of writing JAXB view models/DTOs, see <a href="ugbtb.html#_ugbtb_view-models">this topic</a> in the user guide.</p>
</div>
</div>
</div>
<div class="sect1">
<h2 id="_rgant-XmlRootElement">37. <code>@XmlRootElement</code> (<code>jaxb</code>)</h2>
<button type="button" class="button secondary" onclick="window.location.href="https://github.com/apache/isis/edit/master/adocs/documentation/src/main/asciidoc/guides/_rgant-XmlRootElement.adoc"" style="float: right; font-size: small; padding: 6px; margin-top: -55px; "><i class="fa fa-pencil-square-o"></i> Edit</button>
<div class="sectionbody">
<div class="paragraph">
<p>The <code>@XmlRootElement</code> annotation provides an alternative way to define a <a href="rg.html#_ugbtb_view-models">view model</a>, in particular one intended to act as a DTO for use within <a href="ugvro.html">RestfulObjects viewer</a>, or which contains arbitrarily complex state.</p>
</div>
<div class="paragraph">
<p>A view model is a non-persisted domain object whose state is converted to/from a string memento. In the case of a JAXB-annotated object this memento is its XML representation. JAXB generally requires that the root element of the XML representation is annotated with <code>@XmlRootElement</code>. Apache Isis makes this a mandatory requirement.</p>
</div>
<div class="paragraph">
<p>In comparison to using either the <a href="rgcms.html#_rgcms_classes_super_ViewModel"><code>ViewModel</code></a> interface or the <a href="#_rgant-ViewModel"><code>@ViewModel</code></a> annotation, using <code>@XmlRootElement</code> has a couple of significant advantages:</p>
</div>
<div class="ulist">
<ul>
<li> <p>the view model can be used as a "canonical" DTO, for example when accessing data using the <a href="ugvro.html">RestfulObjects viewer</a> in combination with the <a href="rgsvc.html#_rgsvc_spi_ContentMappingService"><code>ContentMappingService</code></a>.<br></p>
<div class="paragraph">
<p>This provides a stable and versioned API to access data in XML format using whatever client-side technology may be appropriate.</p>
</div> </li>
<li> <p>the XML graph can be as deep as required; in particular it can contain collections of other objects.<br></p>
<div class="paragraph">
<p>In contrast, if the <code>@ViewModel</code> annotation is used then only the state of the properties (not collections) is captured. If using <code>ViewModel</code> interface then arbitrary state (including that of collections), however the programmer must write all the code by hand</p>
</div> </li>
</ul>
</div>
<div class="paragraph">
<p>The main disadvantages of using JAXB-annotated view models is that any referenced persistent entity must be annotated with the <a href="#_rgant-XmlJavaTypeAdapter"><code>@XmlJavaTypeAdapter</code></a>, using the framework-provided <code>PersistentEntityAdapter</code>. This adapter converts any references to such domain entities using the <code>oidDto</code> complex type (as defined by the Apache Isis <a href="rgcms.html#_rgcms_schema-common">common schema</a>): the object’s type and its identifier.</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>The memento string for view models is converted into a form compatible with use within a URL. This is performed by the <a href="rgsvc.html#_rgsvc_spi_UrlEncodingService"><code>UrlEncodingService</code></a>, the default implementation of which simply encodes to base 64. If the view model XML graph is too large to be serialized to a string, then an alternative implementation (eg which maps XML strings to a GUID, say) can be configured using the technique described in <a href="rg.html#_ugfun_how-tos_replacing-default-service-implementations">here</a> in the user guide.</p>
</div> </td>
</tr>
</tbody>
</table>
</div>
<div class="sect2">
<h3 id="_example_2">37.1. Example</h3>
<div class="paragraph">
<p>This example is taken from the (non-ASF) <a href="http://github.com/isisaddons/isis-app-todoapp">Isis addons' todoapp</a>:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code data-lang="java"><span class="annotation">@XmlRootElement</span>(name = <span class="string"><span class="delimiter">"</span><span class="content">toDoItemDto</span><span class="delimiter">"</span></span>) <i class="conum" data-value="1"></i><b>(1)</b>
<span class="directive">public</span> <span class="type">class</span> <span class="class">ToDoItemDto</span> <span class="directive">implements</span> Dto {
<span class="annotation">@Getter</span> <span class="annotation">@Setter</span> <i class="conum" data-value="2"></i><b>(2)</b>
<span class="directive">protected</span> <span class="predefined-type">String</span> description;
<span class="annotation">@Getter</span> <span class="annotation">@Setter</span>
<span class="directive">protected</span> <span class="predefined-type">String</span> category;
<span class="annotation">@Getter</span> <span class="annotation">@Setter</span>
<span class="directive">protected</span> <span class="predefined-type">String</span> subcategory;
<span class="annotation">@Getter</span> <span class="annotation">@Setter</span>
<span class="directive">protected</span> <span class="predefined-type">BigDecimal</span> cost;
}</code></pre>
</div>
</div>
<div class="colist arabic">
<table>
<tbody>
<tr>
<td><i class="conum" data-value="1"></i><b>1</b></td>
<td>identifies this class as a view model and defines the root element for JAXB serialization</td>
</tr>
<tr>
<td><i class="conum" data-value="2"></i><b>2</b></td>
<td>using Project Lombok for getters and setters</td>
</tr>
</tbody>
</table>
</div>
</div>
<div class="sect2">
<h3 id="_see_also">37.2. See also</h3>
<div class="paragraph">
<p>Although (like any other viewmodel) a JAXB-annotated can have behaviour (actions) and UI hints, you may wish to keep the DTO "clean", just focused on specifying the data contract.</p>
</div>
<div class="paragraph">
<p>Behaviour can therefore be provided using <a href="ugbtb.html#_ugbtb_decoupling_mixins">mixins</a> (annotated with <a href="#_rgant-Mixin"><code>@Mixin</code></a>), while <a href="rgcms.html#_rgcms_classes_uievent">UI events</a> can be used to obtain title, icons and so on.</p>
</div>
<div class="paragraph">
<p>For a more complete discussion of writing JAXB view models/DTOs, see <a href="ugbtb.html#_ugbtb_view-models">this topic</a> in the user guide.</p>
</div>
</div>
</div>
</div>
</div>
<footer>
<hr>
<p class="small"> Copyright © 2010~2016 The Apache Software Foundation, licensed under the Apache License, v2.0. <br> Apache, the Apache feather logo, Apache Isis, and the Apache Isis project logo are all trademarks of The Apache Software Foundation. </p>
</footer>
</div>
<div id="doc-content-right" class="large-3 medium-3 xcolumns">
<div id="toc" class="toc2">
<div class="fallback-toc">
<ul class="sectlevel1">
<li><a href="#_rgant">1. Annotations</a>
<ul class="sectlevel2">
<li><a href="#_other_guides">1.1. Other Guides</a></li>
<li><a href="#_examples">1.2. Examples</a></li>
</ul> </li>
<li><a href="#_rgant_aaa">2. Summary</a>
<ul class="sectlevel2">
<li><a href="#_rgant_aaa_main">2.1. Core annotations</a></li>
<li><a href="#_rgant_aaa_other">2.2. Other Isis Annotations</a></li>
<li><a href="#_rgant_aaa_jee">2.3. JDO Annotations</a></li>
<li><a href="#_rgant_aaa_jee">2.4. Java EE Annotations</a></li>
<li><a href="#_rgant_aaa_deprecated">2.5. Deprecated Annotations</a></li>
<li><a href="#_rgant_aaa_partial">2.6. Incomplete/partial support</a></li>
</ul> </li>
<li><a href="#_rgant-Action">3. <code>@Action</code></a>
<ul class="sectlevel2">
<li><a href="#_rgant-Action_command">3.1. <code>command()</code></a>
<ul class="sectlevel3">
<li><a href="#__code_commandpersistence_code">3.1.1. <code>commandPersistence()</code></a></li>
<li><a href="#__code_commandexecutein_code">3.1.2. <code>commandExecuteIn()</code></a></li>
</ul> </li>
<li><a href="#_rgant-Action_domainEvent">3.2. domainEvent()</a>
<ul class="sectlevel3">
<li><a href="#_subscribers">3.2.1. Subscribers</a></li>
<li><a href="#_default_doop_and_noop_events">3.2.2. Default, Doop and Noop events</a></li>
<li><a href="#_raising_events_programmatically">3.2.3. Raising events programmatically</a></li>
</ul> </li>
<li><a href="#_rgant-Action_hidden">3.3. <code>hidden()</code></a></li>
<li><a href="#_rgant-Action_invokeOn">3.4. <code>invokeOn()</code></a></li>
<li><a href="#_rgant-Action_publishing">3.5. <code>publishing()</code></a>
<ul class="sectlevel3">
<li><a href="#__code_publishingpayloadfactory_code">3.5.1. <code>publishingPayloadFactory()</code></a></li>
</ul> </li>
<li><a href="#_rgant-Action_restrictTo">3.6. <code>restrictTo()</code></a></li>
<li><a href="#_rgant-Action_semantics">3.7. <code>semantics()</code></a></li>
<li><a href="#_rgant-Action_typeOf">3.8. <code>typeOf()</code></a></li>
</ul> </li>
<li><a href="#_rgant-ActionLayout">4. <code>@ActionLayout</code></a>
<ul class="sectlevel2">
<li><a href="#_rgant-ActionLayout_bookmarking">4.1. <code>bookmarking()</code></a></li>
<li><a href="#_rgant-ActionLayout_contributedAs">4.2. <code>contributedAs()</code></a></li>
<li><a href="#_rgant-ActionLayout_cssClass">4.3. <code>cssClass()</code></a></li>
<li><a href="#_rgant-ActionLayout_cssClassFa">4.4. <code>cssClassFa()</code></a></li>
<li><a href="#_rgant-ActionLayout_describedAs">4.5. <code>describedAs()</code></a></li>
<li><a href="#_rgant-ActionLayout_hidden">4.6. <code>hidden()</code></a></li>
<li><a href="#_rgant-ActionLayout_named">4.7. <code>named()</code></a></li>
<li><a href="#_rgant-ActionLayout_position">4.8. <code>position()</code></a></li>
</ul> </li>
<li><a href="#_rgant-Collection">5. <code>@Collection</code></a>
<ul class="sectlevel2">
<li><a href="#_rgant-Collection_domainEvent">5.1. <code>domainEvent()</code></a>
<ul class="sectlevel3">
<li><a href="#_subscribers_2">5.1.1. Subscribers</a></li>
<li><a href="#_default_doop_and_noop_events_2">5.1.2. Default, Doop and Noop events</a></li>
<li><a href="#_raising_events_programmatically_2">5.1.3. Raising events programmatically</a></li>
</ul> </li>
<li><a href="#_rgant-Collection_editing">5.2. <code>editing()</code></a></li>
<li><a href="#_rgant-Collection_hidden">5.3. <code>hidden()</code></a></li>
<li><a href="#_rgant-Collection_notPersisted">5.4. <code>notPersisted()</code></a></li>
<li><a href="#_rgant-Collection_typeOf">5.5. <code>typeOf()</code></a></li>
</ul> </li>
<li><a href="#_rgant-CollectionLayout">6. <code>@CollectionLayout</code></a>
<ul class="sectlevel2">
<li><a href="#_rgant-CollectionLayout_cssClass">6.1. <code>cssClass()</code></a></li>
<li><a href="#_rgant-CollectionLayout_defaultView">6.2. <code>defaultView()</code></a></li>
<li><a href="#_rgant-CollectionLayout_describedAs">6.3. <code>describedAs()</code></a></li>
<li><a href="#_rgant-CollectionLayout_hidden">6.4. <code>hidden()</code></a></li>
<li><a href="#_rgant-CollectionLayout_named">6.5. <code>named()</code></a></li>
<li><a href="#_rgant-CollectionLayout_paged">6.6. <code>paged()</code></a></li>
<li><a href="#_rgant-CollectionLayout_render">6.7. <code>render()</code></a></li>
<li><a href="#_rgant-CollectionLayout_sortedBy">6.8. <code>sortedBy()</code></a></li>
</ul> </li>
<li><a href="#_rgant-Column">7. <code>@Column</code> (<code>javax.jdo</code>)</a>
<ul class="sectlevel2">
<li><a href="#_nullability">7.1. Nullability</a></li>
<li><a href="#_length_for_code_string_code_s">7.2. Length for <code>String</code>s</a></li>
<li><a href="#_length_scale_for_code_bigdecimal_code_s">7.3. Length/scale for <code>BigDecimal</code>s</a></li>
<li><a href="#_hints_and_tips">7.4. Hints and Tips</a>
<ul class="sectlevel3">
<li><a href="#_mapping_foreign_keys">7.4.1. Mapping foreign keys</a></li>
</ul> </li>
<li><a href="#_mapping_code_blob_code_s_and_code_clob_code_s">7.5. Mapping <code>Blob</code>s and <code>Clob</code>s</a></li>
</ul> </li>
<li><a href="#_rgant-Digits">8. <code>@Digits</code> (<code>javax</code>)</a></li>
<li><a href="#_rgant-Discriminator">9. <code>@Discriminator</code> (<code>javax.jdo</code>)</a>
<ul class="sectlevel2">
<li><a href="#_examples_2">9.1. Examples</a></li>
<li><a href="#_precedence">9.2. Precedence</a></li>
</ul> </li>
<li><a href="#_rgant-DomainObject">10. <code>@DomainObject</code></a>
<ul class="sectlevel2">
<li><a href="#_rgant-DomainObject_auditing">10.1. <code>auditing()</code></a></li>
<li><a href="#_rgant-DomainObject_autoCompleteRepository">10.2. <code>autoCompleteRepository()</code></a>
<ul class="sectlevel3">
<li><a href="#__code_autocompleteaction_code">10.2.1. <code>autoCompleteAction()</code></a></li>
</ul> </li>
<li><a href="#_rgant-DomainObject_bounded">10.3. <code>bounded()</code></a></li>
<li><a href="#_rgant-DomainObject_createdLifecycleEvent">10.4. createdLifecycleEvent()</a>
<ul class="sectlevel3">
<li><a href="#_subscribers_3">10.4.1. Subscribers</a></li>
<li><a href="#_default_doop_and_noop_events_3">10.4.2. Default, Doop and Noop events</a></li>
</ul> </li>
<li><a href="#_rgant-DomainObject_editing">10.5. <code>editing()</code></a></li>
<li><a href="#_rgant-DomainObject_loadedLifecycleEvent">10.6. loadedLifecycleEvent()</a>
<ul class="sectlevel3">
<li><a href="#_subscribers_4">10.6.1. Subscribers</a></li>
<li><a href="#_default_doop_and_noop_events_4">10.6.2. Default, Doop and Noop events</a></li>
</ul> </li>
<li><a href="#_rgant-DomainObject_mixinMethod">10.7. <code>mixinMethod()</code></a></li>
<li><a href="#_rgant-DomainObject_nature">10.8. <code>nature()</code></a></li>
<li><a href="#_rgant-DomainObject_persistedLifecycleEvent">10.9. persistedLifecycleEvent()</a>
<ul class="sectlevel3">
<li><a href="#_subscribers_5">10.9.1. Subscribers</a></li>
<li><a href="#_default_doop_and_noop_events_5">10.9.2. Default, Doop and Noop events</a></li>
</ul> </li>
<li><a href="#_rgant-DomainObject_persistingLifecycleEvent">10.10. persistingLifecycleEvent()</a>
<ul class="sectlevel3">
<li><a href="#_subscribers_6">10.10.1. Subscribers</a></li>
<li><a href="#_default_doop_and_noop_events_6">10.10.2. Default, Doop and Noop events</a></li>
</ul> </li>
<li><a href="#_rgant-DomainObject_objectType">10.11. <code>objectType()</code></a>
<ul class="sectlevel3">
<li><a href="#_examples_3">10.11.1. Examples</a></li>
<li><a href="#_precedence_2">10.11.2. Precedence</a></li>
</ul> </li>
<li><a href="#_rgant-DomainObject_publishing">10.12. <code>publishing()</code></a>
<ul class="sectlevel3">
<li><a href="#__code_publishingpayloadfactory_code_2">10.12.1. <code>publishingPayloadFactory()</code></a></li>
</ul> </li>
<li><a href="#_rgant-DomainObject_removingLifecycleEvent">10.13. removingLifecycleEvent()</a>
<ul class="sectlevel3">
<li><a href="#_subscribers_7">10.13.1. Subscribers</a></li>
<li><a href="#_default_doop_and_noop_events_7">10.13.2. Default, Doop and Noop events</a></li>
</ul> </li>
<li><a href="#_rgant-DomainObject_updatingLifecycleEvent">10.14. updatingLifecycleEvent()</a>
<ul class="sectlevel3">
<li><a href="#_subscribers_8">10.14.1. Subscribers</a></li>
<li><a href="#_default_doop_and_noop_events_8">10.14.2. Default, Doop and Noop events</a></li>
</ul> </li>
<li><a href="#_rgant-DomainObject_updatedLifecycleEvent">10.15. updatedLifecycleEvent()</a>
<ul class="sectlevel3">
<li><a href="#_subscribers_9">10.15.1. Subscribers</a></li>
<li><a href="#_default_doop_and_noop_events_9">10.15.2. Default, Doop and Noop events</a></li>
</ul> </li>
</ul> </li>
<li><a href="#_rgant-DomainObjectLayout">11. <code>@DomainObjectLayout</code></a>
<ul class="sectlevel2">
<li><a href="#_rgant-DomainObjectLayout_bookmarking">11.1. <code>bookmarking()</code></a></li>
<li><a href="#_rgant-DomainObjectLayout_cssClass">11.2. <code>cssClass()</code></a></li>
<li><a href="#_rgant-DomainObjectLayout_cssClassFa">11.3. <code>cssClassFa()</code></a></li>
<li><a href="#_rgant-DomainObjectLayout_cssClassUiEvent">11.4. cssClassUiEvent()</a>
<ul class="sectlevel3">
<li><a href="#_subscribers_10">11.4.1. Subscribers</a></li>
<li><a href="#_default_doop_and_noop_events_10">11.4.2. Default, Doop and Noop events</a></li>
<li><a href="#_raising_events_programmatically_3">11.4.3. Raising events programmatically</a></li>
</ul> </li>
<li><a href="#_rgant-DomainObjectLayout_describedAs">11.5. <code>describedAs()</code></a></li>
<li><a href="#_rgant-DomainObjectLayout_iconUiEvent">11.6. iconUiEvent()</a>
<ul class="sectlevel3">
<li><a href="#_subscribers_11">11.6.1. Subscribers</a></li>
<li><a href="#_default_doop_and_noop_events_11">11.6.2. Default, Doop and Noop events</a></li>
<li><a href="#_raising_events_programmatically_4">11.6.3. Raising events programmatically</a></li>
</ul> </li>
<li><a href="#_rgant-DomainObjectLayout_named">11.7. <code>named()</code></a></li>
<li><a href="#_rgant-DomainObjectLayout_paged">11.8. <code>paged()</code></a></li>
<li><a href="#_rgant-DomainObjectLayout_plural">11.9. <code>plural()</code></a></li>
<li><a href="#_rgant-DomainObjectLayout_titleUiEvent">11.10. titleUiEvent()</a>
<ul class="sectlevel3">
<li><a href="#_subscribers_12">11.10.1. Subscribers</a></li>
<li><a href="#_default_doop_and_noop_events_12">11.10.2. Default, Doop and Noop events</a></li>
<li><a href="#_raising_events_programmatically_5">11.10.3. Raising events programmatically</a></li>
</ul> </li>
</ul> </li>
<li><a href="#_rgant-DomainService">12. <code>@DomainService</code></a>
<ul class="sectlevel2">
<li><a href="#_rgant-DomainService_nature">12.1. <code>nature()</code></a></li>
<li><a href="#_rgant-DomainService_objectType">12.2. <code>objectType()</code></a>
<ul class="sectlevel3">
<li><a href="#_example">12.2.1. Example</a></li>
<li><a href="#_precedence_3">12.2.2. Precedence</a></li>
</ul> </li>
<li><a href="#_rgant-DomainService_repositoryFor">12.3. <code>repositoryFor()</code></a></li>
</ul> </li>
<li><a href="#_rgant-DomainServiceLayout">13. <code>@DomainServiceLayout</code></a>
<ul class="sectlevel2">
<li><a href="#_rgant-DomainServiceLayout_menuBar">13.1. <code>menuBar()</code></a></li>
<li><a href="#_rgant-DomainServiceLayout_menuOrder">13.2. <code>menuOrder()</code></a></li>
<li><a href="#_rgant-DomainServiceLayout_named">13.3. <code>named()</code></a></li>
</ul> </li>
<li><a href="#_rgant-Facets">14. <code>@Facets</code></a></li>
<li><a href="#_rgant-HomePage">15. <code>@HomePage</code></a></li>
<li><a href="#_rgant-Inject">16. <code>@Inject</code> (<code>javax</code>)</a>
<ul class="sectlevel2">
<li><a href="#_alternative_syntaxes">16.1. Alternative syntaxes</a></li>
<li><a href="#_injecting_collection_of_services">16.2. Injecting collection of services</a></li>
<li><a href="#_manually_injecting_services">16.3. Manually injecting services</a></li>
</ul> </li>
<li><a href="#_rgant-MemberGroupLayout">17. <code>@MemberGroupLayout</code></a></li>
<li><a href="#_rgant-MemberOrder">18. <code>@MemberOrder</code></a></li>
<li><a href="#_rgant-Mixin">19. <code>@Mixin</code></a>
<ul class="sectlevel2">
<li><a href="#_rgant-Mixin_method">19.1. <code>method()</code></a></li>
</ul> </li>
<li><a href="#_rgant-Nullable">20. <code>@Nullable</code> (<code>javax</code>)</a></li>
<li><a href="#_rgant-NotPersistent">21. <code>@NotPersistent</code> (<code>javax.jdo</code>)</a></li>
<li><a href="#_rgant-MinLength">22. <code>@MinLength</code></a></li>
<li><a href="#_rgant-Parameter">23. <code>@Parameter</code></a>
<ul class="sectlevel2">
<li><a href="#_rgant-Parameter_fileAccept">23.1. <code>fileAccept()</code></a></li>
<li><a href="#_rgant-Parameter_maxLength">23.2. <code>maxLength()</code></a></li>
<li><a href="#_rgant-Parameter_mustSatisfy">23.3. <code>mustSatisfy()</code></a></li>
<li><a href="#_rgant-Parameter_optionality">23.4. <code>optionality()</code></a></li>
<li><a href="#_rgant-Parameter_regexPattern">23.5. <code>regexPattern()</code></a></li>
</ul> </li>
<li><a href="#_rgant-ParameterLayout">24. <code>@ParameterLayout</code></a>
<ul class="sectlevel2">
<li><a href="#_rgant-ParameterLayout_cssClass">24.1. <code>cssClass()</code></a></li>
<li><a href="#_rgant-ParameterLayout_describedAs">24.2. <code>describedAs()</code></a></li>
<li><a href="#_rgant-ParameterLayout_labelPosition">24.3. <code>labelPosition()</code></a></li>
<li><a href="#_rgant-ParameterLayout_multiLine">24.4. <code>multiLine()</code></a></li>
<li><a href="#_rgant-ParameterLayout_named">24.5. <code>named()</code></a></li>
<li><a href="#_rgant-ParameterLayout_renderedAsDayBefore">24.6. <code>renderedAsDayBefore()</code></a></li>
<li><a href="#_rgant-ParameterLayout_typicalLength">24.7. <code>typicalLength()</code></a></li>
</ul> </li>
<li><a href="#_rgant-PersistenceCapable">25. <code>@PersistenceCapable</code> (<code>javax.jdo</code>)</a>
<ul class="sectlevel2">
<li><a href="#_examples_4">25.1. Examples</a></li>
<li><a href="#_precedence_4">25.2. Precedence</a></li>
</ul> </li>
<li><a href="#_rgant-PostConstruct">26. <code>@PostConstruct</code> (<code>javax</code>)</a></li>
<li><a href="#_rgant-PreDestroy">27. <code>@PreDestroy</code> (<code>javax</code>)</a></li>
<li><a href="#_rgant-PrimaryKey">28. <code>@PrimaryKey</code> (<code>javax.jdo</code>)</a></li>
<li><a href="#_rgant-Programmatic">29. <code>@Programmatic</code></a></li>
<li><a href="#_rgant-Property">30. <code>@Property</code></a>
<ul class="sectlevel2">
<li><a href="#_rgant-Property_domainEvent">30.1. <code>domainEvent()</code></a>
<ul class="sectlevel3">
<li><a href="#_subscribers_13">30.1.1. Subscribers</a></li>
<li><a href="#_default_doop_and_noop_events_13">30.1.2. Default, Doop and Noop events</a></li>
<li><a href="#_raising_events_programmatically_6">30.1.3. Raising events programmatically</a></li>
</ul> </li>
<li><a href="#_rgant-Property_editing">30.2. <code>editing()</code></a></li>
<li><a href="#_rgant-Property_fileAccept">30.3. <code>fileAccept()</code></a></li>
<li><a href="#_rgant-Property_hidden">30.4. <code>hidden()</code></a></li>
<li><a href="#_rgant-Property_maxLength">30.5. <code>maxLength()</code></a>
<ul class="sectlevel3">
<li><a href="#_non_persistent_properties">30.5.1. Non-persistent properties</a></li>
</ul> </li>
<li><a href="#_rgant-Property_mustSatisfy">30.6. <code>mustSatisfy()</code></a></li>
<li><a href="#_rgant-Property_notPersisted">30.7. <code>notPersisted()</code></a></li>
<li><a href="#_rgant-Property_optionality">30.8. <code>optionality()</code></a>
<ul class="sectlevel3">
<li><a href="#_mismatched_defaults">30.8.1. Mismatched defaults</a></li>
<li><a href="#_superclass_inheritance_type">30.8.2. Superclass inheritance type</a></li>
<li><a href="#_non_persistent_properties_2">30.8.3. Non-persistent properties</a></li>
</ul> </li>
<li><a href="#_rgant-Property_regexPattern">30.9. <code>regexPattern()</code></a></li>
</ul> </li>
<li><a href="#_rgant-PropertyLayout">31. <code>@PropertyLayout</code></a>
<ul class="sectlevel2">
<li><a href="#_rgant-PropertyLayout_cssClass">31.1. <code>cssClass()</code></a></li>
<li><a href="#_rgant-PropertyLayout_describedAs">31.2. <code>describedAs()</code></a></li>
<li><a href="#_rgant-PropertyLayout_labelPosition">31.3. <code>labelPosition()</code></a></li>
<li><a href="#_rgant-PropertyLayout_multiLine">31.4. <code>multiLine()</code></a></li>
<li><a href="#_rgant-PropertyLayout_named">31.5. named()</a></li>
<li><a href="#_rgant-PropertyLayout_renderedAsDayBefore">31.6. <code>renderedAsDayBefore()</code></a></li>
<li><a href="#_rgant-PropertyLayout_typicalLength">31.7. <code>typicalLength()</code></a></li>
</ul> </li>
<li><a href="#_rgant-RequestScoped">32. <code>@RequestScoped</code> (<code>javax</code>)</a></li>
<li><a href="#_rgant-Title">33. <code>@Title</code></a>
<ul class="sectlevel2">
<li><a href="#_lombok_support">33.1. Lombok support</a></li>
</ul> </li>
<li><a href="#_rgant-ViewModel">34. <code>@ViewModel</code></a></li>
<li><a href="#_rgant-ViewModelLayout">35. <code>@ViewModelLayout</code></a>
<ul class="sectlevel2">
<li><a href="#_rgant-ViewModelLayout_cssClass">35.1. <code>cssClass()</code></a></li>
<li><a href="#_rgant-ViewModelLayout_cssClassFa">35.2. <code>cssClassFa()</code></a></li>
<li><a href="#_rgant-ViewModelLayout_describedAs">35.3. <code>describedAs()</code></a></li>
<li><a href="#_rgant-ViewModelLayout_named">35.4. <code>named()</code></a></li>
<li><a href="#_rgant-ViewModelLayout_paged">35.5. <code>paged()</code></a></li>
<li><a href="#_rgant-ViewModelLayout_plural">35.6. <code>plural()</code></a></li>
</ul> </li>
<li><a href="#_rgant-XmlJavaTypeAdapter">36. <code>@XmlJavaTypeAdapter</code> (<code>jaxb</code>)</a></li>
<li><a href="#_rgant-XmlRootElement">37. <code>@XmlRootElement</code> (<code>jaxb</code>)</a>
<ul class="sectlevel2">
<li><a href="#_example_2">37.1. Example</a></li>
<li><a href="#_see_also">37.2. See also</a></li>
</ul> </li>
</ul>
</div>
</div>
</div>
</div>
<script src="../js/foundation/5.5.1/vendor/jquery.js"></script>
<script src="../js/foundation/5.5.1/foundation.min.js"></script>
<link href="../css/jquery.tocify/1.9.0/jquery.tocify.css" rel="stylesheet">
<script src="../js/jqueryui/1.11.4/jquery-ui.min.js"></script>
<script src="../js/jquery.tocify/1.9.0/jquery.tocify.js"></script>
<script type="text/javascript">
$(function () {
$("#toc").tocify({
scrollTo: 50,
extendPage: true,
context: "#doc-content",
highlightOnScroll: true,
hashGenerator: "pretty",
hideEffect: "slideUp",
selectors: "h2,h3,h4,h5"
});
$(".fallback-toc").hide();
});
</script>
<script type="text/javascript">
/****
$(document).foundation();
$(document).ready(function(){
// Cache selectors
var lastId,
topMenu = $("div#toc ul"),
topMenuHeight = 100,
menuItems = topMenu.find("a"),
menuItemsHrefs = menuItems.map(function(){
var item = $($(this).attr("href"));
if (item.length) { return item; }
});
// Bind click handler to menu items to scroll animation
menuItems.click(function(e){
var href = $(this).attr("href"),
offsetTop = href === "#" ? 0 : $(href).offset().top-topMenuHeight+1;
$('html, body').stop().animate({
scrollTop: offsetTop
}, 300);
e.preventDefault();
});
// Bind to scroll of window
$( window ).scroll(function(){
// Get container scroll position
var fromTop = $(this).scrollTop()+topMenuHeight;
var cur = menuItemsHrefs.map(function(){
if ($(this).offset().top < fromTop)
return this;
});
// Get the id of the current element
cur = cur[cur.length-1];
var id = cur && cur.length ? cur[0].id : "";
if (lastId !== id && id) {
scrollTo(id);
}
window.history.pushState({}, "", window.location.origin + window.location.pathname + "#" + id);
});
scrollTo = function(id) {
lastId = id;
menuItems
.removeClass("active");
menuItems
.parents()
.removeClass("active-region");
menuItems
.parents("ul").hide();
menuItems
.filter("[href=#"+id+"]")
.addClass("active");
menuItems
.filter("[href=#"+id+"]")
.parents("ul").show();
menuItems
.filter("[href=#"+id+"]")
.parent().children("ul").show();
menuItems
.filter("[href=#"+id+"]")
.parents("li").addClass("active-region");
}
menuItems
.removeClass("active");
menuItems
.parents()
.removeClass("active-region");
var syncMenuItem;
if(window.location.hash!=="") {
var menuItemFor = $.grep(menuItems, function(e) {
return e.hash === window.location.hash;
});
console.log(menuItemFor);
if(menuItemFor.length === 1) {
syncMenuItem = menuItemFor[0];
}
}
if(!syncMenuItem){
syncMenuItem = menuItems[0];
}
$(syncMenuItem).click();
});
***/
</script>
<script type="text/javascript">
$(document).ready(function(){
if("Documentation" === "Annotations") {
console.log( "processing 'Documentation'" );
$("#doc-content-left").removeClass("large-9").removeClass("medium-9").addClass("large-12").addClass("medium-12");
$("#doc-content-right").removeClass("large-3").removeClass("medium-3").hide();
}
});
</script>
<script>
$( document ).ready(function() {
(function() {
$(function() {
return $("#doc-content h2, #doc-content h3, #doc-content h4, #doc-content h5, #doc-content h6").each(function(i, el) {
var $el, icon, id;
$el = $(el);
id = $el.attr('id');
icon = '<i class="fa fa-link"></i>';
if (id) {
return $el.prepend($("<a />").addClass("header-link").attr("href", "#" + id).html(icon));
}
});
});
}).call(this);
/*
http://osvaldas.info/auto-hide-sticky-header
MIT license
*/
;( function( $, window, document, undefined )
{
'use strict';
var elSelector = '.header',
elClassHidden = 'header--hidden',
throttleTimeout = 500,
$element = $( elSelector );
if( !$element.length ) return true;
var $window = $( window ),
wHeight = 0,
wScrollCurrent = 0,
wScrollBefore = 0,
wScrollDiff = 0,
$document = $( document ),
dHeight = 0,
throttle = function( delay, fn )
{
var last, deferTimer;
return function()
{
var context = this, args = arguments, now = +new Date;
if( last && now < last + delay )
{
clearTimeout( deferTimer );
deferTimer = setTimeout( function(){ last = now; fn.apply( context, args ); }, delay );
}
else
{
last = now;
fn.apply( context, args );
}
};
};
$window.on( 'scroll', throttle( throttleTimeout, function()
{
dHeight = $document.height();
wHeight = $window.height();
wScrollCurrent = $window.scrollTop();
wScrollDiff = wScrollBefore - wScrollCurrent;
if( wScrollCurrent <= 0 ) // scrolled to the very top; element sticks to the top
$element.removeClass( elClassHidden );
else if( wScrollDiff > 0 && $element.hasClass( elClassHidden ) ) // scrolled up; element slides in
$element.removeClass( elClassHidden );
else if( wScrollDiff < 0 ) // scrolled down
{
if( wScrollCurrent + wHeight >= dHeight && $element.hasClass( elClassHidden ) ) // scrolled to the very bottom; element slides in
$element.removeClass( elClassHidden );
else // scrolled down; element slides out
$element.addClass( elClassHidden );
}
wScrollBefore = wScrollCurrent;
}));
})( jQuery, window, document );
});
</script>
</body>
</html>