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 2014/10/09 13:23:24 UTC

[4/4] git commit: ISIS-917: further refactorings to simplify the API of the (newly rechristened) RepresentationService.

ISIS-917: further refactorings to simplify the API of the (newly rechristened) RepresentationService.


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

Branch: refs/heads/ISIS-917
Commit: 6907534b421daa083cd5b96b9a0a476e64c2e8e9
Parents: 9af7833
Author: Dan Haywood <da...@haywood-associates.co.uk>
Authored: Thu Oct 9 12:23:14 2014 +0100
Committer: Dan Haywood <da...@haywood-associates.co.uk>
Committed: Thu Oct 9 12:23:14 2014 +0100

----------------------------------------------------------------------
 .../ServicesInstallerFromAnnotation.java        |   3 +-
 .../AbstractObjectMemberRepresentation.java     |   2 +-
 .../restfulobjects/rendering/Caching.java       |  43 +++
 .../rendering/HasHttpStatusCode.java            |  26 ++
 .../rendering/RendererContext.java              |  10 +-
 .../restfulobjects/rendering/Responses.java     |  64 +++++
 .../RestfulObjectsApplicationException.java     |  69 +++++
 .../AbstractObjectMemberReprRenderer.java       |   9 +
 .../domainobjects/ActionResultReprRenderer.java |   4 +
 .../rendering/domainobjects/MemberReprMode.java |  29 ++
 .../domainobjects/ObjectActionReprRenderer.java |  13 +-
 .../ObjectCollectionReprRenderer.java           |  17 +-
 .../ObjectPropertyReprRenderer.java             |  12 +-
 .../service/RepresentationService.java          |  61 +++++
 .../RepresentationServiceForRestfulObjects.java | 146 ++++++++++
 .../rendering/util/JsonWriterUtil.java          |  41 +++
 .../restfulobjects/rendering/util/Util.java     | 107 ++++++++
 .../server/HasHttpStatusCode.java               |  26 --
 .../restfulobjects/server/ResourceContext.java  |   8 +-
 .../RestfulObjectsApplicationException.java     |  56 +---
 ...estfulObjectsApplicationExceptionMapper.java |   2 +
 .../DomainObjectResourceServerside.java         |  27 +-
 .../server/resources/DomainResourceHelper.java  | 235 +++++++++++++---
 .../DomainServiceResourceServerside.java        |   4 +-
 .../resources/DomainTypeResourceServerside.java |   5 +-
 .../resources/HomePageResourceServerside.java   |   4 +-
 .../server/resources/JsonParserHelper.java      |  54 ++--
 .../server/resources/ObjectActionArgHelper.java |  12 +-
 .../resources/ObjectAdapterAccessHelper.java    |  39 +--
 .../server/resources/ResourceAbstract.java      |  54 +---
 .../resources/ResponseGeneratorService.java     | 269 -------------------
 .../server/resources/Responses.java             |  64 -----
 .../resources/UserResourceServerside.java       |   4 +-
 .../restfulobjects/server/resources/Util.java   | 124 ---------
 .../resources/VersionResourceServerside.java    |   4 +-
 .../server/util/NOTUSED_PathUtils.java          |  40 +++
 .../restfulobjects/server/util/OidUtils.java    |  19 +-
 .../restfulobjects/server/util/PathUtils.java   |  40 ---
 .../server/util/UrlParserUtils.java             |  20 +-
 ...ontextTest_ensureCompatibleAcceptHeader.java |   1 +
 ...ulObjectsApplicationExceptionMapperTest.java |   1 +
 .../DomainResourceHelperTest_readBodyAsMap.java |   3 +-
 .../server/resources/JsonParserHelpTest.java    |  36 +++
 .../server/util/UrlParserUtilsTest.java         |  13 +-
 .../webapp/CustomRepresentationService.java     |  32 +++
 .../webapp/CustomResponseGeneratorService.java  |  32 ---
 .../src/main/webapp/WEB-INF/isis.properties     |   2 +-
 47 files changed, 1080 insertions(+), 806 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/isis/blob/6907534b/core/runtime/src/main/java/org/apache/isis/core/runtime/services/ServicesInstallerFromAnnotation.java
----------------------------------------------------------------------
diff --git a/core/runtime/src/main/java/org/apache/isis/core/runtime/services/ServicesInstallerFromAnnotation.java b/core/runtime/src/main/java/org/apache/isis/core/runtime/services/ServicesInstallerFromAnnotation.java
index e325c06..8b2400b 100644
--- a/core/runtime/src/main/java/org/apache/isis/core/runtime/services/ServicesInstallerFromAnnotation.java
+++ b/core/runtime/src/main/java/org/apache/isis/core/runtime/services/ServicesInstallerFromAnnotation.java
@@ -64,8 +64,7 @@ public class ServicesInstallerFromAnnotation extends InstallerAbstract implement
                                          ",org.apache.isis.core.metamodel.services" +
                                          ",org.apache.isis.core.runtime.services" +
                                          ",org.apache.isis.objectstore.jdo.applib.service" +
-                                         ",org.apache.isis.viewer.restfulobjects.server.resources" +
-                                         ",org.apache.isis.viewer.restfulobjects.rendering.eventserializer" +
+                                         ",org.apache.isis.viewer.restfulobjects.rendering.service" +
                                          ",org.apache.isis.objectstore.jdo.datanucleus.service.support" +
                                          ",org.apache.isis.objectstore.jdo.datanucleus.service.eventbus";
 

http://git-wip-us.apache.org/repos/asf/isis/blob/6907534b/core/viewer-restfulobjects-applib/src/main/java/org/apache/isis/viewer/restfulobjects/applib/domainobjects/AbstractObjectMemberRepresentation.java
----------------------------------------------------------------------
diff --git a/core/viewer-restfulobjects-applib/src/main/java/org/apache/isis/viewer/restfulobjects/applib/domainobjects/AbstractObjectMemberRepresentation.java b/core/viewer-restfulobjects-applib/src/main/java/org/apache/isis/viewer/restfulobjects/applib/domainobjects/AbstractObjectMemberRepresentation.java
index d2de410..fc0c74f 100644
--- a/core/viewer-restfulobjects-applib/src/main/java/org/apache/isis/viewer/restfulobjects/applib/domainobjects/AbstractObjectMemberRepresentation.java
+++ b/core/viewer-restfulobjects-applib/src/main/java/org/apache/isis/viewer/restfulobjects/applib/domainobjects/AbstractObjectMemberRepresentation.java
@@ -18,8 +18,8 @@
  */
 package org.apache.isis.viewer.restfulobjects.applib.domainobjects;
 
-import org.apache.isis.viewer.restfulobjects.applib.LinkRepresentation;
 import org.codehaus.jackson.JsonNode;
+import org.apache.isis.viewer.restfulobjects.applib.LinkRepresentation;
 
 public abstract class AbstractObjectMemberRepresentation extends DomainRepresentation {
 

http://git-wip-us.apache.org/repos/asf/isis/blob/6907534b/core/viewer-restfulobjects-rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/Caching.java
----------------------------------------------------------------------
diff --git a/core/viewer-restfulobjects-rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/Caching.java b/core/viewer-restfulobjects-rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/Caching.java
new file mode 100644
index 0000000..345861d
--- /dev/null
+++ b/core/viewer-restfulobjects-rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/Caching.java
@@ -0,0 +1,43 @@
+/*
+ *  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;
+
+import javax.ws.rs.core.CacheControl;
+
+public enum Caching {
+
+    ONE_DAY(24 * 60 * 60),
+    ONE_HOUR(60 * 60),
+    NONE(0);
+
+    private final CacheControl cacheControl;
+
+    Caching(final int maxAge) {
+        this.cacheControl = new CacheControl();
+        if (maxAge > 0) {
+            cacheControl.setMaxAge(maxAge);
+        } else {
+            cacheControl.setNoCache(true);
+        }
+    }
+
+    public CacheControl getCacheControl() {
+        return cacheControl;
+    }
+}

http://git-wip-us.apache.org/repos/asf/isis/blob/6907534b/core/viewer-restfulobjects-rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/HasHttpStatusCode.java
----------------------------------------------------------------------
diff --git a/core/viewer-restfulobjects-rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/HasHttpStatusCode.java b/core/viewer-restfulobjects-rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/HasHttpStatusCode.java
new file mode 100644
index 0000000..cb35092
--- /dev/null
+++ b/core/viewer-restfulobjects-rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/HasHttpStatusCode.java
@@ -0,0 +1,26 @@
+/*
+ *  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;
+
+import org.apache.isis.viewer.restfulobjects.applib.client.RestfulResponse.HttpStatusCode;
+
+public interface HasHttpStatusCode {
+
+    HttpStatusCode getHttpStatusCode();
+}

http://git-wip-us.apache.org/repos/asf/isis/blob/6907534b/core/viewer-restfulobjects-rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/RendererContext.java
----------------------------------------------------------------------
diff --git a/core/viewer-restfulobjects-rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/RendererContext.java b/core/viewer-restfulobjects-rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/RendererContext.java
index 6b8a7f5..6af0f9f 100644
--- a/core/viewer-restfulobjects-rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/RendererContext.java
+++ b/core/viewer-restfulobjects-rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/RendererContext.java
@@ -19,14 +19,12 @@
 package org.apache.isis.viewer.restfulobjects.rendering;
 
 import java.util.List;
-
 import org.apache.isis.applib.annotation.Render;
 import org.apache.isis.applib.annotation.Where;
 import org.apache.isis.applib.profiles.Localization;
 import org.apache.isis.core.commons.authentication.AuthenticationSession;
 import org.apache.isis.core.commons.config.IsisConfiguration;
 import org.apache.isis.core.metamodel.adapter.ObjectAdapter;
-import org.apache.isis.core.metamodel.adapter.mgr.AdapterManager;
 import org.apache.isis.core.runtime.system.persistence.PersistenceSession;
 import org.apache.isis.viewer.restfulobjects.rendering.domainobjects.DomainObjectReprRenderer;
 
@@ -38,13 +36,11 @@ public interface RendererContext {
     
     public IsisConfiguration getConfiguration();
     
-    public AdapterManager getAdapterManager();
-
     public PersistenceSession getPersistenceSession();
-    
-    public List<List<String>> getFollowLinks();
-    
+
     public Where getWhere();
+
+    public List<List<String>> getFollowLinks();
     
     public Localization getLocalization();
     

http://git-wip-us.apache.org/repos/asf/isis/blob/6907534b/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
new file mode 100644
index 0000000..e4420c1
--- /dev/null
+++ b/core/viewer-restfulobjects-rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/Responses.java
@@ -0,0 +1,64 @@
+/**
+ *  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;
+
+import java.util.Date;
+import javax.ws.rs.core.EntityTag;
+import javax.ws.rs.core.MediaType;
+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.client.RestfulResponse;
+import org.apache.isis.viewer.restfulobjects.rendering.util.JsonWriterUtil;
+
+public final class Responses {
+
+    private Responses(){}
+
+    public static Response.ResponseBuilder ofNoContent() {
+        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, final Version version) {
+        final MediaType mediaType = renderer.getMediaType();
+        final Response.ResponseBuilder response = of(RestfulResponse.HttpStatusCode.OK).type(mediaType).cacheControl(caching.getCacheControl()).entity(JsonWriterUtil.jsonFor(renderer.render()));
+        return addLastModifiedAndETagIfAvailable(response, version);
+    }
+
+    protected static Response.ResponseBuilder of(final RestfulResponse.HttpStatusCode httpStatusCode) {
+        return Response.status(httpStatusCode.getJaxrsStatusType()).type(MediaType.APPLICATION_JSON_TYPE);
+    }
+
+    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);
+            responseBuilder.tag(asETag(time));
+        }
+        return responseBuilder;
+    }
+
+    private static EntityTag asETag(final Date time) {
+        final String utcTime = ISODateTimeFormat.basicDateTime().print(new DateTime(time));
+        return new EntityTag(utcTime, true);
+    }
+}

http://git-wip-us.apache.org/repos/asf/isis/blob/6907534b/core/viewer-restfulobjects-rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/RestfulObjectsApplicationException.java
----------------------------------------------------------------------
diff --git a/core/viewer-restfulobjects-rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/RestfulObjectsApplicationException.java b/core/viewer-restfulobjects-rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/RestfulObjectsApplicationException.java
new file mode 100644
index 0000000..77e3765
--- /dev/null
+++ b/core/viewer-restfulobjects-rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/RestfulObjectsApplicationException.java
@@ -0,0 +1,69 @@
+/*
+ *  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;
+
+import org.apache.isis.viewer.restfulobjects.applib.JsonRepresentation;
+import org.apache.isis.viewer.restfulobjects.applib.client.RestfulResponse.HttpStatusCode;
+
+public class RestfulObjectsApplicationException extends RuntimeException implements HasHttpStatusCode {
+
+    public static final RestfulObjectsApplicationException create(final HttpStatusCode httpStatusCode) {
+        return createWithCause(httpStatusCode, null);
+    }
+
+    public static RestfulObjectsApplicationException createWithMessage(final HttpStatusCode httpStatusCode, final String message, final Object... args) {
+        return createWithCauseAndMessage(httpStatusCode, (Exception) null, message, args);
+    }
+
+    public static RestfulObjectsApplicationException createWithCause(final HttpStatusCode httpStatusCode, final Exception cause) {
+        return createWithCauseAndMessage(httpStatusCode, cause, null);
+    }
+
+    public static RestfulObjectsApplicationException createWithCauseAndMessage(final HttpStatusCode httpStatusCode, final Exception cause, final String message, final Object... args) {
+        return new RestfulObjectsApplicationException(httpStatusCode, formatString(message, args), cause, null);
+    }
+
+    public static RestfulObjectsApplicationException createWithBody(final HttpStatusCode httpStatusCode, final JsonRepresentation body, final String message, final Object... args) {
+        return new RestfulObjectsApplicationException(httpStatusCode, formatString(message, args), null, body);
+    }
+
+    private static String formatString(final String formatStr, final Object... args) {
+        return formatStr != null ? String.format(formatStr, args) : null;
+    }
+
+    private static final long serialVersionUID = 1L;
+    private final HttpStatusCode httpStatusCode;
+    private final JsonRepresentation body;
+
+    protected RestfulObjectsApplicationException(final HttpStatusCode httpStatusCode, final String message, final Throwable cause, final JsonRepresentation body) {
+        super(message, cause);
+        this.httpStatusCode = httpStatusCode;
+        this.body = body;
+    }
+
+    @Override
+    public HttpStatusCode getHttpStatusCode() {
+        return httpStatusCode;
+    }
+
+    public JsonRepresentation getBody() {
+        return body;
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/isis/blob/6907534b/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 c2d2622..d7f187c 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
@@ -33,6 +33,7 @@ import org.apache.isis.viewer.restfulobjects.rendering.ReprRendererAbstract;
 
 public abstract class AbstractObjectMemberReprRenderer<R extends ReprRendererAbstract<R, ObjectAndMember<T>>, T extends ObjectMember> extends ReprRendererAbstract<R, ObjectAndMember<T>> {
 
+
     protected enum Mode {
         INLINE, FOLLOWED, STANDALONE, MUTATED, ARGUMENTS, EVENT_SERIALIZATION;
 
@@ -179,6 +180,14 @@ public abstract class AbstractObjectMemberReprRenderer<R extends ReprRendererAbs
         }
     }
 
+    public void withMemberMode(MemberReprMode memberMode) {
+        if(memberMode == MemberReprMode.WRITE) {
+            this.asMutated();
+        } else {
+            this.asStandalone();
+        }
+    }
+
     private void addLinkToSelf() {
         getLinks().arrayAdd(linkTo.memberBuilder(Rel.SELF, objectMemberType, objectMember).build());
     }

http://git-wip-us.apache.org/repos/asf/isis/blob/6907534b/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 e5df49a..dabdf02 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
@@ -50,6 +50,10 @@ public class ActionResultReprRenderer extends ReprRendererAbstract<ActionResultR
         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) {
         super(rendererContext, linkFollower, RepresentationType.ACTION_RESULT, representation);
         this.selfLink = selfLink;

http://git-wip-us.apache.org/repos/asf/isis/blob/6907534b/core/viewer-restfulobjects-rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/domainobjects/MemberReprMode.java
----------------------------------------------------------------------
diff --git a/core/viewer-restfulobjects-rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/domainobjects/MemberReprMode.java b/core/viewer-restfulobjects-rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/domainobjects/MemberReprMode.java
new file mode 100644
index 0000000..aa90aa0
--- /dev/null
+++ b/core/viewer-restfulobjects-rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/domainobjects/MemberReprMode.java
@@ -0,0 +1,29 @@
+/*
+ *  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.domainobjects;
+
+/**
+ * Some representations may vary according to whether the member is to be represented for read
+ * (render the state of the property or collection) or for write (render additional hypermedia controls to allow
+ * the property to be modified/cleared, or the collection to be added to/removed from).
+*/
+public enum MemberReprMode {
+    READ,
+    WRITE;
+}

http://git-wip-us.apache.org/repos/asf/isis/blob/6907534b/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 187c448..84d512d 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
@@ -18,7 +18,9 @@ package org.apache.isis.viewer.restfulobjects.rendering.domainobjects;
 
 import java.util.List;
 import java.util.Map;
-
+import com.google.common.collect.Lists;
+import com.google.common.collect.Maps;
+import org.codehaus.jackson.node.NullNode;
 import org.apache.isis.applib.annotation.ActionSemantics;
 import org.apache.isis.applib.annotation.Where;
 import org.apache.isis.core.metamodel.adapter.ObjectAdapter;
@@ -32,13 +34,12 @@ import org.apache.isis.viewer.restfulobjects.rendering.LinkFollowSpecs;
 import org.apache.isis.viewer.restfulobjects.rendering.RendererContext;
 import org.apache.isis.viewer.restfulobjects.rendering.domaintypes.ActionDescriptionReprRenderer;
 
-import org.codehaus.jackson.node.NullNode;
-
-import com.google.common.collect.Lists;
-import com.google.common.collect.Maps;
-
 public class ObjectActionReprRenderer extends AbstractObjectMemberReprRenderer<ObjectActionReprRenderer, ObjectAction> {
 
+    public ObjectActionReprRenderer(RendererContext rendererContext) {
+        this(rendererContext, null, null, JsonRepresentation.newMap());
+    }
+
     public ObjectActionReprRenderer(final RendererContext resourceContext, final LinkFollowSpecs linkFollowSpecs, String actionId, final JsonRepresentation representation) {
         super(resourceContext, linkFollowSpecs, actionId, RepresentationType.OBJECT_ACTION, representation, Where.OBJECT_FORMS);
     }

http://git-wip-us.apache.org/repos/asf/isis/blob/6907534b/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 4639386..7f09c09 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
@@ -18,7 +18,7 @@ package org.apache.isis.viewer.restfulobjects.rendering.domainobjects;
 
 import java.util.List;
 import java.util.Map;
-
+import com.google.common.collect.Lists;
 import org.apache.isis.applib.annotation.Render.Type;
 import org.apache.isis.applib.annotation.Where;
 import org.apache.isis.core.metamodel.adapter.ObjectAdapter;
@@ -34,12 +34,19 @@ import org.apache.isis.viewer.restfulobjects.rendering.LinkFollowSpecs;
 import org.apache.isis.viewer.restfulobjects.rendering.RendererContext;
 import org.apache.isis.viewer.restfulobjects.rendering.domaintypes.CollectionDescriptionReprRenderer;
 
-import com.google.common.collect.Lists;
-
 public class ObjectCollectionReprRenderer extends AbstractObjectMemberReprRenderer<ObjectCollectionReprRenderer, OneToManyAssociation> {
 
-    public ObjectCollectionReprRenderer(final RendererContext resourceContext, final LinkFollowSpecs linkFollower, final String collectionId, final JsonRepresentation representation) {
-        super(resourceContext, linkFollower, collectionId, RepresentationType.OBJECT_COLLECTION, representation, Where.PARENTED_TABLES);
+    public ObjectCollectionReprRenderer(
+            final RendererContext resourceContext) {
+        this(resourceContext, null, null, JsonRepresentation.newMap());
+    }
+
+    public ObjectCollectionReprRenderer(
+            final RendererContext resourceContext,
+            final LinkFollowSpecs linkFollowSpecs,
+            final String collectionId,
+            final JsonRepresentation representation) {
+        super(resourceContext, linkFollowSpecs, collectionId, RepresentationType.OBJECT_COLLECTION, representation, Where.PARENTED_TABLES);
     }
 
     @Override

http://git-wip-us.apache.org/repos/asf/isis/blob/6907534b/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 f59181e..09e329f 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
@@ -41,7 +41,16 @@ import org.apache.isis.viewer.restfulobjects.rendering.domaintypes.PropertyDescr
 
 public class ObjectPropertyReprRenderer extends AbstractObjectMemberReprRenderer<ObjectPropertyReprRenderer, OneToOneAssociation> {
 
-    public ObjectPropertyReprRenderer(final RendererContext resourceContext, final LinkFollowSpecs linkFollower, final String propertyId, final JsonRepresentation representation) {
+    public ObjectPropertyReprRenderer(
+            final RendererContext resourceContext) {
+        this(resourceContext, null, null, JsonRepresentation.newMap());
+    }
+
+    public ObjectPropertyReprRenderer(
+            final RendererContext resourceContext,
+            final LinkFollowSpecs linkFollower,
+            final String propertyId,
+            final JsonRepresentation representation) {
         super(resourceContext, linkFollower, propertyId, RepresentationType.OBJECT_PROPERTY, representation, Where.OBJECT_FORMS);
     }
 
@@ -211,4 +220,5 @@ public class ObjectPropertyReprRenderer extends AbstractObjectMemberReprRenderer
         // none
     }
 
+
 }
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/isis/blob/6907534b/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
new file mode 100644
index 0000000..0362160
--- /dev/null
+++ b/core/viewer-restfulobjects-rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/service/RepresentationService.java
@@ -0,0 +1,61 @@
+/**
+ *  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 javax.ws.rs.core.Response;
+import org.apache.isis.applib.annotation.Programmatic;
+import org.apache.isis.core.metamodel.adapter.ObjectAdapter;
+import org.apache.isis.viewer.restfulobjects.rendering.RendererContext;
+import org.apache.isis.viewer.restfulobjects.rendering.domainobjects.*;
+
+/**
+ * This interface is EXPERIMENTAL and may change in the future.
+ */
+public interface RepresentationService {
+
+    @Programmatic
+    Response objectRepresentation(
+            Context resourceContext,
+            ObjectAdapter objectAdapter);
+
+    @Programmatic
+    Response propertyDetails(
+            Context rendererContext,
+            ObjectAndProperty objectAndProperty,
+            MemberReprMode memberReprMode);
+
+    @Programmatic
+    Response collectionDetails(
+            Context rendererContext,
+            ObjectAndCollection objectAndCollection,
+            MemberReprMode memberReprMode);
+
+    @Programmatic
+    Response actionPrompt(
+            Context rendererContext,
+            ObjectAndAction objectAndAction);
+
+    @Programmatic
+    Response actionResult(
+            Context rendererContext,
+            ObjectAndActionInvocation objectAndActionInvocation,
+            ActionResultReprRenderer.SelfLink selfLink);
+
+    public static interface Context extends RendererContext {
+        ObjectAdapterLinkTo getAdapterLinkTo();
+    }
+}

http://git-wip-us.apache.org/repos/asf/isis/blob/6907534b/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
new file mode 100644
index 0000000..0691684
--- /dev/null
+++ b/core/viewer-restfulobjects-rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/service/RepresentationServiceForRestfulObjects.java
@@ -0,0 +1,146 @@
+/**
+ *  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 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.Programmatic;
+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.*;
+import org.apache.isis.viewer.restfulobjects.rendering.domainobjects.ActionResultReprRenderer.SelfLink;
+
+@DomainService
+public class RepresentationServiceForRestfulObjects implements RepresentationService {
+
+    private static final DateFormat ETAG_FORMAT = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSZ");
+
+    // //////////////////////////////////////////////////////////////
+    // objectRepresentation
+    // //////////////////////////////////////////////////////////////
+
+    @Override
+    @Programmatic
+    public Response objectRepresentation(
+            final Context resourceContext,
+            final ObjectAdapter objectAdapter) {
+        final DomainObjectReprRenderer renderer = new DomainObjectReprRenderer(resourceContext, null, JsonRepresentation.newMap());
+        renderer.with(objectAdapter).includesSelf();
+
+        final 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 buildResponse(responseBuilder);
+    }
+
+    // //////////////////////////////////////////////////////////////
+    // propertyDetails
+    // //////////////////////////////////////////////////////////////
+
+
+    @Override
+    @Programmatic
+    public Response propertyDetails(
+            final Context rendererContext,
+            final ObjectAndProperty objectAndProperty,
+            final MemberReprMode memberReprMode) {
+
+        final ObjectPropertyReprRenderer renderer = new ObjectPropertyReprRenderer(rendererContext);
+        renderer.with(objectAndProperty)
+                .usingLinkTo(rendererContext.getAdapterLinkTo())
+                .withMemberMode(memberReprMode);
+
+        final ResponseBuilder responseBuilder = Responses.ofOk(renderer, Caching.NONE);
+        return buildResponse(responseBuilder);
+    }
+
+    // //////////////////////////////////////////////////////////////
+    // collectionDetails
+    // //////////////////////////////////////////////////////////////
+
+    @Override
+    @Programmatic
+    public Response collectionDetails(
+            final Context rendererContext,
+            final ObjectAndCollection objectAndCollection,
+            final MemberReprMode memberReprMode) {
+
+        final ObjectCollectionReprRenderer renderer = new ObjectCollectionReprRenderer(rendererContext);
+        renderer.with(objectAndCollection)
+                .usingLinkTo(rendererContext.getAdapterLinkTo())
+                .withMemberMode(memberReprMode);
+
+        final ResponseBuilder responseBuilder = Responses.ofOk(renderer, Caching.NONE);
+        return buildResponse(responseBuilder);
+    }
+
+    // //////////////////////////////////////////////////////////////
+    // action Prompt
+    // //////////////////////////////////////////////////////////////
+
+    @Override
+    @Programmatic
+    public Response actionPrompt(
+            final Context rendererContext,
+            final ObjectAndAction objectAndAction) {
+
+        final ObjectActionReprRenderer renderer = new ObjectActionReprRenderer(rendererContext);
+        renderer.with(objectAndAction)
+                .usingLinkTo(rendererContext.getAdapterLinkTo())
+                .asStandalone();
+
+        final ResponseBuilder responseBuilder = Responses.ofOk(renderer, Caching.NONE);
+        return buildResponse(responseBuilder);
+    }
+
+    // //////////////////////////////////////////////////////////////
+    // action Result
+    // //////////////////////////////////////////////////////////////
+
+    @Override
+    @Programmatic
+    public Response actionResult(
+            final Context rendererContext,
+            final ObjectAndActionInvocation objectAndActionInvocation,
+            final SelfLink selfLink) {
+
+        final ActionResultReprRenderer renderer = new ActionResultReprRenderer(rendererContext, selfLink);
+        renderer.with(objectAndActionInvocation)
+                .using(rendererContext.getAdapterLinkTo());
+
+        final ResponseBuilder respBuilder = Responses.ofOk(renderer, Caching.NONE);
+        Responses.addLastModifiedAndETagIfAvailable(respBuilder, objectAndActionInvocation.getObjectAdapter().getVersion());
+        return buildResponse(respBuilder);
+    }
+
+    /**
+     * Overridable to allow further customization.
+     */
+    protected Response buildResponse(final ResponseBuilder responseBuilder) {
+        return responseBuilder.build();
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/isis/blob/6907534b/core/viewer-restfulobjects-rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/util/JsonWriterUtil.java
----------------------------------------------------------------------
diff --git a/core/viewer-restfulobjects-rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/util/JsonWriterUtil.java b/core/viewer-restfulobjects-rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/util/JsonWriterUtil.java
new file mode 100644
index 0000000..df90789
--- /dev/null
+++ b/core/viewer-restfulobjects-rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/util/JsonWriterUtil.java
@@ -0,0 +1,41 @@
+/*
+ *  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.util;
+
+import java.io.IOException;
+import org.codehaus.jackson.JsonGenerationException;
+import org.codehaus.jackson.map.JsonMappingException;
+import org.apache.isis.viewer.restfulobjects.applib.util.JsonMapper;
+
+public final class JsonWriterUtil {
+
+    private JsonWriterUtil(){}
+
+    public static String jsonFor(final Object object) {
+        try {
+            return JsonMapper.instance().write(object);
+        } catch (final JsonGenerationException e) {
+            throw new RuntimeException(e);
+        } catch (final JsonMappingException e) {
+            throw new RuntimeException(e);
+        } catch (final IOException e) {
+            throw new RuntimeException(e);
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/isis/blob/6907534b/core/viewer-restfulobjects-rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/util/Util.java
----------------------------------------------------------------------
diff --git a/core/viewer-restfulobjects-rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/util/Util.java b/core/viewer-restfulobjects-rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/util/Util.java
new file mode 100644
index 0000000..341b2ac
--- /dev/null
+++ b/core/viewer-restfulobjects-rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/util/Util.java
@@ -0,0 +1,107 @@
+/**
+ *  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.util;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.Map;
+import com.google.common.base.Charsets;
+import com.google.common.io.ByteStreams;
+import org.codehaus.jackson.JsonParseException;
+import org.codehaus.jackson.map.JsonMappingException;
+import org.apache.isis.viewer.restfulobjects.applib.JsonRepresentation;
+import org.apache.isis.viewer.restfulobjects.applib.client.RestfulResponse;
+import org.apache.isis.viewer.restfulobjects.applib.util.JsonMapper;
+import org.apache.isis.viewer.restfulobjects.rendering.RestfulObjectsApplicationException;
+
+public final class Util {
+
+    private Util(){}
+
+    // //////////////////////////////////////////////////////////////
+    // parsing
+    // //////////////////////////////////////////////////////////////
+
+    /**
+     * Parse {@link java.io.InputStream} to String, else throw exception
+     */
+    public static String asStringUtf8(final InputStream body) {
+        try {
+            final byte[] byteArray = ByteStreams.toByteArray(body);
+            return new String(byteArray, Charsets.UTF_8);
+        } catch (final IOException e) {
+            throw RestfulObjectsApplicationException.createWithCauseAndMessage(RestfulResponse.HttpStatusCode.BAD_REQUEST, e, "could not read body");
+        }
+    }
+
+    /**
+     * Parse (body) string to {@link org.apache.isis.viewer.restfulobjects.applib.JsonRepresentation}, else throw exception
+     */
+    public static JsonRepresentation readAsMap(final String body) {
+        if (body == null) {
+            return JsonRepresentation.newMap();
+        }
+        final String bodyTrimmed = body.trim();
+        if (bodyTrimmed.isEmpty()) {
+            return JsonRepresentation.newMap();
+        }
+        return read(bodyTrimmed, "body");
+    }
+
+    /**
+     * Parse (query) string to {@link org.apache.isis.viewer.restfulobjects.applib.JsonRepresentation}, else throw exception
+     */
+    public static JsonRepresentation readQueryStringAsMap(final String queryString) {
+        if (queryString == null) {
+            return JsonRepresentation.newMap();
+        }
+        final String queryStringTrimmed = queryString.trim();
+        if (queryStringTrimmed.isEmpty()) {
+            return JsonRepresentation.newMap();
+        }
+        return read(queryStringTrimmed, "query string");
+    }
+
+    /**
+     * REVIEW - looks similar to above methods, but now unused; can it be deleted?
+     */
+    public static JsonRepresentation readParameterMapAsMap(final Map<String, String[]> parameterMap) {
+        final JsonRepresentation map = JsonRepresentation.newMap();
+        for (final Map.Entry<String, String[]> parameter : parameterMap.entrySet()) {
+            map.mapPut(parameter.getKey(), parameter.getValue()[0]);
+        }
+        return map;
+    }
+
+    private static JsonRepresentation read(final String args, final String argsNature) {
+        try {
+            final JsonRepresentation jsonRepr = JsonMapper.instance().read(args);
+            if (!jsonRepr.isMap()) {
+                throw RestfulObjectsApplicationException.createWithMessage(RestfulResponse.HttpStatusCode.BAD_REQUEST, "could not read %s as a JSON map", argsNature);
+            }
+            return jsonRepr;
+        } catch (final JsonParseException e) {
+            throw RestfulObjectsApplicationException.createWithCauseAndMessage(RestfulResponse.HttpStatusCode.BAD_REQUEST, e, "could not parse %s", argsNature);
+        } catch (final JsonMappingException e) {
+            throw RestfulObjectsApplicationException.createWithCauseAndMessage(RestfulResponse.HttpStatusCode.BAD_REQUEST, e, "could not read %s as JSON", argsNature);
+        } catch (final IOException e) {
+            throw RestfulObjectsApplicationException.createWithCauseAndMessage(RestfulResponse.HttpStatusCode.BAD_REQUEST, e, "could not parse %s", argsNature);
+        }
+    }
+
+
+}

http://git-wip-us.apache.org/repos/asf/isis/blob/6907534b/core/viewer-restfulobjects-server/src/main/java/org/apache/isis/viewer/restfulobjects/server/HasHttpStatusCode.java
----------------------------------------------------------------------
diff --git a/core/viewer-restfulobjects-server/src/main/java/org/apache/isis/viewer/restfulobjects/server/HasHttpStatusCode.java b/core/viewer-restfulobjects-server/src/main/java/org/apache/isis/viewer/restfulobjects/server/HasHttpStatusCode.java
deleted file mode 100644
index 13cc919..0000000
--- a/core/viewer-restfulobjects-server/src/main/java/org/apache/isis/viewer/restfulobjects/server/HasHttpStatusCode.java
+++ /dev/null
@@ -1,26 +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.server;
-
-import org.apache.isis.viewer.restfulobjects.applib.client.RestfulResponse.HttpStatusCode;
-
-public interface HasHttpStatusCode {
-
-    HttpStatusCode getHttpStatusCode();
-}

http://git-wip-us.apache.org/repos/asf/isis/blob/6907534b/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 efa2d7a..46b602a 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
@@ -41,7 +41,8 @@ import org.apache.isis.viewer.restfulobjects.applib.client.RestfulRequest.Domain
 import org.apache.isis.viewer.restfulobjects.applib.client.RestfulRequest.RequestParameter;
 import org.apache.isis.viewer.restfulobjects.applib.client.RestfulResponse.HttpStatusCode;
 import org.apache.isis.viewer.restfulobjects.rendering.RendererContext;
-import org.apache.isis.viewer.restfulobjects.server.resources.Util;
+import org.apache.isis.viewer.restfulobjects.rendering.RestfulObjectsApplicationException;
+import org.apache.isis.viewer.restfulobjects.rendering.util.Util;
 
 public class ResourceContext implements RendererContext {
 
@@ -118,8 +119,8 @@ public class ResourceContext implements RendererContext {
     private void ensureDomainModelQueryParamSupported() {
         final DomainModel domainModel = getArg(RequestParameter.DOMAIN_MODEL);
         if(domainModel != DomainModel.FORMAL) {
-            throw RestfulObjectsApplicationException.createWithMessage(HttpStatusCode.BAD_REQUEST,  
-                                           "x-ro-domain-model of '%s' is not supported", domainModel);
+            throw RestfulObjectsApplicationException.createWithMessage(HttpStatusCode.BAD_REQUEST,
+                    "x-ro-domain-model of '%s' is not supported", domainModel);
         }
     }
 
@@ -238,7 +239,6 @@ public class ResourceContext implements RendererContext {
     }
 
 
-    
     public Localization getLocalization() {
         return localization;
     }

http://git-wip-us.apache.org/repos/asf/isis/blob/6907534b/core/viewer-restfulobjects-server/src/main/java/org/apache/isis/viewer/restfulobjects/server/RestfulObjectsApplicationException.java
----------------------------------------------------------------------
diff --git a/core/viewer-restfulobjects-server/src/main/java/org/apache/isis/viewer/restfulobjects/server/RestfulObjectsApplicationException.java b/core/viewer-restfulobjects-server/src/main/java/org/apache/isis/viewer/restfulobjects/server/RestfulObjectsApplicationException.java
index 01948f7..7f0d36e 100644
--- a/core/viewer-restfulobjects-server/src/main/java/org/apache/isis/viewer/restfulobjects/server/RestfulObjectsApplicationException.java
+++ b/core/viewer-restfulobjects-server/src/main/java/org/apache/isis/viewer/restfulobjects/server/RestfulObjectsApplicationException.java
@@ -19,51 +19,19 @@
 package org.apache.isis.viewer.restfulobjects.server;
 
 import org.apache.isis.viewer.restfulobjects.applib.JsonRepresentation;
-import org.apache.isis.viewer.restfulobjects.applib.client.RestfulResponse.HttpStatusCode;
+import org.apache.isis.viewer.restfulobjects.applib.client.RestfulResponse;
 
-public class RestfulObjectsApplicationException extends RuntimeException implements HasHttpStatusCode {
-
-    public static final RestfulObjectsApplicationException create(final HttpStatusCode httpStatusCode) {
-        return createWithCause(httpStatusCode, null);
-    }
-
-    public static RestfulObjectsApplicationException createWithMessage(final HttpStatusCode httpStatusCode, final String message, final Object... args) {
-        return createWithCauseAndMessage(httpStatusCode, (Exception) null, message, args);
-    }
-
-    public static RestfulObjectsApplicationException createWithCause(final HttpStatusCode httpStatusCode, final Exception cause) {
-        return createWithCauseAndMessage(httpStatusCode, cause, null);
-    }
-
-    public static RestfulObjectsApplicationException createWithCauseAndMessage(final HttpStatusCode httpStatusCode, final Exception cause, final String message, final Object... args) {
-        return new RestfulObjectsApplicationException(httpStatusCode, formatString(message, args), cause, null);
-    }
-
-    public static RestfulObjectsApplicationException createWithBody(final HttpStatusCode httpStatusCode, final JsonRepresentation body, final String message, final Object... args) {
-        return new RestfulObjectsApplicationException(httpStatusCode, formatString(message, args), null, body);
-    }
-
-    private static String formatString(final String formatStr, final Object... args) {
-        return formatStr != null ? String.format(formatStr, args) : null;
-    }
-
-    private static final long serialVersionUID = 1L;
-    private final HttpStatusCode httpStatusCode;
-    private final JsonRepresentation body;
-
-    private RestfulObjectsApplicationException(final HttpStatusCode httpStatusCode, final String message, final Throwable cause, final JsonRepresentation body) {
-        super(message, cause);
-        this.httpStatusCode = httpStatusCode;
-        this.body = body;
-    }
-
-    @Override
-    public HttpStatusCode getHttpStatusCode() {
-        return httpStatusCode;
-    }
+/**
+ * For backward compatibility only.
+ */
+@Deprecated
+public class RestfulObjectsApplicationException extends org.apache.isis.viewer.restfulobjects.rendering.RestfulObjectsApplicationException {
 
-    public JsonRepresentation getBody() {
-        return body;
+    public RestfulObjectsApplicationException(
+            final RestfulResponse.HttpStatusCode httpStatusCode,
+            final String message,
+            final Throwable cause,
+            final JsonRepresentation body) {
+        super(httpStatusCode, message, cause, body);
     }
-
 }

http://git-wip-us.apache.org/repos/asf/isis/blob/6907534b/core/viewer-restfulobjects-server/src/main/java/org/apache/isis/viewer/restfulobjects/server/RestfulObjectsApplicationExceptionMapper.java
----------------------------------------------------------------------
diff --git a/core/viewer-restfulobjects-server/src/main/java/org/apache/isis/viewer/restfulobjects/server/RestfulObjectsApplicationExceptionMapper.java b/core/viewer-restfulobjects-server/src/main/java/org/apache/isis/viewer/restfulobjects/server/RestfulObjectsApplicationExceptionMapper.java
index 0c9eb4b..4236704 100644
--- a/core/viewer-restfulobjects-server/src/main/java/org/apache/isis/viewer/restfulobjects/server/RestfulObjectsApplicationExceptionMapper.java
+++ b/core/viewer-restfulobjects-server/src/main/java/org/apache/isis/viewer/restfulobjects/server/RestfulObjectsApplicationExceptionMapper.java
@@ -33,6 +33,8 @@ import org.apache.isis.viewer.restfulobjects.applib.JsonRepresentation;
 import org.apache.isis.viewer.restfulobjects.applib.RestfulMediaType;
 import org.apache.isis.viewer.restfulobjects.applib.client.RestfulResponse;
 import org.apache.isis.viewer.restfulobjects.applib.util.JsonMapper;
+import org.apache.isis.viewer.restfulobjects.rendering.HasHttpStatusCode;
+import org.apache.isis.viewer.restfulobjects.rendering.RestfulObjectsApplicationException;
 
 //@Path("/") // FIXME: workaround for TomEE ... but breaks the RestEasy TCK tests so commented out:-(
 @Provider

http://git-wip-us.apache.org/repos/asf/isis/blob/6907534b/core/viewer-restfulobjects-server/src/main/java/org/apache/isis/viewer/restfulobjects/server/resources/DomainObjectResourceServerside.java
----------------------------------------------------------------------
diff --git a/core/viewer-restfulobjects-server/src/main/java/org/apache/isis/viewer/restfulobjects/server/resources/DomainObjectResourceServerside.java b/core/viewer-restfulobjects-server/src/main/java/org/apache/isis/viewer/restfulobjects/server/resources/DomainObjectResourceServerside.java
index 9d63296..895a250 100644
--- a/core/viewer-restfulobjects-server/src/main/java/org/apache/isis/viewer/restfulobjects/server/resources/DomainObjectResourceServerside.java
+++ b/core/viewer-restfulobjects-server/src/main/java/org/apache/isis/viewer/restfulobjects/server/resources/DomainObjectResourceServerside.java
@@ -35,7 +35,9 @@ import org.apache.isis.viewer.restfulobjects.applib.RestfulMediaType;
 import org.apache.isis.viewer.restfulobjects.applib.client.RestfulResponse;
 import org.apache.isis.viewer.restfulobjects.applib.client.RestfulResponse.HttpStatusCode;
 import org.apache.isis.viewer.restfulobjects.applib.domainobjects.DomainObjectResource;
-import org.apache.isis.viewer.restfulobjects.server.RestfulObjectsApplicationException;
+import org.apache.isis.viewer.restfulobjects.rendering.RestfulObjectsApplicationException;
+import org.apache.isis.viewer.restfulobjects.rendering.domainobjects.MemberReprMode;
+import org.apache.isis.viewer.restfulobjects.rendering.util.Util;
 
 @Path("/objects")
 public class DomainObjectResourceServerside extends ResourceAbstract implements DomainObjectResource {
@@ -163,7 +165,10 @@ public class DomainObjectResourceServerside extends ResourceAbstract implements
         final ObjectAdapter objectAdapter = getObjectAdapterElseThrowNotFound(domainType, instanceId);
         final DomainResourceHelper helper = getDomainResourceHelper(objectAdapter);
 
-        return helper.propertyDetails(propertyId, ResponseGeneratorService.MemberMode.NOT_MUTATING, Caching.NONE);
+        return helper.propertyDetails(
+                propertyId,
+                MemberReprMode.READ
+        );
     }
 
     @Override
@@ -192,7 +197,10 @@ public class DomainObjectResourceServerside extends ResourceAbstract implements
 
         property.set(objectAdapter, argAdapter);
 
-        return helper.propertyDetails(propertyId, ResponseGeneratorService.MemberMode.MUTATING, Caching.NONE);
+        return helper.propertyDetails(
+                propertyId,
+                MemberReprMode.WRITE
+        );
     }
 
     @Override
@@ -216,7 +224,10 @@ public class DomainObjectResourceServerside extends ResourceAbstract implements
 
         property.set(objectAdapter, null);
 
-        return helper.propertyDetails(propertyId, ResponseGeneratorService.MemberMode.MUTATING, Caching.NONE);
+        return helper.propertyDetails(
+                propertyId,
+                MemberReprMode.WRITE
+        );
     }
 
     @Override
@@ -238,7 +249,7 @@ public class DomainObjectResourceServerside extends ResourceAbstract implements
         final ObjectAdapter objectAdapter = getObjectAdapterElseThrowNotFound(domainType, instanceId);
         final DomainResourceHelper helper = getDomainResourceHelper(objectAdapter);
 
-        return helper.collectionDetails(collectionId, ResponseGeneratorService.MemberMode.NOT_MUTATING, Caching.NONE);
+        return helper.collectionDetails(collectionId, MemberReprMode.READ);
     }
 
     @Override
@@ -271,7 +282,7 @@ public class DomainObjectResourceServerside extends ResourceAbstract implements
 
         collection.addElement(objectAdapter, argAdapter);
 
-        return helper.collectionDetails(collectionId, ResponseGeneratorService.MemberMode.MUTATING, Caching.NONE);
+        return helper.collectionDetails(collectionId, MemberReprMode.WRITE);
     }
 
     @Override
@@ -304,7 +315,7 @@ public class DomainObjectResourceServerside extends ResourceAbstract implements
 
         collection.addElement(objectAdapter, argAdapter);
 
-        return helper.collectionDetails(collectionId, ResponseGeneratorService.MemberMode.MUTATING, Caching.NONE);
+        return helper.collectionDetails(collectionId, MemberReprMode.WRITE);
     }
 
     @Override
@@ -331,7 +342,7 @@ public class DomainObjectResourceServerside extends ResourceAbstract implements
 
         collection.removeElement(objectAdapter, argAdapter);
 
-        return helper.collectionDetails(collectionId, ResponseGeneratorService.MemberMode.MUTATING, Caching.NONE);
+        return helper.collectionDetails(collectionId, MemberReprMode.WRITE);
     }
 
     // //////////////////////////////////////////////////////////

http://git-wip-us.apache.org/repos/asf/isis/blob/6907534b/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 db04307..9b623ba 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
@@ -16,19 +16,87 @@
  */
 package org.apache.isis.viewer.restfulobjects.server.resources;
 
+import java.util.List;
 import javax.ws.rs.core.Response;
+import org.apache.isis.applib.annotation.ActionSemantics;
+import org.apache.isis.applib.annotation.Where;
+import org.apache.isis.applib.profiles.Localization;
+import org.apache.isis.core.commons.authentication.AuthenticationSession;
+import org.apache.isis.core.commons.config.IsisConfiguration;
 import org.apache.isis.core.metamodel.adapter.ObjectAdapter;
+import org.apache.isis.core.metamodel.spec.feature.ObjectAction;
+import org.apache.isis.core.metamodel.spec.feature.OneToManyAssociation;
+import org.apache.isis.core.metamodel.spec.feature.OneToOneAssociation;
 import org.apache.isis.core.runtime.system.context.IsisContext;
 import org.apache.isis.core.runtime.system.persistence.PersistenceSession;
 import org.apache.isis.viewer.restfulobjects.applib.JsonRepresentation;
-import org.apache.isis.viewer.restfulobjects.rendering.domainobjects.DomainObjectLinkTo;
-import org.apache.isis.viewer.restfulobjects.rendering.domainobjects.ObjectAdapterLinkTo;
+import org.apache.isis.viewer.restfulobjects.applib.client.RestfulResponse;
+import org.apache.isis.viewer.restfulobjects.rendering.RendererContext;
+import org.apache.isis.viewer.restfulobjects.rendering.RestfulObjectsApplicationException;
+import org.apache.isis.viewer.restfulobjects.rendering.domainobjects.*;
+import org.apache.isis.viewer.restfulobjects.rendering.service.RepresentationService;
 import org.apache.isis.viewer.restfulobjects.server.ResourceContext;
-import org.apache.isis.viewer.restfulobjects.server.resources.ResourceAbstract.Caching;
 
-public class DomainResourceHelper implements ResponseGeneratorService.ResponseContext {
+public class DomainResourceHelper {
 
-    private final ResponseGeneratorService generatorService;
+    static class RepresentationServiceContextAdapter implements RepresentationService.Context {
+
+        private final RendererContext rendererContext;
+        private final ObjectAdapterLinkTo adapterLinkTo;
+
+        RepresentationServiceContextAdapter(final RendererContext rendererContext, final ObjectAdapterLinkTo adapterLinkTo) {
+            this.rendererContext = rendererContext;
+            this.adapterLinkTo = adapterLinkTo;
+        }
+
+        @Override
+        public ObjectAdapterLinkTo getAdapterLinkTo() {
+            return adapterLinkTo;
+        }
+
+        @Override
+        public String urlFor(String url) {
+            return rendererContext.urlFor(url);
+        }
+
+        @Override
+        public AuthenticationSession getAuthenticationSession() {
+            return rendererContext.getAuthenticationSession();
+        }
+
+        @Override
+        public IsisConfiguration getConfiguration() {
+            return rendererContext.getConfiguration();
+        }
+
+        @Override
+        public PersistenceSession getPersistenceSession() {
+            return rendererContext.getPersistenceSession();
+        }
+
+        @Override
+        public Where getWhere() {
+            return rendererContext.getWhere();
+        }
+
+        @Override
+        public List<List<String>> getFollowLinks() {
+            return rendererContext.getFollowLinks();
+        }
+
+        @Override
+        public Localization getLocalization() {
+            return rendererContext.getLocalization();
+        }
+
+        @Override
+        public boolean canEagerlyRender(ObjectAdapter objectAdapter) {
+            return rendererContext.canEagerlyRender(objectAdapter);
+        }
+    }
+
+    private final RepresentationService representationService;
+    private RepresentationServiceContextAdapter representationServiceContext;
 
     public DomainResourceHelper(final ResourceContext resourceContext, final ObjectAdapter objectAdapter) {
         this.resourceContext = resourceContext;
@@ -36,75 +104,166 @@ public class DomainResourceHelper implements ResponseGeneratorService.ResponseCo
 
         using(new DomainObjectLinkTo());
 
-        generatorService = lookupService(ResponseGeneratorService.class);
+        representationService = lookupService(RepresentationService.class);
     }
 
-    public DomainResourceHelper using(final ObjectAdapterLinkTo linkTo) {
-        adapterLinkTo = linkTo;
-        adapterLinkTo.usingUrlBase(resourceContext).with(objectAdapter);
-        return this;
-    }
+    public DomainResourceHelper using(final ObjectAdapterLinkTo adapterLinkTo) {
 
-    //region > ResponseContext impl
+        representationServiceContext = new RepresentationServiceContextAdapter(resourceContext, adapterLinkTo);
 
-    private final ResourceContext resourceContext;
-    private final ObjectAdapter objectAdapter;
-    private ObjectAdapterLinkTo adapterLinkTo;
+        adapterLinkTo.usingUrlBase(resourceContext)
+                     .with(objectAdapter);
 
-    @Override
-    public ResourceContext getResourceContext() {
-        return resourceContext;
+        return this;
     }
 
-    @Override
-    public ObjectAdapter getObjectAdapter() {
-        return objectAdapter;
-    }
+    private final ResourceContext resourceContext;
+    private final ObjectAdapter objectAdapter;
 
-    @Override
-    public ObjectAdapterLinkTo getAdapterLinkTo() {
-        return adapterLinkTo;
-    }
-    //endregion
 
+    // //////////////////////////////////////
+    // Helpers (resource delegate here)
+    // //////////////////////////////////////
 
+    /**
+     * Simply delegates to the {@link org.apache.isis.viewer.restfulobjects.rendering.service.RepresentationService} to
+     * render a representation of the object.
+     */
     public Response objectRepresentation() {
-        return generatorService.objectRepresentation(this);
+        return representationService.objectRepresentation(representationServiceContext, objectAdapter);
     }
 
+    /**
+     * Obtains the property (checking it is visible) of the object and then delegates to the
+     * {@link org.apache.isis.viewer.restfulobjects.rendering.service.RepresentationService} to render a representation
+     * of that property.
+     */
     public Response propertyDetails(
             final String propertyId,
-            final ResponseGeneratorService.MemberMode memberMode,
-            final Caching caching) {
-        return generatorService.propertyDetails(this, propertyId, memberMode, caching);
+            final MemberReprMode memberMode) {
+
+        ObjectAdapterAccessHelper accessHelper = new ObjectAdapterAccessHelper(representationServiceContext, objectAdapter);
+
+        final OneToOneAssociation property = accessHelper.getPropertyThatIsVisibleForIntent(propertyId, ObjectAdapterAccessHelper.Intent.ACCESS);
+
+        return representationService.propertyDetails(representationServiceContext, new ObjectAndProperty(objectAdapter, property), memberMode);
     }
 
+
+    /**
+     * Obtains the collection (checking it is visible) of the object and then delegates to the
+     * {@link org.apache.isis.viewer.restfulobjects.rendering.service.RepresentationService} to render a representation
+     * of that collection.
+     */
     public Response collectionDetails(
             final String collectionId,
-            final ResponseGeneratorService.MemberMode memberMode,
-            final Caching caching) {
+            final MemberReprMode memberMode) {
+
+        ObjectAdapterAccessHelper accessHelper = new ObjectAdapterAccessHelper(representationServiceContext, objectAdapter);
+
+        final OneToManyAssociation collection = accessHelper.getCollectionThatIsVisibleForIntent(collectionId, ObjectAdapterAccessHelper.Intent.ACCESS);
 
-        return generatorService.collectionDetails(this, collectionId, memberMode, caching);
+        return representationService.collectionDetails(representationServiceContext, new ObjectAndCollection(objectAdapter, collection), memberMode);
     }
 
+
+    /**
+     * Obtains the action details (arguments etc), checking it is visible, of the object and then delegates to the
+     * {@link org.apache.isis.viewer.restfulobjects.rendering.service.RepresentationService} to render a representation
+     * of that object's action (arguments).
+     */
     public Response actionPrompt(final String actionId) {
 
-        return generatorService.actionPrompt(this, actionId);
+        ObjectAdapterAccessHelper accessHelper = new ObjectAdapterAccessHelper(representationServiceContext, objectAdapter);
+
+        final ObjectAction action = accessHelper.getObjectActionThatIsVisibleForIntent(actionId, ObjectAdapterAccessHelper.Intent.ACCESS);
+
+        return representationService.actionPrompt(representationServiceContext, new ObjectAndAction(objectAdapter, action));
     }
 
+    /**
+     * Invokes the action for the object  (checking it is visible) and then delegates to the
+     * {@link org.apache.isis.viewer.restfulobjects.rendering.service.RepresentationService} to render a representation
+     * of the result of that action.
+     *
+     * <p>
+     *     The action must have {@link org.apache.isis.applib.annotation.ActionSemantics.Of#SAFE safe} semantics
+     *     otherwise an error response is thrown.
+     * </p>
+     */
     public Response invokeActionQueryOnly(final String actionId, final JsonRepresentation arguments) {
 
-        return generatorService.invokeActionQueryOnly(this, actionId, arguments);
+        final ObjectAdapterAccessHelper accessHelper = new ObjectAdapterAccessHelper(representationServiceContext, objectAdapter);
+
+        final ObjectAction action = accessHelper.getObjectActionThatIsVisibleForIntent(actionId, ObjectAdapterAccessHelper.Intent.MUTATE);
+
+        final ActionSemantics.Of actionSemantics = action.getSemantics();
+        if (actionSemantics != ActionSemantics.Of.SAFE) {
+            throw RestfulObjectsApplicationException.createWithMessage(RestfulResponse.HttpStatusCode.METHOD_NOT_ALLOWED, "Method not allowed; action '%s' is not query only", action.getId());
+        }
+
+        return invokeActionUsingAdapters(action, arguments, ActionResultReprRenderer.SelfLink.INCLUDED);
     }
 
+    /**
+     * Invokes the action for the object  (checking it is visible) and then delegates to the
+     * {@link org.apache.isis.viewer.restfulobjects.rendering.service.RepresentationService} to render a representation
+     * of the result of that action.
+     *
+     * <p>
+     *     The action must have {@link org.apache.isis.applib.annotation.ActionSemantics.Of#IDEMPOTENT idempotent}
+     *     semantics otherwise an error response is thrown.
+     * </p>
+     */
     public Response invokeActionIdempotent(final String actionId, final JsonRepresentation arguments) {
 
-        return generatorService.invokeActionIdempotent(this, actionId, arguments);
+        final ObjectAdapterAccessHelper accessHelper = new ObjectAdapterAccessHelper(representationServiceContext, objectAdapter);
+
+        final ObjectAction action = accessHelper.getObjectActionThatIsVisibleForIntent(actionId, ObjectAdapterAccessHelper.Intent.MUTATE);
+
+        final ActionSemantics.Of actionSemantics = action.getSemantics();
+        if (!actionSemantics.isIdempotentInNature()) {
+            throw RestfulObjectsApplicationException.createWithMessage(RestfulResponse.HttpStatusCode.METHOD_NOT_ALLOWED, "Method not allowed; action '%s' is not idempotent", action.getId());
+        }
+        return invokeActionUsingAdapters(action, arguments, ActionResultReprRenderer.SelfLink.EXCLUDED);
     }
 
+    /**
+     * Invokes the action for the object  (checking it is visible) and then delegates to the
+     * {@link org.apache.isis.viewer.restfulobjects.rendering.service.RepresentationService} to render a representation
+     * of the result of that action.
+     */
     public Response invokeAction(final String actionId, final JsonRepresentation arguments) {
 
-        return generatorService.invokeAction(this, actionId, arguments);
+        ObjectAdapterAccessHelper accessHelper = new ObjectAdapterAccessHelper(representationServiceContext, objectAdapter);
+
+        final ObjectAction action = accessHelper.getObjectActionThatIsVisibleForIntent(actionId, ObjectAdapterAccessHelper.Intent.MUTATE);
+
+        return invokeActionUsingAdapters(action, arguments, ActionResultReprRenderer.SelfLink.EXCLUDED);
+    }
+
+
+    private Response invokeActionUsingAdapters(
+            final ObjectAction action,
+            final JsonRepresentation arguments,
+            final ActionResultReprRenderer.SelfLink selfLink) {
+
+        final RepresentationService.Context rendererContext = representationServiceContext;
+        final ObjectAdapter objectAdapter = this.objectAdapter;
+
+        final ObjectActionArgHelper argHelper = new ObjectActionArgHelper(rendererContext, objectAdapter, action);
+
+        final List<ObjectAdapter> argAdapters = argHelper.parseAndValidateArguments(arguments);
+
+        // invoke
+        final ObjectAdapter[] argArray2 = argAdapters.toArray(new ObjectAdapter[0]);
+        final ObjectAdapter returnedAdapter = action.execute(objectAdapter, argArray2);
+
+        final ObjectAndActionInvocation objectAndActionInvocation =
+                new ObjectAndActionInvocation(this.objectAdapter, action, arguments, returnedAdapter);
+
+        // response
+        return representationService.actionResult(representationServiceContext, objectAndActionInvocation, selfLink);
     }
 
 

http://git-wip-us.apache.org/repos/asf/isis/blob/6907534b/core/viewer-restfulobjects-server/src/main/java/org/apache/isis/viewer/restfulobjects/server/resources/DomainServiceResourceServerside.java
----------------------------------------------------------------------
diff --git a/core/viewer-restfulobjects-server/src/main/java/org/apache/isis/viewer/restfulobjects/server/resources/DomainServiceResourceServerside.java b/core/viewer-restfulobjects-server/src/main/java/org/apache/isis/viewer/restfulobjects/server/resources/DomainServiceResourceServerside.java
index d0ecc93..3c7ffa2 100644
--- a/core/viewer-restfulobjects-server/src/main/java/org/apache/isis/viewer/restfulobjects/server/resources/DomainServiceResourceServerside.java
+++ b/core/viewer-restfulobjects-server/src/main/java/org/apache/isis/viewer/restfulobjects/server/resources/DomainServiceResourceServerside.java
@@ -29,9 +29,11 @@ import org.apache.isis.viewer.restfulobjects.applib.RepresentationType;
 import org.apache.isis.viewer.restfulobjects.applib.RestfulMediaType;
 import org.apache.isis.viewer.restfulobjects.applib.client.RestfulResponse;
 import org.apache.isis.viewer.restfulobjects.applib.domainobjects.DomainServiceResource;
+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.DomainServiceLinkTo;
-import org.apache.isis.viewer.restfulobjects.server.RestfulObjectsApplicationException;
+import org.apache.isis.viewer.restfulobjects.rendering.RestfulObjectsApplicationException;
 
 @Path("/services")
 public class DomainServiceResourceServerside extends ResourceAbstract implements DomainServiceResource {

http://git-wip-us.apache.org/repos/asf/isis/blob/6907534b/core/viewer-restfulobjects-server/src/main/java/org/apache/isis/viewer/restfulobjects/server/resources/DomainTypeResourceServerside.java
----------------------------------------------------------------------
diff --git a/core/viewer-restfulobjects-server/src/main/java/org/apache/isis/viewer/restfulobjects/server/resources/DomainTypeResourceServerside.java b/core/viewer-restfulobjects-server/src/main/java/org/apache/isis/viewer/restfulobjects/server/resources/DomainTypeResourceServerside.java
index 46700c3..1135ba9 100644
--- a/core/viewer-restfulobjects-server/src/main/java/org/apache/isis/viewer/restfulobjects/server/resources/DomainTypeResourceServerside.java
+++ b/core/viewer-restfulobjects-server/src/main/java/org/apache/isis/viewer/restfulobjects/server/resources/DomainTypeResourceServerside.java
@@ -45,7 +45,9 @@ import org.apache.isis.viewer.restfulobjects.applib.RestfulMediaType;
 import org.apache.isis.viewer.restfulobjects.applib.client.RestfulResponse.HttpStatusCode;
 import org.apache.isis.viewer.restfulobjects.applib.domaintypes.DomainTypeResource;
 import org.apache.isis.viewer.restfulobjects.applib.util.UrlEncodingUtils;
+import org.apache.isis.viewer.restfulobjects.rendering.Caching;
 import org.apache.isis.viewer.restfulobjects.rendering.LinkBuilder;
+import org.apache.isis.viewer.restfulobjects.rendering.Responses;
 import org.apache.isis.viewer.restfulobjects.rendering.domaintypes.ActionDescriptionReprRenderer;
 import org.apache.isis.viewer.restfulobjects.rendering.domaintypes.ActionParameterDescriptionReprRenderer;
 import org.apache.isis.viewer.restfulobjects.rendering.domaintypes.CollectionDescriptionReprRenderer;
@@ -57,7 +59,8 @@ import org.apache.isis.viewer.restfulobjects.rendering.domaintypes.ParentSpecAnd
 import org.apache.isis.viewer.restfulobjects.rendering.domaintypes.PropertyDescriptionReprRenderer;
 import org.apache.isis.viewer.restfulobjects.rendering.domaintypes.TypeActionResultReprRenderer;
 import org.apache.isis.viewer.restfulobjects.rendering.domaintypes.TypeListReprRenderer;
-import org.apache.isis.viewer.restfulobjects.server.RestfulObjectsApplicationException;
+import org.apache.isis.viewer.restfulobjects.rendering.RestfulObjectsApplicationException;
+import org.apache.isis.viewer.restfulobjects.rendering.util.Util;
 import org.apache.isis.viewer.restfulobjects.server.util.UrlParserUtils;
 
 /**

http://git-wip-us.apache.org/repos/asf/isis/blob/6907534b/core/viewer-restfulobjects-server/src/main/java/org/apache/isis/viewer/restfulobjects/server/resources/HomePageResourceServerside.java
----------------------------------------------------------------------
diff --git a/core/viewer-restfulobjects-server/src/main/java/org/apache/isis/viewer/restfulobjects/server/resources/HomePageResourceServerside.java b/core/viewer-restfulobjects-server/src/main/java/org/apache/isis/viewer/restfulobjects/server/resources/HomePageResourceServerside.java
index 72fef2b..675acff 100644
--- a/core/viewer-restfulobjects-server/src/main/java/org/apache/isis/viewer/restfulobjects/server/resources/HomePageResourceServerside.java
+++ b/core/viewer-restfulobjects-server/src/main/java/org/apache/isis/viewer/restfulobjects/server/resources/HomePageResourceServerside.java
@@ -31,7 +31,9 @@ import org.apache.isis.viewer.restfulobjects.applib.RestfulMediaType;
 import org.apache.isis.viewer.restfulobjects.applib.client.RestfulResponse;
 import org.apache.isis.viewer.restfulobjects.applib.client.RestfulResponse.HttpStatusCode;
 import org.apache.isis.viewer.restfulobjects.applib.homepage.HomePageResource;
-import org.apache.isis.viewer.restfulobjects.server.RestfulObjectsApplicationException;
+import org.apache.isis.viewer.restfulobjects.rendering.Caching;
+import org.apache.isis.viewer.restfulobjects.rendering.Responses;
+import org.apache.isis.viewer.restfulobjects.rendering.RestfulObjectsApplicationException;
 
 public class HomePageResourceServerside extends ResourceAbstract implements HomePageResource {