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 2016/03/14 21:07:41 UTC
[2/2] isis git commit: ISIS-1320: moved ContentMappingService to
applib, updated docs.
ISIS-1320: moved ContentMappingService to applib, updated docs.
Project: http://git-wip-us.apache.org/repos/asf/isis/repo
Commit: http://git-wip-us.apache.org/repos/asf/isis/commit/719bc149
Tree: http://git-wip-us.apache.org/repos/asf/isis/tree/719bc149
Diff: http://git-wip-us.apache.org/repos/asf/isis/diff/719bc149
Branch: refs/heads/master
Commit: 719bc149deaba82c9db97f00ec49dcbdd591c6e7
Parents: cbdc90b
Author: Dan Haywood <da...@haywood-associates.co.uk>
Authored: Mon Mar 14 19:58:09 2016 +0000
Committer: Dan Haywood <da...@haywood-associates.co.uk>
Committed: Mon Mar 14 19:58:09 2016 +0000
----------------------------------------------------------------------
.../src/main/asciidoc/guides/_rgsvc_intro.adoc | 40 ++++---
.../_rgsvc_presentation-layer-internal-spi.adoc | 66 ++++++++++++
.../guides/_rgsvc_presentation-layer-spi.adoc | 82 +++-----------
.../_rgsvc_spi_ContentMappingService.adoc | 107 +++++++++----------
.../guides/_rgsvc_spi_GridSystemService.adoc | 13 ++-
.../guides/_rgsvc_spi_RoutingService.adoc | 10 ++
.../src/main/asciidoc/guides/rgsvc.adoc | 1 +
core/applib/pom.xml | 4 +
.../applib/conmap/ContentMappingService.java | 35 ++++++
core/pom.xml | 6 ++
.../service/conmap/ContentMappingService.java | 7 +-
.../ContentNegotiationServiceXRoDomainType.java | 19 +++-
12 files changed, 241 insertions(+), 149 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/isis/blob/719bc149/adocs/documentation/src/main/asciidoc/guides/_rgsvc_intro.adoc
----------------------------------------------------------------------
diff --git a/adocs/documentation/src/main/asciidoc/guides/_rgsvc_intro.adoc b/adocs/documentation/src/main/asciidoc/guides/_rgsvc_intro.adoc
index 42c02cf..d5153a0 100644
--- a/adocs/documentation/src/main/asciidoc/guides/_rgsvc_intro.adoc
+++ b/adocs/documentation/src/main/asciidoc/guides/_rgsvc_intro.adoc
@@ -14,7 +14,7 @@ The domain services also group into various broad categories. Many support func
system (presentation layer, application layer, core domain, persistence layer); others exist to allow the domain objects
to integrate with other bounded contexts, or provide various metadata (eg for development-time tooling). The diagram below shows these categories:
-image::{_imagesdir}reference-services/categories.png[width="800px",link="{_imagesdir}reference-services/categories.png"]
+image::{_imagesdir}reference-services/categories.png[width="600px",link="{_imagesdir}reference-services/categories.png"]
A small number of domain services can be considered both API and SPI; a good example is the xref:rgsvc.adoc#_rgsvc_api_EmailService[`EmailService`] that is of direct use for domain objects wishing to send out emails,
@@ -45,16 +45,27 @@ public class Customer {
List<String> bcc = Collections.emptyList;
emailService.send(getEmailAddress(), cc, bcc, subject, body);
}
-
public boolean hideSendEmail() {
return !emailService.isConfigured();
}
- @Inject
+ @Inject // <1>
EmailService emailService;
}
----
+<1> Service automatically injected by the framework.
+
+For objects that are already persisted, the service is automatically injected just after the object is rehydrated by
+JDO/DataNucleus.
+
+For transient objects (instantiated programmatically), the (in `1.12.0-SNAPSHOT`)
+xref:rgsvc.adoc#_rgsvc_api_FactoryService[`FactoryService`]'s ``instantiate()`` method (or the deprecated
+xref:rgsvc.adoc#_rgsvc_api_DomainObjectContainer[`DomainObjectContainer`]'s ``newTransientInstance()`` method)
+will automatically inject the services.
+Alternatively the object can be instantiated simply using `new`, then services injected using (`1.12.0-SNAPSHOT)
+xref:rgsvc.adoc#_rgsvc_api_ServiceRegistry[`ServiceRegistry`]'s ``injectServicesInto(...)`` method (or the deprecated
+xref:rgsvc.adoc#_rgsvc_api_DomainObjectContainer[`DomainObjectContainer`]'s ``injectServicesInto(...)`` method).
== Overriding the services
@@ -92,32 +103,27 @@ It's also quite common to want to decorate the existing implementation (ie have
[source,java]
----
-@DomainService(
- nature = NatureOfService.DOMAIN
-)
+@DomainService(nature=NatureOfService.DOMAIN)
@DomainServiceLayout(
- menuOrder = "1" // <1>
+ menuOrder = "1" // <1>
)
public class MyLocaleProvider implements LocaleProvider {
@Override
public Locale getLocale() {
- return getDelegateLocaleProvider().getLocale(); // <2>
+ 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();
+ return Iterables.tryFind(localeProviders, input -> input != this).orNull(); // <3>
}
@Inject
- List<LocaleProvider> localeProviders; // <5>
+ List<LocaleProvider> localeProviders; // <4>
}
----
<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
+<3> find the first implementation that isn't _this_ implementation (else infinite loop!)
+<4> injects all implementations, including this implemenation
+
+The above code could be improved by caching the delegateLocaleProvider once located (rather than searching each time).
http://git-wip-us.apache.org/repos/asf/isis/blob/719bc149/adocs/documentation/src/main/asciidoc/guides/_rgsvc_presentation-layer-internal-spi.adoc
----------------------------------------------------------------------
diff --git a/adocs/documentation/src/main/asciidoc/guides/_rgsvc_presentation-layer-internal-spi.adoc b/adocs/documentation/src/main/asciidoc/guides/_rgsvc_presentation-layer-internal-spi.adoc
new file mode 100644
index 0000000..153c61a
--- /dev/null
+++ b/adocs/documentation/src/main/asciidoc/guides/_rgsvc_presentation-layer-internal-spi.adoc
@@ -0,0 +1,66 @@
+[[_rgsvc_presentation-layer-internal-spi]]
+= Presentation Layer internal SPI
+:Notice: Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements. See the NOTICE file distributed with this work for additional information regarding copyright ownership. The ASF licenses this file to you under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at. http://www.apache.org/licenses/LICENSE-2.0 . Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.
+:_basedir: ../
+:_imagesdir: images/
+
+
+
+Domain service SPIs for the presentation layer influence how the Apache Isis viewers behave. In addition to those defined in the applib, the framework also defines a small number of services that use classes that are internal to the framework.
+
+[WARNING]
+====
+We do not guarantee that link:http://semver.org[semantic versioning] will be honoured for these ASPIs.
+====
+
+
+The table below summarizes the presentation layer non-public SPIs defined by Apache Isis. It also lists their corresponding implementation, either a default implementation provided by Apache Isis itself, or provided by one of the in (non-ASF) link:http://www.isisaddons.org[Isis Addons] modules.
+
+
+
+."Internal" SPI Services
+[cols="3,3,2,2a", options="header"]
+|===
+
+|SPI
+|Maven Module +
+Impl'n (g: a:)
+|Implementation
+|Notes
+
+
+
+
+|xref:rgsvc.adoc#_rgsvc_spi_ContentNegotiationService[`o.a.i.v.ro.` +
+`rendering.service.conneg.` +
+`ContentNegotiationService`]
+|Encodes the algorithm that delegates to any registered xref:rgsvc.adoc#_rgsvc_spi_ContentMappingService[`ContentMappingService`]s.
+|`ContentNegotiationService-` +
+`XRoDomainType` +
+``o.a.i.core`` +
+`isis-core-viewer-restfulobjects-rendering`
+|
+
+
+|xref:rgsvc.adoc#_rgsvc_spi_RepresentationService[`o.a.i.v.ro.` +
+`rendering.service.` +
+`RepresentationService`]
+|Generates the representations, delegating to any registered xref:rgsvc.adoc#_rgsvc_spi_ContentNegotiationService[`ContentNegotiationService`]s.
+|`RepresentationService-` +
+`ForRestfulObjects` +
+``o.a.i.core`` +
+`isis-core-viewer-restfulobjects-rendering`
+|
+
+
+|===
+
+Key:
+
+* `o.a.i.v.ro` is an abbreviation for `org.apache.isis.viewer.restfulobjects`
+
+
+
+
+include::_rgsvc_spi_ContentNegotiationService.adoc[leveloffset=+1]
+include::_rgsvc_spi_RepresentationService.adoc[leveloffset=+1]
http://git-wip-us.apache.org/repos/asf/isis/blob/719bc149/adocs/documentation/src/main/asciidoc/guides/_rgsvc_presentation-layer-spi.adoc
----------------------------------------------------------------------
diff --git a/adocs/documentation/src/main/asciidoc/guides/_rgsvc_presentation-layer-spi.adoc b/adocs/documentation/src/main/asciidoc/guides/_rgsvc_presentation-layer-spi.adoc
index 17c136e..92dd48a 100644
--- a/adocs/documentation/src/main/asciidoc/guides/_rgsvc_presentation-layer-spi.adoc
+++ b/adocs/documentation/src/main/asciidoc/guides/_rgsvc_presentation-layer-spi.adoc
@@ -21,6 +21,17 @@ The table below summarizes the presentation layer SPIs defined by Apache Isis.
|Notes
+|xref:rgsvc.adoc#_rgsvc_spi_ContentMappingService[`o.a.i.applb.` +
+`services.conmap` +
+`ContentMappingService`]
+|(Attempt to) map the returned data into the representation required by the client's HTTP `Accept` header.
+|
+|(Added in `1.12.0-SNAPSHOT`) Replaces (and simplifies) the earlier `ContentMappingService` that defined an SPI using classes internal to the framework. +
++
+No default implementation.
+
+
+
|xref:rgsvc.adoc#_rgsvc_spi_EmailNotificationService[`o.a.i.applib.` +
`services.userreg` +
`EmailNotificationService`]
@@ -158,76 +169,12 @@ Key:
-There are also a number of presentation layer SPIs that use "internal" classes. Semver is not guaranteed for these SPIs.
-
-
-."Internal" SPI Services
-[cols="3,3,2,2a", options="header"]
-|===
-
-|SPI
-|Maven Module +
-Impl'n (g: a:)
-|Implementation
-|Notes
-
-
-|xref:rgsvc.adoc#_rgsvc_spi_ContentMappingService[`o.a.i.v.ro.` +
-`rendering.service.conneg.` +
-`ContentMappingService`]
-|(Attempt to) map the returned data into the representation required by the client's HTTP `Accept` header.
-|
-|No default implementation.
-
-
-
-|xref:rgsvc.adoc#_rgsvc_spi_ContentNegotiationService[`o.a.i.v.ro.` +
-`rendering.service.conneg.` +
-`ContentNegotiationService`]
-|Encodes the algorithm that delegates to any registered xref:rgsvc.adoc#_rgsvc_spi_ContentMappingService[`ContentMappingService`]s.
-|`ContentNegotiationService-` +
-`XRoDomainType` +
-``o.a.i.core`` +
-`isis-core-viewer-restfulobjects-rendering`
-|
-
-
-|xref:rgsvc.adoc#_rgsvc_spi_RepresentationService[`o.a.i.v.ro.` +
-`rendering.service.` +
-`RepresentationService`]
-|Generates the representations, delegating to any registered xref:rgsvc.adoc#_rgsvc_spi_ContentNegotiationService[`ContentNegotiationService`]s.
-|`RepresentationService-` +
-`ForRestfulObjects` +
-``o.a.i.core`` +
-`isis-core-viewer-restfulobjects-rendering`
-|
-
-
-|===
-
-Key:
-
-* `o.a.i.v.ro` is an abbreviation for `org.apache.isis.viewer.restfulobjects`
-
-
+There are also a number of presentation layer SPIs that use internal classes. These can be found in the xref:rgsvc.adoc#_rgsvc_presentation-layer-internal-spi[next chapter].
-
-
-There are also some "internal" SPI services whose definitions depend on the internals of the framework (rather than the applib).
-
-[WARNING]
-====
-We do not guarantee that link:http://semver.org[semantic versioning] will be honoured for these APIs.
-====
-
-
-
include::_rgsvc_spi_ContentMappingService.adoc[leveloffset=+1]
-include::_rgsvc_spi_ContentNegotiationService.adoc[leveloffset=+1]
-
include::_rgsvc_spi_EmailNotificationService.adoc[leveloffset=+1]
include::_rgsvc_spi_ErrorReportingService.adoc[leveloffset=+1]
include::_rgsvc_spi_ExceptionRecognizer.adoc[leveloffset=+1]
@@ -235,9 +182,6 @@ include::_rgsvc_spi_GridSystemService.adoc[leveloffset=+1]
include::_rgsvc_spi_GridLoaderService.adoc[leveloffset=+1]
include::_rgsvc_spi_GridService.adoc[leveloffset=+1]
include::_rgsvc_spi_LocaleProvider.adoc[leveloffset=+1]
-
-include::_rgsvc_spi_RepresentationService.adoc[leveloffset=+1]
-
include::_rgsvc_spi_RoutingService.adoc[leveloffset=+1]
include::_rgsvc_spi_TranslationService.adoc[leveloffset=+1]
include::_rgsvc_spi_TranslationsResolver.adoc[leveloffset=+1]
@@ -245,5 +189,3 @@ include::_rgsvc_spi_UrlEncodingService.adoc[leveloffset=+1]
include::_rgsvc_spi_UserProfileService.adoc[leveloffset=+1]
-
-
http://git-wip-us.apache.org/repos/asf/isis/blob/719bc149/adocs/documentation/src/main/asciidoc/guides/_rgsvc_spi_ContentMappingService.adoc
----------------------------------------------------------------------
diff --git a/adocs/documentation/src/main/asciidoc/guides/_rgsvc_spi_ContentMappingService.adoc b/adocs/documentation/src/main/asciidoc/guides/_rgsvc_spi_ContentMappingService.adoc
index 997ce3e..e755cf5 100644
--- a/adocs/documentation/src/main/asciidoc/guides/_rgsvc_spi_ContentMappingService.adoc
+++ b/adocs/documentation/src/main/asciidoc/guides/_rgsvc_spi_ContentMappingService.adoc
@@ -6,99 +6,94 @@
-The `ContentMappingService` supports the (default implementation of the) xref:rgsvc.adoc#_rgsvc_spi_ContentNegotiationService[`ContentNegotiationService`] allowing the xref:ugvro.adoc#[RestfulObjects viewer] to allow domain objects to be transformed into some other format as specified by the HTTP `Accept` header.
+The `ContentMappingService` supports the (default implementation of the)
+xref:rgsvc.adoc#_rgsvc_spi_ContentNegotiationService[`ContentNegotiationService`] allowing the
+xref:ugvro.adoc#[RestfulObjects viewer] to allow domain objects to be transformed into some other format as specified
+by the HTTP `Accept` header.
See xref:rgsvc.adoc#_rgsvc_spi_ContentNegotiationService[`ContentNegotiationService`] for further discussion.
+[NOTE]
+====
+Unlike most other domain services, the framework (that is, `ContentNegotiationService`) will check _all_ available
+implementations of `ContentMappingService` to convert the domain object to the requested media type, rather than merely
+the first implementation found; in other words it uses the chain-of-responsibility pattern. Services are checked
+in the ordering defined by xref:rgant.adoc#_rgant_DomainServiceLayout_menuOrder[`@DomainServiceLayout#menuOrder()`]).
+The mapped object used will be the first non-`null` result returned by an implementation.
+====
+
== SPI
-The SPI defined by this service is:
+The SPI defined by this service is (as of `1.12.0-SNAPSHOT`):
[source,java]
----
public interface ContentMappingService {
- @Programmatic
Object map(Object object, // <1>
- List<MediaType> acceptableMediaTypes, // <2>
- RepresentationType representationType); // <3>
-
+ List<MediaType> acceptableMediaTypes); // <2>
}
----
<1> typically the input is a domain object (whose structure might change over time), and the output is a DTO (whose structure is guaranteed to be preserved over time)
<2> as per the caller's HTTP `Accept` header
-<3> the representation type required (as per the link:http://restfulobjects.org[Restful Objects spec]).
-[WARNING]
-====
-This is an "internal" SPI, meaning that it uses types that are not part of the Isis applib. We do not guarantee that link:http://semver.org[semantic versioning] will be honoured for these APIs.
-====
+In versions prior to `1.12.0-SNAPSHOT`, this interface resided in a different package, internal to the
+xref:ugvro.adoc[Restful Objects] viewer, and defined a slightly different signature that used an internal enum:
+
+[source,java]
+----
+public interface ContentMappingService {
+ Object map(Object object,
+ List<MediaType> acceptableMediaTypes,
+ RepresentationType representationType); // <1>
+
+}
+
+----
+<1> enum representing the requested representation; only ever take a value of ``DOMAIN_OBJECT`` or ``ACTION_RESULT``.
+
== Implementations
-No default implementations are provided by Apache Isis framework itself. However, the (non-ASF) http://github.com/isisaddons/isis-app-todoapp[Isis addons' todoapp] includes a sample implementation to convert its `ToDoItem`
-entity into (two different versions of) a `ToDoItemDto` (JAXB annotated). This uses the
-link:http://orika-mapper.github.io/orika-docs/intro.html[Orika] mapping library.
+No default implementations are provided by Apache Isis framework itself.
-The source code is:
+However, the (non-ASF) http://github.com/isisaddons/isis-app-todoapp[Isis addons' todoapp] includes a sample implementation to convert its `ToDoItem` entity into a (JAXB annotated) `ToDoItemDto`. The source code is:
[source,java]
----
@DomainService(nature = NatureOfService.DOMAIN)
-public class CustomContentMappingService implements ContentMappingService {
- private MapperFactory mapperFactory; // <1>
- @Programmatic
- @PostConstruct
- public void init() {
- mapperFactory = new DefaultMapperFactory.Builder().build();
- mapperFactory.registerClassMap(
- mapperFactory.classMap(ToDoItem.class, ToDoItemDto.class) // <2>
- .byDefault() // <3>
- .toClassMap());
- mapperFactory.registerClassMap(
- mapperFactory.classMap(Bookmark.class, OidDto.class) // <4>
- .field("identifier", "objectIdentifier") // <5>
- .byDefault() // all other fields are compatible // <6>
- .toClassMap());
- }
- @Programmatic
- @Override // <7>
+public class ContentMappingServiceForToDoItem implements ContentMappingService {
+ @Override
public Object map(
final Object object,
- final List<MediaType> acceptableMediaTypes,
- final RepresentationType representationType) {
+ final List<MediaType> acceptableMediaTypes) {
if(object instanceof ToDoItem) {
- final Bookmark bookmark = bookmarkService.bookmarkFor(object);
- final ToDoItemDto dto =
- mapperFactory.getMapperFacade().map(object, ToDoItemDto.class); // <8>
- final OidDto oidDto =
- mapperFactory.getMapperFacade().map(bookmark, OidDto.class); // <9>
- dto.setOid(oidDto); // <10>
- return dto;
+ for (MediaType acceptableMediaType : acceptableMediaTypes) {
+ final Map<String, String> parameters = acceptableMediaType.getParameters();
+ final String className = parameters.get("x-ro-domain-type");
+ if(className.eqausl(ToDoItemV1_1.class.getName())) {
+ return newToDoItemV1_1((ToDoItem) object);
+ }
+ }
}
return null;
}
- @javax.inject.Inject
- private BookmarkService bookmarkService;
+ private ToDoItemV1_1 newToDoItemV1_1(final ToDoItem toDoItem) {
+ final ToDoItemV1_1 dto = new ToDoItemV1_1();
+ dto.setToDoItem(toDoItem);
+ dto.setDescription(toDoItem.getDescription());
+ ...
+ return dto;
+ }
+ ...
}
----
-<1> registry of known mappings
-<2> how to map `ToDoItem` to `ToDoItemDto` ...
-<3> ... all properties have same name in both source and destination types
-<4> how to map `Bookmark` to `OidDto` ...
-<5> ... this property has a different name
-<6> ... all other properties have same name
-<7> the main API to implement. This implementation ignores the `acceptableMediaTypes` and `representationType`
-<8> map the domain object to the DTO
-<9> and map its oid (by way of the xref:rgsvc.adoc#_rgsvc_api_BookmarkService[`BookmarkService`]
-<10> and perform some additional manual wiring (because domain objects don't _know_ their Oids).
-
-You'll notice that the implementation doesn't actually use the `acceptableMediaTypes` and `representationType` parameters. That's because the calling `ContentNegotiationServiceXRoDomainType` will double check that the returned object is of the correct type (as defined by the `x-ro-domain-type` parameter of the HTTP `Accept` header). Since this (example) todoapp only offers a single mapping, there's therefore no need to for the mapping service to check further.
+
http://git-wip-us.apache.org/repos/asf/isis/blob/719bc149/adocs/documentation/src/main/asciidoc/guides/_rgsvc_spi_GridSystemService.adoc
----------------------------------------------------------------------
diff --git a/adocs/documentation/src/main/asciidoc/guides/_rgsvc_spi_GridSystemService.adoc b/adocs/documentation/src/main/asciidoc/guides/_rgsvc_spi_GridSystemService.adoc
index 68239c5..5aab8ef 100644
--- a/adocs/documentation/src/main/asciidoc/guides/_rgsvc_spi_GridSystemService.adoc
+++ b/adocs/documentation/src/main/asciidoc/guides/_rgsvc_spi_GridSystemService.adoc
@@ -11,10 +11,19 @@ of domain objects. In particular this means being able to return a "normalized"
domain object members into the various regions of the grid) and in providing a default grid if there is no other
metadata available.
-In theory there can be multiple implementations of this service, one per concrete subclass of the applib `Grid` class. Each concrete implementation requires Wicket viewer components capable of interpreting the grid layout.
-
The framework provides a single such grid implementation, namely for Bootstrap3.
+[NOTE]
+====
+Unlike most other domain services, the framework will check _all_ available implementations of `GridSystemService` to
+obtain available grid systems, rather than merely the first implementation found; in other words it uses the
+chain-of-responsibility pattern. Services are called in the order defined by
+xref:rgant.adoc#_rgant_DomainServiceLayout_menuOrder[`@DomainServiceLayout#menuOrder()`]).
+
+Note though that each concrete implementation must also provide corresponding Wicket viewer components capable of
+interpreting the grid layout.
+====
+
== SPI
http://git-wip-us.apache.org/repos/asf/isis/blob/719bc149/adocs/documentation/src/main/asciidoc/guides/_rgsvc_spi_RoutingService.adoc
----------------------------------------------------------------------
diff --git a/adocs/documentation/src/main/asciidoc/guides/_rgsvc_spi_RoutingService.adoc b/adocs/documentation/src/main/asciidoc/guides/_rgsvc_spi_RoutingService.adoc
index 7de9947..3acc8c0 100644
--- a/adocs/documentation/src/main/asciidoc/guides/_rgsvc_spi_RoutingService.adoc
+++ b/adocs/documentation/src/main/asciidoc/guides/_rgsvc_spi_RoutingService.adoc
@@ -23,6 +23,16 @@ For example, return the home page (eg as defined by the xref:rgant.adoc#_rgant_H
Currently the routing service is used only by the xref:ugvw.adoc#[Wicket viewer]; it is ignored by the xref:ugvro.adoc#[Restful Objects] viewer.
+[NOTE]
+====
+Unlike most other domain services, the framework will check _all_ available implementations of
+`RoutingService` to return a route, rather than the first implementation found; in other words it uses the
+chain-of-responsibility pattern. Services are called in the order defined by
+xref:rgant.adoc#_rgant_DomainServiceLayout_menuOrder[`@DomainServiceLayout#menuOrder()`]). The route used will be the
+result of the first implementation checked that declares that it can provide a route.
+====
+
+
== SPI
The SPI defined by this service is:
http://git-wip-us.apache.org/repos/asf/isis/blob/719bc149/adocs/documentation/src/main/asciidoc/guides/rgsvc.adoc
----------------------------------------------------------------------
diff --git a/adocs/documentation/src/main/asciidoc/guides/rgsvc.adoc b/adocs/documentation/src/main/asciidoc/guides/rgsvc.adoc
index d938f0b..4cdcd62 100644
--- a/adocs/documentation/src/main/asciidoc/guides/rgsvc.adoc
+++ b/adocs/documentation/src/main/asciidoc/guides/rgsvc.adoc
@@ -46,6 +46,7 @@ for Apache Isis and contribute back to the project)
include::_rgsvc_intro.adoc[leveloffset=+1]
include::_rgsvc_presentation-layer-spi.adoc[leveloffset=+1]
+include::_rgsvc_presentation-layer-internal-spi.adoc[leveloffset=+1]
include::_rgsvc_application-layer-api.adoc[leveloffset=+1]
include::_rgsvc_application-layer-spi.adoc[leveloffset=+1]
include::_rgsvc_core-domain-api.adoc[leveloffset=+1]
http://git-wip-us.apache.org/repos/asf/isis/blob/719bc149/core/applib/pom.xml
----------------------------------------------------------------------
diff --git a/core/applib/pom.xml b/core/applib/pom.xml
index 757908c..243e5f8 100644
--- a/core/applib/pom.xml
+++ b/core/applib/pom.xml
@@ -105,6 +105,10 @@
<groupId>org.apache.geronimo.specs</groupId>
<artifactId>geronimo-jcdi_1.0_spec</artifactId>
</dependency>
+ <dependency>
+ <groupId>org.jboss.spec.javax.ws.rs</groupId>
+ <artifactId>jboss-jaxrs-api_2.0_spec</artifactId>
+ </dependency>
<!-- DataNucleus' standard JDO support -->
<dependency>
http://git-wip-us.apache.org/repos/asf/isis/blob/719bc149/core/applib/src/main/java/org/apache/isis/applib/conmap/ContentMappingService.java
----------------------------------------------------------------------
diff --git a/core/applib/src/main/java/org/apache/isis/applib/conmap/ContentMappingService.java b/core/applib/src/main/java/org/apache/isis/applib/conmap/ContentMappingService.java
new file mode 100644
index 0000000..d577dfb
--- /dev/null
+++ b/core/applib/src/main/java/org/apache/isis/applib/conmap/ContentMappingService.java
@@ -0,0 +1,35 @@
+/*
+ * 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.conmap;
+
+import java.util.List;
+
+import javax.ws.rs.core.MediaType;
+
+import org.apache.isis.applib.annotation.Programmatic;
+
+public interface ContentMappingService {
+
+ /**
+ * Typically for mapping from a domain object to a DTO.
+ */
+ @Programmatic
+ Object map(Object object, final List<MediaType> acceptableMediaTypes);
+
+}
http://git-wip-us.apache.org/repos/asf/isis/blob/719bc149/core/pom.xml
----------------------------------------------------------------------
diff --git a/core/pom.xml b/core/pom.xml
index f1181b6..1e09119 100644
--- a/core/pom.xml
+++ b/core/pom.xml
@@ -178,6 +178,7 @@
<javax-mail.version>1.4.7</javax-mail.version>
+ <jboss-jaxrs-api_2.0_spec.version>1.0.0.Final</jboss-jaxrs-api_2.0_spec.version>
</properties>
<scm>
@@ -1876,6 +1877,11 @@ ${license.additional-notes}
<version>${geronimo-jcdi_1.0_spec.version}</version>
</dependency>
+ <dependency>
+ <groupId>org.jboss.spec.javax.ws.rs</groupId>
+ <artifactId>jboss-jaxrs-api_2.0_spec</artifactId>
+ <version>${jboss-jaxrs-api_2.0_spec.version}</version>
+ </dependency>
<!-- javax APIs -->
http://git-wip-us.apache.org/repos/asf/isis/blob/719bc149/core/viewer-restfulobjects-rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/service/conmap/ContentMappingService.java
----------------------------------------------------------------------
diff --git a/core/viewer-restfulobjects-rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/service/conmap/ContentMappingService.java b/core/viewer-restfulobjects-rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/service/conmap/ContentMappingService.java
index cb69f98..b4585d7 100644
--- a/core/viewer-restfulobjects-rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/service/conmap/ContentMappingService.java
+++ b/core/viewer-restfulobjects-rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/service/conmap/ContentMappingService.java
@@ -25,11 +25,16 @@ import javax.ws.rs.core.MediaType;
import org.apache.isis.applib.annotation.Programmatic;
import org.apache.isis.viewer.restfulobjects.applib.RepresentationType;
+/**
+ * @deprecated - replaced by simplified version, {@link org.apache.isis.applib.conmap.ContentMappingService}, in the applib.
+ */
+@Deprecated
public interface ContentMappingService {
/**
- * Typically for mapping from a domain object to a DTO.
+ * @deprecated - replaced by simplified version, {@link org.apache.isis.applib.conmap.ContentMappingService#map(Object, List)}, in the applib.
*/
+ @Deprecated
@Programmatic
Object map(Object object, final List<MediaType> acceptableMediaTypes, final RepresentationType representationType);
http://git-wip-us.apache.org/repos/asf/isis/blob/719bc149/core/viewer-restfulobjects-rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/service/conneg/ContentNegotiationServiceXRoDomainType.java
----------------------------------------------------------------------
diff --git a/core/viewer-restfulobjects-rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/service/conneg/ContentNegotiationServiceXRoDomainType.java b/core/viewer-restfulobjects-rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/service/conneg/ContentNegotiationServiceXRoDomainType.java
index 6905cd7..06914fd 100644
--- a/core/viewer-restfulobjects-rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/service/conneg/ContentNegotiationServiceXRoDomainType.java
+++ b/core/viewer-restfulobjects-rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/service/conneg/ContentNegotiationServiceXRoDomainType.java
@@ -20,6 +20,7 @@ package org.apache.isis.viewer.restfulobjects.rendering.service.conneg;
import java.util.List;
+import javax.inject.Inject;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
@@ -140,15 +141,22 @@ public class ContentNegotiationServiceXRoDomainType extends ContentNegotiationSe
}
/**
- * Delegates to any {@link ContentMappingService}s.
+ * Delegates to either the applib {@link org.apache.isis.applib.conmap.ContentMappingService}, else the
+ * original non-applib {@link ContentMappingService}.
*/
protected Object map(
final Object domainObject,
final List<MediaType> acceptableMediaTypes,
final RepresentationType representationType) {
- final Iterable<ContentMappingService> contentMappingServices = container.lookupServices(ContentMappingService.class);
- for (ContentMappingService contentMappingService : contentMappingServices) {
+ for (org.apache.isis.applib.conmap.ContentMappingService contentMappingService : contentMappingServices) {
+ Object mappedObject = contentMappingService.map(domainObject, acceptableMediaTypes);
+ if(mappedObject != null) {
+ return mappedObject;
+ }
+ }
+
+ for (ContentMappingService contentMappingService : legacyContentMappingServices) {
Object mappedObject = contentMappingService.map(domainObject, acceptableMediaTypes, representationType);
if(mappedObject != null) {
return mappedObject;
@@ -158,4 +166,9 @@ public class ContentNegotiationServiceXRoDomainType extends ContentNegotiationSe
return domainObject;
}
+ @Inject
+ List<org.apache.isis.applib.conmap.ContentMappingService> contentMappingServices;
+
+ @Inject
+ List<ContentMappingService> legacyContentMappingServices;
}