ISIS-1521: further minor updates to ugfun.adoc

Project: http://git-wip-us.apache.org/repos/asf/isis/repo
Commit: http://git-wip-us.apache.org/repos/asf/isis/commit/480d6ff2
Tree: http://git-wip-us.apache.org/repos/asf/isis/tree/480d6ff2
Diff: http://git-wip-us.apache.org/repos/asf/isis/diff/480d6ff2

Branch: refs/heads/wip
Commit: 480d6ff24c2a66fc5a31fcb629677016bde0737e
Parents: 45db638
Author: Dan Haywood <d...@haywood-associates.co.uk>
Authored: Fri Apr 14 17:59:07 2017 +0100
Committer: Dan Haywood <d...@haywood-associates.co.uk>
Committed: Thu Apr 20 09:09:30 2017 +0100

----------------------------------------------------------------------
 .../guides/rgcfg/_rgcfg_configuring-core.adoc   |   4 +-
 .../guides/ugbtb/_ugbtb_hints-and-tips.adoc     |   3 +
 .../_ugbtb_hints-and-tips_are-you-sure.adoc     |  76 ++++
 ...d-tips_simulating-collections-of-values.adoc |  23 ++
 ...-and-tips_subclass-properties-in-tables.adoc |  49 +++
 .../guides/ugbtb/_ugbtb_view-models.adoc        |   1 -
 .../guides/ugbtb/_ugbtb_view-models_jaxb.adoc   |   6 +-
 .../_ugbtb_view-models_programming-model.adoc   |   4 +-
 .../ugbtb/_ugbtb_view-models_use-cases.adoc     | 160 --------
 .../guides/ugfun/_ugfun_business-rules.adoc     |  89 ++++
 .../guides/ugfun/_ugfun_class-structure.adoc    |  42 ++
 .../ugfun/_ugfun_class-structure_actions.adoc   | 264 ++++++++++++
 .../_ugfun_class-structure_collections.adoc     | 121 ++++++
 .../_ugfun_class-structure_domain-services.adoc | 155 +++++++
 .../_ugfun_class-structure_inject-services.adoc | 103 +++++
 ...lass-structure_properties-vs-parameters.adoc |  38 ++
 .../_ugfun_class-structure_properties.adoc      | 411 +++++++++++++++++++
 .../main/asciidoc/guides/ugfun/_ugfun_crud.adoc |  29 ++
 .../ugfun/_ugfun_domain-class-ontology.adoc     |  43 ++
 ...n_domain-class-ontology_domain-entities.adoc |  86 ++++
 ...n_domain-class-ontology_domain-services.adoc | 214 ++++++++++
 ...ugfun_domain-class-ontology_view-models.adoc | 196 +++++++++
 .../ugfun/_ugfun_drop-downs-and-defaults.adoc   |  65 +++
 .../asciidoc/guides/ugfun/_ugfun_how-tos.adoc   |  20 -
 .../ugfun/_ugfun_how-tos_bulk-actions.adoc      |   8 -
 .../ugfun/_ugfun_how-tos_business-rules.adoc    |  72 ----
 .../ugfun/_ugfun_how-tos_class-structure.adoc   |  41 --
 .../_ugfun_how-tos_class-structure_actions.adoc | 264 ------------
 ...ow-tos_class-structure_class-definition.adoc | 201 ---------
 ...fun_how-tos_class-structure_collections.adoc |  99 -----
 ...how-tos_class-structure_inject-services.adoc | 103 -----
 ...lass-structure_properties-vs-parameters.adoc |  38 --
 ...gfun_how-tos_class-structure_properties.adoc | 397 ------------------
 .../guides/ugfun/_ugfun_how-tos_crud.adoc       |  29 --
 .../ugfun/_ugfun_how-tos_derived-members.adoc   |  48 ---
 .../ugfun/_ugfun_how-tos_domain-services.adoc   | 312 --------------
 .../_ugfun_how-tos_drop-downs-and-defaults.adoc |  65 ---
 ...how-tos_render-all-properties-in-tables.adoc |  49 ---
 ...ow-tos_simulating-collections-of-values.adoc |  23 --
 .../guides/ugfun/_ugfun_how-tos_ui-hints.adoc   |  15 -
 ...n_how-tos_ui-hints_action-icons-and-css.adoc |  58 ---
 ..._ugfun_how-tos_ui-hints_eager-rendering.adoc |  58 ---
 .../ugfun/_ugfun_how-tos_ui-hints_layout.adoc   |   9 -
 ...how-tos_ui-hints_names-and-descriptions.adoc |  47 ---
 ...ow-tos_ui-hints_object-titles-and-icons.adoc |  97 -----
 .../ugfun/_ugfun_how-tos_ui_are-you-sure.adoc   |  76 ----
 .../asciidoc/guides/ugfun/_ugfun_ui-hints.adoc  |  15 +
 .../_ugfun_ui-hints_action-icons-and-css.adoc   |  58 +++
 .../ugfun/_ugfun_ui-hints_eager-rendering.adoc  |  58 +++
 .../guides/ugfun/_ugfun_ui-hints_layout.adoc    |  14 +
 .../_ugfun_ui-hints_names-and-descriptions.adoc |  47 +++
 ..._ugfun_ui-hints_object-titles-and-icons.adoc |  97 +++++
 .../src/main/asciidoc/guides/ugfun/ugfun.adoc   |  12 +-
 .../src/main/asciidoc/guides/ugvw/ugvw.adoc     |   2 +-
 .../asciidoc/pages/screencasts/screencasts.adoc |   2 +-
 .../tg/_tg_stop-scaffolding-start-coding.adoc   |  20 +-
 56 files changed, 2325 insertions(+), 2311 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/isis/blob/480d6ff2/adocs/documentation/src/main/asciidoc/guides/rgcfg/_rgcfg_configuring-core.adoc
----------------------------------------------------------------------
diff --git 
a/adocs/documentation/src/main/asciidoc/guides/rgcfg/_rgcfg_configuring-core.adoc
 
b/adocs/documentation/src/main/asciidoc/guides/rgcfg/_rgcfg_configuring-core.adoc
index c4948a0..4535000 100644
--- 
a/adocs/documentation/src/main/asciidoc/guides/rgcfg/_rgcfg_configuring-core.adoc
+++ 
b/adocs/documentation/src/main/asciidoc/guides/rgcfg/_rgcfg_configuring-core.adoc
@@ -597,14 +597,14 @@ Only intended for "emergency use" as a workaround while 
pending fix/patch to Apa
 |regex:css1, regex2:css2,...
 |Comma separated list of key:value pairs, where the key is a regex matching 
action names (eg `delete.*`) and the value is a 
link:http://getbootstrap.com/css/[Bootstrap] CSS button class (eg `btn-warning) 
to be applied (as per `@CssClass()`) to all action members matching the regex. +
 
-See xref:../ugfun/ugfun.adoc#_ugfun_how-tos_ui-hints_action-icons-and-css[UI 
hints] for more details.
+See xref:../ugfun/ugfun.adoc#_ugfun_ui-hints_action-icons-and-css[UI hints] 
for more details.
 
 |`isis.reflector.facet.` +
 `cssClassFa.patterns`
 |regex:fa-icon,regex2:fa-icon2,...
 |Comma separated list of key:value pairs, where the key is a regex matching 
action names (eg `create.*`) and the value is a 
link:http://fortawesome.github.io/Font-Awesome/icons/[font-awesome] icon name 
(eg `fa-plus`) to be applied (as per `@CssClassFa()`) to all action members 
matching the regex. +
 
-See xref:../ugfun/ugfun.adoc#_ugfun_how-tos_ui-hints_action-icons-and-css[UI 
hints] for more details.
+See xref:../ugfun/ugfun.adoc#_ugfun_ui-hints_action-icons-and-css[UI hints] 
for more details.
 
 
 |`isis.reflector.facet.` +

http://git-wip-us.apache.org/repos/asf/isis/blob/480d6ff2/adocs/documentation/src/main/asciidoc/guides/ugbtb/_ugbtb_hints-and-tips.adoc
----------------------------------------------------------------------
diff --git 
a/adocs/documentation/src/main/asciidoc/guides/ugbtb/_ugbtb_hints-and-tips.adoc 
b/adocs/documentation/src/main/asciidoc/guides/ugbtb/_ugbtb_hints-and-tips.adoc
index 51c76f0..8ebe0a7 100644
--- 
a/adocs/documentation/src/main/asciidoc/guides/ugbtb/_ugbtb_hints-and-tips.adoc
+++ 
b/adocs/documentation/src/main/asciidoc/guides/ugbtb/_ugbtb_hints-and-tips.adoc
@@ -23,5 +23,8 @@ See also hints-n-tips chapters in the:
 * the xref:../ugbtb/ugbtb.adoc#_ugbtb_hints-and-tips[Beyond the Basics] guide 
(this chapter).
 
 
+include::_ugbtb_hints-and-tips_are-you-sure.adoc[leveloffset=+1]
 
include::_ugbtb_hints-and-tips_how-to-handle-void-and-null-results.adoc[leveloffset=+1]
+include::_ugbtb_hints-and-tips_subclass-properties-in-tables.adoc[leveloffset=+1]
+include::_ugbtb_hints-and-tips_simulating-collections-of-values.adoc[leveloffset=+1]
 
include::_ugbtb_hints-and-tips_how-to-implement-a-spellchecker.adoc[leveloffset=+1]

http://git-wip-us.apache.org/repos/asf/isis/blob/480d6ff2/adocs/documentation/src/main/asciidoc/guides/ugbtb/_ugbtb_hints-and-tips_are-you-sure.adoc
----------------------------------------------------------------------
diff --git 
a/adocs/documentation/src/main/asciidoc/guides/ugbtb/_ugbtb_hints-and-tips_are-you-sure.adoc
 
b/adocs/documentation/src/main/asciidoc/guides/ugbtb/_ugbtb_hints-and-tips_are-you-sure.adoc
new file mode 100644
index 0000000..66bc6d7
--- /dev/null
+++ 
b/adocs/documentation/src/main/asciidoc/guides/ugbtb/_ugbtb_hints-and-tips_are-you-sure.adoc
@@ -0,0 +1,76 @@
+[[_ugbtb_hints-and-tips_are-you-sure]]
+= 'Are you sure?' idiom
+:Notice: 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.
+:_basedir: ../../
+:_imagesdir: images/
+
+
+Sometimes an action might perform irreversible changes.  In such a case it's 
probably a good idea for the UI to require that the
+end-user explicitly confirms that they intended to invoke the action.
+
+== Using action semantics
+
+One way to meet this requirement is using the framework's built-in 
xref:../rgant/rgant.adoc#_rgant-Action_semantics[`@Action#semantics()`] 
attribute:
+
+[source,java]
+----
+@Action(
+        semantics = SemanticsOf.IDEMPOTENT_ARE_YOU_SURE
+)
+public SimpleObject updateName(
+        @Parameter(maxLength = NAME_LENGTH)
+        @ParameterLayout(named = "New name")
+        final String name) {
+    setName(name);
+    return this;
+}
+----
+
+
+This will render as:
+
+image::{_imagesdir}/how-tos/tips-n-tricks/action-semantics-are-you-sure.png[]
+
+
+== Using a checkbox
+
+An alternative approach (for all versions of the framework) is to require the 
end-user to check a dummy checkbox parameter (and prevent the action from being 
invoked if the user hasn't checked that parameter).
+
+For example:
+
+image::{_imagesdir}/how-tos/tips-n-tricks/are-you-sure.png[]
+
+[NOTE]
+====
+Note that these screenshots shows an earlier version of the 
xref:../ugvw/ugvw.adoc#[Wicket viewer] UI (specifically, pre 1.8.0).
+====
+
+If the user checks the box:
+
+image::{_imagesdir}/how-tos/tips-n-tricks/are-you-sure-happy-case.png[]
+
+then the action will complete.
+
+However, if the user fails to check the box, then a validation message is 
shown:
+
+image::{_imagesdir}/how-tos/tips-n-tricks/are-you-sure-sad-case.png[]
+
+
+
+The code for this is pretty simple:
+
+[source,java]
+----
+public List<ToDoItem> delete(@Named("Are you sure?") boolean areYouSure) {
+    container.removeIfNotAlready(this);
+    container.informUser("Deleted " + container.titleOf(this));
+    return toDoItems.notYetComplete();          // <1>
+}
+public String validateDelete(boolean areYouSure) {
+    return areYouSure? null: "Please confirm you are sure";
+}
+----
+<1> invalid to return `this` (cannot render a deleted object)
+
+Note that the action itself does not use the boolean parameter, it is only
+used by the supporting 
xref:../rgcms/rgcms.adoc#_rgcms_methods_prefixes_validate[`validate...()`] 
method.
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/isis/blob/480d6ff2/adocs/documentation/src/main/asciidoc/guides/ugbtb/_ugbtb_hints-and-tips_simulating-collections-of-values.adoc
----------------------------------------------------------------------
diff --git 
a/adocs/documentation/src/main/asciidoc/guides/ugbtb/_ugbtb_hints-and-tips_simulating-collections-of-values.adoc
 
b/adocs/documentation/src/main/asciidoc/guides/ugbtb/_ugbtb_hints-and-tips_simulating-collections-of-values.adoc
new file mode 100644
index 0000000..f606ba7
--- /dev/null
+++ 
b/adocs/documentation/src/main/asciidoc/guides/ugbtb/_ugbtb_hints-and-tips_simulating-collections-of-values.adoc
@@ -0,0 +1,23 @@
+[[_ugbtb_hints-and-tips_simulating-collections-of-values]]
+= Collections of values
+:Notice: 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.
+:_basedir: ../../
+:_imagesdir: images/
+
+
+
+Although in Apache Isis you can have properties of either values (string, 
number, date etc) or of (references to other) entities, with collections the 
framework (currently) only supports collections of (references to) entities.  
That is, collections of values (a bag of numbers, say) are not supported.
+
+However, it is possible to simulate a bag of numbers using view models.
+
+
+== View Model
+
+NOTE: FIXME
+
+
+
+== Persistence Concerns
+
+NOTE: FIXME -  easiest to simply store using DataNucleus' support for 
collections, marked as 
xref:../rgant/rgant.adoc#_rgant-Programmatic[`@Programmatic`] so that it is 
ignored by Apache Isis.  Alternatively can store as json/xml in a varchar(4000) 
or clob and manually unpack.
+

http://git-wip-us.apache.org/repos/asf/isis/blob/480d6ff2/adocs/documentation/src/main/asciidoc/guides/ugbtb/_ugbtb_hints-and-tips_subclass-properties-in-tables.adoc
----------------------------------------------------------------------
diff --git 
a/adocs/documentation/src/main/asciidoc/guides/ugbtb/_ugbtb_hints-and-tips_subclass-properties-in-tables.adoc
 
b/adocs/documentation/src/main/asciidoc/guides/ugbtb/_ugbtb_hints-and-tips_subclass-properties-in-tables.adoc
new file mode 100644
index 0000000..7c29f55
--- /dev/null
+++ 
b/adocs/documentation/src/main/asciidoc/guides/ugbtb/_ugbtb_hints-and-tips_subclass-properties-in-tables.adoc
@@ -0,0 +1,49 @@
+[[_ugbtb_hints-and-tips_subclass-properties-in-tables]]
+= Subclass properties in tables
+:Notice: 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.
+:_basedir: ../../
+:_imagesdir: images/
+
+
+
+Suppose you have a hierarchy of classes where a property is derived and 
abstract in the superclass, concrete implementations in the subclasses. For 
example:
+
+[source,java]
+----
+public abstract class LeaseTerm {
+    public abstract BigDecimal getEffectiveValue();
+    ...
+}
+
+public class LeaseTermForIndexableTerm extends LeaseTerm {
+    public BigDecimal getEffectveValue() { ... }
+    ...
+}
+----
+
+Currently the Wicket viewer will not render the property in tables (though the 
property is correctly rendered in views).
+
+[NOTE]
+====
+For more background on this workaround, see 
https://issues.apache.org/jira/browse/ISIS-582[ISIS-582].
+====
+
+The work-around is simple enough; make the method concrete in the superclass 
and return a dummy implementation, eg:
+
+[source,java]
+----
+public abstract class LeaseTerm {
+    public BigDecimal getEffectiveValue() {
+        return null;        // workaround for ISIS-582
+    }
+    ...
+}
+----
+
+
+Alternatively the implementation could throw a `RuntimeException`, eg
+
+[source,java]
+----
+throw new RuntimeException("never called; workaround for ISIS-582");
+----
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/isis/blob/480d6ff2/adocs/documentation/src/main/asciidoc/guides/ugbtb/_ugbtb_view-models.adoc
----------------------------------------------------------------------
diff --git 
a/adocs/documentation/src/main/asciidoc/guides/ugbtb/_ugbtb_view-models.adoc 
b/adocs/documentation/src/main/asciidoc/guides/ugbtb/_ugbtb_view-models.adoc
index dcd248a..0efd664 100644
--- a/adocs/documentation/src/main/asciidoc/guides/ugbtb/_ugbtb_view-models.adoc
+++ b/adocs/documentation/src/main/asciidoc/guides/ugbtb/_ugbtb_view-models.adoc
@@ -12,7 +12,6 @@ This opens up a number of more advanced use cases.
 In this topic we'll explore those use cases, and learn the programming model 
and conventions to use view models in your application.
 
 
-include::_ugbtb_view-models_use-cases.adoc[leveloffset=+1]
 include::_ugbtb_view-models_programming-model.adoc[leveloffset=+1]
 include::_ugbtb_view-models_jaxb.adoc[leveloffset=+1]
 

http://git-wip-us.apache.org/repos/asf/isis/blob/480d6ff2/adocs/documentation/src/main/asciidoc/guides/ugbtb/_ugbtb_view-models_jaxb.adoc
----------------------------------------------------------------------
diff --git 
a/adocs/documentation/src/main/asciidoc/guides/ugbtb/_ugbtb_view-models_jaxb.adoc
 
b/adocs/documentation/src/main/asciidoc/guides/ugbtb/_ugbtb_view-models_jaxb.adoc
index 258f9e2..fe49916 100644
--- 
a/adocs/documentation/src/main/asciidoc/guides/ugbtb/_ugbtb_view-models_jaxb.adoc
+++ 
b/adocs/documentation/src/main/asciidoc/guides/ugbtb/_ugbtb_view-models_jaxb.adoc
@@ -1,12 +1,12 @@
 [[_ugbtb_view-models_jaxb]]
-= JAXB-annotated DTOs
+= JAXB-annotated View Models/DTOs
 :Notice: 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.
 :_basedir: ../../
 :_imagesdir: images/
 
 
 
-As noted in the 
xref:../ugbtb/ugbtb.adoc#_ugbtb_view-models_use-cases[introduction], view 
models can also be defined using JAXB annotations.
+As noted in the 
xref:../ugfun/ugfun.adoc#_ugfun_domain-class-ontology_view-models[introduction],
 view models can also be defined using JAXB annotations.
 The serialized form of these view models is therefore XML, which also enables 
these view models
 to act as DTOs.
 
@@ -18,7 +18,7 @@ In fact, these JAXB-annotated view models are in many regards 
the most powerful
 In contrast, using xref:../rgant/rgant.adoc#_rgant-ViewModel[`@ViewModel`] (or 
its 
xref:../rgant/rgant.adoc#_rgant-DomainObject_nature[`@DomainObject#nature()`] 
equivalent) will only manage the state of properties, but not collections.
 And if using the 
xref:../rgcms/rgcms.adoc#_rgcms_classes_super_ViewModel[`ViewModel`] interface, 
then the programmer must write all the state management (lots of boilerplate).
 
-* JAXB-annotated view models are editable.
+* JAXB-annotated view models are "in effect" editable.
 
 The examples in this section uses the DTO for `ToDoItem`, taken from the 
(non-ASF) http://github.com/isisaddons/isis-app-todoapp[Isis addons' todoapp].
 This DTO is defined as follows:

http://git-wip-us.apache.org/repos/asf/isis/blob/480d6ff2/adocs/documentation/src/main/asciidoc/guides/ugbtb/_ugbtb_view-models_programming-model.adoc
----------------------------------------------------------------------
diff --git 
a/adocs/documentation/src/main/asciidoc/guides/ugbtb/_ugbtb_view-models_programming-model.adoc
 
b/adocs/documentation/src/main/asciidoc/guides/ugbtb/_ugbtb_view-models_programming-model.adoc
index d4bb007..2fd3a82 100644
--- 
a/adocs/documentation/src/main/asciidoc/guides/ugbtb/_ugbtb_view-models_programming-model.adoc
+++ 
b/adocs/documentation/src/main/asciidoc/guides/ugbtb/_ugbtb_view-models_programming-model.adoc
@@ -6,7 +6,9 @@
 
 
 
-So much for the theory; how should view models be implemented?  Fundamentally 
all view models' state is serialized into
+This section describes how to implement view models.
+
+Fundamentally all view models' state is serialized into
 a string memento; this memento is then held by the client (browser) in the 
form of a URL.  As you might imagine, this
 URL can become quite long, but Apache Isis offers a mechanism (the 
xref:../rgsvc/rgsvc.adoc#_rgsvc_spi_UrlEncodingService[`UrlEncodingService`]) 
if it exceeds the maximum length for a URL
 (2083 characters).  Also, of course, this string memento must only contain 
characters that it is valid for use within

http://git-wip-us.apache.org/repos/asf/isis/blob/480d6ff2/adocs/documentation/src/main/asciidoc/guides/ugbtb/_ugbtb_view-models_use-cases.adoc
----------------------------------------------------------------------
diff --git 
a/adocs/documentation/src/main/asciidoc/guides/ugbtb/_ugbtb_view-models_use-cases.adoc
 
b/adocs/documentation/src/main/asciidoc/guides/ugbtb/_ugbtb_view-models_use-cases.adoc
deleted file mode 100644
index a58f57c..0000000
--- 
a/adocs/documentation/src/main/asciidoc/guides/ugbtb/_ugbtb_view-models_use-cases.adoc
+++ /dev/null
@@ -1,160 +0,0 @@
-[[_ugbtb_view-models_use-cases]]
-= Use Cases
-:Notice: 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.
-:_basedir: ../../
-:_imagesdir: images/
-
-
-When developing an Apache Isis application you will most likely start off with 
the persistent domain entities:
-`Customer`, `Order`, `Product`, and so on.  For some applications this may 
well suffice.  However, if the application
-needs to integrate with other systems, or if the application needs to support 
reasonably complex business processes, then you may need to look beyond just 
domain entities.  This section explores these use cases.
-
-[[__ugbtb_view-models_use-cases_externally-managed-entities]]
-== Externally-managed entities
-
-Sometimes the entities that make up your application are persisted not in the 
local JDO/DataNucleus database
-but reside in some other system, for example accessible only through a SOAP 
web service.  Logically that data
-might still be considered a domain entity and we might want to associate 
behaviour with it, however it cannot be
-modelled as a domain entity if only because JDO/DataNucleus doesn't know about 
the entity nor how to retrieve or
-update it.
-
-There are a couple of ways around this: we could either replicate the data 
somehow from the external system into the
- Isis-managed database (in which case it is once again just another domain 
entity), or we could set up a stub/proxy for
- the externally managed entity.  This proxy would hold the reference to the 
externally-managed domain entity (eg an
- external id), as well as the "smarts" to know how to interact with that 
entity (by making SOAP web service calls etc).
-
-The stub/proxy is a type of view model: a view - if you like - onto the domain 
entity managed by the external system.
-
-[NOTE]
-====
-DataNucleus does in fact define its own 
link:http://www.datanucleus.org/documentation/extensions/store_manager.html[Store
 Manager] extension point, so an alternative architecture would be to implement 
this interface such that DataNucleus
-could make the calls to the external system; these externally-persisted domain 
entities would therefore be modelled as regular `@PersistenceCapable` entities 
after all.  For entities not persisted externally the implementation would 
delegate down to the default RDBMS-specific `StoreManager` provided by 
DataNucleus itself.
-
-An implementation that supported only reading from an external entity ought to 
be comparatively straight-forward, but
-implementing one that also supported updating external entities would need to 
carefully consider error conditions if the
-external system is unavailable; distributed transactions are most likely 
difficult/impossible to implement (and not
-desirable in any case).
-====
-
-
-[[__ugbtb_view-models_use-cases_in-memory-entities]]
-== In-memory entities
-
-As a variation on the above, sometimes there are domain objects that are, 
conceptually at least entities, but whose
-state is not actually persisted anywhere, merely held in-memory (eg in a hash).
-
-A simple example might be read-only configuration data that is read from a 
config file (eg log4j appender
-definitions) but thereafter is presented in the UI just like any other entity.
-
-
-[[__ugbtb_view-models_use-cases_application-layer-view-models]]
-== Application-layer view models
-
-Domain entities (whether locally persisted using JDO/DataNucleus or managed 
externally) are the bread-and-butter of Apache Isis applications: the focus 
after all, should be on the business domain concepts and ensuring that they are
-solid.  Generally those domain entities will make sense to the business domain 
experts: they form the _ubiquitous language_ of the domain.  These domain 
entities are part of the domain layer.
-
-That said, it may not always be practical to expect end-users of the 
application to interact solely with those domain
-entities.  For example, it may be useful to show a dashboard of the most 
significant data in the system to a user,
-often pulling in and aggregating information from multiple points of the app.  
Obtaining this information by hand (by
- querying the respective services/repositories) would be tedious and slow; far 
better to have a dashboard do the job for
- the end user.
-
-A dashboard object is a model of the most relevant state to the end-user, in 
other words it is (quite literally) a view
- model.  It is not a persisted entity, instead it belongs to the application 
layer.
-
-A view model need not merely aggregate data; it could also provide actions of 
its own.  Most likely these actions will
-be queries and will always ultimately just delegate down to the appropriate 
domain-layer service/repository.  But in
-some cases such view model actions might also modify state of underlying 
domain entities.
-
-Another common use for view models is to help co-ordinate complex business 
processes; for example to perform a
-quarterly invoicing run, or to upload annual interest rates from an Excel 
spreadsheet.  In these cases the view model
-might have some state of its own, but in most cases that state does not need 
to be persisted per se.
-
-.Desire Lines
-****
-One way to think of application view models is as modelling the "desire line": 
the commonly-trod path
-that end-users must follow to get from point A to point B as quickly as 
possible.
-
-To explain: there are 
link:http://ask.metafilter.com/62599/Where-the-sidewalk-ends[documented]
-link:https://sivers.org/walkways[examples]
-link:http://www.softpanorama.org/People/Wall/larry_wall_articles_and_interviews.shtml[that]
 architects of university
-campus will only add in paths some while after the campus buildings are 
complete: let the pedestrians figure out the
-routes they want to take.  The name we like best for this idea is "desire 
lines", though it has also been called
-a "desire path", "paving the path" or "paving the sidewalk".
-
-What that means is you should add view models _after_ having built up the 
domain layer, rather than before.  These view
-models pave that commonly-trod path, automating the steps that the end-user 
would otherwise have to do by hand.
-
-It takes a little practice though, because even when building the domain layer 
"first", you should still bear in mind
-what the use cases are that those domain entities are trying to support.  You 
certainly _shouldn't_ try to build out a
-domain layer that could support every conceivable use case before starting to 
think about view models.
-
-Instead, you should iterate.  Identify the use case/story/end-user objective 
that you will deliver value to the
-business.  Then build out the minimum domain entities to support that use case 
(refining the 
xref:../ugfun/ugfun.adoc#__ugfun_core-concepts_philosophy_domain-driven-design_ubiquitous-language[ubiquitous
 language] as you
-go).  Then, identify if there any view models that could be introduced which 
would simplify the end-user interactions
-with the system (perhaps automating several related use cases together).
-****
-
-[[__ugbtb_view-models_use-cases_dtos]]
-== DTOs
-
-DTOs (data transfer objects) are simple classes that (according to 
link:https://en.wikipedia.org/wiki/Data_transfer_object[wikipedia]) "carry data 
between processes".
-
-If those two processes are parts of the same overall application (the same 
team builds and deploys both server and
-client) then there's generally no need to define a DTO; just access the 
entities using Apache Isis'
-xref:../ugvro/ugvro.adoc#[RestfulObjects viewer].
-
-On the other hand, if the client consuming the DTO is a different application 
-- by which we mean developed/deployed by
-a different (possible third-party) team -- then the DTOs act as a formal 
contract between the provider and the consumer.
-In such cases, exposing domain entities over 
xref:../ugvro/ugvro.adoc#[RestfulObjects] would be
-"A Bad Thing"(TM) because the consumer would in effect have access to 
implementation details that could then not be
-easily changed by the producer.
-
-To support this use case, a view model can be defined such that it can act as 
a DTO.  This is done by annotating the
-class using JAXB annotations; this allows the consumer to obtain the DTO in 
XML format along with a corresponding
-XSD schema describing the structure of that XML.  A discussion of how that 
might be done using an ESB such as
-link:http://camel.apache.org[Apache Camel(TM)] follows 
xref:../ugbtb/ugbtb.adoc#__ugbtb_view-models_use-cases_dtos_consumers[below].
-
-In case it's not obvious, these DTOs are still usable as "regular" view 
models; they will render in the xref:../ugvw/ugvw.adoc#[Wicket viewer] just 
like any other.  In fact (as the 
xref:../ugbtb/ugbtb.adoc#_ugbtb_view-models_programming-model[programming 
model] section below makes clear), these JAXB-annotated view models are in many 
regards the most powerful of all the alternative ways of writing view models.
-
-
-It's also worth noting that it is also possible to download the XML (or XSD) 
straight from the UI, useful during development.
-The view model simply needs to implement the 
xref:../rgcms/rgcms.adoc#_rgcms_classes_mixins_Dto[`Dto`] marker interface; the
-framework has xref:../rgcms/rgcms.adoc#_rgcms_classes_mixins_Dto[mixins] that 
contribute the download actions to the view model.
-
-
-[[__ugbtb_view-models_use-cases_dtos_consumers]]
-=== DTO Consumers
-
-The actual consumers of DTOs will generally obtain the XML of the view models 
either by requesting the XML directly,
-eg using the xref:../ugvro/ugvro.adoc#[RestfulObjects viewer], or may have the 
XML sent to them asynchronously using an ESB
-such as Apache Camel.
-
-In the former case, the consumer requests the DTO by calling the REST API with 
the appropriate HTTP `Accept` header.
-An appropriate implementation of 
xref:../rgsvc/rgsvc.adoc#_rgsvc_spi_ContentMappingService[`ContentMappingService`]
 can then be
-used to return the appropriate DTO (as XML).
-
-For the latter case, one design is simply for the application to instantiate 
the view model, then call the
-xref:../rgsvc/rgsvc.adoc#_rgsvc_api_JaxbService[`JaxbService`] to obtain its 
corresponding XML.  This can then be published onto
-the ESB, for example using an http://activemq.apache.org[Apache ActiveMQ (TM)] 
queue.
-
-However, rather than try to push all the data that might be needed by any of 
these external systems in a single XML event
- (which would require anticipating all the requirements, likely a hopeless 
task), a better design is to publish only
- the fact that something of note has changed - ie, that an action on a domain 
object has been invoked - and then let the consumers call back to obtain other 
information if required.  This can once again be done by calling the REST API 
with
- an appropriate HTTP `Accept` header.
-
-[TIP]
-====
-This is an example of the link:https://leanpub.com/camel-design-patterns[VETRO 
pattern] (validate, enrich, transform, route, operate).  In our case we focus 
on the validation (to determine the nature of the inbound message, ie which 
action was
-invoked), and the enrich (callback to obtain a DTO with additional information 
required by the consumer).
-====
-
-The (non-ASF) http://github.com/isisaddons/isis-module-publishmq[Isis addons' 
publishmq] module provides an out-of-the-box solution of this design.  It 
provides an implementation of the 
xref:../rgsvc/rgsvc.adoc#_rgsvc_spi_PublishingService[`PublishingService`],
-but which simply publishes instances of 
xref:../rgcms/rgcms.adoc#_rgcms_schema-aim[`ActionInvocationMemento`] to an 
ActiveMQ
-queue.  Camel (or similar) can then be hooked up to consume these events from 
this queue, and use a processor to
-parse the action memento to determine what has changed on the source system.  
Thereafter, a subsequent Camel processor
-can then call back to the source - via the xref:../ugvro/ugvro.adoc[Restful 
Objects viewer] - to enrich the message with
-additional details using a DTO.
-
-
-

http://git-wip-us.apache.org/repos/asf/isis/blob/480d6ff2/adocs/documentation/src/main/asciidoc/guides/ugfun/_ugfun_business-rules.adoc
----------------------------------------------------------------------
diff --git 
a/adocs/documentation/src/main/asciidoc/guides/ugfun/_ugfun_business-rules.adoc 
b/adocs/documentation/src/main/asciidoc/guides/ugfun/_ugfun_business-rules.adoc
new file mode 100644
index 0000000..e799572
--- /dev/null
+++ 
b/adocs/documentation/src/main/asciidoc/guides/ugfun/_ugfun_business-rules.adoc
@@ -0,0 +1,89 @@
+[[_ugfun_business-rules]]
+= Business Rules
+:Notice: 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.
+:_basedir: ../../
+:_imagesdir: images/
+
+NOTE: FIXME
+
+
+
+== Visibility ("see it")
+
+NOTE: FIXME - 
xref:../rgcms/rgcms.adoc#_rgcms_methods_prefixes_hide[`hide...()`]
+
+### Hide a Property
+
+### Hide a Collection
+
+### Hide an Action
+
+### Hide a Contributed Property, Collection or Action
+
+### All Members Hidden
+
+
+
+
+== Usability ("use it")
+
+NOTE: FIXME - 
xref:../rgcms/rgcms.adoc#_rgcms_methods_prefixes_disable[`disable...()`]
+
+### Disable a Property
+
+### Disable a Collection
+
+### Disable an Action
+
+### Disable a Contributed Property, Collection or Action
+
+### All Members Unmodifiable (Disabling the Edit Button)
+
+Sometimes an object is unmodifiable.
+
+In the Wicket viewer this means disabling the edit button.
+
+#### Declarative
+
+`@DomainObject(editing=...)`
+
+#### Imperative
+
+
+
+== Validity ("do it")
+
+NOTE: FIXME - 
xref:../rgcms/rgcms.adoc#_rgcms_methods_prefixes_validate[`validate...()`], 
xref:../rgcms/rgcms.adoc#_rgcms_methods_prefixes_validateAddTo[`validateAddTo...()`],
 
xref:../rgcms/rgcms.adoc#_rgcms_methods_prefixes_validateRemoveFrom[`validateRemoveFrom...()`]
 and xref:../rgcms/rgcms.adoc#_rgcms_methods_reserved_validate[`validate()`]
+
+
+### Validate (change to) a Property
+
+### Validate (adding or removing from) a Collection
+
+### Validate (arguments to invoke) an Action
+
+### Validating a Contributed Property, Collection or Action
+
+### Declarative validation
+
+NOTE: FIXME - using 
xref:../rgant/rgant.adoc#_rgant-Parameter_mustSatisfy[`@Parameter#mustSatisfy()`],
 xref:../rgant/rgant.adoc#_rgant-Property_mustSatisfy[`@Property#mustSatisfy()`]
+
+
+
+
+
+
+
+== On modification
+
+NOTE: FIXME - detail here...
+
+=== Trigger on property change
+
+NOTE: FIXME - 
xref:../rgcms/rgcms.adoc#_rgcms_methods_prefixes_modify[`modify...()`], 
xref:../rgcms/rgcms.adoc#_rgcms_methods_prefixes_clear[`clear...()`]
+
+
+
+=== Trigger on collection change
+
+NOTE: FIXME - 
xref:../rgcms/rgcms.adoc#_rgcms_methods_prefixes_addTo[`addTo...()`], 
xref:../rgcms/rgcms.adoc#_rgcms_methods_prefixes_removeFrom[`removeFrom...()`]

http://git-wip-us.apache.org/repos/asf/isis/blob/480d6ff2/adocs/documentation/src/main/asciidoc/guides/ugfun/_ugfun_class-structure.adoc
----------------------------------------------------------------------
diff --git 
a/adocs/documentation/src/main/asciidoc/guides/ugfun/_ugfun_class-structure.adoc
 
b/adocs/documentation/src/main/asciidoc/guides/ugfun/_ugfun_class-structure.adoc
new file mode 100644
index 0000000..4ea4350
--- /dev/null
+++ 
b/adocs/documentation/src/main/asciidoc/guides/ugfun/_ugfun_class-structure.adoc
@@ -0,0 +1,42 @@
+[[_ugfun_class-structure]]
+= Class Structure
+:Notice: 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.
+:_basedir: ../../
+:_imagesdir: images/
+
+
+Apache Isis works by building a metamodel of the domain objects: entities, 
xref:../ugbtb/ugbtb.adoc#_ugbtb_view-models[view model]s and services.
+The class methods of both entities and view models represent both state -- 
(single-valued) properties and (multi-valued) collections -- and behaviour -- 
actions.  The class members of domain services is simpler: just behaviour, ie 
actions.
+
+In the automatically generated UI a property is rendered as a field.
+This can be either of a value type (a string, number, date, boolean etc) or 
can be a reference to another entity.
+A collection is generally rendered as a table.
+
+In order for Apache Isis to build its metamodel the domain objects must follow 
some conventions: what we call the _Apache Isis Programming Model_.
+This is just an extension of the pojo / JavaBean standard of yesteryear: 
properties and collections are getters/setters, while actions are simply any 
remaining `public` methods.
+
+Additional metamodel semantics are inferred both imperatively from _supporting 
methods_ and declaratively from annotations.
+
+In this section we discuss the mechanics of writing domain objects that comply 
with Apache Isis' programming model.
+
+[TIP]
+====
+In fact, the Apache Isis programming model is extensible; you can teach Apache 
Isis new programming conventions and you can remove existing ones; ultimately 
they amount to syntax.
+The only real fundamental that can't be changed is the notion that objects 
consist of properties, collections and actions.
+
+You can learn more about extending Apache Isis programming model 
xref:../ugbtb/ugbtb.adoc#_ugbtb_programming-model[here].
+====
+
+
+include::_ugfun_class-structure_properties.adoc[leveloffset=+1]
+include::_ugfun_class-structure_collections.adoc[leveloffset=+1]
+include::_ugfun_class-structure_actions.adoc[leveloffset=+1]
+include::_ugfun_class-structure_inject-services.adoc[leveloffset=+1]
+
+include::_ugfun_class-structure_properties-vs-parameters.adoc[leveloffset=+1]
+
+include::_ugfun_class-structure_domain-services.adoc[leveloffset=+1]
+
+
+
+

http://git-wip-us.apache.org/repos/asf/isis/blob/480d6ff2/adocs/documentation/src/main/asciidoc/guides/ugfun/_ugfun_class-structure_actions.adoc
----------------------------------------------------------------------
diff --git 
a/adocs/documentation/src/main/asciidoc/guides/ugfun/_ugfun_class-structure_actions.adoc
 
b/adocs/documentation/src/main/asciidoc/guides/ugfun/_ugfun_class-structure_actions.adoc
new file mode 100644
index 0000000..613cbb9
--- /dev/null
+++ 
b/adocs/documentation/src/main/asciidoc/guides/ugfun/_ugfun_class-structure_actions.adoc
@@ -0,0 +1,264 @@
+[[_ugfun_class-structure_actions]]
+= Actions
+:Notice: 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.
+:_basedir: ../../
+:_imagesdir: images/
+
+
+
+While xref:../ugfun/ugfun.adoc#_ugfun_class-structure_properties[properties] 
and xref:../ugfun/ugfun.adoc#_ugfun_class-structure_collections[collections] 
define the state held by a domain object (its "know what" responsibilities), 
actions define the object's behaviour (its "know how-to" responsibilities).
+
+An application whose domain objects have only/mostly "know-what" 
responsibilities is pretty dumb: it requires that the end-user know the 
business rules and doesn't modify the state of the domain objects such that 
they are invalid (for example, an "end date" being before a "start date").
+Such applications are often called CRUD applications 
(create/read/update/delete).
+
+In more complex domains, it's not realistic/feasible to expect the end-user to 
have to remember all the different business rules that govern the valid states 
for each domain object.
+So instead actions allow those business rules to be encoded programmatically.
+An Apache Isis application doesn't try to constrain the end-user as to way in 
which they interact with the user (it doesn't attempt to define a rigid 
business process) but it does aim to ensure that business rule invariants are 
maintained, that is that business objects aren't allowed to go into an invalid 
state.
+
+For simple domain applications, you may want to start prototyping only with 
properties, and only later introduce actions (representing the most common 
business operations).
+But an alternative approach, recommended for more complex applications, is 
actually to start the application with all properties non-editable.
+Then, as the end-user requires the ability to modify some state, there is a 
context in which to ask the question "why does this state need to change?" and 
"are their any side-effects?" (ie, other state that changes at the same time, 
or other behaviour that should occur).
+If the state change is simple, for example just being able to correct an 
invalid address, or adding a note or comment, then that can probably be 
modelled as a simple editable property.
+But if the state change is more complex, then most likely an action should be 
used instead.
+
+
+[[__ugfun_class-structure_actions_defining-actions]]
+== Defining actions
+
+Broadly speaking, actions are all the `public` methods that are not getters or 
setters which represent properties or collections.
+This is a slight simplification; there are a number of other method prefixes 
(such as `hide` or `validate`) that represent 
xref:../ugfun/ugfun.adoc#_ugfun_business-rules[business rules]); these also not 
treated as actions.
+And, any method that are annotated with `@Programmatic` will also be excluded.
+But by and large, all other methods such as `placeOrder(...)` or 
`approveInvoice(...)` will be treated as actions.
+
+For example:
+
+[source,java]
+----
+@Action(semantics=SemanticsOf.IDEMPOTENT)       // <1>
+public ShoppingBasket addToBasket(
+        Product product,
+        @ParameterLayout(named="Quantity")      // <2>
+        int quantity
+        ) {
+    ...
+    return this;
+}
+----
+<1> `@Action` annotation is optional but used to specify additional domain 
semantics (such as being idempotent).
+<2> The names of action parameters (as rendered in the UI) will by default be 
the parameter types, not the paramter names.
+For the `product` parameter this is reasonable, but not so for the `quantity` 
parameter (which would by default show up with a name of "int".
+The `@ParameterLayout` annotation provides a UI hint to the framework.
+
+[TIP]
+====
+The (non-ASF) Isis addons' 
http://github.com/isisaddons/isis-metamodel-paraname8[paraname8] metamodel 
extension allows the parameter name to be used in the UI, rather than the type.
+====
+
+
+[[__ugfun_class-structure_actions_reference-parameter-types]]
+== (Reference) Parameter types
+
+Parameter types can be value types or reference types.
+In the case of primitive types, the end-user can just enter the value directly 
through the parameter field.
+In the case of reference types however (such as `Product`), a drop-down must 
be provided from which the end-user to select.
+This is done using either a supporting 
xref:../rgcms/rgcms.adoc#_rgcms_methods_prefixes_choices[`choices`] or 
xref:../rgcms/rgcms.adoc#_rgcms_methods_prefixes_autoComplete[`autoComplete`] 
method.
+The "choices" is used when there is a limited set of options, while 
"autoComplete" is used when there are large set of options such that the 
end-user must provide some characters to use for a search.
+
+For example, the `addToBasket(...)` action shown above might well have a :
+
+[source,java]
+----
+@Action(semantics=SemanticsOf.IDEMPOTENT)
+public ShoppingBasket addToBasket(
+        Product product,
+        @ParameterLayout(named="Quantity")
+        int quantity
+        ) {
+    ...
+    return this;
+}
+public List<Product> autoComplete0AddToBasket(              // <1>
+    @MinLength(3)                                           // <2>
+    String searchTerm) {
+    return productRepository.find(searchTerm);              // <3>
+}
+@javax.inject.Inject
+ProductRepository productRepository;
+----
+<1> Supporting `autoComplete` method.
+The "0" in the name means that this corresponds to parameter 0 of the 
"addToBasket" action (ie `Product`).
+It is also required to return a Collection of that type.
+<2> The xref:../rgant/rgant.adoc#_rgant_MinLength[`@MinLength`] annotation 
defines how many characters the end-user must enter before performing a search.
+<3> The implementation delegates to an injected repository service.  This is 
typical.
+
+Note that it is also valid to define "choices" and "autoComplete" for value 
types (such as `quantity`, above); it just isn't as common to do so.
+
+[[__ugfun_class-structure_actions_reference-parameter-types_removing-boilerplate]]
+=== Removing boilerplate
+
+To save having to define an `autoCompleteNXxx(...)` method everywhere that a 
reference to a particular type (such as `Product`) appears as an action 
parameter, it is also possible to use the `@DomainObject` annotation on 
`Product` itself:
+
+[source,java]
+----
+@DomainObject(
+    autoCompleteRepository=ProductRepository.class          // <1>
+    autoCompleteAction="find"                               // <2>
+)
+public class Product ... {
+    ...
+}
+----
+<1> Whenever an action parameter requiring a `Product` is defined, provide an 
autoComplete drop-down automatically
+<2> Use the "find" method of `ProductRepository` (rather than the default name 
of "autoComplete")
+
+(As noted above), if the number of available instances of the reference type 
is a small number (in other words, all of which could comfortably be shown in a 
drop-down) then instead the `choicesNXxx()` supporting method can be used.
+This too can be avoided by annotating the referenced class.
+
+For example, suppose we have an action to specify the `PaymentMethodType`, 
where there are only 10 or so such (Visa, Mastercard, Amex, Paypal etc).
+We could define this as:
+
+[source,java]
+----
+public Order payUsing(PaymentMethodType type) {
+    ...
+}
+----
+
+where `PaymentMethodType` would be annotated using:
+
+[source,java]
+----
+@DomainObject(
+    bounded=true                            // <1>
+)
+public class PaymentMethodType ... {
+    ...
+}
+----
+<1> only a small (ie "bounded") number of instances available, meaning that 
the framework should render all in a drop-down.
+
+
+[[__ugfun_class-structure_actions_collection-parameter-types]]
+== Collection Parameter types
+
+Action parameters can also be collections of values (for example 
`List<String>`), or can be collections of references (such as `List<Customer>`).
+
+For example:
+
+[source,java]
+----
+@Action(semantics=SemanticsOf.IDEMPOTENT)
+public ShoppingBasket addToBasket(
+        List<Product> products,
+        @ParameterLayout(named="Quantity") int quantity
+        ) {
+    ...
+    return this;
+}
+public List<Product> autoComplete0AddToBasket(@MinLength(3) String searchTerm) 
{
+    return ...
+}
+----
+
+As the example suggests, any collection parameter type must provide a way to 
select items, either by way of a "choices" or "autoComplete" supporting method 
or alternatively defined globally using 
xref:../rgant/rgant.adoc#_rgant_DomainObject[`@DomainObject`] on the referenced 
type (described 
xref:../ugfun/ugfun.adoc#__ugfun_class-structure_actions_reference-parameter-types_removing-boilerplate[above]).
+
+
+[[__ugfun_class-structure_actions_optional-parameters]]
+== Optional Parameters
+
+Whereas the 
xref:../ugfun/ugfun.adoc#__ugfun_class-structure_properties_optional-properties[optionality
 of properties] is defined using 
xref:../rgant/rgant.adoc#_rgant_Column_allowsNull[`@javax.jdo.annotations.Column#allowsNull()`],
 that JDO annotation cannot be applied to parameter types.
+Instead, either the xref:../rgant/rgant.adoc#_rgant_Nullable[`@Nullable`] 
annotation or the 
xref:../rgant/rgant.adoc#_rgant_Parameter_optionality[`@Parameter#optionality()`]
  annotation/attribute is used.
+
+For example:
+
+[source,java]
+----
+@javax.jdo.annotations.Column(allowsNull="true")                // <1>
+@lombok.Getter @lombok.Setter
+private LocalDate shipBy;
+
+public Order invoice(
+                PaymentMethodType paymentMethodType,
+                @Nullable                                       // <2>
+                @ParameterLayout(named="Ship no later than")
+                LocalDate shipBy) {
+    ...
+    setShipBy(shipBy)
+    return this;
+}
+----
+<1> Specifies the property is optional.
+<2> Specifies the corresponding parameter is optional.
+
+See also 
xref:../ugfun/ugfun.adoc#_ugfun_class-structure_properties-vs-parameters[properties
 vs parameters].
+
+[[__ugfun_class-structure_actions_string-parameters]]
+== ``String`` Parameters (Length)
+
+Whereas the 
xref:../ugfun/ugfun.adoc#__ugfun_class-structure_properties_datatypes_strings[length
 of string properties] is defined using 
xref:../rgant/rgant.adoc#_rgant_Column_length[`@javax.jdo.annotations.Column#length()`],
 that JDO annotation cannot be applied to parameter types.
+Instead, the 
xref:../rgant/rgant.adoc#_rgant_Parameter_maxLength[`@Parameter#maxLength()`] 
annotation/attribute is used.
+
+For example:
+
+[source,java]
+----
+@javax.jdo.annotations.Column(length=50)                // <1>
+@lombok.Getter @lombok.Setter
+private String firstName;
+
+@javax.jdo.annotations.Column(length=50)
+@lombok.Getter @lombok.Setter
+private String lastName;
+
+public Customer updateName(
+                @Parameter(maxLength=50)                // <2>
+                @ParameterLayout(named="First name")
+                String firstName,
+                @Parameter(maxLength=50)
+                @ParameterLayout(named="Last name")
+                String lastName) {
+    setFirstName(firstName);
+    setLastName(lastName);
+    return this;
+}
+----
+<1> Specifies the property length using the JDO 
xref:../rgant/rgant.adoc#_rgant_Column_length[`@Column#length()`] annotation
+<2> Specifies the parameter length using the (Apache Isis) 
xref:../rgant/rgant.adoc#_rgant_Parameter_maxLength[`@Parameter#maxLength()`] 
annotation
+
+[IMPORTANT]
+====
+Incidentally, note in the above example that the new value is assigned to the 
properties using the setter methods; the action does not simply set the 
instance field directly.
+This is important, because it allows JDO/DataNucleus to keep track that this 
instance variable is "dirty" and so needs flushing to the database table before 
the transaction completes.
+====
+
+See also 
xref:../ugfun/ugfun.adoc#_ugfun_class-structure_properties-vs-parameters[properties
 vs parameters].
+
+[[__ugfun_class-structure_actions_bigdecimal-parameters]]
+== ``BigDecimal``s (Precision)
+
+Whereas the 
xref:../ugfun/ugfun.adoc#__ugfun_class-structure_properties_datatypes_bigdecimals[precision
 of BigDecimal properties] is defined using 
xref:../rgant/rgant.adoc#_rgant_Column_scale[`@javax.jdo.annotations.Column#scale()`],
 that JDO annotation cannot be applied to parameter types.
+Instead, the 
xref:../rgant/rgant.adoc#_rgant_Digits_fraction[`@javax.validation.constraints.Digits#fraction()`]
 annotation/attribute is used.
+
+For example:
+
+[source,java]
+----
+@javax.jdo.annotations.Column(scale=2)                              // <1>
+@lombok.Getter @lombok.Setter
+private BigDecimal discountRate;
+
+public Order updateDiscount(
+                @javax.validation.constraints.Digits(fraction=2)    // <2>
+                @ParameterLayout(named="Discount rate")
+                String discountRate) {
+    setDiscountRate(discountRate);
+    return this;
+}
+----
+<1> Specifies the property precision using 
xref:../rgant/rgant.adoc#_rgant_Column_scale[`@Column#scale()`]
+<2> Specifies the corresponding parameter precision using 
xref:../rgant/rgant.adoc#_rgant_Digits_fraction[`@Digits#fraction()`].
+
+See also 
xref:../ugfun/ugfun.adoc#_ugfun_class-structure_properties-vs-parameters[properties
 vs parameters].
+
+
+

http://git-wip-us.apache.org/repos/asf/isis/blob/480d6ff2/adocs/documentation/src/main/asciidoc/guides/ugfun/_ugfun_class-structure_collections.adoc
----------------------------------------------------------------------
diff --git 
a/adocs/documentation/src/main/asciidoc/guides/ugfun/_ugfun_class-structure_collections.adoc
 
b/adocs/documentation/src/main/asciidoc/guides/ugfun/_ugfun_class-structure_collections.adoc
new file mode 100644
index 0000000..a3e09da
--- /dev/null
+++ 
b/adocs/documentation/src/main/asciidoc/guides/ugfun/_ugfun_class-structure_collections.adoc
@@ -0,0 +1,121 @@
+[[_ugfun_class-structure_collections]]
+= Collections
+:Notice: 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.
+:_basedir: ../../
+:_imagesdir: images/
+
+
+A collection is an instance variable of a domain object, of a collection type 
that holds references to other domain objects.
+For example, a `Customer` may have a collection of ``Order``s).
+
+It's ok for a 
xref:../ugfun/ugfun.adoc#__ugfun_class-structure_class-definition_entities[domain
 entity] to reference another domain entity, and for a 
xref:../ugfun/ugfun.adoc#__ugfun_class-structure_class-definition_view-models[view
 model] to reference both view model and domain entities.
+However, it isn't valid for a domain entity to hold a persisted reference to 
view model (DataNucleus will not know how to persist that view model).
+
+Formally speaking, a collection is simply a regular JavaBean getter, returning 
a collection type (subtype of `java.util.Collection`).
+Most collections (those that are modifiable) will also have a setter and (if 
persisted) a backing instance field.
+And collections properties will also have a number of annotations:
+
+* Apache Isis defines its own set own `@Collection` annotation for capturing 
domain semantics.
+It also provides a `@CollectionLayout` for UI hints (though the information in 
this annotation may instead be provided by a supplementary 
xref:../ugvw/ugvw.adoc#_ugvw_layout[`.layout.xml`] file
+
+* the collections of domain entities are often annotated with various 
JDO/DataNucleus annotations, most notable `javax.jdo.annotations.Persistent`.
+This and other annotations can be used to specify if the association is 
bidirectional, and whether to define a link table or not to hold foreign key 
columns.
+
+* for the collections of view models, then JAXB annotations such as 
`@javax.xml.bind.annotation.XmlElementWrapper` and 
`@javax.xml.bind.annotation.XmlElement` will be present
+
+Apache Isis recognises some of these annotations for JDO/DataNucleus and JAXB 
and infers some domain semantics from them (for example, the maximum allowable 
length of a string property).
+
+Unlike xref:../ugfun/ugfun.adoc#_ugfun_class-structure_properties[properties], 
the framework (at least, the xref:../ugvw/ugvw.adoc[Wicket viewer]) does not 
allow collections to be "edited".
+Instead, xref:../ugfun/ugfun.adoc#_ugfun_class-structure_actions[action]s can 
be written that will modify the contents of the collection as a side-effect.
+For example, a `placeOrder(...)` action will likely add an `Order` to the 
`Customer#orders` collection.
+
+Since writing getter and setter methods adds quite a bit of boilerplate, it's 
common to use link:https://projectlombok.org/[Project Lombok] to code generate 
these methods at compile time (using Java's annotation processor) simply by 
adding the `@lombok.Getter` and `@lombok.Setter` annotations to the field.
+
+
+
+[[__ugfun_class-structure_collections_mapping-bidir-1m]]
+== Mapping bidir 1:m
+
+Bidirectional one-to-many collections are one of the most common types of 
associations between two entities.
+In the parent object, the collection can be defined as:
+
+[source,java]
+----
+public class ParentObject
+        implements Comparable<ParentObject>{
+
+    @javax.jdo.annotations.Persistent(
+        mappedBy = "parent",                                                // 
<1>
+        dependentElement = "false"                                          // 
<2>
+    )
+    @Collection                                                             // 
<3>
+    @lombok.Getter @lombok.Setter
+    private SortedSet<ChildObject> children = new TreeSet<ChildObject>();   // 
<4>
+
+}
+----
+<1> indicates a bidirectional association; the foreign key pointing back to 
the `Parent` will be in the table for `ChildObject`
+<2> disable cascade delete
+<3> (not actually required in this case, because no attributes are set, but 
acts as a useful reminder that this collection will be rendered in the UI by 
Apache Isis)
+<4> uses a `SortedSet` (as opposed to some other collection type; discussion 
below)
+
+while in the child object you will have:
+
+[source,java]
+----
+public class ChildObject
+        implements Comparable<ChildObject> {    // <1>
+
+    @javax.jdo.annotations.Column(
+        allowsNull = "false"                    // <2>
+    )
+    @Property(editing = Editing.DISABLED)       // <3>
+    @lombok.Getter @lombok.Setter
+    private ParentObject parent;
+}
+----
+<1> implements `Comparable` because is mapped using a `SortedSet`
+<2> mandatory; every child must reference its parent
+<3> cannot be edited directly
+
+Generally speaking you should use `SortedSet` for collection types (as opposed 
to `Set`, `List` or `Collection`).
+JDO/Datanucleus does support the mapping of these other types, but RDBMS are 
set-oriented, so using this type introduces the least friction.
+
+[NOTE]
+====
+For further details on mapping associations, see the JDO/DataNucleus 
documentation for 
link:http://www.datanucleus.org/products/accessplatform_4_1/jdo/orm/one_to_many.html[one-to-many]
 associations, 
link:http://www.datanucleus.org/products/accessplatform_4_1/jdo/orm/many_to_one.html[many-to-one]
 associations, 
link:http://www.datanucleus.org/products/accessplatform_4_1/jdo/orm/many_to_many.html[many-to-many]
 associations, and so on.
+
+Also, while JDO/DataNucleus itself supports `java.util.Map` as a collection 
type, this is not supported by Apache Isis.
+If you do wish to use this collection type, then annotate the getter with 
`@Programmatic` so that it is ignored by the Apache Isis framework.
+====
+
+
+
+== Value vs Reference Types
+
+Apache Isis can (currently) only provide a UI for collections of references.
+While you can use DataNucleus to persist collections/arrays of value types, 
such properties must be annotated as `@Programmatic` so that they are ignored 
by Apache Isis.
+
+If you want to visualize an array of value types in Apache Isis, then one 
option is to wrap value in a view model, as explained 
xref:../ugfun/ugfun.adoc#_ugbtb_hints-and-tips_simulating-collections-of-values[elsewhere].
+
+
+
+[[__ugfun_class-structure_collections_derived-collections]]
+== Derived Collections
+
+A derived collection is simply a getter (no setter) that returns a 
`java.util.Collection` (or subtype).
+
+While derived properties and derived collections typically "walk the graph" to 
associated objects, there is nothing to prevent the returned value being the 
result of invoking a repository (domain service) action.
+
+For example:
+
+[source,java]
+----
+public class Customer {
+    ...
+    public List<Order> getMostRecentOrders() {
+        return orderRepo.findMostRecentOrders(this, 5);
+    }
+}
+----
+

http://git-wip-us.apache.org/repos/asf/isis/blob/480d6ff2/adocs/documentation/src/main/asciidoc/guides/ugfun/_ugfun_class-structure_domain-services.adoc
----------------------------------------------------------------------
diff --git 
a/adocs/documentation/src/main/asciidoc/guides/ugfun/_ugfun_class-structure_domain-services.adoc
 
b/adocs/documentation/src/main/asciidoc/guides/ugfun/_ugfun_class-structure_domain-services.adoc
new file mode 100644
index 0000000..ce7c3e7
--- /dev/null
+++ 
b/adocs/documentation/src/main/asciidoc/guides/ugfun/_ugfun_class-structure_domain-services.adoc
@@ -0,0 +1,155 @@
+[[_ugfun_class-structure_domain-services]]
+= Domain Services
+:Notice: 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.
+:_basedir: ../../
+:_imagesdir: images/
+
+
+This section looks at the programming conventions of writing your own domain 
services.
+
+
+== Typical Implementation
+
+Domain services are generally singletons that are automatically injected into 
other domain services.
+A very common usage is as a repository (to find/locate existing entities) or 
as a factory (to create new instances of entities).
+But services can also be exposed in the UI as top-level menus; and services 
are also used as a bridge to access technical resources (eg rendering a 
document object as a PDF).
+
+The Apache Isis framework itself also provides a large number of number of 
domain services, catalogued in the xref:../rgsvc/rgsvc.adoc#[Domain Services 
Reference Guide].
+Some of these are APIs (intended to be called by your application's own domain 
objects) and some are SPIs (implemented by your application and called by the 
framework, customising the way it works).
+
+The following is a typical menu service:
+
+[source,java]
+----
+@DomainService(                                                 // <1>
+        nature = NatureOfService.VIEW_MENU_ONLY
+)
+@DomainServiceLayout(                                           // <2>
+        named = "Simple Objects",
+        menuOrder = "10"
+)
+public class SimpleObjectMenu {
+
+    ...
+
+    @Action(semantics = SemanticsOf.SAFE)
+    @ActionLayout(bookmarking = BookmarkPolicy.AS_ROOT)
+    @MemberOrder(sequence = "2")
+    public List<SimpleObject> findByName(                       // <3>
+            @ParameterLayout(named="Name")
+            final String name
+    ) {
+        return simpleObjectRepository.findByName(name);
+    }
+
+    @javax.inject.Inject
+    SimpleObjectRepository simpleObjectRepository;              // <4>
+}
+----
+<1> The (Apache Isis) `@DomainService` annotation is used to identify the 
class as a domain service.
+Apache Isis scans the classpath looking for classes with this annotation, so 
there very little configuration other than to tell the framework which packages 
to scan underneath.
+The `VIEW_MENU_ONLY` nature indicates that this service's actions should be 
exposed as menu items.
+<2> The (Apache Isis) `@DomainServiceLayout` annotation provides UI hints.
+In the example above the menu is named "Simple Objects" (otherwise it would 
have defaulted to "Simple Object Menu", based on the class name, while the 
`menuOrder` attribute determines the order of the menu with respect to other 
menu services.
+<3> The `findByName` method is annotated with various Apache Isis annotations 
(`@Action`, `@ActionLayout` and `@MemberOrder`) and is itself rendered in the 
UI as a "Find By Name" menu item underneath the "Simple Objects" menu.
+The implementation delegates to an `SimpleObjectRepository` service, which is 
injected.
+<4> The `javax.inject.Inject` annotation instructs Apache Isis framework to 
inject the `SimpleObjectRepository` service into this domain object.
+The framework can inject into not just other domain services but will also 
automatically into domain entities and view models.
+There is further discussion of service injection 
xref:../ugfun/ugfun.adoc#_ugfun_class-structure_inject-services[below].
+
+
+
+
+== Scoped services
+
+By default all domain services are considered to be singletons, and 
thread-safe.
+
+Sometimes though a service's lifetime is applicable only to a single request; 
in other words it is request-scoped.
+
+The CDI annotation 
xref:../rgant/rgant.adoc#_rgant-RequestScoped[`@javax.enterprise.context.RequestScoped`]
 is used to indicate this fact:
+
+[source,java]
+----
+@javax.enterprise.context.RequestScoped
+public class MyService extends AbstractService {
+    ...
+}
+----
+
+The framework provides a number of request-scoped services, include a 
xref:../rgsvc/rgsvc.adoc#_rgsvc_api_Scratchpad[`Scratchpad`] service query 
results caching through the 
xref:../rgsvc/rgsvc.adoc#_rgsvc_api_QueryResultsCache[`QueryResultsCache`], and 
support for co-ordinating bulk actions through the 
xref:../rgsvc/rgsvc.adoc#_rgsvc_api_ActionInvocationContext[`ActionInvocationContext`]
 service.  See the xref:../rgsvc/rgsvc.adoc[domain services] reference guide 
for further details.
+
+
+
+
+== Registering domain services
+
+The easiest way to register domain services is using 
xref:../rgcms/rgcms.adoc#_rgcms_classes_AppManifest-bootstrapping[`AppManifest`]
 to specify the modules
+which contain 
xref:../rgant/rgant.adoc#_rgant-DomainService[`@DomainService`]-annotated 
classes.
+
+For example:
+
+[source,ini]
+----
+public class MyAppManifest implements AppManifest {
+    public List<Class<?>> getModules() {
+        return Arrays.asList(
+                ToDoAppDomainModule.class,
+                ToDoAppFixtureModule.class,
+                ToDoAppAppModule.class,
+                org.isisaddons.module.audit.AuditModule.class);
+    }
+    ...
+}
+----
+
+will load all services in the packages underneath the four modules listed.
+
+An alternative (older) mechanism is to registered domain services in the 
`isis.properties` configuration file, under `isis.services` key (a 
comma-separated list); for example:
+
+[source,ini]
+----
+isis.services = com.mycompany.myapp.employee.Employees\,
+                com.mycompany.myapp.claim.Claims\,
+                ...
+----
+
+This will then result in the framework instantiating a single instance of each 
of the services listed.
+
+If all services reside under a common package, then the `isis.services.prefix` 
can specify this prefix:
+
+[source,ini]
+----
+isis.services.prefix = com.mycompany.myapp
+isis.services = employee.Employees,\
+                claim.Claims,\
+                ...
+----
+
+This is quite rare, however; you will often want to use default 
implementations of domain services that are provided by the framework and so 
will not reside under this prefix.
+
+Examples of framework-provided services (as defined in the applib) include 
clock, auditing, publishing, exception handling, view model support, 
snapshots/mementos, and user/application settings management; see the 
xref:../rgsvc/rgsvc.adoc[domain services] reference guide for further details.
+
+
+
+== Initialization
+
+Services can optionally declare lifecycle callbacks to initialize them (when 
the app is deployed) and to shut them down (when the app is undeployed).
+
+An Apache Isis session _is_ available when initialization occurs (so services 
can interact with the object store, for example).
+
+
+The framework will call any `public` method annotated with 
xref:../rgant/rgant.adoc#_rgant-PostConstruct[`@PostConstruct`] with either no 
arguments of an argument of type `Map<String,String>`
+
+or
+
+In the latter case, the framework passes in the configuration 
(`isis.properties` and any other component-specific configuration files).
+
+
+Shutdown is similar; the framework will call any method annotated with 
xref:../rgant/rgant.adoc#_rgant-PreDestroy[`@PreDestroy`].
+
+
+
+== The getId() method
+
+Optionally, a service may provide a 
xref:../rgcms/rgcms.adoc#_rgcms_methods_reserved_getId[`getId()`] method.  This 
method returns a logical identifier for a service, independent of its 
implementation.
+

http://git-wip-us.apache.org/repos/asf/isis/blob/480d6ff2/adocs/documentation/src/main/asciidoc/guides/ugfun/_ugfun_class-structure_inject-services.adoc
----------------------------------------------------------------------
diff --git 
a/adocs/documentation/src/main/asciidoc/guides/ugfun/_ugfun_class-structure_inject-services.adoc
 
b/adocs/documentation/src/main/asciidoc/guides/ugfun/_ugfun_class-structure_inject-services.adoc
new file mode 100644
index 0000000..fb09fe1
--- /dev/null
+++ 
b/adocs/documentation/src/main/asciidoc/guides/ugfun/_ugfun_class-structure_inject-services.adoc
@@ -0,0 +1,103 @@
+[[_ugfun_class-structure_inject-services]]
+= Injecting services
+:Notice: 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.
+:_basedir: ../../
+:_imagesdir: images/
+
+
+Apache Isis autowires (automatically injects) domain services into each 
entity, as well as into the domain services themselves, using either method 
injection or field injection.
+The framework defines many additional services (such as 
xref:../rgsvc/rgsvc.adoc#_rgsvc_api_RepositoryService[`RepositoryService`]); 
these are injected in exactly the same manner.
+
+Sometimes there may be multiple services that implement a single type.
+This is common for example for SPI service, whereby one module defines an SPI 
service, and other module(s) in the application implement that service.
+To support this, the framework also allows lists of services to be injected.
+
+When there are multiple service implementations of a given type, the framework 
will inject the service with highest priority, as defined through 
xref:../rgant/rgant.adoc#_rgant_DomainService_menuOrder[`@DomainService#menuOrder()`]
 (even for domain services that are not menus), lowest first.
+If a list of services is injected, then that list will be ordered according to 
`menuOrder`, again lowest first.
+
+
+
+[NOTE]
+====
+Isis currently does _not_ support qualified injection of services; the domain 
service of each type must be distinct from any other.
+
+If you find a requirement to inject two instances of type `SomeService`, say, 
then the work-around is to create trivial subclasses `SomeServiceA` and 
`SomeServiceB` and inject these instead.
+====
+
+
+== Field Injection
+
+Field injection is recommended, using the `@javax.inject.Inject` annotation.
+For example:
+
+[source,java]
+----
+public class Customer {
+    ...
+    @javax.inject.Inject
+    OrderRepository orderRepository;
+}
+----
+
+To inject a list of services, use:
+
+[source,java]
+----
+public class DocumentService {
+    ...
+    @javax.inject.Inject
+    List<PaperclipFactory> paperclipFactories;
+}
+----
+
+We recommend using default rather than `private` visibility so that the field 
can be mocked out within unit tests (placed in the same package as the code 
under test).
+
+
+
+
+== Method Injection
+
+The framework also supports two forms of method injection.
+All that is required to inject a service into a entity/service is to provide 
an appropriate method or field.
+The name of the method does not matter, only that it is prefixed either `set` 
or `inject`, is public, and has a single parameter of the correct type.
+
+For example:
+
+[source,java]
+----
+public class Customer {
+    private OrderRepository orderRepository;
+    public void setOrderRepository(OrderRepository orderRepository) {
+        this.orderRepository = orderRepository;
+    }
+    ...
+}
+----
+
+or alternatively, using 'inject' as the prefix:
+
+[source,java]
+----
+public class Customer {
+    private OrderRepository orderRepository;
+    public void injectOrderRepository(OrderRepository orderRepository) {
+        this.orderRepository = orderRepository;
+    }
+    ...
+}
+----
+
+Lists of services can be injected in a similar manner.
+
+Note that the method name can be anything; it doesn't need to be related to 
the type being injected.
+
+
+== Constructor injection
+
+Simply to note that constructor injection is _not_ supported by Apache Isis 
(and is unlikely to be, because the JDO specification for entities requires a 
no-arg constructor).
+
+
+
+
+
+

http://git-wip-us.apache.org/repos/asf/isis/blob/480d6ff2/adocs/documentation/src/main/asciidoc/guides/ugfun/_ugfun_class-structure_properties-vs-parameters.adoc
----------------------------------------------------------------------
diff --git 
a/adocs/documentation/src/main/asciidoc/guides/ugfun/_ugfun_class-structure_properties-vs-parameters.adoc
 
b/adocs/documentation/src/main/asciidoc/guides/ugfun/_ugfun_class-structure_properties-vs-parameters.adoc
new file mode 100644
index 0000000..a0a926a
--- /dev/null
+++ 
b/adocs/documentation/src/main/asciidoc/guides/ugfun/_ugfun_class-structure_properties-vs-parameters.adoc
@@ -0,0 +1,38 @@
+[[_ugfun_class-structure_properties-vs-parameters]]
+= Properties vs Parameters
+:Notice: 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.
+:_basedir: ../../
+:_imagesdir: images/
+
+
+In many cases the value types of properties and of action parameters align.
+For example, a `Customer` entity might have a `surname` property, and there 
might also be corresponding `changeSurname`.
+Ideally we want the surname property and surname action parameter to use the 
same value type.
+
+Since JDO/DataNucleus handles persistence, its annotations are requiredto 
specify semantics such as optionality or maximum length on properties.
+However, they cannot be applied to action parameters.
+It is therefore necessary to use Apache Isis' equivalent annotations for 
action parameters.
+
+The table below summarises the equivalence of some of the most common cases.
+
+.Comparing annotations of Properties vs Action Parameters
+[cols="2,3,3", options="header"]
+|===
+|value type/semantic
+|(JDO) property
+|action parameter
+
+|string (length)
+|`@javax.jdo.annotations.Column(length=50)`
+|`@javax.jdo.annotations.Parameter(maxLength=50)`
+
+|big decimal (precision)
+|`@javax.jdo.annotations.Column(scale=2)`
+|`@javax.validation.constraints.Digits(fraction=2)`
+
+|optionality
+|`@Column(allowsNull="true")`
+|`@Nullable` or `ParameterLayout(optionality=Optionality.OPTIONAL`) (also 
`@Optional`, now deprecated)
+|===
+
+

Reply via email to