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 2015/12/22 23:40:31 UTC
[1/4] isis git commit: ISIS-1243: reworking the ugbtb (beyond the
basics) guide a little, breaking out and renaming the techniques chapter
Repository: isis
Updated Branches:
refs/heads/master c2eb5eec9 -> 29452af6e
http://git-wip-us.apache.org/repos/asf/isis/blob/29452af6/adocs/documentation/src/main/asciidoc/guides/_ugbtb_programming-model.adoc
----------------------------------------------------------------------
diff --git a/adocs/documentation/src/main/asciidoc/guides/_ugbtb_programming-model.adoc b/adocs/documentation/src/main/asciidoc/guides/_ugbtb_programming-model.adoc
index 9b587b9..9094cf4 100644
--- a/adocs/documentation/src/main/asciidoc/guides/_ugbtb_programming-model.adoc
+++ b/adocs/documentation/src/main/asciidoc/guides/_ugbtb_programming-model.adoc
@@ -1,5 +1,5 @@
[[_ugbtb_programming-model]]
-= Programming Model
+= Customizing the Prog Model
: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/
http://git-wip-us.apache.org/repos/asf/isis/blob/29452af6/adocs/documentation/src/main/asciidoc/guides/_ugbtb_programming-model_custom-validator.adoc
----------------------------------------------------------------------
diff --git a/adocs/documentation/src/main/asciidoc/guides/_ugbtb_programming-model_custom-validator.adoc b/adocs/documentation/src/main/asciidoc/guides/_ugbtb_programming-model_custom-validator.adoc
index a60e876..37ad7e8 100644
--- a/adocs/documentation/src/main/asciidoc/guides/_ugbtb_programming-model_custom-validator.adoc
+++ b/adocs/documentation/src/main/asciidoc/guides/_ugbtb_programming-model_custom-validator.adoc
@@ -17,7 +17,7 @@ You can also impose your own application-specific rules by installing your own m
[TIP]
====
-Isis' xref:ugfun.adoc#_ugfun_isis-maven-plugin[Maven plugin] will also validate the domain object model during build time.
+Isis' xref:cg.adoc#_cg_isis-maven-plugin[Maven plugin] will also validate the domain object model during build time.
====
http://git-wip-us.apache.org/repos/asf/isis/blob/29452af6/adocs/documentation/src/main/asciidoc/guides/_ugbtb_programming-model_finetuning.adoc
----------------------------------------------------------------------
diff --git a/adocs/documentation/src/main/asciidoc/guides/_ugbtb_programming-model_finetuning.adoc b/adocs/documentation/src/main/asciidoc/guides/_ugbtb_programming-model_finetuning.adoc
index cf7e6ac..04a7203 100644
--- a/adocs/documentation/src/main/asciidoc/guides/_ugbtb_programming-model_finetuning.adoc
+++ b/adocs/documentation/src/main/asciidoc/guides/_ugbtb_programming-model_finetuning.adoc
@@ -58,7 +58,7 @@ To include/exclude more than one `FacetFactory`, specify as a comma-separated li
[TIP]
====
-This http://isis.markmail.org/thread/472c3mrvcgnripst[thread] from the users mailing list (in Apr 2014) shows a typical customization (to enable per-instance security) (though note that xref:ugbtb.adoc#_ugbtb_more-advanced_multi-tenancy[Multi-Tenancy] is now a better solution to that particular use-case.
+This http://isis.markmail.org/thread/472c3mrvcgnripst[thread] from the users mailing list (in Apr 2014) shows a typical customization (to enable per-instance security) (though note that xref:ugbtb.adoc#_ugbtb_other-techniques_multi-tenancy[Multi-Tenancy] is now a better solution to that particular use-case.
====
http://git-wip-us.apache.org/repos/asf/isis/blob/29452af6/adocs/documentation/src/main/asciidoc/guides/_ugbtb_view-models.adoc
----------------------------------------------------------------------
diff --git a/adocs/documentation/src/main/asciidoc/guides/_ugbtb_view-models.adoc b/adocs/documentation/src/main/asciidoc/guides/_ugbtb_view-models.adoc
new file mode 100644
index 0000000..2de5852
--- /dev/null
+++ b/adocs/documentation/src/main/asciidoc/guides/_ugbtb_view-models.adoc
@@ -0,0 +1,19 @@
+[[_ugbtb_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 a type of domain object (with state, behaviour etc) but where the state is _not_ persisted into the
+ JDO/DataNucleus-managed database, but is instead converted to/from a string memento, and held by the calling client.
+This opens up a number of more advanced use cases.
+
+In this topic we'll explore those use cases, and learn the programming model and conventions to use view models in your application.
+
+
+include::_ugbtb_view-models_use-cases.adoc[leveloffset=+1]
+include::_ugbtb_view-models_programming-model.adoc[leveloffset=+1]
+include::_ugbtb_view-models_jaxb.adoc[leveloffset=+1]
+
+
http://git-wip-us.apache.org/repos/asf/isis/blob/29452af6/adocs/documentation/src/main/asciidoc/guides/_ugbtb_view-models_jaxb.adoc
----------------------------------------------------------------------
diff --git a/adocs/documentation/src/main/asciidoc/guides/_ugbtb_view-models_jaxb.adoc b/adocs/documentation/src/main/asciidoc/guides/_ugbtb_view-models_jaxb.adoc
new file mode 100644
index 0000000..be0d561
--- /dev/null
+++ b/adocs/documentation/src/main/asciidoc/guides/_ugbtb_view-models_jaxb.adoc
@@ -0,0 +1,240 @@
+[[_ugbtb_view-models_jaxb]]
+= JAXB-annotated DTOs (`1.11.0-SNAPSHOT`)
+: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 provides some recommended practices if using JAXB and `@XmlRootElement` to define domain models. The
+examples are taken from the (non-ASF) http://github.com/isisaddons/isis-app-todoapp[Isis addons' todoapp].
+
+
+
+[[_ugbtb_view-models_jaxb_using-packages-to-version]]
+== Use packages to version DTOs
+
+The whole point of using DTOs (in Apache Isis, at least) is to define a formal contact between two interoperating but
+independent applications. Since the only thing we can predicate about the future with any certainty is that it one or
+both of these applications will change, we should version DTOs from the get-go.
+
+With XML every element may be defined as belonging to a particular namespace; in JAXB this translates to Java packages.
+We therefore should place each DTO within its own package, and that package should include a version identifier.
+
+For example, the http://github.com/isisaddons/isis-app-todoapp[Isis addons' todoapp] defines this DTO (as a versioned
+representation of its underlying `ToDoItem` entity):
+
+[source,java]
+----
+@XmlRootElement(name = "toDoItemDto") // <1>
+@XmlType(
+ propOrder = { // <2>
+ "description",
+ "category",
+ "subcategory",
+ "cost"
+ }
+)
+@DomainObjectLayout(
+ titleUiEvent = TitleUiEvent.Doop.class // <3>
+)
+public class ToDoItemDto implements Dto {
+ @XmlElement(required = true)
+ @Getter @Setter // <4>
+ protected String description;
+
+ @XmlElement(required = true)
+ @Getter @Setter
+ protected String category;
+
+ @Getter @Setter
+ protected String subcategory;
+
+ @Getter @Setter
+ protected BigDecimal cost;
+}
+----
+<1> identifies this class as a view model and defines the root element for JAXB serialization
+<2> all properties in the class must be listed; (they can be ignored using `@XmlTransient`)
+<3> demonstrating use of UI events for a subscriber to provide the DTO's title; see xref:rgant.adoc#_rgant-DomainObjectLayout_titleUiEvent[`@DomainObjectLayout#titleUiEvent()`].
+<4> optional; JAXB metadata can specify such attributes as required/optional
+
+
+For the package in which the DTO class resides, we define a corresponding namespace. This goes in `package-info.java`:
+
+[source,java]
+----
+@javax.xml.bind.annotation.XmlSchema(
+ namespace = "http://viewmodels.app.todoapp/todoitem/v1_0/todoitem.xsd", // <1>
+ elementFormDefault = javax.xml.bind.annotation.XmlNsForm.QUALIFIED
+)
+package todoapp.app.viewmodels.todoitem.v1_0; // <2>
+----
+<1> the namespace URI, used by the DTO residing in this package. There is no requirement for this to correspond to a physical URL, but it should be unique (this
+usually implies the usage of a company domain name).
+<2> the package in which the DTO resides.
+
+Note how both the XML namespace and package are broadly equivalent to each other; in particular note that they both
+also include a version "v1_0".
+
+
+
+
+[[_ugbtb_view-models_jaxb_semantic-versioning]]
+== Semantic Versioning
+
+Versioning DTOs enables us to make changes without breaking existing consumers of the data. We can distinguish two
+types of changes:
+
+* backwardly compatible changes
+* breaking changes.
+
+Following link:http://semver.org[semantic versioning] approach, we suggest using `v1_0`, `v1_1`, `v1_2` etc as the
+package version for a sequence of backwardly compatible changes, then bump up to `v2_0` for a breaking change.
+
+Backwardly compatible changes can generally (always?) be modelled using class inheritance. Thus, `v1_1.ToDoItemDto`
+is a subclass of `v1_0.ToDoItemDto`. This makes sense too: OO inheritance means "is-substitutable-for", so what is
+true in an OO context is true when processing XML documents.
+
+On the other hand, breaking changes probably (always?) imply that the next version of the DTO does not use inheritance.
+Thus `v2_0.ToDoItemDto` might share many of the same properties as the `v1_1.ToDoItemDto`, but any reuse would be
+copy-n-paste rather than through inheritance.
+
+To see this in practice, here's (the outline of) v1.1 of `ToDoItemDto`:
+
+[source,java]
+----
+package todoapp.app.viewmodels.todoitem.v1_1;
+...
+@XmlRootElement(name = "toDoItemDto")
+@XmlType(
+ propOrder = {
+ "toDoItem",
+ "similarItems"
+ }
+)
+public class ToDoItemDto extends todoapp.app.viewmodels.todoitem.v1_0.ToDoItemDto {
+ ...
+}
+----
+
+
+The corresponding `package-info.java` is similar to that for `v1_0`, though note how it also defines a namespace prefix
+for `v1_0`:
+
+[source,java]
+----
+@javax.xml.bind.annotation.XmlSchema(
+ namespace = "http://viewmodels.app.todoapp/todoitem/v1_1/todoitem.xsd", <!--1-->
+ xmlns = {
+ @javax.xml.bind.annotation.XmlNs( <!--2-->
+ namespaceURI = "http://isis.apache.org/schema/common",
+ prefix = "common"
+ ),
+ @javax.xml.bind.annotation.XmlNs(
+ namespaceURI = "http://viewmodels.app.todoapp/todoitem/v1_0/todoitem.xsd",
+ prefix = "todoitem-v1_0"
+ )
+ },
+ elementFormDefault = javax.xml.bind.annotation.XmlNsForm.QUALIFIED
+)
+package todoapp.app.viewmodels.todoitem.v1_1;
+----
+<1> namespace URI for DTO in this class.
+<2> aliases for any other namespaces referenced.
+
+
+
+[[_ugbtb_view-models_jaxb_referencing-domain-entities]]
+== Referencing Domain Entities
+
+It's quite common for view models to be "backed by" (be projections of) some underlying domain entity. The
+`ToDoItemDto` we've been using as the example in this section is an example: there is an underlying `ToDoItem` entity.
+
+It wouldn't make sense to serialize out the state of a persistent entity: the point of a DTO is to act as a facade
+on top of the entity so that the implementation details (of the entity's structure) don't leak out to the consumer.
+However, the identity of the underlying entity can be well defined; Apache Isis defines the
+xref:rgcms.adoc#_rgcms_schema-common[Common schema] which defines the `<oid-dto>` element (and corresponding `OidDto` class):
+the object's type and its identifier. This is basically a formal XML equivalent to the `Bookmark` object obtained
+from the xref:rgsvc.adoc#_rgsvc_api_BookmarkService[`BookmarkService`].
+
+There is only one requirement to make this work: every referenced domain entity must be annotated with
+xref:rgant.adoc#_rgant-XmlJavaTypeAdapter[`@XmlJavaTypeAdapter`], specifying the framework-provided
+`PersistentEntityAdapter.class`. This class is similar to the `BookmarkService`: it knows how to create an `OidDto`
+from an object reference.
+
+Thus, in our view model we can legitimately write:
+
+[source,java]
+----
+package todoapp.app.viewmodels.todoitem.v1_1;
+...
+public class ToDoItemDto extends todoapp.app.viewmodels.todoitem.v1_0.ToDoItemDto {
+ ...
+ @Getter @Setter
+ protected ToDoItem toDoItem;
+}
+----
+
+All we need to do is remember to add that `@XmlJavaTypeAdapter` annotation to the referenced entity:
+
+[source,java]
+----
+@XmlJavaTypeAdapter(PersistentEntityAdapter.class)
+public class ToDoItem ... {
+ ...
+}
+----
+
+
+
+[[_ugbtb_view-models_jaxb_collections]]
+== Collections
+
+It's also possible for a DTO to hold collections of objects. These can be of any type, either simple properties, or
+references to other objects.
+
+The only bit of boilerplate that is required is the `@XmlElementWrapper` annotation. This instructs JAXB to create
+an XML element (based on the field name) to contain each of the elements. (If this is omitted then the contents of
+the collection are at the same level as the properties; almost certainly not what is required).
+
+For example, the v1.1 of the `ToDoItemDto` could also contain:
+
+[source,java]
+----
+package todoapp.app.viewmodels.todoitem.v1_1;
+...
+public class ToDoItemDto extends todoapp.app.viewmodels.todoitem.v1_0.ToDoItemDto {
+ ...
+ @XmlElementWrapper
+ @XmlElement(name = "todoItem")
+ @Getter @Setter
+ protected List<ToDoItem> similarItems = Lists.newArrayList();
+}
+----
+
+
+There's nothing to prevent a JAXB DTO from containing rich graphs of data, parent containing children containing
+children. Be aware though that all of this state will become the DTO's memento, ultimately converted into a URL-safe
+form, by way of the xref:rgsvc.adoc#_rgsvc_spi_UrlEncodingService[`UrlEncodingService`].
+
+There are limits to the lengths of URLs, however. Therefore the DTO should not include state that can easily be
+derived from other information. If the URL does exceed limits, then provide a custom implementation of `UrlEncodingService`
+to handle the memento string in some other fashion (eg substituting it with a GUID, with the memento cached somehow
+on the server).
+
+
+
+
+
+== Generating XSDs and DTOs
+
+The xref:cg.adoc#_cg_isis-maven-plugin[Apache Isis maven plugin] provides the xref:cg.adoc#_cg_isis-maven-plugin_xsd[xsd] goal that allows the XSDs to be generated from any JAXB-annotated view models.
+These use the xref:rgsvc.adoc#_rgsvc_api_JaxbService[`JaxbService`] to generate the schemas; using the
+standard `schemagen` command line will not correctly interpret any references to domain entities as OIDs.
+
+The documentation for the `xsd` goal also explains how to generate DTO classes from the generated XSDs. Note that these
+DTOs are not the same as the JAXB view models; they can be used outside of an Isis application, for example in a
+standalone subscriber running on an enterprise service bus such as Apache Camel.
+
http://git-wip-us.apache.org/repos/asf/isis/blob/29452af6/adocs/documentation/src/main/asciidoc/guides/_ugbtb_view-models_programming-model.adoc
----------------------------------------------------------------------
diff --git a/adocs/documentation/src/main/asciidoc/guides/_ugbtb_view-models_programming-model.adoc b/adocs/documentation/src/main/asciidoc/guides/_ugbtb_view-models_programming-model.adoc
new file mode 100644
index 0000000..59a62b3
--- /dev/null
+++ b/adocs/documentation/src/main/asciidoc/guides/_ugbtb_view-models_programming-model.adoc
@@ -0,0 +1,87 @@
+[[_ugbtb_view-models_programming-model]]
+= Programming Model
+: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/
+
+
+
+So much for the theory; how should view models be implemented? Fundamentally all view models' state is serialized into
+a string memento; this memento is then held by the client (browser) in the form of a URL. As you might imagine, this
+URL can become quite long, but Apache Isis offers a mechanism (the xref:rgsvc.adoc#_rgsvc_spi_UrlEncodingService[`UrlEncodingService`]) if it exceeds the maximum length for a URL
+(2083 characters). Also, of course, this string memento must only contain characters that it is valid for use within
+a URL.
+
+While the underlying technique is the same irrespective of use case, the programming model provides various ways of
+defining a view model so that the original intent is not lost. They are:
+
+.View model programming model
+[cols="1a,4a,2a", options="header"]
+|===
+
+| Use case
+| Code
+| Description
+
+
+| External entity
+|[source,java]
+----
+@DomainObject(nature=Nature.EXTERNAL_ENTITY)
+public class CustomerRecordOnSAP { ... }
+----
+|Annotated with xref:rgant.adoc#_rgant-DomainObject_nature[`@DomainObject#nature()`] and a nature of `EXTERNAL_ENTITY`, with memento derived automatically from the properties of the domain object. Collections are ignored, as are any properties annotated as xref:rgant.adoc#_rgant-Property_notPersisted[not persisted].
+
+| In-memory entity
+|[source,java]
+----
+@DomainObject(nature=Nature.INMEMORY_ENTITY)
+public class Log4JAppender { ... }
+----
+|As preceding, but using a nature of `INMEMORY_ENTITY`.
+
+|Application view model
+|[source,java]
+----
+@DomainObject(nature=Nature.VIEW_MODEL)
+public class Dashboard { ... }
+----
+|As preceding, but using a nature of `VIEW_MODEL`.
+
+|Application view model
+|
+[source,java]
+----
+@ViewModel
+public class Dashboard { ... }
+----
+
+|Annotated with xref:rgant.adoc#_rgant-ViewModel[`@ViewModel`] annotation (effectively just an alias)' memento is as preceding: from "persisted" properties, collections ignored
+
+|Application view model
+|
+[source,java]
+----
+public class ExcelUploadManager implements ViewModel {
+ public String viewModelMemento() { ... }
+ public void viewModelInit(String memento) { ... }
+}
+|Implement xref:rgcms.adoc#_rgcms_classes_super_ViewModel[`ViewModel`] interface. The memento is as defined by the
+interface's methods: the programmer has full control (but also full responsibility) for the string memento.
+
+|DTO (`1.11.0-SNAPSHOT`)
+|
+[source,java]
+----
+@XmlRootElement("customer")
+public class CustomerDto { ... }
+----
+|Annotate using JAXB xref:rgant.adoc#_rgant-XmlRootElement[`@XmlRootElement`] annotation. Memento
+derived automatically by serializing the XML graph as implied by the JAXB annotations. Note that (unlike `@ViewModel`
+et al) this state _can_ include collections.
+|===
+
+JAXB-annotated DTOs are discussed in more detail immediately xref:rg.adoc#_ugbtb_view-models_jaxb[below].
+
+
+
http://git-wip-us.apache.org/repos/asf/isis/blob/29452af6/adocs/documentation/src/main/asciidoc/guides/_ugbtb_view-models_use-cases.adoc
----------------------------------------------------------------------
diff --git a/adocs/documentation/src/main/asciidoc/guides/_ugbtb_view-models_use-cases.adoc b/adocs/documentation/src/main/asciidoc/guides/_ugbtb_view-models_use-cases.adoc
new file mode 100644
index 0000000..d92e80d
--- /dev/null
+++ b/adocs/documentation/src/main/asciidoc/guides/_ugbtb_view-models_use-cases.adoc
@@ -0,0 +1,142 @@
+[[_ugbtb_view-models_use-cases]]
+= Use Cases
+:Notice: Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements. See the NOTICE file distributed with this work for additional information regarding copyright ownership. The ASF licenses this file to you under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at. http://www.apache.org/licenses/LICENSE-2.0 . Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.
+:_basedir: ../
+:_imagesdir: images/
+
+
+When developing an Apache Isis application you will most likely start off with the persistent domain entities:
+`Customer`, `Order`, `Product`, and so on. For some applications this may well suffice. However, if the application
+needs to integrate with other systems, or if the application needs to support reasonably complex business processes, then you may need to look beyond just domain entities. This section explores these use cases.
+
+== 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).
+====
+
+
+== 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.
+
+
+== 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.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).
+****
+
+== DTOs (`1.11.0-SNAPSHOT`)
+
+DTOs (data transfer objects) are simple classes that (according to link:https://en.wikipedia.org/wiki/Data_transfer_object[wikipedia]) "carries 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.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.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.
+
+Instead, a view model can be defined to act as a DTO. To put this formal contract onto a solid footing, this view
+model can (as of `1.11.0-SNAPSHOT`) simply be defined as a JAXB-annotated entity; this allows the consumer to obtain
+the DTO in XML format along with a corresponding XSD schema describing the structure of that XML. These XML
+representations can be surfaced by the xref:ugvro.adoc#[RestfulObjects viewer] (by implementing
+the xref:rgsvc.adoc#_rgsvc_spi_ContentMappingService[`ContentMappingService`]); the XSD can be obtained
+using the xref:rgsvc.adoc#_rgsvc_api_JaxbService[`JaxbService`]. Using the formalism of XML also allows
+DTOs to be carefully and properly versioned using XML namespaces.
+
+[TIP]
+====
+If the view model DTO implements the xref:rgcms.adoc#_rgcms_classes_mixins_Dto[`Dto`] marker interface, then the framework
+will also provide the ability to download the XML or its XSD directly from the UI.
+====
+
+In case it's not clear, these DTOs are still usable as "regular" view models; they will render in the xref:ugvw.adoc#[Wicket viewer] just like any other. Indeed (as the xref: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 view model alternatives.
+
+
+== ESB Subscribers
+
+One important variation of the DTO use case concerns subscribers on an enterprise event bus such as
+link:http://camel.apache.org[Apache Camel(TM)] and similar.
+
+A xref:rgsvc.adoc#_rgsvc_spi_PublishingService[`PublishingService`] implementation (eg that provided by
+(non-ASF) http://github.com/isisaddons/isis-module-publishmq[Isis addons' publishmq] module) can publish XML events
+onto a message queue, typically representing action invocations within the originating Isis application. The ESB
+(Apache Camel) then dispatches this event to all interested subscribers. These subscribers represent external systems
+in the enterprise, managed by other teams, and so act as the third-party consumers of the data.
+
+Rather than try to anticipate their requirements and push the data that these subscribers might need into the original
+XML event (a hopeless task), DTO objects can be defined to allow these consumers to call back to the publishing Isis
+application to obtain the data they need.
+
+
http://git-wip-us.apache.org/repos/asf/isis/blob/29452af6/adocs/documentation/src/main/asciidoc/guides/_ugfun_core-concepts_building-blocks.adoc
----------------------------------------------------------------------
diff --git a/adocs/documentation/src/main/asciidoc/guides/_ugfun_core-concepts_building-blocks.adoc b/adocs/documentation/src/main/asciidoc/guides/_ugfun_core-concepts_building-blocks.adoc
index d864f24..99a96d1 100644
--- a/adocs/documentation/src/main/asciidoc/guides/_ugfun_core-concepts_building-blocks.adoc
+++ b/adocs/documentation/src/main/asciidoc/guides/_ugfun_core-concepts_building-blocks.adoc
@@ -229,7 +229,7 @@ We introduce view models here because they do get mentioned quite often within t
we do consider them a more advanced topic; we generally recommend that you build your applications from the domain
layer up, rather than from the view model down.
-For further discussion on view models, see xref:ugbtb.adoc#_ugbtb_more-advanced_view-models[this topic].
+For further discussion on view models, see xref:ugbtb.adoc#_ugbtb_view-models[this topic].
@@ -265,8 +265,8 @@ In Apache Isis these are all implemented as domain services. Indeed, it is quit
NOTE: TODO
-For more information, see xref:ugbtb.adoc#_ugbtb_more-advanced_decoupling_contributions[this topic on contribution]s, and
-xref:ugbtb.adoc#_ugbtb_more-advanced_decoupling_mixins[this topic on mixin]s.
+For more information, see xref:ugbtb.adoc#_ugbtb_decoupling_contributions[this topic on contribution]s, and
+xref:ugbtb.adoc#_ugbtb_decoupling_mixins[this topic on mixin]s.
http://git-wip-us.apache.org/repos/asf/isis/blob/29452af6/adocs/documentation/src/main/asciidoc/guides/_ugfun_core-concepts_philosophy_aop.adoc
----------------------------------------------------------------------
diff --git a/adocs/documentation/src/main/asciidoc/guides/_ugfun_core-concepts_philosophy_aop.adoc b/adocs/documentation/src/main/asciidoc/guides/_ugfun_core-concepts_philosophy_aop.adoc
index 286296a..e5bf15d 100644
--- a/adocs/documentation/src/main/asciidoc/guides/_ugfun_core-concepts_philosophy_aop.adoc
+++ b/adocs/documentation/src/main/asciidoc/guides/_ugfun_core-concepts_philosophy_aop.adoc
@@ -29,8 +29,8 @@ Isis also draws heavily on the AOP concept of interceptors. Whenever an object
Another example of interceptors are the http://github.com/isisaddons/isis-module-command[Isis addons' command] and http://github.com/isisaddons/isis-module-audit[Isis addons' audit] modules. The command module captures every user interaction that modifies the state of the system (the "cause" of a change) while the audit module captures every change to every object (the "effect" of a change). Again, this is all transparent to the user.
-Apache Isis also has an internal event bus (you can switch between an underlying implementation of Gauva or Axon). A domain event is fired whenever an object is interacted with, and this allows any subscribers to influence the operation (or even veto it). This is a key mechanism in ensuring that Isis applications are maintainable, and we discuss it in depth in the section on xref:ugbtb.adoc#_ugbtb_more-advanced_decoupling[Decoupling]. But fundamentally its relying on this AOP concept of interceptors.
+Apache Isis also has an internal event bus (you can switch between an underlying implementation of Gauva or Axon). A domain event is fired whenever an object is interacted with, and this allows any subscribers to influence the operation (or even veto it). This is a key mechanism in ensuring that Isis applications are maintainable, and we discuss it in depth in the section on xref:ugbtb.adoc#_ugbtb_decoupling[Decoupling]. But fundamentally its relying on this AOP concept of interceptors.
Finally, Isis also a feature that is akin to AOP mix-ins. A "contributed action" is one that is implemented on a domain service but that appears to be a behaviour of rendered domain object. In other words, we can dissociate behaviour from data. That's not always the right thing to do of course. In Richard Pawson's description of the xref:ugfun.adoc#_ugfun_core-concepts_philosophy_naked-objects-pattern[naked objects pattern] he talks about "behaviourally rich" objects, in other words where the business functionality encapsulated the data. But on the other hand sometimes the behaviour and data structures change at different rates. The link:http://en.wikipedia.org/wiki/Single_responsibility_principle[single responsibility principle] says we should only lump code together that changes at the same rate. Apache Isis' support for contributions (not only contributed actions, but also contributed properties and contributed collections) enables this. And again, to loop back to the to
pic of this section, it's an AOP concept that being implemented by the framework.
-The nice thing about aspect orientation is that for the most part you can ignore these cross-cutting concerns and - at least initially at least - just focus on implementing your domain object. Later when your app starts to grow and you start to break it out into smaller modules, you can leverage Apache Isis' AOP support for (xref:ugbtb.adoc#_ugbtb_more-advanced_decoupling_mixins[mixins]), (xref:ugbtb.adoc#_ugbtb_more-advanced_decoupling_contributions[contributions]) and interceptors (the xref:ugbtb.adoc#_ugbtb_more-advanced_decoupling_event-bus[event bus]) to ensure that your codebase remains maintainable.
\ No newline at end of file
+The nice thing about aspect orientation is that for the most part you can ignore these cross-cutting concerns and - at least initially at least - just focus on implementing your domain object. Later when your app starts to grow and you start to break it out into smaller modules, you can leverage Apache Isis' AOP support for (xref:ugbtb.adoc#_ugbtb_decoupling_mixins[mixins]), (xref:ugbtb.adoc#_ugbtb_decoupling_contributions[contributions]) and interceptors (the xref:ugbtb.adoc#_ugbtb_decoupling_event-bus[event bus]) to ensure that your codebase remains maintainable.
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/isis/blob/29452af6/adocs/documentation/src/main/asciidoc/guides/_ugfun_core-concepts_principles_apache-isis-vs_cqrs.adoc
----------------------------------------------------------------------
diff --git a/adocs/documentation/src/main/asciidoc/guides/_ugfun_core-concepts_principles_apache-isis-vs_cqrs.adoc b/adocs/documentation/src/main/asciidoc/guides/_ugfun_core-concepts_principles_apache-isis-vs_cqrs.adoc
index 230ef04..43f87b0 100644
--- a/adocs/documentation/src/main/asciidoc/guides/_ugfun_core-concepts_principles_apache-isis-vs_cqrs.adoc
+++ b/adocs/documentation/src/main/asciidoc/guides/_ugfun_core-concepts_principles_apache-isis-vs_cqrs.adoc
@@ -17,12 +17,12 @@ Comparing CQRS to Apache Isis, the most obvious difference is that Apache Isis d
There are other reasons though why a separate read model might make sense, such as to precompute particular queries, or against denormalized data. In these cases Apache Isis can often provide a reasonable alternative, namely to map domain entities against RDBMS views, either materialized views or dynamic. In such cases there is still only a single physical datastore, and so transactional integrity is retained.
-Or, the CQRS architecture can be more fully implemented with Apache Isis by introducing a separate read model, synchronized using the xref:rgsvc.adoc#_rgsvc_api_PublishingService[`PublishingService`], or using xref:rgcms.adoc#_rgcms_classes_super_AbstractSubscriber[subscribers] on the xref:rgsvc.adoc#_rgsvc_api_EventBusService[`EventBusService`]. One can then use xref:ugbtb.adoc#_ugbtb_more-advanced_view-models[view models] to surface the data in the external read datastore.
+Or, the CQRS architecture can be more fully implemented with Apache Isis by introducing a separate read model, synchronized using the xref:rgsvc.adoc#_rgsvc_api_PublishingService[`PublishingService`], or using xref:rgcms.adoc#_rgcms_classes_super_AbstractSubscriber[subscribers] on the xref:rgsvc.adoc#_rgsvc_api_EventBusService[`EventBusService`]. One can then use xref:ugbtb.adoc#_ugbtb_view-models[view models] to surface the data in the external read datastore.
With respect to commands, Apache Isis does of course support the xref:rgsvc.adoc#_rgsvc_spi_CommandService[`CommandService`] which allows each business action to be reified into a `Command`. However, names are misleading here: Apache Isis' commands are relatively passive, merely recording the intent of the user to invoke some operation. In a CQRS architecture, though, commands take a more active role, locating and acting upon the domain objects. More significantly, in CQRS each command has its own class, such as `PlaceOrderCommand`, instantiated by the client and then executed. With Apache Isis, though, the end-user merely invokes the `placeOrder(...)` action upon the domain object; the framework itself creates the `Command` as a side-effect of this.
In CQRS the commands correspond to the business logic that mutates the system. Whether this logic is part of the command class (`PlaceOrderCommand`) or whether that command delegates to methods on the domain object is an implementation detail; but it certainly is common for the business logic to be wholly within the command object and for the domain object to be merely a data holder of the data within the command/write datastore.
-In Apache Isis this same separation of business logic from the underlying data can be accomplished most straightforwardly using xref:ugbtb.adoc#_ugbtb_more-advanced_decoupling_mixins[mixins] or xref:ugfun.adoc#_ugfun_how-tos_contributed-members[contributions]. In the UI (surfaced by the xref:ugvw.adoc#[Wicket viewer]) or in the REST API (surfaced by the xref:ugvro.adoc#[RestfulObjects viewer]) the behaviour appears to reside on the domain object; however the behaviour actually resides on separate classes and is mixed in (like a trait) only at runtime.
+In Apache Isis this same separation of business logic from the underlying data can be accomplished most straightforwardly using xref:ugbtb.adoc#_ugbtb_decoupling_mixins[mixins] or xref:ugfun.adoc#_ugfun_how-tos_contributed-members[contributions]. In the UI (surfaced by the xref:ugvw.adoc#[Wicket viewer]) or in the REST API (surfaced by the xref:ugvro.adoc#[RestfulObjects viewer]) the behaviour appears to reside on the domain object; however the behaviour actually resides on separate classes and is mixed in (like a trait) only at runtime.
http://git-wip-us.apache.org/repos/asf/isis/blob/29452af6/adocs/documentation/src/main/asciidoc/guides/_ugfun_how-tos_class-structure.adoc
----------------------------------------------------------------------
diff --git a/adocs/documentation/src/main/asciidoc/guides/_ugfun_how-tos_class-structure.adoc b/adocs/documentation/src/main/asciidoc/guides/_ugfun_how-tos_class-structure.adoc
index 4907108..df242af 100644
--- a/adocs/documentation/src/main/asciidoc/guides/_ugfun_how-tos_class-structure.adoc
+++ b/adocs/documentation/src/main/asciidoc/guides/_ugfun_how-tos_class-structure.adoc
@@ -5,7 +5,7 @@
:_imagesdir: images/
-Apache Isis works by building a metamodel of the domain objects: entities, xref:ugbtb.adoc#_ugbtb_more-advanced_view-models[view model]s and services. The class members 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.
+Apache Isis works by building a metamodel of the domain objects: entities, xref:ugbtb.adoc#_ugbtb_view-models[view model]s and services. The class members 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.
http://git-wip-us.apache.org/repos/asf/isis/blob/29452af6/adocs/documentation/src/main/asciidoc/guides/_ugfun_how-tos_class-structure_class-definition.adoc
----------------------------------------------------------------------
diff --git a/adocs/documentation/src/main/asciidoc/guides/_ugfun_how-tos_class-structure_class-definition.adoc b/adocs/documentation/src/main/asciidoc/guides/_ugfun_how-tos_class-structure_class-definition.adoc
index 94ed01c..678508d 100644
--- a/adocs/documentation/src/main/asciidoc/guides/_ugfun_how-tos_class-structure_class-definition.adoc
+++ b/adocs/documentation/src/main/asciidoc/guides/_ugfun_how-tos_class-structure_class-definition.adoc
@@ -18,7 +18,7 @@ In the same way that Java packages act as a namespace for domain objects, it's g
[TIP]
====
-For more on this topic, see the topic discussing modules and xref:ugbtb.adoc#_ugbtb_more-advanced_decoupling[decoupling].
+For more on this topic, see the topic discussing modules and xref:ugbtb.adoc#_ugbtb_decoupling[decoupling].
====
http://git-wip-us.apache.org/repos/asf/isis/blob/29452af6/adocs/documentation/src/main/asciidoc/guides/_ugfun_how-tos_domain-services.adoc
----------------------------------------------------------------------
diff --git a/adocs/documentation/src/main/asciidoc/guides/_ugfun_how-tos_domain-services.adoc b/adocs/documentation/src/main/asciidoc/guides/_ugfun_how-tos_domain-services.adoc
index eb70bdc..26a8119 100644
--- a/adocs/documentation/src/main/asciidoc/guides/_ugfun_how-tos_domain-services.adoc
+++ b/adocs/documentation/src/main/asciidoc/guides/_ugfun_how-tos_domain-services.adoc
@@ -173,7 +173,7 @@ public OrderContributions {
<3> Only actions with a single argument can be contributed as associations
More information about contributions can be found xref: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.adoc#_ugbtb_more-advanced_decoupling_contributions[here] and xref:ugbtb.adoc#_ugbtb_more-advanced_decoupling_mixins[here].
+about using contributions and mixins to keep your domain application decoupled can be found xref:ugbtb.adoc#_ugbtb_decoupling_contributions[here] and xref:ugbtb.adoc#_ugbtb_decoupling_mixins[here].
=== Event Subscribers
http://git-wip-us.apache.org/repos/asf/isis/blob/29452af6/adocs/documentation/src/main/asciidoc/guides/_ugfun_how-tos_ui-hints_names-and-descriptions.adoc
----------------------------------------------------------------------
diff --git a/adocs/documentation/src/main/asciidoc/guides/_ugfun_how-tos_ui-hints_names-and-descriptions.adoc b/adocs/documentation/src/main/asciidoc/guides/_ugfun_how-tos_ui-hints_names-and-descriptions.adoc
index 7977e5e..ae892d4 100644
--- a/adocs/documentation/src/main/asciidoc/guides/_ugfun_how-tos_ui-hints_names-and-descriptions.adoc
+++ b/adocs/documentation/src/main/asciidoc/guides/_ugfun_how-tos_ui-hints_names-and-descriptions.adoc
@@ -8,7 +8,7 @@ NOTE: TODO
-NOTE: see also xref:ugbtb.adoc#_ugbtb_more-advanced_i18n[Internationalization]
+NOTE: see also xref:ugbtb.adoc#_ugbtb_i18n[Internationalization]
== Class (object)
http://git-wip-us.apache.org/repos/asf/isis/blob/29452af6/adocs/documentation/src/main/asciidoc/guides/_ugfun_object-layout_application-menu.adoc
----------------------------------------------------------------------
diff --git a/adocs/documentation/src/main/asciidoc/guides/_ugfun_object-layout_application-menu.adoc b/adocs/documentation/src/main/asciidoc/guides/_ugfun_object-layout_application-menu.adoc
index 0467972..e8cf1a3 100644
--- a/adocs/documentation/src/main/asciidoc/guides/_ugfun_object-layout_application-menu.adoc
+++ b/adocs/documentation/src/main/asciidoc/guides/_ugfun_object-layout_application-menu.adoc
@@ -167,5 +167,5 @@ Meanwhile the http://github.com/isisaddons/isis-module-devutils[devutils] module
so forth - on a "Prototyping" top-level menu, on the SECONDARY menu bar.
Currently there is no facility to alter the placement of these services. However, their UI can be suppressed
-using security or using a xref:ugbtb.adoc#_ugbtb_more-advanced_decoupling_vetoing-visibility[vetoing subscriber].
+using security or using a xref:ugbtb.adoc#_ugbtb_decoupling_vetoing-visibility[vetoing subscriber].
http://git-wip-us.apache.org/repos/asf/isis/blob/29452af6/adocs/documentation/src/main/asciidoc/guides/_ugsec_usage-by-isis-viewers.adoc
----------------------------------------------------------------------
diff --git a/adocs/documentation/src/main/asciidoc/guides/_ugsec_usage-by-isis-viewers.adoc b/adocs/documentation/src/main/asciidoc/guides/_ugsec_usage-by-isis-viewers.adoc
index 13f951b..c502fe2 100644
--- a/adocs/documentation/src/main/asciidoc/guides/_ugsec_usage-by-isis-viewers.adoc
+++ b/adocs/documentation/src/main/asciidoc/guides/_ugsec_usage-by-isis-viewers.adoc
@@ -49,7 +49,7 @@ Similarly, for those object members that _are_ visible, the viewer also checks i
=== User-registration
-As well as providing a sign-in screen, the Wicket viewer also provides the ability for xref:_user_registration[users to self-register]. By and large this operates outside of Apache Isis' security mechanisms; indeed the various pages (sign-up, sign-up verification, password reset) are all rendered _without_ there being any current user session. These pages all "reach inside" Apache Isis framework using a mechanism similar to xref:ugbtb.adoc#_ugbtb_more-advanced_headless-access[Headless access] in order to actually do their stuff.
+As well as providing a sign-in screen, the Wicket viewer also provides the ability for xref:_user_registration[users to self-register]. By and large this operates outside of Apache Isis' security mechanisms; indeed the various pages (sign-up, sign-up verification, password reset) are all rendered _without_ there being any current user session. These pages all "reach inside" Apache Isis framework using a mechanism similar to xref:ugbtb.adoc#_ugbtb_headless-access[Headless access] in order to actually do their stuff.
[TIP]
====
http://git-wip-us.apache.org/repos/asf/isis/blob/29452af6/adocs/documentation/src/main/asciidoc/guides/_ugtst_integ-test-support_bootstrapping.adoc
----------------------------------------------------------------------
diff --git a/adocs/documentation/src/main/asciidoc/guides/_ugtst_integ-test-support_bootstrapping.adoc b/adocs/documentation/src/main/asciidoc/guides/_ugtst_integ-test-support_bootstrapping.adoc
index 18d8b70..1a5134b 100644
--- a/adocs/documentation/src/main/asciidoc/guides/_ugtst_integ-test-support_bootstrapping.adoc
+++ b/adocs/documentation/src/main/asciidoc/guides/_ugtst_integ-test-support_bootstrapping.adoc
@@ -250,7 +250,7 @@ Although not mandatory, this provides a number of helper/convenience methods and
<1> ensures an Apache Isis session/transaction running for each test
<2> sets up a JMock context (using Apache Isis' extension to JMock as described in xref:ugtst.adoc#_ugtst_unit-test-support_jmock-extensions[JMock Extensions].
<3> standard JUnit rule for writing tests that throw exceptions
-<4> to capture messages that require translation, as described in xref:ugbtb.adoc#_ugbtb_more-advanced_i18n[i18 support].
+<4> to capture messages that require translation, as described in xref:ugbtb.adoc#_ugbtb_i18n[i18 support].
All of these rules could be inlined in your own base class; as we say, they are a convenience.
http://git-wip-us.apache.org/repos/asf/isis/blob/29452af6/adocs/documentation/src/main/asciidoc/guides/ugbtb.adoc
----------------------------------------------------------------------
diff --git a/adocs/documentation/src/main/asciidoc/guides/ugbtb.adoc b/adocs/documentation/src/main/asciidoc/guides/ugbtb.adoc
index a7ba529..072e978 100644
--- a/adocs/documentation/src/main/asciidoc/guides/ugbtb.adoc
+++ b/adocs/documentation/src/main/asciidoc/guides/ugbtb.adoc
@@ -9,7 +9,7 @@
[[_ugbtb]]
== Beyond the Basics
-This guide provides xref:ugbtb.adoc#_ugbtb_more-advanced[more advanced] guidance on writing maintainable larger
+This guide provides xref:ugbtb.adoc#_ugbtb_other-techniques[more advanced] guidance on writing maintainable larger
applications.
Later chapters discuss how to xref:ugbtb.adoc#_ugbtb_deployment[deploy] your app, and discuss other ways in which you can xref:ugbtb.adoc#[extend] or adapt the framework itself to your particular needs.
@@ -37,7 +37,11 @@ The reference guides are:
In addition, there is a xref:cg.adoc#_cg[Contributors' Guide] describing development practices for contributors and committers alike.
-include::_ugbtb_more-advanced.adoc[leveloffset=+1]
+include::_ugbtb_view-models.adoc[leveloffset=+1]
+include::_ugbtb_decoupling.adoc[leveloffset=+1]
+include::_ugbtb_i18n.adoc[leveloffset=+1]
+include::_ugbtb_headless-access.adoc[leveloffset=+1]
+include::_ugbtb_other-techniques.adoc[leveloffset=+1]
include::_ugbtb_programming-model.adoc[leveloffset=+1]
include::_ugbtb_deployment.adoc[leveloffset=+1]
include::_ugbtb_web-xml.adoc[leveloffset=+1]
[4/4] isis git commit: ISIS-1243: reworking the ugbtb (beyond the
basics) guide a little, breaking out and renaming the techniques chapter
Posted by da...@apache.org.
ISIS-1243: reworking the ugbtb (beyond the basics) guide a little, breaking out and renaming the techniques chapter
Project: http://git-wip-us.apache.org/repos/asf/isis/repo
Commit: http://git-wip-us.apache.org/repos/asf/isis/commit/29452af6
Tree: http://git-wip-us.apache.org/repos/asf/isis/tree/29452af6
Diff: http://git-wip-us.apache.org/repos/asf/isis/diff/29452af6
Branch: refs/heads/master
Commit: 29452af6e8f57dffd58035feeae385100cbd927a
Parents: c2eb5ee
Author: Dan Haywood <da...@haywood-associates.co.uk>
Authored: Tue Dec 22 22:37:56 2015 +0000
Committer: Dan Haywood <da...@haywood-associates.co.uk>
Committed: Tue Dec 22 22:37:56 2015 +0000
----------------------------------------------------------------------
adocs/documentation/pom.xml | 2 +-
.../asciidoc/_powered-by_gesconsultor-grc.adoc | 2 +-
.../guides/_cg_isis-maven-plugin_xsd.adoc | 4 +-
.../guides/_rgant-ActionLayout_named.adoc | 2 +-
.../asciidoc/guides/_rgant-Action_command.adoc | 4 +-
.../guides/_rgant-CollectionLayout_named.adoc | 2 +-
...gant-DomainObjectLayout_cssClassUiEvent.adoc | 4 +-
.../_rgant-DomainObjectLayout_iconUiEvent.adoc | 4 +-
.../guides/_rgant-DomainObjectLayout_named.adoc | 2 +-
.../_rgant-DomainObjectLayout_titleUiEvent.adoc | 4 +-
.../guides/_rgant-DomainObject_nature.adoc | 2 +-
.../src/main/asciidoc/guides/_rgant-Mixin.adoc | 2 +-
.../guides/_rgant-ParameterLayout_named.adoc | 2 +-
.../asciidoc/guides/_rgant-PostConstruct.adoc | 2 +-
.../guides/_rgant-PropertyLayout_named.adoc | 2 +-
.../guides/_rgant-ViewModelLayout_named.adoc | 2 +-
.../guides/_rgant-XmlJavaTypeAdapter.adoc | 2 +-
.../asciidoc/guides/_rgant-XmlRootElement.adoc | 6 +-
.../guides/_rgcfg_configuring-core.adoc | 2 +-
.../guides/_rgcfg_configuring-datanucleus.adoc | 2 +-
.../_rgcms_classes_i18n_TranslatableString.adoc | 2 +-
.../guides/_rgcms_classes_roles_Dto.adoc | 2 +-
.../guides/_rgcms_methods_prefixes_disable.adoc | 2 +-
.../_rgcms_methods_prefixes_validate.adoc | 2 +-
.../_rgcms_methods_prefixes_validateAddTo.adoc | 2 +-
...cms_methods_prefixes_validateRemoveFrom.adoc | 2 +-
.../guides/_rgcms_methods_reserved_disable.adoc | 2 +-
.../guides/_rgcms_methods_reserved_title.adoc | 2 +-
.../_rgcms_methods_reserved_validate.adoc | 2 +-
..._api_DomainObjectContainer_messages-api.adoc | 2 +-
.../asciidoc/guides/_rgsvc_api_JaxbService.adoc | 2 +-
.../guides/_rgsvc_api_MementoService.adoc | 2 +-
.../asciidoc/guides/_rgsvc_api_Scratchpad.adoc | 2 +-
.../guides/_rgsvc_api_SwaggerService.adoc | 2 +-
.../guides/_rgsvc_spi_AuditingService.adoc | 2 +-
.../_rgsvc_spi_BackgroundCommandService.adoc | 4 +-
.../guides/_rgsvc_spi_CommandService.adoc | 2 +-
.../_rgsvc_spi_ContentNegotiationService.adoc | 4 +-
.../guides/_rgsvc_spi_LocaleProvider.adoc | 2 +-
.../guides/_rgsvc_spi_PublishingService.adoc | 2 +-
.../guides/_rgsvc_spi_TranslationService.adoc | 6 +-
.../guides/_rgsvc_spi_TranslationsResolver.adoc | 2 +-
.../guides/_rgsvc_spi_UrlEncodingService.adoc | 2 +-
.../main/asciidoc/guides/_ugbtb_decoupling.adoc | 28 ++
.../guides/_ugbtb_decoupling_contributions.adoc | 23 ++
.../guides/_ugbtb_decoupling_db-schemas.adoc | 141 +++++++
.../guides/_ugbtb_decoupling_event-bus.adoc | 11 +
.../guides/_ugbtb_decoupling_mixins.adoc | 191 +++++++++
.../_ugbtb_decoupling_pushing-changes.adoc | 140 +++++++
.../_ugbtb_decoupling_vetoing-visibility.adoc | 15 +
.../asciidoc/guides/_ugbtb_headless-access.adoc | 27 ++
...less-access_AbstractIsisSessionTemplate.adoc | 40 ++
...dless-access_BackgroundCommandExecution.adoc | 45 ++
.../src/main/asciidoc/guides/_ugbtb_i18n.adoc | 409 +++++++++++++++++++
.../asciidoc/guides/_ugbtb_more-advanced.adoc | 26 --
.../guides/_ugbtb_more-advanced_decoupling.adoc | 28 --
..._more-advanced_decoupling_contributions.adoc | 23 --
...btb_more-advanced_decoupling_db-schemas.adoc | 141 -------
...gbtb_more-advanced_decoupling_event-bus.adoc | 11 -
.../_ugbtb_more-advanced_decoupling_mixins.adoc | 191 ---------
...ore-advanced_decoupling_pushing-changes.adoc | 140 -------
...-advanced_decoupling_vetoing-visibility.adoc | 15 -
.../_ugbtb_more-advanced_headless-access.adoc | 27 --
...less-access_AbstractIsisSessionTemplate.adoc | 40 --
...dless-access_BackgroundCommandExecution.adoc | 45 --
.../guides/_ugbtb_more-advanced_i18n.adoc | 409 -------------------
...ugbtb_more-advanced_mapping-rdbms-views.adoc | 9 -
.../_ugbtb_more-advanced_multi-tenancy.adoc | 8 -
...ore-advanced_overriding-jdo-annotations.adoc | 64 ---
.../_ugbtb_more-advanced_persisted-title.adoc | 82 ----
...placing-default-service-implementations.adoc | 64 ---
...b_more-advanced_transactions-and-errors.adoc | 33 --
.../_ugbtb_more-advanced_view-models.adoc | 19 -
.../_ugbtb_more-advanced_view-models_jaxb.adoc | 240 -----------
...-advanced_view-models_programming-model.adoc | 87 ----
...btb_more-advanced_view-models_use-cases.adoc | 142 -------
.../guides/_ugbtb_other-techniques.adoc | 22 +
...tb_other-techniques_mapping-rdbms-views.adoc | 9 +
.../_ugbtb_other-techniques_multi-tenancy.adoc | 8 +
...r-techniques_overriding-jdo-annotations.adoc | 64 +++
..._ugbtb_other-techniques_persisted-title.adoc | 82 ++++
...placing-default-service-implementations.adoc | 64 +++
...ther-techniques_transactions-and-errors.adoc | 33 ++
.../guides/_ugbtb_programming-model.adoc | 2 +-
...gbtb_programming-model_custom-validator.adoc | 2 +-
.../_ugbtb_programming-model_finetuning.adoc | 2 +-
.../asciidoc/guides/_ugbtb_view-models.adoc | 19 +
.../guides/_ugbtb_view-models_jaxb.adoc | 240 +++++++++++
.../_ugbtb_view-models_programming-model.adoc | 87 ++++
.../guides/_ugbtb_view-models_use-cases.adoc | 142 +++++++
.../_ugfun_core-concepts_building-blocks.adoc | 6 +-
.../_ugfun_core-concepts_philosophy_aop.adoc | 4 +-
...concepts_principles_apache-isis-vs_cqrs.adoc | 4 +-
.../guides/_ugfun_how-tos_class-structure.adoc | 2 +-
...ow-tos_class-structure_class-definition.adoc | 2 +-
.../guides/_ugfun_how-tos_domain-services.adoc | 2 +-
...how-tos_ui-hints_names-and-descriptions.adoc | 2 +-
.../_ugfun_object-layout_application-menu.adoc | 2 +-
.../guides/_ugsec_usage-by-isis-viewers.adoc | 2 +-
..._ugtst_integ-test-support_bootstrapping.adoc | 2 +-
.../src/main/asciidoc/guides/ugbtb.adoc | 8 +-
101 files changed, 1917 insertions(+), 1917 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/isis/blob/29452af6/adocs/documentation/pom.xml
----------------------------------------------------------------------
diff --git a/adocs/documentation/pom.xml b/adocs/documentation/pom.xml
index 6a86dce..c43f20c 100644
--- a/adocs/documentation/pom.xml
+++ b/adocs/documentation/pom.xml
@@ -33,7 +33,7 @@
<groupId>org.apache.isis.docs</groupId>
<artifactId>isis-documentation</artifactId>
- <version>1.10.0-SNAPSHOT</version>
+ <version>1.11.0-SNAPSHOT</version>
<packaging>pom</packaging>
<name>Apache Isis Docs</name>
http://git-wip-us.apache.org/repos/asf/isis/blob/29452af6/adocs/documentation/src/main/asciidoc/_powered-by_gesconsultor-grc.adoc
----------------------------------------------------------------------
diff --git a/adocs/documentation/src/main/asciidoc/_powered-by_gesconsultor-grc.adoc b/adocs/documentation/src/main/asciidoc/_powered-by_gesconsultor-grc.adoc
index 3f38834..a0c54de 100644
--- a/adocs/documentation/src/main/asciidoc/_powered-by_gesconsultor-grc.adoc
+++ b/adocs/documentation/src/main/asciidoc/_powered-by_gesconsultor-grc.adoc
@@ -85,7 +85,7 @@ automatically generated from the underlying domain entities; the GRC viewer is a
xref:ugvw.adoc#[Wicket viewer]. At the last count more than 400 domain entities, across 6 different
Bounded Contexts, are surfaced in the UI in this this way.
-At the Domain level, we also extensively use the xref:ugbtb.adoc#_ugbtb_more-advanced_decoupling_event-bus[domain events]
+At the Domain level, we also extensively use the xref:ugbtb.adoc#_ugbtb_decoupling_event-bus[domain events]
functionality available in Apache Isis, along with many of the (non-ASF) link:http://isisaddons.org[Isis Addons] (such
as http://github.com/isisaddons/isis-module-audit[audit], http://github.com/isisaddons/isis-module-security[security]
and the http://github.com/isisaddons/isis-module-excel[excel] modules).
http://git-wip-us.apache.org/repos/asf/isis/blob/29452af6/adocs/documentation/src/main/asciidoc/guides/_cg_isis-maven-plugin_xsd.adoc
----------------------------------------------------------------------
diff --git a/adocs/documentation/src/main/asciidoc/guides/_cg_isis-maven-plugin_xsd.adoc b/adocs/documentation/src/main/asciidoc/guides/_cg_isis-maven-plugin_xsd.adoc
index f50f4a3..20c2531 100644
--- a/adocs/documentation/src/main/asciidoc/guides/_cg_isis-maven-plugin_xsd.adoc
+++ b/adocs/documentation/src/main/asciidoc/guides/_cg_isis-maven-plugin_xsd.adoc
@@ -7,7 +7,7 @@
The `xsd` goal of the `isis-maven-plugin` uses the xref:rgsvc.adoc#_rgsvc_api_JaxbService[`JaxbService`] to
-generate XSD schemas from any JAXB-annotated xref:ugbtb.adoc#_ugbtb_more-advanced_view-models[view model/DTOs].
+generate XSD schemas from any JAXB-annotated xref:ugbtb.adoc#_ugbtb_view-models[view model/DTOs].
This is instead of and preferable to using the JAXB link:https://jaxb.java.net/2.2.4/docs/schemagen.html[schemagen]
tool, because it uses the framework's support (via
@@ -18,7 +18,7 @@ The `xsd` goal defines the following properties:
* `appManifest` - fully qualified class name for the app manifest used to bootstrap the application (see discussion above)
-* `jaxbClasses` - a list of xref:rg.adoc#_ugbtb_more-advanced_view-models_jaxb[JAXB-annotated view model] classes;
+* `jaxbClasses` - a list of xref:rg.adoc#_ugbtb_view-models_jaxb[JAXB-annotated view model] classes;
* `output` - (optional) subdirectory under the `target` directory to generate the XSDs +
+
http://git-wip-us.apache.org/repos/asf/isis/blob/29452af6/adocs/documentation/src/main/asciidoc/guides/_rgant-ActionLayout_named.adoc
----------------------------------------------------------------------
diff --git a/adocs/documentation/src/main/asciidoc/guides/_rgant-ActionLayout_named.adoc b/adocs/documentation/src/main/asciidoc/guides/_rgant-ActionLayout_named.adoc
index 2c6952c..4a3ea1f 100644
--- a/adocs/documentation/src/main/asciidoc/guides/_rgant-ActionLayout_named.adoc
+++ b/adocs/documentation/src/main/asciidoc/guides/_rgant-ActionLayout_named.adoc
@@ -38,7 +38,7 @@ can be used instead, eg:
[TIP]
====
-The framework also provides a separate, powerful mechanism for xref:ugbtb.adoc#_ugbtb_more-advanced_i18n[internationalization].
+The framework also provides a separate, powerful mechanism for xref:ugbtb.adoc#_ugbtb_i18n[internationalization].
====
http://git-wip-us.apache.org/repos/asf/isis/blob/29452af6/adocs/documentation/src/main/asciidoc/guides/_rgant-Action_command.adoc
----------------------------------------------------------------------
diff --git a/adocs/documentation/src/main/asciidoc/guides/_rgant-Action_command.adoc b/adocs/documentation/src/main/asciidoc/guides/_rgant-Action_command.adoc
index 63d6723..760a3af 100644
--- a/adocs/documentation/src/main/asciidoc/guides/_rgant-Action_command.adoc
+++ b/adocs/documentation/src/main/asciidoc/guides/_rgant-Action_command.adoc
@@ -23,7 +23,7 @@ By default, actions are invoked in directly in the thread of the invocation. I
[NOTE]
====
-If background ``Command``s are used, then an external scheduler, using xref:ugbtb.adoc#_ugbtb_more-advanced_headless-access_BackgroundCommandExecution[headless access], must also be configured.
+If background ``Command``s are used, then an external scheduler, using xref:ugbtb.adoc#_ugbtb_headless-access_BackgroundCommandExecution[headless access], must also be configured.
====
@@ -112,7 +112,7 @@ will prevent the parent `Command` object from being persisted, _even if_ a child
For persisted commands, the `commandExecuteIn()` attribute determines whether the `Command` should be executed in the foreground (the default) or executed in the background.
-Background execution means that the command is not executed immediately, but is available for a configured xref:rgsvc.adoc#_rgsvc_spi_BackgroundCommandService[`BackgroundCommandService`] to execute, eg by way of an in-memory scheduler such as Quartz. See xref:ugbtb.adoc#_ugbtb_more-advanced_headless-access_BackgroundCommandExecution[here] for further information on this topic.
+Background execution means that the command is not executed immediately, but is available for a configured xref:rgsvc.adoc#_rgsvc_spi_BackgroundCommandService[`BackgroundCommandService`] to execute, eg by way of an in-memory scheduler such as Quartz. See xref:ugbtb.adoc#_ugbtb_headless-access_BackgroundCommandExecution[here] for further information on this topic.
For example:
http://git-wip-us.apache.org/repos/asf/isis/blob/29452af6/adocs/documentation/src/main/asciidoc/guides/_rgant-CollectionLayout_named.adoc
----------------------------------------------------------------------
diff --git a/adocs/documentation/src/main/asciidoc/guides/_rgant-CollectionLayout_named.adoc b/adocs/documentation/src/main/asciidoc/guides/_rgant-CollectionLayout_named.adoc
index 2ab0b68..1dcc4a3 100644
--- a/adocs/documentation/src/main/asciidoc/guides/_rgant-CollectionLayout_named.adoc
+++ b/adocs/documentation/src/main/asciidoc/guides/_rgant-CollectionLayout_named.adoc
@@ -49,5 +49,5 @@ can be used instead, eg:
[TIP]
====
-The framework also provides a separate, powerful mechanism for xref:ugbtb.adoc#_ugbtb_more-advanced_i18n[internationalization].
+The framework also provides a separate, powerful mechanism for xref:ugbtb.adoc#_ugbtb_i18n[internationalization].
====
http://git-wip-us.apache.org/repos/asf/isis/blob/29452af6/adocs/documentation/src/main/asciidoc/guides/_rgant-DomainObjectLayout_cssClassUiEvent.adoc
----------------------------------------------------------------------
diff --git a/adocs/documentation/src/main/asciidoc/guides/_rgant-DomainObjectLayout_cssClassUiEvent.adoc b/adocs/documentation/src/main/asciidoc/guides/_rgant-DomainObjectLayout_cssClassUiEvent.adoc
index 6b1211e..1a58a02 100644
--- a/adocs/documentation/src/main/asciidoc/guides/_rgant-DomainObjectLayout_cssClassUiEvent.adoc
+++ b/adocs/documentation/src/main/asciidoc/guides/_rgant-DomainObjectLayout_cssClassUiEvent.adoc
@@ -17,8 +17,8 @@ the domain object using the event's API.
[NOTE]
====
The feature was originally introduced so that xref:rgant.adoc#_rgant-XmlRootElement[`@XmlRootElement`]-annotated
-xref:ugbtb.adoc#_ugbtb_more-advanced_view-models[view model]s could be kept as minimal as possible, just defining the data.
-UI events allow subscribers to provide UI hints, while xref:ugbtb.adoc#_ugbtb_more-advanced_decoupling_mixins[mixin]s can be used to provide the behaviour.
+xref:ugbtb.adoc#_ugbtb_view-models[view model]s could be kept as minimal as possible, just defining the data.
+UI events allow subscribers to provide UI hints, while xref:ugbtb.adoc#_ugbtb_decoupling_mixins[mixin]s can be used to provide the behaviour.
====
By default the event raised is `CssClassUiEvent.Default`. For example:
http://git-wip-us.apache.org/repos/asf/isis/blob/29452af6/adocs/documentation/src/main/asciidoc/guides/_rgant-DomainObjectLayout_iconUiEvent.adoc
----------------------------------------------------------------------
diff --git a/adocs/documentation/src/main/asciidoc/guides/_rgant-DomainObjectLayout_iconUiEvent.adoc b/adocs/documentation/src/main/asciidoc/guides/_rgant-DomainObjectLayout_iconUiEvent.adoc
index fcb9b17..d545388 100644
--- a/adocs/documentation/src/main/asciidoc/guides/_rgant-DomainObjectLayout_iconUiEvent.adoc
+++ b/adocs/documentation/src/main/asciidoc/guides/_rgant-DomainObjectLayout_iconUiEvent.adoc
@@ -18,8 +18,8 @@ the domain object using the event's API.
[NOTE]
====
The feature was originally introduced so that xref:rgant.adoc#_rgant-XmlRootElement[`@XmlRootElement`]-annotated
-xref:ugbtb.adoc#_ugbtb_more-advanced_view-models[view model]s could be kept as minimal as possible, just defining the data.
-UI events allow subscribers to provide UI hints, while xref:ugbtb.adoc#_ugbtb_more-advanced_decoupling_mixins[mixin]s can be used to provide the behaviour.
+xref:ugbtb.adoc#_ugbtb_view-models[view model]s could be kept as minimal as possible, just defining the data.
+UI events allow subscribers to provide UI hints, while xref:ugbtb.adoc#_ugbtb_decoupling_mixins[mixin]s can be used to provide the behaviour.
====
By default the event raised is `IconUiEvent.Default`. For example:
http://git-wip-us.apache.org/repos/asf/isis/blob/29452af6/adocs/documentation/src/main/asciidoc/guides/_rgant-DomainObjectLayout_named.adoc
----------------------------------------------------------------------
diff --git a/adocs/documentation/src/main/asciidoc/guides/_rgant-DomainObjectLayout_named.adoc b/adocs/documentation/src/main/asciidoc/guides/_rgant-DomainObjectLayout_named.adoc
index 93e6549..dc178ab 100644
--- a/adocs/documentation/src/main/asciidoc/guides/_rgant-DomainObjectLayout_named.adoc
+++ b/adocs/documentation/src/main/asciidoc/guides/_rgant-DomainObjectLayout_named.adoc
@@ -31,7 +31,7 @@ It's also possible to specify a xref:rgant.adoc#_rgant-DomainObjectLayout_plural
[TIP]
====
-The framework also provides a separate, powerful mechanism for xref:ugbtb.adoc#_ugbtb_more-advanced_i18n[internationalization].
+The framework also provides a separate, powerful mechanism for xref:ugbtb.adoc#_ugbtb_i18n[internationalization].
====
http://git-wip-us.apache.org/repos/asf/isis/blob/29452af6/adocs/documentation/src/main/asciidoc/guides/_rgant-DomainObjectLayout_titleUiEvent.adoc
----------------------------------------------------------------------
diff --git a/adocs/documentation/src/main/asciidoc/guides/_rgant-DomainObjectLayout_titleUiEvent.adoc b/adocs/documentation/src/main/asciidoc/guides/_rgant-DomainObjectLayout_titleUiEvent.adoc
index 1ebae33..b315b0e 100644
--- a/adocs/documentation/src/main/asciidoc/guides/_rgant-DomainObjectLayout_titleUiEvent.adoc
+++ b/adocs/documentation/src/main/asciidoc/guides/_rgant-DomainObjectLayout_titleUiEvent.adoc
@@ -17,8 +17,8 @@ the domain object using the event's API.
[NOTE]
====
The feature was originally introduced so that xref:rgant.adoc#_rgant-XmlRootElement[`@XmlRootElement`]-annotated
-xref:ugbtb.adoc#_ugbtb_more-advanced_view-models[view model]s could be kept as minimal as possible, just defining the data.
-UI events allow subscribers to provide UI hints, while xref:ugbtb.adoc#_ugbtb_more-advanced_decoupling_mixins[mixin]s can be used to provide the behaviour.
+xref:ugbtb.adoc#_ugbtb_view-models[view model]s could be kept as minimal as possible, just defining the data.
+UI events allow subscribers to provide UI hints, while xref:ugbtb.adoc#_ugbtb_decoupling_mixins[mixin]s can be used to provide the behaviour.
====
By default the event raised is `TitleUiEvent.Default`. For example:
http://git-wip-us.apache.org/repos/asf/isis/blob/29452af6/adocs/documentation/src/main/asciidoc/guides/_rgant-DomainObject_nature.adoc
----------------------------------------------------------------------
diff --git a/adocs/documentation/src/main/asciidoc/guides/_rgant-DomainObject_nature.adoc b/adocs/documentation/src/main/asciidoc/guides/_rgant-DomainObject_nature.adoc
index 0625cc0..b598dc1 100644
--- a/adocs/documentation/src/main/asciidoc/guides/_rgant-DomainObject_nature.adoc
+++ b/adocs/documentation/src/main/asciidoc/guides/_rgant-DomainObject_nature.adoc
@@ -44,7 +44,7 @@ The identity of an inmemory entity is determined solely by the state of entity's
+
indicates that the domain object is part of the domain layer, and is contributing behaviour to objects of some other type as a mixin (also known as a trait).
-Equivalent to annotating with xref:rgant.adoc#_rgant-Mixin[`@Mixin`]. For further discussion on using mixins, see xref:ugbtb.adoc#_ugbtb_more-advanced_decoupling_mixins[mixins] in the user guide.
+Equivalent to annotating with xref:rgant.adoc#_rgant-Mixin[`@Mixin`]. For further discussion on using mixins, see xref:ugbtb.adoc#_ugbtb_decoupling_mixins[mixins] in the user guide.
* `VIEW_MODEL` +
http://git-wip-us.apache.org/repos/asf/isis/blob/29452af6/adocs/documentation/src/main/asciidoc/guides/_rgant-Mixin.adoc
----------------------------------------------------------------------
diff --git a/adocs/documentation/src/main/asciidoc/guides/_rgant-Mixin.adoc b/adocs/documentation/src/main/asciidoc/guides/_rgant-Mixin.adoc
index 67be427..427c783 100644
--- a/adocs/documentation/src/main/asciidoc/guides/_rgant-Mixin.adoc
+++ b/adocs/documentation/src/main/asciidoc/guides/_rgant-Mixin.adoc
@@ -34,7 +34,7 @@ An alternative and equivalent approach is to use the
xref:rgant.adoc#_rgant-DomainObject_nature[`@DomainObject#nature()`] annotation with a nature of `MIXIN`.
-For further discussion on using mixins, see xref:ugbtb.adoc#_ugbtb_more-advanced_decoupling_mixins[mixins] in the user guide.
+For further discussion on using mixins, see xref:ugbtb.adoc#_ugbtb_decoupling_mixins[mixins] in the user guide.
http://git-wip-us.apache.org/repos/asf/isis/blob/29452af6/adocs/documentation/src/main/asciidoc/guides/_rgant-ParameterLayout_named.adoc
----------------------------------------------------------------------
diff --git a/adocs/documentation/src/main/asciidoc/guides/_rgant-ParameterLayout_named.adoc b/adocs/documentation/src/main/asciidoc/guides/_rgant-ParameterLayout_named.adoc
index 411a066..586c205 100644
--- a/adocs/documentation/src/main/asciidoc/guides/_rgant-ParameterLayout_named.adoc
+++ b/adocs/documentation/src/main/asciidoc/guides/_rgant-ParameterLayout_named.adoc
@@ -40,5 +40,5 @@ public class Customer {
[TIP]
====
-The framework also provides a separate, powerful mechanism for xref:ugbtb.adoc#_ugbtb_more-advanced_i18n[internationalization].
+The framework also provides a separate, powerful mechanism for xref:ugbtb.adoc#_ugbtb_i18n[internationalization].
====
http://git-wip-us.apache.org/repos/asf/isis/blob/29452af6/adocs/documentation/src/main/asciidoc/guides/_rgant-PostConstruct.adoc
----------------------------------------------------------------------
diff --git a/adocs/documentation/src/main/asciidoc/guides/_rgant-PostConstruct.adoc b/adocs/documentation/src/main/asciidoc/guides/_rgant-PostConstruct.adoc
index 2cf790a..8186d7d 100644
--- a/adocs/documentation/src/main/asciidoc/guides/_rgant-PostConstruct.adoc
+++ b/adocs/documentation/src/main/asciidoc/guides/_rgant-PostConstruct.adoc
@@ -7,7 +7,7 @@
The `@javax.annotation.PostConstruct` annotation, as defined in link:https://jcp.org/en/jsr/detail?id=250[JSR-250], is recognized by Apache Isis as a callback method on domain services to be called just after they have been constructed, in order that they initialize themselves.
-It is also recognized for xref:ugbtb.adoc#_ugbtb_more-advanced_view-models[view models] (eg annotated with xref:rgant.adoc#_rgant-ViewModel[`@ViewModel`]).
+It is also recognized for xref:ugbtb.adoc#_ugbtb_view-models[view models] (eg annotated with xref:rgant.adoc#_rgant-ViewModel[`@ViewModel`]).
For the default application-scoped (singleton) domain services, this means that the method, if present, is called during the bootstrapping of the application. For xref:rgant.adoc#_rgant-RequestScoped[`@RequestScoped`] domain services, the method is called at the beginning of the request.
http://git-wip-us.apache.org/repos/asf/isis/blob/29452af6/adocs/documentation/src/main/asciidoc/guides/_rgant-PropertyLayout_named.adoc
----------------------------------------------------------------------
diff --git a/adocs/documentation/src/main/asciidoc/guides/_rgant-PropertyLayout_named.adoc b/adocs/documentation/src/main/asciidoc/guides/_rgant-PropertyLayout_named.adoc
index 9aece74..fa1d1cd 100644
--- a/adocs/documentation/src/main/asciidoc/guides/_rgant-PropertyLayout_named.adoc
+++ b/adocs/documentation/src/main/asciidoc/guides/_rgant-PropertyLayout_named.adoc
@@ -47,5 +47,5 @@ can be used instead, eg:
[TIP]
====
-The framework also provides a separate, powerful mechanism for xref:ugbtb.adoc#_ugbtb_more-advanced_i18n[internationalization].
+The framework also provides a separate, powerful mechanism for xref:ugbtb.adoc#_ugbtb_i18n[internationalization].
====
http://git-wip-us.apache.org/repos/asf/isis/blob/29452af6/adocs/documentation/src/main/asciidoc/guides/_rgant-ViewModelLayout_named.adoc
----------------------------------------------------------------------
diff --git a/adocs/documentation/src/main/asciidoc/guides/_rgant-ViewModelLayout_named.adoc b/adocs/documentation/src/main/asciidoc/guides/_rgant-ViewModelLayout_named.adoc
index ed397fb..2ce74dd 100644
--- a/adocs/documentation/src/main/asciidoc/guides/_rgant-ViewModelLayout_named.adoc
+++ b/adocs/documentation/src/main/asciidoc/guides/_rgant-ViewModelLayout_named.adoc
@@ -31,5 +31,5 @@ public class PieChartAnalysisViewModel {
[TIP]
====
-The framework also provides a separate, powerful mechanism for xref:ugbtb.adoc#_ugbtb_more-advanced_i18n[internationalization].
+The framework also provides a separate, powerful mechanism for xref:ugbtb.adoc#_ugbtb_i18n[internationalization].
====
http://git-wip-us.apache.org/repos/asf/isis/blob/29452af6/adocs/documentation/src/main/asciidoc/guides/_rgant-XmlJavaTypeAdapter.adoc
----------------------------------------------------------------------
diff --git a/adocs/documentation/src/main/asciidoc/guides/_rgant-XmlJavaTypeAdapter.adoc b/adocs/documentation/src/main/asciidoc/guides/_rgant-XmlJavaTypeAdapter.adoc
index 5fb817d..ecf9545 100644
--- a/adocs/documentation/src/main/asciidoc/guides/_rgant-XmlJavaTypeAdapter.adoc
+++ b/adocs/documentation/src/main/asciidoc/guides/_rgant-XmlJavaTypeAdapter.adoc
@@ -22,6 +22,6 @@ public class ToDoItem ... {
This annotation therefore allows view models/DTOs to have references to persistent entities; a common idiom.
-For a more complete discussion of writing JAXB view models/DTOs, see xref:ugbtb.adoc#_ugbtb_more-advanced_view-models[this topic]
+For a more complete discussion of writing JAXB view models/DTOs, see xref:ugbtb.adoc#_ugbtb_view-models[this topic]
in the user guide.
http://git-wip-us.apache.org/repos/asf/isis/blob/29452af6/adocs/documentation/src/main/asciidoc/guides/_rgant-XmlRootElement.adoc
----------------------------------------------------------------------
diff --git a/adocs/documentation/src/main/asciidoc/guides/_rgant-XmlRootElement.adoc b/adocs/documentation/src/main/asciidoc/guides/_rgant-XmlRootElement.adoc
index 0378260..0cfd4af 100644
--- a/adocs/documentation/src/main/asciidoc/guides/_rgant-XmlRootElement.adoc
+++ b/adocs/documentation/src/main/asciidoc/guides/_rgant-XmlRootElement.adoc
@@ -6,7 +6,7 @@
The `@XmlRootElement` annotation (`1.11.0-SNAPSHOT`) provides an alternative way to define a
-xref:rg.adoc#_ugbtb_more-advanced_view-models[view model], in particular one intended to act as a DTO for use within
+xref:rg.adoc#_ugbtb_view-models[view model], in particular one intended to act as a DTO for use within
xref:ugvro.adoc#[RestfulObjects viewer], or which contains arbitrarily complex state.
A view model is a non-persisted domain object whose state is converted to/from a string memento. In the case of a
@@ -74,10 +74,10 @@ public class ToDoItemDto implements Dto {
Although (like any other viewmodel) a JAXB-annotated can have behaviour (actions) and UI hints, you may wish to keep
the DTO "clean", just focused on specifying the data contract.
-Behaviour can therefore be provided using xref:ugbtb.adoc#_ugbtb_more-advanced_decoupling_mixins[mixins] (annotated with
+Behaviour can therefore be provided using xref:ugbtb.adoc#_ugbtb_decoupling_mixins[mixins] (annotated with
xref:rgant.adoc#_rgant-Mixin[`@Mixin`]), while xref:rgcms.adoc#_rgcms_classes_uievent[UI events] can be used
to obtain title, icons and so on.
-For a more complete discussion of writing JAXB view models/DTOs, see xref:ugbtb.adoc#_ugbtb_more-advanced_view-models[this topic]
+For a more complete discussion of writing JAXB view models/DTOs, see xref:ugbtb.adoc#_ugbtb_view-models[this topic]
in the user guide.
http://git-wip-us.apache.org/repos/asf/isis/blob/29452af6/adocs/documentation/src/main/asciidoc/guides/_rgcfg_configuring-core.adoc
----------------------------------------------------------------------
diff --git a/adocs/documentation/src/main/asciidoc/guides/_rgcfg_configuring-core.adoc b/adocs/documentation/src/main/asciidoc/guides/_rgcfg_configuring-core.adoc
index 78d7759..38bb116 100644
--- a/adocs/documentation/src/main/asciidoc/guides/_rgcfg_configuring-core.adoc
+++ b/adocs/documentation/src/main/asciidoc/guides/_rgcfg_configuring-core.adoc
@@ -355,7 +355,7 @@ This property is IGNORED if the xref:rgcfg.adoc#_rgcfg_configuring-components[`i
| `read`,`write`
|Whether to force the `TranslationService` into either read or write mode. +
-See xref:ugbtb.adoc#_ugbtb_more-advanced_i18n[i18n support] to learn more about the translation service.
+See xref:ugbtb.adoc#_ugbtb_i18n[i18n support] to learn more about the translation service.
|`isis.viewers.` +
`paged.parented`
http://git-wip-us.apache.org/repos/asf/isis/blob/29452af6/adocs/documentation/src/main/asciidoc/guides/_rgcfg_configuring-datanucleus.adoc
----------------------------------------------------------------------
diff --git a/adocs/documentation/src/main/asciidoc/guides/_rgcfg_configuring-datanucleus.adoc b/adocs/documentation/src/main/asciidoc/guides/_rgcfg_configuring-datanucleus.adoc
index f5f1b77..a03bce8 100644
--- a/adocs/documentation/src/main/asciidoc/guides/_rgcfg_configuring-datanucleus.adoc
+++ b/adocs/documentation/src/main/asciidoc/guides/_rgcfg_configuring-datanucleus.adoc
@@ -8,7 +8,7 @@ Apache Isis programmatically configures DataNucleus; any Apache Isis properties
DataNucleus will for itself also and read the `META-INF/persistence.xml`; at a minimum this defines the name of the "persistence unit". n theory it could also hold mappings, though in Apache Isis we tend to use annotations instead.
-Furthermore, DataNucleus will search for various other XML mapping files, eg `mappings.jdo`. A full list can be found http://www.datanucleus.org/products/datanucleus/jdo/metadata.html[here]. The metadata in these XML can be used to override the annotations of annotated entities; see xref:ugbtb.adoc#_ugbtb_more-advanced_overriding-jdo-annotations[Overriding JDO Annotatons] for further discussion.
+Furthermore, DataNucleus will search for various other XML mapping files, eg `mappings.jdo`. A full list can be found http://www.datanucleus.org/products/datanucleus/jdo/metadata.html[here]. The metadata in these XML can be used to override the annotations of annotated entities; see xref:ugbtb.adoc#_ugbtb_other-techniques_overriding-jdo-annotations[Overriding JDO Annotatons] for further discussion.
include::_rgcfg_configuring-datanucleus_properties.adoc[leveloffset=+1]
http://git-wip-us.apache.org/repos/asf/isis/blob/29452af6/adocs/documentation/src/main/asciidoc/guides/_rgcms_classes_i18n_TranslatableString.adoc
----------------------------------------------------------------------
diff --git a/adocs/documentation/src/main/asciidoc/guides/_rgcms_classes_i18n_TranslatableString.adoc b/adocs/documentation/src/main/asciidoc/guides/_rgcms_classes_i18n_TranslatableString.adoc
index 311cbca..52aa7c6 100644
--- a/adocs/documentation/src/main/asciidoc/guides/_rgcms_classes_i18n_TranslatableString.adoc
+++ b/adocs/documentation/src/main/asciidoc/guides/_rgcms_classes_i18n_TranslatableString.adoc
@@ -5,7 +5,7 @@
:_imagesdir: images/
-IMPORTANT: TODO - see xref:ugbtb.adoc#_ugbtb_more-advanced_i18n[user guide, i18n].
+IMPORTANT: TODO - see xref:ugbtb.adoc#_ugbtb_i18n[user guide, i18n].
The `TranslatableString` utility class ...
http://git-wip-us.apache.org/repos/asf/isis/blob/29452af6/adocs/documentation/src/main/asciidoc/guides/_rgcms_classes_roles_Dto.adoc
----------------------------------------------------------------------
diff --git a/adocs/documentation/src/main/asciidoc/guides/_rgcms_classes_roles_Dto.adoc b/adocs/documentation/src/main/asciidoc/guides/_rgcms_classes_roles_Dto.adoc
index 93ff771..6c32fea 100644
--- a/adocs/documentation/src/main/asciidoc/guides/_rgcms_classes_roles_Dto.adoc
+++ b/adocs/documentation/src/main/asciidoc/guides/_rgcms_classes_roles_Dto.adoc
@@ -7,7 +7,7 @@
The `Dto` role interface (`1.11.0-SNAPSHOT`) is intended to be implemented by JAXB-annotated view models, that is, annotated using
xref:rgant.adoc#_rgant-XmlRootElement[`@XmlRootElement`]. It enables the ability to download the XML and
-XSD schema of those objects using two xref:ugbtb.adoc#_ugbtb_more-advanced_decoupling_mixins[mixins],
+XSD schema of those objects using two xref:ugbtb.adoc#_ugbtb_decoupling_mixins[mixins],
`Dto_downloadXml` and `Dto_downloadXsd`.
The interface is just a marker interface (with no members), and is defined as:
http://git-wip-us.apache.org/repos/asf/isis/blob/29452af6/adocs/documentation/src/main/asciidoc/guides/_rgcms_methods_prefixes_disable.adoc
----------------------------------------------------------------------
diff --git a/adocs/documentation/src/main/asciidoc/guides/_rgcms_methods_prefixes_disable.adoc b/adocs/documentation/src/main/asciidoc/guides/_rgcms_methods_prefixes_disable.adoc
index c0c9797..d564b08 100644
--- a/adocs/documentation/src/main/asciidoc/guides/_rgcms_methods_prefixes_disable.adoc
+++ b/adocs/documentation/src/main/asciidoc/guides/_rgcms_methods_prefixes_disable.adoc
@@ -17,7 +17,7 @@ Directly mutable collections are not currently supported by the xref:ugvw.adoc#[
Typically modification/invocation is vetoed based on the state of the domain object being interacted with, though it could be any reason at all (eg the current date/time of the interaction, or the state of some other related data such as stock levels, or the identity of the calling user).
-The reason for vetoing a modification/invocation is normally returned as a string. However, Apache Isis' xref:ugbtb.adoc#_ugbtb_more-advanced_i18n[i18n support] extends this so that reasons can be internationalized.
+The reason for vetoing a modification/invocation is normally returned as a string. However, Apache Isis' xref:ugbtb.adoc#_ugbtb_i18n[i18n support] extends this so that reasons can be internationalized.
http://git-wip-us.apache.org/repos/asf/isis/blob/29452af6/adocs/documentation/src/main/asciidoc/guides/_rgcms_methods_prefixes_validate.adoc
----------------------------------------------------------------------
diff --git a/adocs/documentation/src/main/asciidoc/guides/_rgcms_methods_prefixes_validate.adoc b/adocs/documentation/src/main/asciidoc/guides/_rgcms_methods_prefixes_validate.adoc
index 4c85cf9..2aa2d4e 100644
--- a/adocs/documentation/src/main/asciidoc/guides/_rgcms_methods_prefixes_validate.adoc
+++ b/adocs/documentation/src/main/asciidoc/guides/_rgcms_methods_prefixes_validate.adoc
@@ -9,7 +9,7 @@
The `validate...()` supporting method is called for properties, actions and action parameters. It allows the proposed new value for a property to be rejected, or the proposed argument of an action parameter to be rejected, or to reject a whole set of action arguments for an actio invocation.
-The reason for vetoing a modification/invocation is normally returned as a string. However, Apache Isis' xref:ugbtb.adoc#_ugbtb_more-advanced_i18n[i18n support] extends this so that reasons can be internationalized if required.
+The reason for vetoing a modification/invocation is normally returned as a string. However, Apache Isis' xref:ugbtb.adoc#_ugbtb_i18n[i18n support] extends this so that reasons can be internationalized if required.
http://git-wip-us.apache.org/repos/asf/isis/blob/29452af6/adocs/documentation/src/main/asciidoc/guides/_rgcms_methods_prefixes_validateAddTo.adoc
----------------------------------------------------------------------
diff --git a/adocs/documentation/src/main/asciidoc/guides/_rgcms_methods_prefixes_validateAddTo.adoc b/adocs/documentation/src/main/asciidoc/guides/_rgcms_methods_prefixes_validateAddTo.adoc
index 5b1f535..4665899 100644
--- a/adocs/documentation/src/main/asciidoc/guides/_rgcms_methods_prefixes_validateAddTo.adoc
+++ b/adocs/documentation/src/main/asciidoc/guides/_rgcms_methods_prefixes_validateAddTo.adoc
@@ -22,7 +22,7 @@ The signature of the supporting method for a collection with element type `E` is
public String validateAddToXxx(E element) { ... }
----
-where the returned string is the reason the collection modification invocation is vetoed (or `null` if not vetoed). Apache Isis' xref:ugbtb.adoc#_ugbtb_more-advanced_i18n[i18n support] extends this so that reasons can be internationalized if required.
+where the returned string is the reason the collection modification invocation is vetoed (or `null` if not vetoed). Apache Isis' xref:ugbtb.adoc#_ugbtb_i18n[i18n support] extends this so that reasons can be internationalized if required.
For example:
http://git-wip-us.apache.org/repos/asf/isis/blob/29452af6/adocs/documentation/src/main/asciidoc/guides/_rgcms_methods_prefixes_validateRemoveFrom.adoc
----------------------------------------------------------------------
diff --git a/adocs/documentation/src/main/asciidoc/guides/_rgcms_methods_prefixes_validateRemoveFrom.adoc b/adocs/documentation/src/main/asciidoc/guides/_rgcms_methods_prefixes_validateRemoveFrom.adoc
index 773b269..e820a41 100644
--- a/adocs/documentation/src/main/asciidoc/guides/_rgcms_methods_prefixes_validateRemoveFrom.adoc
+++ b/adocs/documentation/src/main/asciidoc/guides/_rgcms_methods_prefixes_validateRemoveFrom.adoc
@@ -22,7 +22,7 @@ The signature of the supporting method for a collection with element type `E` is
public String validateRemoveFromXxx(E element) { ... }
----
-where the returned string is the reason the collection modification invocation is vetoed (or `null` if not vetoed). Apache Isis' xref:ugbtb.adoc#_ugbtb_more-advanced_i18n[i18n support] extends this so that reasons can be internationalized if required.
+where the returned string is the reason the collection modification invocation is vetoed (or `null` if not vetoed). Apache Isis' xref:ugbtb.adoc#_ugbtb_i18n[i18n support] extends this so that reasons can be internationalized if required.
For example:
http://git-wip-us.apache.org/repos/asf/isis/blob/29452af6/adocs/documentation/src/main/asciidoc/guides/_rgcms_methods_reserved_disable.adoc
----------------------------------------------------------------------
diff --git a/adocs/documentation/src/main/asciidoc/guides/_rgcms_methods_reserved_disable.adoc b/adocs/documentation/src/main/asciidoc/guides/_rgcms_methods_reserved_disable.adoc
index 0490c73..55c3572 100644
--- a/adocs/documentation/src/main/asciidoc/guides/_rgcms_methods_reserved_disable.adoc
+++ b/adocs/documentation/src/main/asciidoc/guides/_rgcms_methods_reserved_disable.adoc
@@ -18,7 +18,7 @@ public String disable(Identifier.Type identifierType) { ... }
where `Identifier.Type` is part of the Isis applib (nested static class of `o.a.i.applib.Identifier`) to distinguish between an interaction with an action, a property or an action.
-Note that Apache Isis' xref:ugbtb.adoc#_ugbtb_more-advanced_i18n[i18n support] extends this so that the returned reason can also be internationalized.
+Note that Apache Isis' xref:ugbtb.adoc#_ugbtb_i18n[i18n support] extends this so that the returned reason can also be internationalized.
For example:
http://git-wip-us.apache.org/repos/asf/isis/blob/29452af6/adocs/documentation/src/main/asciidoc/guides/_rgcms_methods_reserved_title.adoc
----------------------------------------------------------------------
diff --git a/adocs/documentation/src/main/asciidoc/guides/_rgcms_methods_reserved_title.adoc b/adocs/documentation/src/main/asciidoc/guides/_rgcms_methods_reserved_title.adoc
index 851c9b9..28e24ac 100644
--- a/adocs/documentation/src/main/asciidoc/guides/_rgcms_methods_reserved_title.adoc
+++ b/adocs/documentation/src/main/asciidoc/guides/_rgcms_methods_reserved_title.adoc
@@ -17,7 +17,7 @@ An object's title can be constructed in various ways, but the most flexible is t
public String title() { ... }
----
-Note that Apache Isis' xref:ugbtb.adoc#_ugbtb_more-advanced_i18n[i18n support] extends this so that titles can also be internationalized.
+Note that Apache Isis' xref:ugbtb.adoc#_ugbtb_i18n[i18n support] extends this so that titles can also be internationalized.
For example, the (non-ASF) http://github.com/isisaddons/isis-app-todoapp[Isis addons' todoapp] uses this technique to add an overlay for todo items that have been completed:
http://git-wip-us.apache.org/repos/asf/isis/blob/29452af6/adocs/documentation/src/main/asciidoc/guides/_rgcms_methods_reserved_validate.adoc
----------------------------------------------------------------------
diff --git a/adocs/documentation/src/main/asciidoc/guides/_rgcms_methods_reserved_validate.adoc b/adocs/documentation/src/main/asciidoc/guides/_rgcms_methods_reserved_validate.adoc
index 3fae49e..a03ec54 100644
--- a/adocs/documentation/src/main/asciidoc/guides/_rgcms_methods_reserved_validate.adoc
+++ b/adocs/documentation/src/main/asciidoc/guides/_rgcms_methods_reserved_validate.adoc
@@ -24,4 +24,4 @@ public String validate() { ... }
where the returned string is the reason that the invocation is vetoed.
-Note that Apache Isis' xref:ugbtb.adoc#_ugbtb_more-advanced_i18n[i18n support] extends this so that the returned reason can also be internationalized.
+Note that Apache Isis' xref:ugbtb.adoc#_ugbtb_i18n[i18n support] extends this so that the returned reason can also be internationalized.
http://git-wip-us.apache.org/repos/asf/isis/blob/29452af6/adocs/documentation/src/main/asciidoc/guides/_rgsvc_api_DomainObjectContainer_messages-api.adoc
----------------------------------------------------------------------
diff --git a/adocs/documentation/src/main/asciidoc/guides/_rgsvc_api_DomainObjectContainer_messages-api.adoc b/adocs/documentation/src/main/asciidoc/guides/_rgsvc_api_DomainObjectContainer_messages-api.adoc
index b3b89b5..3ac6cd7 100644
--- a/adocs/documentation/src/main/asciidoc/guides/_rgsvc_api_DomainObjectContainer_messages-api.adoc
+++ b/adocs/documentation/src/main/asciidoc/guides/_rgsvc_api_DomainObjectContainer_messages-api.adoc
@@ -29,7 +29,7 @@ public interface DomainObjectContainer {
}
----
<1> display as a transient message to the user (not requiring acknowledgement). In the xref:ugvw.adoc#[Wicket viewer] this is implemented as a toast that automatically disappears after a period of time.
-<2> ditto, but with translatable string, for xref:ugbtb.adoc#_ugbtb_more-advanced_i18n[i18n support].
+<2> ditto, but with translatable string, for xref:ugbtb.adoc#_ugbtb_i18n[i18n support].
<3> warn the user about a situation with the specified message. In the xref:ugvw.adoc#[Wicket viewer] this is implemented as a toast that must be closed by the end-user.
<4> ditto, but with translatable string, for i18n support.
<5> show the user an unexpected application error. In the xref:ugvw.adoc#[Wicket viewer] this is implemented as a toast (with a different colour) that must be closed by the end-user.
http://git-wip-us.apache.org/repos/asf/isis/blob/29452af6/adocs/documentation/src/main/asciidoc/guides/_rgsvc_api_JaxbService.adoc
----------------------------------------------------------------------
diff --git a/adocs/documentation/src/main/asciidoc/guides/_rgsvc_api_JaxbService.adoc b/adocs/documentation/src/main/asciidoc/guides/_rgsvc_api_JaxbService.adoc
index b0ccc25..9072fd5 100644
--- a/adocs/documentation/src/main/asciidoc/guides/_rgsvc_api_JaxbService.adoc
+++ b/adocs/documentation/src/main/asciidoc/guides/_rgsvc_api_JaxbService.adoc
@@ -50,7 +50,7 @@ Isis provides a default implementation of the service, `o.a.i.schema.services.ja
This service is provided as a convenience for applications, but is also used internally by the framework to
xref:rgant.adoc#_rgant-XmlRootElement[`@XmlRootElement`]-annotated
-xref:ugbtb.adoc#_ugbtb_more-advanced_view-models[view models]. The functionality to download XML and XSD schemas is also
+xref:ugbtb.adoc#_ugbtb_view-models[view models]. The functionality to download XML and XSD schemas is also
exposed in the UI through mixins to xref:rgcms.adoc#_rgcms_classes_roles_Dto[`Dto`] interface.
http://git-wip-us.apache.org/repos/asf/isis/blob/29452af6/adocs/documentation/src/main/asciidoc/guides/_rgsvc_api_MementoService.adoc
----------------------------------------------------------------------
diff --git a/adocs/documentation/src/main/asciidoc/guides/_rgsvc_api_MementoService.adoc b/adocs/documentation/src/main/asciidoc/guides/_rgsvc_api_MementoService.adoc
index cd43c46..2ae5058 100644
--- a/adocs/documentation/src/main/asciidoc/guides/_rgsvc_api_MementoService.adoc
+++ b/adocs/documentation/src/main/asciidoc/guides/_rgsvc_api_MementoService.adoc
@@ -6,7 +6,7 @@
-The `MementoService` was originally introduced to simplify the implementation of xref:ugbtb.adoc#_ugbtb_more-advanced_view-models[ViewModel]s which are required by the framework to return string representation of all of their backing state, moreover which is safe for use within a URL.
+The `MementoService` was originally introduced to simplify the implementation of xref:ugbtb.adoc#_ugbtb_view-models[ViewModel]s which are required by the framework to return string representation of all of their backing state, moreover which is safe for use within a URL.
However, it can also be used to create a memento of arbitrary objects. Indeed, it is used internally by the core implementation of xref:rgsvc.adoc#_rgsvc_api_BackgroundService[`BackgroundService`] to capture the state of action invocations so that they can be executed by a background process.
http://git-wip-us.apache.org/repos/asf/isis/blob/29452af6/adocs/documentation/src/main/asciidoc/guides/_rgsvc_api_Scratchpad.adoc
----------------------------------------------------------------------
diff --git a/adocs/documentation/src/main/asciidoc/guides/_rgsvc_api_Scratchpad.adoc b/adocs/documentation/src/main/asciidoc/guides/_rgsvc_api_Scratchpad.adoc
index e5c2f71..9dcf43b 100644
--- a/adocs/documentation/src/main/asciidoc/guides/_rgsvc_api_Scratchpad.adoc
+++ b/adocs/documentation/src/main/asciidoc/guides/_rgsvc_api_Scratchpad.adoc
@@ -59,7 +59,7 @@ public BigDecimal totalCost() {
Scratchpad scratchpad;
----
-A more complex example could use a xref:ugbtb.adoc#_ugbtb_more-advanced_view-models[view model] to enable bulk updates to a set of objects. The view model's job is to gather track of the items to be updated:
+A more complex example could use a xref:ugbtb.adoc#_ugbtb_view-models[view model] to enable bulk updates to a set of objects. The view model's job is to gather track of the items to be updated:
[source,java]
----
http://git-wip-us.apache.org/repos/asf/isis/blob/29452af6/adocs/documentation/src/main/asciidoc/guides/_rgsvc_api_SwaggerService.adoc
----------------------------------------------------------------------
diff --git a/adocs/documentation/src/main/asciidoc/guides/_rgsvc_api_SwaggerService.adoc b/adocs/documentation/src/main/asciidoc/guides/_rgsvc_api_SwaggerService.adoc
index 724a179..2884ede 100644
--- a/adocs/documentation/src/main/asciidoc/guides/_rgsvc_api_SwaggerService.adoc
+++ b/adocs/documentation/src/main/asciidoc/guides/_rgsvc_api_SwaggerService.adoc
@@ -40,7 +40,7 @@ public interface SwaggerService {
}
----
<1> Generate a Swagger spec for use by third-party clients, ie public use. This specification is restricted only to
-xref:ugbtb.adoc#_ugbtb_more-advanced_view-models[view model]s and to domain services with a xref:rgant.adoc#_rgant_DomainService_nature[nature] of `VIEW_REST_ONLY`.
+xref:ugbtb.adoc#_ugbtb_view-models[view model]s and to domain services with a xref:rgant.adoc#_rgant_DomainService_nature[nature] of `VIEW_REST_ONLY`.
<2> Generate a Swagger spec for use only by internally-managed clients, ie private internal use. This specification includes domain entities and all menu domain services (as well as any view models).
<3> Generate a Swagger spec that is the same as private case (above), but also including any xref:rgant.adoc#_rgant_Action_restrictTo[prototype] actions.
<4> Swagger specs can be written either in JSON or YAML format.
http://git-wip-us.apache.org/repos/asf/isis/blob/29452af6/adocs/documentation/src/main/asciidoc/guides/_rgsvc_spi_AuditingService.adoc
----------------------------------------------------------------------
diff --git a/adocs/documentation/src/main/asciidoc/guides/_rgsvc_spi_AuditingService.adoc b/adocs/documentation/src/main/asciidoc/guides/_rgsvc_spi_AuditingService.adoc
index 8dd93c4..99c8f2b 100644
--- a/adocs/documentation/src/main/asciidoc/guides/_rgsvc_spi_AuditingService.adoc
+++ b/adocs/documentation/src/main/asciidoc/guides/_rgsvc_spi_AuditingService.adoc
@@ -71,7 +71,7 @@ Assuming that an `AppManifest` is being used to xref:rgcms.adoc#_rgcms_classes_A
then this can be activated by updating the `pom.xml` and updating the `AppManifest#getModules()` method.
If menu items or contributions are not required in the UI, these can be suppressed either using security or by
-implementing a xref:ugbtb.adoc#_ugbtb_more-advanced_decoupling_vetoing-visibility[vetoing subscriber].
+implementing a xref:ugbtb.adoc#_ugbtb_decoupling_vetoing-visibility[vetoing subscriber].
http://git-wip-us.apache.org/repos/asf/isis/blob/29452af6/adocs/documentation/src/main/asciidoc/guides/_rgsvc_spi_BackgroundCommandService.adoc
----------------------------------------------------------------------
diff --git a/adocs/documentation/src/main/asciidoc/guides/_rgsvc_spi_BackgroundCommandService.adoc b/adocs/documentation/src/main/asciidoc/guides/_rgsvc_spi_BackgroundCommandService.adoc
index 6aeb1d6..abe24e9 100644
--- a/adocs/documentation/src/main/asciidoc/guides/_rgsvc_spi_BackgroundCommandService.adoc
+++ b/adocs/documentation/src/main/asciidoc/guides/_rgsvc_spi_BackgroundCommandService.adoc
@@ -55,7 +55,7 @@ public class ActionInvocationMemento {
== "Internal" SPI
-The `BackgroundCommandExecution` (in isis-core) is an abstract template class for xref:ugbtb.adoc#_ugbtb_more-advanced_headless-access_AbstractIsisSessionTemplate[headless access], that defines an abstract hook method to obtain background `Command`s to be executed:
+The `BackgroundCommandExecution` (in isis-core) is an abstract template class for xref:ugbtb.adoc#_ugbtb_headless-access_AbstractIsisSessionTemplate[headless access], that defines an abstract hook method to obtain background `Command`s to be executed:
[source,java]
----
@@ -113,7 +113,7 @@ Assuming that an `AppManifest` is being used to xref:rgcms.adoc#_rgcms_classes_A
then this can be activated by updating the `pom.xml` and updating the `AppManifest#getModules()` method.
If contributions are not required in the UI, these can be suppressed either using security or by implementing a
-xref:ugbtb.adoc#_ugbtb_more-advanced_decoupling_vetoing-visibility[vetoing subscriber].
+xref:ugbtb.adoc#_ugbtb_decoupling_vetoing-visibility[vetoing subscriber].
http://git-wip-us.apache.org/repos/asf/isis/blob/29452af6/adocs/documentation/src/main/asciidoc/guides/_rgsvc_spi_CommandService.adoc
----------------------------------------------------------------------
diff --git a/adocs/documentation/src/main/asciidoc/guides/_rgsvc_spi_CommandService.adoc b/adocs/documentation/src/main/asciidoc/guides/_rgsvc_spi_CommandService.adoc
index ba0dfac..4aa78d9 100644
--- a/adocs/documentation/src/main/asciidoc/guides/_rgsvc_spi_CommandService.adoc
+++ b/adocs/documentation/src/main/asciidoc/guides/_rgsvc_spi_CommandService.adoc
@@ -80,7 +80,7 @@ Assuming that an `AppManifest` is being used to xref:rgcms.adoc#_rgcms_classes_A
then this can be activated by updating the `pom.xml` and updating the `AppManifest#getModules()` method.
If contributions are not required in the UI, these can be suppressed either using security or by implementing a
-xref:ugbtb.adoc#_ugbtb_more-advanced_decoupling_vetoing-visibility[vetoing subscriber].
+xref:ugbtb.adoc#_ugbtb_decoupling_vetoing-visibility[vetoing subscriber].
http://git-wip-us.apache.org/repos/asf/isis/blob/29452af6/adocs/documentation/src/main/asciidoc/guides/_rgsvc_spi_ContentNegotiationService.adoc
----------------------------------------------------------------------
diff --git a/adocs/documentation/src/main/asciidoc/guides/_rgsvc_spi_ContentNegotiationService.adoc b/adocs/documentation/src/main/asciidoc/guides/_rgsvc_spi_ContentNegotiationService.adoc
index 498a859..77eb40d 100644
--- a/adocs/documentation/src/main/asciidoc/guides/_rgsvc_spi_ContentNegotiationService.adoc
+++ b/adocs/documentation/src/main/asciidoc/guides/_rgsvc_spi_ContentNegotiationService.adoc
@@ -14,11 +14,11 @@ Another use case is to support "third party" REST clients over which you have no
Instead you need to create some sort of stable facade over your domain entities, one which you will preserve even if the domain entities change. There are three ways in which you can do this:
-* first is to solve the problem at the domain layer by defining a regular Apache Isis xref:ugbtb.adoc#_ugbtb_more-advanced_view-models[view model]. This is then surfaced over the RO viewer. +
+* first is to solve the problem at the domain layer by defining a regular Apache Isis xref:ugbtb.adoc#_ugbtb_view-models[view model]. This is then surfaced over the RO viewer. +
+
If the underlying entities change, then care must be taken to ensure that structure of the view model nevertheless is unchanged.
-* a second option is to solve the problem at the persistence layer, but defining a (SQL) view in the database and then xref:ugbtb.adoc#_ugbtb_more-advanced_mapping-rdbms-views[mapping this] to a (read-only) entity. Again this is surfaced by the RO viewer. +
+* a second option is to solve the problem at the persistence layer, but defining a (SQL) view in the database and then xref:ugbtb.adoc#_ugbtb_other-techniques_mapping-rdbms-views[mapping this] to a (read-only) entity. Again this is surfaced by the RO viewer. +
+
If the underlying tables change (as the result of a change in their corresponding domain entities) then once more the view must be refactored so that it still presents the same structure.
http://git-wip-us.apache.org/repos/asf/isis/blob/29452af6/adocs/documentation/src/main/asciidoc/guides/_rgsvc_spi_LocaleProvider.adoc
----------------------------------------------------------------------
diff --git a/adocs/documentation/src/main/asciidoc/guides/_rgsvc_spi_LocaleProvider.adoc b/adocs/documentation/src/main/asciidoc/guides/_rgsvc_spi_LocaleProvider.adoc
index 8005f63..dd99647 100644
--- a/adocs/documentation/src/main/asciidoc/guides/_rgsvc_spi_LocaleProvider.adoc
+++ b/adocs/documentation/src/main/asciidoc/guides/_rgsvc_spi_LocaleProvider.adoc
@@ -13,7 +13,7 @@ The role of the service itself is simply to return the `Locale` of the current u
[NOTE]
====
-For the "big picture" and further details on Apache Isis' i18n support, see xref:ugbtb.adoc#_ugbtb_more-advanced_i18n[here].
+For the "big picture" and further details on Apache Isis' i18n support, see xref:ugbtb.adoc#_ugbtb_i18n[here].
====
http://git-wip-us.apache.org/repos/asf/isis/blob/29452af6/adocs/documentation/src/main/asciidoc/guides/_rgsvc_spi_PublishingService.adoc
----------------------------------------------------------------------
diff --git a/adocs/documentation/src/main/asciidoc/guides/_rgsvc_spi_PublishingService.adoc b/adocs/documentation/src/main/asciidoc/guides/_rgsvc_spi_PublishingService.adoc
index ab736ff..a67aad5 100644
--- a/adocs/documentation/src/main/asciidoc/guides/_rgsvc_spi_PublishingService.adoc
+++ b/adocs/documentation/src/main/asciidoc/guides/_rgsvc_spi_PublishingService.adoc
@@ -166,7 +166,7 @@ then this can be activated by updating the `pom.xml` and updating the `AppManife
The modules also provide services that contribute to the UI. If contributions are not required in the UI, these can be
suppressed either using security or by implementing a
-xref:ugbtb.adoc#_ugbtb_more-advanced_decoupling_vetoing-visibility[vetoing subscriber].
+xref:ugbtb.adoc#_ugbtb_decoupling_vetoing-visibility[vetoing subscriber].
http://git-wip-us.apache.org/repos/asf/isis/blob/29452af6/adocs/documentation/src/main/asciidoc/guides/_rgsvc_spi_TranslationService.adoc
----------------------------------------------------------------------
diff --git a/adocs/documentation/src/main/asciidoc/guides/_rgsvc_spi_TranslationService.adoc b/adocs/documentation/src/main/asciidoc/guides/_rgsvc_spi_TranslationService.adoc
index dc5503e..4476549 100644
--- a/adocs/documentation/src/main/asciidoc/guides/_rgsvc_spi_TranslationService.adoc
+++ b/adocs/documentation/src/main/asciidoc/guides/_rgsvc_spi_TranslationService.adoc
@@ -11,7 +11,7 @@ The `TranslationService` is the cornerstone of Apache Isis' i18n support. Its r
[NOTE]
====
-For the "big picture" and further details on Apache Isis' i18n support, see xref:ugbtb.adoc#_ugbtb_more-advanced_i18n[here].
+For the "big picture" and further details on Apache Isis' i18n support, see xref:ugbtb.adoc#_ugbtb_i18n[here].
====
@@ -53,7 +53,7 @@ The Apache Isis framework provides a default implementation (`TranslationService
The framework also provides a supporting `TranslationServicePoMenu` provides menu items under the "Prototyping" secondary menu for controlling this service and downloading `.pot` files for translation.
-For more details on the implementation, see xref:ugbtb.adoc#_ugbtb_more-advanced_i18n[i18n support].
+For more details on the implementation, see xref:ugbtb.adoc#_ugbtb_i18n[i18n support].
@@ -64,7 +64,7 @@ Assuming that the `configuration-and-annotation` services installer is configure
`AppManifest` to xref:rgcms.adoc#_rgcms_classes_AppManifest-bootstrapping[bootstrap the app]) then Apache Isis' core
implementation of `TranslationService` service (along with the supporting menu service) are automatically registered and injected (it is annotated with `@DomainService`) so no further configuration is required.
-If the menu items are not required then these can be suppressed either using security or by implementing a xref:ugbtb.adoc#_ugbtb_more-advanced_decoupling_vetoing-visibility[vetoing subscriber].
+If the menu items are not required then these can be suppressed either using security or by implementing a xref:ugbtb.adoc#_ugbtb_decoupling_vetoing-visibility[vetoing subscriber].
To use an alternative implementation, use
xref:rgant.adoc#_rgant-DomainServiceLayout_menuOrder[`@DomainServiceLayout#menuOrder()`] (as explained
http://git-wip-us.apache.org/repos/asf/isis/blob/29452af6/adocs/documentation/src/main/asciidoc/guides/_rgsvc_spi_TranslationsResolver.adoc
----------------------------------------------------------------------
diff --git a/adocs/documentation/src/main/asciidoc/guides/_rgsvc_spi_TranslationsResolver.adoc b/adocs/documentation/src/main/asciidoc/guides/_rgsvc_spi_TranslationsResolver.adoc
index faceae0..0c3c305 100644
--- a/adocs/documentation/src/main/asciidoc/guides/_rgsvc_spi_TranslationsResolver.adoc
+++ b/adocs/documentation/src/main/asciidoc/guides/_rgsvc_spi_TranslationsResolver.adoc
@@ -13,7 +13,7 @@ The role of the service itself is locate and return translations.
[NOTE]
====
-For the "big picture" and further details on Apache Isis' i18n support, see xref:ugbtb.adoc#_ugbtb_more-advanced_i18n[here].
+For the "big picture" and further details on Apache Isis' i18n support, see xref:ugbtb.adoc#_ugbtb_i18n[here].
====
http://git-wip-us.apache.org/repos/asf/isis/blob/29452af6/adocs/documentation/src/main/asciidoc/guides/_rgsvc_spi_UrlEncodingService.adoc
----------------------------------------------------------------------
diff --git a/adocs/documentation/src/main/asciidoc/guides/_rgsvc_spi_UrlEncodingService.adoc b/adocs/documentation/src/main/asciidoc/guides/_rgsvc_spi_UrlEncodingService.adoc
index 6d094a5..e96b045 100644
--- a/adocs/documentation/src/main/asciidoc/guides/_rgsvc_spi_UrlEncodingService.adoc
+++ b/adocs/documentation/src/main/asciidoc/guides/_rgsvc_spi_UrlEncodingService.adoc
@@ -7,7 +7,7 @@
The `UrlEncodingService` (`1.11.0-SNAPSHOT`) defines a consistent way to convert strings to/from a form safe for use
-within a URL. The service is used by the framework to map xref:ugbtb.adoc#_ugbtb_more-advanced_view-models[view model]
+within a URL. The service is used by the framework to map xref:ugbtb.adoc#_ugbtb_view-models[view model]
mementos (derived from the state of the view model itself) into a form that can be used as a view model. When the
framework needs to recreate the view model (for example to invoke an action on it), this URL is converted back into a
view model memento, from which the view model can then be hydrated.
http://git-wip-us.apache.org/repos/asf/isis/blob/29452af6/adocs/documentation/src/main/asciidoc/guides/_ugbtb_decoupling.adoc
----------------------------------------------------------------------
diff --git a/adocs/documentation/src/main/asciidoc/guides/_ugbtb_decoupling.adoc b/adocs/documentation/src/main/asciidoc/guides/_ugbtb_decoupling.adoc
new file mode 100644
index 0000000..3cfb2b1
--- /dev/null
+++ b/adocs/documentation/src/main/asciidoc/guides/_ugbtb_decoupling.adoc
@@ -0,0 +1,28 @@
+[[_ugbtb_decoupling]]
+= Decoupling
+: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/
+
+
+We use Java packages as a way to group related domain objects together; the package name forms a namespace. We can then
+reason about all the classes in that package/namespace as a single unit, or module.
+
+This section describes how to use Apache Isis' features to ensure that your domain application remains decoupled. The techniques described here are also the ones that have been adopted by the various http://github.com/isisaddons[Isis Addons] modules (not ASF) for security, commands, auditing etc.
+
+The following sections describe how to re-assemble an application, in particular where some modules are in-house but others are potentially third-party (eg the Isis Addons modules).
+
+[NOTE]
+====
+There is some overlap with OSGi and Java 9's Jigsaw concepts of "module"; in the future we expect to refactor Apache Isis to leverage these module systems.
+====
+
+include::_ugbtb_decoupling_db-schemas.adoc[leveloffset=+1]
+include::_ugbtb_decoupling_mixins.adoc[leveloffset=+1]
+include::_ugbtb_decoupling_contributions.adoc[leveloffset=+1]
+include::_ugbtb_decoupling_vetoing-visibility.adoc[leveloffset=+1]
+include::_ugbtb_decoupling_event-bus.adoc[leveloffset=+1]
+include::_ugbtb_decoupling_pushing-changes.adoc[leveloffset=+1]
+
+
+
http://git-wip-us.apache.org/repos/asf/isis/blob/29452af6/adocs/documentation/src/main/asciidoc/guides/_ugbtb_decoupling_contributions.adoc
----------------------------------------------------------------------
diff --git a/adocs/documentation/src/main/asciidoc/guides/_ugbtb_decoupling_contributions.adoc b/adocs/documentation/src/main/asciidoc/guides/_ugbtb_decoupling_contributions.adoc
new file mode 100644
index 0000000..dbb3526
--- /dev/null
+++ b/adocs/documentation/src/main/asciidoc/guides/_ugbtb_decoupling_contributions.adoc
@@ -0,0 +1,23 @@
+[[_ugbtb_decoupling_contributions]]
+= Contributions
+: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/
+
+
+Contributed services provide many of the same benefits as xref:ugbtb.adoc#_ugbtb_decoupling_mixins[mixins];
+indeed mixins are an evolution and refinement of the contributions concept.
+
+The main difference between contributed services and mixins is that the actions of a contributed service will
+contribute to _all_ the parameters of its actions, whereas a mixin only contributes to the type accepted in its
+constructor. Also, contributed services are long-lived
+singletons, whereas mixins are instantiated as required (by the framework) and then discarded almost immediately.
+
+For more on contributed services:
+
+* the syntax of writing contributed actions/properties/collections is described in this xref:ugfun.adoc#_ugfun_how-tos_contributed-members[how-to]
+
+* there's also useful information in the reference guide, discussing the xref:rgant.adoc#_rgant-DomainService_nature[@DomainService#nature()] attribute, for the `NatureOfService.VIEW_CONTRIBUTIONS_ONLY` nature.
+
+
+
http://git-wip-us.apache.org/repos/asf/isis/blob/29452af6/adocs/documentation/src/main/asciidoc/guides/_ugbtb_decoupling_db-schemas.adoc
----------------------------------------------------------------------
diff --git a/adocs/documentation/src/main/asciidoc/guides/_ugbtb_decoupling_db-schemas.adoc b/adocs/documentation/src/main/asciidoc/guides/_ugbtb_decoupling_db-schemas.adoc
new file mode 100644
index 0000000..299a970
--- /dev/null
+++ b/adocs/documentation/src/main/asciidoc/guides/_ugbtb_decoupling_db-schemas.adoc
@@ -0,0 +1,141 @@
+[[_ugbtb_decoupling_db-schemas]]
+= Database Schemas
+: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 the same way that Java packages act as a namespace for domain objects, it's good practice to map domain entities to
+their own (database) schemas. As of 1.9.0, all the link:http://www.isisaddons.org[Isis Addons] (non-ASF) modules do this, for example:
+
+
+
+[source,java]
+----
+@javax.jdo.annotations.PersistenceCapable( ...
+ schema = "isissecurity",
+ table = "ApplicationUser")
+public class ApplicationUser ... { ... }
+----
+
+results in a `CREATE TABLE` statement of:
+
+[source,sql]
+----
+CREATE TABLE isissecurity."ApplicationUser" (
+ ...
+)
+----
+
+
+while:
+
+[source,java]
+----
+@javax.jdo.annotations.PersistenceCapable( ...
+ schema = "isisaudit",
+ table="AuditEntry")
+public class AuditEntry ... { ... }
+----
+
+similarly results in:
+
+[source,sql]
+----
+CREATE TABLE isisaudit."AuditEntry" (
+ ...
+)
+----
+
+
+[TIP]
+====
+If for some reason you don't want to use schemas (though we strongly recommend that you do), then note that you can override the `@PersistenceCapable` annotation by providing XML metadata (the `mappings.jdo` file); see the section on xref:rgcfg.adoc#_rgcfg_configuring-datanucleus[configuring DataNucleus Overriding Annotations] for more details.
+====
+
+
+
+
+== Listener to create schema
+
+JDO/DataNucleus does not automatically create these schema objects, but it _does_ provide a listener callback API
+on the initialization of each class into the JDO metamodel.
+
+[TIP]
+====
+Actually, the above statement isn't quite true. In DN 3.2.x (as used by Apache Isis up to v1.8.0) there was no support for schemas. As of Apache Isis 1.9.0 and DN 4.0 there is now support. But we implemented this feature initially against DN 3.2.x, and it still works, so for now we've decided to leave it in.
+====
+
+Therefore Apache Isis attaches a listener, `CreateSchemaObjectFromClassMetadata`, that checks for the schema's existence, and creates the schema if required.
+
+The guts of its implementation is:
+
+[source,java]
+----
+public class CreateSchemaObjectFromClassMetadata
+ implements MetaDataListener,
+ DataNucleusPropertiesAware {
+ @Override
+ public void loaded(final AbstractClassMetaData cmd) { ... }
+
+ protected String buildSqlToCheck(final AbstractClassMetaData cmd) {
+ final String schemaName = schemaNameFor(cmd);
+ return String.format(
+ "SELECT count(*) FROM INFORMATION_SCHEMA.SCHEMATA where SCHEMA_NAME = '%s'", schemaName);
+ }
+ protected String buildSqlToExec(final AbstractClassMetaData cmd) {
+ final String schemaName = schemaNameFor(cmd);
+ return String.format("CREATE SCHEMA \"%s\"", schemaName);
+ }
+}
+----
+
+where `MetaDataListener` is the DataNucleus listener API:
+
+[source,java]
+----
+public interface MetaDataListener {
+ void loaded(AbstractClassMetaData cmd);
+}
+----
+
+Although not formal API, the default `CreateSchemaObjectFromClassMetadata` has been designed to be easily overrideable if you
+need to tweak it to support other RDBMS'. Any implementation must implement `org.datanucleus.metadata.MetaDataListener`:
+
+The implementation provided has has been tested for HSQLDB, PostgreSQL and MS SQL Server, and is used automatically unless an alternative implementation is specified (as described in the section below).
+
+
+
+
+
+== Alternative implementation
+
+An alternative implementation can be registered and used through the following configuration property:
+
+[source,ini]
+----
+isis.persistor.datanucleus.classMetadataLoadedListener=\
+ org.apache.isis.objectstore.jdo.datanucleus.CreateSchemaObjectFromClassMetadata
+----
+
+
+Because this pertains to the JDO Objectstore we suggest you put this configuration property in `WEB-INF/persistor_datanucleus.properties`; but putting it in `isis.properties` will also work.
+
+Any implementation must implement `org.datanucleus.metadata.MetaDataListener`. In many cases simply subclassing from `CreateSchemaObjectFromClassMetadata` and overriding `buildSqlToCheck(...)` and `buildSqlToExec(...)` should suffice.
+
+If you _do_ need more control, your implementation can also optionally implement `org.apache.isis.objectstore.jdo.datanucleus.DataNucleusPropertiesAware`:
+
+[source,java]
+----
+public interface DataNucleusPropertiesAware {
+ public void setDataNucleusProperties(final Map<String, String> properties);
+}
+----
+
+This provides access to the properties passed through to JDO/DataNucleus.
+
+
+[IMPORTANT]
+====
+If you do extend Apache Isis' `CreateSchemaObjectFromClassMetadata` class for some other database, please https://issues.apache.org/jira/browse/ISIS[contribute back] your improvements.
+====
+
http://git-wip-us.apache.org/repos/asf/isis/blob/29452af6/adocs/documentation/src/main/asciidoc/guides/_ugbtb_decoupling_event-bus.adoc
----------------------------------------------------------------------
diff --git a/adocs/documentation/src/main/asciidoc/guides/_ugbtb_decoupling_event-bus.adoc b/adocs/documentation/src/main/asciidoc/guides/_ugbtb_decoupling_event-bus.adoc
new file mode 100644
index 0000000..0ce845e
--- /dev/null
+++ b/adocs/documentation/src/main/asciidoc/guides/_ugbtb_decoupling_event-bus.adoc
@@ -0,0 +1,11 @@
+[[_ugbtb_decoupling_event-bus]]
+= Event Bus
+: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: TODO - see xref:rgsvc.adoc#_rgsvc_api_EventBusService[`EventBusService`], xref:rgant.adoc#_rgant-Action_domainEvent[`@Action#domainEvent()`], xref:rgant.adoc#_rgant-Property_domainEvent[`@Property#domainEvent()`], xref:rgant.adoc#_rgant-Collection_domainEvent[`@Collection#domainEvent()`], xref:rgsvc.adoc#_rgsvc_api_WrapperFactory[`WrapperFactory`].
+
+
+
+
http://git-wip-us.apache.org/repos/asf/isis/blob/29452af6/adocs/documentation/src/main/asciidoc/guides/_ugbtb_decoupling_mixins.adoc
----------------------------------------------------------------------
diff --git a/adocs/documentation/src/main/asciidoc/guides/_ugbtb_decoupling_mixins.adoc b/adocs/documentation/src/main/asciidoc/guides/_ugbtb_decoupling_mixins.adoc
new file mode 100644
index 0000000..2013fc9
--- /dev/null
+++ b/adocs/documentation/src/main/asciidoc/guides/_ugbtb_decoupling_mixins.adoc
@@ -0,0 +1,191 @@
+[[_ugbtb_decoupling_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/
+
+
+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.
+
+Some programming languages use the term "trait" instead of mixin, and some languages (such as AspectJ) define their own
+syntax for defining such constructs. In Apache Isis a mixin is very similar to a domain service, however it also
+defines a single 1-arg constructor that defines the type of the domain objects that it contributes to.
+
+Why do this? The main reason is to allow the app to be decoupled, so that it doesn't degrade into the proverbial
+link:http://www.laputan.org/mud/mud.html#BigBallOfMud["big ball of mud"]. Mixins (and contributions) allow dependency
+to be inverted, so that the dependencies between modules can be kept acyclic and under control.
+
+
+
+== Example
+
+This is probably best explained by way of an example. Suppose we have the `Customer` domain object which implements
+a `DocumentHolder` interface:
+
+[source,java]
+----
+public class Customer implements DocumentHolder {
+ ...
+}
+----
+
+
+We could then imagine a mixin that would contribute behaviour to list, add and remove the ``Document``s for this holder:
+
+[source,java]
+----
+@Mixin // <1>
+public class DocumentHolder_documents {
+ private final DocumentHolder holder;
+ public DocumentHolder_documents(DocumentHolder holder) { // <2>
+ this.holder = holder;
+ }
+ @Action(semantics=SemanticsOf.SAFE)
+ @ActionLayout(contributed = Contributed.AS_ASSOCIATION)
+ @CollectionLayout(render = RenderType.EAGERLY)
+ public List<Document> documents() {
+ ... // <3>
+ }
+ @Action(semantics=SemanticsOf.IDEMPOTENT)
+ public DocumentHolder add(Document document) {
+ ... // <4>
+ }
+ @Action(semantics=SemanticsOf.IDEMPOTENT)
+ public DocumentHolder remove(Document document) {
+ ... // <5>
+ }
+}
+----
+<1> alternatively can use `@DomainObject(nature=Nature.MIXIN)`
+<2> constructor indicates the type that is contributed to
+<3> implementation could, for example, use the (non-ASF)
+http://github.com/isisaddons/isis-module-poly[Isis addons' poly] module.
+<4> implementation would probably delegate to an injected repository to (ultimately) insert data into some table
+<5> implementation would probably delegate to an injected repository to (ultimately) delete data from some table
+
+The above example also omits any supporting methods, eg `hideXxx()`, `disableXxx()`, `validateXxx()`, etc.
+
+In the user interface the "documents" collection, the "add" and the "delete" actions will appear to be part of
+`Customer`. In essence the framework constructs a composite UI from the parts of multiple objects.
+
+
+[TIP]
+====
+The (non-ASF) http://github.com/incodehq/incode-module-note[Incode note] and
+http://github.com/incodehq/incode-module-commchannel[Incode commchannel] modules are real-world examples that use this
+technique throughout.
+====
+
+
+
+== Contributing a single member
+
+The mixin can contribute as much or as little behaviour as makes sense. For example, in the example above it might be
+that ``Document``s are created through some other mechanism (eg scanned) and are never deleted. In that case, the
+mixin might be simply:
+
+[source,java]
+----
+@Mixin
+public class DocumentHolder_documents {
+ ..
+ public List<Document> documents() { ... }
+ ...
+}
+----
+
+
+For the case where there is only a single member being contributed, the special name "__" (that is, two underscores)
+can be used instead. In this case, the contributee member's name will be inferred from the mixin's class name. If the
+class name itself contains an underscore, then the last part of the class name will be used.
+
+Thus, for a mixin whose class name is `DocumentHolder_documents`, the effective member name is `documents`. We could
+therefore rewrite the mixin as:
+
+[source,java]
+----
+@Mixin
+public class DocumentHolder_documents {
+ ..
+ public List<Document> __() { ... }
+ ...
+}
+----
+
+The benefit of this is marginal unless there are supporting methods, in which case the removal of boilerplate is welcome:
+
+[source,java]
+----
+@Mixin
+public class DocumentHolder_documents {
+ ..
+ public List<Document> __() { ... }
+ public boolean hide__() { ... }
+ public String disable__() { ... }
+ ...
+}
+----
+
+
+== Programmatic usage
+
+When a domain object is rendered, the framework will automatically instantiate all required mixins and delegate to them
+dynamically. If writing integration tests or fixtures, or (sometimes) just regular domain logic, then you may need to
+instantiate mixins directly.
+
+For this you can use the
+xref:rgsvc.adoc#_rgsvc_api_DomainObjectContainer_object-creation-api[`DomainObjectContainer#mixin(...)`
+method. For example:
+
+[source,java]
+----
+DocumentHolder_documents mixin = container.mixin(DocumentHolder_documents.class, customer);
+----
+
+The xref:ugtst.adoc#_ugtst_integ-test-support_bootstrapping_IntegrationTestAbstract[`IntegrationTestAbstract`] and
+xref:rgcms.adoc#_rgcms_classes_super_FixtureScript[`FixtureScript`] classes both provide a `mixin(...)` convenience
+method.
+
+
+
+== Other reasons to use mixins
+
+In the introduction to this topic we mentioned that mixins are most useful for ensuring that the domain app remains
+decoupled. This applies to the case where 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.
+
+However, you might also want to consider moving behaviour out of entities even within the same module, perhaps even
+within the same Java package. And the reason for this is to 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 usually "stuffs things up". 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 (or
+xref:ugbtb.adoc#_ugbtb_decoupling_contributions[contributed services]), then these can be reloaded happily.
+(When running in prototype mode), Apache Isis will automatically recreate the portion of the metamodel for any domain
+object as it is rendered.
+
+
+
+== Related reading
+
+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/29452af6/adocs/documentation/src/main/asciidoc/guides/_ugbtb_decoupling_pushing-changes.adoc
----------------------------------------------------------------------
diff --git a/adocs/documentation/src/main/asciidoc/guides/_ugbtb_decoupling_pushing-changes.adoc b/adocs/documentation/src/main/asciidoc/guides/_ugbtb_decoupling_pushing-changes.adoc
new file mode 100644
index 0000000..003e7e2
--- /dev/null
+++ b/adocs/documentation/src/main/asciidoc/guides/_ugbtb_decoupling_pushing-changes.adoc
@@ -0,0 +1,140 @@
+[[_ugbtb_decoupling_pushing-changes]]
+= Pushing Changes
+: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]
+====
+This technique is much less powerful than using xref:ugbtb.adoc#_ugbtb_decoupling_event-bus[the event bus] . We present it mostly for completeness.
+====
+
+
+
+
+== When a property is changed
+
+If you want to invoke functionality whenever a property is changed by the user, then you should create a supporting `modifyXxx()` method and include the functionality within that. The syntax is:
+
+[source,java]
+--
+public void modifyPropertyName(PropertyType param) { ... }
+--
+
+Why not just put this functionality in the setter? Well, the setter is used by the object store to recreate the state of an already persisted object. Putting additional behaviour in the setter would cause it to be triggered incorrectly.
+
+For example:
+
+[source,java]
+--
+public class Order() {
+ public Integer getAmount() { ... }
+ public void setAmount(Integer amount) { ... }
+ public void modifyAmount(Integer amount) { // <1>
+ setAmount(amount); // <3>
+ addToTotal(amount); // <2>
+ }
+ ...
+}
+--
+<1> The `modifyAmount()` method calls ...
+<2> ... the `addToTotal()` (not shown) to maintain some running total.
+
+We don't want this `addToCall()` method to be called when pulling the object back from the object store, so we put it into the modify, not the setter.
+
+You may optionally also specify a `clearXxx()` which works the same way as modify `modify Xxx()` but is called when the property is cleared by the user (i.e. the current value replaced by nothing). The syntax is:
+
+[source,java]
+--
+public void clearPropertyName() { ... }
+--
+
+To extend the above example:
+
+[source,java]
+--
+public class Order() {
+ public Integer getAmount() { ... }
+ public void setAmount(Integer amount) { ... }
+ public void modifyAmount(Integer amount) { ... }
+ public void clearAmount() {
+ removeFromTotal(this.amount);
+ setAmount(null);
+ }
+ ...
+}
+--
+
+
+
+
+== When a collection is modified
+
+A collection may have a corresponding `addToXxx()` and/or
+`removeFromXxx()` method. If present, and direct manipulation of the
+contents of the connection has not been disabled (see ?), then they will
+be called (instead of adding/removing an object directly to the
+collection returned by the accessor).
+
+The reason for this behaviour is to allow other behaviour to be
+triggered when the contents of the collection is altered. That is, it is
+directly equivalent to the supporting `modifyXxx()` and `clearXxx()`
+methods for properties (see ?).
+
+The syntax is:
+
+[source,java]
+--
+public void addTo<CollectionName>(EntityType param) { ... }
+--
+
+and
+
+[source,java]
+--
+public void removeFromCollectionName(EntityType param) { ... }
+--
+
+where `EntityType` is the same type as the generic collection type.
+
+For example:
+
+[source,java]
+--
+public class Employee { ... }
+
+public class Department {
+
+ private int numMaleEmployees; // <1>
+ private int numFemaleEmployees; // <2>
+
+ private Set<Employee> employees = new TreeSet<Employee>();
+ public Set<Employee> getEmployees() {
+ return employees;
+ }
+ private void setEmployees(Set<Employee> employees) {
+ this.employees = employees;
+ }
+ public void addToEmployees(Employee employee) { // <3>
+ numMaleEmployees += countOneMale(employee);
+ numFemaleEmployees += countOneFemale(employee);
+ employees.add(employee);
+ }
+ public void removeFromEmployees(Employee employee) { // <4>
+ numMaleEmployees -= countOneMale(employee);
+ numFemaleEmployees -= countOneFemale(employee);
+ employees.remove(employee);
+ }
+ private int countOneMale(Employee employee) { return employee.isMale()?1:0; }
+ private int countOneFemale(Employee employee) { return employee.isFemale()?1:0; }
+
+ ...
+}
+--
+<1> maintain a count of the number of male ...
+<2> ... and female employees (getters and setters omitted)
+<3> the xref:rgcms.adoc#_rgcms_methods_prefixes_addTo[`addTo...()`] method increments the derived properties
+<4> the xref:rgcms.adoc#_rgcms_methods_prefixes_removeFrom[`removeFrom...()`] method similarly decrements the derived properties
+
+
[3/4] isis git commit: ISIS-1243: reworking the ugbtb (beyond the
basics) guide a little, breaking out and renaming the techniques chapter
Posted by da...@apache.org.
http://git-wip-us.apache.org/repos/asf/isis/blob/29452af6/adocs/documentation/src/main/asciidoc/guides/_ugbtb_decoupling_vetoing-visibility.adoc
----------------------------------------------------------------------
diff --git a/adocs/documentation/src/main/asciidoc/guides/_ugbtb_decoupling_vetoing-visibility.adoc b/adocs/documentation/src/main/asciidoc/guides/_ugbtb_decoupling_vetoing-visibility.adoc
new file mode 100644
index 0000000..d304c1b
--- /dev/null
+++ b/adocs/documentation/src/main/asciidoc/guides/_ugbtb_decoupling_vetoing-visibility.adoc
@@ -0,0 +1,15 @@
+[[_ugbtb_decoupling_vetoing-visibility]]
+= Vetoing Visibility
+: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: TODO - a write-up of the "vetoing subscriber" design pattern, eg as described in the xref:rgsvc.adoc#_rgsvc_api_BookmarkService[`BookmarkService`]
+
+
+eg if included an addon such as auditing or security.
+
+solution is to write a domain event subscriber that vetoes the visibility
+
+All the addons actions inherit from common base classes so this can be as broad-brush or fine-grained as required
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/isis/blob/29452af6/adocs/documentation/src/main/asciidoc/guides/_ugbtb_headless-access.adoc
----------------------------------------------------------------------
diff --git a/adocs/documentation/src/main/asciidoc/guides/_ugbtb_headless-access.adoc b/adocs/documentation/src/main/asciidoc/guides/_ugbtb_headless-access.adoc
new file mode 100644
index 0000000..7dcc5a8
--- /dev/null
+++ b/adocs/documentation/src/main/asciidoc/guides/_ugbtb_headless-access.adoc
@@ -0,0 +1,27 @@
+[[_ugbtb_headless-access]]
+= Headless access
+: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 tackles the topic of enabling access to an Isis application directly, or at least, not through either the xref:ugvw.adoc#[Wicket] or xref:ugvro.adoc#[Restful] viewers.
+
+There are several main use-cases:
+
+* enabling background execution, eg of a thread managed by Quartz scheduler and running within the webapp
+
+* integration from other systems, eg for a subscriber on a pub/sub mechanism such as Camel, pushing changes through an Apache Isis domain model.
+
+* leveraging an Isis application within a batch process
+
+Note that the calling thread runs in the same process space as the Apache Isis domain object model (must be physically linked to the JAR files containing the domain classes). For use cases where the calling thread runs in some other process space (eg migrating data from a legacy system), then the xref:ugvro.adoc#[Restful Objects viewer] is usually the way to go.
+
+The API described in this chapter is reasonably low-level, allowing code to interact very directly with the Apache Isis metamodel and runtime. Such callers should be considered trusted: they do not (by default) honour any business rules eg implicit in the Isis annotations or hide/disable/validate methods. However the xref:rgsvc.adoc#_rgsvc_api_WrapperFactory[`WrapperFactory`] service could be used to enforce such business rules if required.
+
+
+
+include::_ugbtb_headless-access_AbstractIsisSessionTemplate.adoc[leveloffset=+1]
+include::_ugbtb_headless-access_BackgroundCommandExecution.adoc[leveloffset=+1]
+
+
+
http://git-wip-us.apache.org/repos/asf/isis/blob/29452af6/adocs/documentation/src/main/asciidoc/guides/_ugbtb_headless-access_AbstractIsisSessionTemplate.adoc
----------------------------------------------------------------------
diff --git a/adocs/documentation/src/main/asciidoc/guides/_ugbtb_headless-access_AbstractIsisSessionTemplate.adoc b/adocs/documentation/src/main/asciidoc/guides/_ugbtb_headless-access_AbstractIsisSessionTemplate.adoc
new file mode 100644
index 0000000..14e0e36
--- /dev/null
+++ b/adocs/documentation/src/main/asciidoc/guides/_ugbtb_headless-access_AbstractIsisSessionTemplate.adoc
@@ -0,0 +1,40 @@
+[[_ugbtb_headless-access_AbstractIsisSessionTemplate]]
+= AbstractIsisSessionTemplate
+: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 `AbstractIsisSessionTemplate` class (whose name is inspired by the Spring framework's naming convention for similar classes that query http://docs.spring.io/spring/docs/2.5.x/reference/jdbc.html#jdbc-JdbcTemplate[JDBC], http://docs.spring.io/spring/docs/2.5.x/reference/jms.html#jms-jmstemplate[JMS], http://docs.spring.io/spring/docs/2.5.x/reference/orm.html#orm-jpa-template[JPA] etc.) provides the mechanism to open up a 'session' within the Apache Isis framework, in order to resolve and interact with entities.
+
+The class itself is intended to be subclassed:
+
+[source,java]
+----
+public abstract class AbstractIsisSessionTemplate {
+
+ public void execute(final AuthenticationSession authSession, final Object context) { ... } //<1>
+ protected abstract void doExecute(Object context); // <2>
+
+ protected ObjectAdapter adapterFor(final Object targetObject) { ... }
+ protected ObjectAdapter adapterFor(final RootOid rootOid) { ... }
+
+ protected PersistenceSession getPersistenceSession() { ... }
+ protected IsisTransactionManager getTransactionManager() { ... }
+ protected AdapterManager getAdapterManager() { ... }
+}
+----
+<1> `execute(...)` sets up the `IsisSession` and delegates to ...
+<2> `doExecute(...)`, the mandatory hook method for subclasses to implement.
+The passed object represents passes a context from the caller (eg the scheduler, cron job, JMS etc) that instantiated and executed the class.
+
+The `protected` methods expose key internal APIs within Apache Isis, for the subclass to use as necessary.
+
+
+[TIP]
+====
+One notable feature of `AbstractIsisSessionTemplate` is that it will automatically inject any domain services into itself. Thus, it is relatively easy for the subclass to "reach into" the domain, through injected repository services.
+====
+
+
+
http://git-wip-us.apache.org/repos/asf/isis/blob/29452af6/adocs/documentation/src/main/asciidoc/guides/_ugbtb_headless-access_BackgroundCommandExecution.adoc
----------------------------------------------------------------------
diff --git a/adocs/documentation/src/main/asciidoc/guides/_ugbtb_headless-access_BackgroundCommandExecution.adoc b/adocs/documentation/src/main/asciidoc/guides/_ugbtb_headless-access_BackgroundCommandExecution.adoc
new file mode 100644
index 0000000..570e1de
--- /dev/null
+++ b/adocs/documentation/src/main/asciidoc/guides/_ugbtb_headless-access_BackgroundCommandExecution.adoc
@@ -0,0 +1,45 @@
+[[_ugbtb_headless-access_BackgroundCommandExecution]]
+= BackgroundCommandExecution
+: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 `BackgroundCommandExecution` class (a subclass of xref:ugbtb.adoc#_ugbtb_headless-access_AbstractIsisSessionTemplate[AbstractIsisSessionTemplate]) is intended to simplify the execution of background ``Command``s persisted by way of the xref:rgsvc.adoc#_rgsvc_spi_CommandService[`CommandService`] and the xref:rgsvc.adoc#_rgsvc_spi_BackgroundCommandService[`BackgroundCommandService`].
+
+Its signature is:
+
+[source,java]
+----
+public abstract class BackgroundCommandExecution extends AbstractIsisSessionTemplate {
+ protected void doExecute(Object context) { ... }
+ protected abstract List<? extends Command> findBackgroundCommandsToExecute(); // <1>
+}
+----
+<1> `findBackgroundCommandsToExecute()` is a mandatory hook method for subclasses to implement.
+
+This allows for different implementations of the `CommandService` and `BackgroundCommandService` to persist to wherever.
+
+The diagram below (http://yuml.me/edit/363b335f[yuml.me/363b335f]) shows the dependencies between these various classes:
+
+.Inheritance Hierarchy for `BackgroundCommandExecution`
+image::{_imagesdir}headless-access/BackgroundCommandExecution.png[width="400px"]
+
+
+
+
+
+
+
+== Background Execution
+
+The `BackgroundCommandExecutionFromBackgroundCommandServiceJdo` is a concrete subclass of `BackgroundCommandExecution` (see the xref:rgsvc.adoc#_rgsvc_api_BackgroundService[`BackgroundCommandService`]), the intended use being for the class to be instantiated regularly (eg every 10 seconds) by a scheduler such as http://quartz-scheduler.org[Quartz]) to poll for ``Command``s to be executed, and then execute them.
+
+This implementation queries for ``Command``s persisted by the link:http://www.isisaddons.org/isis-module-command[Isis addons Command Module]'s implementations of xref:rgsvc.adoc#_rgsvc_spi_CommandService[`CommandService`] and xref:rgsvc.adoc#_rgsvc_spi_BackgroundCommandService[`BackgroundCommandService`] using the `BackgroundCommandServiceJdoRepository`.
+
+The diagram below (link:http://yuml.me/edit/25343da1[yuml.me/25343da1]) shows the inheritance hierarchy for this class:
+
+.Inheritance Hierarchy for `BackgroundCommandExecutionFromBackgroundCommandServiceJdo`
+image::{_imagesdir}headless-access/BackgroundCommandExecutionFromBackgroundCommandServiceJdo.png[width="500px"]
+
http://git-wip-us.apache.org/repos/asf/isis/blob/29452af6/adocs/documentation/src/main/asciidoc/guides/_ugbtb_i18n.adoc
----------------------------------------------------------------------
diff --git a/adocs/documentation/src/main/asciidoc/guides/_ugbtb_i18n.adoc b/adocs/documentation/src/main/asciidoc/guides/_ugbtb_i18n.adoc
new file mode 100644
index 0000000..e63293c
--- /dev/null
+++ b/adocs/documentation/src/main/asciidoc/guides/_ugbtb_i18n.adoc
@@ -0,0 +1,409 @@
+[[_ugbtb_i18n]]
+= i18n
+: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' support for i18n allows every element of the domain model (the class names, property names, action names, parameter names and so forth) to be translated.
+
+It also supports translations of messages raised imperatively, by which we mean as the result of a call to `title()` to obtain an object's title, or messages resulting from any business rule violations (eg xref:rgcms.adoc#_rgcms_methods_prefixes_disable[`disable...()`] or xref:rgcms.adoc#_rgcms_methods_prefixes_validate[`validate...()`], and so on.
+
+Isis does not translate the values of your domain objects, though. So, if you have a domain concept such as `Country` whose name is intended to be localized according to the current user, you will need to model
+
+
+
+== Implementation Approach
+
+Most Java frameworks tackle i18n by using Java's own `ResourceBundle` API. However, there are some serious drawbacks in this approach, such as:
+
+* if a string appears more than once (eg "name" or "description") then it must be translated everywhere it appears in every resource bundle file
+* there is no support for plural forms (see this link:http://stackoverflow.com/questions/14326653/java-internationalization-i18n-with-proper-plurals/14327683#14327683[SO answer])
+* there is no tooling support for translators
+
+Apache Isis therefore takes a different approach, drawing inspiration from GNU's https://www.gnu.org/software/gettext/manual/index.html[gettext] API and specifically its `.pot` and `.po` files. These are intended to be used as follows:
+
+* the `.pot` (portable object template) file holds the message text to be translated
+* this file is translated into multiple `.po` (portable object) files, one per supported locale
+* these `.po` files are renamed according to their locale, and placed into the 'appropriate' location to be picked up by the runtime. The name of each `.po` resolved in a very similar way to resource bundles.
+
+The format of the `.pot` and `.po` files is identical; the only difference is that the `.po` file has translations for each of the message strings. These message strings can also have singular and plural forms.
+
+
+[IMPORTANT]
+====
+Although Apache Isis' implementation is modelled after GNU's API, it does _not_ use any GNU software. This is for two reasons: (a) to simplify the toolchain/developer experience, and (b) because GNU software is usually GPL, which would be incompatible with the Apache license).
+====
+
+This design tackles all the issues of ``ResourceBundle``s:
+
+* the `.po` message format is such that any given message text to translate need only be translated once, even if it appears in multiple places in the application (eg "Name")
+* the `.po` message format includes translations for (optional) plural form as well as singular form
+* there are lots of freely available editors https://www.google.co.uk/search?q=.po+file+editor[to be found], many summarized on this https://www.drupal.org/node/11131[Drupal.org] webpage. +
++
+In fact, there are also online communities/platforms of translators to assist with translating files. One such is https://crowdin.com/[crowdin] (nb: this link does not imply endorsement).
+
+In Apache Isis' implementation, if the translation is missing from the `.po` file then the original message text from the `.pot` file will be returned. In fact, it isn't even necessary for there to be any `.po` files; `.po` translations can be added piecemeal as the need arises.
+
+
+
+
+== `TranslationService`
+
+The cornerstone of Apache Isis' support for i18n is the `TranslationService` service. This is defined in the applib with the following API:
+
+[source,java]
+----
+public interface TranslationService {
+ public String translate( // <1>
+ final String context,
+ final String text);
+ public String translate( // <2>
+ final String context,
+ final String singularText,
+ final String pluralText,
+ final int num);
+ public enum Mode {
+ READ,
+ WRITE;
+ }
+ Mode getMode(); // <3>
+}
+----
+<1> is to translate the singular form of the text
+<2> is to translate the plural form of the text
+<3> indicates whether the translation service is in read or write mode.
+
+The `translate(...)` methods are closely modelled on GNU's gettext API. The first version is used when no translation is required, the second is when both a singular and plural form will be required, with the `num` parameter being used to select which is returned. In both cases the `context` parameter provides some contextual information for the translator; this generally corresponds to the class member.
+
+The mode meanwhile determines the behaviour of the service. More on this below.
+
+
+
+=== `TranslationServicePo`
+
+Isis provides a default implementation of `TranslationService`, namely `TranslationServicePo`.
+
+If the service is running in the normal read mode, then it simply provides translations for the locale of the current user. This means locates the appropriate `.po` file (based on the requesting user's locale), finds the translation and returns it.
+
+If however the service is configured to run in write mode, then it instead records the fact that the message was requested to be translated (a little like a spy/mock in unit testing mock), and returns the original message. The service can then be queried to discover which messages need to be translated. All requested translations are written into the `.pot` file.
+
+To make the service as convenient as possible to use, the service configures itself as follows:
+
+* if running in prototype mode xref:rgcfg.adoc#_rgcfg_deployment-types[deployment type] or during integration tests, then the service runs in *write* mode, in which case it records all translations into the `.pot` file. The `.pot` file is written out when the system is shutdown.
+* if running in server (production) mode xref:rgcfg.adoc#_rgcfg_deployment-types[deployment type], then the service runs in *read* mode. It is also possible to set a configuration setting in `isis.properties` to force read mode even if running in prototype mode (useful to manually test/demo the translations).
+
+When running in write mode the original text is returned to the caller untranslated. If in read mode, then the translated `.po` files are read and translations provided as required.
+
+
+
+
+
+== Imperative messages
+
+The `TranslationService` is used internally by Apache Isis when building up the metamodel; the name and description of every class, property, collection, action and action parameter is automatically translated. Thus the simple act of bootstrapping Apache Isis will cause most of the messages requiring translation (that is: those for the Apache Isis metamodel) to be captured by the `TranslationService`.
+
+However, for an application to be fully internationalized, any validation messages (from either `disableXxx()` or `validateXxx()` supporting methods) and also possibly an object's title (from the `title()` method) will also require translation. Moreover, these messages must be captured in the `.pot` file such that they can be translated.
+
+
+=== `TranslatableString`
+
+The first part of the puzzle is tackled by an extension to Apache Isis' programming model. Whereas previously the `disableXxx()` / `validateXxx()` / `title()` methods could only return a `java.lang.String`, they may now optionally return a `TranslatableString` (defined in Isis applib) instead.
+
+Here's a (silly) example from the xref:ugfun.adoc#_ugfun_getting-started_simpleapp-archetype[SimpleApp archetype]:
+
+[source,java]
+----
+public TranslatableString validateUpdateName(final String name) {
+ return name.contains("!")? TranslatableString.tr("Exclamation mark is not allowed"): null;
+}
+----
+
+This corresponds to the following entry in the `.pot` file:
+
+[source,ini]
+----
+#: dom.simple.SimpleObject#updateName()
+msgid "Exclamation mark is not allowed"
+msgstr ""
+----
+
+The full API of `TranslatableString` is modelled on the design of GNU gettext (in particular the https://code.google.com/p/gettext-commons/wiki/Tutorial[gettext-commons] library):
+
+[source,java]
+----
+public final class TranslatableString {
+ public static TranslatableString tr( // <1>
+ final String pattern,
+ final Object... paramArgs) { ... }
+ public static TranslatableString trn( // <2>
+ final String singularPattern,
+ final String pluralPattern,
+ final int number,
+ final Object... paramArgs) { ... }
+ public String translate( // <3>
+ final TranslationService translationService,
+ final String context) { ... }
+}
+----
+<1> returns a translatable string with a single pattern for both singular and plural forms.
+<2> returns a translatable string with different patterns for singular and plural forms; the one to use is determined by the 'number' argument
+<3> translates the string using the provided `TranslationService`, using the appropriate singular/regular or plural form, and interpolating any arguments.
+
+The interpolation uses the format `{xxx}`, where the placeholder can occur multiple times.
+
+For example:
+
+[source,java]
+----
+final TranslatableString ts = TranslatableString.tr(
+ "My name is {lastName}, {firstName} {lastName}.",
+ "lastName", "Bond", "firstName", "James");
+----
+
+would interpolate (for the English locale) as "My name is Bond, James Bond".
+
+For a German user, on the other hand, if the translation in the corresponding `.po` file was:
+
+[source,ini]
+----
+#: xxx.yyy.Whatever#context()
+msgid "My name is {lastName}, {firstName} {lastName}."
+msgstr "Iche heisse {firstName} {lastName}."
+----
+
+then the translation would be: "Ich heisse James Bond".
+
+
+The same class is used in xref:rgsvc.adoc#_rgsvc_api_DomainObjectContainer[`DomainObjectContainer`] so that you can raise translatable info, warning and error messages; each of the relevant methods are overloaded.
+
+For example:
+
+[source,java]
+----
+public interface DomainObjectContainer {
+ void informUser(String message);
+ void informUser(
+ TranslatableMessage message,
+ final Class<?> contextClass, final String contextMethod); // <1>
+ ...
+}
+----
+<1> are concatenated together to form the context for the `.pot` file.
+
+
+
+=== `TranslatableException`
+
+Another mechanism by which messages can be rendered to the user are as the result of exception messages thrown and recognized by an xref:rgsvc.adoc#_rgsvc_spi_ExceptionRecognizer[`ExceptionRecognizer`].
+
+In this case, if the exception implements `TranslatableException`, then the message will automatically be translated before being rendered. The `TranslatableException` itself takes the form:
+
+[source,java]
+----
+public interface TranslatableException {
+ TranslatableString getTranslatableMessage(); // <1>
+ String getTranslationContext(); // <2>
+}
+
+----
+<1> the message to translate. If returns `null`, then the `Exception#getMessage()` is used as a fallback
+<2> the context to use when translating the message
+
+
+
+
+
+== Integration Testing
+
+So much for the API; but as noted, it is also necessary to ensure that the required translations are recorded (by the `TranslationService`) into the `.pot` file.
+
+For this, we recommend that you ensure that all such methods are tested through an xref:ugtst.adoc#_ugtst_integ-test-support[integration test] (not unit test).
+
+For example, here's the corresponding integration test for the "Exclamation mark" example from the simpleapp (above):
+
+[source,java]
+----
+@Rule
+public ExpectedException expectedException = ExpectedException.none();
+
+@Inject
+FixtureScripts fixtureScripts;
+
+@Test
+public void failsValidation() throws Exception {
+ // given
+ RecreateSimpleObjects fs = new RecreateSimpleObjects().setNumber(1);
+ fixtureScripts.runFixtureScript(fs, null);
+ SimpleObject simpleObjectWrapped = wrap(fs.getSimpleObjects().get(0));
+
+ // expect
+ expectedExceptions.expect(InvalidException.class);
+ expectedExceptions.expectMessage("Exclamation mark is not allowed");
+
+ // when
+ simpleObjectWrapped.updateName("new name!");
+}
+----
+
+Running this test will result in the framework calling the `validateUpdateName(...)` method, and thus to record that a translation is required in the `.pot` file.
+
+When the integration tests are complete (that is, when Apache Isis is shutdown), the `TranslationServicePo` will write out all captured translations to its log (more on this below). This will include all the translations captured from the Apache Isis metamodel, along with all translations as exercised by the integration tests.
+
+To ensure your app is fully internationalized app, you must therefore:
+
+* use `TranslatableString` rather than `String` for all validation/disable and title methods.
+* ensure that (at a minimum) all validation messages and title methods are integration tested.
+
+[NOTE]
+====
+We make no apologies for this requirement: one of the reasons that we decided to implement Apache Isis' i18n support in this way is because it encourages/requires the app to be properly tested.
+
+Behind the scenes Apache Isis uses a JUnit rule (`ExceptionRecognizerTranslate`) to intercept any exceptions that are thrown. These are simply passed through to the registered xref:rgsvc.adoc#_rgsvc_spi_ExceptionRecognizer[`ExceptionRecognizer`]s so that any messages are recorded as requiring translation.
+====
+
+
+
+
+
+
+== Escaped strings
+
+Translated messages can be escaped if required, eg to include embedded markup.
+
+[source,ini]
+----
+#: com.mycompany.myapp.OrderItem#quantity
+msgid "<i>Quantity</i>"
+msgstr "<i>Quantité</i>"
+----
+
+For this to work, the `namedEscaped()` attribute must be specified using either the
+xref:ugfun.adoc#_ugfun_object-layout_dynamic[dynamic layout] json file, or using an annotation such as
+xref:rgant.adoc#_rgant_PropertyLayout[`@PropertyLayout`] or xref:rgant.adoc#_rgant_ParameterLayout[`@ParameterLayout`].
+
+For example:
+
+[source,java]
+----
+@ParameterLayout(
+ named="<i>Quantity</i>", // <1>
+ namedEscaped=false
+)
+public Integer getQuantity() { ... }
+----
+<1> required (even though it won't be used when a translation is read; otherwise the escaped flag is ignored)
+
+
+
+
+== Configuration
+
+There are several different aspects of the translation service that can be configured.
+
+=== Logging
+
+To configure the `TranslationServicePo` to write to out the `translations.pot` file, add the following to the _integtests_ `logging.properties` file:
+
+[source,ini]
+----
+log4j.appender.translations-po=org.apache.log4j.FileAppender
+log4j.appender.translations-po.File=./translations.pot
+log4j.appender.translations-po.Append=false
+log4j.appender.translations-po.layout=org.apache.log4j.PatternLayout
+log4j.appender.translations-po.layout.ConversionPattern=%m%n
+
+log4j.logger.org.apache.isis.core.runtime.services.i18n.po.PoWriter=INFO,translations-po
+log4j.additivity.org.apache.isis.core.runtime.services.i18n.po.PotWriter=false
+----
+
+Just to repeat, this is _not_ the `WEB-INF/logging.properties` file, it should instead be added to the `integtests/logging.properties` file.
+
+=== Location of the `.po` files
+
+The default location of the translated `.po` files is in the `WEB-INF` directory. These are named and searched for similarly to regular Java resource bundles.
+
+For example, assuming these translations:
+
+[source,ini]
+----
+/WEB-INF/translations-en-US.po
+ /translations-en.po
+ /translations-fr-FR.po
+ /translations.po
+----
+
+then:
+
+* a user with `en-US` locale will use `translations-en-US.po`
+* a user with `en-GB` locale will use `translations-en.po`
+* a user with `fr-FR` locale will use `translations-fr-FR.po`
+* a user with `fr-CA` locale will use `translations.po`
+
+The basename for translation files is always `translations`; this cannot be altered.
+
+
+=== Externalized translation files
+
+Normally Apache Isis configuration files are read from the `WEB-INF` file. However, Apache Isis can be configured to read config files from an xref:ugbtb.adoc#_ugbtb_deployment_externalized-configuration[external directory]; this is also supported for translations.
+
+Thus, if in `web.xml` the external configuration directory has been set:
+
+[source,xml]
+----
+<context-param>
+ <param-name>isis.config.dir</param-name>
+ <param-value>location of external config directory</param-value>
+</context-param>
+----
+
+Then this directory will be used as the base for searching for translations (rather than the default 'WEB-INF/' directory).
+
+=== Force read mode
+
+As noted above, if running in prototype mode then `TranslationServicePo` will be in write mode, if in production mode then will be in read mode. To force read mode (ie use translations) even if in prototype mode, add the following configuration property to `isis.properties`:
+
+[source,ini]
+----
+isis.services.translation.po.mode=read
+----
+
+== Supporting services
+
+The `TranslationServicePo` has a number of supporting/related services.
+
+=== `LocaleProvider`
+
+The `LocaleProvider` API is used by the `TranslationServicePo` implementation to obtain the locale of the "current user".
+
+A default implementation is provided by the Wicket viewer.
+
+[NOTE]
+====
+Note that this default implementation does not support requests made through the Restful Objects viewer (there is no Wicket 'application' object available); the upshot is that requests through Restful Objects are never translated. Registering a different implementation of `LocaleProvider` that taps into appropriate REST (RestEasy?) APIs would be the way to address this.
+====
+
+
+=== `TranslationsResolver`
+
+The `TranslationResolver` is used by the `TranslationService` implementation to lookup translations for a specified locale. It is this service that reads from the `WEB-INF/` (or externalized directory).
+
+
+=== `TranslationServicePoMenu`
+
+The `TranslationServicePoMenu` provides a couple of menu actions in the UI (prototype mode only) that interacts with the underlying `TranslationServicePo`:
+
+* the `downloadTranslationsFile()` action - available only in write mode - allows the current `.pot` file to be downloaded. +
++
+[NOTE]
+====
+While this will contain all the translations from the metamodel, it will not necessarily contain all translations for all imperative methods returning `TranslatableString` instances; which are present and which are missing will depend on which imperative methods have been called (recorded by the service) prior to downloading.
+====
+
+* the `clearTranslationsCache()` action - available only in read mode - will clear the cache so that new translations can be loaded. +
++
+This allows a translator to edit the appropriate `translations-xx-XX.po` file and check the translation is correct without having to restart the app.
+
+
+
+
http://git-wip-us.apache.org/repos/asf/isis/blob/29452af6/adocs/documentation/src/main/asciidoc/guides/_ugbtb_more-advanced.adoc
----------------------------------------------------------------------
diff --git a/adocs/documentation/src/main/asciidoc/guides/_ugbtb_more-advanced.adoc b/adocs/documentation/src/main/asciidoc/guides/_ugbtb_more-advanced.adoc
deleted file mode 100644
index 051c8d6..0000000
--- a/adocs/documentation/src/main/asciidoc/guides/_ugbtb_more-advanced.adoc
+++ /dev/null
@@ -1,26 +0,0 @@
-[[_ugbtb_more-advanced]]
-= Techniques
-: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 pulls together a number of more advanced techniques that we've discovered and developed while building our own Isis applications.
-
-
-include::_ugbtb_more-advanced_decoupling.adoc[leveloffset=+1]
-include::_ugbtb_more-advanced_overriding-jdo-annotations.adoc[leveloffset=+1]
-include::_ugbtb_more-advanced_view-models.adoc[leveloffset=+1]
-include::_ugbtb_more-advanced_mapping-rdbms-views.adoc[leveloffset=+1]
-include::_ugbtb_more-advanced_transactions-and-errors.adoc[leveloffset=+1]
-include::_ugbtb_more-advanced_i18n.adoc[leveloffset=+1]
-include::_ugbtb_more-advanced_multi-tenancy.adoc[leveloffset=+1]
-include::_ugbtb_more-advanced_persisted-title.adoc[leveloffset=+1]
-include::_ugbtb_more-advanced_replacing-default-service-implementations.adoc[leveloffset=+1]include::_ugbtb_more-advanced_tips-n-tricks.adoc[leveloffset=+1]
-include::_ugbtb_more-advanced_headless-access.adoc[leveloffset=+1]
-
-
-
-
-
http://git-wip-us.apache.org/repos/asf/isis/blob/29452af6/adocs/documentation/src/main/asciidoc/guides/_ugbtb_more-advanced_decoupling.adoc
----------------------------------------------------------------------
diff --git a/adocs/documentation/src/main/asciidoc/guides/_ugbtb_more-advanced_decoupling.adoc b/adocs/documentation/src/main/asciidoc/guides/_ugbtb_more-advanced_decoupling.adoc
deleted file mode 100644
index c0983ec..0000000
--- a/adocs/documentation/src/main/asciidoc/guides/_ugbtb_more-advanced_decoupling.adoc
+++ /dev/null
@@ -1,28 +0,0 @@
-[[_ugbtb_more-advanced_decoupling]]
-= Decoupling
-: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/
-
-
-We use Java packages as a way to group related domain objects together; the package name forms a namespace. We can then
-reason about all the classes in that package/namespace as a single unit, or module.
-
-This section describes how to use Apache Isis' features to ensure that your domain application remains decoupled. The techniques described here are also the ones that have been adopted by the various http://github.com/isisaddons[Isis Addons] modules (not ASF) for security, commands, auditing etc.
-
-The following sections describe how to re-assemble an application, in particular where some modules are in-house but others are potentially third-party (eg the Isis Addons modules).
-
-[NOTE]
-====
-There is some overlap with OSGi and Java 9's Jigsaw concepts of "module"; in the future we expect to refactor Apache Isis to leverage these module systems.
-====
-
-include::_ugbtb_more-advanced_decoupling_db-schemas.adoc[leveloffset=+1]
-include::_ugbtb_more-advanced_decoupling_mixins.adoc[leveloffset=+1]
-include::_ugbtb_more-advanced_decoupling_contributions.adoc[leveloffset=+1]
-include::_ugbtb_more-advanced_decoupling_vetoing-visibility.adoc[leveloffset=+1]
-include::_ugbtb_more-advanced_decoupling_event-bus.adoc[leveloffset=+1]
-include::_ugbtb_more-advanced_decoupling_pushing-changes.adoc[leveloffset=+1]
-
-
-
http://git-wip-us.apache.org/repos/asf/isis/blob/29452af6/adocs/documentation/src/main/asciidoc/guides/_ugbtb_more-advanced_decoupling_contributions.adoc
----------------------------------------------------------------------
diff --git a/adocs/documentation/src/main/asciidoc/guides/_ugbtb_more-advanced_decoupling_contributions.adoc b/adocs/documentation/src/main/asciidoc/guides/_ugbtb_more-advanced_decoupling_contributions.adoc
deleted file mode 100644
index 255f716..0000000
--- a/adocs/documentation/src/main/asciidoc/guides/_ugbtb_more-advanced_decoupling_contributions.adoc
+++ /dev/null
@@ -1,23 +0,0 @@
-[[_ugbtb_more-advanced_decoupling_contributions]]
-= Contributions
-: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/
-
-
-Contributed services provide many of the same benefits as xref:ugbtb.adoc#_ugbtb_more-advanced_decoupling_mixins[mixins];
-indeed mixins are an evolution and refinement of the contributions concept.
-
-The main difference between contributed services and mixins is that the actions of a contributed service will
-contribute to _all_ the parameters of its actions, whereas a mixin only contributes to the type accepted in its
-constructor. Also, contributed services are long-lived
-singletons, whereas mixins are instantiated as required (by the framework) and then discarded almost immediately.
-
-For more on contributed services:
-
-* the syntax of writing contributed actions/properties/collections is described in this xref:ugfun.adoc#_ugfun_how-tos_contributed-members[how-to]
-
-* there's also useful information in the reference guide, discussing the xref:rgant.adoc#_rgant-DomainService_nature[@DomainService#nature()] attribute, for the `NatureOfService.VIEW_CONTRIBUTIONS_ONLY` nature.
-
-
-
http://git-wip-us.apache.org/repos/asf/isis/blob/29452af6/adocs/documentation/src/main/asciidoc/guides/_ugbtb_more-advanced_decoupling_db-schemas.adoc
----------------------------------------------------------------------
diff --git a/adocs/documentation/src/main/asciidoc/guides/_ugbtb_more-advanced_decoupling_db-schemas.adoc b/adocs/documentation/src/main/asciidoc/guides/_ugbtb_more-advanced_decoupling_db-schemas.adoc
deleted file mode 100644
index 687fb32..0000000
--- a/adocs/documentation/src/main/asciidoc/guides/_ugbtb_more-advanced_decoupling_db-schemas.adoc
+++ /dev/null
@@ -1,141 +0,0 @@
-[[_ugbtb_more-advanced_decoupling_db-schemas]]
-= Database Schemas
-: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 the same way that Java packages act as a namespace for domain objects, it's good practice to map domain entities to
-their own (database) schemas. As of 1.9.0, all the link:http://www.isisaddons.org[Isis Addons] (non-ASF) modules do this, for example:
-
-
-
-[source,java]
-----
-@javax.jdo.annotations.PersistenceCapable( ...
- schema = "isissecurity",
- table = "ApplicationUser")
-public class ApplicationUser ... { ... }
-----
-
-results in a `CREATE TABLE` statement of:
-
-[source,sql]
-----
-CREATE TABLE isissecurity."ApplicationUser" (
- ...
-)
-----
-
-
-while:
-
-[source,java]
-----
-@javax.jdo.annotations.PersistenceCapable( ...
- schema = "isisaudit",
- table="AuditEntry")
-public class AuditEntry ... { ... }
-----
-
-similarly results in:
-
-[source,sql]
-----
-CREATE TABLE isisaudit."AuditEntry" (
- ...
-)
-----
-
-
-[TIP]
-====
-If for some reason you don't want to use schemas (though we strongly recommend that you do), then note that you can override the `@PersistenceCapable` annotation by providing XML metadata (the `mappings.jdo` file); see the section on xref:rgcfg.adoc#_rgcfg_configuring-datanucleus[configuring DataNucleus Overriding Annotations] for more details.
-====
-
-
-
-
-== Listener to create schema
-
-JDO/DataNucleus does not automatically create these schema objects, but it _does_ provide a listener callback API
-on the initialization of each class into the JDO metamodel.
-
-[TIP]
-====
-Actually, the above statement isn't quite true. In DN 3.2.x (as used by Apache Isis up to v1.8.0) there was no support for schemas. As of Apache Isis 1.9.0 and DN 4.0 there is now support. But we implemented this feature initially against DN 3.2.x, and it still works, so for now we've decided to leave it in.
-====
-
-Therefore Apache Isis attaches a listener, `CreateSchemaObjectFromClassMetadata`, that checks for the schema's existence, and creates the schema if required.
-
-The guts of its implementation is:
-
-[source,java]
-----
-public class CreateSchemaObjectFromClassMetadata
- implements MetaDataListener,
- DataNucleusPropertiesAware {
- @Override
- public void loaded(final AbstractClassMetaData cmd) { ... }
-
- protected String buildSqlToCheck(final AbstractClassMetaData cmd) {
- final String schemaName = schemaNameFor(cmd);
- return String.format(
- "SELECT count(*) FROM INFORMATION_SCHEMA.SCHEMATA where SCHEMA_NAME = '%s'", schemaName);
- }
- protected String buildSqlToExec(final AbstractClassMetaData cmd) {
- final String schemaName = schemaNameFor(cmd);
- return String.format("CREATE SCHEMA \"%s\"", schemaName);
- }
-}
-----
-
-where `MetaDataListener` is the DataNucleus listener API:
-
-[source,java]
-----
-public interface MetaDataListener {
- void loaded(AbstractClassMetaData cmd);
-}
-----
-
-Although not formal API, the default `CreateSchemaObjectFromClassMetadata` has been designed to be easily overrideable if you
-need to tweak it to support other RDBMS'. Any implementation must implement `org.datanucleus.metadata.MetaDataListener`:
-
-The implementation provided has has been tested for HSQLDB, PostgreSQL and MS SQL Server, and is used automatically unless an alternative implementation is specified (as described in the section below).
-
-
-
-
-
-== Alternative implementation
-
-An alternative implementation can be registered and used through the following configuration property:
-
-[source,ini]
-----
-isis.persistor.datanucleus.classMetadataLoadedListener=\
- org.apache.isis.objectstore.jdo.datanucleus.CreateSchemaObjectFromClassMetadata
-----
-
-
-Because this pertains to the JDO Objectstore we suggest you put this configuration property in `WEB-INF/persistor_datanucleus.properties`; but putting it in `isis.properties` will also work.
-
-Any implementation must implement `org.datanucleus.metadata.MetaDataListener`. In many cases simply subclassing from `CreateSchemaObjectFromClassMetadata` and overriding `buildSqlToCheck(...)` and `buildSqlToExec(...)` should suffice.
-
-If you _do_ need more control, your implementation can also optionally implement `org.apache.isis.objectstore.jdo.datanucleus.DataNucleusPropertiesAware`:
-
-[source,java]
-----
-public interface DataNucleusPropertiesAware {
- public void setDataNucleusProperties(final Map<String, String> properties);
-}
-----
-
-This provides access to the properties passed through to JDO/DataNucleus.
-
-
-[IMPORTANT]
-====
-If you do extend Apache Isis' `CreateSchemaObjectFromClassMetadata` class for some other database, please https://issues.apache.org/jira/browse/ISIS[contribute back] your improvements.
-====
-
http://git-wip-us.apache.org/repos/asf/isis/blob/29452af6/adocs/documentation/src/main/asciidoc/guides/_ugbtb_more-advanced_decoupling_event-bus.adoc
----------------------------------------------------------------------
diff --git a/adocs/documentation/src/main/asciidoc/guides/_ugbtb_more-advanced_decoupling_event-bus.adoc b/adocs/documentation/src/main/asciidoc/guides/_ugbtb_more-advanced_decoupling_event-bus.adoc
deleted file mode 100644
index 97dd52c..0000000
--- a/adocs/documentation/src/main/asciidoc/guides/_ugbtb_more-advanced_decoupling_event-bus.adoc
+++ /dev/null
@@ -1,11 +0,0 @@
-[[_ugbtb_more-advanced_decoupling_event-bus]]
-= Event Bus
-: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: TODO - see xref:rgsvc.adoc#_rgsvc_api_EventBusService[`EventBusService`], xref:rgant.adoc#_rgant-Action_domainEvent[`@Action#domainEvent()`], xref:rgant.adoc#_rgant-Property_domainEvent[`@Property#domainEvent()`], xref:rgant.adoc#_rgant-Collection_domainEvent[`@Collection#domainEvent()`], xref:rgsvc.adoc#_rgsvc_api_WrapperFactory[`WrapperFactory`].
-
-
-
-
http://git-wip-us.apache.org/repos/asf/isis/blob/29452af6/adocs/documentation/src/main/asciidoc/guides/_ugbtb_more-advanced_decoupling_mixins.adoc
----------------------------------------------------------------------
diff --git a/adocs/documentation/src/main/asciidoc/guides/_ugbtb_more-advanced_decoupling_mixins.adoc b/adocs/documentation/src/main/asciidoc/guides/_ugbtb_more-advanced_decoupling_mixins.adoc
deleted file mode 100644
index 29eb3e6..0000000
--- a/adocs/documentation/src/main/asciidoc/guides/_ugbtb_more-advanced_decoupling_mixins.adoc
+++ /dev/null
@@ -1,191 +0,0 @@
-[[_ugbtb_more-advanced_decoupling_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/
-
-
-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.
-
-Some programming languages use the term "trait" instead of mixin, and some languages (such as AspectJ) define their own
-syntax for defining such constructs. In Apache Isis a mixin is very similar to a domain service, however it also
-defines a single 1-arg constructor that defines the type of the domain objects that it contributes to.
-
-Why do this? The main reason is to allow the app to be decoupled, so that it doesn't degrade into the proverbial
-link:http://www.laputan.org/mud/mud.html#BigBallOfMud["big ball of mud"]. Mixins (and contributions) allow dependency
-to be inverted, so that the dependencies between modules can be kept acyclic and under control.
-
-
-
-== Example
-
-This is probably best explained by way of an example. Suppose we have the `Customer` domain object which implements
-a `DocumentHolder` interface:
-
-[source,java]
-----
-public class Customer implements DocumentHolder {
- ...
-}
-----
-
-
-We could then imagine a mixin that would contribute behaviour to list, add and remove the ``Document``s for this holder:
-
-[source,java]
-----
-@Mixin // <1>
-public class DocumentHolder_documents {
- private final DocumentHolder holder;
- public DocumentHolder_documents(DocumentHolder holder) { // <2>
- this.holder = holder;
- }
- @Action(semantics=SemanticsOf.SAFE)
- @ActionLayout(contributed = Contributed.AS_ASSOCIATION)
- @CollectionLayout(render = RenderType.EAGERLY)
- public List<Document> documents() {
- ... // <3>
- }
- @Action(semantics=SemanticsOf.IDEMPOTENT)
- public DocumentHolder add(Document document) {
- ... // <4>
- }
- @Action(semantics=SemanticsOf.IDEMPOTENT)
- public DocumentHolder remove(Document document) {
- ... // <5>
- }
-}
-----
-<1> alternatively can use `@DomainObject(nature=Nature.MIXIN)`
-<2> constructor indicates the type that is contributed to
-<3> implementation could, for example, use the (non-ASF)
-http://github.com/isisaddons/isis-module-poly[Isis addons' poly] module.
-<4> implementation would probably delegate to an injected repository to (ultimately) insert data into some table
-<5> implementation would probably delegate to an injected repository to (ultimately) delete data from some table
-
-The above example also omits any supporting methods, eg `hideXxx()`, `disableXxx()`, `validateXxx()`, etc.
-
-In the user interface the "documents" collection, the "add" and the "delete" actions will appear to be part of
-`Customer`. In essence the framework constructs a composite UI from the parts of multiple objects.
-
-
-[TIP]
-====
-The (non-ASF) http://github.com/incodehq/incode-module-note[Incode note] and
-http://github.com/incodehq/incode-module-commchannel[Incode commchannel] modules are real-world examples that use this
-technique throughout.
-====
-
-
-
-== Contributing a single member
-
-The mixin can contribute as much or as little behaviour as makes sense. For example, in the example above it might be
-that ``Document``s are created through some other mechanism (eg scanned) and are never deleted. In that case, the
-mixin might be simply:
-
-[source,java]
-----
-@Mixin
-public class DocumentHolder_documents {
- ..
- public List<Document> documents() { ... }
- ...
-}
-----
-
-
-For the case where there is only a single member being contributed, the special name "__" (that is, two underscores)
-can be used instead. In this case, the contributee member's name will be inferred from the mixin's class name. If the
-class name itself contains an underscore, then the last part of the class name will be used.
-
-Thus, for a mixin whose class name is `DocumentHolder_documents`, the effective member name is `documents`. We could
-therefore rewrite the mixin as:
-
-[source,java]
-----
-@Mixin
-public class DocumentHolder_documents {
- ..
- public List<Document> __() { ... }
- ...
-}
-----
-
-The benefit of this is marginal unless there are supporting methods, in which case the removal of boilerplate is welcome:
-
-[source,java]
-----
-@Mixin
-public class DocumentHolder_documents {
- ..
- public List<Document> __() { ... }
- public boolean hide__() { ... }
- public String disable__() { ... }
- ...
-}
-----
-
-
-== Programmatic usage
-
-When a domain object is rendered, the framework will automatically instantiate all required mixins and delegate to them
-dynamically. If writing integration tests or fixtures, or (sometimes) just regular domain logic, then you may need to
-instantiate mixins directly.
-
-For this you can use the
-xref:rgsvc.adoc#_rgsvc_api_DomainObjectContainer_object-creation-api[`DomainObjectContainer#mixin(...)`
-method. For example:
-
-[source,java]
-----
-DocumentHolder_documents mixin = container.mixin(DocumentHolder_documents.class, customer);
-----
-
-The xref:ugtst.adoc#_ugtst_integ-test-support_bootstrapping_IntegrationTestAbstract[`IntegrationTestAbstract`] and
-xref:rgcms.adoc#_rgcms_classes_super_FixtureScript[`FixtureScript`] classes both provide a `mixin(...)` convenience
-method.
-
-
-
-== Other reasons to use mixins
-
-In the introduction to this topic we mentioned that mixins are most useful for ensuring that the domain app remains
-decoupled. This applies to the case where 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.
-
-However, you might also want to consider moving behaviour out of entities even within the same module, perhaps even
-within the same Java package. And the reason for this is to 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 usually "stuffs things up". 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 (or
-xref:ugbtb.adoc#_ugbtb_more-advanced_decoupling_contributions[contributed services]), then these can be reloaded happily.
-(When running in prototype mode), Apache Isis will automatically recreate the portion of the metamodel for any domain
-object as it is rendered.
-
-
-
-== Related reading
-
-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/29452af6/adocs/documentation/src/main/asciidoc/guides/_ugbtb_more-advanced_decoupling_pushing-changes.adoc
----------------------------------------------------------------------
diff --git a/adocs/documentation/src/main/asciidoc/guides/_ugbtb_more-advanced_decoupling_pushing-changes.adoc b/adocs/documentation/src/main/asciidoc/guides/_ugbtb_more-advanced_decoupling_pushing-changes.adoc
deleted file mode 100644
index 7cd2f5d..0000000
--- a/adocs/documentation/src/main/asciidoc/guides/_ugbtb_more-advanced_decoupling_pushing-changes.adoc
+++ /dev/null
@@ -1,140 +0,0 @@
-[[_ugbtb_more-advanced_decoupling_pushing-changes]]
-= Pushing Changes
-: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]
-====
-This technique is much less powerful than using xref:ugbtb.adoc#_ugbtb_more-advanced_decoupling_event-bus[the event bus] . We present it mostly for completeness.
-====
-
-
-
-
-== When a property is changed
-
-If you want to invoke functionality whenever a property is changed by the user, then you should create a supporting `modifyXxx()` method and include the functionality within that. The syntax is:
-
-[source,java]
---
-public void modifyPropertyName(PropertyType param) { ... }
---
-
-Why not just put this functionality in the setter? Well, the setter is used by the object store to recreate the state of an already persisted object. Putting additional behaviour in the setter would cause it to be triggered incorrectly.
-
-For example:
-
-[source,java]
---
-public class Order() {
- public Integer getAmount() { ... }
- public void setAmount(Integer amount) { ... }
- public void modifyAmount(Integer amount) { // <1>
- setAmount(amount); // <3>
- addToTotal(amount); // <2>
- }
- ...
-}
---
-<1> The `modifyAmount()` method calls ...
-<2> ... the `addToTotal()` (not shown) to maintain some running total.
-
-We don't want this `addToCall()` method to be called when pulling the object back from the object store, so we put it into the modify, not the setter.
-
-You may optionally also specify a `clearXxx()` which works the same way as modify `modify Xxx()` but is called when the property is cleared by the user (i.e. the current value replaced by nothing). The syntax is:
-
-[source,java]
---
-public void clearPropertyName() { ... }
---
-
-To extend the above example:
-
-[source,java]
---
-public class Order() {
- public Integer getAmount() { ... }
- public void setAmount(Integer amount) { ... }
- public void modifyAmount(Integer amount) { ... }
- public void clearAmount() {
- removeFromTotal(this.amount);
- setAmount(null);
- }
- ...
-}
---
-
-
-
-
-== When a collection is modified
-
-A collection may have a corresponding `addToXxx()` and/or
-`removeFromXxx()` method. If present, and direct manipulation of the
-contents of the connection has not been disabled (see ?), then they will
-be called (instead of adding/removing an object directly to the
-collection returned by the accessor).
-
-The reason for this behaviour is to allow other behaviour to be
-triggered when the contents of the collection is altered. That is, it is
-directly equivalent to the supporting `modifyXxx()` and `clearXxx()`
-methods for properties (see ?).
-
-The syntax is:
-
-[source,java]
---
-public void addTo<CollectionName>(EntityType param) { ... }
---
-
-and
-
-[source,java]
---
-public void removeFromCollectionName(EntityType param) { ... }
---
-
-where `EntityType` is the same type as the generic collection type.
-
-For example:
-
-[source,java]
---
-public class Employee { ... }
-
-public class Department {
-
- private int numMaleEmployees; // <1>
- private int numFemaleEmployees; // <2>
-
- private Set<Employee> employees = new TreeSet<Employee>();
- public Set<Employee> getEmployees() {
- return employees;
- }
- private void setEmployees(Set<Employee> employees) {
- this.employees = employees;
- }
- public void addToEmployees(Employee employee) { // <3>
- numMaleEmployees += countOneMale(employee);
- numFemaleEmployees += countOneFemale(employee);
- employees.add(employee);
- }
- public void removeFromEmployees(Employee employee) { // <4>
- numMaleEmployees -= countOneMale(employee);
- numFemaleEmployees -= countOneFemale(employee);
- employees.remove(employee);
- }
- private int countOneMale(Employee employee) { return employee.isMale()?1:0; }
- private int countOneFemale(Employee employee) { return employee.isFemale()?1:0; }
-
- ...
-}
---
-<1> maintain a count of the number of male ...
-<2> ... and female employees (getters and setters omitted)
-<3> the xref:rgcms.adoc#_rgcms_methods_prefixes_addTo[`addTo...()`] method increments the derived properties
-<4> the xref:rgcms.adoc#_rgcms_methods_prefixes_removeFrom[`removeFrom...()`] method similarly decrements the derived properties
-
-
http://git-wip-us.apache.org/repos/asf/isis/blob/29452af6/adocs/documentation/src/main/asciidoc/guides/_ugbtb_more-advanced_decoupling_vetoing-visibility.adoc
----------------------------------------------------------------------
diff --git a/adocs/documentation/src/main/asciidoc/guides/_ugbtb_more-advanced_decoupling_vetoing-visibility.adoc b/adocs/documentation/src/main/asciidoc/guides/_ugbtb_more-advanced_decoupling_vetoing-visibility.adoc
deleted file mode 100644
index d5abe7f..0000000
--- a/adocs/documentation/src/main/asciidoc/guides/_ugbtb_more-advanced_decoupling_vetoing-visibility.adoc
+++ /dev/null
@@ -1,15 +0,0 @@
-[[_ugbtb_more-advanced_decoupling_vetoing-visibility]]
-= Vetoing Visibility
-: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: TODO - a write-up of the "vetoing subscriber" design pattern, eg as described in the xref:rgsvc.adoc#_rgsvc_api_BookmarkService[`BookmarkService`]
-
-
-eg if included an addon such as auditing or security.
-
-solution is to write a domain event subscriber that vetoes the visibility
-
-All the addons actions inherit from common base classes so this can be as broad-brush or fine-grained as required
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/isis/blob/29452af6/adocs/documentation/src/main/asciidoc/guides/_ugbtb_more-advanced_headless-access.adoc
----------------------------------------------------------------------
diff --git a/adocs/documentation/src/main/asciidoc/guides/_ugbtb_more-advanced_headless-access.adoc b/adocs/documentation/src/main/asciidoc/guides/_ugbtb_more-advanced_headless-access.adoc
deleted file mode 100644
index b7c77c0..0000000
--- a/adocs/documentation/src/main/asciidoc/guides/_ugbtb_more-advanced_headless-access.adoc
+++ /dev/null
@@ -1,27 +0,0 @@
-[[_ugbtb_more-advanced_headless-access]]
-= Headless access
-: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 tackles the topic of enabling access to an Isis application directly, or at least, not through either the xref:ugvw.adoc#[Wicket] or xref:ugvro.adoc#[Restful] viewers.
-
-There are several main use-cases:
-
-* enabling background execution, eg of a thread managed by Quartz scheduler and running within the webapp
-
-* integration from other systems, eg for a subscriber on a pub/sub mechanism such as Camel, pushing changes through an Apache Isis domain model.
-
-* leveraging an Isis application within a batch process
-
-Note that the calling thread runs in the same process space as the Apache Isis domain object model (must be physically linked to the JAR files containing the domain classes). For use cases where the calling thread runs in some other process space (eg migrating data from a legacy system), then the xref:ugvro.adoc#[Restful Objects viewer] is usually the way to go.
-
-The API described in this chapter is reasonably low-level, allowing code to interact very directly with the Apache Isis metamodel and runtime. Such callers should be considered trusted: they do not (by default) honour any business rules eg implicit in the Isis annotations or hide/disable/validate methods. However the xref:rgsvc.adoc#_rgsvc_api_WrapperFactory[`WrapperFactory`] service could be used to enforce such business rules if required.
-
-
-
-include::_ugbtb_more-advanced_headless-access_AbstractIsisSessionTemplate.adoc[leveloffset=+1]
-include::_ugbtb_more-advanced_headless-access_BackgroundCommandExecution.adoc[leveloffset=+1]
-
-
-
http://git-wip-us.apache.org/repos/asf/isis/blob/29452af6/adocs/documentation/src/main/asciidoc/guides/_ugbtb_more-advanced_headless-access_AbstractIsisSessionTemplate.adoc
----------------------------------------------------------------------
diff --git a/adocs/documentation/src/main/asciidoc/guides/_ugbtb_more-advanced_headless-access_AbstractIsisSessionTemplate.adoc b/adocs/documentation/src/main/asciidoc/guides/_ugbtb_more-advanced_headless-access_AbstractIsisSessionTemplate.adoc
deleted file mode 100644
index a0dcc5a..0000000
--- a/adocs/documentation/src/main/asciidoc/guides/_ugbtb_more-advanced_headless-access_AbstractIsisSessionTemplate.adoc
+++ /dev/null
@@ -1,40 +0,0 @@
-[[_ugbtb_more-advanced_headless-access_AbstractIsisSessionTemplate]]
-= AbstractIsisSessionTemplate
-: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 `AbstractIsisSessionTemplate` class (whose name is inspired by the Spring framework's naming convention for similar classes that query http://docs.spring.io/spring/docs/2.5.x/reference/jdbc.html#jdbc-JdbcTemplate[JDBC], http://docs.spring.io/spring/docs/2.5.x/reference/jms.html#jms-jmstemplate[JMS], http://docs.spring.io/spring/docs/2.5.x/reference/orm.html#orm-jpa-template[JPA] etc.) provides the mechanism to open up a 'session' within the Apache Isis framework, in order to resolve and interact with entities.
-
-The class itself is intended to be subclassed:
-
-[source,java]
-----
-public abstract class AbstractIsisSessionTemplate {
-
- public void execute(final AuthenticationSession authSession, final Object context) { ... } //<1>
- protected abstract void doExecute(Object context); // <2>
-
- protected ObjectAdapter adapterFor(final Object targetObject) { ... }
- protected ObjectAdapter adapterFor(final RootOid rootOid) { ... }
-
- protected PersistenceSession getPersistenceSession() { ... }
- protected IsisTransactionManager getTransactionManager() { ... }
- protected AdapterManager getAdapterManager() { ... }
-}
-----
-<1> `execute(...)` sets up the `IsisSession` and delegates to ...
-<2> `doExecute(...)`, the mandatory hook method for subclasses to implement.
-The passed object represents passes a context from the caller (eg the scheduler, cron job, JMS etc) that instantiated and executed the class.
-
-The `protected` methods expose key internal APIs within Apache Isis, for the subclass to use as necessary.
-
-
-[TIP]
-====
-One notable feature of `AbstractIsisSessionTemplate` is that it will automatically inject any domain services into itself. Thus, it is relatively easy for the subclass to "reach into" the domain, through injected repository services.
-====
-
-
-
http://git-wip-us.apache.org/repos/asf/isis/blob/29452af6/adocs/documentation/src/main/asciidoc/guides/_ugbtb_more-advanced_headless-access_BackgroundCommandExecution.adoc
----------------------------------------------------------------------
diff --git a/adocs/documentation/src/main/asciidoc/guides/_ugbtb_more-advanced_headless-access_BackgroundCommandExecution.adoc b/adocs/documentation/src/main/asciidoc/guides/_ugbtb_more-advanced_headless-access_BackgroundCommandExecution.adoc
deleted file mode 100644
index 06d6747..0000000
--- a/adocs/documentation/src/main/asciidoc/guides/_ugbtb_more-advanced_headless-access_BackgroundCommandExecution.adoc
+++ /dev/null
@@ -1,45 +0,0 @@
-[[_ugbtb_more-advanced_headless-access_BackgroundCommandExecution]]
-= BackgroundCommandExecution
-: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 `BackgroundCommandExecution` class (a subclass of xref:ugbtb.adoc#_ugbtb_more-advanced_headless-access_AbstractIsisSessionTemplate[AbstractIsisSessionTemplate]) is intended to simplify the execution of background ``Command``s persisted by way of the xref:rgsvc.adoc#_rgsvc_spi_CommandService[`CommandService`] and the xref:rgsvc.adoc#_rgsvc_spi_BackgroundCommandService[`BackgroundCommandService`].
-
-Its signature is:
-
-[source,java]
-----
-public abstract class BackgroundCommandExecution extends AbstractIsisSessionTemplate {
- protected void doExecute(Object context) { ... }
- protected abstract List<? extends Command> findBackgroundCommandsToExecute(); // <1>
-}
-----
-<1> `findBackgroundCommandsToExecute()` is a mandatory hook method for subclasses to implement.
-
-This allows for different implementations of the `CommandService` and `BackgroundCommandService` to persist to wherever.
-
-The diagram below (http://yuml.me/edit/363b335f[yuml.me/363b335f]) shows the dependencies between these various classes:
-
-.Inheritance Hierarchy for `BackgroundCommandExecution`
-image::{_imagesdir}headless-access/BackgroundCommandExecution.png[width="400px"]
-
-
-
-
-
-
-
-== Background Execution
-
-The `BackgroundCommandExecutionFromBackgroundCommandServiceJdo` is a concrete subclass of `BackgroundCommandExecution` (see the xref:rgsvc.adoc#_rgsvc_api_BackgroundService[`BackgroundCommandService`]), the intended use being for the class to be instantiated regularly (eg every 10 seconds) by a scheduler such as http://quartz-scheduler.org[Quartz]) to poll for ``Command``s to be executed, and then execute them.
-
-This implementation queries for ``Command``s persisted by the link:http://www.isisaddons.org/isis-module-command[Isis addons Command Module]'s implementations of xref:rgsvc.adoc#_rgsvc_spi_CommandService[`CommandService`] and xref:rgsvc.adoc#_rgsvc_spi_BackgroundCommandService[`BackgroundCommandService`] using the `BackgroundCommandServiceJdoRepository`.
-
-The diagram below (link:http://yuml.me/edit/25343da1[yuml.me/25343da1]) shows the inheritance hierarchy for this class:
-
-.Inheritance Hierarchy for `BackgroundCommandExecutionFromBackgroundCommandServiceJdo`
-image::{_imagesdir}headless-access/BackgroundCommandExecutionFromBackgroundCommandServiceJdo.png[width="500px"]
-
[2/4] isis git commit: ISIS-1243: reworking the ugbtb (beyond the
basics) guide a little, breaking out and renaming the techniques chapter
Posted by da...@apache.org.
http://git-wip-us.apache.org/repos/asf/isis/blob/29452af6/adocs/documentation/src/main/asciidoc/guides/_ugbtb_more-advanced_i18n.adoc
----------------------------------------------------------------------
diff --git a/adocs/documentation/src/main/asciidoc/guides/_ugbtb_more-advanced_i18n.adoc b/adocs/documentation/src/main/asciidoc/guides/_ugbtb_more-advanced_i18n.adoc
deleted file mode 100644
index cfbebcf..0000000
--- a/adocs/documentation/src/main/asciidoc/guides/_ugbtb_more-advanced_i18n.adoc
+++ /dev/null
@@ -1,409 +0,0 @@
-[[_ugbtb_more-advanced_i18n]]
-= i18n
-: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' support for i18n allows every element of the domain model (the class names, property names, action names, parameter names and so forth) to be translated.
-
-It also supports translations of messages raised imperatively, by which we mean as the result of a call to `title()` to obtain an object's title, or messages resulting from any business rule violations (eg xref:rgcms.adoc#_rgcms_methods_prefixes_disable[`disable...()`] or xref:rgcms.adoc#_rgcms_methods_prefixes_validate[`validate...()`], and so on.
-
-Isis does not translate the values of your domain objects, though. So, if you have a domain concept such as `Country` whose name is intended to be localized according to the current user, you will need to model
-
-
-
-== Implementation Approach
-
-Most Java frameworks tackle i18n by using Java's own `ResourceBundle` API. However, there are some serious drawbacks in this approach, such as:
-
-* if a string appears more than once (eg "name" or "description") then it must be translated everywhere it appears in every resource bundle file
-* there is no support for plural forms (see this link:http://stackoverflow.com/questions/14326653/java-internationalization-i18n-with-proper-plurals/14327683#14327683[SO answer])
-* there is no tooling support for translators
-
-Apache Isis therefore takes a different approach, drawing inspiration from GNU's https://www.gnu.org/software/gettext/manual/index.html[gettext] API and specifically its `.pot` and `.po` files. These are intended to be used as follows:
-
-* the `.pot` (portable object template) file holds the message text to be translated
-* this file is translated into multiple `.po` (portable object) files, one per supported locale
-* these `.po` files are renamed according to their locale, and placed into the 'appropriate' location to be picked up by the runtime. The name of each `.po` resolved in a very similar way to resource bundles.
-
-The format of the `.pot` and `.po` files is identical; the only difference is that the `.po` file has translations for each of the message strings. These message strings can also have singular and plural forms.
-
-
-[IMPORTANT]
-====
-Although Apache Isis' implementation is modelled after GNU's API, it does _not_ use any GNU software. This is for two reasons: (a) to simplify the toolchain/developer experience, and (b) because GNU software is usually GPL, which would be incompatible with the Apache license).
-====
-
-This design tackles all the issues of ``ResourceBundle``s:
-
-* the `.po` message format is such that any given message text to translate need only be translated once, even if it appears in multiple places in the application (eg "Name")
-* the `.po` message format includes translations for (optional) plural form as well as singular form
-* there are lots of freely available editors https://www.google.co.uk/search?q=.po+file+editor[to be found], many summarized on this https://www.drupal.org/node/11131[Drupal.org] webpage. +
-+
-In fact, there are also online communities/platforms of translators to assist with translating files. One such is https://crowdin.com/[crowdin] (nb: this link does not imply endorsement).
-
-In Apache Isis' implementation, if the translation is missing from the `.po` file then the original message text from the `.pot` file will be returned. In fact, it isn't even necessary for there to be any `.po` files; `.po` translations can be added piecemeal as the need arises.
-
-
-
-
-== `TranslationService`
-
-The cornerstone of Apache Isis' support for i18n is the `TranslationService` service. This is defined in the applib with the following API:
-
-[source,java]
-----
-public interface TranslationService {
- public String translate( // <1>
- final String context,
- final String text);
- public String translate( // <2>
- final String context,
- final String singularText,
- final String pluralText,
- final int num);
- public enum Mode {
- READ,
- WRITE;
- }
- Mode getMode(); // <3>
-}
-----
-<1> is to translate the singular form of the text
-<2> is to translate the plural form of the text
-<3> indicates whether the translation service is in read or write mode.
-
-The `translate(...)` methods are closely modelled on GNU's gettext API. The first version is used when no translation is required, the second is when both a singular and plural form will be required, with the `num` parameter being used to select which is returned. In both cases the `context` parameter provides some contextual information for the translator; this generally corresponds to the class member.
-
-The mode meanwhile determines the behaviour of the service. More on this below.
-
-
-
-=== `TranslationServicePo`
-
-Isis provides a default implementation of `TranslationService`, namely `TranslationServicePo`.
-
-If the service is running in the normal read mode, then it simply provides translations for the locale of the current user. This means locates the appropriate `.po` file (based on the requesting user's locale), finds the translation and returns it.
-
-If however the service is configured to run in write mode, then it instead records the fact that the message was requested to be translated (a little like a spy/mock in unit testing mock), and returns the original message. The service can then be queried to discover which messages need to be translated. All requested translations are written into the `.pot` file.
-
-To make the service as convenient as possible to use, the service configures itself as follows:
-
-* if running in prototype mode xref:rgcfg.adoc#_rgcfg_deployment-types[deployment type] or during integration tests, then the service runs in *write* mode, in which case it records all translations into the `.pot` file. The `.pot` file is written out when the system is shutdown.
-* if running in server (production) mode xref:rgcfg.adoc#_rgcfg_deployment-types[deployment type], then the service runs in *read* mode. It is also possible to set a configuration setting in `isis.properties` to force read mode even if running in prototype mode (useful to manually test/demo the translations).
-
-When running in write mode the original text is returned to the caller untranslated. If in read mode, then the translated `.po` files are read and translations provided as required.
-
-
-
-
-
-== Imperative messages
-
-The `TranslationService` is used internally by Apache Isis when building up the metamodel; the name and description of every class, property, collection, action and action parameter is automatically translated. Thus the simple act of bootstrapping Apache Isis will cause most of the messages requiring translation (that is: those for the Apache Isis metamodel) to be captured by the `TranslationService`.
-
-However, for an application to be fully internationalized, any validation messages (from either `disableXxx()` or `validateXxx()` supporting methods) and also possibly an object's title (from the `title()` method) will also require translation. Moreover, these messages must be captured in the `.pot` file such that they can be translated.
-
-
-=== `TranslatableString`
-
-The first part of the puzzle is tackled by an extension to Apache Isis' programming model. Whereas previously the `disableXxx()` / `validateXxx()` / `title()` methods could only return a `java.lang.String`, they may now optionally return a `TranslatableString` (defined in Isis applib) instead.
-
-Here's a (silly) example from the xref:ugfun.adoc#_ugfun_getting-started_simpleapp-archetype[SimpleApp archetype]:
-
-[source,java]
-----
-public TranslatableString validateUpdateName(final String name) {
- return name.contains("!")? TranslatableString.tr("Exclamation mark is not allowed"): null;
-}
-----
-
-This corresponds to the following entry in the `.pot` file:
-
-[source,ini]
-----
-#: dom.simple.SimpleObject#updateName()
-msgid "Exclamation mark is not allowed"
-msgstr ""
-----
-
-The full API of `TranslatableString` is modelled on the design of GNU gettext (in particular the https://code.google.com/p/gettext-commons/wiki/Tutorial[gettext-commons] library):
-
-[source,java]
-----
-public final class TranslatableString {
- public static TranslatableString tr( // <1>
- final String pattern,
- final Object... paramArgs) { ... }
- public static TranslatableString trn( // <2>
- final String singularPattern,
- final String pluralPattern,
- final int number,
- final Object... paramArgs) { ... }
- public String translate( // <3>
- final TranslationService translationService,
- final String context) { ... }
-}
-----
-<1> returns a translatable string with a single pattern for both singular and plural forms.
-<2> returns a translatable string with different patterns for singular and plural forms; the one to use is determined by the 'number' argument
-<3> translates the string using the provided `TranslationService`, using the appropriate singular/regular or plural form, and interpolating any arguments.
-
-The interpolation uses the format `{xxx}`, where the placeholder can occur multiple times.
-
-For example:
-
-[source,java]
-----
-final TranslatableString ts = TranslatableString.tr(
- "My name is {lastName}, {firstName} {lastName}.",
- "lastName", "Bond", "firstName", "James");
-----
-
-would interpolate (for the English locale) as "My name is Bond, James Bond".
-
-For a German user, on the other hand, if the translation in the corresponding `.po` file was:
-
-[source,ini]
-----
-#: xxx.yyy.Whatever#context()
-msgid "My name is {lastName}, {firstName} {lastName}."
-msgstr "Iche heisse {firstName} {lastName}."
-----
-
-then the translation would be: "Ich heisse James Bond".
-
-
-The same class is used in xref:rgsvc.adoc#_rgsvc_api_DomainObjectContainer[`DomainObjectContainer`] so that you can raise translatable info, warning and error messages; each of the relevant methods are overloaded.
-
-For example:
-
-[source,java]
-----
-public interface DomainObjectContainer {
- void informUser(String message);
- void informUser(
- TranslatableMessage message,
- final Class<?> contextClass, final String contextMethod); // <1>
- ...
-}
-----
-<1> are concatenated together to form the context for the `.pot` file.
-
-
-
-=== `TranslatableException`
-
-Another mechanism by which messages can be rendered to the user are as the result of exception messages thrown and recognized by an xref:rgsvc.adoc#_rgsvc_spi_ExceptionRecognizer[`ExceptionRecognizer`].
-
-In this case, if the exception implements `TranslatableException`, then the message will automatically be translated before being rendered. The `TranslatableException` itself takes the form:
-
-[source,java]
-----
-public interface TranslatableException {
- TranslatableString getTranslatableMessage(); // <1>
- String getTranslationContext(); // <2>
-}
-
-----
-<1> the message to translate. If returns `null`, then the `Exception#getMessage()` is used as a fallback
-<2> the context to use when translating the message
-
-
-
-
-
-== Integration Testing
-
-So much for the API; but as noted, it is also necessary to ensure that the required translations are recorded (by the `TranslationService`) into the `.pot` file.
-
-For this, we recommend that you ensure that all such methods are tested through an xref:ugtst.adoc#_ugtst_integ-test-support[integration test] (not unit test).
-
-For example, here's the corresponding integration test for the "Exclamation mark" example from the simpleapp (above):
-
-[source,java]
-----
-@Rule
-public ExpectedException expectedException = ExpectedException.none();
-
-@Inject
-FixtureScripts fixtureScripts;
-
-@Test
-public void failsValidation() throws Exception {
- // given
- RecreateSimpleObjects fs = new RecreateSimpleObjects().setNumber(1);
- fixtureScripts.runFixtureScript(fs, null);
- SimpleObject simpleObjectWrapped = wrap(fs.getSimpleObjects().get(0));
-
- // expect
- expectedExceptions.expect(InvalidException.class);
- expectedExceptions.expectMessage("Exclamation mark is not allowed");
-
- // when
- simpleObjectWrapped.updateName("new name!");
-}
-----
-
-Running this test will result in the framework calling the `validateUpdateName(...)` method, and thus to record that a translation is required in the `.pot` file.
-
-When the integration tests are complete (that is, when Apache Isis is shutdown), the `TranslationServicePo` will write out all captured translations to its log (more on this below). This will include all the translations captured from the Apache Isis metamodel, along with all translations as exercised by the integration tests.
-
-To ensure your app is fully internationalized app, you must therefore:
-
-* use `TranslatableString` rather than `String` for all validation/disable and title methods.
-* ensure that (at a minimum) all validation messages and title methods are integration tested.
-
-[NOTE]
-====
-We make no apologies for this requirement: one of the reasons that we decided to implement Apache Isis' i18n support in this way is because it encourages/requires the app to be properly tested.
-
-Behind the scenes Apache Isis uses a JUnit rule (`ExceptionRecognizerTranslate`) to intercept any exceptions that are thrown. These are simply passed through to the registered xref:rgsvc.adoc#_rgsvc_spi_ExceptionRecognizer[`ExceptionRecognizer`]s so that any messages are recorded as requiring translation.
-====
-
-
-
-
-
-
-== Escaped strings
-
-Translated messages can be escaped if required, eg to include embedded markup.
-
-[source,ini]
-----
-#: com.mycompany.myapp.OrderItem#quantity
-msgid "<i>Quantity</i>"
-msgstr "<i>Quantité</i>"
-----
-
-For this to work, the `namedEscaped()` attribute must be specified using either the
-xref:ugfun.adoc#_ugfun_object-layout_dynamic[dynamic layout] json file, or using an annotation such as
-xref:rgant.adoc#_rgant_PropertyLayout[`@PropertyLayout`] or xref:rgant.adoc#_rgant_ParameterLayout[`@ParameterLayout`].
-
-For example:
-
-[source,java]
-----
-@ParameterLayout(
- named="<i>Quantity</i>", // <1>
- namedEscaped=false
-)
-public Integer getQuantity() { ... }
-----
-<1> required (even though it won't be used when a translation is read; otherwise the escaped flag is ignored)
-
-
-
-
-== Configuration
-
-There are several different aspects of the translation service that can be configured.
-
-=== Logging
-
-To configure the `TranslationServicePo` to write to out the `translations.pot` file, add the following to the _integtests_ `logging.properties` file:
-
-[source,ini]
-----
-log4j.appender.translations-po=org.apache.log4j.FileAppender
-log4j.appender.translations-po.File=./translations.pot
-log4j.appender.translations-po.Append=false
-log4j.appender.translations-po.layout=org.apache.log4j.PatternLayout
-log4j.appender.translations-po.layout.ConversionPattern=%m%n
-
-log4j.logger.org.apache.isis.core.runtime.services.i18n.po.PoWriter=INFO,translations-po
-log4j.additivity.org.apache.isis.core.runtime.services.i18n.po.PotWriter=false
-----
-
-Just to repeat, this is _not_ the `WEB-INF/logging.properties` file, it should instead be added to the `integtests/logging.properties` file.
-
-=== Location of the `.po` files
-
-The default location of the translated `.po` files is in the `WEB-INF` directory. These are named and searched for similarly to regular Java resource bundles.
-
-For example, assuming these translations:
-
-[source,ini]
-----
-/WEB-INF/translations-en-US.po
- /translations-en.po
- /translations-fr-FR.po
- /translations.po
-----
-
-then:
-
-* a user with `en-US` locale will use `translations-en-US.po`
-* a user with `en-GB` locale will use `translations-en.po`
-* a user with `fr-FR` locale will use `translations-fr-FR.po`
-* a user with `fr-CA` locale will use `translations.po`
-
-The basename for translation files is always `translations`; this cannot be altered.
-
-
-=== Externalized translation files
-
-Normally Apache Isis configuration files are read from the `WEB-INF` file. However, Apache Isis can be configured to read config files from an xref:ugbtb.adoc#_ugbtb_deployment_externalized-configuration[external directory]; this is also supported for translations.
-
-Thus, if in `web.xml` the external configuration directory has been set:
-
-[source,xml]
-----
-<context-param>
- <param-name>isis.config.dir</param-name>
- <param-value>location of external config directory</param-value>
-</context-param>
-----
-
-Then this directory will be used as the base for searching for translations (rather than the default 'WEB-INF/' directory).
-
-=== Force read mode
-
-As noted above, if running in prototype mode then `TranslationServicePo` will be in write mode, if in production mode then will be in read mode. To force read mode (ie use translations) even if in prototype mode, add the following configuration property to `isis.properties`:
-
-[source,ini]
-----
-isis.services.translation.po.mode=read
-----
-
-== Supporting services
-
-The `TranslationServicePo` has a number of supporting/related services.
-
-=== `LocaleProvider`
-
-The `LocaleProvider` API is used by the `TranslationServicePo` implementation to obtain the locale of the "current user".
-
-A default implementation is provided by the Wicket viewer.
-
-[NOTE]
-====
-Note that this default implementation does not support requests made through the Restful Objects viewer (there is no Wicket 'application' object available); the upshot is that requests through Restful Objects are never translated. Registering a different implementation of `LocaleProvider` that taps into appropriate REST (RestEasy?) APIs would be the way to address this.
-====
-
-
-=== `TranslationsResolver`
-
-The `TranslationResolver` is used by the `TranslationService` implementation to lookup translations for a specified locale. It is this service that reads from the `WEB-INF/` (or externalized directory).
-
-
-=== `TranslationServicePoMenu`
-
-The `TranslationServicePoMenu` provides a couple of menu actions in the UI (prototype mode only) that interacts with the underlying `TranslationServicePo`:
-
-* the `downloadTranslationsFile()` action - available only in write mode - allows the current `.pot` file to be downloaded. +
-+
-[NOTE]
-====
-While this will contain all the translations from the metamodel, it will not necessarily contain all translations for all imperative methods returning `TranslatableString` instances; which are present and which are missing will depend on which imperative methods have been called (recorded by the service) prior to downloading.
-====
-
-* the `clearTranslationsCache()` action - available only in read mode - will clear the cache so that new translations can be loaded. +
-+
-This allows a translator to edit the appropriate `translations-xx-XX.po` file and check the translation is correct without having to restart the app.
-
-
-
-
http://git-wip-us.apache.org/repos/asf/isis/blob/29452af6/adocs/documentation/src/main/asciidoc/guides/_ugbtb_more-advanced_mapping-rdbms-views.adoc
----------------------------------------------------------------------
diff --git a/adocs/documentation/src/main/asciidoc/guides/_ugbtb_more-advanced_mapping-rdbms-views.adoc b/adocs/documentation/src/main/asciidoc/guides/_ugbtb_more-advanced_mapping-rdbms-views.adoc
deleted file mode 100644
index e4f9049..0000000
--- a/adocs/documentation/src/main/asciidoc/guides/_ugbtb_more-advanced_mapping-rdbms-views.adoc
+++ /dev/null
@@ -1,9 +0,0 @@
-[[_ugbtb_more-advanced_mapping-rdbms-views]]
-= Mapping RDBMS Views
-: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: TODO - as used in link:http://github.com/estatio/estatio[Estatio]
-
http://git-wip-us.apache.org/repos/asf/isis/blob/29452af6/adocs/documentation/src/main/asciidoc/guides/_ugbtb_more-advanced_multi-tenancy.adoc
----------------------------------------------------------------------
diff --git a/adocs/documentation/src/main/asciidoc/guides/_ugbtb_more-advanced_multi-tenancy.adoc b/adocs/documentation/src/main/asciidoc/guides/_ugbtb_more-advanced_multi-tenancy.adoc
deleted file mode 100644
index 945b157..0000000
--- a/adocs/documentation/src/main/asciidoc/guides/_ugbtb_more-advanced_multi-tenancy.adoc
+++ /dev/null
@@ -1,8 +0,0 @@
-[[_ugbtb_more-advanced_multi-tenancy]]
-= Multi-tenancy
-: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: TODO - as supported by (non-ASF) http://github.com/isisaddons/isis-module-security[Isis addons' security] module.
-
http://git-wip-us.apache.org/repos/asf/isis/blob/29452af6/adocs/documentation/src/main/asciidoc/guides/_ugbtb_more-advanced_overriding-jdo-annotations.adoc
----------------------------------------------------------------------
diff --git a/adocs/documentation/src/main/asciidoc/guides/_ugbtb_more-advanced_overriding-jdo-annotations.adoc b/adocs/documentation/src/main/asciidoc/guides/_ugbtb_more-advanced_overriding-jdo-annotations.adoc
deleted file mode 100644
index 5601c75..0000000
--- a/adocs/documentation/src/main/asciidoc/guides/_ugbtb_more-advanced_overriding-jdo-annotations.adoc
+++ /dev/null
@@ -1,64 +0,0 @@
-[[_ugbtb_more-advanced_overriding-jdo-annotations]]
-= Overriding JDO Annotations
-: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 JDO Objectstore (or rather, the underlying DataNucleus implementation) builds its own persistence metamodel by reading both annotations on the class and also by searching for metadata in XML files. The metadata in the XML files takes precedence over the annotations, and so can be used to override metadata that is "hard-coded" in annotations.
-
-For example, as of 1.9.0 the various http://www.isisaddons.org[Isis addons] modules (not ASF) use schemas for each entity. For example, the `AuditEntry` entity in the http://github.com/isisaddons/isis-module-audit[audit module] is annotated as:
-
-[source,java]
-----
-@javax.jdo.annotations.PersistenceCapable(
- identityType=IdentityType.DATASTORE,
- schema = "IsisAddonsAudit",
- table="AuditEntry")
-public class AuditEntry {
- ...
-}
-----
-
-This will map the `AuditEntry` class to a table `"IsisAddonsAudit"."AuditEntry"`; that is using a custom schema to own the object.
-
-Suppose though that for whatever reason we didn't want to use a custom schema but would rather use the default. We can override the above annotation using a `package.jdo` file, for example:
-
-[source,xml]
-----
-<?xml version="1.0" encoding="UTF-8" ?>
-<jdo xmlns="http://xmlns.jcp.org/xml/ns/jdo/jdo"
- xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
- xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/jdo/jdo
- http://xmlns.jcp.org/xml/ns/jdo/jdo_3_0.xsd" version="3.0">
- <package name="org.isisaddons.module.audit.dom">
- <class name="AuditEntry" schema="PUBLIC" table="IsisAddonsAuditEntry">
- </class>
- </package>
-</jdo>
-----
-
-This file should be placed can be placed in `src/main/java/META-INF` within your application's `dom` module.
-
-[TIP]
-====
-(As of `1.11.0-SNAPSHOT`) you can use a mixin action on xref:rgcms.adoc#_rgcms_classes_mixins_Persistable[`Persistable`] mixin
-to download the JDO class metadata in XML form.
-====
-
-
-[NOTE]
-====
-* The same approach should work for any other JDO metadata, but some experimentation might be required.+
-+
-For example, in writing up the above example we found that writing `schema=""` (in an attempt to say, "use the default schema for this table") actually caused the original annotation value to be used instead.
-
-* Forcing the schema to "PUBLIC" (as in the above example) works, but it isn't ideal because the name "PUBLIC" is not vendor-neutral (it works for HSQLDB, but MS SQL Server uses "dbo" as its default).
-
-* As of 1.9.0 Apache Isis will automatically (attempt) to create the owning schema for a given table if it does not exist. This behaviour can be customized, as described in the section on xref:_ugbtb_more-advanced_decoupling_db-schemas[using modules].
-
-* You may need to override the entire class metadata rather than individual elements; the mixin (`1.11.0-SNAPSHOT`) mentioned above can help here.
-====
-
-
http://git-wip-us.apache.org/repos/asf/isis/blob/29452af6/adocs/documentation/src/main/asciidoc/guides/_ugbtb_more-advanced_persisted-title.adoc
----------------------------------------------------------------------
diff --git a/adocs/documentation/src/main/asciidoc/guides/_ugbtb_more-advanced_persisted-title.adoc b/adocs/documentation/src/main/asciidoc/guides/_ugbtb_more-advanced_persisted-title.adoc
deleted file mode 100644
index 59d3cb4..0000000
--- a/adocs/documentation/src/main/asciidoc/guides/_ugbtb_more-advanced_persisted-title.adoc
+++ /dev/null
@@ -1,82 +0,0 @@
-[[_ugbtb_more-advanced_persisted-title]]
-= Persisted Title
-: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/
-
-
-
-Normally the title of an object is not persisted to the database, rather it is recomputed automatically from underlying properties. On occasion though you might want the title to also be persisted; either to make things easier for the DBA, or for an integration scenario, or some other purpose.
-
-We can implement this feature by leveraging the xref:rgcms.adoc#_rgcms_methods_lifecycle_jdo-api[JDO lifecycle]. In the design we discuss here we make it a responsibility of the entities to persist the title as a property, by implementing a `ObjectWithPersistedTitle` interface:
-
-[source,java]
-----
-public interface ObjectWithPersistedTitle {
- @PropertyLayout(hidden = Where.EVERYWHERE) // <1>
- String getTitle();
- void setTitle(final String title);
-}
-----
-<1> we don't want to expose this in the UI because the title is already prominently displayed.
-
-We can then define a subscribing domain service that leverage this.
-
-[source,java]
-----
-@DomainService(nature = NatureOfService.DOMAIN)
-public class TitlingService extends AbstractSubscriber {
- @Subscribe
- public void on(final ObjectPersistingEvent ev) {
- handle(ev.getSource());
- }
- @Subscribe
- public void on(final ObjectUpdatingEvent ev) {
- handle(ev.getSource());
- }
- private void handle(final Object persistentInstance) {
- if(persistentInstance instanceof ObjectWithPersistedTitle) {
- final ObjectWithPersistedTitle objectWithPersistedTitle =
- (ObjectWithPersistedTitle) persistentInstance;
- objectWithPersistedTitle.setTitle(container.titleOf(objectWithPersistedTitle));
- }
- }
- @Inject
- private DomainObjectContainer container;
-}
-----
-
-Prior to 1.10.0 (when lifecycle events were introduced), this could also be be done by accessing the JDO API directly:
-
-[source,java]
-----
-@RequestScoped
-@DomainService(nature = NatureOfService.DOMAIN)
-public class TitlingService {
- @PostConstruct
- public void init() {
- isisJdoSupport.getJdoPersistenceManager().addInstanceLifecycleListener(
- new StoreLifecycleListener() {
- @Override
- public void preStore(final InstanceLifecycleEvent event) {
- final Object persistentInstance = event.getPersistentInstance();
- if(persistentInstance instanceof ObjectWithPersistedTitle) {
- final ObjectWithPersistedTitle objectWithPersistedTitle =
- (ObjectWithPersistedTitle) persistentInstance;
- objectWithPersistedTitle.setTitle(container.titleOf(objectWithPersistedTitle));
- }
- }
- @Override
- public void postStore(final InstanceLifecycleEvent event) {
- }
- }, null);
- }
- @Inject
- private IsisJdoSupport isisJdoSupport;
- @Inject
- private DomainObjectContainer container;
-}
-----
-
-The above is probably the easiest and most straightforward design. One could imagine other designs where the persisted title is stored elsewhere. It could even be stored off into an link:http://lucene.apache.org/[Apache Lucene] (or similar) database to allow for free-text searches.
-
http://git-wip-us.apache.org/repos/asf/isis/blob/29452af6/adocs/documentation/src/main/asciidoc/guides/_ugbtb_more-advanced_replacing-default-service-implementations.adoc
----------------------------------------------------------------------
diff --git a/adocs/documentation/src/main/asciidoc/guides/_ugbtb_more-advanced_replacing-default-service-implementations.adoc b/adocs/documentation/src/main/asciidoc/guides/_ugbtb_more-advanced_replacing-default-service-implementations.adoc
deleted file mode 100644
index 5ba01a7..0000000
--- a/adocs/documentation/src/main/asciidoc/guides/_ugbtb_more-advanced_replacing-default-service-implementations.adoc
+++ /dev/null
@@ -1,64 +0,0 @@
-[[_ugbtb_more-advanced_replacing-default-service-implementations]]
-= Replacing Service Implns
-: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 framework provides default implementations for many of the xref:rgsvc.adoc#_rgsvc_api[API Services]. This is convenient, but sometimes you will want to replace the default implementation with your own service implementation.
-
-The trick is to use the xref:rgant.adoc#_rgant-DomainServiceLayout_menuOrder[`@DomainServiceLayout#menuOrder()`] attribute, specifying a low number (typically `"1"`).
-
-For example, suppose you wanted to provide your own implementation of xref:rgsvc.adoc#_rgsvc_api_LocaleProvider[`LocaleProvider`]. Here's how:
-
-[source,java]
-----
-@DomainService(
- nature = NatureOfService.DOMAIN
-)
-@DomainServiceLayout(
- menuOrder = "1" // <1>
-)
-public class MyLocaleProvider implements LocaleProvider {
- @Override
- public Locale getLocale() {
- return ...
- }
-}
-----
-<1> takes precedence over the default implementation.
-
-
-It's also quite common to want to decorate the existing implementation (ie have your own implementation delegate to the default); this is also possible and quite easy if using `1.10.0` or later:
-
-[source,java]
-----
-@DomainService(
- nature = NatureOfService.DOMAIN
-)
-@DomainServiceLayout(
- menuOrder = "1" // <1>
-)
-public class MyLocaleProvider implements LocaleProvider {
- @Override
- public Locale getLocale() {
- return getDelegateLocaleProvider().getLocale(); // <2>
- }
- Optional<LocaleProvider> delegateLocaleProvider; // <3>
- private LocaleProvider getDelegateLocaleProvider() {
- if(delegateLocaleProvider == null) {
- delegateLocaleProvider = Iterables.tryFind(localeProviders, input -> input != this); // <4>
- }
- return delegateLocaleProvider.orNull();
- }
- @Inject
- List<LocaleProvider> localeProviders; // <5>
-}
-----
-<1> takes precedence over the default implementation when injected elsewhere.
-<2> this implementation merely delegates to the default implementation
-<3> lazily populated
-<4> delegate to the first implementation that isn't _this_ implementation (else infinite loop!)
-<5> Injects all implementations, including this implemenation
-
http://git-wip-us.apache.org/repos/asf/isis/blob/29452af6/adocs/documentation/src/main/asciidoc/guides/_ugbtb_more-advanced_transactions-and-errors.adoc
----------------------------------------------------------------------
diff --git a/adocs/documentation/src/main/asciidoc/guides/_ugbtb_more-advanced_transactions-and-errors.adoc b/adocs/documentation/src/main/asciidoc/guides/_ugbtb_more-advanced_transactions-and-errors.adoc
deleted file mode 100644
index a3fe75c..0000000
--- a/adocs/documentation/src/main/asciidoc/guides/_ugbtb_more-advanced_transactions-and-errors.adoc
+++ /dev/null
@@ -1,33 +0,0 @@
-[[_ugbtb_more-advanced_transactions-and-errors]]
-= Transactions and Errors
-: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, every action invocation (in fact, every interaction) is automatically wrapped in a transaction, and any repository query automatically does a flush.
-
-What that means is that there's no need to explicitly start or commit transactions in Apache Isis; this will be done for you. Indeed, if you do try to manage transactions (eg by reaching into the JDO `PersistenceManager` exposed by the xref:rgsvc.adoc#_rgsvc_api_IsisJdoSupport[IsisJdoSupport] domain service, then you are likely to confuse Isis and get a stack trace for your trouble.
-
-
-
-
-== Aborting Transactions
-
-If you want to abort Apache Isis' transaction, this can be done by throwing `RecoverableException` (or any subclass, eg `ApplicationException`). The transaction will be aborted, and the exception message will be displayed to the user.
-
-If you throw any other exception (ie not a subclass of `RecoverableException`), then the users will see an error page (if Wicket viewer) or a 500 (if Restful Objects viewer).
-
-
-
-
-
-== Raise message/errors to users
-
-NOTE: TODO - xref:rgsvc.adoc#_rgsvc_api_DomainObjectContainer_messages-api[`DomainObjectContainer`]
-
-
-
-== Exception Recognizers
-
-NOTE: TODO - xref:rgsvc.adoc#_rgsvc_spi_ExceptionRecognizer[`ExceptionRecognizer`] service
-
http://git-wip-us.apache.org/repos/asf/isis/blob/29452af6/adocs/documentation/src/main/asciidoc/guides/_ugbtb_more-advanced_view-models.adoc
----------------------------------------------------------------------
diff --git a/adocs/documentation/src/main/asciidoc/guides/_ugbtb_more-advanced_view-models.adoc b/adocs/documentation/src/main/asciidoc/guides/_ugbtb_more-advanced_view-models.adoc
deleted file mode 100644
index ad2c5cd..0000000
--- a/adocs/documentation/src/main/asciidoc/guides/_ugbtb_more-advanced_view-models.adoc
+++ /dev/null
@@ -1,19 +0,0 @@
-[[_ugbtb_more-advanced_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 a type of domain object (with state, behaviour etc) but where the state is _not_ persisted into the
- JDO/DataNucleus-managed database, but is instead converted to/from a string memento, and held by the calling client.
-This opens up a number of more advanced use cases.
-
-In this topic we'll explore those use cases, and learn the programming model and conventions to use view models in your application.
-
-
-include::_ugbtb_more-advanced_view-models_use-cases.adoc[leveloffset=+1]
-include::_ugbtb_more-advanced_view-models_programming-model.adoc[leveloffset=+1]
-include::_ugbtb_more-advanced_view-models_jaxb.adoc[leveloffset=+1]
-
-
http://git-wip-us.apache.org/repos/asf/isis/blob/29452af6/adocs/documentation/src/main/asciidoc/guides/_ugbtb_more-advanced_view-models_jaxb.adoc
----------------------------------------------------------------------
diff --git a/adocs/documentation/src/main/asciidoc/guides/_ugbtb_more-advanced_view-models_jaxb.adoc b/adocs/documentation/src/main/asciidoc/guides/_ugbtb_more-advanced_view-models_jaxb.adoc
deleted file mode 100644
index 51eef39..0000000
--- a/adocs/documentation/src/main/asciidoc/guides/_ugbtb_more-advanced_view-models_jaxb.adoc
+++ /dev/null
@@ -1,240 +0,0 @@
-[[_ugbtb_more-advanced_view-models_jaxb]]
-= JAXB-annotated DTOs (`1.11.0-SNAPSHOT`)
-: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 provides some recommended practices if using JAXB and `@XmlRootElement` to define domain models. The
-examples are taken from the (non-ASF) http://github.com/isisaddons/isis-app-todoapp[Isis addons' todoapp].
-
-
-
-[[_ugbtb_more-advanced_view-models_jaxb_using-packages-to-version]]
-== Use packages to version DTOs
-
-The whole point of using DTOs (in Apache Isis, at least) is to define a formal contact between two interoperating but
-independent applications. Since the only thing we can predicate about the future with any certainty is that it one or
-both of these applications will change, we should version DTOs from the get-go.
-
-With XML every element may be defined as belonging to a particular namespace; in JAXB this translates to Java packages.
-We therefore should place each DTO within its own package, and that package should include a version identifier.
-
-For example, the http://github.com/isisaddons/isis-app-todoapp[Isis addons' todoapp] defines this DTO (as a versioned
-representation of its underlying `ToDoItem` entity):
-
-[source,java]
-----
-@XmlRootElement(name = "toDoItemDto") // <1>
-@XmlType(
- propOrder = { // <2>
- "description",
- "category",
- "subcategory",
- "cost"
- }
-)
-@DomainObjectLayout(
- titleUiEvent = TitleUiEvent.Doop.class // <3>
-)
-public class ToDoItemDto implements Dto {
- @XmlElement(required = true)
- @Getter @Setter // <4>
- protected String description;
-
- @XmlElement(required = true)
- @Getter @Setter
- protected String category;
-
- @Getter @Setter
- protected String subcategory;
-
- @Getter @Setter
- protected BigDecimal cost;
-}
-----
-<1> identifies this class as a view model and defines the root element for JAXB serialization
-<2> all properties in the class must be listed; (they can be ignored using `@XmlTransient`)
-<3> demonstrating use of UI events for a subscriber to provide the DTO's title; see xref:rgant.adoc#_rgant-DomainObjectLayout_titleUiEvent[`@DomainObjectLayout#titleUiEvent()`].
-<4> optional; JAXB metadata can specify such attributes as required/optional
-
-
-For the package in which the DTO class resides, we define a corresponding namespace. This goes in `package-info.java`:
-
-[source,java]
-----
-@javax.xml.bind.annotation.XmlSchema(
- namespace = "http://viewmodels.app.todoapp/todoitem/v1_0/todoitem.xsd", // <1>
- elementFormDefault = javax.xml.bind.annotation.XmlNsForm.QUALIFIED
-)
-package todoapp.app.viewmodels.todoitem.v1_0; // <2>
-----
-<1> the namespace URI, used by the DTO residing in this package. There is no requirement for this to correspond to a physical URL, but it should be unique (this
-usually implies the usage of a company domain name).
-<2> the package in which the DTO resides.
-
-Note how both the XML namespace and package are broadly equivalent to each other; in particular note that they both
-also include a version "v1_0".
-
-
-
-
-[[_ugbtb_more-advanced_view-models_jaxb_semantic-versioning]]
-== Semantic Versioning
-
-Versioning DTOs enables us to make changes without breaking existing consumers of the data. We can distinguish two
-types of changes:
-
-* backwardly compatible changes
-* breaking changes.
-
-Following link:http://semver.org[semantic versioning] approach, we suggest using `v1_0`, `v1_1`, `v1_2` etc as the
-package version for a sequence of backwardly compatible changes, then bump up to `v2_0` for a breaking change.
-
-Backwardly compatible changes can generally (always?) be modelled using class inheritance. Thus, `v1_1.ToDoItemDto`
-is a subclass of `v1_0.ToDoItemDto`. This makes sense too: OO inheritance means "is-substitutable-for", so what is
-true in an OO context is true when processing XML documents.
-
-On the other hand, breaking changes probably (always?) imply that the next version of the DTO does not use inheritance.
-Thus `v2_0.ToDoItemDto` might share many of the same properties as the `v1_1.ToDoItemDto`, but any reuse would be
-copy-n-paste rather than through inheritance.
-
-To see this in practice, here's (the outline of) v1.1 of `ToDoItemDto`:
-
-[source,java]
-----
-package todoapp.app.viewmodels.todoitem.v1_1;
-...
-@XmlRootElement(name = "toDoItemDto")
-@XmlType(
- propOrder = {
- "toDoItem",
- "similarItems"
- }
-)
-public class ToDoItemDto extends todoapp.app.viewmodels.todoitem.v1_0.ToDoItemDto {
- ...
-}
-----
-
-
-The corresponding `package-info.java` is similar to that for `v1_0`, though note how it also defines a namespace prefix
-for `v1_0`:
-
-[source,java]
-----
-@javax.xml.bind.annotation.XmlSchema(
- namespace = "http://viewmodels.app.todoapp/todoitem/v1_1/todoitem.xsd", <!--1-->
- xmlns = {
- @javax.xml.bind.annotation.XmlNs( <!--2-->
- namespaceURI = "http://isis.apache.org/schema/common",
- prefix = "common"
- ),
- @javax.xml.bind.annotation.XmlNs(
- namespaceURI = "http://viewmodels.app.todoapp/todoitem/v1_0/todoitem.xsd",
- prefix = "todoitem-v1_0"
- )
- },
- elementFormDefault = javax.xml.bind.annotation.XmlNsForm.QUALIFIED
-)
-package todoapp.app.viewmodels.todoitem.v1_1;
-----
-<1> namespace URI for DTO in this class.
-<2> aliases for any other namespaces referenced.
-
-
-
-[[_ugbtb_more-advanced_view-models_jaxb_referencing-domain-entities]]
-== Referencing Domain Entities
-
-It's quite common for view models to be "backed by" (be projections of) some underlying domain entity. The
-`ToDoItemDto` we've been using as the example in this section is an example: there is an underlying `ToDoItem` entity.
-
-It wouldn't make sense to serialize out the state of a persistent entity: the point of a DTO is to act as a facade
-on top of the entity so that the implementation details (of the entity's structure) don't leak out to the consumer.
-However, the identity of the underlying entity can be well defined; Apache Isis defines the
-xref:rgcms.adoc#_rgcms_schema-common[Common schema] which defines the `<oid-dto>` element (and corresponding `OidDto` class):
-the object's type and its identifier. This is basically a formal XML equivalent to the `Bookmark` object obtained
-from the xref:rgsvc.adoc#_rgsvc_api_BookmarkService[`BookmarkService`].
-
-There is only one requirement to make this work: every referenced domain entity must be annotated with
-xref:rgant.adoc#_rgant-XmlJavaTypeAdapter[`@XmlJavaTypeAdapter`], specifying the framework-provided
-`PersistentEntityAdapter.class`. This class is similar to the `BookmarkService`: it knows how to create an `OidDto`
-from an object reference.
-
-Thus, in our view model we can legitimately write:
-
-[source,java]
-----
-package todoapp.app.viewmodels.todoitem.v1_1;
-...
-public class ToDoItemDto extends todoapp.app.viewmodels.todoitem.v1_0.ToDoItemDto {
- ...
- @Getter @Setter
- protected ToDoItem toDoItem;
-}
-----
-
-All we need to do is remember to add that `@XmlJavaTypeAdapter` annotation to the referenced entity:
-
-[source,java]
-----
-@XmlJavaTypeAdapter(PersistentEntityAdapter.class)
-public class ToDoItem ... {
- ...
-}
-----
-
-
-
-[[_ugbtb_more-advanced_view-models_jaxb_collections]]
-== Collections
-
-It's also possible for a DTO to hold collections of objects. These can be of any type, either simple properties, or
-references to other objects.
-
-The only bit of boilerplate that is required is the `@XmlElementWrapper` annotation. This instructs JAXB to create
-an XML element (based on the field name) to contain each of the elements. (If this is omitted then the contents of
-the collection are at the same level as the properties; almost certainly not what is required).
-
-For example, the v1.1 of the `ToDoItemDto` could also contain:
-
-[source,java]
-----
-package todoapp.app.viewmodels.todoitem.v1_1;
-...
-public class ToDoItemDto extends todoapp.app.viewmodels.todoitem.v1_0.ToDoItemDto {
- ...
- @XmlElementWrapper
- @XmlElement(name = "todoItem")
- @Getter @Setter
- protected List<ToDoItem> similarItems = Lists.newArrayList();
-}
-----
-
-
-There's nothing to prevent a JAXB DTO from containing rich graphs of data, parent containing children containing
-children. Be aware though that all of this state will become the DTO's memento, ultimately converted into a URL-safe
-form, by way of the xref:rgsvc.adoc#_rgsvc_spi_UrlEncodingService[`UrlEncodingService`].
-
-There are limits to the lengths of URLs, however. Therefore the DTO should not include state that can easily be
-derived from other information. If the URL does exceed limits, then provide a custom implementation of `UrlEncodingService`
-to handle the memento string in some other fashion (eg substituting it with a GUID, with the memento cached somehow
-on the server).
-
-
-
-
-
-== Generating XSDs and DTOs
-
-The xref:cg.adoc#_cg_isis-maven-plugin[Apache Isis maven plugin] provides the xref:cg.adoc#_cg_isis-maven-plugin_xsd[xsd] goal that allows the XSDs to be generated from any JAXB-annotated view models.
-These use the xref:rgsvc.adoc#_rgsvc_api_JaxbService[`JaxbService`] to generate the schemas; using the
-standard `schemagen` command line will not correctly interpret any references to domain entities as OIDs.
-
-The documentation for the `xsd` goal also explains how to generate DTO classes from the generated XSDs. Note that these
-DTOs are not the same as the JAXB view models; they can be used outside of an Isis application, for example in a
-standalone subscriber running on an enterprise service bus such as Apache Camel.
-
http://git-wip-us.apache.org/repos/asf/isis/blob/29452af6/adocs/documentation/src/main/asciidoc/guides/_ugbtb_more-advanced_view-models_programming-model.adoc
----------------------------------------------------------------------
diff --git a/adocs/documentation/src/main/asciidoc/guides/_ugbtb_more-advanced_view-models_programming-model.adoc b/adocs/documentation/src/main/asciidoc/guides/_ugbtb_more-advanced_view-models_programming-model.adoc
deleted file mode 100644
index 29cafd8..0000000
--- a/adocs/documentation/src/main/asciidoc/guides/_ugbtb_more-advanced_view-models_programming-model.adoc
+++ /dev/null
@@ -1,87 +0,0 @@
-[[_ugbtb_more-advanced_view-models_programming-model]]
-= Programming Model
-: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/
-
-
-
-So much for the theory; how should view models be implemented? Fundamentally all view models' state is serialized into
-a string memento; this memento is then held by the client (browser) in the form of a URL. As you might imagine, this
-URL can become quite long, but Apache Isis offers a mechanism (the xref:rgsvc.adoc#_rgsvc_spi_UrlEncodingService[`UrlEncodingService`]) if it exceeds the maximum length for a URL
-(2083 characters). Also, of course, this string memento must only contain characters that it is valid for use within
-a URL.
-
-While the underlying technique is the same irrespective of use case, the programming model provides various ways of
-defining a view model so that the original intent is not lost. They are:
-
-.View model programming model
-[cols="1a,4a,2a", options="header"]
-|===
-
-| Use case
-| Code
-| Description
-
-
-| External entity
-|[source,java]
-----
-@DomainObject(nature=Nature.EXTERNAL_ENTITY)
-public class CustomerRecordOnSAP { ... }
-----
-|Annotated with xref:rgant.adoc#_rgant-DomainObject_nature[`@DomainObject#nature()`] and a nature of `EXTERNAL_ENTITY`, with memento derived automatically from the properties of the domain object. Collections are ignored, as are any properties annotated as xref:rgant.adoc#_rgant-Property_notPersisted[not persisted].
-
-| In-memory entity
-|[source,java]
-----
-@DomainObject(nature=Nature.INMEMORY_ENTITY)
-public class Log4JAppender { ... }
-----
-|As preceding, but using a nature of `INMEMORY_ENTITY`.
-
-|Application view model
-|[source,java]
-----
-@DomainObject(nature=Nature.VIEW_MODEL)
-public class Dashboard { ... }
-----
-|As preceding, but using a nature of `VIEW_MODEL`.
-
-|Application view model
-|
-[source,java]
-----
-@ViewModel
-public class Dashboard { ... }
-----
-
-|Annotated with xref:rgant.adoc#_rgant-ViewModel[`@ViewModel`] annotation (effectively just an alias)' memento is as preceding: from "persisted" properties, collections ignored
-
-|Application view model
-|
-[source,java]
-----
-public class ExcelUploadManager implements ViewModel {
- public String viewModelMemento() { ... }
- public void viewModelInit(String memento) { ... }
-}
-|Implement xref:rgcms.adoc#_rgcms_classes_super_ViewModel[`ViewModel`] interface. The memento is as defined by the
-interface's methods: the programmer has full control (but also full responsibility) for the string memento.
-
-|DTO (`1.11.0-SNAPSHOT`)
-|
-[source,java]
-----
-@XmlRootElement("customer")
-public class CustomerDto { ... }
-----
-|Annotate using JAXB xref:rgant.adoc#_rgant-XmlRootElement[`@XmlRootElement`] annotation. Memento
-derived automatically by serializing the XML graph as implied by the JAXB annotations. Note that (unlike `@ViewModel`
-et al) this state _can_ include collections.
-|===
-
-JAXB-annotated DTOs are discussed in more detail immediately xref:rg.adoc#_ugbtb_more-advanced_view-models_jaxb[below].
-
-
-
http://git-wip-us.apache.org/repos/asf/isis/blob/29452af6/adocs/documentation/src/main/asciidoc/guides/_ugbtb_more-advanced_view-models_use-cases.adoc
----------------------------------------------------------------------
diff --git a/adocs/documentation/src/main/asciidoc/guides/_ugbtb_more-advanced_view-models_use-cases.adoc b/adocs/documentation/src/main/asciidoc/guides/_ugbtb_more-advanced_view-models_use-cases.adoc
deleted file mode 100644
index 3a10b53..0000000
--- a/adocs/documentation/src/main/asciidoc/guides/_ugbtb_more-advanced_view-models_use-cases.adoc
+++ /dev/null
@@ -1,142 +0,0 @@
-[[_ugbtb_more-advanced_view-models_use-cases]]
-= Use Cases
-:Notice: Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements. See the NOTICE file distributed with this work for additional information regarding copyright ownership. The ASF licenses this file to you under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at. http://www.apache.org/licenses/LICENSE-2.0 . Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.
-:_basedir: ../
-:_imagesdir: images/
-
-
-When developing an Apache Isis application you will most likely start off with the persistent domain entities:
-`Customer`, `Order`, `Product`, and so on. For some applications this may well suffice. However, if the application
-needs to integrate with other systems, or if the application needs to support reasonably complex business processes, then you may need to look beyond just domain entities. This section explores these use cases.
-
-== 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).
-====
-
-
-== 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.
-
-
-== 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.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).
-****
-
-== DTOs (`1.11.0-SNAPSHOT`)
-
-DTOs (data transfer objects) are simple classes that (according to link:https://en.wikipedia.org/wiki/Data_transfer_object[wikipedia]) "carries 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.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.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.
-
-Instead, a view model can be defined to act as a DTO. To put this formal contract onto a solid footing, this view
-model can (as of `1.11.0-SNAPSHOT`) simply be defined as a JAXB-annotated entity; this allows the consumer to obtain
-the DTO in XML format along with a corresponding XSD schema describing the structure of that XML. These XML
-representations can be surfaced by the xref:ugvro.adoc#[RestfulObjects viewer] (by implementing
-the xref:rgsvc.adoc#_rgsvc_spi_ContentMappingService[`ContentMappingService`]); the XSD can be obtained
-using the xref:rgsvc.adoc#_rgsvc_api_JaxbService[`JaxbService`]. Using the formalism of XML also allows
-DTOs to be carefully and properly versioned using XML namespaces.
-
-[TIP]
-====
-If the view model DTO implements the xref:rgcms.adoc#_rgcms_classes_mixins_Dto[`Dto`] marker interface, then the framework
-will also provide the ability to download the XML or its XSD directly from the UI.
-====
-
-In case it's not clear, these DTOs are still usable as "regular" view models; they will render in the xref:ugvw.adoc#[Wicket viewer] just like any other. Indeed (as the xref:ugbtb.adoc#_ugbtb_more-advanced_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 view model alternatives.
-
-
-== ESB Subscribers
-
-One important variation of the DTO use case concerns subscribers on an enterprise event bus such as
-link:http://camel.apache.org[Apache Camel(TM)] and similar.
-
-A xref:rgsvc.adoc#_rgsvc_spi_PublishingService[`PublishingService`] implementation (eg that provided by
-(non-ASF) http://github.com/isisaddons/isis-module-publishmq[Isis addons' publishmq] module) can publish XML events
-onto a message queue, typically representing action invocations within the originating Isis application. The ESB
-(Apache Camel) then dispatches this event to all interested subscribers. These subscribers represent external systems
-in the enterprise, managed by other teams, and so act as the third-party consumers of the data.
-
-Rather than try to anticipate their requirements and push the data that these subscribers might need into the original
-XML event (a hopeless task), DTO objects can be defined to allow these consumers to call back to the publishing Isis
-application to obtain the data they need.
-
-
http://git-wip-us.apache.org/repos/asf/isis/blob/29452af6/adocs/documentation/src/main/asciidoc/guides/_ugbtb_other-techniques.adoc
----------------------------------------------------------------------
diff --git a/adocs/documentation/src/main/asciidoc/guides/_ugbtb_other-techniques.adoc b/adocs/documentation/src/main/asciidoc/guides/_ugbtb_other-techniques.adoc
new file mode 100644
index 0000000..d03bf12
--- /dev/null
+++ b/adocs/documentation/src/main/asciidoc/guides/_ugbtb_other-techniques.adoc
@@ -0,0 +1,22 @@
+[[_ugbtb_other-techniques]]
+= Other Techniques
+: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 pulls together a number of more advanced techniques that we've discovered and developed while building our own Isis applications.
+
+
+include::_ugbtb_other-techniques_overriding-jdo-annotations.adoc[leveloffset=+1]
+include::_ugbtb_other-techniques_mapping-rdbms-views.adoc[leveloffset=+1]
+include::_ugbtb_other-techniques_transactions-and-errors.adoc[leveloffset=+1]
+include::_ugbtb_other-techniques_multi-tenancy.adoc[leveloffset=+1]
+include::_ugbtb_other-techniques_persisted-title.adoc[leveloffset=+1]
+include::_ugbtb_other-techniques_replacing-default-service-implementations.adoc[leveloffset=+1]
+
+
+
+
+
http://git-wip-us.apache.org/repos/asf/isis/blob/29452af6/adocs/documentation/src/main/asciidoc/guides/_ugbtb_other-techniques_mapping-rdbms-views.adoc
----------------------------------------------------------------------
diff --git a/adocs/documentation/src/main/asciidoc/guides/_ugbtb_other-techniques_mapping-rdbms-views.adoc b/adocs/documentation/src/main/asciidoc/guides/_ugbtb_other-techniques_mapping-rdbms-views.adoc
new file mode 100644
index 0000000..7bc2d12
--- /dev/null
+++ b/adocs/documentation/src/main/asciidoc/guides/_ugbtb_other-techniques_mapping-rdbms-views.adoc
@@ -0,0 +1,9 @@
+[[_ugbtb_other-techniques_mapping-rdbms-views]]
+= Mapping RDBMS Views
+: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: TODO - as used in link:http://github.com/estatio/estatio[Estatio]
+
http://git-wip-us.apache.org/repos/asf/isis/blob/29452af6/adocs/documentation/src/main/asciidoc/guides/_ugbtb_other-techniques_multi-tenancy.adoc
----------------------------------------------------------------------
diff --git a/adocs/documentation/src/main/asciidoc/guides/_ugbtb_other-techniques_multi-tenancy.adoc b/adocs/documentation/src/main/asciidoc/guides/_ugbtb_other-techniques_multi-tenancy.adoc
new file mode 100644
index 0000000..6bc2936
--- /dev/null
+++ b/adocs/documentation/src/main/asciidoc/guides/_ugbtb_other-techniques_multi-tenancy.adoc
@@ -0,0 +1,8 @@
+[[_ugbtb_other-techniques_multi-tenancy]]
+= Multi-tenancy
+: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: TODO - as supported by (non-ASF) http://github.com/isisaddons/isis-module-security[Isis addons' security] module.
+
http://git-wip-us.apache.org/repos/asf/isis/blob/29452af6/adocs/documentation/src/main/asciidoc/guides/_ugbtb_other-techniques_overriding-jdo-annotations.adoc
----------------------------------------------------------------------
diff --git a/adocs/documentation/src/main/asciidoc/guides/_ugbtb_other-techniques_overriding-jdo-annotations.adoc b/adocs/documentation/src/main/asciidoc/guides/_ugbtb_other-techniques_overriding-jdo-annotations.adoc
new file mode 100644
index 0000000..ffada22
--- /dev/null
+++ b/adocs/documentation/src/main/asciidoc/guides/_ugbtb_other-techniques_overriding-jdo-annotations.adoc
@@ -0,0 +1,64 @@
+[[_ugbtb_other-techniques_overriding-jdo-annotations]]
+= Overriding JDO Annotations
+: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 JDO Objectstore (or rather, the underlying DataNucleus implementation) builds its own persistence metamodel by reading both annotations on the class and also by searching for metadata in XML files. The metadata in the XML files takes precedence over the annotations, and so can be used to override metadata that is "hard-coded" in annotations.
+
+For example, as of 1.9.0 the various http://www.isisaddons.org[Isis addons] modules (not ASF) use schemas for each entity. For example, the `AuditEntry` entity in the http://github.com/isisaddons/isis-module-audit[audit module] is annotated as:
+
+[source,java]
+----
+@javax.jdo.annotations.PersistenceCapable(
+ identityType=IdentityType.DATASTORE,
+ schema = "IsisAddonsAudit",
+ table="AuditEntry")
+public class AuditEntry {
+ ...
+}
+----
+
+This will map the `AuditEntry` class to a table `"IsisAddonsAudit"."AuditEntry"`; that is using a custom schema to own the object.
+
+Suppose though that for whatever reason we didn't want to use a custom schema but would rather use the default. We can override the above annotation using a `package.jdo` file, for example:
+
+[source,xml]
+----
+<?xml version="1.0" encoding="UTF-8" ?>
+<jdo xmlns="http://xmlns.jcp.org/xml/ns/jdo/jdo"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/jdo/jdo
+ http://xmlns.jcp.org/xml/ns/jdo/jdo_3_0.xsd" version="3.0">
+ <package name="org.isisaddons.module.audit.dom">
+ <class name="AuditEntry" schema="PUBLIC" table="IsisAddonsAuditEntry">
+ </class>
+ </package>
+</jdo>
+----
+
+This file should be placed can be placed in `src/main/java/META-INF` within your application's `dom` module.
+
+[TIP]
+====
+(As of `1.11.0-SNAPSHOT`) you can use a mixin action on xref:rgcms.adoc#_rgcms_classes_mixins_Persistable[`Persistable`] mixin
+to download the JDO class metadata in XML form.
+====
+
+
+[NOTE]
+====
+* The same approach should work for any other JDO metadata, but some experimentation might be required.+
++
+For example, in writing up the above example we found that writing `schema=""` (in an attempt to say, "use the default schema for this table") actually caused the original annotation value to be used instead.
+
+* Forcing the schema to "PUBLIC" (as in the above example) works, but it isn't ideal because the name "PUBLIC" is not vendor-neutral (it works for HSQLDB, but MS SQL Server uses "dbo" as its default).
+
+* As of 1.9.0 Apache Isis will automatically (attempt) to create the owning schema for a given table if it does not exist. This behaviour can be customized, as described in the section on xref:_ugbtb_decoupling_db-schemas[using modules].
+
+* You may need to override the entire class metadata rather than individual elements; the mixin (`1.11.0-SNAPSHOT`) mentioned above can help here.
+====
+
+
http://git-wip-us.apache.org/repos/asf/isis/blob/29452af6/adocs/documentation/src/main/asciidoc/guides/_ugbtb_other-techniques_persisted-title.adoc
----------------------------------------------------------------------
diff --git a/adocs/documentation/src/main/asciidoc/guides/_ugbtb_other-techniques_persisted-title.adoc b/adocs/documentation/src/main/asciidoc/guides/_ugbtb_other-techniques_persisted-title.adoc
new file mode 100644
index 0000000..ea3a88e
--- /dev/null
+++ b/adocs/documentation/src/main/asciidoc/guides/_ugbtb_other-techniques_persisted-title.adoc
@@ -0,0 +1,82 @@
+[[_ugbtb_other-techniques_persisted-title]]
+= Persisted Title
+: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/
+
+
+
+Normally the title of an object is not persisted to the database, rather it is recomputed automatically from underlying properties. On occasion though you might want the title to also be persisted; either to make things easier for the DBA, or for an integration scenario, or some other purpose.
+
+We can implement this feature by leveraging the xref:rgcms.adoc#_rgcms_methods_lifecycle_jdo-api[JDO lifecycle]. In the design we discuss here we make it a responsibility of the entities to persist the title as a property, by implementing a `ObjectWithPersistedTitle` interface:
+
+[source,java]
+----
+public interface ObjectWithPersistedTitle {
+ @PropertyLayout(hidden = Where.EVERYWHERE) // <1>
+ String getTitle();
+ void setTitle(final String title);
+}
+----
+<1> we don't want to expose this in the UI because the title is already prominently displayed.
+
+We can then define a subscribing domain service that leverage this.
+
+[source,java]
+----
+@DomainService(nature = NatureOfService.DOMAIN)
+public class TitlingService extends AbstractSubscriber {
+ @Subscribe
+ public void on(final ObjectPersistingEvent ev) {
+ handle(ev.getSource());
+ }
+ @Subscribe
+ public void on(final ObjectUpdatingEvent ev) {
+ handle(ev.getSource());
+ }
+ private void handle(final Object persistentInstance) {
+ if(persistentInstance instanceof ObjectWithPersistedTitle) {
+ final ObjectWithPersistedTitle objectWithPersistedTitle =
+ (ObjectWithPersistedTitle) persistentInstance;
+ objectWithPersistedTitle.setTitle(container.titleOf(objectWithPersistedTitle));
+ }
+ }
+ @Inject
+ private DomainObjectContainer container;
+}
+----
+
+Prior to 1.10.0 (when lifecycle events were introduced), this could also be be done by accessing the JDO API directly:
+
+[source,java]
+----
+@RequestScoped
+@DomainService(nature = NatureOfService.DOMAIN)
+public class TitlingService {
+ @PostConstruct
+ public void init() {
+ isisJdoSupport.getJdoPersistenceManager().addInstanceLifecycleListener(
+ new StoreLifecycleListener() {
+ @Override
+ public void preStore(final InstanceLifecycleEvent event) {
+ final Object persistentInstance = event.getPersistentInstance();
+ if(persistentInstance instanceof ObjectWithPersistedTitle) {
+ final ObjectWithPersistedTitle objectWithPersistedTitle =
+ (ObjectWithPersistedTitle) persistentInstance;
+ objectWithPersistedTitle.setTitle(container.titleOf(objectWithPersistedTitle));
+ }
+ }
+ @Override
+ public void postStore(final InstanceLifecycleEvent event) {
+ }
+ }, null);
+ }
+ @Inject
+ private IsisJdoSupport isisJdoSupport;
+ @Inject
+ private DomainObjectContainer container;
+}
+----
+
+The above is probably the easiest and most straightforward design. One could imagine other designs where the persisted title is stored elsewhere. It could even be stored off into an link:http://lucene.apache.org/[Apache Lucene] (or similar) database to allow for free-text searches.
+
http://git-wip-us.apache.org/repos/asf/isis/blob/29452af6/adocs/documentation/src/main/asciidoc/guides/_ugbtb_other-techniques_replacing-default-service-implementations.adoc
----------------------------------------------------------------------
diff --git a/adocs/documentation/src/main/asciidoc/guides/_ugbtb_other-techniques_replacing-default-service-implementations.adoc b/adocs/documentation/src/main/asciidoc/guides/_ugbtb_other-techniques_replacing-default-service-implementations.adoc
new file mode 100644
index 0000000..bff0d40
--- /dev/null
+++ b/adocs/documentation/src/main/asciidoc/guides/_ugbtb_other-techniques_replacing-default-service-implementations.adoc
@@ -0,0 +1,64 @@
+[[_ugbtb_other-techniques_replacing-default-service-implementations]]
+= Replacing Service Implns
+: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 framework provides default implementations for many of the xref:rgsvc.adoc#_rgsvc_api[API Services]. This is convenient, but sometimes you will want to replace the default implementation with your own service implementation.
+
+The trick is to use the xref:rgant.adoc#_rgant-DomainServiceLayout_menuOrder[`@DomainServiceLayout#menuOrder()`] attribute, specifying a low number (typically `"1"`).
+
+For example, suppose you wanted to provide your own implementation of xref:rgsvc.adoc#_rgsvc_api_LocaleProvider[`LocaleProvider`]. Here's how:
+
+[source,java]
+----
+@DomainService(
+ nature = NatureOfService.DOMAIN
+)
+@DomainServiceLayout(
+ menuOrder = "1" // <1>
+)
+public class MyLocaleProvider implements LocaleProvider {
+ @Override
+ public Locale getLocale() {
+ return ...
+ }
+}
+----
+<1> takes precedence over the default implementation.
+
+
+It's also quite common to want to decorate the existing implementation (ie have your own implementation delegate to the default); this is also possible and quite easy if using `1.10.0` or later:
+
+[source,java]
+----
+@DomainService(
+ nature = NatureOfService.DOMAIN
+)
+@DomainServiceLayout(
+ menuOrder = "1" // <1>
+)
+public class MyLocaleProvider implements LocaleProvider {
+ @Override
+ public Locale getLocale() {
+ return getDelegateLocaleProvider().getLocale(); // <2>
+ }
+ Optional<LocaleProvider> delegateLocaleProvider; // <3>
+ private LocaleProvider getDelegateLocaleProvider() {
+ if(delegateLocaleProvider == null) {
+ delegateLocaleProvider = Iterables.tryFind(localeProviders, input -> input != this); // <4>
+ }
+ return delegateLocaleProvider.orNull();
+ }
+ @Inject
+ List<LocaleProvider> localeProviders; // <5>
+}
+----
+<1> takes precedence over the default implementation when injected elsewhere.
+<2> this implementation merely delegates to the default implementation
+<3> lazily populated
+<4> delegate to the first implementation that isn't _this_ implementation (else infinite loop!)
+<5> Injects all implementations, including this implemenation
+
http://git-wip-us.apache.org/repos/asf/isis/blob/29452af6/adocs/documentation/src/main/asciidoc/guides/_ugbtb_other-techniques_transactions-and-errors.adoc
----------------------------------------------------------------------
diff --git a/adocs/documentation/src/main/asciidoc/guides/_ugbtb_other-techniques_transactions-and-errors.adoc b/adocs/documentation/src/main/asciidoc/guides/_ugbtb_other-techniques_transactions-and-errors.adoc
new file mode 100644
index 0000000..19eb19e
--- /dev/null
+++ b/adocs/documentation/src/main/asciidoc/guides/_ugbtb_other-techniques_transactions-and-errors.adoc
@@ -0,0 +1,33 @@
+[[_ugbtb_other-techniques_transactions-and-errors]]
+= Transactions and Errors
+: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, every action invocation (in fact, every interaction) is automatically wrapped in a transaction, and any repository query automatically does a flush.
+
+What that means is that there's no need to explicitly start or commit transactions in Apache Isis; this will be done for you. Indeed, if you do try to manage transactions (eg by reaching into the JDO `PersistenceManager` exposed by the xref:rgsvc.adoc#_rgsvc_api_IsisJdoSupport[IsisJdoSupport] domain service, then you are likely to confuse Isis and get a stack trace for your trouble.
+
+
+
+
+== Aborting Transactions
+
+If you want to abort Apache Isis' transaction, this can be done by throwing `RecoverableException` (or any subclass, eg `ApplicationException`). The transaction will be aborted, and the exception message will be displayed to the user.
+
+If you throw any other exception (ie not a subclass of `RecoverableException`), then the users will see an error page (if Wicket viewer) or a 500 (if Restful Objects viewer).
+
+
+
+
+
+== Raise message/errors to users
+
+NOTE: TODO - xref:rgsvc.adoc#_rgsvc_api_DomainObjectContainer_messages-api[`DomainObjectContainer`]
+
+
+
+== Exception Recognizers
+
+NOTE: TODO - xref:rgsvc.adoc#_rgsvc_spi_ExceptionRecognizer[`ExceptionRecognizer`] service
+