You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@isis.apache.org by da...@apache.org on 2015/12/01 08:26:24 UTC

[1/5] isis git commit: ISIS-1274: started with new ContentNegotiationService

Repository: isis
Updated Branches:
  refs/heads/master 587a8bd62 -> 3271f0e33


ISIS-1274: started with new ContentNegotiationService


Project: http://git-wip-us.apache.org/repos/asf/isis/repo
Commit: http://git-wip-us.apache.org/repos/asf/isis/commit/0bd001f9
Tree: http://git-wip-us.apache.org/repos/asf/isis/tree/0bd001f9
Diff: http://git-wip-us.apache.org/repos/asf/isis/diff/0bd001f9

Branch: refs/heads/master
Commit: 0bd001f9263a5adf0e8cd3ce76407dc1a2cefe9c
Parents: 587a8bd
Author: Dan Haywood <da...@haywood-associates.co.uk>
Authored: Sun Nov 29 12:42:51 2015 +0000
Committer: Dan Haywood <da...@haywood-associates.co.uk>
Committed: Sun Nov 29 12:43:12 2015 +0000

----------------------------------------------------------------------
 .../ContentNegotiationServiceAbstract.java      |  20 +++
 .../ContentNegotiationServiceSimplified.java    | 121 +++++++++++++++++++
 2 files changed, 141 insertions(+)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/isis/blob/0bd001f9/core/viewer-restfulobjects-rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/service/conneg/ContentNegotiationServiceAbstract.java
----------------------------------------------------------------------
diff --git a/core/viewer-restfulobjects-rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/service/conneg/ContentNegotiationServiceAbstract.java b/core/viewer-restfulobjects-rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/service/conneg/ContentNegotiationServiceAbstract.java
index 16cebe6..936ed73 100644
--- a/core/viewer-restfulobjects-rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/service/conneg/ContentNegotiationServiceAbstract.java
+++ b/core/viewer-restfulobjects-rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/service/conneg/ContentNegotiationServiceAbstract.java
@@ -18,11 +18,14 @@
  */
 package org.apache.isis.viewer.restfulobjects.rendering.service.conneg;
 
+import java.util.List;
 import java.util.Map;
+import java.util.Objects;
 
 import javax.annotation.PostConstruct;
 import javax.annotation.PreDestroy;
 import javax.inject.Inject;
+import javax.ws.rs.core.MediaType;
 import javax.ws.rs.core.Response;
 import javax.xml.bind.annotation.XmlRootElement;
 
@@ -30,6 +33,7 @@ import org.apache.isis.applib.DomainObjectContainer;
 import org.apache.isis.applib.annotation.Programmatic;
 import org.apache.isis.core.commons.factory.InstanceUtil;
 import org.apache.isis.core.metamodel.adapter.ObjectAdapter;
+import org.apache.isis.viewer.restfulobjects.applib.RepresentationType;
 import org.apache.isis.viewer.restfulobjects.applib.client.RestfulResponse;
 import org.apache.isis.viewer.restfulobjects.rendering.RestfulObjectsApplicationException;
 import org.apache.isis.viewer.restfulobjects.rendering.domainobjects.ObjectAndAction;
@@ -125,6 +129,22 @@ public abstract class ContentNegotiationServiceAbstract implements ContentNegoti
                     xRoDomainType, domainObject.getClass().getName());
         }
     }
+
+    protected boolean canAccept(
+            final RepresentationType representationType,
+            final List<MediaType> acceptableMediaTypes,
+            final String profileValue) {
+        for (MediaType mediaType : acceptableMediaTypes) {
+            if(representationType.matchesJsonProfile(mediaType)) {
+                final String paramValue = mediaType.getParameters().get("profile");
+                if (Objects.equals(paramValue, profileValue)) {
+                    return true;
+                }
+            }
+        }
+        return false;
+    }
+
     //endregion
 
     @Inject

http://git-wip-us.apache.org/repos/asf/isis/blob/0bd001f9/core/viewer-restfulobjects-rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/service/conneg/ContentNegotiationServiceSimplified.java
----------------------------------------------------------------------
diff --git a/core/viewer-restfulobjects-rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/service/conneg/ContentNegotiationServiceSimplified.java b/core/viewer-restfulobjects-rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/service/conneg/ContentNegotiationServiceSimplified.java
new file mode 100644
index 0000000..1d95e57
--- /dev/null
+++ b/core/viewer-restfulobjects-rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/service/conneg/ContentNegotiationServiceSimplified.java
@@ -0,0 +1,121 @@
+/*
+ *  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.viewer.restfulobjects.rendering.service.conneg;
+
+import java.text.DateFormat;
+import java.text.SimpleDateFormat;
+import java.util.List;
+
+import javax.inject.Inject;
+import javax.ws.rs.core.MediaType;
+import javax.ws.rs.core.Response;
+
+import org.apache.isis.applib.DomainObjectContainer;
+import org.apache.isis.applib.annotation.Programmatic;
+import org.apache.isis.applib.annotation.Where;
+import org.apache.isis.core.metamodel.adapter.ObjectAdapter;
+import org.apache.isis.core.metamodel.adapter.version.Version;
+import org.apache.isis.core.metamodel.consent.Consent;
+import org.apache.isis.core.metamodel.consent.InteractionInitiatedBy;
+import org.apache.isis.core.metamodel.spec.feature.Contributed;
+import org.apache.isis.core.metamodel.spec.feature.OneToOneAssociation;
+import org.apache.isis.viewer.restfulobjects.applib.JsonRepresentation;
+import org.apache.isis.viewer.restfulobjects.applib.RepresentationType;
+import org.apache.isis.viewer.restfulobjects.rendering.Caching;
+import org.apache.isis.viewer.restfulobjects.rendering.Responses;
+import org.apache.isis.viewer.restfulobjects.rendering.domainobjects.DomainObjectReprRenderer;
+import org.apache.isis.viewer.restfulobjects.rendering.domainobjects.ObjectAndAction;
+import org.apache.isis.viewer.restfulobjects.rendering.domainobjects.ObjectAndActionInvocation;
+import org.apache.isis.viewer.restfulobjects.rendering.domainobjects.ObjectAndCollection;
+import org.apache.isis.viewer.restfulobjects.rendering.domainobjects.ObjectAndProperty;
+import org.apache.isis.viewer.restfulobjects.rendering.service.RepresentationService;
+
+public class ContentNegotiationServiceSimplified extends ContentNegotiationServiceAbstract {
+
+    private static final DateFormat ETAG_FORMAT = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSZ");
+
+    private static final String ACCEPT_OBJECT = "urn:org.apache.isis:repr-types/object/v1";
+
+    public Response.ResponseBuilder buildResponse(
+            final RepresentationService.Context2 renderContext2,
+            final ObjectAdapter objectAdapter) {
+
+        final RepresentationType representationType = RepresentationType.DOMAIN_OBJECT;
+        final List<MediaType> acceptableMediaTypes = renderContext2.getAcceptableMediaTypes();
+
+        boolean canAccept = canAccept(representationType, acceptableMediaTypes, ACCEPT_OBJECT);
+        if(!canAccept) {
+            return null;
+        }
+
+        JsonRepresentation representation = JsonRepresentation.newMap();
+
+        List<OneToOneAssociation> properties = objectAdapter.getSpecification().getProperties(Contributed.INCLUDED);
+        for (OneToOneAssociation property : properties) {
+            Consent visibility = property.isVisible(objectAdapter, InteractionInitiatedBy.USER, Where.ANYWHERE);
+            if(visibility.isAllowed()) {
+
+            }
+        }
+
+        final DomainObjectReprRenderer renderer = new DomainObjectReprRenderer(renderContext2, null, representation);
+
+        renderer.with(objectAdapter).includesSelf();
+
+        final Response.ResponseBuilder responseBuilder = Responses.ofOk(renderer, Caching.NONE);
+
+        final Version version = objectAdapter.getVersion();
+        if (version != null && version.getTime() != null) {
+            responseBuilder.tag(ETAG_FORMAT.format(version.getTime()));
+        }
+
+        return null;
+    }
+
+    @Programmatic
+    public Response.ResponseBuilder buildResponse(
+            final RepresentationService.Context2 renderContext2,
+            final ObjectAndProperty objectAndProperty)  {
+        return null;
+    }
+
+    @Programmatic
+    public Response.ResponseBuilder buildResponse(
+            final RepresentationService.Context2 renderContext2,
+            final ObjectAndCollection objectAndCollection) {
+        return null;
+    }
+
+    @Programmatic
+    public Response.ResponseBuilder buildResponse(
+            final RepresentationService.Context2 renderContext2,
+            final ObjectAndAction objectAndAction)  {
+        return null;
+    }
+
+    @Programmatic
+    public Response.ResponseBuilder buildResponse(
+            final RepresentationService.Context2 renderContext2,
+            final ObjectAndActionInvocation objectAndActionInvocation) {
+        return null;
+    }
+
+    @Inject
+    protected DomainObjectContainer container;
+}


[5/5] isis git commit: ISIS-1274: merging in feature branch.

Posted by da...@apache.org.
ISIS-1274: merging in feature branch.


Project: http://git-wip-us.apache.org/repos/asf/isis/repo
Commit: http://git-wip-us.apache.org/repos/asf/isis/commit/3271f0e3
Tree: http://git-wip-us.apache.org/repos/asf/isis/tree/3271f0e3
Diff: http://git-wip-us.apache.org/repos/asf/isis/diff/3271f0e3

Branch: refs/heads/master
Commit: 3271f0e33e4dfdb0aa5d04fa84c69dfb50c81286
Parents: 64c6cee 5f46ef1
Author: Dan Haywood <da...@haywood-associates.co.uk>
Authored: Tue Dec 1 07:20:51 2015 +0000
Committer: Dan Haywood <da...@haywood-associates.co.uk>
Committed: Tue Dec 1 07:20:51 2015 +0000

----------------------------------------------------------------------
 .../ActionResultRepresentation.java             |   3 +-
 .../rendering/RendererContext2.java             |   2 +-
 .../rendering/ReprRendererAbstract.java         |   6 +-
 .../restfulobjects/rendering/Responses.java     |  57 ++-
 .../AbstractObjectMemberReprRenderer.java       |   2 +-
 .../domainobjects/ActionResultReprRenderer.java | 107 ++---
 .../domainobjects/DomainObjectReprRenderer.java |  26 +-
 .../domainobjects/ListReprRenderer.java         |   8 +-
 .../domainobjects/ObjectActionReprRenderer.java |   9 +-
 .../ObjectAndActionInvocation.java              |  31 ++
 .../ObjectCollectionReprRenderer.java           |  19 +-
 .../ObjectPropertyReprRenderer.java             |  12 +-
 .../domainobjects/ScalarValueReprRenderer.java  |   5 +-
 .../AbstractTypeFeatureReprRenderer.java        |   4 +-
 .../domaintypes/DomainTypeReprRenderer.java     |   6 +-
 ...NegotiationServiceForRestfulObjectsV1_0.java | 173 --------
 .../service/RepresentationService.java          |   8 +-
 .../RepresentationServiceForRestfulObjects.java |   1 +
 .../ContentNegotiationServiceAbstract.java      |  16 +
 ...NegotiationServiceForRestfulObjectsV1_0.java | 260 ++++++++++++
 .../ContentNegotiationServiceSimplified.java    | 402 +++++++++++++++++++
 .../restfulobjects/server/ResourceContext.java  |  26 +-
 .../server/resources/DomainResourceHelper.java  |   6 +-
 23 files changed, 904 insertions(+), 285 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/isis/blob/3271f0e3/core/viewer-restfulobjects-server/src/main/java/org/apache/isis/viewer/restfulobjects/server/resources/DomainResourceHelper.java
----------------------------------------------------------------------


[4/5] isis git commit: ISIS-1273: RO rendering of collection not showing details.

Posted by da...@apache.org.
ISIS-1273: RO rendering of collection not showing details.

Also: fix to NPE when attempt to render collection as RO.


Project: http://git-wip-us.apache.org/repos/asf/isis/repo
Commit: http://git-wip-us.apache.org/repos/asf/isis/commit/64c6cee1
Tree: http://git-wip-us.apache.org/repos/asf/isis/tree/64c6cee1
Diff: http://git-wip-us.apache.org/repos/asf/isis/diff/64c6cee1

Branch: refs/heads/master
Commit: 64c6cee14fe868011c9e78d01542c679d4c0744b
Parents: 587a8bd
Author: Dan Haywood <da...@haywood-associates.co.uk>
Authored: Tue Dec 1 07:20:28 2015 +0000
Committer: Dan Haywood <da...@haywood-associates.co.uk>
Committed: Tue Dec 1 07:20:28 2015 +0000

----------------------------------------------------------------------
 .../domainobjects/AbstractObjectMemberReprRenderer.java          | 3 ++-
 .../restfulobjects/server/resources/DomainResourceHelper.java    | 4 ++--
 2 files changed, 4 insertions(+), 3 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/isis/blob/64c6cee1/core/viewer-restfulobjects-rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/domainobjects/AbstractObjectMemberReprRenderer.java
----------------------------------------------------------------------
diff --git a/core/viewer-restfulobjects-rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/domainobjects/AbstractObjectMemberReprRenderer.java b/core/viewer-restfulobjects-rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/domainobjects/AbstractObjectMemberReprRenderer.java
index 474db32..c76aae7 100644
--- a/core/viewer-restfulobjects-rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/domainobjects/AbstractObjectMemberReprRenderer.java
+++ b/core/viewer-restfulobjects-rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/domainobjects/AbstractObjectMemberReprRenderer.java
@@ -78,7 +78,7 @@ public abstract class AbstractObjectMemberReprRenderer<R extends ReprRendererAbs
      * <p>
      * Used to determine whether to follow links; only populated for {@link Mode#INLINE inline} Mode.
      */
-    private final String memberId;
+    private String memberId;
     private final Where where;
 
     public AbstractObjectMemberReprRenderer(
@@ -103,6 +103,7 @@ public abstract class AbstractObjectMemberReprRenderer<R extends ReprRendererAbs
         this.objectAdapter = objectAndMember.getObjectAdapter();
         this.objectMember = objectAndMember.getMember();
         this.objectMemberType = MemberType.determineFrom(objectMember);
+        this.memberId = objectMember.getId();
         usingLinkTo(new DomainObjectLinkTo());
 
         return cast(this);

http://git-wip-us.apache.org/repos/asf/isis/blob/64c6cee1/core/viewer-restfulobjects-server/src/main/java/org/apache/isis/viewer/restfulobjects/server/resources/DomainResourceHelper.java
----------------------------------------------------------------------
diff --git a/core/viewer-restfulobjects-server/src/main/java/org/apache/isis/viewer/restfulobjects/server/resources/DomainResourceHelper.java b/core/viewer-restfulobjects-server/src/main/java/org/apache/isis/viewer/restfulobjects/server/resources/DomainResourceHelper.java
index abc56ef..9e0567f 100644
--- a/core/viewer-restfulobjects-server/src/main/java/org/apache/isis/viewer/restfulobjects/server/resources/DomainResourceHelper.java
+++ b/core/viewer-restfulobjects-server/src/main/java/org/apache/isis/viewer/restfulobjects/server/resources/DomainResourceHelper.java
@@ -46,7 +46,7 @@ import org.apache.isis.viewer.restfulobjects.rendering.domainobjects.MemberReprM
 import org.apache.isis.viewer.restfulobjects.rendering.domainobjects.ObjectAdapterLinkTo;
 import org.apache.isis.viewer.restfulobjects.rendering.domainobjects.ObjectAndAction;
 import org.apache.isis.viewer.restfulobjects.rendering.domainobjects.ObjectAndActionInvocation;
-import org.apache.isis.viewer.restfulobjects.rendering.domainobjects.ObjectAndCollection;
+import org.apache.isis.viewer.restfulobjects.rendering.domainobjects.ObjectAndCollection2;
 import org.apache.isis.viewer.restfulobjects.rendering.domainobjects.ObjectAndProperty2;
 import org.apache.isis.viewer.restfulobjects.rendering.service.RepresentationService;
 import org.apache.isis.viewer.restfulobjects.server.ResourceContext;
@@ -270,7 +270,7 @@ public class DomainResourceHelper {
 
         final OneToManyAssociation collection = accessHelper.getCollectionThatIsVisibleForIntent(collectionId, ObjectAdapterAccessHelper.Intent.ACCESS);
 
-        return representationService.collectionDetails(representationServiceContext, new ObjectAndCollection(objectAdapter, collection), memberMode);
+        return representationService.collectionDetails(representationServiceContext, new ObjectAndCollection2(objectAdapter, collection, memberMode), memberMode);
     }
 
 


[2/5] isis git commit: ISIS-1274: object representation now generates a simplified map for the properties. Also puts the original repr under a '11432ro' json-prop. Still working on simplified map of collections

Posted by da...@apache.org.
ISIS-1274: object representation now generates a simplified map for the properties. Also puts the original repr under a '11432ro' json-prop.  Still working on simplified map of collections


Project: http://git-wip-us.apache.org/repos/asf/isis/repo
Commit: http://git-wip-us.apache.org/repos/asf/isis/commit/a4f04eb4
Tree: http://git-wip-us.apache.org/repos/asf/isis/tree/a4f04eb4
Diff: http://git-wip-us.apache.org/repos/asf/isis/diff/a4f04eb4

Branch: refs/heads/master
Commit: a4f04eb461736dfd6acc63d473836535d990eebe
Parents: 0bd001f
Author: Dan Haywood <da...@haywood-associates.co.uk>
Authored: Sun Nov 29 15:26:13 2015 +0000
Committer: Dan Haywood <da...@haywood-associates.co.uk>
Committed: Sun Nov 29 15:26:13 2015 +0000

----------------------------------------------------------------------
 .../rendering/RendererContext2.java             |   2 +-
 .../rendering/ReprRendererAbstract.java         |   6 +-
 .../restfulobjects/rendering/Responses.java     |  40 +++-
 .../AbstractObjectMemberReprRenderer.java       |   5 +-
 .../domainobjects/ActionResultReprRenderer.java |   3 +-
 .../domainobjects/DomainObjectReprRenderer.java |  22 +-
 .../domainobjects/ListReprRenderer.java         |   3 +-
 .../domainobjects/ObjectActionReprRenderer.java |   9 +-
 .../ObjectCollectionReprRenderer.java           |  10 +-
 .../ObjectPropertyReprRenderer.java             |  12 +-
 .../AbstractTypeFeatureReprRenderer.java        |   4 +-
 .../domaintypes/DomainTypeReprRenderer.java     |   6 +-
 ...NegotiationServiceForRestfulObjectsV1_0.java | 173 --------------
 .../service/RepresentationService.java          |   8 +-
 .../RepresentationServiceForRestfulObjects.java |   1 +
 .../ContentNegotiationServiceAbstract.java      |  10 +-
 ...NegotiationServiceForRestfulObjectsV1_0.java | 233 +++++++++++++++++++
 .../ContentNegotiationServiceSimplified.java    |  93 ++++++--
 .../restfulobjects/server/ResourceContext.java  |  26 +--
 .../server/resources/DomainResourceHelper.java  |   6 +-
 20 files changed, 410 insertions(+), 262 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/isis/blob/a4f04eb4/core/viewer-restfulobjects-rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/RendererContext2.java
----------------------------------------------------------------------
diff --git a/core/viewer-restfulobjects-rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/RendererContext2.java b/core/viewer-restfulobjects-rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/RendererContext2.java
index 6c64e15..fb7e596 100644
--- a/core/viewer-restfulobjects-rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/RendererContext2.java
+++ b/core/viewer-restfulobjects-rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/RendererContext2.java
@@ -27,6 +27,6 @@ import javax.ws.rs.core.MediaType;
  */
 public interface RendererContext2 extends RendererContext {
 
-    public List<MediaType> getAcceptableMediaTypes();
+    List<MediaType> getAcceptableMediaTypes();
 
 }

http://git-wip-us.apache.org/repos/asf/isis/blob/a4f04eb4/core/viewer-restfulobjects-rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/ReprRendererAbstract.java
----------------------------------------------------------------------
diff --git a/core/viewer-restfulobjects-rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/ReprRendererAbstract.java b/core/viewer-restfulobjects-rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/ReprRendererAbstract.java
index 6b94aef..f3c2c0c 100644
--- a/core/viewer-restfulobjects-rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/ReprRendererAbstract.java
+++ b/core/viewer-restfulobjects-rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/ReprRendererAbstract.java
@@ -48,7 +48,11 @@ public abstract class ReprRendererAbstract<R extends ReprRendererAbstract<R, T>,
 
     protected boolean includesSelf;
 
-    public ReprRendererAbstract(final RendererContext rendererContext, final LinkFollowSpecs linkFollower, final RepresentationType representationType, final JsonRepresentation representation) {
+    public ReprRendererAbstract(
+            final RendererContext rendererContext,
+            final LinkFollowSpecs linkFollower,
+            final RepresentationType representationType,
+            final JsonRepresentation representation) {
         this.rendererContext = rendererContext;
         this.linkFollower = asProvidedElseCreate(linkFollower);
         this.representationType = representationType;

http://git-wip-us.apache.org/repos/asf/isis/blob/a4f04eb4/core/viewer-restfulobjects-rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/Responses.java
----------------------------------------------------------------------
diff --git a/core/viewer-restfulobjects-rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/Responses.java b/core/viewer-restfulobjects-rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/Responses.java
index e4420c1..0d4ddac 100644
--- a/core/viewer-restfulobjects-rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/Responses.java
+++ b/core/viewer-restfulobjects-rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/Responses.java
@@ -23,6 +23,7 @@ import javax.ws.rs.core.Response;
 import org.joda.time.DateTime;
 import org.joda.time.format.ISODateTimeFormat;
 import org.apache.isis.core.metamodel.adapter.version.Version;
+import org.apache.isis.viewer.restfulobjects.applib.JsonRepresentation;
 import org.apache.isis.viewer.restfulobjects.applib.client.RestfulResponse;
 import org.apache.isis.viewer.restfulobjects.rendering.util.JsonWriterUtil;
 
@@ -34,13 +35,44 @@ public final class Responses {
         return of(RestfulResponse.HttpStatusCode.NO_CONTENT);
     }
 
-    public static Response.ResponseBuilder ofOk(final ReprRenderer<?, ?> renderer, final Caching caching) {
-        return ofOk(renderer, caching, null);
+    public static Response.ResponseBuilder ofOk(
+            final ReprRenderer<?, ?> renderer,
+            final Caching caching) {
+        return ofOk(renderer, caching, null, null);
     }
 
-    public static Response.ResponseBuilder ofOk(final ReprRenderer<?, ?> renderer, final Caching caching, final Version version) {
+    public static Response.ResponseBuilder ofOk(
+            final ReprRenderer<?, ?> renderer,
+            final Caching caching,
+            final JsonRepresentation rootRepresentation) {
+        return ofOk(renderer, caching, null, rootRepresentation);
+    }
+
+    public static Response.ResponseBuilder ofOk(
+            final ReprRenderer<?, ?> renderer,
+            final Caching caching,
+            final Version version) {
+        return ofOk(renderer, caching, version, null);
+    }
+
+    public static Response.ResponseBuilder ofOk(
+            final ReprRenderer<?, ?> renderer,
+            final Caching caching,
+            final Version version,
+            final JsonRepresentation rootRepresentation) {
+
+        final JsonRepresentation representation = renderer.render();
+        // if a rootRepresentation is provided, then the assumption is that the rendered
+        // will be rendering to some submap of the rootRepresentation
+        final JsonRepresentation entityRepresentation =
+                rootRepresentation != null? rootRepresentation : representation;
+
         final MediaType mediaType = renderer.getMediaType();
-        final Response.ResponseBuilder response = of(RestfulResponse.HttpStatusCode.OK).type(mediaType).cacheControl(caching.getCacheControl()).entity(JsonWriterUtil.jsonFor(renderer.render()));
+        final Response.ResponseBuilder response =
+                of(RestfulResponse.HttpStatusCode.OK)
+                    .type(mediaType)
+                    .cacheControl(caching.getCacheControl())
+                    .entity(JsonWriterUtil.jsonFor(entityRepresentation));
         return addLastModifiedAndETagIfAvailable(response, version);
     }
 

http://git-wip-us.apache.org/repos/asf/isis/blob/a4f04eb4/core/viewer-restfulobjects-rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/domainobjects/AbstractObjectMemberReprRenderer.java
----------------------------------------------------------------------
diff --git a/core/viewer-restfulobjects-rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/domainobjects/AbstractObjectMemberReprRenderer.java b/core/viewer-restfulobjects-rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/domainobjects/AbstractObjectMemberReprRenderer.java
index 474db32..4216d58 100644
--- a/core/viewer-restfulobjects-rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/domainobjects/AbstractObjectMemberReprRenderer.java
+++ b/core/viewer-restfulobjects-rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/domainobjects/AbstractObjectMemberReprRenderer.java
@@ -78,7 +78,7 @@ public abstract class AbstractObjectMemberReprRenderer<R extends ReprRendererAbs
      * <p>
      * Used to determine whether to follow links; only populated for {@link Mode#INLINE inline} Mode.
      */
-    private final String memberId;
+    private String memberId;
     private final Where where;
 
     public AbstractObjectMemberReprRenderer(
@@ -103,6 +103,7 @@ public abstract class AbstractObjectMemberReprRenderer<R extends ReprRendererAbs
         this.objectAdapter = objectAndMember.getObjectAdapter();
         this.objectMember = objectAndMember.getMember();
         this.objectMemberType = MemberType.determineFrom(objectMember);
+        this.memberId = objectMember.getId();
         usingLinkTo(new DomainObjectLinkTo());
 
         return cast(this);
@@ -262,7 +263,7 @@ public abstract class AbstractObjectMemberReprRenderer<R extends ReprRendererAbs
         
         // create a temporary map that looks the same as the member map we'll be following
         final JsonRepresentation memberMap = JsonRepresentation.newMap();
-        memberMap.mapPut(getMemberId(), this.representation);
+        memberMap.mapPut(getMemberId(), representation);
         if (membersLinkFollower.matches(memberMap) && detailsLinkFollower.matches(link)) {
             followDetailsLink(link);
         }

http://git-wip-us.apache.org/repos/asf/isis/blob/a4f04eb4/core/viewer-restfulobjects-rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/domainobjects/ActionResultReprRenderer.java
----------------------------------------------------------------------
diff --git a/core/viewer-restfulobjects-rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/domainobjects/ActionResultReprRenderer.java b/core/viewer-restfulobjects-rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/domainobjects/ActionResultReprRenderer.java
index 005e26e..7917a1e 100644
--- a/core/viewer-restfulobjects-rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/domainobjects/ActionResultReprRenderer.java
+++ b/core/viewer-restfulobjects-rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/domainobjects/ActionResultReprRenderer.java
@@ -142,7 +142,8 @@ public class ActionResultReprRenderer extends ReprRendererAbstract<ActionResultR
         {
             // object
             if(returnedAdapter != null) {
-                final DomainObjectReprRenderer renderer = new DomainObjectReprRenderer(rendererContext, null, result);
+                final DomainObjectReprRenderer renderer = new DomainObjectReprRenderer(rendererContext, null, result
+                );
                 
                 renderer.with(returnedAdapter).includesSelf();
                 

http://git-wip-us.apache.org/repos/asf/isis/blob/a4f04eb4/core/viewer-restfulobjects-rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/domainobjects/DomainObjectReprRenderer.java
----------------------------------------------------------------------
diff --git a/core/viewer-restfulobjects-rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/domainobjects/DomainObjectReprRenderer.java b/core/viewer-restfulobjects-rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/domainobjects/DomainObjectReprRenderer.java
index e1d0ac2..95fdd5d 100644
--- a/core/viewer-restfulobjects-rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/domainobjects/DomainObjectReprRenderer.java
+++ b/core/viewer-restfulobjects-rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/domainobjects/DomainObjectReprRenderer.java
@@ -96,7 +96,10 @@ public class DomainObjectReprRenderer extends ReprRendererAbstract<DomainObjectR
     private ObjectAdapter objectAdapter;
     private Mode mode = Mode.REGULAR;
 
-    public DomainObjectReprRenderer(final RendererContext resourceContext, final LinkFollowSpecs linkFollower, final JsonRepresentation representation) {
+    public DomainObjectReprRenderer(
+            final RendererContext resourceContext,
+            final LinkFollowSpecs linkFollower,
+            final JsonRepresentation representation) {
         super(resourceContext, linkFollower, RepresentationType.DOMAIN_OBJECT, representation);
         usingLinkToBuilder(new DomainObjectLinkTo());
     }
@@ -182,7 +185,8 @@ public class DomainObjectReprRenderer extends ReprRendererAbstract<DomainObjectR
 
         final LinkFollowSpecs linkFollower = getLinkFollowSpecs().follow("links");
         if (linkFollower.matches(link)) {
-            final DomainObjectReprRenderer renderer = new DomainObjectReprRenderer(getRendererContext(), linkFollower, JsonRepresentation.newMap());
+            final DomainObjectReprRenderer renderer = new DomainObjectReprRenderer(getRendererContext(), linkFollower, JsonRepresentation.newMap()
+            );
             renderer.with(objectAdapter);
             link.mapPut("value", renderer.render());
         }
@@ -257,7 +261,9 @@ public class DomainObjectReprRenderer extends ReprRendererAbstract<DomainObjectR
 
             final OneToOneAssociation property = (OneToOneAssociation) assoc;
             final LinkFollowSpecs linkFollowerForProp = getLinkFollowSpecs().follow("members[" + property.getId() + "]");
-            final ObjectPropertyReprRenderer renderer = new ObjectPropertyReprRenderer(getRendererContext(), linkFollowerForProp, property.getId(), JsonRepresentation.newMap());
+            final JsonRepresentation propertyRepresentation = JsonRepresentation.newMap();
+            final ObjectPropertyReprRenderer renderer =
+                    new ObjectPropertyReprRenderer(getRendererContext(), linkFollowerForProp, property.getId(), propertyRepresentation);
             renderer.with(new ObjectAndProperty(objectAdapter, property)).usingLinkTo(linkToBuilder);
 
             if (mode.isArgs()) {
@@ -293,7 +299,9 @@ public class DomainObjectReprRenderer extends ReprRendererAbstract<DomainObjectR
 
             final LinkFollowSpecs linkFollowerForColl = getLinkFollowSpecs().follow(
                     "members[" + collection.getId() + "]");
-            final ObjectCollectionReprRenderer renderer = new ObjectCollectionReprRenderer(getRendererContext(), linkFollowerForColl, collection.getId(), JsonRepresentation.newMap());
+            final JsonRepresentation collectionRepresentation = JsonRepresentation.newMap();
+            final ObjectCollectionReprRenderer renderer =
+                    new ObjectCollectionReprRenderer(getRendererContext(), linkFollowerForColl, collection.getId(), collectionRepresentation);
 
             renderer.with(new ObjectAndCollection(objectAdapter, collection)).usingLinkTo(linkToBuilder);
             if(mode.isEventSerialization()) {
@@ -327,7 +335,8 @@ public class DomainObjectReprRenderer extends ReprRendererAbstract<DomainObjectR
         if(objectAdapter.getSpecification().containsDoOpFacet(NotPersistableFacet.class)) {
             return;
         }
-        final DomainObjectReprRenderer renderer = new DomainObjectReprRenderer(getRendererContext(), null, JsonRepresentation.newMap());
+        final DomainObjectReprRenderer renderer = new DomainObjectReprRenderer(getRendererContext(), null, JsonRepresentation.newMap()
+        );
         final JsonRepresentation domainObjectRepr = renderer.with(objectAdapter).asPersistLinkArguments().render();
 
         final String domainType = objectAdapter.getSpecification().getSpecId().asString();
@@ -364,7 +373,8 @@ public class DomainObjectReprRenderer extends ReprRendererAbstract<DomainObjectR
             return;
         }
 
-        final DomainObjectReprRenderer renderer = new DomainObjectReprRenderer(getRendererContext(), null, JsonRepresentation.newMap());
+        final DomainObjectReprRenderer renderer = new DomainObjectReprRenderer(getRendererContext(), null, JsonRepresentation.newMap()
+        );
         final JsonRepresentation domainObjectRepr = renderer.with(objectAdapter).asUpdatePropertiesLinkArguments().render();
 
         if(!getRendererContext().suppressUpdateLink()) {

http://git-wip-us.apache.org/repos/asf/isis/blob/a4f04eb4/core/viewer-restfulobjects-rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/domainobjects/ListReprRenderer.java
----------------------------------------------------------------------
diff --git a/core/viewer-restfulobjects-rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/domainobjects/ListReprRenderer.java b/core/viewer-restfulobjects-rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/domainobjects/ListReprRenderer.java
index 5b8dcc8..0135345 100644
--- a/core/viewer-restfulobjects-rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/domainobjects/ListReprRenderer.java
+++ b/core/viewer-restfulobjects-rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/domainobjects/ListReprRenderer.java
@@ -95,7 +95,8 @@ public class ListReprRenderer extends ReprRendererAbstract<ListReprRenderer, Col
 
             final LinkFollowSpecs linkFollower = getLinkFollowSpecs().follow("value");
             if (linkFollower.matches(linkToObject)) {
-                final DomainObjectReprRenderer renderer = new DomainObjectReprRenderer(getRendererContext(), linkFollower, JsonRepresentation.newMap());
+                final DomainObjectReprRenderer renderer = new DomainObjectReprRenderer(getRendererContext(), linkFollower, JsonRepresentation.newMap()
+                );
                 final JsonRepresentation domainObject = renderer.with(adapter).render();
                 linkToObject.mapPut("value", domainObject);
             }

http://git-wip-us.apache.org/repos/asf/isis/blob/a4f04eb4/core/viewer-restfulobjects-rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/domainobjects/ObjectActionReprRenderer.java
----------------------------------------------------------------------
diff --git a/core/viewer-restfulobjects-rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/domainobjects/ObjectActionReprRenderer.java b/core/viewer-restfulobjects-rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/domainobjects/ObjectActionReprRenderer.java
index 7b5db43..436db7e 100644
--- a/core/viewer-restfulobjects-rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/domainobjects/ObjectActionReprRenderer.java
+++ b/core/viewer-restfulobjects-rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/domainobjects/ObjectActionReprRenderer.java
@@ -43,8 +43,13 @@ public class ObjectActionReprRenderer extends AbstractObjectMemberReprRenderer<O
         this(rendererContext, null, null, JsonRepresentation.newMap());
     }
 
-    public ObjectActionReprRenderer(final RendererContext rendererContext, final LinkFollowSpecs linkFollowSpecs, String actionId, final JsonRepresentation representation) {
-        super(rendererContext, linkFollowSpecs, actionId, RepresentationType.OBJECT_ACTION, representation, Where.OBJECT_FORMS);
+    public ObjectActionReprRenderer(
+            final RendererContext rendererContext,
+            final LinkFollowSpecs linkFollowSpecs,
+            String actionId,
+            final JsonRepresentation representation) {
+        super(rendererContext, linkFollowSpecs, actionId, RepresentationType.OBJECT_ACTION, representation,
+                Where.OBJECT_FORMS);
     }
 
     @Override

http://git-wip-us.apache.org/repos/asf/isis/blob/a4f04eb4/core/viewer-restfulobjects-rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/domainobjects/ObjectCollectionReprRenderer.java
----------------------------------------------------------------------
diff --git a/core/viewer-restfulobjects-rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/domainobjects/ObjectCollectionReprRenderer.java b/core/viewer-restfulobjects-rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/domainobjects/ObjectCollectionReprRenderer.java
index 22de842..c91751f 100644
--- a/core/viewer-restfulobjects-rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/domainobjects/ObjectCollectionReprRenderer.java
+++ b/core/viewer-restfulobjects-rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/domainobjects/ObjectCollectionReprRenderer.java
@@ -46,7 +46,8 @@ public class ObjectCollectionReprRenderer extends AbstractObjectMemberReprRender
             final LinkFollowSpecs linkFollowSpecs,
             final String collectionId,
             final JsonRepresentation representation) {
-        super(rendererContext, linkFollowSpecs, collectionId, RepresentationType.OBJECT_COLLECTION, representation, Where.PARENTED_TABLES);
+        super(rendererContext, linkFollowSpecs, collectionId, RepresentationType.OBJECT_COLLECTION, representation,
+                Where.PARENTED_TABLES);
     }
 
     @Override
@@ -95,7 +96,8 @@ public class ObjectCollectionReprRenderer extends AbstractObjectMemberReprRender
 
             final LinkBuilder valueLinkBuilder = DomainObjectReprRenderer.newLinkToBuilder(rendererContext, Rel.VALUE, elementAdapter);
             if(eagerlyRender) {
-                final DomainObjectReprRenderer renderer = new DomainObjectReprRenderer(getRendererContext(), followHref, JsonRepresentation.newMap());
+                final DomainObjectReprRenderer renderer = new DomainObjectReprRenderer(getRendererContext(), followHref, JsonRepresentation.newMap()
+                );
                 renderer.with(elementAdapter);
                 if(mode.isEventSerialization()) {
                     renderer.asEventSerialization();
@@ -124,7 +126,9 @@ public class ObjectCollectionReprRenderer extends AbstractObjectMemberReprRender
      */
     @Override
     protected void followDetailsLink(final JsonRepresentation detailsLink) {
-        final ObjectCollectionReprRenderer renderer = new ObjectCollectionReprRenderer(getRendererContext(), getLinkFollowSpecs(), null, JsonRepresentation.newMap());
+        final JsonRepresentation representation = JsonRepresentation.newMap();
+        final ObjectCollectionReprRenderer renderer = new ObjectCollectionReprRenderer(getRendererContext(), getLinkFollowSpecs(), null,
+                representation);
         renderer.with(new ObjectAndCollection(objectAdapter, objectMember)).asFollowed();
         detailsLink.mapPut("value", renderer.render());
     }

http://git-wip-us.apache.org/repos/asf/isis/blob/a4f04eb4/core/viewer-restfulobjects-rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/domainobjects/ObjectPropertyReprRenderer.java
----------------------------------------------------------------------
diff --git a/core/viewer-restfulobjects-rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/domainobjects/ObjectPropertyReprRenderer.java b/core/viewer-restfulobjects-rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/domainobjects/ObjectPropertyReprRenderer.java
index 8e77441..bf3f7b7 100644
--- a/core/viewer-restfulobjects-rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/domainobjects/ObjectPropertyReprRenderer.java
+++ b/core/viewer-restfulobjects-rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/domainobjects/ObjectPropertyReprRenderer.java
@@ -54,7 +54,8 @@ public class ObjectPropertyReprRenderer extends AbstractObjectMemberReprRenderer
             final LinkFollowSpecs linkFollower,
             final String propertyId,
             final JsonRepresentation representation) {
-        super(resourceContext, linkFollower, propertyId, RepresentationType.OBJECT_PROPERTY, representation, Where.OBJECT_FORMS);
+        super(resourceContext, linkFollower, propertyId, RepresentationType.OBJECT_PROPERTY, representation,
+                Where.OBJECT_FORMS);
     }
 
     @Override
@@ -116,7 +117,8 @@ public class ObjectPropertyReprRenderer extends AbstractObjectMemberReprRenderer
 
         final RenderFacet renderFacet = objectMember.getFacet(RenderFacet.class);
         boolean eagerlyRender =
-                renderFacet != null && renderFacet.value() == Type.EAGERLY && rendererContext.canEagerlyRender(valueAdapter) || !linkFollower.isTerminated();
+                (renderFacet != null && renderFacet.value() == Type.EAGERLY && rendererContext.canEagerlyRender(valueAdapter))
+                        || (linkFollower != null && !linkFollower.isTerminated());
 
         if(valueAdapter == null) {
             final NullNode value = NullNode.getInstance();
@@ -128,7 +130,8 @@ public class ObjectPropertyReprRenderer extends AbstractObjectMemberReprRenderer
             
             final LinkBuilder valueLinkBuilder = DomainObjectReprRenderer.newLinkToBuilder(rendererContext, Rel.VALUE, valueAdapter).withTitle(title);
             if(eagerlyRender) {
-                final DomainObjectReprRenderer renderer = new DomainObjectReprRenderer(rendererContext, linkFollower, JsonRepresentation.newMap());
+                final DomainObjectReprRenderer renderer = new DomainObjectReprRenderer(rendererContext, linkFollower, JsonRepresentation.newMap()
+                );
                 renderer.with(valueAdapter);
                 if(mode.isEventSerialization()) {
                     renderer.asEventSerialization();
@@ -167,7 +170,8 @@ public class ObjectPropertyReprRenderer extends AbstractObjectMemberReprRenderer
      */
     @Override
     protected void followDetailsLink(final JsonRepresentation detailsLink) {
-        final ObjectPropertyReprRenderer renderer = new ObjectPropertyReprRenderer(getRendererContext(), getLinkFollowSpecs(), null, JsonRepresentation.newMap());
+        final JsonRepresentation representation = JsonRepresentation.newMap();
+        final ObjectPropertyReprRenderer renderer = new ObjectPropertyReprRenderer(getRendererContext(), getLinkFollowSpecs(), null, representation);
         renderer.with(new ObjectAndProperty(objectAdapter, objectMember)).asFollowed();
         detailsLink.mapPut("value", renderer.render());
     }

http://git-wip-us.apache.org/repos/asf/isis/blob/a4f04eb4/core/viewer-restfulobjects-rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/domaintypes/AbstractTypeFeatureReprRenderer.java
----------------------------------------------------------------------
diff --git a/core/viewer-restfulobjects-rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/domaintypes/AbstractTypeFeatureReprRenderer.java b/core/viewer-restfulobjects-rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/domaintypes/AbstractTypeFeatureReprRenderer.java
index a67beb2..61a3684 100644
--- a/core/viewer-restfulobjects-rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/domaintypes/AbstractTypeFeatureReprRenderer.java
+++ b/core/viewer-restfulobjects-rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/domaintypes/AbstractTypeFeatureReprRenderer.java
@@ -16,6 +16,8 @@
  */
 package org.apache.isis.viewer.restfulobjects.rendering.domaintypes;
 
+import com.google.common.base.Strings;
+
 import org.apache.isis.core.metamodel.spec.ObjectSpecification;
 import org.apache.isis.core.metamodel.spec.feature.ObjectFeature;
 import org.apache.isis.viewer.restfulobjects.applib.JsonRepresentation;
@@ -24,8 +26,6 @@ import org.apache.isis.viewer.restfulobjects.rendering.LinkFollowSpecs;
 import org.apache.isis.viewer.restfulobjects.rendering.RendererContext;
 import org.apache.isis.viewer.restfulobjects.rendering.ReprRendererAbstract;
 
-import com.google.common.base.Strings;
-
 public abstract class AbstractTypeFeatureReprRenderer<R extends ReprRendererAbstract<R, ParentSpecAndFeature<T>>, T extends ObjectFeature> extends ReprRendererAbstract<R, ParentSpecAndFeature<T>> {
 
     protected ObjectSpecification objectSpecification;

http://git-wip-us.apache.org/repos/asf/isis/blob/a4f04eb4/core/viewer-restfulobjects-rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/domaintypes/DomainTypeReprRenderer.java
----------------------------------------------------------------------
diff --git a/core/viewer-restfulobjects-rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/domaintypes/DomainTypeReprRenderer.java b/core/viewer-restfulobjects-rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/domaintypes/DomainTypeReprRenderer.java
index fc3e529..26baf69 100644
--- a/core/viewer-restfulobjects-rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/domaintypes/DomainTypeReprRenderer.java
+++ b/core/viewer-restfulobjects-rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/domaintypes/DomainTypeReprRenderer.java
@@ -18,6 +18,9 @@ package org.apache.isis.viewer.restfulobjects.rendering.domaintypes;
 
 import java.util.List;
 
+import com.fasterxml.jackson.databind.node.NullNode;
+import com.google.common.base.Strings;
+
 import org.apache.isis.core.metamodel.spec.ObjectSpecification;
 import org.apache.isis.core.metamodel.spec.feature.Contributed;
 import org.apache.isis.core.metamodel.spec.feature.ObjectAction;
@@ -32,9 +35,6 @@ import org.apache.isis.viewer.restfulobjects.rendering.LinkFollowSpecs;
 import org.apache.isis.viewer.restfulobjects.rendering.RendererContext;
 import org.apache.isis.viewer.restfulobjects.rendering.ReprRendererAbstract;
 
-import com.fasterxml.jackson.databind.node.NullNode;
-import com.google.common.base.Strings;
-
 public class DomainTypeReprRenderer extends ReprRendererAbstract<DomainTypeReprRenderer, ObjectSpecification> {
 
     public static LinkBuilder newLinkToBuilder(final RendererContext resourceContext, final Rel rel, final ObjectSpecification objectSpec) {

http://git-wip-us.apache.org/repos/asf/isis/blob/a4f04eb4/core/viewer-restfulobjects-rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/service/ContentNegotiationServiceForRestfulObjectsV1_0.java
----------------------------------------------------------------------
diff --git a/core/viewer-restfulobjects-rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/service/ContentNegotiationServiceForRestfulObjectsV1_0.java b/core/viewer-restfulobjects-rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/service/ContentNegotiationServiceForRestfulObjectsV1_0.java
deleted file mode 100644
index b6e218a..0000000
--- a/core/viewer-restfulobjects-rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/service/ContentNegotiationServiceForRestfulObjectsV1_0.java
+++ /dev/null
@@ -1,173 +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.viewer.restfulobjects.rendering.service;
-
-import java.text.DateFormat;
-import java.text.SimpleDateFormat;
-import java.util.Map;
-
-import javax.annotation.PostConstruct;
-import javax.annotation.PreDestroy;
-import javax.ws.rs.core.Response;
-import javax.ws.rs.core.Response.ResponseBuilder;
-
-import org.apache.isis.applib.annotation.DomainService;
-import org.apache.isis.applib.annotation.DomainServiceLayout;
-import org.apache.isis.applib.annotation.NatureOfService;
-import org.apache.isis.core.metamodel.adapter.ObjectAdapter;
-import org.apache.isis.core.metamodel.adapter.version.Version;
-import org.apache.isis.viewer.restfulobjects.applib.JsonRepresentation;
-import org.apache.isis.viewer.restfulobjects.rendering.Caching;
-import org.apache.isis.viewer.restfulobjects.rendering.Responses;
-import org.apache.isis.viewer.restfulobjects.rendering.domainobjects.ActionResultReprRenderer;
-import org.apache.isis.viewer.restfulobjects.rendering.domainobjects.DomainObjectReprRenderer;
-import org.apache.isis.viewer.restfulobjects.rendering.domainobjects.ObjectActionReprRenderer;
-import org.apache.isis.viewer.restfulobjects.rendering.domainobjects.ObjectAndAction;
-import org.apache.isis.viewer.restfulobjects.rendering.domainobjects.ObjectAndActionInvocation;
-import org.apache.isis.viewer.restfulobjects.rendering.domainobjects.ObjectAndCollection;
-import org.apache.isis.viewer.restfulobjects.rendering.domainobjects.ObjectAndCollection2;
-import org.apache.isis.viewer.restfulobjects.rendering.domainobjects.ObjectAndProperty;
-import org.apache.isis.viewer.restfulobjects.rendering.domainobjects.ObjectAndProperty2;
-import org.apache.isis.viewer.restfulobjects.rendering.domainobjects.ObjectCollectionReprRenderer;
-import org.apache.isis.viewer.restfulobjects.rendering.domainobjects.ObjectPropertyReprRenderer;
-import org.apache.isis.viewer.restfulobjects.rendering.service.conneg.ContentNegotiationService;
-
-@DomainService(
-        nature = NatureOfService.DOMAIN
-)
-@DomainServiceLayout(
-        menuOrder = "" + Integer.MAX_VALUE // default
-)
-public class ContentNegotiationServiceForRestfulObjectsV1_0 implements ContentNegotiationService {
-
-    private static final DateFormat ETAG_FORMAT = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSZ");
-
-    @PostConstruct
-    public void init(final Map<String, String> properties) {
-
-    }
-
-    @PreDestroy
-    public void shutdown() {
-    }
-
-    @Override
-    public ResponseBuilder buildResponse(
-            final RepresentationService.Context2 renderContext2,
-            final ObjectAdapter objectAdapter) {
-
-        final DomainObjectReprRenderer renderer =
-                new DomainObjectReprRenderer(renderContext2, null, JsonRepresentation.newMap());
-        renderer.with(objectAdapter).includesSelf();
-
-        final ResponseBuilder responseBuilder = Responses.ofOk(renderer, Caching.NONE);
-
-        if(renderContext2 instanceof RepresentationService.Context6) {
-            final RepresentationService.Context6 context6 = (RepresentationService.Context6) renderContext2;
-            final RepresentationService.Intent intent = context6.getIntent();
-            if(intent == RepresentationService.Intent.JUST_CREATED) {
-                responseBuilder.status(Response.Status.CREATED);
-            }
-        }
-
-        final Version version = objectAdapter.getVersion();
-        if (version != null && version.getTime() != null) {
-            responseBuilder.tag(ETAG_FORMAT.format(version.getTime()));
-        }
-
-        return responseBuilder(responseBuilder);
-    }
-
-    @Override
-    public ResponseBuilder buildResponse(
-            final RepresentationService.Context2 renderContext2,
-            final ObjectAndProperty objectAndProperty) {
-
-        final ObjectPropertyReprRenderer renderer = new ObjectPropertyReprRenderer(renderContext2);
-        renderer.with(objectAndProperty)
-                .usingLinkTo(renderContext2.getAdapterLinkTo());
-
-        if(objectAndProperty instanceof ObjectAndProperty2) {
-            final ObjectAndProperty2 objectAndProperty2 = (ObjectAndProperty2) objectAndProperty;
-            renderer
-                .withMemberMode(objectAndProperty2.getMemberReprMode());
-
-        }
-
-        final ResponseBuilder responseBuilder = Responses.ofOk(renderer, Caching.NONE);
-        return responseBuilder;
-    }
-
-    @Override
-    public ResponseBuilder buildResponse(
-            final RepresentationService.Context2 renderContext2,
-            final ObjectAndCollection objectAndCollection) {
-
-        final ObjectCollectionReprRenderer renderer = new ObjectCollectionReprRenderer(renderContext2);
-        renderer.with(objectAndCollection)
-                .usingLinkTo(renderContext2.getAdapterLinkTo());
-
-        if(objectAndCollection instanceof ObjectAndCollection2) {
-            final ObjectAndCollection2 objectAndCollection2 = (ObjectAndCollection2) objectAndCollection;
-
-            renderer.withMemberMode(objectAndCollection2.getMemberReprMode());
-        }
-
-        final ResponseBuilder responseBuilder = Responses.ofOk(renderer, Caching.NONE);
-
-        return responseBuilder(responseBuilder);
-    }
-
-    @Override
-    public ResponseBuilder buildResponse(
-            final RepresentationService.Context2 renderContext2,
-            final ObjectAndAction objectAndAction) {
-
-        final ObjectActionReprRenderer renderer = new ObjectActionReprRenderer(renderContext2);
-        renderer.with(objectAndAction)
-                .usingLinkTo(renderContext2.getAdapterLinkTo())
-                .asStandalone();
-
-        final ResponseBuilder responseBuilder = Responses.ofOk(renderer, Caching.NONE);
-
-        return responseBuilder(responseBuilder);
-    }
-
-    @Override
-    public ResponseBuilder buildResponse(
-            final RepresentationService.Context2 renderContext2,
-            final ObjectAndActionInvocation objectAndActionInvocation) {
-
-        final ActionResultReprRenderer renderer = new ActionResultReprRenderer(renderContext2, objectAndActionInvocation.getSelfLink());
-        renderer.with(objectAndActionInvocation)
-                .using(renderContext2.getAdapterLinkTo());
-
-        final ResponseBuilder responseBuilder = Responses.ofOk(renderer, Caching.NONE);
-        Responses.addLastModifiedAndETagIfAvailable(responseBuilder, objectAndActionInvocation.getObjectAdapter().getVersion());
-
-        return responseBuilder(responseBuilder);
-    }
-
-    /**
-     * For easy subclassing to further customize, eg additional headers
-     */
-    protected ResponseBuilder responseBuilder(final ResponseBuilder responseBuilder) {
-        return responseBuilder;
-    }
-
-
-}

http://git-wip-us.apache.org/repos/asf/isis/blob/a4f04eb4/core/viewer-restfulobjects-rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/service/RepresentationService.java
----------------------------------------------------------------------
diff --git a/core/viewer-restfulobjects-rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/service/RepresentationService.java b/core/viewer-restfulobjects-rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/service/RepresentationService.java
index 1f2e720..f56d1d2 100644
--- a/core/viewer-restfulobjects-rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/service/RepresentationService.java
+++ b/core/viewer-restfulobjects-rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/service/RepresentationService.java
@@ -63,15 +63,15 @@ public interface RepresentationService {
         NOT_APPLICABLE
     }
 
-    /**
-     * @deprecated - use {@link #objectRepresentation(Context, ObjectAdapter, Intent)}.
-     */
-    @Deprecated
     @Programmatic
     Response objectRepresentation(
             Context resourceContext,
             ObjectAdapter objectAdapter);
 
+    /**
+     * @deprecated - use {@link #objectRepresentation(Context, ObjectAdapter)}.
+     */
+    @Deprecated
     @Programmatic
     Response objectRepresentation(
             Context resourceContext,

http://git-wip-us.apache.org/repos/asf/isis/blob/a4f04eb4/core/viewer-restfulobjects-rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/service/RepresentationServiceForRestfulObjects.java
----------------------------------------------------------------------
diff --git a/core/viewer-restfulobjects-rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/service/RepresentationServiceForRestfulObjects.java b/core/viewer-restfulobjects-rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/service/RepresentationServiceForRestfulObjects.java
index 4beba01..51a6689 100644
--- a/core/viewer-restfulobjects-rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/service/RepresentationServiceForRestfulObjects.java
+++ b/core/viewer-restfulobjects-rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/service/RepresentationServiceForRestfulObjects.java
@@ -37,6 +37,7 @@ import org.apache.isis.viewer.restfulobjects.rendering.domainobjects.ObjectAndAc
 import org.apache.isis.viewer.restfulobjects.rendering.domainobjects.ObjectAndCollection;
 import org.apache.isis.viewer.restfulobjects.rendering.domainobjects.ObjectAndProperty;
 import org.apache.isis.viewer.restfulobjects.rendering.service.conneg.ContentNegotiationService;
+import org.apache.isis.viewer.restfulobjects.rendering.service.conneg.ContentNegotiationServiceForRestfulObjectsV1_0;
 
 @DomainService(
         nature = NatureOfService.DOMAIN

http://git-wip-us.apache.org/repos/asf/isis/blob/a4f04eb4/core/viewer-restfulobjects-rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/service/conneg/ContentNegotiationServiceAbstract.java
----------------------------------------------------------------------
diff --git a/core/viewer-restfulobjects-rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/service/conneg/ContentNegotiationServiceAbstract.java b/core/viewer-restfulobjects-rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/service/conneg/ContentNegotiationServiceAbstract.java
index 936ed73..ca7e651 100644
--- a/core/viewer-restfulobjects-rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/service/conneg/ContentNegotiationServiceAbstract.java
+++ b/core/viewer-restfulobjects-rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/service/conneg/ContentNegotiationServiceAbstract.java
@@ -33,7 +33,6 @@ import org.apache.isis.applib.DomainObjectContainer;
 import org.apache.isis.applib.annotation.Programmatic;
 import org.apache.isis.core.commons.factory.InstanceUtil;
 import org.apache.isis.core.metamodel.adapter.ObjectAdapter;
-import org.apache.isis.viewer.restfulobjects.applib.RepresentationType;
 import org.apache.isis.viewer.restfulobjects.applib.client.RestfulResponse;
 import org.apache.isis.viewer.restfulobjects.rendering.RestfulObjectsApplicationException;
 import org.apache.isis.viewer.restfulobjects.rendering.domainobjects.ObjectAndAction;
@@ -131,15 +130,12 @@ public abstract class ContentNegotiationServiceAbstract implements ContentNegoti
     }
 
     protected boolean canAccept(
-            final RepresentationType representationType,
             final List<MediaType> acceptableMediaTypes,
             final String profileValue) {
         for (MediaType mediaType : acceptableMediaTypes) {
-            if(representationType.matchesJsonProfile(mediaType)) {
-                final String paramValue = mediaType.getParameters().get("profile");
-                if (Objects.equals(paramValue, profileValue)) {
-                    return true;
-                }
+            final String paramValue = mediaType.getParameters().get("profile");
+            if (Objects.equals(paramValue, profileValue)) {
+                return true;
             }
         }
         return false;

http://git-wip-us.apache.org/repos/asf/isis/blob/a4f04eb4/core/viewer-restfulobjects-rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/service/conneg/ContentNegotiationServiceForRestfulObjectsV1_0.java
----------------------------------------------------------------------
diff --git a/core/viewer-restfulobjects-rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/service/conneg/ContentNegotiationServiceForRestfulObjectsV1_0.java b/core/viewer-restfulobjects-rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/service/conneg/ContentNegotiationServiceForRestfulObjectsV1_0.java
new file mode 100644
index 0000000..04fe098
--- /dev/null
+++ b/core/viewer-restfulobjects-rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/service/conneg/ContentNegotiationServiceForRestfulObjectsV1_0.java
@@ -0,0 +1,233 @@
+/**
+ *  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.viewer.restfulobjects.rendering.service.conneg;
+
+import java.text.DateFormat;
+import java.text.SimpleDateFormat;
+import java.util.List;
+import java.util.Map;
+
+import javax.annotation.PostConstruct;
+import javax.annotation.PreDestroy;
+import javax.ws.rs.core.MediaType;
+import javax.ws.rs.core.Response;
+import javax.ws.rs.core.Response.ResponseBuilder;
+
+import org.apache.isis.applib.annotation.DomainService;
+import org.apache.isis.applib.annotation.DomainServiceLayout;
+import org.apache.isis.applib.annotation.NatureOfService;
+import org.apache.isis.core.metamodel.adapter.ObjectAdapter;
+import org.apache.isis.core.metamodel.adapter.version.Version;
+import org.apache.isis.viewer.restfulobjects.applib.JsonRepresentation;
+import org.apache.isis.viewer.restfulobjects.applib.RepresentationType;
+import org.apache.isis.viewer.restfulobjects.applib.client.RestfulResponse;
+import org.apache.isis.viewer.restfulobjects.rendering.Caching;
+import org.apache.isis.viewer.restfulobjects.rendering.Responses;
+import org.apache.isis.viewer.restfulobjects.rendering.RestfulObjectsApplicationException;
+import org.apache.isis.viewer.restfulobjects.rendering.domainobjects.ActionResultReprRenderer;
+import org.apache.isis.viewer.restfulobjects.rendering.domainobjects.DomainObjectReprRenderer;
+import org.apache.isis.viewer.restfulobjects.rendering.domainobjects.ObjectActionReprRenderer;
+import org.apache.isis.viewer.restfulobjects.rendering.domainobjects.ObjectAndAction;
+import org.apache.isis.viewer.restfulobjects.rendering.domainobjects.ObjectAndActionInvocation;
+import org.apache.isis.viewer.restfulobjects.rendering.domainobjects.ObjectAndCollection;
+import org.apache.isis.viewer.restfulobjects.rendering.domainobjects.ObjectAndCollection2;
+import org.apache.isis.viewer.restfulobjects.rendering.domainobjects.ObjectAndProperty;
+import org.apache.isis.viewer.restfulobjects.rendering.domainobjects.ObjectAndProperty2;
+import org.apache.isis.viewer.restfulobjects.rendering.domainobjects.ObjectCollectionReprRenderer;
+import org.apache.isis.viewer.restfulobjects.rendering.domainobjects.ObjectPropertyReprRenderer;
+import org.apache.isis.viewer.restfulobjects.rendering.service.RepresentationService;
+
+@DomainService(
+        nature = NatureOfService.DOMAIN
+)
+@DomainServiceLayout(
+        menuOrder = "" + Integer.MAX_VALUE // default
+)
+public class ContentNegotiationServiceForRestfulObjectsV1_0 implements ContentNegotiationService {
+
+    private static final DateFormat ETAG_FORMAT = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSZ");
+
+    @PostConstruct
+    public void init(final Map<String, String> properties) {
+
+    }
+
+    @PreDestroy
+    public void shutdown() {
+    }
+
+
+    @Override
+    public ResponseBuilder buildResponse(
+            final RepresentationService.Context2 renderContext2,
+            final ObjectAdapter objectAdapter) {
+
+        final List<MediaType> list = renderContext2.getAcceptableMediaTypes();
+        ensureCompatibleAcceptHeader(RepresentationType.DOMAIN_OBJECT, list);
+
+        final ResponseBuilder responseBuilder = buildResponseTo(
+                renderContext2, objectAdapter, JsonRepresentation.newMap(), null);
+
+        return responseBuilder(responseBuilder);
+    }
+
+    /**
+     * Not API
+     */
+    ResponseBuilder buildResponseTo(
+            final RepresentationService.Context2 renderContext2,
+            final ObjectAdapter objectAdapter,
+            final JsonRepresentation representation,
+            final JsonRepresentation rootRepresentation) {
+
+        final DomainObjectReprRenderer renderer =
+                new DomainObjectReprRenderer(renderContext2, null, representation);
+        renderer.with(objectAdapter).includesSelf();
+
+        final ResponseBuilder responseBuilder = Responses.ofOk(renderer, Caching.NONE, rootRepresentation);
+
+        if(renderContext2 instanceof RepresentationService.Context6) {
+            final RepresentationService.Context6 context6 = (RepresentationService.Context6) renderContext2;
+            final RepresentationService.Intent intent = context6.getIntent();
+            if(intent == RepresentationService.Intent.JUST_CREATED) {
+                responseBuilder.status(Response.Status.CREATED);
+            }
+        }
+
+        final Version version = objectAdapter.getVersion();
+        if (version != null && version.getTime() != null) {
+            responseBuilder.tag(ETAG_FORMAT.format(version.getTime()));
+        }
+        return responseBuilder;
+    }
+
+    @Override
+    public ResponseBuilder buildResponse(
+            final RepresentationService.Context2 renderContext2,
+            final ObjectAndProperty objectAndProperty) {
+
+        final List<MediaType> list = renderContext2.getAcceptableMediaTypes();
+        ensureCompatibleAcceptHeader(RepresentationType.OBJECT_PROPERTY, list);
+
+        final ObjectPropertyReprRenderer renderer = new ObjectPropertyReprRenderer(renderContext2);
+        renderer.with(objectAndProperty)
+                .usingLinkTo(renderContext2.getAdapterLinkTo());
+
+        if(objectAndProperty instanceof ObjectAndProperty2) {
+            final ObjectAndProperty2 objectAndProperty2 = (ObjectAndProperty2) objectAndProperty;
+            renderer
+                .withMemberMode(objectAndProperty2.getMemberReprMode());
+
+        }
+
+        final ResponseBuilder responseBuilder = Responses.ofOk(renderer, Caching.NONE);
+        return responseBuilder;
+    }
+
+    @Override
+    public ResponseBuilder buildResponse(
+            final RepresentationService.Context2 renderContext2,
+            final ObjectAndCollection objectAndCollection) {
+
+        final List<MediaType> list = renderContext2.getAcceptableMediaTypes();
+        ensureCompatibleAcceptHeader(RepresentationType.OBJECT_COLLECTION, list);
+
+        final ObjectCollectionReprRenderer renderer = new ObjectCollectionReprRenderer(renderContext2);
+        renderer.with(objectAndCollection)
+                .usingLinkTo(renderContext2.getAdapterLinkTo());
+
+        if(objectAndCollection instanceof ObjectAndCollection2) {
+            final ObjectAndCollection2 objectAndCollection2 = (ObjectAndCollection2) objectAndCollection;
+
+            renderer.withMemberMode(objectAndCollection2.getMemberReprMode());
+        }
+
+        final ResponseBuilder responseBuilder = Responses.ofOk(renderer, Caching.NONE);
+
+        return responseBuilder(responseBuilder);
+    }
+
+    @Override
+    public ResponseBuilder buildResponse(
+            final RepresentationService.Context2 renderContext2,
+            final ObjectAndAction objectAndAction) {
+
+        final List<MediaType> list = renderContext2.getAcceptableMediaTypes();
+        ensureCompatibleAcceptHeader(RepresentationType.OBJECT_ACTION, list);
+
+        final ObjectActionReprRenderer renderer = new ObjectActionReprRenderer(renderContext2);
+        renderer.with(objectAndAction)
+                .usingLinkTo(renderContext2.getAdapterLinkTo())
+                .asStandalone();
+
+        final ResponseBuilder responseBuilder = Responses.ofOk(renderer, Caching.NONE);
+
+        return responseBuilder(responseBuilder);
+    }
+
+    @Override
+    public ResponseBuilder buildResponse(
+            final RepresentationService.Context2 renderContext2,
+            final ObjectAndActionInvocation objectAndActionInvocation) {
+
+        final List<MediaType> list = renderContext2.getAcceptableMediaTypes();
+        ensureCompatibleAcceptHeader(RepresentationType.ACTION_RESULT, list);
+
+        final ActionResultReprRenderer renderer = new ActionResultReprRenderer(renderContext2, objectAndActionInvocation.getSelfLink());
+        renderer.with(objectAndActionInvocation)
+                .using(renderContext2.getAdapterLinkTo());
+
+        final ResponseBuilder responseBuilder = Responses.ofOk(renderer, Caching.NONE);
+        Responses.addLastModifiedAndETagIfAvailable(responseBuilder, objectAndActionInvocation.getObjectAdapter().getVersion());
+
+        return responseBuilder(responseBuilder);
+    }
+
+    /**
+     * For easy subclassing to further customize, eg additional headers
+     */
+    protected ResponseBuilder responseBuilder(final ResponseBuilder responseBuilder) {
+        return responseBuilder;
+    }
+
+
+
+    private void ensureCompatibleAcceptHeader(
+            final RepresentationType representationType,
+            final List<MediaType> acceptableMediaTypes) {
+        if (representationType == null) {
+            return;
+        }
+
+        // RestEasy will check the basic media types...
+        // ... so we just need to check the profile paramter
+        final String producedProfile = representationType.getMediaTypeProfile();
+        if(producedProfile != null) {
+            for (MediaType mediaType : acceptableMediaTypes ) {
+                String acceptedProfileValue = mediaType.getParameters().get("profile");
+                if(acceptedProfileValue == null) {
+                    continue;
+                }
+                if(!producedProfile.equals(acceptedProfileValue)) {
+                    throw RestfulObjectsApplicationException.create(RestfulResponse.HttpStatusCode.NOT_ACCEPTABLE);
+                }
+            }
+        }
+    }
+
+
+}

http://git-wip-us.apache.org/repos/asf/isis/blob/a4f04eb4/core/viewer-restfulobjects-rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/service/conneg/ContentNegotiationServiceSimplified.java
----------------------------------------------------------------------
diff --git a/core/viewer-restfulobjects-rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/service/conneg/ContentNegotiationServiceSimplified.java b/core/viewer-restfulobjects-rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/service/conneg/ContentNegotiationServiceSimplified.java
index 1d95e57..7ebddef 100644
--- a/core/viewer-restfulobjects-rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/service/conneg/ContentNegotiationServiceSimplified.java
+++ b/core/viewer-restfulobjects-rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/service/conneg/ContentNegotiationServiceSimplified.java
@@ -18,8 +18,6 @@
  */
 package org.apache.isis.viewer.restfulobjects.rendering.service.conneg;
 
-import java.text.DateFormat;
-import java.text.SimpleDateFormat;
 import java.util.List;
 
 import javax.inject.Inject;
@@ -27,65 +25,109 @@ import javax.ws.rs.core.MediaType;
 import javax.ws.rs.core.Response;
 
 import org.apache.isis.applib.DomainObjectContainer;
+import org.apache.isis.applib.annotation.DomainService;
+import org.apache.isis.applib.annotation.DomainServiceLayout;
+import org.apache.isis.applib.annotation.NatureOfService;
 import org.apache.isis.applib.annotation.Programmatic;
 import org.apache.isis.applib.annotation.Where;
 import org.apache.isis.core.metamodel.adapter.ObjectAdapter;
-import org.apache.isis.core.metamodel.adapter.version.Version;
 import org.apache.isis.core.metamodel.consent.Consent;
 import org.apache.isis.core.metamodel.consent.InteractionInitiatedBy;
 import org.apache.isis.core.metamodel.spec.feature.Contributed;
+import org.apache.isis.core.metamodel.spec.feature.OneToManyAssociation;
 import org.apache.isis.core.metamodel.spec.feature.OneToOneAssociation;
 import org.apache.isis.viewer.restfulobjects.applib.JsonRepresentation;
-import org.apache.isis.viewer.restfulobjects.applib.RepresentationType;
-import org.apache.isis.viewer.restfulobjects.rendering.Caching;
-import org.apache.isis.viewer.restfulobjects.rendering.Responses;
-import org.apache.isis.viewer.restfulobjects.rendering.domainobjects.DomainObjectReprRenderer;
+import org.apache.isis.viewer.restfulobjects.rendering.RendererContext;
 import org.apache.isis.viewer.restfulobjects.rendering.domainobjects.ObjectAndAction;
 import org.apache.isis.viewer.restfulobjects.rendering.domainobjects.ObjectAndActionInvocation;
 import org.apache.isis.viewer.restfulobjects.rendering.domainobjects.ObjectAndCollection;
 import org.apache.isis.viewer.restfulobjects.rendering.domainobjects.ObjectAndProperty;
+import org.apache.isis.viewer.restfulobjects.rendering.domainobjects.ObjectCollectionReprRenderer;
+import org.apache.isis.viewer.restfulobjects.rendering.domainobjects.ObjectPropertyReprRenderer;
 import org.apache.isis.viewer.restfulobjects.rendering.service.RepresentationService;
 
+@DomainService(
+        nature = NatureOfService.DOMAIN
+)
+@DomainServiceLayout(
+        menuOrder = "1500"
+)
 public class ContentNegotiationServiceSimplified extends ContentNegotiationServiceAbstract {
 
-    private static final DateFormat ETAG_FORMAT = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSZ");
-
     private static final String ACCEPT_OBJECT = "urn:org.apache.isis:repr-types/object/v1";
 
+    private ContentNegotiationServiceForRestfulObjectsV1_0 restfulObjectsV1_0 = new ContentNegotiationServiceForRestfulObjectsV1_0();
+
     public Response.ResponseBuilder buildResponse(
             final RepresentationService.Context2 renderContext2,
             final ObjectAdapter objectAdapter) {
 
-        final RepresentationType representationType = RepresentationType.DOMAIN_OBJECT;
         final List<MediaType> acceptableMediaTypes = renderContext2.getAcceptableMediaTypes();
 
-        boolean canAccept = canAccept(representationType, acceptableMediaTypes, ACCEPT_OBJECT);
+        boolean canAccept = canAccept(acceptableMediaTypes, ACCEPT_OBJECT);
         if(!canAccept) {
             return null;
         }
 
-        JsonRepresentation representation = JsonRepresentation.newMap();
+        final InteractionInitiatedBy interactionInitiatedBy =
+                determineInteractionInitiatedByFrom(renderContext2);
+        final Where where = renderContext2.getWhere();
+
+        final JsonRepresentation rootRepresentation = JsonRepresentation.newMap();
 
         List<OneToOneAssociation> properties = objectAdapter.getSpecification().getProperties(Contributed.INCLUDED);
-        for (OneToOneAssociation property : properties) {
-            Consent visibility = property.isVisible(objectAdapter, InteractionInitiatedBy.USER, Where.ANYWHERE);
-            if(visibility.isAllowed()) {
+        for (final OneToOneAssociation property : properties) {
 
+            final Consent visibility = property.isVisible(objectAdapter, interactionInitiatedBy, where);
+            if (!visibility.isAllowed()) {
+                continue;
             }
+
+            final JsonRepresentation propertyRepresentation = JsonRepresentation.newMap();
+            final ObjectPropertyReprRenderer renderer =
+                    new ObjectPropertyReprRenderer(renderContext2, null, property.getId(), propertyRepresentation);
+            renderer.with(new ObjectAndProperty(objectAdapter, property));
+
+            final JsonRepresentation propertyValueRepresentation = renderer.render();
+            rootRepresentation.mapPut(property.getId(), propertyValueRepresentation.getRepresentation("value"));
         }
 
-        final DomainObjectReprRenderer renderer = new DomainObjectReprRenderer(renderContext2, null, representation);
+        List<OneToManyAssociation> collections = objectAdapter.getSpecification().getCollections(Contributed.INCLUDED);
+        for (final OneToManyAssociation collection : collections) {
 
-        renderer.with(objectAdapter).includesSelf();
+            final Consent visibility = collection.isVisible(objectAdapter, interactionInitiatedBy, where);
+            if (!visibility.isAllowed()) {
+                continue;
+            }
 
-        final Response.ResponseBuilder responseBuilder = Responses.ofOk(renderer, Caching.NONE);
+            final JsonRepresentation propertyRepresentation = JsonRepresentation.newMap();
+            final ObjectCollectionReprRenderer renderer =
+                    new ObjectCollectionReprRenderer(renderContext2, null, collection.getId(), propertyRepresentation);
+            renderer.with(new ObjectAndCollection(objectAdapter, collection));
 
-        final Version version = objectAdapter.getVersion();
-        if (version != null && version.getTime() != null) {
-            responseBuilder.tag(ETAG_FORMAT.format(version.getTime()));
+            final JsonRepresentation collectionValueRepresentation = renderer.render();
+            rootRepresentation.mapPut(collection.getId(), collectionValueRepresentation);
         }
 
-        return null;
+
+        final JsonRepresentation $$roRepresentation = JsonRepresentation.newMap();
+        rootRepresentation.mapPut("$$ro", $$roRepresentation);
+
+        final Response.ResponseBuilder responseBuilder =
+                restfulObjectsV1_0.buildResponseTo(
+                        renderContext2, objectAdapter, $$roRepresentation, rootRepresentation);
+
+        return responseBuilder(responseBuilder);
+    }
+
+    private static InteractionInitiatedBy determineInteractionInitiatedByFrom(
+            final RendererContext rendererContext) {
+        if (rendererContext instanceof RepresentationService.Context4) {
+            return ((RepresentationService.Context4) rendererContext).getInteractionInitiatedBy();
+        } else {
+            // fallback
+            return InteractionInitiatedBy.USER;
+        }
     }
 
     @Programmatic
@@ -116,6 +158,13 @@ public class ContentNegotiationServiceSimplified extends ContentNegotiationServi
         return null;
     }
 
+    /**
+     * For easy subclassing to further customize, eg additional headers
+     */
+    protected Response.ResponseBuilder responseBuilder(final Response.ResponseBuilder responseBuilder) {
+        return responseBuilder;
+    }
+
     @Inject
     protected DomainObjectContainer container;
 }

http://git-wip-us.apache.org/repos/asf/isis/blob/a4f04eb4/core/viewer-restfulobjects-server/src/main/java/org/apache/isis/viewer/restfulobjects/server/ResourceContext.java
----------------------------------------------------------------------
diff --git a/core/viewer-restfulobjects-server/src/main/java/org/apache/isis/viewer/restfulobjects/server/ResourceContext.java b/core/viewer-restfulobjects-server/src/main/java/org/apache/isis/viewer/restfulobjects/server/ResourceContext.java
index f739491..a485073 100644
--- a/core/viewer-restfulobjects-server/src/main/java/org/apache/isis/viewer/restfulobjects/server/ResourceContext.java
+++ b/core/viewer-restfulobjects-server/src/main/java/org/apache/isis/viewer/restfulobjects/server/ResourceContext.java
@@ -132,8 +132,9 @@ public class ResourceContext implements RendererContext6 {
     
     void init(final RepresentationType representationType) {
         getQueryStringAsJsonRepr(); // force it to be cached
-        
-        ensureCompatibleAcceptHeader(representationType);
+
+        // previously we checked for compatible accept headers here.
+        // now, though, this is a responsibility of the various ContentNegotiationService implementations
         ensureDomainModelQueryParamSupported();
         
         this.followLinks = Collections.unmodifiableList(getArg(RequestParameter.FOLLOW_LINKS));
@@ -147,27 +148,6 @@ public class ResourceContext implements RendererContext6 {
         }
     }
 
-    private void ensureCompatibleAcceptHeader(final RepresentationType representationType) {
-        if (representationType == null) {
-            return;
-        }
-
-        // RestEasy will check the basic media types...
-        // ... so we just need to check the profile paramter
-        final String producedProfile = representationType.getMediaTypeProfile();
-        if(producedProfile != null) {
-            for (MediaType mediaType : httpHeaders.getAcceptableMediaTypes()) {
-                String acceptedProfileValue = mediaType.getParameters().get("profile");
-                if(acceptedProfileValue == null) {
-                    continue;
-                }
-                if(!producedProfile.equals(acceptedProfileValue)) {
-                    throw RestfulObjectsApplicationException.create(HttpStatusCode.NOT_ACCEPTABLE);
-                }
-            }
-        }
-    }
-
     //endregion
 
     

http://git-wip-us.apache.org/repos/asf/isis/blob/a4f04eb4/core/viewer-restfulobjects-server/src/main/java/org/apache/isis/viewer/restfulobjects/server/resources/DomainResourceHelper.java
----------------------------------------------------------------------
diff --git a/core/viewer-restfulobjects-server/src/main/java/org/apache/isis/viewer/restfulobjects/server/resources/DomainResourceHelper.java b/core/viewer-restfulobjects-server/src/main/java/org/apache/isis/viewer/restfulobjects/server/resources/DomainResourceHelper.java
index abc56ef..9630369 100644
--- a/core/viewer-restfulobjects-server/src/main/java/org/apache/isis/viewer/restfulobjects/server/resources/DomainResourceHelper.java
+++ b/core/viewer-restfulobjects-server/src/main/java/org/apache/isis/viewer/restfulobjects/server/resources/DomainResourceHelper.java
@@ -222,10 +222,7 @@ public class DomainResourceHelper {
     /**
      * Simply delegates to the {@link org.apache.isis.viewer.restfulobjects.rendering.service.RepresentationService} to
      * render a representation of the object.
-     *
-     * @deprecated - use {@link #objectRepresentation(RepresentationService.Intent)}
      */
-    @Deprecated
     public Response objectRepresentation() {
         return representationService
                 .objectRepresentation(representationServiceContext, objectAdapter);
@@ -234,7 +231,10 @@ public class DomainResourceHelper {
     /**
      * Simply delegates to the {@link org.apache.isis.viewer.restfulobjects.rendering.service.RepresentationService} to
      * render a representation of the object.
+     *
+     * @deprecated - use {@link #objectRepresentation()}
      */
+    @Deprecated
     public Response objectRepresentation(final RepresentationService.Intent intent) {
         return representationService
                 .objectRepresentation(representationServiceContext, objectAdapter, intent);


[3/5] isis git commit: ISIS-1274: new simplified Accept header and corresponding returned content type now more-or-less implemented.

Posted by da...@apache.org.
ISIS-1274: new simplified Accept header and corresponding returned content type now more-or-less implemented.

For domain objects, domain object (parented) collections, and actions, can specify an Accept header of 'application/json;profile="urn:org.apache.isis/v1"

This will generate a simplified representation, with the original RO v1.0 representation still available under a '$$ro' property

For collections and actions returning lists, a list is returned rather than a map.  The RO v1.0 representation is available as an object in this list, with a single '$$ro' property.

The caller can distinguish whether a domain object or collection or list has been returned by checking the Content-Type header.  This uses a 'repr-type' parameter to distinguish, so will take the values of either:

- domain object:
   application/json;profile="urn:org.apache.isis/v1";repr-type="object"

- parented collection:
  application/json;profile="urn:org.apache.isis/v1";repr-type="object-collection"

- standalone list (from action):
   application/json;profile="urn:org.apache.isis/v1";repr-type="list"

In addition, the '$$ro' representation can be suppressed completely by using the 'suppress' parameter for the Accept header, eg  application/json;profile="urn:org.apache.isis/v1";suppress="true"


Project: http://git-wip-us.apache.org/repos/asf/isis/repo
Commit: http://git-wip-us.apache.org/repos/asf/isis/commit/5f46ef13
Tree: http://git-wip-us.apache.org/repos/asf/isis/tree/5f46ef13
Diff: http://git-wip-us.apache.org/repos/asf/isis/diff/5f46ef13

Branch: refs/heads/master
Commit: 5f46ef13fa3b427a34e4ab48e4098fe6a1f26f98
Parents: a4f04eb
Author: Dan Haywood <da...@haywood-associates.co.uk>
Authored: Tue Dec 1 06:53:56 2015 +0000
Committer: Dan Haywood <da...@haywood-associates.co.uk>
Committed: Tue Dec 1 06:53:56 2015 +0000

----------------------------------------------------------------------
 .../ActionResultRepresentation.java             |   3 +-
 .../restfulobjects/rendering/Responses.java     |  25 +-
 .../domainobjects/ActionResultReprRenderer.java | 108 +++---
 .../domainobjects/DomainObjectReprRenderer.java |  16 +-
 .../domainobjects/ListReprRenderer.java         |   5 +
 .../ObjectAndActionInvocation.java              |  31 ++
 .../ObjectCollectionReprRenderer.java           |   9 +-
 .../domainobjects/ScalarValueReprRenderer.java  |   5 +-
 .../ContentNegotiationServiceAbstract.java      |   8 +-
 ...NegotiationServiceForRestfulObjectsV1_0.java |  87 +++--
 .../ContentNegotiationServiceSimplified.java    | 358 +++++++++++++++----
 11 files changed, 493 insertions(+), 162 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/isis/blob/5f46ef13/core/viewer-restfulobjects-applib/src/main/java/org/apache/isis/viewer/restfulobjects/applib/domainobjects/ActionResultRepresentation.java
----------------------------------------------------------------------
diff --git a/core/viewer-restfulobjects-applib/src/main/java/org/apache/isis/viewer/restfulobjects/applib/domainobjects/ActionResultRepresentation.java b/core/viewer-restfulobjects-applib/src/main/java/org/apache/isis/viewer/restfulobjects/applib/domainobjects/ActionResultRepresentation.java
index d03a5d6..252ae20 100644
--- a/core/viewer-restfulobjects-applib/src/main/java/org/apache/isis/viewer/restfulobjects/applib/domainobjects/ActionResultRepresentation.java
+++ b/core/viewer-restfulobjects-applib/src/main/java/org/apache/isis/viewer/restfulobjects/applib/domainobjects/ActionResultRepresentation.java
@@ -19,6 +19,7 @@
 package org.apache.isis.viewer.restfulobjects.applib.domainobjects;
 
 import com.fasterxml.jackson.databind.JsonNode;
+
 import org.apache.isis.viewer.restfulobjects.applib.JsonRepresentation;
 
 public class ActionResultRepresentation extends AbstractObjectMemberRepresentation {
@@ -28,7 +29,7 @@ public class ActionResultRepresentation extends AbstractObjectMemberRepresentati
 
         private final String value;
 
-        private ResultType(final String value) {
+        ResultType(final String value) {
             this.value = value;
         }
 

http://git-wip-us.apache.org/repos/asf/isis/blob/5f46ef13/core/viewer-restfulobjects-rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/Responses.java
----------------------------------------------------------------------
diff --git a/core/viewer-restfulobjects-rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/Responses.java b/core/viewer-restfulobjects-rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/Responses.java
index 0d4ddac..e68e250 100644
--- a/core/viewer-restfulobjects-rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/Responses.java
+++ b/core/viewer-restfulobjects-rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/Responses.java
@@ -41,11 +41,14 @@ public final class Responses {
         return ofOk(renderer, caching, null, null);
     }
 
+    /**
+     * @param rootRepresentationIfAny - if specified, is used for entity; otherwise the renderer is used.  The idea is that the renderer will be set up to render to some sub-node of root representation
+     */
     public static Response.ResponseBuilder ofOk(
             final ReprRenderer<?, ?> renderer,
             final Caching caching,
-            final JsonRepresentation rootRepresentation) {
-        return ofOk(renderer, caching, null, rootRepresentation);
+            final JsonRepresentation rootRepresentationIfAny) {
+        return ofOk(renderer, caching, null, rootRepresentationIfAny);
     }
 
     public static Response.ResponseBuilder ofOk(
@@ -55,17 +58,20 @@ public final class Responses {
         return ofOk(renderer, caching, version, null);
     }
 
+    /**
+     * @param rootRepresentationIfAny - if specified, is used for entity; otherwise the renderer is used.  The idea is that the renderer will be set up to render to some sub-node of root representation
+     */
     public static Response.ResponseBuilder ofOk(
             final ReprRenderer<?, ?> renderer,
             final Caching caching,
             final Version version,
-            final JsonRepresentation rootRepresentation) {
+            final JsonRepresentation rootRepresentationIfAny) {
 
         final JsonRepresentation representation = renderer.render();
         // if a rootRepresentation is provided, then the assumption is that the rendered
         // will be rendering to some submap of the rootRepresentation
         final JsonRepresentation entityRepresentation =
-                rootRepresentation != null? rootRepresentation : representation;
+                rootRepresentationIfAny != null? rootRepresentationIfAny : representation;
 
         final MediaType mediaType = renderer.getMediaType();
         final Response.ResponseBuilder response =
@@ -80,7 +86,16 @@ public final class Responses {
         return Response.status(httpStatusCode.getJaxrsStatusType()).type(MediaType.APPLICATION_JSON_TYPE);
     }
 
-    public static Response.ResponseBuilder addLastModifiedAndETagIfAvailable(final Response.ResponseBuilder responseBuilder, final Version version) {
+    public static Response.ResponseBuilder mediaType(
+            final Response.ResponseBuilder responseBuilder,
+            final MediaType mediaType) {
+        responseBuilder.type(mediaType);
+        return responseBuilder;
+    }
+
+    public static Response.ResponseBuilder addLastModifiedAndETagIfAvailable(
+            final Response.ResponseBuilder responseBuilder,
+            final Version version) {
         if (version != null && version.getTime() != null) {
             final Date time = version.getTime();
             responseBuilder.lastModified(time);

http://git-wip-us.apache.org/repos/asf/isis/blob/5f46ef13/core/viewer-restfulobjects-rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/domainobjects/ActionResultReprRenderer.java
----------------------------------------------------------------------
diff --git a/core/viewer-restfulobjects-rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/domainobjects/ActionResultReprRenderer.java b/core/viewer-restfulobjects-rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/domainobjects/ActionResultReprRenderer.java
index 7917a1e..7ebaaec 100644
--- a/core/viewer-restfulobjects-rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/domainobjects/ActionResultReprRenderer.java
+++ b/core/viewer-restfulobjects-rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/domainobjects/ActionResultReprRenderer.java
@@ -20,9 +20,9 @@ import java.util.Collection;
 import java.util.Map;
 
 import com.fasterxml.jackson.databind.node.NullNode;
+
 import org.apache.isis.core.metamodel.adapter.ObjectAdapter;
 import org.apache.isis.core.metamodel.facets.collections.modify.CollectionFacet;
-import org.apache.isis.core.metamodel.facets.object.encodeable.EncodableFacet;
 import org.apache.isis.core.metamodel.spec.ObjectSpecification;
 import org.apache.isis.core.metamodel.spec.feature.ObjectAction;
 import org.apache.isis.viewer.restfulobjects.applib.JsonRepresentation;
@@ -43,17 +43,17 @@ public class ActionResultReprRenderer extends ReprRendererAbstract<ActionResultR
     private JsonRepresentation arguments;
     private ObjectAdapter returnedAdapter;
     private final SelfLink selfLink;
-
+    private ObjectAndActionInvocation objectAndActionInvocation;
 
     public enum SelfLink {
         INCLUDED, EXCLUDED
     }
 
-    public ActionResultReprRenderer(final RendererContext rendererContext, final SelfLink selfLink) {
-        this(rendererContext, null, selfLink, JsonRepresentation.newMap());
-    }
-
-    public ActionResultReprRenderer(final RendererContext rendererContext, final LinkFollowSpecs linkFollower, final SelfLink selfLink, final JsonRepresentation representation) {
+    public ActionResultReprRenderer(
+            final RendererContext rendererContext,
+            final LinkFollowSpecs linkFollower,
+            final SelfLink selfLink,
+            final JsonRepresentation representation) {
         super(rendererContext, linkFollower, RepresentationType.ACTION_RESULT, representation);
         this.selfLink = selfLink;
     }
@@ -61,6 +61,8 @@ public class ActionResultReprRenderer extends ReprRendererAbstract<ActionResultR
     @Override
     public ActionResultReprRenderer with(final ObjectAndActionInvocation objectAndActionInvocation) {
 
+        this.objectAndActionInvocation = objectAndActionInvocation;
+
         objectAdapter = objectAndActionInvocation.getObjectAdapter();
         action = objectAndActionInvocation.getAction();
         arguments = objectAndActionInvocation.getArguments();
@@ -78,6 +80,10 @@ public class ActionResultReprRenderer extends ReprRendererAbstract<ActionResultR
     @Override
     public JsonRepresentation render() {
 
+        if(representation == null) {
+            return null;
+        }
+
         representationWithSelfFor(action, arguments);
 
         addResult(representation);
@@ -88,8 +94,10 @@ public class ActionResultReprRenderer extends ReprRendererAbstract<ActionResultR
     }
 
     private void addResult(final JsonRepresentation representation) {
+
+        final ResultType resultType = objectAndActionInvocation.determineResultType();
         final JsonRepresentation result = JsonRepresentation.newMap();
-        final ResultType resultType = addResultTo(result);
+        addResultTo(resultType, result);
 
         if (!resultType.isVoid()) {
             putResultType(representation, resultType);
@@ -101,55 +109,61 @@ public class ActionResultReprRenderer extends ReprRendererAbstract<ActionResultR
         }
     }
 
-    private ResultType addResultTo(final JsonRepresentation result) {
+    private void addResultTo(
+            final ResultType resultType, final JsonRepresentation representation) {
 
-        final ObjectSpecification returnType = this.action.getReturnType();
+        if(returnedAdapter == null) {
+            return;
+        }
 
-        if (returnType.getCorrespondingClass() == void.class) {
-            // void
-            return ResultType.VOID;
+        final ReprRendererAbstract<?, ?> renderer = buildResultRenderer(resultType, representation);
+        if(renderer != null) {
+            renderer.render();
         }
+    }
 
-        final CollectionFacet collectionFacet = returnType.getFacet(CollectionFacet.class);
-        if (collectionFacet != null) {
-            // collection
+    private ReprRendererAbstract<?, ?> buildResultRenderer(
+            final ResultType resultType,
+            final JsonRepresentation representation) {
 
-            if(returnedAdapter != null) {
+        final ObjectSpecification returnType = this.action.getReturnType();
+
+        switch (resultType) {
+            case VOID:
+                return null;
+
+            case LIST:
+
+                final CollectionFacet collectionFacet = returnType.getFacet(CollectionFacet.class);
                 final Collection<ObjectAdapter> collectionAdapters = collectionFacet.collection(returnedAdapter);
-    
-                final ListReprRenderer renderer = new ListReprRenderer(rendererContext, null, result).withElementRel(Rel.ELEMENT);
-                renderer.with(collectionAdapters).withReturnType(action.getReturnType()).withElementType(returnedAdapter.getElementSpecification());
-    
-                renderer.render();
-            }
-            return ResultType.LIST;
-        }
 
-        final EncodableFacet encodableFacet = returnType.getFacet(EncodableFacet.class);
-        if (encodableFacet != null) {
-            // scalar
+                final ListReprRenderer listReprRenderer =
+                        new ListReprRenderer(rendererContext, null, representation).withElementRel(Rel.ELEMENT);
+                listReprRenderer.with(collectionAdapters)
+                        .withReturnType(action.getReturnType())
+                        .withElementType(returnedAdapter.getElementSpecification());
 
-            if(returnedAdapter != null) {
-                final ScalarValueReprRenderer renderer = new ScalarValueReprRenderer(rendererContext, null, result);
-                renderer.with(returnedAdapter).withReturnType(action.getReturnType());
-    
-                renderer.render();
-            }
-            return ResultType.SCALAR_VALUE;
+                return listReprRenderer;
 
-        }
+            case SCALAR_VALUE:
 
-        {
-            // object
-            if(returnedAdapter != null) {
-                final DomainObjectReprRenderer renderer = new DomainObjectReprRenderer(rendererContext, null, result
-                );
-                
-                renderer.with(returnedAdapter).includesSelf();
-                
-                renderer.render();
-            }
-            return ResultType.DOMAIN_OBJECT;
+                final ScalarValueReprRenderer scalarValueReprRenderer =
+                        new ScalarValueReprRenderer(rendererContext, null, representation);
+                scalarValueReprRenderer.with(returnedAdapter)
+                        .withReturnType(action.getReturnType());
+
+                return scalarValueReprRenderer;
+
+            case DOMAIN_OBJECT:
+
+                final DomainObjectReprRenderer objectReprRenderer =
+                        new DomainObjectReprRenderer(rendererContext, null, representation);
+
+                objectReprRenderer.with(returnedAdapter).includesSelf();
+
+                return objectReprRenderer;
+            default:
+                throw new IllegalStateException("All possible states of ResultType enumerated; resultType = " + resultType);
         }
     }
 

http://git-wip-us.apache.org/repos/asf/isis/blob/5f46ef13/core/viewer-restfulobjects-rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/domainobjects/DomainObjectReprRenderer.java
----------------------------------------------------------------------
diff --git a/core/viewer-restfulobjects-rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/domainobjects/DomainObjectReprRenderer.java b/core/viewer-restfulobjects-rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/domainobjects/DomainObjectReprRenderer.java
index 95fdd5d..5dc34b8 100644
--- a/core/viewer-restfulobjects-rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/domainobjects/DomainObjectReprRenderer.java
+++ b/core/viewer-restfulobjects-rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/domainobjects/DomainObjectReprRenderer.java
@@ -124,6 +124,10 @@ public class DomainObjectReprRenderer extends ReprRendererAbstract<DomainObjectR
     @Override
     public JsonRepresentation render() {
 
+        if(representation == null) {
+            return null;
+        }
+
         final boolean isService = objectAdapter.getSpecification().isService();
 
         if (!(mode.isArgs())) {
@@ -185,8 +189,8 @@ public class DomainObjectReprRenderer extends ReprRendererAbstract<DomainObjectR
 
         final LinkFollowSpecs linkFollower = getLinkFollowSpecs().follow("links");
         if (linkFollower.matches(link)) {
-            final DomainObjectReprRenderer renderer = new DomainObjectReprRenderer(getRendererContext(), linkFollower, JsonRepresentation.newMap()
-            );
+            final DomainObjectReprRenderer renderer =
+                    new DomainObjectReprRenderer(getRendererContext(), linkFollower, JsonRepresentation.newMap());
             renderer.with(objectAdapter);
             link.mapPut("value", renderer.render());
         }
@@ -335,8 +339,8 @@ public class DomainObjectReprRenderer extends ReprRendererAbstract<DomainObjectR
         if(objectAdapter.getSpecification().containsDoOpFacet(NotPersistableFacet.class)) {
             return;
         }
-        final DomainObjectReprRenderer renderer = new DomainObjectReprRenderer(getRendererContext(), null, JsonRepresentation.newMap()
-        );
+        final DomainObjectReprRenderer renderer =
+                new DomainObjectReprRenderer(getRendererContext(), null, JsonRepresentation.newMap());
         final JsonRepresentation domainObjectRepr = renderer.with(objectAdapter).asPersistLinkArguments().render();
 
         final String domainType = objectAdapter.getSpecification().getSpecId().asString();
@@ -373,8 +377,8 @@ public class DomainObjectReprRenderer extends ReprRendererAbstract<DomainObjectR
             return;
         }
 
-        final DomainObjectReprRenderer renderer = new DomainObjectReprRenderer(getRendererContext(), null, JsonRepresentation.newMap()
-        );
+        final DomainObjectReprRenderer renderer =
+                new DomainObjectReprRenderer(getRendererContext(), null, JsonRepresentation.newMap());
         final JsonRepresentation domainObjectRepr = renderer.with(objectAdapter).asUpdatePropertiesLinkArguments().render();
 
         if(!getRendererContext().suppressUpdateLink()) {

http://git-wip-us.apache.org/repos/asf/isis/blob/5f46ef13/core/viewer-restfulobjects-rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/domainobjects/ListReprRenderer.java
----------------------------------------------------------------------
diff --git a/core/viewer-restfulobjects-rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/domainobjects/ListReprRenderer.java b/core/viewer-restfulobjects-rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/domainobjects/ListReprRenderer.java
index 0135345..2e837a9 100644
--- a/core/viewer-restfulobjects-rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/domainobjects/ListReprRenderer.java
+++ b/core/viewer-restfulobjects-rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/domainobjects/ListReprRenderer.java
@@ -68,6 +68,11 @@ public class ListReprRenderer extends ReprRendererAbstract<ListReprRenderer, Col
 
     @Override
     public JsonRepresentation render() {
+
+        if(representation == null) {
+            return null;
+        }
+
         addValue();
 
         addLinkToReturnType();

http://git-wip-us.apache.org/repos/asf/isis/blob/5f46ef13/core/viewer-restfulobjects-rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/domainobjects/ObjectAndActionInvocation.java
----------------------------------------------------------------------
diff --git a/core/viewer-restfulobjects-rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/domainobjects/ObjectAndActionInvocation.java b/core/viewer-restfulobjects-rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/domainobjects/ObjectAndActionInvocation.java
index a8c16fb..f009d3f 100644
--- a/core/viewer-restfulobjects-rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/domainobjects/ObjectAndActionInvocation.java
+++ b/core/viewer-restfulobjects-rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/domainobjects/ObjectAndActionInvocation.java
@@ -19,8 +19,12 @@
 package org.apache.isis.viewer.restfulobjects.rendering.domainobjects;
 
 import org.apache.isis.core.metamodel.adapter.ObjectAdapter;
+import org.apache.isis.core.metamodel.facets.collections.modify.CollectionFacet;
+import org.apache.isis.core.metamodel.facets.object.encodeable.EncodableFacet;
+import org.apache.isis.core.metamodel.spec.ObjectSpecification;
 import org.apache.isis.core.metamodel.spec.feature.ObjectAction;
 import org.apache.isis.viewer.restfulobjects.applib.JsonRepresentation;
+import org.apache.isis.viewer.restfulobjects.applib.domainobjects.ActionResultRepresentation;
 
 public class ObjectAndActionInvocation {
 
@@ -62,4 +66,31 @@ public class ObjectAndActionInvocation {
     public ActionResultReprRenderer.SelfLink getSelfLink() {
         return selfLink;
     }
+
+
+    /**
+     * not API
+     */
+    public ActionResultRepresentation.ResultType determineResultType() {
+
+        final ObjectSpecification returnType = this.action.getReturnType();
+
+        if (returnType.getCorrespondingClass() == void.class) {
+            return ActionResultRepresentation.ResultType.VOID;
+        }
+
+        final CollectionFacet collectionFacet = returnType.getFacet(CollectionFacet.class);
+        if (collectionFacet != null) {
+            return ActionResultRepresentation.ResultType.LIST;
+        }
+
+        final EncodableFacet encodableFacet = returnType.getFacet(EncodableFacet.class);
+        if (encodableFacet != null) {
+            return ActionResultRepresentation.ResultType.SCALAR_VALUE;
+        }
+
+        // else
+        return ActionResultRepresentation.ResultType.DOMAIN_OBJECT;
+    }
+
 }
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/isis/blob/5f46ef13/core/viewer-restfulobjects-rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/domainobjects/ObjectCollectionReprRenderer.java
----------------------------------------------------------------------
diff --git a/core/viewer-restfulobjects-rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/domainobjects/ObjectCollectionReprRenderer.java b/core/viewer-restfulobjects-rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/domainobjects/ObjectCollectionReprRenderer.java
index c91751f..aac5e03 100644
--- a/core/viewer-restfulobjects-rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/domainobjects/ObjectCollectionReprRenderer.java
+++ b/core/viewer-restfulobjects-rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/domainobjects/ObjectCollectionReprRenderer.java
@@ -37,11 +37,6 @@ import org.apache.isis.viewer.restfulobjects.rendering.domaintypes.CollectionDes
 public class ObjectCollectionReprRenderer extends AbstractObjectMemberReprRenderer<ObjectCollectionReprRenderer, OneToManyAssociation> {
 
     public ObjectCollectionReprRenderer(
-            final RendererContext rendererContext) {
-        this(rendererContext, null, null, JsonRepresentation.newMap());
-    }
-
-    public ObjectCollectionReprRenderer(
             final RendererContext rendererContext,
             final LinkFollowSpecs linkFollowSpecs,
             final String collectionId,
@@ -53,6 +48,10 @@ public class ObjectCollectionReprRenderer extends AbstractObjectMemberReprRender
     @Override
     public JsonRepresentation render() {
 
+        if(representation == null) {
+            return null;
+        }
+
         renderMemberContent();
 
         final LinkFollowSpecs followValue = getLinkFollowSpecs().follow("value");

http://git-wip-us.apache.org/repos/asf/isis/blob/5f46ef13/core/viewer-restfulobjects-rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/domainobjects/ScalarValueReprRenderer.java
----------------------------------------------------------------------
diff --git a/core/viewer-restfulobjects-rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/domainobjects/ScalarValueReprRenderer.java b/core/viewer-restfulobjects-rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/domainobjects/ScalarValueReprRenderer.java
index 5aee110..0d319fc 100644
--- a/core/viewer-restfulobjects-rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/domainobjects/ScalarValueReprRenderer.java
+++ b/core/viewer-restfulobjects-rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/domainobjects/ScalarValueReprRenderer.java
@@ -31,7 +31,10 @@ public class ScalarValueReprRenderer extends ReprRendererAbstract<ScalarValueRep
 
     private ObjectSpecification returnType;
 
-    ScalarValueReprRenderer(final RendererContext resourceContext, final LinkFollowSpecs linkFollower, final JsonRepresentation representation) {
+    public ScalarValueReprRenderer(
+            final RendererContext resourceContext,
+            final LinkFollowSpecs linkFollower,
+            final JsonRepresentation representation) {
         super(resourceContext, linkFollower, null, representation); // null for representationType (there is none)
     }
 

http://git-wip-us.apache.org/repos/asf/isis/blob/5f46ef13/core/viewer-restfulobjects-rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/service/conneg/ContentNegotiationServiceAbstract.java
----------------------------------------------------------------------
diff --git a/core/viewer-restfulobjects-rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/service/conneg/ContentNegotiationServiceAbstract.java b/core/viewer-restfulobjects-rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/service/conneg/ContentNegotiationServiceAbstract.java
index ca7e651..18dc7c1 100644
--- a/core/viewer-restfulobjects-rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/service/conneg/ContentNegotiationServiceAbstract.java
+++ b/core/viewer-restfulobjects-rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/service/conneg/ContentNegotiationServiceAbstract.java
@@ -129,12 +129,12 @@ public abstract class ContentNegotiationServiceAbstract implements ContentNegoti
         }
     }
 
-    protected boolean canAccept(
+    protected boolean mediaTypeParameterMatches(
             final List<MediaType> acceptableMediaTypes,
-            final String profileValue) {
+            final String parameter, final String parameterValue) {
         for (MediaType mediaType : acceptableMediaTypes) {
-            final String paramValue = mediaType.getParameters().get("profile");
-            if (Objects.equals(paramValue, profileValue)) {
+            final String paramValue = mediaType.getParameters().get(parameter);
+            if (Objects.equals(paramValue, parameterValue)) {
                 return true;
             }
         }

http://git-wip-us.apache.org/repos/asf/isis/blob/5f46ef13/core/viewer-restfulobjects-rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/service/conneg/ContentNegotiationServiceForRestfulObjectsV1_0.java
----------------------------------------------------------------------
diff --git a/core/viewer-restfulobjects-rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/service/conneg/ContentNegotiationServiceForRestfulObjectsV1_0.java b/core/viewer-restfulobjects-rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/service/conneg/ContentNegotiationServiceForRestfulObjectsV1_0.java
index 04fe098..e24b6f9 100644
--- a/core/viewer-restfulobjects-rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/service/conneg/ContentNegotiationServiceForRestfulObjectsV1_0.java
+++ b/core/viewer-restfulobjects-rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/service/conneg/ContentNegotiationServiceForRestfulObjectsV1_0.java
@@ -73,14 +73,14 @@ public class ContentNegotiationServiceForRestfulObjectsV1_0 implements ContentNe
 
     @Override
     public ResponseBuilder buildResponse(
-            final RepresentationService.Context2 renderContext2,
+            final RepresentationService.Context2 rendererContext,
             final ObjectAdapter objectAdapter) {
 
-        final List<MediaType> list = renderContext2.getAcceptableMediaTypes();
+        final List<MediaType> list = rendererContext.getAcceptableMediaTypes();
         ensureCompatibleAcceptHeader(RepresentationType.DOMAIN_OBJECT, list);
 
         final ResponseBuilder responseBuilder = buildResponseTo(
-                renderContext2, objectAdapter, JsonRepresentation.newMap(), null);
+                rendererContext, objectAdapter, JsonRepresentation.newMap(), null);
 
         return responseBuilder(responseBuilder);
     }
@@ -89,19 +89,19 @@ public class ContentNegotiationServiceForRestfulObjectsV1_0 implements ContentNe
      * Not API
      */
     ResponseBuilder buildResponseTo(
-            final RepresentationService.Context2 renderContext2,
+            final RepresentationService.Context2 rendererContext,
             final ObjectAdapter objectAdapter,
-            final JsonRepresentation representation,
+            final JsonRepresentation representationIfAnyRequired,
             final JsonRepresentation rootRepresentation) {
 
         final DomainObjectReprRenderer renderer =
-                new DomainObjectReprRenderer(renderContext2, null, representation);
+                new DomainObjectReprRenderer(rendererContext, null, representationIfAnyRequired);
         renderer.with(objectAdapter).includesSelf();
 
         final ResponseBuilder responseBuilder = Responses.ofOk(renderer, Caching.NONE, rootRepresentation);
 
-        if(renderContext2 instanceof RepresentationService.Context6) {
-            final RepresentationService.Context6 context6 = (RepresentationService.Context6) renderContext2;
+        if(rendererContext instanceof RepresentationService.Context6) {
+            final RepresentationService.Context6 context6 = (RepresentationService.Context6) rendererContext;
             final RepresentationService.Intent intent = context6.getIntent();
             if(intent == RepresentationService.Intent.JUST_CREATED) {
                 responseBuilder.status(Response.Status.CREATED);
@@ -117,15 +117,15 @@ public class ContentNegotiationServiceForRestfulObjectsV1_0 implements ContentNe
 
     @Override
     public ResponseBuilder buildResponse(
-            final RepresentationService.Context2 renderContext2,
+            final RepresentationService.Context2 rendererContext,
             final ObjectAndProperty objectAndProperty) {
 
-        final List<MediaType> list = renderContext2.getAcceptableMediaTypes();
+        final List<MediaType> list = rendererContext.getAcceptableMediaTypes();
         ensureCompatibleAcceptHeader(RepresentationType.OBJECT_PROPERTY, list);
 
-        final ObjectPropertyReprRenderer renderer = new ObjectPropertyReprRenderer(renderContext2);
+        final ObjectPropertyReprRenderer renderer = new ObjectPropertyReprRenderer(rendererContext);
         renderer.with(objectAndProperty)
-                .usingLinkTo(renderContext2.getAdapterLinkTo());
+                .usingLinkTo(rendererContext.getAdapterLinkTo());
 
         if(objectAndProperty instanceof ObjectAndProperty2) {
             final ObjectAndProperty2 objectAndProperty2 = (ObjectAndProperty2) objectAndProperty;
@@ -140,15 +140,30 @@ public class ContentNegotiationServiceForRestfulObjectsV1_0 implements ContentNe
 
     @Override
     public ResponseBuilder buildResponse(
-            final RepresentationService.Context2 renderContext2,
+            final RepresentationService.Context2 rendererContext,
             final ObjectAndCollection objectAndCollection) {
 
-        final List<MediaType> list = renderContext2.getAcceptableMediaTypes();
+        final List<MediaType> list = rendererContext.getAcceptableMediaTypes();
         ensureCompatibleAcceptHeader(RepresentationType.OBJECT_COLLECTION, list);
 
-        final ObjectCollectionReprRenderer renderer = new ObjectCollectionReprRenderer(renderContext2);
+        final ResponseBuilder responseBuilder =
+                buildResponseTo(rendererContext, objectAndCollection, JsonRepresentation.newMap(), null);
+
+        return responseBuilder(responseBuilder);
+    }
+
+    /**
+     * Not API
+     */
+    ResponseBuilder buildResponseTo(
+            final RepresentationService.Context2 rendererContext,
+            final ObjectAndCollection objectAndCollection,
+            final JsonRepresentation representation,
+            final JsonRepresentation rootRepresentation) {
+        final ObjectCollectionReprRenderer renderer =
+                new ObjectCollectionReprRenderer(rendererContext, null, null, representation);
         renderer.with(objectAndCollection)
-                .usingLinkTo(renderContext2.getAdapterLinkTo());
+                .usingLinkTo(rendererContext.getAdapterLinkTo());
 
         if(objectAndCollection instanceof ObjectAndCollection2) {
             final ObjectAndCollection2 objectAndCollection2 = (ObjectAndCollection2) objectAndCollection;
@@ -156,22 +171,20 @@ public class ContentNegotiationServiceForRestfulObjectsV1_0 implements ContentNe
             renderer.withMemberMode(objectAndCollection2.getMemberReprMode());
         }
 
-        final ResponseBuilder responseBuilder = Responses.ofOk(renderer, Caching.NONE);
-
-        return responseBuilder(responseBuilder);
+        return Responses.ofOk(renderer, Caching.NONE, rootRepresentation);
     }
 
     @Override
     public ResponseBuilder buildResponse(
-            final RepresentationService.Context2 renderContext2,
+            final RepresentationService.Context2 rendererContext,
             final ObjectAndAction objectAndAction) {
 
-        final List<MediaType> list = renderContext2.getAcceptableMediaTypes();
+        final List<MediaType> list = rendererContext.getAcceptableMediaTypes();
         ensureCompatibleAcceptHeader(RepresentationType.OBJECT_ACTION, list);
 
-        final ObjectActionReprRenderer renderer = new ObjectActionReprRenderer(renderContext2);
+        final ObjectActionReprRenderer renderer = new ObjectActionReprRenderer(rendererContext);
         renderer.with(objectAndAction)
-                .usingLinkTo(renderContext2.getAdapterLinkTo())
+                .usingLinkTo(rendererContext.getAdapterLinkTo())
                 .asStandalone();
 
         final ResponseBuilder responseBuilder = Responses.ofOk(renderer, Caching.NONE);
@@ -181,20 +194,34 @@ public class ContentNegotiationServiceForRestfulObjectsV1_0 implements ContentNe
 
     @Override
     public ResponseBuilder buildResponse(
-            final RepresentationService.Context2 renderContext2,
+            final RepresentationService.Context2 rendererContext,
             final ObjectAndActionInvocation objectAndActionInvocation) {
 
-        final List<MediaType> list = renderContext2.getAcceptableMediaTypes();
+        final List<MediaType> list = rendererContext.getAcceptableMediaTypes();
         ensureCompatibleAcceptHeader(RepresentationType.ACTION_RESULT, list);
 
-        final ActionResultReprRenderer renderer = new ActionResultReprRenderer(renderContext2, objectAndActionInvocation.getSelfLink());
+        final ResponseBuilder responseBuilder =
+                buildResponseTo(rendererContext, objectAndActionInvocation, JsonRepresentation.newMap(), null);
+
+        return responseBuilder(responseBuilder);
+    }
+
+    /**
+     * Not API
+     */
+    ResponseBuilder buildResponseTo(
+            final RepresentationService.Context2 rendererContext,
+            final ObjectAndActionInvocation objectAndActionInvocation,
+            final JsonRepresentation representation,
+            final JsonRepresentation rootRepresentation) {
+        final ActionResultReprRenderer renderer =
+                new ActionResultReprRenderer(rendererContext, null, objectAndActionInvocation.getSelfLink(), representation);
         renderer.with(objectAndActionInvocation)
-                .using(renderContext2.getAdapterLinkTo());
+                .using(rendererContext.getAdapterLinkTo());
 
-        final ResponseBuilder responseBuilder = Responses.ofOk(renderer, Caching.NONE);
+        final ResponseBuilder responseBuilder = Responses.ofOk(renderer, Caching.NONE, rootRepresentation);
         Responses.addLastModifiedAndETagIfAvailable(responseBuilder, objectAndActionInvocation.getObjectAdapter().getVersion());
-
-        return responseBuilder(responseBuilder);
+        return responseBuilder;
     }
 
     /**

http://git-wip-us.apache.org/repos/asf/isis/blob/5f46ef13/core/viewer-restfulobjects-rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/service/conneg/ContentNegotiationServiceSimplified.java
----------------------------------------------------------------------
diff --git a/core/viewer-restfulobjects-rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/service/conneg/ContentNegotiationServiceSimplified.java b/core/viewer-restfulobjects-rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/service/conneg/ContentNegotiationServiceSimplified.java
index 7ebddef..2d774aa 100644
--- a/core/viewer-restfulobjects-rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/service/conneg/ContentNegotiationServiceSimplified.java
+++ b/core/viewer-restfulobjects-rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/service/conneg/ContentNegotiationServiceSimplified.java
@@ -18,6 +18,7 @@
  */
 package org.apache.isis.viewer.restfulobjects.rendering.service.conneg;
 
+import java.util.Collection;
 import java.util.List;
 
 import javax.inject.Inject;
@@ -33,16 +34,19 @@ import org.apache.isis.applib.annotation.Where;
 import org.apache.isis.core.metamodel.adapter.ObjectAdapter;
 import org.apache.isis.core.metamodel.consent.Consent;
 import org.apache.isis.core.metamodel.consent.InteractionInitiatedBy;
+import org.apache.isis.core.metamodel.facets.collections.modify.CollectionFacet;
+import org.apache.isis.core.metamodel.facets.collections.modify.CollectionFacetUtils;
+import org.apache.isis.core.metamodel.spec.ObjectSpecification;
 import org.apache.isis.core.metamodel.spec.feature.Contributed;
 import org.apache.isis.core.metamodel.spec.feature.OneToManyAssociation;
 import org.apache.isis.core.metamodel.spec.feature.OneToOneAssociation;
 import org.apache.isis.viewer.restfulobjects.applib.JsonRepresentation;
+import org.apache.isis.viewer.restfulobjects.applib.domainobjects.ActionResultRepresentation;
 import org.apache.isis.viewer.restfulobjects.rendering.RendererContext;
 import org.apache.isis.viewer.restfulobjects.rendering.domainobjects.ObjectAndAction;
 import org.apache.isis.viewer.restfulobjects.rendering.domainobjects.ObjectAndActionInvocation;
 import org.apache.isis.viewer.restfulobjects.rendering.domainobjects.ObjectAndCollection;
 import org.apache.isis.viewer.restfulobjects.rendering.domainobjects.ObjectAndProperty;
-import org.apache.isis.viewer.restfulobjects.rendering.domainobjects.ObjectCollectionReprRenderer;
 import org.apache.isis.viewer.restfulobjects.rendering.domainobjects.ObjectPropertyReprRenderer;
 import org.apache.isis.viewer.restfulobjects.rendering.service.RepresentationService;
 
@@ -54,108 +58,227 @@ import org.apache.isis.viewer.restfulobjects.rendering.service.RepresentationSer
 )
 public class ContentNegotiationServiceSimplified extends ContentNegotiationServiceAbstract {
 
-    private static final String ACCEPT_OBJECT = "urn:org.apache.isis:repr-types/object/v1";
+    /**
+     * Unlike RO v1.0, use a single content-type of <code>application/json;profile="urn:org.apache.isis/v1"</code>.
+     *
+     * <p>
+     * The response content types ({@link #CONTENT_TYPE_OAI_V1_OBJECT}, {@link #CONTENT_TYPE_OAI_V1_OBJECT_COLLECTION},
+     * {@link #CONTENT_TYPE_OAI_V1_LIST}) append the 'repr-type' parameter.
+     * </p>
+     */
+    public static final String ACCEPT_PROFILE = "urn:org.apache.isis/v1";
+
+    /**
+     * Whether to suppress the RO v1.0 '$$ro' node; suppress='false' or suppress='true'
+     */
+    public static final String ACCEPT_RO = "suppress";
+
+    /**
+     * The media type (as a string) used as the content-Type header when a domain object is rendered.
+     *
+     * @see #ACCEPT_PROFILE for discussion.
+     */
+    public static final String CONTENT_TYPE_OAI_V1_OBJECT = "application/json;"
+            + "profile=\"" + ACCEPT_PROFILE + "\""
+            + ";repr-type=\"object\""
+            ;
+    /**
+     * The media type (as a string) used as the content-Type header when a parented collection is rendered.
+     *
+     * @see #ACCEPT_PROFILE for discussion.
+     */
+    public static final String CONTENT_TYPE_OAI_V1_OBJECT_COLLECTION = "application/json;"
+            + "profile=\"" + ACCEPT_PROFILE + "\""
+            + ";repr-type=\"object-collection\""
+            ;
+    /**
+     * The media type (as a string) used as the content-Type header when a standalone collection is rendered.
+     *
+     * @see #ACCEPT_PROFILE for discussion.
+     */
+    public static final String CONTENT_TYPE_OAI_V1_LIST = "application/json;"
+            + "profile=\"" + ACCEPT_PROFILE + "\""
+            + ";repr-type=\"list\""
+            ;
 
     private ContentNegotiationServiceForRestfulObjectsV1_0 restfulObjectsV1_0 = new ContentNegotiationServiceForRestfulObjectsV1_0();
 
+    /**
+     * Domain object is returned as a map with the RO 1.0 representation as a special '$$ro' property
+     * within that map.
+     */
     public Response.ResponseBuilder buildResponse(
-            final RepresentationService.Context2 renderContext2,
+            final RepresentationService.Context2 rendererContext,
             final ObjectAdapter objectAdapter) {
 
-        final List<MediaType> acceptableMediaTypes = renderContext2.getAcceptableMediaTypes();
-
-        boolean canAccept = canAccept(acceptableMediaTypes, ACCEPT_OBJECT);
+        boolean canAccept = canAccept(rendererContext);
         if(!canAccept) {
             return null;
         }
-
-        final InteractionInitiatedBy interactionInitiatedBy =
-                determineInteractionInitiatedByFrom(renderContext2);
-        final Where where = renderContext2.getWhere();
+        boolean suppressRO = suppress(rendererContext);
 
         final JsonRepresentation rootRepresentation = JsonRepresentation.newMap();
 
-        List<OneToOneAssociation> properties = objectAdapter.getSpecification().getProperties(Contributed.INCLUDED);
-        for (final OneToOneAssociation property : properties) {
-
-            final Consent visibility = property.isVisible(objectAdapter, interactionInitiatedBy, where);
-            if (!visibility.isAllowed()) {
-                continue;
-            }
-
-            final JsonRepresentation propertyRepresentation = JsonRepresentation.newMap();
-            final ObjectPropertyReprRenderer renderer =
-                    new ObjectPropertyReprRenderer(renderContext2, null, property.getId(), propertyRepresentation);
-            renderer.with(new ObjectAndProperty(objectAdapter, property));
-
-            final JsonRepresentation propertyValueRepresentation = renderer.render();
-            rootRepresentation.mapPut(property.getId(), propertyValueRepresentation.getRepresentation("value"));
-        }
-
-        List<OneToManyAssociation> collections = objectAdapter.getSpecification().getCollections(Contributed.INCLUDED);
-        for (final OneToManyAssociation collection : collections) {
+        appendObjectTo(rendererContext, objectAdapter, rootRepresentation);
 
-            final Consent visibility = collection.isVisible(objectAdapter, interactionInitiatedBy, where);
-            if (!visibility.isAllowed()) {
-                continue;
-            }
-
-            final JsonRepresentation propertyRepresentation = JsonRepresentation.newMap();
-            final ObjectCollectionReprRenderer renderer =
-                    new ObjectCollectionReprRenderer(renderContext2, null, collection.getId(), propertyRepresentation);
-            renderer.with(new ObjectAndCollection(objectAdapter, collection));
-
-            final JsonRepresentation collectionValueRepresentation = renderer.render();
-            rootRepresentation.mapPut(collection.getId(), collectionValueRepresentation);
+        final JsonRepresentation $$roRepresentation;
+        if(!suppressRO) {
+            $$roRepresentation = JsonRepresentation.newMap();
+            rootRepresentation.mapPut("$$ro", $$roRepresentation);
+        } else {
+            $$roRepresentation = null;
         }
-
-
-        final JsonRepresentation $$roRepresentation = JsonRepresentation.newMap();
-        rootRepresentation.mapPut("$$ro", $$roRepresentation);
-
         final Response.ResponseBuilder responseBuilder =
                 restfulObjectsV1_0.buildResponseTo(
-                        renderContext2, objectAdapter, $$roRepresentation, rootRepresentation);
+                        rendererContext, objectAdapter, $$roRepresentation, rootRepresentation);
 
-        return responseBuilder(responseBuilder);
-    }
+        responseBuilder.type(CONTENT_TYPE_OAI_V1_OBJECT);
 
-    private static InteractionInitiatedBy determineInteractionInitiatedByFrom(
-            final RendererContext rendererContext) {
-        if (rendererContext instanceof RepresentationService.Context4) {
-            return ((RepresentationService.Context4) rendererContext).getInteractionInitiatedBy();
-        } else {
-            // fallback
-            return InteractionInitiatedBy.USER;
-        }
+        return responseBuilder(responseBuilder);
     }
 
+    /**
+     * Individual property of an object is not supported.
+     */
     @Programmatic
     public Response.ResponseBuilder buildResponse(
-            final RepresentationService.Context2 renderContext2,
+            final RepresentationService.Context2 rendererContext,
             final ObjectAndProperty objectAndProperty)  {
+
         return null;
     }
 
+    /**
+     * Individual (parented) collection of an object is returned as a list with the RO representation
+     * as an object in the list with a single property named '$$ro'
+     */
     @Programmatic
     public Response.ResponseBuilder buildResponse(
-            final RepresentationService.Context2 renderContext2,
+            final RepresentationService.Context2 rendererContext,
             final ObjectAndCollection objectAndCollection) {
-        return null;
+
+        if(!canAccept(rendererContext)) {
+            return null;
+        }
+        boolean suppressRO = suppress(rendererContext);
+
+        final JsonRepresentation rootRepresentation = JsonRepresentation.newArray();
+
+        ObjectAdapter objectAdapter = objectAndCollection.getObjectAdapter();
+        OneToManyAssociation collection = objectAndCollection.getMember();
+
+        appendCollectionTo(rendererContext, objectAdapter, collection, rootRepresentation);
+
+        final JsonRepresentation $$roRepresentation;
+        if(!suppressRO) {
+            // $$ro representation will be an object in the list with a single property named "$$ro"
+            final JsonRepresentation $$roContainerRepresentation = JsonRepresentation.newMap();
+            rootRepresentation.arrayAdd($$roContainerRepresentation);
+
+            $$roRepresentation = JsonRepresentation.newMap();
+            $$roContainerRepresentation.mapPut("$$ro", $$roRepresentation);
+        } else {
+            $$roRepresentation = null;
+        }
+
+        final Response.ResponseBuilder responseBuilder =
+                restfulObjectsV1_0.buildResponseTo(
+                        rendererContext, objectAndCollection, $$roRepresentation, rootRepresentation);
+
+        responseBuilder.type(CONTENT_TYPE_OAI_V1_OBJECT_COLLECTION);
+
+        return responseBuilder(responseBuilder);
     }
 
+    /**
+     * Action prompt is not supported.
+     */
     @Programmatic
     public Response.ResponseBuilder buildResponse(
-            final RepresentationService.Context2 renderContext2,
+            final RepresentationService.Context2 rendererContext,
             final ObjectAndAction objectAndAction)  {
         return null;
     }
 
+    /**
+     * Action invocation is supported provided it returns a single domain object or a list of domain objects
+     * (ie invocations returning void or scalar value are not supported).
+     *
+     * Action invocations returning a domain object will be rendered as a map with the RO v1.0 representation as a
+     * '$$ro' property within (same as {@link #buildResponse(RepresentationService.Context2, ObjectAdapter)}), while
+     * action invocations returning a list will be rendered as a list with the RO v1.0 representation as a map object
+     * with a single '$$ro' property (similar to {@link #buildResponse(RepresentationService.Context2, ObjectAndCollection)})
+     */
     @Programmatic
     public Response.ResponseBuilder buildResponse(
-            final RepresentationService.Context2 renderContext2,
+            final RepresentationService.Context2 rendererContext,
             final ObjectAndActionInvocation objectAndActionInvocation) {
-        return null;
+
+        if(!canAccept(rendererContext)) {
+            return null;
+        }
+        boolean suppressRO = suppress(rendererContext);
+
+        JsonRepresentation rootRepresentation = null;
+        final JsonRepresentation $$roRepresentation;
+        if(!suppressRO) {
+            $$roRepresentation = JsonRepresentation.newMap();
+        } else {
+            $$roRepresentation = null;
+        }
+
+        final ObjectAdapter returnedAdapter = objectAndActionInvocation.getReturnedAdapter();
+        final ObjectSpecification returnType = objectAndActionInvocation.getAction().getReturnType();
+
+        if (returnedAdapter == null) {
+            return null;
+        }
+
+        final ActionResultRepresentation.ResultType resultType = objectAndActionInvocation.determineResultType();
+        switch (resultType) {
+            case DOMAIN_OBJECT:
+
+                rootRepresentation = JsonRepresentation.newMap();
+                appendObjectTo(rendererContext, returnedAdapter, rootRepresentation);
+
+                break;
+
+            case LIST:
+
+                rootRepresentation = JsonRepresentation.newArray();
+
+                final CollectionFacet collectionFacet = returnType.getFacet(CollectionFacet.class);
+                final Collection<ObjectAdapter> collectionAdapters = collectionFacet.collection(returnedAdapter);
+                appendIterableTo(rendererContext, collectionAdapters, rootRepresentation);
+
+                // $$ro representation will be an object in the list with a single property named "$$ro"
+                if(!suppressRO) {
+                    JsonRepresentation $$roContainerRepresentation = JsonRepresentation.newMap();
+                    rootRepresentation.arrayAdd($$roContainerRepresentation);
+                    $$roContainerRepresentation.mapPut("$$ro", $$roRepresentation);
+                }
+
+                break;
+
+            case SCALAR_VALUE:
+            case VOID:
+
+                // not supported
+                return null;
+        }
+
+        final Response.ResponseBuilder responseBuilder =
+                restfulObjectsV1_0.buildResponseTo(
+                        rendererContext, objectAndActionInvocation, $$roRepresentation, rootRepresentation);
+
+        // set appropriate Content-Type
+        responseBuilder.type(
+                resultType == ActionResultRepresentation.ResultType.DOMAIN_OBJECT
+                        ? CONTENT_TYPE_OAI_V1_OBJECT
+                        : CONTENT_TYPE_OAI_V1_LIST
+        );
+
+        return responseBuilder(responseBuilder);
     }
 
     /**
@@ -165,6 +288,115 @@ public class ContentNegotiationServiceSimplified extends ContentNegotiationServi
         return responseBuilder;
     }
 
+    boolean canAccept(final RepresentationService.Context2 rendererContext) {
+        final List<MediaType> acceptableMediaTypes = rendererContext.getAcceptableMediaTypes();
+        return mediaTypeParameterMatches(acceptableMediaTypes, "profile", ACCEPT_PROFILE);
+    }
+
+    protected boolean suppress(
+            final RepresentationService.Context2 rendererContext) {
+        final List<MediaType> acceptableMediaTypes = rendererContext.getAcceptableMediaTypes();
+        return mediaTypeParameterMatches(acceptableMediaTypes, "suppress", "true");
+    }
+
+    private void appendObjectTo(
+            final RepresentationService.Context2 rendererContext,
+            final ObjectAdapter objectAdapter,
+            final JsonRepresentation rootRepresentation) {
+
+        appendPropertiesTo(rendererContext, objectAdapter, rootRepresentation);
+
+        final List<OneToManyAssociation> collections = objectAdapter.getSpecification().getCollections(Contributed.INCLUDED);
+        final Where where = rendererContext.getWhere();
+        for (final OneToManyAssociation collection : collections) {
+
+            final JsonRepresentation collectionRepresentation = JsonRepresentation.newArray();
+
+            rootRepresentation.mapPut(collection.getId(), collectionRepresentation);
+
+            final InteractionInitiatedBy interactionInitiatedBy = determineInteractionInitiatedByFrom(rendererContext);
+            final Consent visibility = collection.isVisible(objectAdapter, interactionInitiatedBy, where);
+            if (!visibility.isAllowed()) {
+                continue;
+            }
+
+            appendCollectionTo(rendererContext, objectAdapter, collection, collectionRepresentation);
+        }
+    }
+
+    private void appendPropertiesTo(
+            final RepresentationService.Context2 rendererContext,
+            final ObjectAdapter objectAdapter,
+            final JsonRepresentation rootRepresentation) {
+        final InteractionInitiatedBy interactionInitiatedBy = determineInteractionInitiatedByFrom(rendererContext);
+        final Where where = rendererContext.getWhere();
+        List<OneToOneAssociation> properties = objectAdapter.getSpecification().getProperties(Contributed.INCLUDED);
+        for (final OneToOneAssociation property : properties) {
+
+            final Consent visibility = property.isVisible(objectAdapter, interactionInitiatedBy, where);
+            if (!visibility.isAllowed()) {
+                continue;
+            }
+
+            final JsonRepresentation propertyRepresentation = JsonRepresentation.newMap();
+            final ObjectPropertyReprRenderer renderer =
+                    new ObjectPropertyReprRenderer(rendererContext, null, property.getId(), propertyRepresentation)
+                        .asStandalone();
+            renderer.with(new ObjectAndProperty(objectAdapter, property));
+
+            final JsonRepresentation propertyValueRepresentation = renderer.render();
+
+            final String upHref = propertyValueRepresentation.getString("links[rel=up].href");
+            rootRepresentation.mapPut("$$href", upHref);
+            final String upTitle = propertyValueRepresentation.getString("links[rel=up].title");
+            rootRepresentation.mapPut("$$title", upTitle);
+
+            final JsonRepresentation value = propertyValueRepresentation.getRepresentation("value");
+            rootRepresentation.mapPut(property.getId(), value);
+        }
+    }
+
+    private void appendCollectionTo(
+            final RepresentationService.Context2 rendererContext,
+            final ObjectAdapter objectAdapter,
+            final OneToManyAssociation collection,
+            final JsonRepresentation representation) {
+
+        final InteractionInitiatedBy interactionInitiatedBy = determineInteractionInitiatedByFrom(rendererContext);
+        final ObjectAdapter valueAdapter = collection.get(objectAdapter, interactionInitiatedBy);
+        if (valueAdapter == null) {
+            return;
+        }
+
+        final CollectionFacet facet = CollectionFacetUtils.getCollectionFacetFromSpec(valueAdapter);
+        final Iterable<ObjectAdapter> iterable = facet.iterable(valueAdapter);
+        appendIterableTo(rendererContext, iterable, representation);
+    }
+
+    private void appendIterableTo(
+            final RepresentationService.Context2 rendererContext,
+            final Iterable<ObjectAdapter> iterable,
+            final JsonRepresentation collectionRepresentation) {
+        for (final ObjectAdapter elementAdapter : iterable) {
+
+            JsonRepresentation elementRepresentation = JsonRepresentation.newMap();
+            appendPropertiesTo(rendererContext, elementAdapter, elementRepresentation);
+
+            collectionRepresentation.arrayAdd(elementRepresentation);
+        }
+    }
+
+    private static InteractionInitiatedBy determineInteractionInitiatedByFrom(
+            final RendererContext rendererContext) {
+        if (rendererContext instanceof RepresentationService.Context4) {
+            return ((RepresentationService.Context4) rendererContext).getInteractionInitiatedBy();
+        } else {
+            // fallback
+            return InteractionInitiatedBy.USER;
+        }
+    }
+
+
     @Inject
     protected DomainObjectContainer container;
 }