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/11/17 21:49:05 UTC

[2/4] isis git commit: ISIS-1250: custom MessageBodyWriter for x-ro-domain-type Accept requests; remove the configuration option for ignoring/including Isis common schemas; move Dto role interface to own package; updating docs

http://git-wip-us.apache.org/repos/asf/isis/blob/19cdaaba/adocs/documentation/src/main/asciidoc/guides/_rg_services-spi_manpage-ErrorReportingService.adoc
----------------------------------------------------------------------
diff --git a/adocs/documentation/src/main/asciidoc/guides/_rg_services-spi_manpage-ErrorReportingService.adoc b/adocs/documentation/src/main/asciidoc/guides/_rg_services-spi_manpage-ErrorReportingService.adoc
index a4c81d5..525e1d9 100644
--- a/adocs/documentation/src/main/asciidoc/guides/_rg_services-spi_manpage-ErrorReportingService.adoc
+++ b/adocs/documentation/src/main/asciidoc/guides/_rg_services-spi_manpage-ErrorReportingService.adoc
@@ -99,7 +99,8 @@ image::{_imagesdir}reference-services-spi/ErrorReportingService/kitchensink-exam
 
 == Registering the Services
 
-Assuming that the `AppManifest` to xref:rg.adoc#_rg_classes_AppManifest-bootstrapping[bootstrap the app], then just
- ensure that the implementation is on the classpath and the module containing the implementation is returned in
- `AppManifest#getModules()`.
+There is no default implementation of this service.  To register your own implementation (and assuming that an
+`AppManifest` is being used to xref:rg.adoc#_rg_classes_AppManifest-bootstrapping[bootstrap the app]), then just
+ensure that the implementation is on the classpath and the module containing the implementation is returned in
+`AppManifest#getModules()`.
 

http://git-wip-us.apache.org/repos/asf/isis/blob/19cdaaba/adocs/documentation/src/main/asciidoc/guides/_rg_services-spi_manpage-EventSerializer.adoc
----------------------------------------------------------------------
diff --git a/adocs/documentation/src/main/asciidoc/guides/_rg_services-spi_manpage-EventSerializer.adoc b/adocs/documentation/src/main/asciidoc/guides/_rg_services-spi_manpage-EventSerializer.adoc
index 3253323..4a02273 100644
--- a/adocs/documentation/src/main/asciidoc/guides/_rg_services-spi_manpage-EventSerializer.adoc
+++ b/adocs/documentation/src/main/asciidoc/guides/_rg_services-spi_manpage-EventSerializer.adoc
@@ -53,21 +53,22 @@ You could if you wish change the representation by registering your own implemen
 
 
 
-
 == Registering the Services
 
-Assuming that the `configuration-and-annotation` services installer is configured (implicit if using the
-`AppManifest` to xref:rg.adoc#_rg_classes_AppManifest-bootstrapping[bootstrap the app]):
+There is no default implementation of this service provided by the core Apache Isis framework.
 
-[source,ini]
-----
-isis.services-installer=configuration-and-annotation
-----
+The (non-ASF) http://github.com/isisaddons/isis-module-publishing[Isis addons' publishing] module provides an
+implementation of this service (`RestfulObjectsSpecEventSerializer`) that serializes action invocations and published
+objects into a format based on the Restful Objects specification.  It also (as you might imagine) provides an
+implementation of the xref:rg.adoc#_rg_services-spi_manpage-PublishingService[`PublishingService`].
 
-then adding the (non-ASF) http://github.com/isisaddons/isis-module-publishing[Isis addons' publishing] module to the classpath will automatically register the `RestfulObjectsSpecEventSerializer` implementation (and also the module's `PublishingService` implementation).
+Assuming that an `AppManifest` is being used to xref:rg.adoc#_rg_classes_AppManifest-bootstrapping[bootstrap the app])
+then this can be activated by updating the `pom.xml` and updating the `AppManifest#getModules()` method.
 
 
 
 == Related Services
 
-This service is intended (though not mandated) to be used by implementations of xref:rg.adoc#_rg_services-spi_manpage-PublishingService[`PublishingService`].
\ No newline at end of file
+This service is intended (though not mandated) to be used by implementations of xref:rg.adoc#_rg_services-spi_manpage-PublishingService[`PublishingService`].  The (non-ASF) http://github.com/isisaddons/isis-module-publishing[Isis addons' publishing] module does use it (though the (non-ASF)
+http://github.com/isisaddons/isis-module-publishmq[Isis addons' publishmq] module does not).
+

http://git-wip-us.apache.org/repos/asf/isis/blob/19cdaaba/adocs/documentation/src/main/asciidoc/guides/_rg_services-spi_manpage-ExceptionRecognizer.adoc
----------------------------------------------------------------------
diff --git a/adocs/documentation/src/main/asciidoc/guides/_rg_services-spi_manpage-ExceptionRecognizer.adoc b/adocs/documentation/src/main/asciidoc/guides/_rg_services-spi_manpage-ExceptionRecognizer.adoc
index dba9775..c0227eb 100644
--- a/adocs/documentation/src/main/asciidoc/guides/_rg_services-spi_manpage-ExceptionRecognizer.adoc
+++ b/adocs/documentation/src/main/asciidoc/guides/_rg_services-spi_manpage-ExceptionRecognizer.adoc
@@ -96,16 +96,10 @@ If you want to recognize and handle additional exceptions (for example to captur
 
 == Registering the Services
 
-
 Assuming that the `configuration-and-annotation` services installer is configured (implicit if using the
-`AppManifest` to xref:rg.adoc#_rg_classes_AppManifest-bootstrapping[bootstrap the app]):
-
-[source,ini]
-----
-isis.services-installer=configuration-and-annotation
-----
-
-then the default implementations provided by the framework (`DomainObjectContainerDefault` and `ExceptionRecognizerCompositeForJdoObjectStore`) will be registered.
+`AppManifest` to xref:rg.adoc#_rg_classes_AppManifest-bootstrapping[bootstrap the app]) then the default
+implementations provided by the framework (`DomainObjectContainerDefault` and
+`ExceptionRecognizerCompositeForJdoObjectStore`) will be registered.
 
 In addition, you can register any further exception recognizers in `isis.properties`:
 
@@ -121,6 +115,5 @@ isis.services=...,\
 Prior to 1.9.0, the `ExceptionRecognizerCompositeForJdoObjectStore` also required manual registration.
 ====
 
-
 If the JDO exception recognizers are not required (rather unlikely), then they can be disabled en-masse using the xref:rg.adoc#_rg_runtime_configuring-core[configuration property] `isis.services.ExceptionRecognizerCompositeForJdoObjectStore.disable`.
 

http://git-wip-us.apache.org/repos/asf/isis/blob/19cdaaba/adocs/documentation/src/main/asciidoc/guides/_rg_services-spi_manpage-FixtureScriptsSpecificationProvider.adoc
----------------------------------------------------------------------
diff --git a/adocs/documentation/src/main/asciidoc/guides/_rg_services-spi_manpage-FixtureScriptsSpecificationProvider.adoc b/adocs/documentation/src/main/asciidoc/guides/_rg_services-spi_manpage-FixtureScriptsSpecificationProvider.adoc
index 38c07f4..3e3dc2a 100644
--- a/adocs/documentation/src/main/asciidoc/guides/_rg_services-spi_manpage-FixtureScriptsSpecificationProvider.adoc
+++ b/adocs/documentation/src/main/asciidoc/guides/_rg_services-spi_manpage-FixtureScriptsSpecificationProvider.adoc
@@ -6,13 +6,19 @@
 
 
 
-The `FixtureScriptsSpecificationProvider` configures the xref:rg.adoc#_rg_services-api_manpage-FixtureScriptsDefault[`FixtureScriptsDefault`] domain service, providing the location to search for fixture scripts and other settings.
+The `FixtureScriptsSpecificationProvider` configures the
+xref:rg.adoc#_rg_services-api_manpage-FixtureScriptsDefault[`FixtureScriptsDefault`] domain service, providing the
+location to search for fixture scripts and other settings.
 
-The service is only used if the `FixtureScriptsDefault` service is instantiated as a fallback by the framework.  If the application provides its own subclass of xref:rg.adoc#_rg_classes_super_manpage-FixtureScripts[`FixtureScripts`] superclass, then this provider service is not used.
+The service is only used if the `FixtureScriptsDefault` service is instantiated as a fallback by the framework.  If
+the application provides its own subclass of xref:rg.adoc#_rg_classes_super_manpage-FixtureScripts[`FixtureScripts`]
+superclass, then this provider service is not used.
 
 [TIP]
 ====
-Of the two designs, we encourage you to implement this "provider" SPI rather than subclass `FixtureScripts`.  The primary benefit (apart from decoupling responsibilities) is that it ensures that there is always an instance of `FixtureScripts` available for use.
+Of the two designs, we encourage you to implement this "provider" SPI rather than subclass `FixtureScripts`.  The
+primary benefit (apart from decoupling responsibilities) is that it ensures that there is always an instance of
+`FixtureScripts` available for use.
 ====
 
 

http://git-wip-us.apache.org/repos/asf/isis/blob/19cdaaba/adocs/documentation/src/main/asciidoc/guides/_rg_services-spi_manpage-LocaleProvider.adoc
----------------------------------------------------------------------
diff --git a/adocs/documentation/src/main/asciidoc/guides/_rg_services-spi_manpage-LocaleProvider.adoc b/adocs/documentation/src/main/asciidoc/guides/_rg_services-spi_manpage-LocaleProvider.adoc
index 81f8ecf..686e654 100644
--- a/adocs/documentation/src/main/asciidoc/guides/_rg_services-spi_manpage-LocaleProvider.adoc
+++ b/adocs/documentation/src/main/asciidoc/guides/_rg_services-spi_manpage-LocaleProvider.adoc
@@ -50,15 +50,13 @@ Currently there is no equivalent implementation for the xref:ug.adoc#_ug_restful
 == Registering the Services
 
 Assuming that the `configuration-and-annotation` services installer is configured (implicit if using the
-`AppManifest` to xref:rg.adoc#_rg_classes_AppManifest-bootstrapping[bootstrap the app]):
-
-[source,ini]
-----
-isis.services-installer=configuration-and-annotation
-----
-
-and that the xref:ug.adoc#_ug_wicket-viewer[Wicket viewer] is being used then an implementation of `LocaleProvider` is automatically registered and injected (it is annotated with `@DomainService`) so no further configuration is required.
+`AppManifest` to xref:rg.adoc#_rg_classes_AppManifest-bootstrapping[bootstrap the app]), _and_ that the
+xref:ug.adoc#_ug_wicket-viewer[Wicket viewer] is being used, then an implementation of `LocaleProvider` is
+automatically registered and injected (it is annotated with `@DomainService`) so no further configuration is required.
 
+To use an alternative implementation, use
+xref:rg.adoc#_rg_annotations_manpage-DomainServiceLayout_menuOrder[`@DomainServiceLayout#menuOrder()`] (as explained
+further in this xref:ug.adoc#_ug_how-tos_replacing-default-service-implementations["how to"] tip).
 
 
 

http://git-wip-us.apache.org/repos/asf/isis/blob/19cdaaba/adocs/documentation/src/main/asciidoc/guides/_rg_services-spi_manpage-PublishingService.adoc
----------------------------------------------------------------------
diff --git a/adocs/documentation/src/main/asciidoc/guides/_rg_services-spi_manpage-PublishingService.adoc b/adocs/documentation/src/main/asciidoc/guides/_rg_services-spi_manpage-PublishingService.adoc
index 9a197a6..2af475b 100644
--- a/adocs/documentation/src/main/asciidoc/guides/_rg_services-spi_manpage-PublishingService.adoc
+++ b/adocs/documentation/src/main/asciidoc/guides/_rg_services-spi_manpage-PublishingService.adoc
@@ -45,10 +45,36 @@ The serialized form returned by `EventSerializer` must be in a form that the `Pu
 
 == Implementation
 
-The (non-ASF) http://github.com/isisaddons/isis-module-publishing[Isis addons' publishing] module provides an implementation (`org.isisaddons.module.publishing.dom.org.apache.isis.applib.services.publish`) that persists each event as a `PublishedEvent` entity.  This holds the serialized form of the event metadata and payload as translated into a string by the injected `EventSerializer`.  The module also provides its own implementation of `EventSerializer`, namely `RestfulObjectsSpecEventSerializer`, which represents the event payload using the representation defined by the link:http://restfulobjects.org[Restful Objects spec] of (transient) objects, grafting on the metadata as additional JSON nodes.
+The framework provides no default implementations of this service.  There are however two implementations available in
+the (non-ASF) link:http://isisaddons.org[Isis Addons].
 
-The `PublishedEvent` entity also has a `state` field taking the values either "QUEUED" or "PROCESSED".  The intention here is that an event bus can poll this table to grab pending events and dispatch them to downstream systems.  When ``PublishedEvent``s are persisted initially they always take the value "QUEUED".
+=== isis-module-publishing
 
+The (non-ASF) http://github.com/isisaddons/isis-module-publishing[Isis addons' publishing] module provides an
+implementation (`org.isisaddons.module.publishing.dom.PublishingService`) that persists each
+event as a `PublishedEvent` entity.  This holds the serialized form of the event metadata and payload as translated
+into a string by the injected `EventSerializer`.  The module also provides its own implementation of `EventSerializer`,
+namely `RestfulObjectsSpecEventSerializer`, which represents the event payload using the representation defined by the link:http://restfulobjects.org[Restful Objects spec] of (transient) objects, grafting on the metadata as additional
+JSON nodes.
+
+The `PublishedEvent` entity also has a `state` field taking the values either "QUEUED" or "PROCESSED".  The intention
+here is that an event bus can poll this table to grab pending events and dispatch them to downstream systems.  When
+``PublishedEvent``s are persisted initially they always take the value "QUEUED".
+
+=== isis-module-publishmq
+
+The (non-ASF) http://github.com/isisaddons/isis-module-publishmq[Isis addons' publishmq] module provides an
+implementation (`org.isisaddons.module.publismq.dom.servicespi.PublishingServiceUsingActiveMq`) that publishes each 
+action invocation as an event on an link:http://activemq.apache.org[ActiveMQ] message queue.  These are converted into
+a canonical XML form (the xref:rg.adoc#_rg_schema-aim[ActionInvocationMemento] schema) using the
+xref:rg.adoc#_rg_schema-utilities-ActionInvocationMementoDtoUtils[`ActionInvocationMementoDtoUtils`] class; the idea
+being that subscribers on the ActiveMQ message queue can then query back for further information, for example using
+the xref:ug.adoc#_ug_restfulobjects-viewer[RestfulObjects viewer].
+
+[NOTE]
+====
+At the time of writing this implementation does not publish changed object events.
+====
 
 
 
@@ -131,15 +157,17 @@ public class ToDoItemChangedPayloadFactory implements PublishingPayloadFactoryFo
 
 == Registering the Services
 
-Assuming that the `configuration-and-annotation` services installer is configured (implicit if using the
-`AppManifest` to xref:rg.adoc#_rg_classes_AppManifest-bootstrapping[bootstrap the app]):
+There is no default implementation of this service provided by the core Apache Isis framework.
 
-[source,ini]
-----
-isis.services-installer=configuration-and-annotation
-----
+Both the (non-ASF) Isis addons' http://github.com/isisaddons/isis-module-publishing[publishing] module and the
+http://github.com/isisaddons/isis-module-publishmq[publishmq] module provide implementations of this service.
+Assuming that an `AppManifest` is being used to xref:rg.adoc#_rg_classes_AppManifest-bootstrapping[bootstrap the app])
+then this can be activated by updating the `pom.xml` and updating the `AppManifest#getModules()` method.
+
+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:ug.adoc#_ug_more-advanced_decoupling_vetoing-visibility[vetoing subscriber].
 
-then adding the (non-ASF) http://github.com/isisaddons/isis-module-publishing[Isis addons' publishing] module to the classpath will automatically register the `PublishingService` implementation (and also the module's `RestfulObjectsSpecEventSerializer` implementation).
 
 
 

http://git-wip-us.apache.org/repos/asf/isis/blob/19cdaaba/adocs/documentation/src/main/asciidoc/guides/_rg_services-spi_manpage-RepresentationService.adoc
----------------------------------------------------------------------
diff --git a/adocs/documentation/src/main/asciidoc/guides/_rg_services-spi_manpage-RepresentationService.adoc b/adocs/documentation/src/main/asciidoc/guides/_rg_services-spi_manpage-RepresentationService.adoc
index 7480586..889f7e7 100644
--- a/adocs/documentation/src/main/asciidoc/guides/_rg_services-spi_manpage-RepresentationService.adoc
+++ b/adocs/documentation/src/main/asciidoc/guides/_rg_services-spi_manpage-RepresentationService.adoc
@@ -85,19 +85,15 @@ This is an "internal" SPI, meaning that it uses types that are not part of the I
 
 As discussed in the introduction, the framework provides a default implementation, `o.a.i.v.ro.rendering.service.RepresentationServiceForRestfulObjects`.   This delegates to xref:rg.adoc#_rg_services-spi_manpage-ContentNegotiationService[`ContentNegotiationService`] to generate an alternative representation; but if none is provided then it falls back on generating the representations as defined in the link:http://restfulobjects.org[Restful Objects spec] v1.0.
 
+To use an alternative implementation, use
+xref:rg.adoc#_rg_annotations_manpage-DomainServiceLayout_menuOrder[`@DomainServiceLayout#menuOrder()`] (as explained
+further in this xref:ug.adoc#_ug_how-tos_replacing-default-service-implementations["how to"] tip).
 
 
 == Registering the Services
 
 Assuming that the `configuration-and-annotation` services installer is configured (implicit if using the
-`AppManifest` to xref:rg.adoc#_rg_classes_AppManifest-bootstrapping[bootstrap the app]):
-
-[source,ini]
-----
-isis.services-installer=configuration-and-annotation
-----
-
-then Isis' default implementation of `RepresentationService` service is automatically registered and injected (it is annotated with `@DomainService`) so no further configuration is required.
+`AppManifest` to xref:rg.adoc#_rg_classes_AppManifest-bootstrapping[bootstrap the app]) then Apache Isis' default implementation of `RepresentationService` service is automatically registered and injected (it is annotated with `@DomainService`) so no further configuration is required.
 
 
 

http://git-wip-us.apache.org/repos/asf/isis/blob/19cdaaba/adocs/documentation/src/main/asciidoc/guides/_rg_services-spi_manpage-TranslationService.adoc
----------------------------------------------------------------------
diff --git a/adocs/documentation/src/main/asciidoc/guides/_rg_services-spi_manpage-TranslationService.adoc b/adocs/documentation/src/main/asciidoc/guides/_rg_services-spi_manpage-TranslationService.adoc
index 2008ca0..636b2dd 100644
--- a/adocs/documentation/src/main/asciidoc/guides/_rg_services-spi_manpage-TranslationService.adoc
+++ b/adocs/documentation/src/main/asciidoc/guides/_rg_services-spi_manpage-TranslationService.adoc
@@ -61,14 +61,14 @@ For more details on the implementation, see xref:ug.adoc#_ug_more-advanced_i18n[
 == Registering the Services
 
 Assuming that the `configuration-and-annotation` services installer is configured (implicit if using the
-`AppManifest` to xref:rg.adoc#_rg_classes_AppManifest-bootstrapping[bootstrap the app]):
+`AppManifest` to xref:rg.adoc#_rg_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.
 
-[source,ini]
-----
-isis.services-installer=configuration-and-annotation
-----
+If the menu items are not required then these can be suppressed either using security or by implementing a xref:ug.adoc#_ug_more-advanced_decoupling_vetoing-visibility[vetoing subscriber].
 
-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:ug.adoc#_ug_more-advanced_decoupling_vetoing-visibility[vetoing subscriber].
+To use an alternative implementation, use
+xref:rg.adoc#_rg_annotations_manpage-DomainServiceLayout_menuOrder[`@DomainServiceLayout#menuOrder()`] (as explained
+further in this xref:ug.adoc#_ug_how-tos_replacing-default-service-implementations["how to"] tip).
 
 
 

http://git-wip-us.apache.org/repos/asf/isis/blob/19cdaaba/adocs/documentation/src/main/asciidoc/guides/_rg_services-spi_manpage-TranslationsResolver.adoc
----------------------------------------------------------------------
diff --git a/adocs/documentation/src/main/asciidoc/guides/_rg_services-spi_manpage-TranslationsResolver.adoc b/adocs/documentation/src/main/asciidoc/guides/_rg_services-spi_manpage-TranslationsResolver.adoc
index e263894..1a4a94f 100644
--- a/adocs/documentation/src/main/asciidoc/guides/_rg_services-spi_manpage-TranslationsResolver.adoc
+++ b/adocs/documentation/src/main/asciidoc/guides/_rg_services-spi_manpage-TranslationsResolver.adoc
@@ -47,14 +47,13 @@ Currently there is no equivalent implementation for the xref:ug.adoc#_ug_restful
 == Registering the Service
 
 Assuming that the `configuration-and-annotation` services installer is configured (implicit if using the
-`AppManifest` to xref:rg.adoc#_rg_classes_AppManifest-bootstrapping[bootstrap the app]):
+`AppManifest` to xref:rg.adoc#_rg_classes_AppManifest-bootstrapping[bootstrap the app]), _and_ that the xref:ug.adoc#_ug_wicket-viewer[Wicket viewer] is being used, then an implementation of `TranslationsResolver` is
+automatically registered and injected (it is annotated with `@DomainService`) so no further configuration is required.
 
-[source,ini]
-----
-isis.services-installer=configuration-and-annotation
-----
+To use an alternative implementation, use
+xref:rg.adoc#_rg_annotations_manpage-DomainServiceLayout_menuOrder[`@DomainServiceLayout#menuOrder()`] (as explained
+further in this xref:ug.adoc#_ug_how-tos_replacing-default-service-implementations["how to"] tip).
 
-and that the xref:ug.adoc#_ug_wicket-viewer[Wicket viewer] is being used then an implementation of `TranslationsResolver` is automatically registered and injected (it is annotated with `@DomainService`) so no further configuration is required.
 
 
 

http://git-wip-us.apache.org/repos/asf/isis/blob/19cdaaba/adocs/documentation/src/main/asciidoc/guides/_rg_services-spi_manpage-UrlEncodingService.adoc
----------------------------------------------------------------------
diff --git a/adocs/documentation/src/main/asciidoc/guides/_rg_services-spi_manpage-UrlEncodingService.adoc b/adocs/documentation/src/main/asciidoc/guides/_rg_services-spi_manpage-UrlEncodingService.adoc
new file mode 100644
index 0000000..1d21696
--- /dev/null
+++ b/adocs/documentation/src/main/asciidoc/guides/_rg_services-spi_manpage-UrlEncodingService.adoc
@@ -0,0 +1,37 @@
+[[_rg_services-spi_manpage-UrlEncodingService]]
+= `UrlEncodingService` (`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/
+
+
+
+The `UrlEncodingService` (`1.11.0-SNAPSHOT`) is used by the framework to map 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.
+
+The framework provides a default implementation of this service, `UrlEncodingServiceUsingBaseEncoding` (also in the
+applib) that uses `base-64` encoding to `UTF-8` charset.
+
+
+== SPI
+
+The SPI defined by the service is:
+
+[source,java]
+----
+public interface UrlEncodingService {
+    @Programmatic
+    public String encode(final String str);     // <1>
+    @Programmatic
+    public String decode(String str);           // <2>
+}
+----
+<1> convert the string (eg view model memento) into a string safe for use within an URL
+<2> unconvert the string from its URL form into its original form URL
+
+
+
+== Implementation
+

http://git-wip-us.apache.org/repos/asf/isis/blob/19cdaaba/adocs/documentation/src/main/asciidoc/guides/_rg_services-spi_manpage-UserProfileService.adoc
----------------------------------------------------------------------
diff --git a/adocs/documentation/src/main/asciidoc/guides/_rg_services-spi_manpage-UserProfileService.adoc b/adocs/documentation/src/main/asciidoc/guides/_rg_services-spi_manpage-UserProfileService.adoc
index 00048c5..8f55eea 100644
--- a/adocs/documentation/src/main/asciidoc/guides/_rg_services-spi_manpage-UserProfileService.adoc
+++ b/adocs/documentation/src/main/asciidoc/guides/_rg_services-spi_manpage-UserProfileService.adoc
@@ -33,7 +33,10 @@ In the future this API may be expanded; one obvious possibility is to return a p
 
 == Implementation
 
-The (non-ASF) http://github.com/isisaddons/isis-app-todoapp[Isis addons' todoapp] has a simple implementation of this service:
+There is no default implementation of this service provided by the core Apache Isis framework.
+
+An example implementation can be found in the (non-ASF)
+http://github.com/isisaddons/isis-app-todoapp[Isis addons' todoapp]:
 
 image::{_imagesdir}reference-services-spi/UserProfileService/todoapp.png[width="800px",link="{_imagesdir}reference-services-spi/UserProfileService/todoapp.png"]
 

http://git-wip-us.apache.org/repos/asf/isis/blob/19cdaaba/adocs/documentation/src/main/asciidoc/guides/_rg_services-spi_manpage-UserRegistrationService.adoc
----------------------------------------------------------------------
diff --git a/adocs/documentation/src/main/asciidoc/guides/_rg_services-spi_manpage-UserRegistrationService.adoc b/adocs/documentation/src/main/asciidoc/guides/_rg_services-spi_manpage-UserRegistrationService.adoc
index 745c241..25865f2 100644
--- a/adocs/documentation/src/main/asciidoc/guides/_rg_services-spi_manpage-UserRegistrationService.adoc
+++ b/adocs/documentation/src/main/asciidoc/guides/_rg_services-spi_manpage-UserRegistrationService.adoc
@@ -58,16 +58,32 @@ This is needed so that the self-registered users are assigned automatically to y
 
 == Registering the Services
 
-Assuming that the `configuration-and-annotation` services installer is configured (implicit if using the
-`AppManifest` to xref:rg.adoc#_rg_classes_AppManifest-bootstrapping[bootstrap the app]):
+There is no default implementation of this service provided by the core Apache Isis framework.
 
-[source,ini]
-----
-isis.services-installer=configuration-and-annotation
-----
+If using the (non-ASF) http://github.com/isisaddons/isis-module-security[Isis addons' security] module) for
+authentication and authorization, then note that it provides an adapter class,
+`SecurityModuleAppUserRegistrationServiceAbstract`, that provides most of the implementation.  You are still required
+to implement a subclass and register.
 
-then (if using the (non-ASF) http://github.com/isisaddons/isis-module-security[Isis addons' security] module) you will need to register your concrete implementation of `SecurityModuleAppUserRegistrationServiceAbstract`.
+For example:
 
+[source,java]
+----
+@DomainService(nature=NatureOfService.DOMAIN)
+public class AppUserRegistrationService extends SecurityModuleAppUserRegistrationServiceAbstract {
+    protected ApplicationRole getInitialRole() {
+    return findRole("regular-user");
+    }
+    protected Set<ApplicationRole> getAdditionalInitialRoles() {
+        return Collections.singleton(findRole("self-registered-user"));
+    }
+    private ApplicationRole findRole(final String roleName) {
+        return applicationRoles.findRoleByName(roleName);
+    }
+    @Inject
+    private ApplicationRoles applicationRoles;
+}
+----
 
 
 

http://git-wip-us.apache.org/repos/asf/isis/blob/19cdaaba/adocs/documentation/src/main/asciidoc/guides/rg.adoc
----------------------------------------------------------------------
diff --git a/adocs/documentation/src/main/asciidoc/guides/rg.adoc b/adocs/documentation/src/main/asciidoc/guides/rg.adoc
index 670052f..d3c44f8 100644
--- a/adocs/documentation/src/main/asciidoc/guides/rg.adoc
+++ b/adocs/documentation/src/main/asciidoc/guides/rg.adoc
@@ -27,4 +27,5 @@ include::_rg_services-spi.adoc[leveloffset=+1]
 include::_rg_classes.adoc[leveloffset=+1]
 include::_rg_object-layout.adoc[leveloffset=+1]
 include::_rg_runtime.adoc[leveloffset=+1]
+include::_rg_schema.adoc[leveloffset=+1]
 include::_rg_web-xml.adoc[leveloffset=+1]

http://git-wip-us.apache.org/repos/asf/isis/blob/19cdaaba/adocs/documentation/src/main/asciidoc/migration-notes.adoc
----------------------------------------------------------------------
diff --git a/adocs/documentation/src/main/asciidoc/migration-notes.adoc b/adocs/documentation/src/main/asciidoc/migration-notes.adoc
index eef8ed1..0506693 100644
--- a/adocs/documentation/src/main/asciidoc/migration-notes.adoc
+++ b/adocs/documentation/src/main/asciidoc/migration-notes.adoc
@@ -7,6 +7,7 @@
 
 
 
+include::_migration-notes_1.10.0-to-1.11.0.adoc[leveloffset=+1]
 include::_migration-notes_1.9.0-to-1.10.0.adoc[leveloffset=+1]
 include::_migration-notes_1.8.0-to-1.9.0.adoc[leveloffset=+1]
 include::_migration-notes_1.7.0-to-1.8.0.adoc[leveloffset=+1]

http://git-wip-us.apache.org/repos/asf/isis/blob/19cdaaba/core/applib/src/main/java/org/apache/isis/applib/AppManifest.java
----------------------------------------------------------------------
diff --git a/core/applib/src/main/java/org/apache/isis/applib/AppManifest.java b/core/applib/src/main/java/org/apache/isis/applib/AppManifest.java
index 515ea54..5ac3ef8 100644
--- a/core/applib/src/main/java/org/apache/isis/applib/AppManifest.java
+++ b/core/applib/src/main/java/org/apache/isis/applib/AppManifest.java
@@ -170,6 +170,7 @@ public interface AppManifest {
                 "org.apache.isis.core.wrapper" ,
                 "org.apache.isis.core.metamodel.services" ,
                 "org.apache.isis.core.runtime.services" ,
+                "org.apache.isis.schema.services" ,
                 "org.apache.isis.objectstore.jdo.applib.service" ,
                 "org.apache.isis.viewer.restfulobjects.rendering.service" ,
                 "org.apache.isis.objectstore.jdo.datanucleus.service.support" ,

http://git-wip-us.apache.org/repos/asf/isis/blob/19cdaaba/core/applib/src/main/java/org/apache/isis/applib/services/dto/Dto.java
----------------------------------------------------------------------
diff --git a/core/applib/src/main/java/org/apache/isis/applib/services/dto/Dto.java b/core/applib/src/main/java/org/apache/isis/applib/services/dto/Dto.java
new file mode 100644
index 0000000..ca4d801
--- /dev/null
+++ b/core/applib/src/main/java/org/apache/isis/applib/services/dto/Dto.java
@@ -0,0 +1,21 @@
+/**
+ *  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.
+ */
+package org.apache.isis.applib.services.dto;
+
+public interface Dto {
+
+}

http://git-wip-us.apache.org/repos/asf/isis/blob/19cdaaba/core/applib/src/main/java/org/apache/isis/applib/services/dto/Dto_downloadXml.java
----------------------------------------------------------------------
diff --git a/core/applib/src/main/java/org/apache/isis/applib/services/dto/Dto_downloadXml.java b/core/applib/src/main/java/org/apache/isis/applib/services/dto/Dto_downloadXml.java
new file mode 100644
index 0000000..b4360bf
--- /dev/null
+++ b/core/applib/src/main/java/org/apache/isis/applib/services/dto/Dto_downloadXml.java
@@ -0,0 +1,67 @@
+/**
+ *  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.
+ */
+package org.apache.isis.applib.services.dto;
+
+import java.io.IOException;
+
+import javax.inject.Inject;
+import javax.xml.bind.JAXBException;
+
+import org.apache.isis.applib.annotation.Action;
+import org.apache.isis.applib.annotation.ActionLayout;
+import org.apache.isis.applib.annotation.MemberOrder;
+import org.apache.isis.applib.annotation.Mixin;
+import org.apache.isis.applib.annotation.RestrictTo;
+import org.apache.isis.applib.annotation.SemanticsOf;
+import org.apache.isis.applib.services.jaxb.JaxbService;
+import org.apache.isis.applib.value.Clob;
+
+@Mixin
+public class Dto_downloadXml {
+
+    private final Dto dto;
+
+    public Dto_downloadXml(final Dto dto) {
+        this.dto = dto;
+    }
+
+    public static class ActionDomainEvent extends org.apache.isis.applib.IsisApplibModule.ActionDomainEvent<Dto> {}
+
+    @Action(
+            domainEvent = ActionDomainEvent.class,
+            semantics = SemanticsOf.SAFE,
+            restrictTo = RestrictTo.PROTOTYPING
+    )
+    @ActionLayout(
+            cssClassFa = "fa-download"
+    )
+    @MemberOrder(sequence = "500.1")
+    public Object $$(final String fileName) throws JAXBException, IOException {
+
+        final String xml = jaxbService.toXml(dto);
+        return new Clob(Util.withSuffix(fileName, "xml"), "text/xml", xml);
+    }
+
+    public String default0$$() {
+        return Util.withSuffix(dto.getClass().getName(), "xml");
+    }
+
+
+    @Inject
+    JaxbService jaxbService;
+
+}

http://git-wip-us.apache.org/repos/asf/isis/blob/19cdaaba/core/applib/src/main/java/org/apache/isis/applib/services/dto/Dto_downloadXsd.java
----------------------------------------------------------------------
diff --git a/core/applib/src/main/java/org/apache/isis/applib/services/dto/Dto_downloadXsd.java b/core/applib/src/main/java/org/apache/isis/applib/services/dto/Dto_downloadXsd.java
new file mode 100644
index 0000000..7d433e2
--- /dev/null
+++ b/core/applib/src/main/java/org/apache/isis/applib/services/dto/Dto_downloadXsd.java
@@ -0,0 +1,119 @@
+/**
+ *  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.
+ */
+package org.apache.isis.applib.services.dto;
+
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.OutputStreamWriter;
+import java.util.Map;
+import java.util.zip.ZipEntry;
+import java.util.zip.ZipOutputStream;
+
+import javax.activation.MimeType;
+import javax.activation.MimeTypeParseException;
+import javax.inject.Inject;
+
+import org.apache.isis.applib.DomainObjectContainer;
+import org.apache.isis.applib.FatalException;
+import org.apache.isis.applib.annotation.Action;
+import org.apache.isis.applib.annotation.ActionLayout;
+import org.apache.isis.applib.annotation.MemberOrder;
+import org.apache.isis.applib.annotation.Mixin;
+import org.apache.isis.applib.annotation.RestrictTo;
+import org.apache.isis.applib.annotation.SemanticsOf;
+import org.apache.isis.applib.services.jaxb.JaxbService;
+import org.apache.isis.applib.value.Blob;
+import org.apache.isis.applib.value.Clob;
+
+@Mixin
+public class Dto_downloadXsd {
+
+    private final Dto dto;
+
+    private final MimeType mimeTypeApplicationZip;
+
+    public Dto_downloadXsd(final Dto dto) {
+        this.dto = dto;
+        try {
+            mimeTypeApplicationZip = new MimeType("application", "zip");
+        } catch (final MimeTypeParseException ex) {
+            throw new FatalException(ex);
+        }
+    }
+
+    public static class ActionDomainEvent extends org.apache.isis.applib.IsisApplibModule.ActionDomainEvent<Dto> {}
+
+    @Action(
+            domainEvent = ActionDomainEvent.class,
+            semantics = SemanticsOf.SAFE,
+            restrictTo = RestrictTo.PROTOTYPING
+    )
+    @ActionLayout(
+
+    )
+    @MemberOrder(sequence = "500.2")
+    public Object $$(final String fileName) {
+
+        final Map<String, String> map = jaxbService.toXsd(dto, JaxbService.IsisSchemas.IGNORE);
+
+        if(map.isEmpty()) {
+            container.warnUser("No schemas were generated for " + dto.getClass().getName() + "; programming error?");
+            return null;
+        }
+
+        if(map.size() == 1) {
+            final Map.Entry<String, String> entry = map.entrySet().iterator().next();
+            return new Clob(Util.withSuffix(fileName, "xsd"), "text/xml", entry.getValue());
+        }
+
+        try {
+            final ByteArrayOutputStream baos = new ByteArrayOutputStream();
+            final ZipOutputStream zos = new ZipOutputStream(baos);
+            final OutputStreamWriter writer = new OutputStreamWriter(zos);
+
+            for (Map.Entry<String, String> entry : map.entrySet()) {
+                final String namespaceUri = entry.getKey();
+                final String schemaText = entry.getValue();
+                zos.putNextEntry(new ZipEntry(zipEntryNameFor(namespaceUri)));
+                writer.write(schemaText);
+                writer.flush();
+                zos.closeEntry();
+            }
+
+            writer.close();
+            return new Blob(Util.withSuffix(fileName, "zip"), mimeTypeApplicationZip, baos.toByteArray());
+        } catch (final IOException ex) {
+            throw new FatalException("Unable to create zip", ex);
+        }
+    }
+
+    public String default0$$() {
+        return Util.withSuffix(dto.getClass().getName(), "xsd");
+    }
+
+    private static String zipEntryNameFor(final String namespaceUri) {
+        return Util.withSuffix(namespaceUri, "xsd");
+    }
+
+
+    @Inject
+    DomainObjectContainer container;
+
+    @Inject
+    JaxbService jaxbService;
+}
+

http://git-wip-us.apache.org/repos/asf/isis/blob/19cdaaba/core/applib/src/main/java/org/apache/isis/applib/services/dto/Util.java
----------------------------------------------------------------------
diff --git a/core/applib/src/main/java/org/apache/isis/applib/services/dto/Util.java b/core/applib/src/main/java/org/apache/isis/applib/services/dto/Util.java
new file mode 100644
index 0000000..b87051b
--- /dev/null
+++ b/core/applib/src/main/java/org/apache/isis/applib/services/dto/Util.java
@@ -0,0 +1,33 @@
+/**
+ *  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.
+ */
+package org.apache.isis.applib.services.dto;
+
+class Util {
+
+    private Util(){}
+
+    static String withSuffix(String fileName, String suffix) {
+        if(!suffix.startsWith(".")) {
+            suffix = "." + suffix;
+        }
+        if(!fileName.endsWith(suffix)) {
+            fileName += suffix;
+        }
+        return fileName;
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/isis/blob/19cdaaba/core/applib/src/main/java/org/apache/isis/applib/services/jaxb/Dto.java
----------------------------------------------------------------------
diff --git a/core/applib/src/main/java/org/apache/isis/applib/services/jaxb/Dto.java b/core/applib/src/main/java/org/apache/isis/applib/services/jaxb/Dto.java
deleted file mode 100644
index 84a6999..0000000
--- a/core/applib/src/main/java/org/apache/isis/applib/services/jaxb/Dto.java
+++ /dev/null
@@ -1,21 +0,0 @@
-/**
- *  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.
- */
-package org.apache.isis.applib.services.jaxb;
-
-public interface Dto {
-
-}

http://git-wip-us.apache.org/repos/asf/isis/blob/19cdaaba/core/applib/src/main/java/org/apache/isis/applib/services/jaxb/Dto_downloadXml.java
----------------------------------------------------------------------
diff --git a/core/applib/src/main/java/org/apache/isis/applib/services/jaxb/Dto_downloadXml.java b/core/applib/src/main/java/org/apache/isis/applib/services/jaxb/Dto_downloadXml.java
deleted file mode 100644
index 61f7fd0..0000000
--- a/core/applib/src/main/java/org/apache/isis/applib/services/jaxb/Dto_downloadXml.java
+++ /dev/null
@@ -1,69 +0,0 @@
-/**
- *  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.
- */
-package org.apache.isis.applib.services.jaxb;
-
-import java.io.IOException;
-
-import javax.activation.MimeType;
-import javax.activation.MimeTypeParseException;
-import javax.inject.Inject;
-import javax.xml.bind.JAXBException;
-
-import org.apache.isis.applib.FatalException;
-import org.apache.isis.applib.annotation.Action;
-import org.apache.isis.applib.annotation.ActionLayout;
-import org.apache.isis.applib.annotation.MemberOrder;
-import org.apache.isis.applib.annotation.Mixin;
-import org.apache.isis.applib.annotation.RestrictTo;
-import org.apache.isis.applib.annotation.SemanticsOf;
-import org.apache.isis.applib.value.Clob;
-
-@Mixin
-public class Dto_downloadXml {
-
-    private final Dto dto;
-
-    public Dto_downloadXml(final Dto dto) {
-        this.dto = dto;
-    }
-
-    public static class ActionDomainEvent extends org.apache.isis.applib.IsisApplibModule.ActionDomainEvent<Dto> {}
-
-    @Action(
-            domainEvent = ActionDomainEvent.class,
-            semantics = SemanticsOf.SAFE,
-            restrictTo = RestrictTo.PROTOTYPING
-    )
-    @ActionLayout(
-            cssClassFa = "fa-download"
-    )
-    @MemberOrder(sequence = "500.1")
-    public Object $$(final String fileName) throws JAXBException, IOException {
-
-        final String xml = jaxbService.toXml(dto);
-        return new Clob(Util.withSuffix(fileName, "xml"), "text/xml", xml);
-    }
-
-    public String default0$$() {
-        return Util.withSuffix(dto.getClass().getName(), "xml");
-    }
-
-
-    @Inject
-    JaxbService jaxbService;
-
-}

http://git-wip-us.apache.org/repos/asf/isis/blob/19cdaaba/core/applib/src/main/java/org/apache/isis/applib/services/jaxb/Dto_downloadXsd.java
----------------------------------------------------------------------
diff --git a/core/applib/src/main/java/org/apache/isis/applib/services/jaxb/Dto_downloadXsd.java b/core/applib/src/main/java/org/apache/isis/applib/services/jaxb/Dto_downloadXsd.java
deleted file mode 100644
index 7213326..0000000
--- a/core/applib/src/main/java/org/apache/isis/applib/services/jaxb/Dto_downloadXsd.java
+++ /dev/null
@@ -1,118 +0,0 @@
-/**
- *  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.
- */
-package org.apache.isis.applib.services.jaxb;
-
-import java.io.ByteArrayOutputStream;
-import java.io.IOException;
-import java.io.OutputStreamWriter;
-import java.util.Map;
-import java.util.zip.ZipEntry;
-import java.util.zip.ZipOutputStream;
-
-import javax.activation.MimeType;
-import javax.activation.MimeTypeParseException;
-import javax.inject.Inject;
-
-import org.apache.isis.applib.DomainObjectContainer;
-import org.apache.isis.applib.FatalException;
-import org.apache.isis.applib.annotation.Action;
-import org.apache.isis.applib.annotation.ActionLayout;
-import org.apache.isis.applib.annotation.MemberOrder;
-import org.apache.isis.applib.annotation.Mixin;
-import org.apache.isis.applib.annotation.RestrictTo;
-import org.apache.isis.applib.annotation.SemanticsOf;
-import org.apache.isis.applib.value.Blob;
-import org.apache.isis.applib.value.Clob;
-
-@Mixin
-public class Dto_downloadXsd {
-
-    private final Dto dto;
-
-    private final MimeType mimeTypeApplicationZip;
-
-    public Dto_downloadXsd(final Dto dto) {
-        this.dto = dto;
-        try {
-            mimeTypeApplicationZip = new MimeType("application", "zip");
-        } catch (final MimeTypeParseException ex) {
-            throw new FatalException(ex);
-        }
-    }
-
-    public static class ActionDomainEvent extends org.apache.isis.applib.IsisApplibModule.ActionDomainEvent<Dto> {}
-
-    @Action(
-            domainEvent = ActionDomainEvent.class,
-            semantics = SemanticsOf.SAFE,
-            restrictTo = RestrictTo.PROTOTYPING
-    )
-    @ActionLayout(
-
-    )
-    @MemberOrder(sequence = "500.2")
-    public Object $$(final String fileName) {
-
-        final Map<String, String> map = jaxbService.toXsd(dto);
-
-        if(map.isEmpty()) {
-            container.warnUser("No schemas were generated for " + dto.getClass().getName() + "; programming error?");
-            return null;
-        }
-
-        if(map.size() == 1) {
-            final Map.Entry<String, String> entry = map.entrySet().iterator().next();
-            return new Clob(Util.withSuffix(fileName, "xsd"), "text/xml", entry.getValue());
-        }
-
-        try {
-            final ByteArrayOutputStream baos = new ByteArrayOutputStream();
-            final ZipOutputStream zos = new ZipOutputStream(baos);
-            final OutputStreamWriter writer = new OutputStreamWriter(zos);
-
-            for (Map.Entry<String, String> entry : map.entrySet()) {
-                final String namespaceUri = entry.getKey();
-                final String schemaText = entry.getValue();
-                zos.putNextEntry(new ZipEntry(zipEntryNameFor(namespaceUri)));
-                writer.write(schemaText);
-                writer.flush();
-                zos.closeEntry();
-            }
-
-            writer.close();
-            return new Blob(Util.withSuffix(fileName, "zip"), mimeTypeApplicationZip, baos.toByteArray());
-        } catch (final IOException ex) {
-            throw new FatalException("Unable to create zip", ex);
-        }
-    }
-
-    public String default0$$() {
-        return Util.withSuffix(dto.getClass().getName(), "xsd");
-    }
-
-    private static String zipEntryNameFor(final String namespaceUri) {
-        return Util.withSuffix(namespaceUri, "xsd");
-    }
-
-
-    @Inject
-    DomainObjectContainer container;
-
-    @Inject
-    JaxbService jaxbService;
-}
-

http://git-wip-us.apache.org/repos/asf/isis/blob/19cdaaba/core/applib/src/main/java/org/apache/isis/applib/services/jaxb/JaxbService.java
----------------------------------------------------------------------
diff --git a/core/applib/src/main/java/org/apache/isis/applib/services/jaxb/JaxbService.java b/core/applib/src/main/java/org/apache/isis/applib/services/jaxb/JaxbService.java
index 0cdd9e5..3b623a4 100644
--- a/core/applib/src/main/java/org/apache/isis/applib/services/jaxb/JaxbService.java
+++ b/core/applib/src/main/java/org/apache/isis/applib/services/jaxb/JaxbService.java
@@ -19,6 +19,7 @@ package org.apache.isis.applib.services.jaxb;
 import java.util.Map;
 
 import org.apache.isis.applib.annotation.Programmatic;
+import org.apache.isis.applib.services.dto.Dto_downloadXsd;
 
 public interface JaxbService {
 
@@ -28,6 +29,36 @@ public interface JaxbService {
     @Programmatic
     public String toXml(final Object domainObject);
 
+
+    /**
+     * Controls whether, when generating {@link #toXsd(Object, IsisSchemas) XML schemas},
+     * any of the common Isis schemas (in the namespace <code>http://org.apache.isis.schema</code>) should be included
+     * or just ignored (and therefore don't appear in the returned map).
+     *
+     * <p>
+     *     The practical benefit of this is that for many DTOs there will only be one other
+     *     schema, that of the DTO itself.  The {@link Dto_downloadXsd} mixin uses this to return that single XSD,
+     *     rather than generating a ZIP of two schemas (the Isis schema and the one for the DTO), as it would otherwise;
+     *     far more convenient when debugging and so on.  The Isis schemas can always be
+     *     <a href="http://isis.apache.org/schema">downloaded</a> from the Isis website.
+     * </p>
+     */
+    public enum IsisSchemas {
+        INCLUDE {
+            public boolean shouldIgnore(final String namespaceUri) {
+                return false;
+            }
+
+        },
+        IGNORE {
+            public boolean shouldIgnore(final String namespaceUri) {
+                return namespaceUri.matches(".*isis\\.apache\\.org.*");
+            }
+        };
+
+        public abstract boolean shouldIgnore(final String namespaceUri);
+    }
+
     @Programmatic
-    public Map<String, String> toXsd(final Object domainObject);
+    public Map<String, String> toXsd(final Object domainObject, final IsisSchemas isisSchemas);
 }
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/isis/blob/19cdaaba/core/applib/src/main/java/org/apache/isis/applib/services/jaxb/Util.java
----------------------------------------------------------------------
diff --git a/core/applib/src/main/java/org/apache/isis/applib/services/jaxb/Util.java b/core/applib/src/main/java/org/apache/isis/applib/services/jaxb/Util.java
deleted file mode 100644
index 0859d07..0000000
--- a/core/applib/src/main/java/org/apache/isis/applib/services/jaxb/Util.java
+++ /dev/null
@@ -1,33 +0,0 @@
-/**
- *  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.
- */
-package org.apache.isis.applib.services.jaxb;
-
-class Util {
-
-    private Util(){}
-
-    static String withSuffix(String fileName, String suffix) {
-        if(!suffix.startsWith(".")) {
-            suffix = "." + suffix;
-        }
-        if(!fileName.endsWith(suffix)) {
-            fileName += suffix;
-        }
-        return fileName;
-    }
-
-}

http://git-wip-us.apache.org/repos/asf/isis/blob/19cdaaba/core/applib/src/main/java/org/apache/isis/applib/services/urlencoding/UrlEncodingService.java
----------------------------------------------------------------------
diff --git a/core/applib/src/main/java/org/apache/isis/applib/services/urlencoding/UrlEncodingService.java b/core/applib/src/main/java/org/apache/isis/applib/services/urlencoding/UrlEncodingService.java
index 9c8c25f..9f02e84 100644
--- a/core/applib/src/main/java/org/apache/isis/applib/services/urlencoding/UrlEncodingService.java
+++ b/core/applib/src/main/java/org/apache/isis/applib/services/urlencoding/UrlEncodingService.java
@@ -16,29 +16,14 @@
  */
 package org.apache.isis.applib.services.urlencoding;
 
-import java.nio.charset.Charset;
-
-import com.google.common.io.BaseEncoding;
-
-import org.apache.isis.applib.annotation.DomainService;
-import org.apache.isis.applib.annotation.NatureOfService;
 import org.apache.isis.applib.annotation.Programmatic;
 
-@DomainService(
-        nature = NatureOfService.DOMAIN
-)
-public class UrlEncodingService {
+public interface UrlEncodingService {
 
     @Programmatic
-    public String decode(String str) {
-        final byte[] bytes = BaseEncoding.base64Url().decode(str);
-        return new String(bytes, Charset.forName("UTF-8"));
-    }
+    public String encode(final String str);
 
     @Programmatic
-    public String encode(final String xmlStr) {
-        byte[] bytes = xmlStr.getBytes(Charset.forName("UTF-8"));
-        return BaseEncoding.base64Url().encode(bytes);
-    }
+    public String decode(String str);
 
 }

http://git-wip-us.apache.org/repos/asf/isis/blob/19cdaaba/core/applib/src/main/java/org/apache/isis/applib/services/urlencoding/UrlEncodingServiceUsingBaseEncoding.java
----------------------------------------------------------------------
diff --git a/core/applib/src/main/java/org/apache/isis/applib/services/urlencoding/UrlEncodingServiceUsingBaseEncoding.java b/core/applib/src/main/java/org/apache/isis/applib/services/urlencoding/UrlEncodingServiceUsingBaseEncoding.java
new file mode 100644
index 0000000..fdab8c3
--- /dev/null
+++ b/core/applib/src/main/java/org/apache/isis/applib/services/urlencoding/UrlEncodingServiceUsingBaseEncoding.java
@@ -0,0 +1,57 @@
+/**
+ *  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.
+ */
+package org.apache.isis.applib.services.urlencoding;
+
+import java.nio.charset.Charset;
+
+import com.google.common.io.BaseEncoding;
+
+import org.apache.isis.applib.annotation.DomainService;
+import org.apache.isis.applib.annotation.NatureOfService;
+import org.apache.isis.applib.annotation.Programmatic;
+
+@DomainService(
+        nature = NatureOfService.DOMAIN
+)
+public class UrlEncodingServiceUsingBaseEncoding implements UrlEncodingService {
+
+    private final BaseEncoding baseEncoding;
+    private final Charset charset;
+
+    public UrlEncodingServiceUsingBaseEncoding(final BaseEncoding baseEncoding, final Charset charset) {
+        this.baseEncoding = baseEncoding;
+        this.charset = charset;
+    }
+
+    public UrlEncodingServiceUsingBaseEncoding() {
+        this(BaseEncoding.base64Url(), Charset.forName("UTF-8"));
+    }
+
+
+    @Programmatic
+    public String encode(final String str) {
+        byte[] bytes = str.getBytes(charset);
+        return baseEncoding.encode(bytes);
+    }
+
+    @Programmatic
+    public String decode(String str) {
+        final byte[] bytes = baseEncoding.decode(str);
+        return new String(bytes, Charset.forName("UTF-8"));
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/isis/blob/19cdaaba/core/runtime/src/main/java/org/apache/isis/core/runtime/services/jaxb/JaxbServiceDefault.java
----------------------------------------------------------------------
diff --git a/core/runtime/src/main/java/org/apache/isis/core/runtime/services/jaxb/JaxbServiceDefault.java b/core/runtime/src/main/java/org/apache/isis/core/runtime/services/jaxb/JaxbServiceDefault.java
deleted file mode 100644
index caeb11e..0000000
--- a/core/runtime/src/main/java/org/apache/isis/core/runtime/services/jaxb/JaxbServiceDefault.java
+++ /dev/null
@@ -1,167 +0,0 @@
-/**
- *  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.
- */
-package org.apache.isis.core.runtime.services.jaxb;
-
-import java.io.IOException;
-import java.io.StringReader;
-import java.io.StringWriter;
-import java.lang.reflect.Method;
-import java.util.List;
-import java.util.Map;
-
-import javax.annotation.PostConstruct;
-import javax.inject.Inject;
-import javax.xml.bind.JAXBContext;
-import javax.xml.bind.JAXBException;
-import javax.xml.bind.Marshaller;
-import javax.xml.bind.Unmarshaller;
-
-import com.google.common.base.Function;
-import com.google.common.base.Joiner;
-import com.google.common.collect.Iterables;
-
-import org.apache.isis.applib.ApplicationException;
-import org.apache.isis.applib.DomainObjectContainer;
-import org.apache.isis.applib.NonRecoverableException;
-import org.apache.isis.applib.annotation.DomainService;
-import org.apache.isis.applib.annotation.NatureOfService;
-import org.apache.isis.applib.services.jaxb.JaxbService;
-import org.apache.isis.core.runtime.services.jaxb.util.CatalogingSchemaOutputResolver;
-import org.apache.isis.schema.utils.jaxbadapters.PersistentEntityAdapter;
-
-@DomainService(
-        nature = NatureOfService.DOMAIN
-)
-public class JaxbServiceDefault implements JaxbService {
-
-    /**
-     * This boolean flag controls whether, when generating {@link #toXsd(Object) XML schemas},
-     * any of the common Isis schemas (in the namespace <code>http://org.apache.isis.schema</code>) should be included or just ignored (and therefore don't appear in the ZIP file).
-     *
-     * <p>
-     *     The practical benefit of this is that for many DTOs there will only be one other
-     *     schema, that of the DTO itself.  Rather than generating a ZIP of two schemas (the Isis
-     *     schema and the one for the DTO), the {@link #toXsd(Object) toXsd} method will instead
-     *     return a single XSD file; far more convenient when debugging and so on.
-     *     The Isis schemas meanwhile can always be <a href="http://isis.apache.org/schema">downloaded from the website </a>.
-     * </p>
-     */
-    public static final String INCLUDE_ISIS_SCHEMA = "isis.services.jaxb.includeIsisSchema";
-
-    private boolean includeIsisSchema;
-
-    @PostConstruct
-    public void init(Map<String,String> props) {
-        final String prop = props.get(INCLUDE_ISIS_SCHEMA);
-        this.includeIsisSchema = prop != null && Boolean.parseBoolean(prop);
-
-    }
-
-    @Override
-    public <T> T fromXml(final Class<T> domainClass, final String xml) {
-        try {
-            final JAXBContext context = JAXBContext.newInstance(domainClass);
-
-            final PersistentEntityAdapter adapter = new PersistentEntityAdapter();
-            container.injectServicesInto(adapter);
-
-            final Unmarshaller unmarshaller = context.createUnmarshaller();
-            unmarshaller.setAdapter(PersistentEntityAdapter.class, adapter);
-
-            final Object unmarshal = unmarshaller.unmarshal(new StringReader(xml));
-            return (T) unmarshal;
-
-        } catch (final JAXBException ex) {
-            throw new NonRecoverableException("Error unmarshalling domain object from XML; domain object class is '" + domainClass.getName() + "'", ex);
-        }
-    }
-
-    @Override
-    public String toXml(final Object domainObject)  {
-
-        final Class<?> domainClass = domainObject.getClass();
-        try {
-            final JAXBContext context = JAXBContext.newInstance(domainClass);
-
-            final PersistentEntityAdapter adapter = new PersistentEntityAdapter();
-            container.injectServicesInto(adapter);
-
-            final Marshaller marshaller = context.createMarshaller();
-            marshaller.setAdapter(PersistentEntityAdapter.class, adapter);
-            marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
-
-            final StringWriter sw = new StringWriter();
-            marshaller.marshal(domainObject, sw);
-            final String xml = sw.toString();
-
-            return xml;
-
-        } catch (final JAXBException ex) {
-            final Class<? extends JAXBException> exClass = ex.getClass();
-
-            final String name = exClass.getName();
-            if(name.equals("com.sun.xml.bind.v2.runtime.IllegalAnnotationsException")) {
-                // report a better error if possible
-                // this is done reflectively so as to not have to bring in a new Maven dependency
-                List<? extends Exception> errors = null;
-                String annotationExceptionMessages = null;
-                try {
-                    final Method getErrorsMethod = exClass.getMethod("getErrors");
-                    errors = (List<? extends Exception>) getErrorsMethod.invoke(ex);
-                    annotationExceptionMessages = ": " + Joiner.on("; ").join(
-                            Iterables.transform(errors, new Function<Exception, String>() {
-                                @Override public String apply(final Exception e) {
-                                    return e.getMessage();
-                                }
-                            }));
-                } catch (Exception e) {
-                    // fall through if we hit any snags, and instead throw the more generic error message.
-                }
-                if(errors != null) {
-                    throw new NonRecoverableException(
-                            "Error marshalling domain object to XML, due to illegal annotations on domain object class '"
-                                    + domainClass.getName() + "'; " + errors.size() + " error"
-                                    + (errors.size() == 1? "": "s")
-                                    + " reported" + (!errors
-                                    .isEmpty() ? annotationExceptionMessages : ""), ex);
-                }
-            }
-
-            throw new NonRecoverableException("Error marshalling domain object to XML; domain object class is '" + domainClass.getName() + "'", ex);
-        }
-    }
-
-    public Map<String,String> toXsd(final Object domainObject) {
-
-        try {
-            final Class<?> domainClass = domainObject.getClass();
-            final JAXBContext context = JAXBContext.newInstance(domainClass);
-
-            final CatalogingSchemaOutputResolver outputResolver = new CatalogingSchemaOutputResolver(includeIsisSchema);
-            context.generateSchema(outputResolver);
-
-            return outputResolver.asMap();
-        } catch (final JAXBException | IOException ex) {
-            throw new ApplicationException(ex);
-        }
-    }
-
-
-    @Inject
-    DomainObjectContainer container;
-}
-

http://git-wip-us.apache.org/repos/asf/isis/blob/19cdaaba/core/runtime/src/main/java/org/apache/isis/core/runtime/services/jaxb/util/CatalogingSchemaOutputResolver.java
----------------------------------------------------------------------
diff --git a/core/runtime/src/main/java/org/apache/isis/core/runtime/services/jaxb/util/CatalogingSchemaOutputResolver.java b/core/runtime/src/main/java/org/apache/isis/core/runtime/services/jaxb/util/CatalogingSchemaOutputResolver.java
deleted file mode 100644
index b267284..0000000
--- a/core/runtime/src/main/java/org/apache/isis/core/runtime/services/jaxb/util/CatalogingSchemaOutputResolver.java
+++ /dev/null
@@ -1,83 +0,0 @@
-/**
- *  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.
- */
-package org.apache.isis.core.runtime.services.jaxb.util;
-
-import java.io.IOException;
-import java.util.Collections;
-import java.util.List;
-import java.util.Map;
-
-import javax.xml.bind.SchemaOutputResolver;
-import javax.xml.transform.Result;
-import javax.xml.transform.stream.StreamResult;
-
-import com.google.common.collect.Lists;
-import com.google.common.collect.Maps;
-
-/**
- * An implementation of {@link SchemaOutputResolver} that keeps track of all the schemas for which it has
- * {@link #createOutput(String, String) created} an output {@link StreamResult} containing the content of the schema.
- */
-public class CatalogingSchemaOutputResolver extends SchemaOutputResolver
-{
-    private final boolean includeIsisSchema;
-    private List<String> namespaceUris = Lists.newArrayList();
-
-    public CatalogingSchemaOutputResolver(final boolean includeIsisSchema) {
-        this.includeIsisSchema = includeIsisSchema;
-    }
-
-    public List<String> getNamespaceUris() {
-        return namespaceUris;
-    }
-
-    private Map<String, StreamResultWithWriter> schemaResultByNamespaceUri = Maps.newLinkedHashMap();
-
-    public String getSchemaTextFor(final String namespaceUri) {
-        final StreamResultWithWriter streamResult = schemaResultByNamespaceUri.get(namespaceUri);
-        return streamResult != null? streamResult.asString(): null;
-    }
-
-    @Override
-    public Result createOutput(
-            final String namespaceUri, final String suggestedFileName) throws IOException {
-
-        final StreamResultWithWriter result = new StreamResultWithWriter();
-
-        result.setSystemId(namespaceUri);
-
-        if (namespaceUri.matches(".*isis\\.apache\\.org.*") && !includeIsisSchema) {
-            // ignore
-        } else {
-            namespaceUris.add(namespaceUri);
-            schemaResultByNamespaceUri.put(namespaceUri, result);
-        }
-
-        return result;
-    }
-
-    public Map<String, String> asMap() {
-        final Map<String,String> map = Maps.newLinkedHashMap();
-        final List<String> namespaceUris = getNamespaceUris();
-
-        for (String namespaceUri : namespaceUris) {
-            map.put(namespaceUri, getSchemaTextFor(namespaceUri));
-        }
-
-        return Collections.unmodifiableMap(map);
-    }
-}

http://git-wip-us.apache.org/repos/asf/isis/blob/19cdaaba/core/runtime/src/main/java/org/apache/isis/core/runtime/services/jaxb/util/StreamResultWithWriter.java
----------------------------------------------------------------------
diff --git a/core/runtime/src/main/java/org/apache/isis/core/runtime/services/jaxb/util/StreamResultWithWriter.java b/core/runtime/src/main/java/org/apache/isis/core/runtime/services/jaxb/util/StreamResultWithWriter.java
deleted file mode 100644
index 99884be..0000000
--- a/core/runtime/src/main/java/org/apache/isis/core/runtime/services/jaxb/util/StreamResultWithWriter.java
+++ /dev/null
@@ -1,45 +0,0 @@
-/**
- *  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.
- */
-package org.apache.isis.core.runtime.services.jaxb.util;
-
-import java.io.StringWriter;
-
-import javax.xml.transform.stream.StreamResult;
-
-/**
- * A {@link StreamResult} that contains its own writer.
- *
- * <p>
- *     The point is that the writer is only ever queried lazily AFTER the result has been generated.
- * </p>
- */
-public class StreamResultWithWriter extends StreamResult {
-    private final StringWriter writer;
-
-    public StreamResultWithWriter() {
-        this(new StringWriter());
-    }
-
-    private StreamResultWithWriter(StringWriter writer) {
-        super(writer);
-        this.writer = writer;
-    }
-
-    public String asString() {
-        return writer.toString();
-    }
-}

http://git-wip-us.apache.org/repos/asf/isis/blob/19cdaaba/core/schema/src/main/java/org/apache/isis/schema/services/jaxb/CatalogingSchemaOutputResolver.java
----------------------------------------------------------------------
diff --git a/core/schema/src/main/java/org/apache/isis/schema/services/jaxb/CatalogingSchemaOutputResolver.java b/core/schema/src/main/java/org/apache/isis/schema/services/jaxb/CatalogingSchemaOutputResolver.java
new file mode 100644
index 0000000..aac43d7
--- /dev/null
+++ b/core/schema/src/main/java/org/apache/isis/schema/services/jaxb/CatalogingSchemaOutputResolver.java
@@ -0,0 +1,85 @@
+/**
+ *  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.
+ */
+package org.apache.isis.schema.services.jaxb;
+
+import java.io.IOException;
+import java.util.Collections;
+import java.util.List;
+import java.util.Map;
+
+import javax.xml.bind.SchemaOutputResolver;
+import javax.xml.transform.Result;
+import javax.xml.transform.stream.StreamResult;
+
+import com.google.common.collect.Lists;
+import com.google.common.collect.Maps;
+
+import org.apache.isis.applib.services.jaxb.JaxbService;
+
+/**
+ * An implementation of {@link SchemaOutputResolver} that keeps track of all the schemas for which it has
+ * {@link #createOutput(String, String) created} an output {@link StreamResult} containing the content of the schema.
+ */
+class CatalogingSchemaOutputResolver extends SchemaOutputResolver
+{
+    private final JaxbService.IsisSchemas isisSchemas;
+    private List<String> namespaceUris = Lists.newArrayList();
+
+    public CatalogingSchemaOutputResolver(final JaxbService.IsisSchemas isisSchemas) {
+        this.isisSchemas = isisSchemas;
+    }
+
+    public List<String> getNamespaceUris() {
+        return namespaceUris;
+    }
+
+    private Map<String, StreamResultWithWriter> schemaResultByNamespaceUri = Maps.newLinkedHashMap();
+
+    public String getSchemaTextFor(final String namespaceUri) {
+        final StreamResultWithWriter streamResult = schemaResultByNamespaceUri.get(namespaceUri);
+        return streamResult != null? streamResult.asString(): null;
+    }
+
+    @Override
+    public Result createOutput(
+            final String namespaceUri, final String suggestedFileName) throws IOException {
+
+        final StreamResultWithWriter result = new StreamResultWithWriter();
+
+        result.setSystemId(namespaceUri);
+
+        if (isisSchemas.shouldIgnore(namespaceUri)) {
+            // skip
+        } else {
+            namespaceUris.add(namespaceUri);
+            schemaResultByNamespaceUri.put(namespaceUri, result);
+        }
+
+        return result;
+    }
+
+    public Map<String, String> asMap() {
+        final Map<String,String> map = Maps.newLinkedHashMap();
+        final List<String> namespaceUris = getNamespaceUris();
+
+        for (String namespaceUri : namespaceUris) {
+            map.put(namespaceUri, getSchemaTextFor(namespaceUri));
+        }
+
+        return Collections.unmodifiableMap(map);
+    }
+}

http://git-wip-us.apache.org/repos/asf/isis/blob/19cdaaba/core/schema/src/main/java/org/apache/isis/schema/services/jaxb/JaxbServiceDefault.java
----------------------------------------------------------------------
diff --git a/core/schema/src/main/java/org/apache/isis/schema/services/jaxb/JaxbServiceDefault.java b/core/schema/src/main/java/org/apache/isis/schema/services/jaxb/JaxbServiceDefault.java
new file mode 100644
index 0000000..2d2bf79
--- /dev/null
+++ b/core/schema/src/main/java/org/apache/isis/schema/services/jaxb/JaxbServiceDefault.java
@@ -0,0 +1,142 @@
+/**
+ *  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.
+ */
+package org.apache.isis.schema.services.jaxb;
+
+import java.io.IOException;
+import java.io.StringReader;
+import java.io.StringWriter;
+import java.lang.reflect.Method;
+import java.util.List;
+import java.util.Map;
+
+import javax.inject.Inject;
+import javax.xml.bind.JAXBContext;
+import javax.xml.bind.JAXBException;
+import javax.xml.bind.Marshaller;
+import javax.xml.bind.Unmarshaller;
+
+import com.google.common.base.Function;
+import com.google.common.base.Joiner;
+import com.google.common.collect.Iterables;
+
+import org.apache.isis.applib.ApplicationException;
+import org.apache.isis.applib.DomainObjectContainer;
+import org.apache.isis.applib.NonRecoverableException;
+import org.apache.isis.applib.annotation.DomainService;
+import org.apache.isis.applib.annotation.NatureOfService;
+import org.apache.isis.applib.services.jaxb.JaxbService;
+import org.apache.isis.schema.utils.jaxbadapters.PersistentEntityAdapter;
+
+@DomainService(
+        nature = NatureOfService.DOMAIN
+)
+public class JaxbServiceDefault implements JaxbService {
+
+    @Override
+    public <T> T fromXml(final Class<T> domainClass, final String xml) {
+        try {
+            final JAXBContext context = JAXBContext.newInstance(domainClass);
+
+            final PersistentEntityAdapter adapter = new PersistentEntityAdapter();
+            container.injectServicesInto(adapter);
+
+            final Unmarshaller unmarshaller = context.createUnmarshaller();
+            unmarshaller.setAdapter(PersistentEntityAdapter.class, adapter);
+
+            final Object unmarshal = unmarshaller.unmarshal(new StringReader(xml));
+            return (T) unmarshal;
+
+        } catch (final JAXBException ex) {
+            throw new NonRecoverableException("Error unmarshalling domain object from XML; domain object class is '" + domainClass.getName() + "'", ex);
+        }
+    }
+
+    @Override
+    public String toXml(final Object domainObject)  {
+
+        final Class<?> domainClass = domainObject.getClass();
+        try {
+            final JAXBContext context = JAXBContext.newInstance(domainClass);
+
+            final PersistentEntityAdapter adapter = new PersistentEntityAdapter();
+            container.injectServicesInto(adapter);
+
+            final Marshaller marshaller = context.createMarshaller();
+            marshaller.setAdapter(PersistentEntityAdapter.class, adapter);
+            marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
+
+            final StringWriter sw = new StringWriter();
+            marshaller.marshal(domainObject, sw);
+            final String xml = sw.toString();
+
+            return xml;
+
+        } catch (final JAXBException ex) {
+            final Class<? extends JAXBException> exClass = ex.getClass();
+
+            final String name = exClass.getName();
+            if(name.equals("com.sun.xml.bind.v2.runtime.IllegalAnnotationsException")) {
+                // report a better error if possible
+                // this is done reflectively so as to not have to bring in a new Maven dependency
+                List<? extends Exception> errors = null;
+                String annotationExceptionMessages = null;
+                try {
+                    final Method getErrorsMethod = exClass.getMethod("getErrors");
+                    errors = (List<? extends Exception>) getErrorsMethod.invoke(ex);
+                    annotationExceptionMessages = ": " + Joiner.on("; ").join(
+                            Iterables.transform(errors, new Function<Exception, String>() {
+                                @Override public String apply(final Exception e) {
+                                    return e.getMessage();
+                                }
+                            }));
+                } catch (Exception e) {
+                    // fall through if we hit any snags, and instead throw the more generic error message.
+                }
+                if(errors != null) {
+                    throw new NonRecoverableException(
+                            "Error marshalling domain object to XML, due to illegal annotations on domain object class '"
+                                    + domainClass.getName() + "'; " + errors.size() + " error"
+                                    + (errors.size() == 1? "": "s")
+                                    + " reported" + (!errors
+                                    .isEmpty() ? annotationExceptionMessages : ""), ex);
+                }
+            }
+
+            throw new NonRecoverableException("Error marshalling domain object to XML; domain object class is '" + domainClass.getName() + "'", ex);
+        }
+    }
+
+    public Map<String,String> toXsd(final Object domainObject, final IsisSchemas isisSchemas) {
+
+        try {
+            final Class<?> domainClass = domainObject.getClass();
+            final JAXBContext context = JAXBContext.newInstance(domainClass);
+
+            final CatalogingSchemaOutputResolver outputResolver = new CatalogingSchemaOutputResolver(isisSchemas);
+            context.generateSchema(outputResolver);
+
+            return outputResolver.asMap();
+        } catch (final JAXBException | IOException ex) {
+            throw new ApplicationException(ex);
+        }
+    }
+
+
+    @Inject
+    DomainObjectContainer container;
+}
+

http://git-wip-us.apache.org/repos/asf/isis/blob/19cdaaba/core/schema/src/main/java/org/apache/isis/schema/services/jaxb/StreamResultWithWriter.java
----------------------------------------------------------------------
diff --git a/core/schema/src/main/java/org/apache/isis/schema/services/jaxb/StreamResultWithWriter.java b/core/schema/src/main/java/org/apache/isis/schema/services/jaxb/StreamResultWithWriter.java
new file mode 100644
index 0000000..c07b49b
--- /dev/null
+++ b/core/schema/src/main/java/org/apache/isis/schema/services/jaxb/StreamResultWithWriter.java
@@ -0,0 +1,45 @@
+/**
+ *  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.
+ */
+package org.apache.isis.schema.services.jaxb;
+
+import java.io.StringWriter;
+
+import javax.xml.transform.stream.StreamResult;
+
+/**
+ * A {@link StreamResult} that contains its own writer.
+ *
+ * <p>
+ *     The point is that the writer is only ever queried lazily AFTER the result has been generated.
+ * </p>
+ */
+class StreamResultWithWriter extends StreamResult {
+    private final StringWriter writer;
+
+    public StreamResultWithWriter() {
+        this(new StringWriter());
+    }
+
+    private StreamResultWithWriter(StringWriter writer) {
+        super(writer);
+        this.writer = writer;
+    }
+
+    public String asString() {
+        return writer.toString();
+    }
+}

http://git-wip-us.apache.org/repos/asf/isis/blob/19cdaaba/core/schema/src/main/java/org/apache/isis/schema/utils/ActionInvocationMementoDtoUtils.java
----------------------------------------------------------------------
diff --git a/core/schema/src/main/java/org/apache/isis/schema/utils/ActionInvocationMementoDtoUtils.java b/core/schema/src/main/java/org/apache/isis/schema/utils/ActionInvocationMementoDtoUtils.java
index 37ac6a1..1314b75 100644
--- a/core/schema/src/main/java/org/apache/isis/schema/utils/ActionInvocationMementoDtoUtils.java
+++ b/core/schema/src/main/java/org/apache/isis/schema/utils/ActionInvocationMementoDtoUtils.java
@@ -133,7 +133,11 @@ public class ActionInvocationMementoDtoUtils {
     //endregion
 
     //region > addArgValue, addArgReference
-    public static boolean addArgValue(final ActionInvocationMementoDto aim, final String parameterName, final Class<?> parameterType, final Object arg) {
+    public static boolean addArgValue(
+            final ActionInvocationMementoDto aim,
+            final String parameterName,
+            final Class<?> parameterType,
+            final Object arg) {
 
         ParamDto paramDto = null;
         if(parameterType == String.class) {
@@ -265,7 +269,9 @@ public class ActionInvocationMementoDtoUtils {
         return setValue(valueDto, returnType, returnVal);
     }
 
-    public static void addReturnReference(final ActionInvocationMementoDto aim, final Bookmark bookmark) {
+    public static void addReturnReference(
+            final ActionInvocationMementoDto aim,
+            final Bookmark bookmark) {
         final ValueDto valueDto = returnValueDtoFor(aim);
         OidDto argValue = asOidDto(bookmark);
         valueDto.setReference(argValue);

http://git-wip-us.apache.org/repos/asf/isis/blob/19cdaaba/core/schema/src/main/java/org/apache/isis/schema/utils/jaxbadapters/PersistentEntityAdapter.java
----------------------------------------------------------------------
diff --git a/core/schema/src/main/java/org/apache/isis/schema/utils/jaxbadapters/PersistentEntityAdapter.java b/core/schema/src/main/java/org/apache/isis/schema/utils/jaxbadapters/PersistentEntityAdapter.java
index 612205b..41d0125 100644
--- a/core/schema/src/main/java/org/apache/isis/schema/utils/jaxbadapters/PersistentEntityAdapter.java
+++ b/core/schema/src/main/java/org/apache/isis/schema/utils/jaxbadapters/PersistentEntityAdapter.java
@@ -41,7 +41,7 @@ public class PersistentEntityAdapter extends XmlAdapter<OidDto, Object> {
         if(domainObject == null) {
             return null;
         }
-        final Bookmark bookmark = bookmarkService.bookmarkFor(domainObject);
+        final Bookmark bookmark = getBookmarkService().bookmarkFor(domainObject);
         final OidDto oidDto = new OidDto();
         oidDto.setObjectIdentifier(bookmark.getIdentifier());
         oidDto.setObjectState(convert(bookmark.getObjectState()));
@@ -58,6 +58,10 @@ public class PersistentEntityAdapter extends XmlAdapter<OidDto, Object> {
         throw new IllegalArgumentException("Not recognized: " + objectState.name());
     }
 
+    protected BookmarkService getBookmarkService() {
+        return bookmarkService;
+    }
+
     @Inject
     BookmarkService bookmarkService;
 }