http://git-wip-us.apache.org/repos/asf/isis/blob/480d6ff2/adocs/documentation/src/main/asciidoc/guides/ugfun/_ugfun_class-structure_properties.adoc
----------------------------------------------------------------------
diff --git 
a/adocs/documentation/src/main/asciidoc/guides/ugfun/_ugfun_class-structure_properties.adoc
 
b/adocs/documentation/src/main/asciidoc/guides/ugfun/_ugfun_class-structure_properties.adoc
new file mode 100644
index 0000000..540ada1
--- /dev/null
+++ 
b/adocs/documentation/src/main/asciidoc/guides/ugfun/_ugfun_class-structure_properties.adoc
@@ -0,0 +1,411 @@
+[[_ugfun_class-structure_properties]]
+= Property
+: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 property is an instance variable of a domain object, of a scalar type, that 
holds some state about either a 
xref:../ugfun/ugfun.adoc#__ugfun_class-structure_class-definition_entities[domain
 entity] or a 
xref:../ugfun/ugfun.adoc#__ugfun_class-structure_class-definition_view-models[view
 model].
+
+For example, a ``Customer``'s `firstName` would be a property, as would their 
`accountCreationDate` that they created their account.
+All properties have at least a "getter" method, and most properties have also 
a "setter" method (meaning that they are mutable).
+Properties that do _not_ have a setter method are derived properties, and so 
are not persisted.
+
+Formally speaking, a property is simply a regular JavaBean getter, returning a 
scalar value recognized by the framework.
+Most properties (those that are editable/modifiable) will also have a setter 
and (if persisted) a backing instance field.
+And most properties will also have a number of annotations:
+
+* Apache Isis defines its own set own `@Property` annotation for capturing 
domain semantics.
+It also provides a `@PropertyLayout` 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 properties of domain entities are often annotated with the 
JDO/DataNucleus `@javax.jdo.annotations.Column` annotation.
+For property references, there may be other annotations to indicate whether 
the reference is bidirectional.
+It's also possible (using annotations) to define a link table to hold foreign 
key columns.
+
+* for the properties of view models, then JAXB annotations such as 
`@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).
+
+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.
+The 
xref:guides/ugfun.adoc#_ugfun_getting-started_simpleapp-archetype[SimpleApp 
archetype] uses this approach.
+
+
+[[__ugfun_class-structure_properties_value-vs-reference-types]]
+== Value vs Reference Types
+
+Properties can be either a value type (strings, int, date and so on) or be a 
reference to another object (for example, an `Order` referencing the `Customer` 
that placed it).
+
+For example, to map a string value type:
+
+[source,java]
+----
+@lombok.Getter @lombok.Setter       // <1>
+private String notes;
+----
+<1> using link:https://projectlombok.org/[Project Lombok] annotations to 
reduce boilerplate
+
+You could also add the `@Property` annotation if you wished:
+
+[source,java]
+----
+@Property
+@lombok.Getter @lombok.Setter
+private String notes;
+----
+
+Although in this case it is not required (none of its attributes have been 
set).
+
+Or to map a reference type:
+
+[source,java]
+----
+@lombok.Getter @lombok.Setter
+private Customer customer;
+----
+
+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).
+
+[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.
+====
+
+For domain entities, the annotations for mapping value types tend to be 
different for properties vs action parameters, because JDO annotations are only 
valid on properties.
+The table in the 
xref:../ugfun/ugfun.adoc#_ugfun_class-structure_properties-vs-parameters[Properties
 vs Parameters] section provides a handy reference of each.
+
+
+[[__ugfun_class-structure_properties_optional-properties]]
+== Optional Properties
+
+(For domain entities) JDO/DataNucleus' default is that a property is assumed 
to be mandatory if it is a primitive type (eg `int`, `boolean`), but optional 
if a reference type (eg `String`, `BigDecimal` etc).
+To override optionality in JDO/DataNucleus the `@Column(allowsNull="...")` 
annotations is used.
+
+Apache Isis on the other hand assumes that all properties (and action 
parameters, for that matter) are mandatory, not optional.
+These defaults can also be overridden using Apache Isis' own annotations, 
specifically `@Property(optionality=...)`, or (because it's much less verbose) 
using `@javax.annotation.Nullable`.
+
+These different defaults can lead to incompatibilities between the two 
frameworks.
+To counteract that, Apache Isis also recognizes and honours JDO's 
`@Column(allowsNull=...)`.
+
+For example, you can write:
+
+[source,java]
+----
+@javax.jdo.annotations.Column(allowsNull="true")
+@lombok.Getter @lombok.Setter
+private LocalDate date;
+----
+
+rather than the more verbose:
+
+[source,java]
+----
+@javax.jdo.annotations.Column(allowsNull="true")
+@Property(optionality=Optionality.OPTIONAL)
+@lombok.Getter @lombok.Setter
+private LocalDate date;
+----
+
+The framework will search for any incompatibilities in optionality (whether 
specified explicitly or defaulted implicitly) between Isis' defaults and 
DataNucleus, and refuse to boot if any are found (fail fast).
+
+[[__ugfun_class-structure_properties_editable-properties]]
+== Editable Properties
+
+Apache Isis provides the capability to allow individual properties to be 
modified.
+This is specified using the `@Property(editing=...)` attribute.
+
+For example:
+
+[source,java]
+----
+@Property(editing = Editing.ENABLED)
+@lombok.Getter @lombok.Setter
+private String notes;
+----
+
+If this is omitted then whether editing is enabled or disabled is defined 
globally, in the `isis.properties` configuration file; see 
xref:../rgcfg/rgcfg.adoc#__rgcfg_configuring-core_isis-objects-editing[reference
 configuration guide] for further details.
+
+
+[[__ugfun_class-structure_properties_ignoring-properties]]
+== Ignoring Properties
+
+By default Apache Isis will automatically render all properties in the 
xref:../ugvw/ugvw.adoc[UI] or in the xref:../ugvro/ugvro.adoc[REST API].
+To get Apache Isis to ignore a property (exclude it from its metamodel), 
annotate the getter using `@Programmatic`.
+
+Similarly, you can tell JDO/DataNucleus to ignore a property using the 
`@javax.jdo.annotations.NotPersistent` annotation.
+This is independent of Apache Isis; in other words that property will still be 
rendered in the UI (unless also annotated with `@Programmatic`).
+
+For view models, you can tell JAXB to ignore a property using the 
`@javax.xml.bind.annotation.XmlTransient` annotation.
+Again, this is independent of Apache Isis.
+
+
+[[__ugfun_class-structure_properties_derived-properties]]
+== Derived Properties
+
+Derived properties are those with a getter but no setter.
+Provided that the property has not been annotated with `@Programmatic`, these 
will still be rendered in the UI, but they will be read-only (not editable) and 
their state will not be persisted.
+
+Subtly different, it is also possible to have non-persisted but still editable 
properties.
+In this case you will need a getter and a setter, but with the getter 
annotated using `@NotPersistent`.
+The implementation of these getters and setters will most likely persist state 
using other properties (which might be hidden from view using `@Programmatic`).
+
+For example:
+
+[source,java]
+----
+@javax.jdo.annotations.NotPersistent
+@Property(editing=Editing.ENABLED)
+public String getAddress() { return addressService.toAddress( getLatLong() ); 
}             // <1>
+public void setAddress(String address) { 
setLatLong(addressService.toLatLong(address)); }
+
+@javax.jdo.annotations.Column
+private String latLong;
+@Programmatic
+public String getLatLong() { return latLong; }                                 
             // <2>
+public void setLatLong(String latLong) { this.latLong = latLong; }
+
+@javax.inject.Inject
+AddressService addressService;                                                 
             // <3>
+----
+<1> the representation of the address, in human readable form, eg "10 Downing 
Street, London, UK"
+<2> the lat/long representation of the address, eg "51.503363;-0.127625"
+<3> an injected service that can convert to/from address and latLong.
+
+
+
+[[__ugfun_class-structure_properties_datatypes]]
+== Data types
+
+This section shows specific considerations for various datatypes, in 
particular how to annotate them for DataNucleus mapping to the persistence 
object store.
+
+
+
+[[__ugfun_class-structure_properties_datatypes_strings]]
+=== ``String``s (Length)
+
+By default JDO/DataNucleus will map string properties to a `VARCHAR(255)`.
+To limit the length, use the `@Column(length=...)` annotation.
+
+For example:
+
+[source,java]
+----
+@javax.jdo.annotations.Column(length=50)
+@lombok.Getter @lombok.Setter
+private String firstName
+----
+
+This is a good example of a case where Apache Isis infers domain semantics 
from the JDO annotation.
+
+
+
+[[__ugfun_class-structure_properties_datatypes-joda-dates]]
+=== JODA Dates
+
+Isis' JDO objectstore bundles DataNucleus' 
http://www.datanucleus.org/documentation/products/plugins.html[built-in 
support] for Joda `LocalDate` and `LocalDateTime` datatypes, meaning that 
entity properties of these types will be persisted as appropriate data types in 
the database tables.
+
+It is, however, necessary to annotate your properties with 
`@javax.jdo.annotations.Persistent`, otherwise the data won't actually be 
persisted.
+See the link:http://db.apache.org/jdo/field_types.html[JDO docs] for more 
details on this.
+
+Moreover, these datatypes are _not_ in the default fetch group, meaning that 
JDO/DataNucleus will perform an additional `SELECT` query for each attribute.
+To avoid this extra query, the annotation should indicate that the property is 
in the default fetch group.
+
+For example, the `ToDoItem` (in the 
https://github.com/isisaddons/isis-app-todoapp[todoapp example app] (not ASF)) 
defines the `dueBy` property as follows:
+
+[source,java]
+----
+@javax.jdo.annotations.Persistent(defaultFetchGroup="true")
+@javax.jdo.annotations.Column(allowsNull="true")
+@Getter @Setter
+private LocalDate dueBy;
+----
+
+
+[[__ugfun_class-structure_properties_datatypes_bigdecimals]]
+=== ``BigDecimal``s (Precision)
+
+Working with `java.math.BigDecimal` properties takes a little care due to 
scale/precision issues.
+
+For example, suppose we have:
+
+[source,java]
+----
+@lombok.Getter @lombok.Setter
+private BigDecimal impact;
+----
+
+JDO/DataNucleus creates, at least with HSQL, the table with the field type as 
NUMERIC(19). No decimal digits are admitted. (Further details 
http://hsqldb.org/doc/2.0/guide/sqlgeneral-chapt.html#sgc_numeric_types[here]).
+
+What this implies is that, when a record is inserted, a log entry similar to 
this one appears:
+
+[source,java]
+----
+INSERT INTO ENTITY(..., IMPACT, ....) VALUES (...., 0.5, ....)
+----
+
+But when that same record is retrieved, the log will show that a value of "0" 
is returned, instead of 0.5.
+
+The solution is to explicitly add the scale to the field like this:
+
+[source,java]
+----
+@javax.jdo.annotations.Column(scale=2)
+@lombok.Getter @lombok.Setter
+private BigDecimal impact;
+----
+
+In addition, you should also set the scale of the `BigDecimal`, using 
`setScale(scale, roundingMode)`.
+
+More information can be found 
http://www.opentaps.org/docs/index.php/How_to_Use_Java_BigDecimal:_A_Tutorial[here]
 and 
http://www.tutorialspoint.com/java/math/bigdecimal_setscale_rm_roundingmode.htm[here].
+
+
+
+[[__ugfun_class-structure_properties_datatypes_blobs]]
+=== ``Blob``s
+
+Apache Isis configures JDO/DataNucleus so that the properties of type 
`org.apache.isis.applib.value.Blob` and `org.apache.isis.applib.value.Clob` can 
also be persisted.
+
+As for 
xref:../ugfun/ugfun.adoc#__ugfun_class-structure_properties_datatypes_joda-dates[Joda
 dates], this requires the `@javax.jdo.annotations.Persistent` annotation.
+However, whereas for dates one would always expect this value to be retrieved 
eagerly, for blobs and clobs it is not so clear cut.
+
+For example, in the `ToDoItem` class (of the 
https://github.com/isisaddons/isis-app-todoapp/blob/0333852ddd18ad67e3356fccf805aa442246790d/dom/src/main/java/todoapp/dom/todoitem/ToDoItem.java#L442[todoapp
 example app] (non-ASF) the `attachment` property is as follows:
+
+[source,java]
+----
+@javax.jdo.annotations.Persistent(defaultFetchGroup="false", columns = {
+    @javax.jdo.annotations.Column(name = "attachment_name"),
+    @javax.jdo.annotations.Column(name = "attachment_mimetype"),
+    @javax.jdo.annotations.Column(name = "attachment_bytes", jdbcType="BLOB", 
sqlType = "LONGVARBINARY")
+})
+@Property(
+        optionality = Optionality.OPTIONAL
+)
+@lombok.Getter @lombok.Setter
+private Blob attachment;
+----
+
+The three `@javax.jdo.annotations.Column` annotations are required because the 
mapping classes that Apache Isis provides 
(https://github.com/apache/isis/blob/isis-1.4.0/component/objectstore/jdo/jdo-datanucleus/src/main/java/org/apache/isis/objectstore/jdo/datanucleus/valuetypes/IsisBlobMapping.java#L59[IsisBlobMapping]
 and 
https://github.com/apache/isis/blob/isis-1.4.0/component/objectstore/jdo/jdo-datanucleus/src/main/java/org/apache/isis/objectstore/jdo/datanucleus/valuetypes/IsisClobMapping.java#L59[IsisClobMapping])
 map to 3 columns.
+(It is not an error to omit these `@Column` annotations, but without them the 
names of the table columns are simply suffixed `_0`, `_1`, `_2` etc.
+
+If the `Blob` is mandatory, then use:
+
+[source,java]
+----
+@javax.jdo.annotations.Persistent(defaultFetchGroup="false", columns = {
+    @javax.jdo.annotations.Column(name = "attachment_name", 
allowsNull="false"),
+    @javax.jdo.annotations.Column(name = "attachment_mimetype", 
allowsNull="false"),
+    @javax.jdo.annotations.Column(name = "attachment_bytes",
+                                  jdbcType="BLOB", sqlType = "LONGVARBINARY",
+                                  allowsNull="false")
+})
+@Property(
+    optionality = Optionality.MANDATORY
+)
+@lombok.Getter @lombok.Setter
+private Blob attachment;
+----
+
+[NOTE]
+====
+If specifying a `sqlType` of "LONGVARBINARY" does not work, try instead "BLOB".
+There can be differences in behaviour between JDBC drivers.
+====
+
+[[__ugfun_class-structure_properties_datatypes_clobs]]
+=== ``Clob``s
+
+
+Mapping `Clob`s works in a very similar way to 
xref:../ugfun/ugfun.adoc#__ugfun_class-structure_properties_datatypes_blobs[``Blob``]s,
 but the `jdbcType` and `sqlType` attributes will, respectively, be `CLOB` and 
`LONGVARCHAR`:
+
+[source,java]
+----
+@javax.jdo.annotations.Persistent(defaultFetchGroup="false", columns = {
+    @javax.jdo.annotations.Column(name = "attachment_name"),
+    @javax.jdo.annotations.Column(name = "attachment_mimetype"),
+    @javax.jdo.annotations.Column(name = "attachment_chars",
+                                  jdbcType="CLOB", sqlType = "LONGVARCHAR")
+})
+private Clob doc;
+@Property(
+    optionality = Optionality.OPTIONAL
+)
+public Clob getDoc() {
+    return doc;
+}
+public void setDoc(final Clob doc) {
+    this.doc = doc;
+}
+----
+
+[NOTE]
+====
+If specifying a `sqlType` of "LONGVARCHAR" does not work, try instead "CLOB".  
There can be differences in behaviour between JDBC drivers.
+====
+
+
+[[__ugfun_class-structure_properties_datatypes_mapping-to-varbinary-or-varchar]]
+=== Mapping to VARBINARY or VARCHAR
+
+Instead of mapping to a sqlType of `LONGVARBINARY` (or perhaps `BLOB`), you 
might instead decide to map to a `VARBINARY`.
+The difference is whether the binary data is held "on-row" or as a pointer 
"off-row"; with a `VARBINARY` the data is held on-row and so you will need to 
specify a length.
+
+For example:
+
+[source,java]
+----
+@javax.jdo.annotations.Column(name = "attachment_bytes", jdbcTypr="BLOB", 
sqlType = "VARBINARY", length=2048)
+----
+
+The same argument applies to `LONGVARCHAR` (or `CLOB`); you could instead map 
to a regular `VARCHAR`:
+
+[source,java]
+----
+@javax.jdo.annotations.Column(name = "attachment_chars", sqlType = "VARCHAR", 
length=2048)
+----
+Support and maximum allowed length will vary by database vendor.
+
+
+
+[[__ugfun_class-structure_properties_handling-mandatory-properties-in-subtypes]]
+== Handling Mandatory Properties in Subtypes
+
+
+NOTE: FIXME - move to ugodn.adoc#_ugodn_hints-and-tips
+
+
+If you have a hierarchy of classes then you need to decide which inheritance 
strategy to use.
+
+* "table per hierarchy", or "rollup" (`InheritanceStrategy.SUPERCLASS_TABLE`) +
++
+whereby a single table corresponds to the superclass, and also holds the 
properties of the subtype (or subtypes) being rolled up
+
+* "table per class" (`InheritanceStrategy.NEW_TABLE`) +
++
+whereby there is a table for both superclass and subclass, in 1:1 
correspondence
+
+* "rolldown" (`InheritanceStrategy.SUBCLASS_TABLE`) +
++
+whereby a single table holds the properties of the subtype, and also holds the 
properties of its supertype
+
+In the first "rollup" case, we can have a situation where - logically speaking 
- the property is mandatory in the subtype - but it must be mapped as nullable 
in the database because it is n/a for any other subtypes that are rolled up.
+
+In this situation we must tell JDO that the column is optional, but to Apache 
Isis we want to enforce it being mandatory. This can be done using the 
`@Property(optionality=Optionality.MANDATORY)` annotation.
+
+For example:
+
+[source,java]
+----
+@javax.jdo.annotations.Inheritance(strategy = InheritanceStrategy.SUPER_TABLE)
+public class SomeSubtype extends SomeSuperType {
+    @javax.jdo.annotations.Column(allowsNull="true")
+    @Property(optionality=Optionality.MANDATORY)
+    @lombok.Getter @lombok.Setter
+    private LocalDate date;
+}
+----
+
+[TIP]
+====
+The `@Property(optionality=...)` annotation is equivalent to the older but 
still supported `@Optional` annotation and `@Mandatory` annotations.
+====
+

http://git-wip-us.apache.org/repos/asf/isis/blob/480d6ff2/adocs/documentation/src/main/asciidoc/guides/ugfun/_ugfun_crud.adoc
----------------------------------------------------------------------
diff --git 
a/adocs/documentation/src/main/asciidoc/guides/ugfun/_ugfun_crud.adoc 
b/adocs/documentation/src/main/asciidoc/guides/ugfun/_ugfun_crud.adoc
new file mode 100644
index 0000000..247deaf
--- /dev/null
+++ b/adocs/documentation/src/main/asciidoc/guides/ugfun/_ugfun_crud.adoc
@@ -0,0 +1,29 @@
+[[_ugfun_crud]]
+= Object Management (CRUD)
+: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
+
+
+## Instantiating and Persisting
+
+NOTE: FIXME - using ``DomainObjectContainer``'s support for  
xref:../rgsvc/rgsvc.adoc#_rgsvc_api_DomainObjectContainer_object-creation-api[creation]
 and 
xref:../rgsvc/rgsvc.adoc#_rgsvc_api_DomainObjectContainer_object-persistence-api[persistence]
+
+## Finding Objects
+
+NOTE: FIXME - using 
xref:../rgsvc/rgsvc.adoc#_rgsvc_api_DomainObjectContainer_generic-repository-api[`DomainObjectContainer`]
+
+### Using DataNucleus type-safe queries
+
+NOTE: FIXME - as described 
xref:../rgsvc/rgsvc.adoc#__rgsvc_api_IsisJdoSupport_type-safe-jdoql-queries[here]
+
+
+
+## Deleting Objects
+
+NOTE: FIXME using ``DomainObjectContainer``'s support for  
xref:../rgsvc/rgsvc.adoc#_rgsvc_api_DomainObjectContainer_object-persistence-api[persistence]
+
+
+

http://git-wip-us.apache.org/repos/asf/isis/blob/480d6ff2/adocs/documentation/src/main/asciidoc/guides/ugfun/_ugfun_domain-class-ontology.adoc
----------------------------------------------------------------------
diff --git 
a/adocs/documentation/src/main/asciidoc/guides/ugfun/_ugfun_domain-class-ontology.adoc
 
b/adocs/documentation/src/main/asciidoc/guides/ugfun/_ugfun_domain-class-ontology.adoc
new file mode 100644
index 0000000..7e496a0
--- /dev/null
+++ 
b/adocs/documentation/src/main/asciidoc/guides/ugfun/_ugfun_domain-class-ontology.adoc
@@ -0,0 +1,43 @@
+[[_ugfun_domain-class-ontology]]
+= Domain Class Ontology
+: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 supports recognises three main types of domain classes:
+
+* domain entities - domain objects persisted to the database using 
JDO/DataNucleus; for example `Customer`
+
+* domain services - generally singletons, automatically injected, and 
providing various functionality; for example `CustomerRepository`
+
+* view models - domain objects that are a projection of some state held by the 
database, in support a particular use case; for example `CustomerDashboard` (to 
pull together commonly accessed information about a customer).
+
+Domain classes are generally recognized using annotations.
+Apache Isis defines its own set of annotations, while entities are annotated 
using JDO/DataNucleus (though XML can also be used if required).
+JAXB can also be used for view models.
+Apache Isis recognizes some of the JDO and JAXB annotations and infers domain 
semantics from these annotations.
+
+You can generally recognize an Apache Isis domain class because it will be 
probably be annotated using `@DomainObject` and `@DomainService`.
+The framework also defines supplementary annotations, `@DomainObjectLayout` 
and `@DomainServiceLayout`.
+These provide hints relating to the layout of the domain object in the user 
interface.
+(Alternatively, these UI hints can be defined in a supplementary 
xref:../ugvw/ugvw.adoc#_ugvw_layout[`.layout.xml`] file.
+
+We use Maven modules as a way to group related domain objects together; we can 
then reason about all the classes in that module as a single unit.
+By convention there will be a single top-level package corresponding to the 
module.
+
+For example, the (non-ASF) 
link:https://github.com/incodehq/incode-module-document[Document module] (part 
of the link:http://catalog.incode.org[Incode Catalog]) has a top-level package 
of `org.incode.module.document`.
+Within the module there may be various subpackages, but its the module defines 
the namespace.
+
+In the same way that the Java module act as a namespace for domain objects, 
it's good practice to map domain entities to their own (database) schemas.
+
+
+
+include::_ugfun_domain-class-ontology_domain-entities.adoc[leveloffset=+1]
+include::_ugfun_domain-class-ontology_domain-services.adoc[leveloffset=+1]
+include::_ugfun_domain-class-ontology_view-models.adoc[leveloffset=+1]
+
+
+
+

http://git-wip-us.apache.org/repos/asf/isis/blob/480d6ff2/adocs/documentation/src/main/asciidoc/guides/ugfun/_ugfun_domain-class-ontology_domain-entities.adoc
----------------------------------------------------------------------
diff --git 
a/adocs/documentation/src/main/asciidoc/guides/ugfun/_ugfun_domain-class-ontology_domain-entities.adoc
 
b/adocs/documentation/src/main/asciidoc/guides/ugfun/_ugfun_domain-class-ontology_domain-entities.adoc
new file mode 100644
index 0000000..ce399e3
--- /dev/null
+++ 
b/adocs/documentation/src/main/asciidoc/guides/ugfun/_ugfun_domain-class-ontology_domain-entities.adoc
@@ -0,0 +1,86 @@
+[[_ugfun_domain-class-ontology_domain-entities]]
+= Domain Entities
+: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/
+
+
+
+Entities are persistent domain objects, with their persistence handled by 
JDO/DataNucleus.
+As such, they are mapped to a persistent object store, typically an RDBMS, 
with DataNucleus taking care of both lazy loading and also the persisting of 
modified ("dirty") objects.
+
+Domain entities are generally decorated with both DataNucleus and Apache Isis 
annotations.
+The following is typical:
+
+[source,java]
+----
+@javax.jdo.annotations.PersistenceCapable(                                     
 // <1>
+        identityType=IdentityType.DATASTORE,                                   
 // <2>
+        schema = "simple",                                                     
 // <3>
+        table = "SimpleObject"
+)
+@javax.jdo.annotations.DatastoreIdentity(                                      
 // <4>
+        strategy=javax.jdo.annotations.IdGeneratorStrategy.IDENTITY,
+        column="id"
+)
+@javax.jdo.annotations.Version(                                                
 // <5>
+        strategy= VersionStrategy.DATE_TIME,
+        column="version"
+)
+@javax.jdo.annotations.Queries({
+        @javax.jdo.annotations.Query(                                          
 // <6>
+                name = "findByName",
+                value = "SELECT "
+                        + "FROM domainapp.modules.simple.dom.impl.SimpleObject 
"
+                        + "WHERE name.indexOf(:name) >= 0 ")
+})
+@javax.jdo.annotations.Unique(name="SimpleObject_name_UNQ", members = 
{"name"}) // <7>
+@DomainObject(                                                                 
 // <8>
+        objectType = "simple.SimpleObject"
+)
+public class SimpleObject
+             implements Comparable<SimpleObject> {                             
 // <9>
+
+    public SimpleObject(final String name) {                                   
 // <10>
+        setName(name);
+    }
+
+    ...
+
+    @Override
+    public String toString() {
+        return ObjectContracts.toString(this, "name");                         
 // <11>
+    }
+    @Override
+    public int compareTo(final SimpleObject other) {
+        return ObjectContracts.compare(this, other, "name");                   
 // <9>
+    }
+}
+----
+<1> The `@PersistenceCapable` annotation indicates that this is an entity to 
DataNucleus.
+The DataNucleus enhancer acts on the bytecode of compiled entities, injecting 
lazy loading and dirty object tracking functionality.
+Enhanced entities end up also implementing the 
`javax.jdo.spi.PersistenceCapable` interface.
+<2> Indicates how identifiers for the entity are handled.
+Using `DATASTORE` means that a DataNucleus is responsible for assigning the 
value (rather than the application).
+<3> Specifies the RDBMS database schema and table name for this entity will 
reside.
+The schema should correspond with the module in which the entity resides.
+The table will default to the entity name if omitted.
+<4> For entities that are using `DATASTORE` identity, indicates how the id 
will be assigned.
+A common strategy is to allow the database to assign the id, for example using 
an identity column or a sequence.
+<5> The `@Version` annotation is useful for optimistic locking; the strategy 
indicates what to store in the `version` column.
+<6> The `@Query` annotation (usually several of them, nested within a 
`@Queries` annotation) defines queries using JDOQL.
+DataNucleus provides several APIs for defining queries, including entirely 
programmatic and type-safe APIs; but JDOQL is very similar to SQL and so easily 
learnt.
+<7> DataNucleus will automatically add a unique index to the primary surrogate 
id (discussed above), but additional alternative keys can be defined using the 
`@Unique` annotation.
+In the example above, the "name" property is assumed to be unique.
+<8> The `@DomainObject` annotation identifies the domain object to Apache Isis 
(not DataNucleus).
+It isn't necessary to include this annotation -- at least, not for entities -- 
but it is nevertheless recommended.
+In particular, its strongly recommended that the `objectType` (which acts like 
an alias to the concrete domain class) is specified; note that it corresponds 
to the schema/table for DataNucleus' `@PersistenceCapable` annotation.
+<9> Although not required, we strongly recommend that all entities are 
naturally `Comparable`.
+This then allows parent/child relationships to be defined using 
``SortedSet``s; RDBMS after all are set-oriented.
+The `ObjectContracts` utility class provided by Apache Isis makes it easy to 
implement the `compareTo()` method, but you can also just use an IDE to 
generate an implementation or roll your own.
+<10> Chances are that some of the properties of the entity will be mandatory, 
for example any properties that represent an alternate unique key to the entity.
+In regular Java programming we would represent this using a constructor that 
defines these mandatory properties, and in Apache Isis/DataNucleus we can 
likewise define such a constructor.
+When DataNucleus rehydrates domain entities from the database at runtime, it 
actually requires a no-arg constructor (it then sets all state reflectively).
+However, there is no need to provide such a no-arg constructor; it is added by 
the enhancer process.
+<11> The `ObjectContracts` utility class also provides assistance for 
`toString()`, useful when debugging in an IDE.
+

http://git-wip-us.apache.org/repos/asf/isis/blob/480d6ff2/adocs/documentation/src/main/asciidoc/guides/ugfun/_ugfun_domain-class-ontology_domain-services.adoc
----------------------------------------------------------------------
diff --git 
a/adocs/documentation/src/main/asciidoc/guides/ugfun/_ugfun_domain-class-ontology_domain-services.adoc
 
b/adocs/documentation/src/main/asciidoc/guides/ugfun/_ugfun_domain-class-ontology_domain-services.adoc
new file mode 100644
index 0000000..e89b754
--- /dev/null
+++ 
b/adocs/documentation/src/main/asciidoc/guides/ugfun/_ugfun_domain-class-ontology_domain-services.adoc
@@ -0,0 +1,214 @@
+[[_ugfun_domain-class-ontology_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/
+
+
+In Apache Isis domain services have several responsibilities:
+
+- to expose actions to be rendered in the menu
+- to provide actions that are rendered as contributed 
actions/properties/collections on the contributee domain object
+- they act as subscribers to the event bus
+- they act as repositories (find existing objects) or as factories (create new 
objects)
+- they provide other services (eg performing calculations, attach a barcode, 
send an email etc).
+- to implement an SPI of the framework, most notably cross-cutting concerns 
such as security, command profiling, auditing and publishing.
+
+It's worth extending the 
xref:../ugfun/ugfun.adoc#_ugfun_core-concepts_philosophy_hexagonal-architecture[Hexagonal
 Architecture] to show where domain services -- and in particular the domain 
services provided by link:http://www.isisaddons.org[Isis Addons] (non-ASF) -- 
fit in:
+
+.The hexagonal architecture with Isis addons
+image::{_imagesdir}how-tos/domain-services/hexagonal-architecture-addons.png[width="700px"]
+
+The (non-ASF) link:http://isisaddons.org[Isis Addons] are a good source of 
domain services, providing SPI implementations of the common cross-cutting 
concerns, and also a number of APIs for domain objects to invoke (eg tags, 
excel, settings).  Of course, you can also write your own domain services as 
well, for example to interface with some external CMS system, say.
+
+
+
+[[__ugfun_domain-class-ontology_domain-services_organizing-services]]
+== Organizing Services
+
+In larger applications we have found it worthwhile to ensure that our domain 
services only act aligned with these responsibilities, employing a naming 
convention so that it is clear what the responsibilities of each domain service 
is.
+
+The application provides the `@DomainService(nature=...)` annotation that 
helps distinguish some of these responsibilities:
+
+- `VIEW` indicates that the actions should appear both on the menu and also be 
used as contributions
+- `VIEW_MENU_ONLY` indicates that the actions should appear on the menu
+- `VIEW_CONTRIBUTIONS_ONLY` indicates that the actions should not appear on 
the menu
+- `DOMAIN` indicates that the actions are for other domain objects to invoke 
(either directly or indirectly through the event bus), but in any case should 
not be rendered at all in the UI
+
+Pulling all the above together, here are our suggestions as to how you should 
organize your domain services.
+
+
+=== Factory and Repository
+
+The factory/repository uses an injected `DomainObjectContainer` to both 
instantiate new objects and to query the database for existing objects of a 
given entity type.  It is not visible in UI, rather other services delegate to 
it.
+
+We suggest naming such classes `XxxRepository`, eg:
+
+
+[source,java]
+----
+@DomainService(
+    nature=NatureOfService.DOMAIN                               // <1>
+)
+public CustomerRepository {
+    public List<Customer> findCustomerBy...(...) {
+        return allMatches(...);
+    }
+    public Customer newCustomer(...) {
+        Customer Customer = container.newTransientInstance(Customer.class);
+        ...
+        persistIfNotAlready(Customer);
+        return Customer;
+    }
+    public List<Customer> allCustomers() {
+        return container.allInstances(Customer.class);
+    }
+    @Inject
+    DomainObjectContainer container;
+}
+----
+<1> interacted with only programmatically by other objects in the domain layer.
+
+There is no need to annotate the actions; they are implicitly hidden because 
of the domain service's nature.
+
+
+
+=== Menu
+
+Menu services provide actions to be rendered on the menu.
+
+For the Wicket viewer, each service's actions appear as a collection of menu 
items of a named menu, and this menu is on one of the three menu bars provided 
by the Wicket viewer.  It is possible for more than one menu service's actions 
to appear on the same menu; a separator is shown between each.
+
+For the Restful Objects viewer, all menu services are shown in the services 
representation.
+
+We suggest naming such classes `XxxMenu`, eg:
+
+
+[source,java]
+----
+@DomainService(
+    nature = NatureOfService.VIEW_MENU_ONLY                     // <1>
+)
+@DomainServiceLayout(
+        named = "Customers",                                    // <2>
+        menuBar = DomainServiceLayout.MenuBar.PRIMARY,
+        menuOrder = "10"
+)
+public class CustomerMenu {
+    @Action(
+            semantics = SemanticsOf.SAFE
+    )
+    @MemberOrder( sequence = "1" )
+    public List<Customer> findCustomerBy...(...) {
+        return customerRepository.findCustomerBy(...);          // <3>
+    }
+
+    @Action(
+            semantics = SemanticsOf.NON_IDEMPOTENT
+    )
+    @MemberOrder( sequence = "3" )
+    public Customer newCustomer(...) {
+        return customerRepository.newCustomer(...);
+    }
+
+    @Action(
+            semantics = SemanticsOf.SAFE,
+            restrictTo = RestrictTo.PROTOTYPING
+    )
+    @MemberOrder( sequence = "99" )
+    public List<Customer> allCustomers() {
+        return customerRepository.allBankMandates();
+    }
+
+    @Inject
+    protected CustomerRepository customerRepository;
+}
+----
+<1> the service's actions should be rendered as menu items
+<2> specifies the menu name.  All services with the same menu name will be 
displayed on the same menu, with separators between
+<3> delegates to an injected repository.
+
+Not every action on the repository need to be delegated to of course (the 
above example does but only because it is very simple).
+
+[TIP]
+====
+Note also that while there's nothing to stop `VIEW_MENU` domain services being 
injected into other domain objects and interacted with programmatically, we 
recommend against it.  Instead, inject the underlying repository.  If there is 
additional business logic, then consider introducing a further `DOMAIN`-scoped 
service and call that instead.
+====
+
+
+
+=== Contributions
+
+Services can contribute either actions, properties or collections, based on 
the type of their parameters.
+
+We suggest naming such classes `XxxContributions`, eg:
+
+[source,java]
+----
+@DomainService(
+    nature=NatureOfService.VIEW_CONTRIBUTIONS_ONLY              // <1>
+)
+@DomainServiceLayout(
+    menuOrder="10",
+    name="...",
+}
+public OrderContributions {
+    @Action(semantics=SemanticsOf.SAFE)
+    @ActionLayout(contributed=Contributed.AS_ASSOCIATION)       // <2>
+    @CollectionLayout(render=RenderType.EAGERLY)
+    public List<Order> orders(Customer customer) {              // <3>
+        return container.allMatches(...);
+    }
+
+    @Inject
+    CustomerRepository customerRepository;
+}
+----
+<1> the service's actions should be contributed to the entities of the 
parameters of those actions
+<2> contributed as an association, in particular as a collection because 
returns a `List<T>`.
+<3> Only actions with a single argument can be contributed as associations
+
+More information about contributions can be found 
xref:../ugfun/ugfun.adoc#_ugfun_how-tos_contributed-members[here].  More 
information
+about using contributions and mixins to keep your domain application decoupled 
can be found xref:../ugbtb/ugbtb.adoc#_ugbtb_decoupling_contributions[here] and 
xref:../ugbtb/ugbtb.adoc#_ugbtb_decoupling_mixins[here].
+
+
+=== Event Subscribers
+
+Event subscribers can both veto interactions (hiding members, disabling 
members or validating changes), or can react to interactions (eg action 
invocation or property edit).
+
+We suggest naming such classes `XxxSubscriptions`, eg:
+
+[source,java]
+----
+@DomainService(
+    nature=NatureOfService.DOMAIN                       // <1>
+)
+@DomainServiceLayout(
+    menuOrder="10",
+    name="...",
+}
+public CustomerOrderSubscriptions {
+    @com.google.common.eventbus.Subscribe
+    public void on(final Customer.DeletedEvent ev) {
+        Customer customer = ev.getSource();
+        orderRepository.delete(customer);
+    }
+    @Inject
+    OrderRepository orderRepository;
+}
+----
+<1> subscriptions do not appear in the UI at all, so should use the domain 
nature of service
+
+
+
+== Prototyping
+
+While for long-term maintainability we do recommend the naming conventions 
described 
xref:../ugfun/ugfun.adoc#__ugfun_domain-class-ontology_domain-services_organizing-services[above],
 you can get away with far fewer services when just prototyping a domain.
+
+If the domain service nature is not specified (or is left to its default, 
`VIEW`), then the service's actions will
+appear in the UI both as menu items _and_ as contributions (and the service 
can of course be injected into other domain objects for programmatic 
invocation).
+
+Later on it is easy enough to refactor the code to tease apart the different 
responsibilities.
+
+
+

http://git-wip-us.apache.org/repos/asf/isis/blob/480d6ff2/adocs/documentation/src/main/asciidoc/guides/ugfun/_ugfun_domain-class-ontology_view-models.adoc
----------------------------------------------------------------------
diff --git 
a/adocs/documentation/src/main/asciidoc/guides/ugfun/_ugfun_domain-class-ontology_view-models.adoc
 
b/adocs/documentation/src/main/asciidoc/guides/ugfun/_ugfun_domain-class-ontology_view-models.adoc
new file mode 100644
index 0000000..4e510ac
--- /dev/null
+++ 
b/adocs/documentation/src/main/asciidoc/guides/ugfun/_ugfun_domain-class-ontology_view-models.adoc
@@ -0,0 +1,196 @@
+[[_ugfun_domain-class-ontology_view-models]]
+= View Models
+: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/
+
+
+
+View models are similar to entities in that (unlike domain services) there can 
be many instances of any given type; but they differ from entities in that they 
are not persisted into a database.
+Instead they are recreated dynamically by serializing their state, ultimately 
into the URL itself.
+
+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, to view models.
+This section explores these use cases.
+
+
+
+
+[[__ugfun_domain-class-ontology_view-models_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).
+====
+
+
+[[__ugfun_domain-class-ontology_view-models_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.
+
+
+[[__ugfun_domain-class-ontology_view-models_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).
+****
+
+[[__ugfun_domain-class-ontology_view-models_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#__ugfun_domain-class-ontology_view-models_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.
+
+
+[[__ugfun_domain-class-ontology_view-models_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.
+
+
+
+
+
+[[__ugfun_domain-class-ontology_view-models_typical-implementation]]
+== Typical Implementation
+
+Apache Isis offers several ways to implement view models, but the most 
flexible/powerful is to annotate the class using JAXB annotations.
+For example:
+
+[source,java]
+----
+@XmlRootElement(name = "invoiceRun")    // <1>
+@XmlType(
+        propOrder = {                   // <2>
+            ...
+        }
+)
+public class InvoiceRun {
+    ...
+}
+----
+<1> The JAXB `@XmlRootElement` annotation indicates this is a view model to 
Apache Isis, which then uses JAXB to serialize the state of the view model 
between interactions
+<2> All properties of the view model must be listed using the 
`XmlType#propOrder` attribute.
+
+Use JAXB elements such as `@XmlElement` for properties and the combination of 
`@XmlElementWrapper` and `@XmlElement` for collections.
+Properties can be ignored (for serialization) using `@XmlTransient`.
+

http://git-wip-us.apache.org/repos/asf/isis/blob/480d6ff2/adocs/documentation/src/main/asciidoc/guides/ugfun/_ugfun_drop-downs-and-defaults.adoc
----------------------------------------------------------------------
diff --git 
a/adocs/documentation/src/main/asciidoc/guides/ugfun/_ugfun_drop-downs-and-defaults.adoc
 
b/adocs/documentation/src/main/asciidoc/guides/ugfun/_ugfun_drop-downs-and-defaults.adoc
new file mode 100644
index 0000000..fdf2a1f
--- /dev/null
+++ 
b/adocs/documentation/src/main/asciidoc/guides/ugfun/_ugfun_drop-downs-and-defaults.adoc
@@ -0,0 +1,65 @@
+[[_ugfun_drop-downs-and-defaults]]
+= Drop Downs and Defaults
+: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
+
+
+== For Properties
+
+NOTE: FIXME
+
+### Choices for Property
+
+NOTE: FIXME - 
xref:../rgcms/rgcms.adoc#_rgcms_methods_prefixes_choices[`choices...()`]
+
+### Auto-complete for property
+
+NOTE: FIXME - 
xref:../rgcms/rgcms.adoc#_rgcms_methods_prefixes_autoComplete[`autoComplete...()`]
+
+### Default for property
+
+NOTE: FIXME -  
xref:../rgcms/rgcms.adoc#_rgcms_methods_prefixes_default[`default...()`]
+
+
+
+
+== For Action Parameters
+
+NOTE: FIXME
+
+### Choices for action parameter
+
+NOTE: FIXME - 
xref:../rgcms/rgcms.adoc#_rgcms_methods_prefixes_choices[`choices...()`]
+
+### Dependent choices for action params
+
+NOTE: FIXME - 
xref:../rgcms/rgcms.adoc#_rgcms_methods_prefixes_choices[`choices...()`]
+
+### Auto-complete for action param
+
+NOTE: FIXME - 
xref:../rgcms/rgcms.adoc#_rgcms_methods_prefixes_autoComplete[`autoComplete...()`]
+
+### Default for action param
+
+NOTE: FIXME -  
xref:../rgcms/rgcms.adoc#_rgcms_methods_prefixes_default[`default...()`]
+
+
+
+
+
+== For both Properties and Action Parameters
+
+NOTE: FIXME
+
+
+### Drop-down for limited number of instances
+
+NOTE: FIXME - 
xref:../rgant/rgant.adoc#_rgant-DomainObject_bounded[`@DomainObject#bounded()`]
+
+
+### Auto-complete (repository-based)
+
+xref:../rgant/rgant.adoc#_rgant-DomainObject_autoCompleteRepository[`@DomainObject#autoCompleteRepository()`]

http://git-wip-us.apache.org/repos/asf/isis/blob/480d6ff2/adocs/documentation/src/main/asciidoc/guides/ugfun/_ugfun_how-tos.adoc
----------------------------------------------------------------------
diff --git 
a/adocs/documentation/src/main/asciidoc/guides/ugfun/_ugfun_how-tos.adoc 
b/adocs/documentation/src/main/asciidoc/guides/ugfun/_ugfun_how-tos.adoc
deleted file mode 100644
index 3d2af8e..0000000
--- a/adocs/documentation/src/main/asciidoc/guides/ugfun/_ugfun_how-tos.adoc
+++ /dev/null
@@ -1,20 +0,0 @@
-[[_ugfun_how-tos]]
-= How tos
-: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 chapter provides a grab bag of "how-to"s and tips to help you go about 
actually developing Apache Isis domain applications.
-
-include::_ugfun_how-tos_class-structure.adoc[leveloffset=+1]
-include::_ugfun_how-tos_ui-hints.adoc[leveloffset=+1]
-include::_ugfun_how-tos_domain-services.adoc[leveloffset=+1]
-include::_ugfun_how-tos_crud.adoc[leveloffset=+1]
-include::_ugfun_how-tos_business-rules.adoc[leveloffset=+1]
-include::_ugfun_how-tos_derived-members.adoc[leveloffset=+1]
-include::_ugfun_how-tos_drop-downs-and-defaults.adoc[leveloffset=+1]
-include::_ugfun_how-tos_bulk-actions.adoc[leveloffset=+1]
-include::_ugfun_how-tos_simulating-collections-of-values.adoc[leveloffset=+1]
-include::_ugfun_how-tos_render-all-properties-in-tables.adoc[leveloffset=+1]
-

http://git-wip-us.apache.org/repos/asf/isis/blob/480d6ff2/adocs/documentation/src/main/asciidoc/guides/ugfun/_ugfun_how-tos_bulk-actions.adoc
----------------------------------------------------------------------
diff --git 
a/adocs/documentation/src/main/asciidoc/guides/ugfun/_ugfun_how-tos_bulk-actions.adoc
 
b/adocs/documentation/src/main/asciidoc/guides/ugfun/_ugfun_how-tos_bulk-actions.adoc
deleted file mode 100644
index f3d5e41..0000000
--- 
a/adocs/documentation/src/main/asciidoc/guides/ugfun/_ugfun_how-tos_bulk-actions.adoc
+++ /dev/null
@@ -1,8 +0,0 @@
-[[_ugfun_how-tos_bulk-actions]]
-= Bulk 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/
-
-NOTE: FIXME - 
xref:../rgant/rgant.adoc#_rgant-Action_invokeOn[`@Action#invokeOn()`]
-

http://git-wip-us.apache.org/repos/asf/isis/blob/480d6ff2/adocs/documentation/src/main/asciidoc/guides/ugfun/_ugfun_how-tos_business-rules.adoc
----------------------------------------------------------------------
diff --git 
a/adocs/documentation/src/main/asciidoc/guides/ugfun/_ugfun_how-tos_business-rules.adoc
 
b/adocs/documentation/src/main/asciidoc/guides/ugfun/_ugfun_how-tos_business-rules.adoc
deleted file mode 100644
index 8c02ad3..0000000
--- 
a/adocs/documentation/src/main/asciidoc/guides/ugfun/_ugfun_how-tos_business-rules.adoc
+++ /dev/null
@@ -1,72 +0,0 @@
-[[_ugfun_how-tos_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()`]
-
-
-

http://git-wip-us.apache.org/repos/asf/isis/blob/480d6ff2/adocs/documentation/src/main/asciidoc/guides/ugfun/_ugfun_how-tos_class-structure.adoc
----------------------------------------------------------------------
diff --git 
a/adocs/documentation/src/main/asciidoc/guides/ugfun/_ugfun_how-tos_class-structure.adoc
 
b/adocs/documentation/src/main/asciidoc/guides/ugfun/_ugfun_how-tos_class-structure.adoc
deleted file mode 100644
index 4e0b7f9..0000000
--- 
a/adocs/documentation/src/main/asciidoc/guides/ugfun/_ugfun_how-tos_class-structure.adoc
+++ /dev/null
@@ -1,41 +0,0 @@
-[[_ugfun_how-tos_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_how-tos_class-structure_class-definition.adoc[leveloffset=+1]
-include::_ugfun_how-tos_class-structure_properties.adoc[leveloffset=+1]
-include::_ugfun_how-tos_class-structure_collections.adoc[leveloffset=+1]
-include::_ugfun_how-tos_class-structure_actions.adoc[leveloffset=+1]
-include::_ugfun_how-tos_class-structure_inject-services.adoc[leveloffset=+1]
-
-include::_ugfun_how-tos_class-structure_properties-vs-parameters.adoc[leveloffset=+1]
-
-
-
-

http://git-wip-us.apache.org/repos/asf/isis/blob/480d6ff2/adocs/documentation/src/main/asciidoc/guides/ugfun/_ugfun_how-tos_class-structure_actions.adoc
----------------------------------------------------------------------
diff --git 
a/adocs/documentation/src/main/asciidoc/guides/ugfun/_ugfun_how-tos_class-structure_actions.adoc
 
b/adocs/documentation/src/main/asciidoc/guides/ugfun/_ugfun_how-tos_class-structure_actions.adoc
deleted file mode 100644
index 1954d64..0000000
--- 
a/adocs/documentation/src/main/asciidoc/guides/ugfun/_ugfun_how-tos_class-structure_actions.adoc
+++ /dev/null
@@ -1,264 +0,0 @@
-[[_ugfun_how-tos_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_how-tos_class-structure_properties[properties] 
and 
xref:../ugfun/ugfun.adoc#_ugfun_how-tos_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_how-tos_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_how-tos_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_how-tos_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_how-tos_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_how-tos_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_how-tos_class-structure_actions_reference-parameter-types_removing-boilerplate[above]).
-
-
-[[__ugfun_how-tos_class-structure_actions_optional-parameters]]
-== Optional Parameters
-
-Whereas the 
xref:../ugfun/ugfun.adoc#__ugfun_how-tos_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_how-tos_class-structure_properties-vs-parameters[properties
 vs parameters].
-
-[[__ugfun_how-tos_class-structure_actions_string-parameters]]
-== ``String`` Parameters (Length)
-
-Whereas the 
xref:../ugfun/ugfun.adoc#__ugfun_how-tos_class-structure_properties_mapping-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_how-tos_class-structure_properties-vs-parameters[properties
 vs parameters].
-
-[[__ugfun_how-tos_class-structure_actions_bigdecimal-parameters]]
-== ``BigDecimal``s (Precision)
-
-Whereas the 
xref:../ugfun/ugfun.adoc#__ugfun_how-tos_class-structure_properties_mapping-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_how-tos_class-structure_properties-vs-parameters[properties
 vs parameters].
-
-
-

Reply via email to