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

[42/43] isis git commit: ISIS-1521: working on ugfun.adoc

http://git-wip-us.apache.org/repos/asf/isis/blob/f6f6a40b/adocs/documentation/src/main/asciidoc/guides/ugfun/_ugfun_building-blocks_object-members.adoc
----------------------------------------------------------------------
diff --git a/adocs/documentation/src/main/asciidoc/guides/ugfun/_ugfun_building-blocks_object-members.adoc b/adocs/documentation/src/main/asciidoc/guides/ugfun/_ugfun_building-blocks_object-members.adoc
new file mode 100644
index 0000000..38a18c7
--- /dev/null
+++ b/adocs/documentation/src/main/asciidoc/guides/ugfun/_ugfun_building-blocks_object-members.adoc
@@ -0,0 +1,87 @@
+[[_ugfun_building-blocks_objects-members]]
+= Object Members
+: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/
+
+
+Every domain object in Apache Isis consists of (at most) three types of members:
+
+* properties, such as a ``Customer``'s `firstName`
+
+* collections, such as a ``Customer``'s `orders` collection of ``Order``s
+
+* actions, such as a ``Customer'``s `placeOrder(...)` method.
+
+Some domain objects -- specifically domain services and mixins -- only have actions.
+In the case of contributing services and mixins these actions can (depending upon their semantics and signatures) be represented as derived properties or collections on the entity/view model to which they contribute/mix-in.
+
+
+== Properties
+
+Properties follow the standard getter/setter pattern, with the return type being a scalar (a value object or another entity or view model).
+
+For example, with:
+
+[source,java]
+----
+public class Customer
+    private String firstName;
+    public String getFirstName() { return firstName; }
+    public void setFirstName(String firstName) { this.firstName = firstName; }
+    ...
+}
+----
+
+the framework infers the `Customer` domain entity, which in turn has a `firstName` string _property_.
+
+
+== Collections
+
+Collections are also represented by a getter and setter, however the return type is a `Collection` or subtype.
+
+For example, with:
+
+[source,java]
+----
+public class Customer
+    private SortedSet<Order> orders = new TreeSet<Order>();
+    public SortedSet<Order> getOrders() { return orders; }
+    public void setOrders(SortedSet<Order> orders) { this.orders = orders; }
+    ...
+}
+----
+
+the framework infers the `orders` _collection_.
+
+[TIP]
+====
+The most commonly used collection type is `java.util.SortedSet`; entities are most commonly mapped to a relational database (ie a datastore with set semantics) and we recommend that all entities define a natural ordering so that when rendered in the UI they will be ordered "meaningfully" to the end-user.
+====
+
+
+== Actions
+
+The third type of object member is actions.
+(To a first approximation), actions are all public methods that do not represent properties or collections.
+
+For example:
+
+[source,java]
+----
+public class Customer
+    public Customer placeOrder(Product p, int quantity) { ... }
+    ...
+}
+----
+
+corresponds to the `placeOrder` _action_.
+
+[NOTE]
+====
+The above _is_ a simplification; the Apache Isis programming model also recognizes a number of other supporting methods each of which has its own prefix such as `hide`, `disable` or `validate`.
+These can be considered as "reserved words" in Apache Isis, and do _not_ correspond to actions even though they have public visibility.
+====
+
+
+

http://git-wip-us.apache.org/repos/asf/isis/blob/f6f6a40b/adocs/documentation/src/main/asciidoc/guides/ugfun/_ugfun_building-blocks_types-of-domain-objects.adoc
----------------------------------------------------------------------
diff --git a/adocs/documentation/src/main/asciidoc/guides/ugfun/_ugfun_building-blocks_types-of-domain-objects.adoc b/adocs/documentation/src/main/asciidoc/guides/ugfun/_ugfun_building-blocks_types-of-domain-objects.adoc
new file mode 100644
index 0000000..87f28b8
--- /dev/null
+++ b/adocs/documentation/src/main/asciidoc/guides/ugfun/_ugfun_building-blocks_types-of-domain-objects.adoc
@@ -0,0 +1,35 @@
+[[_ugfun_building-blocks_types-of-domain-objects]]
+= Type of Domain Objects
+: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 four 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).
+
+* *mixins* - allow functionality to be "contributed" in the UI by one module to another object, similar to traits or extension methods provided in some programming languages.
+This is an important capability to help keep large applications xref:../ugbtb/ugbtb.adoc#_ugbtb_decoupling[decoupled].
+
+From the end-user's perspective the UI displays a single domain object instance that has state (that is, a domain entity or a view model) per page.
+The end-user can then inspect and modify its state, and navigate to related objects.
+
+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).
+Apache Isis recognizes some of the JDO and JAXB annotations and infers domain semantics from these annotations.
+Similarly, JAXB annotations are typically used for view models.
+There is a smattering of other Java/JEE annotations that are also supported, such as `@javax.inject.Inject` and `@javax.annotation.Nullable`.
+
+The following subsections explain this in further detail.
+
+
+include::_ugfun_building-blocks_types-of-domain-objects_domain-entities.adoc[leveloffset=+1]
+include::_ugfun_building-blocks_types-of-domain-objects_domain-services.adoc[leveloffset=+1]
+include::_ugfun_building-blocks_types-of-domain-objects_view-models.adoc[leveloffset=+1]
+include::_ugfun_building-blocks_types-of-domain-objects_mixins.adoc[leveloffset=+1]

http://git-wip-us.apache.org/repos/asf/isis/blob/f6f6a40b/adocs/documentation/src/main/asciidoc/guides/ugfun/_ugfun_building-blocks_types-of-domain-objects_domain-entities.adoc
----------------------------------------------------------------------
diff --git a/adocs/documentation/src/main/asciidoc/guides/ugfun/_ugfun_building-blocks_types-of-domain-objects_domain-entities.adoc b/adocs/documentation/src/main/asciidoc/guides/ugfun/_ugfun_building-blocks_types-of-domain-objects_domain-entities.adoc
new file mode 100644
index 0000000..e2bb0a7
--- /dev/null
+++ b/adocs/documentation/src/main/asciidoc/guides/ugfun/_ugfun_building-blocks_types-of-domain-objects_domain-entities.adoc
@@ -0,0 +1,37 @@
+[[_ugfun_building-blocks_types-of-domain-objects_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/
+
+
+Most domain objects that the end-user interacts with are _domain entities_, such as `Customer`, `Order`, `Product` and so on.
+These are persistent objects and which are mapped to a database (usually relational), using JDO/DataNucleus annotations.
+
+Some domain entities are really aggregates, a combination of multiple objects.
+A commonly cited example of this is an `Order`, which really consists of both a root `Order` entity and a collection of ``OrderItem``s.
+From the end-users' perspective, when they talk of "order" they almost always mean the aggregate rather than just the `Order` root entity.
+
+Eric Evans' link:http://books.google.com/books/about/Domain_Driven_Design.html?id=hHBf4YxMnWMC[Domain Driven Design] has a lot to say about aggregate roots and their responsibilities: in particular that it is the responsibility of the aggregate root to maintain the invariants of its component pieces, and that roots may only reference other roots.
+There's good logic here: requiring only root-to-root relationships reduces the number of moving parts that the developer has to think about.
+
+On the other hand, this constraint can substantially complicate matters when mapping domain layer to the persistenec layer.
+DDD tends to de-emphasise such matters: it aims to be completely agnostic about the persistence layer, with the responsibilities for managing relationships moved (pretty much by definition) into the domain layer.
+
+As a framework though Apache Isis is less dogmatic about such things.
+Generally the domain objects are mapped to a relational database and so we can lean on the referential integrity capabilities of the persistence layer to maintain referential invariants.
+Said another way: we don't tend to require that only roots can maintain roots: we don't see anything wrong in an `InvoiceItem` referencing an `OrderItem`, for example.
+
+Nonetheless the concepts of "aggregate" and "aggregate root" are worth holding onto.
+You'll likely find that you'll define a repository service (discussed in more detail below) for each aggregate root: for example `Order` will have a corresponding `OrderRepository` service.
+Similarly, you may also have a factory service, for example `OrderFactory`.
+However, you are less likely to have a repository service for the parts of an aggregate root: the role of retrieving ``OrderItem``s should fall to the `Order` (typically by way of lazy loading of an "items" collection) rather than through an `OrderItemRepository` service.
+Again, this isn't a hard-n-fast rule, but a good rule of thumb.
+
+
+[TIP]
+====
+Details on how to actually write a domain entity (the programming model for domain entities) is
+xref:../ugfun/ugfun.adoc#_ugfun_programming-model_domain-entities[here].
+====
+

http://git-wip-us.apache.org/repos/asf/isis/blob/f6f6a40b/adocs/documentation/src/main/asciidoc/guides/ugfun/_ugfun_building-blocks_types-of-domain-objects_domain-services.adoc
----------------------------------------------------------------------
diff --git a/adocs/documentation/src/main/asciidoc/guides/ugfun/_ugfun_building-blocks_types-of-domain-objects_domain-services.adoc b/adocs/documentation/src/main/asciidoc/guides/ugfun/_ugfun_building-blocks_types-of-domain-objects_domain-services.adoc
new file mode 100644
index 0000000..726c004
--- /dev/null
+++ b/adocs/documentation/src/main/asciidoc/guides/ugfun/_ugfun_building-blocks_types-of-domain-objects_domain-services.adoc
@@ -0,0 +1,66 @@
+[[_ugfun_building-blocks_types-of-domain-objects_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/
+
+
+_Domain services_ are (usually) singleton stateless services that provide additional functionality.
+Domain services consist of a set of logically grouped actions, and as such follow the same conventions as for entities.
+However, a service cannot have (persisted) properties, nor can it have (persisted) collections.
+
+A very common type of domain service is a repository, that is used to look up existing instances of a domain entity.
+For example, for the `Customer` entity there may be a `CustomerRepository`, while for `Order` entity there may be an `OrderRepository`.
+
+Similarly, entities might also have a corresponding factory service: a `CustomerFactory` or an `OrderFactory`; Evans' link:http://books.google.com/books/about/Domain_Driven_Design.html?id=hHBf4YxMnWMC[Domain Driven Design], draws a clear distinction is made between a factory (that creates object) and a repository (that is used to find existing objects).
+
+On the other hand, from an end-users' perspective the act of finding an existing object vs creating a new one are quite closely related.
+For this reason, in Apache Isis it's therefore quite common to have a single domain service that acts as both a factory and a repository (and is usually called just a "repository").
+
+The behaviour of these services is rendered in various ways, though the most obvious is as the menu actions on the top-level menu bars in the xref:../ugvw/ugvw.adoc#[Wicket viewer]'s UI.
+
+Domain services can also be used for a number of other purposes:
+
+* to provide additional non-UI functionality; an example being to perform an address geocoding lookup against the google-maps API, or to perform some calculation, or attach a barcode, send an email etc
+
+* to act as a subscribers to the event bus, potentially influencing events fired by some other module (a key technique for decoupling large applications) +
++
+This is discussed in more detail below, in the section on xref:../ugfun/ugfun.adoc#_ugfun_building-blocks_events[events].
+
+* to implement an link:https://en.wikipedia.org/wiki/Service_provider_interface[SPI] of the Apache Isis framework, most notably cross-cutting concerns such as security, command profiling, auditing and publishing.
+
+* to contribute behaviour or (derived) state to entities/view models. +
++
+
+[NOTE]
+====
+Mixins can do everything that contributed services can, and have a cleaner programming model.
+As such, contributed services should be considered a deprecated feature; it may be removed in a future release.
+====
+
+Domain objects of any type (entities, other services, view models, mixins) can also delegate to domain services; domain services are automatically injected into every other domain object.
+This injection of domain services into entities is significant: it allows business logic to be implemented in the domain entities, rather than have it "leach away" into
+supporting service layers.
+Said another way: it is the means by which Apache Isis helps you avoid the anaemic domain model anti-pattern.
+
+Domain services are instantiated once and once only by the framework, and are used to centralize any domain logic that does not logically belong in a domain entity or value.
+
+[TIP]
+====
+Details on how to actually write a domain service (the programming model for domain services) is
+xref:../ugfun/ugfun.adoc#_ugfun_programming-model_domain-services[here].
+====
+
+
+== Hexagonal Arch. + services
+
+It's worth extending the xref:../ugfun/ugfun.adoc#_ugfun_core-concepts_philosophy_hexagonal-architecture[Hexagonal Architecture] to show where domain services fit in:
+
+.The hexagonal architecture with Isis addons
+image::{_imagesdir}core-concepts/philosophy/hexagonal-architecture-addons.png[width="700px"]
+
+The (non-ASF) link:http://isisaddons.org[Isis Addons] provide SPI implementations of the common cross-cutting concerns.
+They also provide a number of APIs for domain objects to invoke (not shown in the diagram).
+You can also write your own domain services as well, for example to interface with some external CMS system, say.
+
+

http://git-wip-us.apache.org/repos/asf/isis/blob/f6f6a40b/adocs/documentation/src/main/asciidoc/guides/ugfun/_ugfun_building-blocks_types-of-domain-objects_mixins.adoc
----------------------------------------------------------------------
diff --git a/adocs/documentation/src/main/asciidoc/guides/ugfun/_ugfun_building-blocks_types-of-domain-objects_mixins.adoc b/adocs/documentation/src/main/asciidoc/guides/ugfun/_ugfun_building-blocks_types-of-domain-objects_mixins.adoc
new file mode 100644
index 0000000..a663702
--- /dev/null
+++ b/adocs/documentation/src/main/asciidoc/guides/ugfun/_ugfun_building-blocks_types-of-domain-objects_mixins.adoc
@@ -0,0 +1,56 @@
+[[_ugfun_building-blocks_types-of-domain-objects_mixins]]
+= Mixins
+: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/
+
+
+The final type of domain object is the *mixin*.
+These are similar to traits or extension methods in other programming languages, in that they contribute (or rather, mixin) both behaviour or (derived) state to entities/view models.
+
+A mixin object allows one class to contribute behaviour - actions, (derived) properties and (derived) collections - to another domain object, either a domain entity or view model.
+
+The allows the app to stay decoupled, so that it doesn't degrade into the proverbial link:http://www.laputan.org/mud/mud.html#BigBallOfMud["big ball of mud"].
+Mixins allow dependencies to be inverted, so that the dependencies between modules can be kept acyclic and under control.
+
+For example, the contributee (eg `Customer`, being mixed into) is in one module, while the contributor mixin (`DocumentHolder_documents`) is in some other module.
+The `customer` module knows about the `document` module, but not vice versa.
+
+Mixins are also a convenient mechanism for grouping functionality even for a concrete type, helping to rationalize about the dependency between the data and the behaviour.
+Each mixin is in effect a single behavioural "responsibility" of the domain object.
+
+
+There are also practical reasons for moving behaviour out of entities even within the same module, because structuring your application this way helps support hot-reloading of Java classes (so that you can modify and recompile your application without having to restart it).
+This can provide substantial productivity gains.
+
+The Hotspot JVM has limited support for hot reloading; generally you can change method implementations but you cannot introduce new methods.
+However, the link:https://dcevm.github.io/[DCEVM] open source project will patch the JVM to support much more complete hot reloading support.
+There are also, of course, commercial products such as JRebel.
+
+The main snag in all this is the DataNucleus enhancer... any change to entities is going to require the entity to be re-enhanced, and the JDO metamodel recreated, which invariably breaks things.
+So hot-reloading of an app whose fundamental structure is changing is likely to remain a no-no.
+
+However, chances are that the structure of your domain objects (the data) will change much less rapidly than the behaviour of those domain objects.
+Thus, it's the behaviour that you're most likely wanting to change while the app is still running.
+If you move that behaviour out into mixins, then these can be reloaded happily.
+(And when running in prototype mode), Apache Isis will automatically recreate the portion of the metamodel for any domain object as it is rendered.
+
+[TIP]
+====
+Details on how to actually write a mixin (the programming model for mixins) is
+xref:../ugfun/ugfun.adoc#_ugfun_programming-model_mixins[here].
+====
+
+
+.DCI Architecture
+****
+Mixins are an implementation of the link:http://www.artima.com/articles/dci_vision.html[DCI architecture] architecture, as formulated and described by link:https://en.wikipedia.org/wiki/Trygve_Reenskaug[Trygve Reenskaug] and link:https://en.wikipedia.org/wiki/Jim_Coplien[Jim Coplien].
+Reenskaug was the inventor of the MVC pattern (and also the external examiner for Richard Pawson's PhD thesis), while Coplien has a long history in object-orientation, C++ and patterns.
+
+DCI stands for Data-Context-Interaction and is presented as an evolution of object-oriented programming, but one where behaviour is bound to objects dynamically rather than statically in some context or other.
+The mixin pattern is Apache Isis' straightforward take on the same basic concept.
+
+You might also wish to check out link:http://zest.apache.org[Apache Zest] (formerly Qi4J), which implements a much more general purpose implementation of the same concepts.
+****
+
+

http://git-wip-us.apache.org/repos/asf/isis/blob/f6f6a40b/adocs/documentation/src/main/asciidoc/guides/ugfun/_ugfun_building-blocks_types-of-domain-objects_view-models.adoc
----------------------------------------------------------------------
diff --git a/adocs/documentation/src/main/asciidoc/guides/ugfun/_ugfun_building-blocks_types-of-domain-objects_view-models.adoc b/adocs/documentation/src/main/asciidoc/guides/ugfun/_ugfun_building-blocks_types-of-domain-objects_view-models.adoc
new file mode 100644
index 0000000..bc08274
--- /dev/null
+++ b/adocs/documentation/src/main/asciidoc/guides/ugfun/_ugfun_building-blocks_types-of-domain-objects_view-models.adoc
@@ -0,0 +1,162 @@
+[[_ugfun_building-blocks_types-of-domain-objects_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.
+End users interact with view models in the same way as a domain entity, indeed they are unlikely to distinguish one from the other.
+
+However, whereas a domain entities is mapped to a datastore, view models are not.
+Instead they are recreated dynamically by serializing their state, ultimately into the URL itself (meaning their state it is in effect implicitly managed by the client browser).
+You will notice that the URL for view models (as shown in xref:../ugvw/ugvw.adoc#[Wicket viewer] or xref:../ugvro/ugvro.adoc#[RestfulObjects viewer]) tends to be quite long.
+
+This capability opens up a number of more advanced use cases:
+
+* In the same way that an (RDBMS) database view can aggregate and abstract from multiple underlying database tables, so a view model sits on top of one or many underlying entities.
+
+* A view model could also be used as a proxy for some externally managed entity, accessed over a web service or REST API; it could even be a representation of state held in-memory (such as user preferences, for example).
+
+* view models can also be used to support a particular use case.
+An example that comes to mind is to expose a list of scanned PDFs to be processed as an "intray", showing the list of PDFs on one side of the page, and the current PDF being viewed on the other.
+Such view models are part of the application layer, not part of the domain layer (where entities live).
+
+We explore these use cases in more detail below.
+
+
+[TIP]
+====
+Details on how to actually write a view model (the programming model for view models) is
+xref:../ugfun/ugfun.adoc#_ugfun_programming-model_view-models[here].
+====
+
+
+
+[[__ugfun_building-blocks_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_building-blocks_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_building-blocks_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).
+****
+
+
+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; view models are the tool of choice.
+
+[WARNING]
+====
+We strongly recommend that you build your applications from the domain layer up, rather than from the view model down.
+====
+
+
+[[__ugfun_building-blocks_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_building-blocks_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_building-blocks_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.
+
+
+
+

http://git-wip-us.apache.org/repos/asf/isis/blob/f6f6a40b/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
deleted file mode 100644
index bd6b28e..0000000
--- a/adocs/documentation/src/main/asciidoc/guides/ugfun/_ugfun_class-structure.adoc
+++ /dev/null
@@ -1,46 +0,0 @@
-[[_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, domain services, view models and mixins.
-Dependent on the sort of domain object, the class methods represent
-both state -- (single-valued) properties and (multi-valued) collections -- and behaviour -- actions.
-
-More specifically, both entities and view models can have properties, collections and actions, while domain services have just actions.
-Mixins also define only actions, though depending on their semantics they may be rendered as derived properties or collections on the domain object to which they contribute.
-
-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/f6f6a40b/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
deleted file mode 100644
index 613cbb9..0000000
--- a/adocs/documentation/src/main/asciidoc/guides/ugfun/_ugfun_class-structure_actions.adoc
+++ /dev/null
@@ -1,264 +0,0 @@
-[[_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/f6f6a40b/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
deleted file mode 100644
index a3e09da..0000000
--- a/adocs/documentation/src/main/asciidoc/guides/ugfun/_ugfun_class-structure_collections.adoc
+++ /dev/null
@@ -1,121 +0,0 @@
-[[_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/f6f6a40b/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
deleted file mode 100644
index ce7c3e7..0000000
--- a/adocs/documentation/src/main/asciidoc/guides/ugfun/_ugfun_class-structure_domain-services.adoc
+++ /dev/null
@@ -1,155 +0,0 @@
-[[_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/f6f6a40b/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
deleted file mode 100644
index fb09fe1..0000000
--- a/adocs/documentation/src/main/asciidoc/guides/ugfun/_ugfun_class-structure_inject-services.adoc
+++ /dev/null
@@ -1,103 +0,0 @@
-[[_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/f6f6a40b/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
deleted file mode 100644
index a0a926a..0000000
--- a/adocs/documentation/src/main/asciidoc/guides/ugfun/_ugfun_class-structure_properties-vs-parameters.adoc
+++ /dev/null
@@ -1,38 +0,0 @@
-[[_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)
-|===
-
-