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 2013/04/24 08:31:48 UTC

git commit: ISIS-233: more tck tests for RO viewer

Updated Branches:
  refs/heads/dan/ISIS-233-ro b3a39bc91 -> 584eb10a1


ISIS-233: more tck tests for RO viewer

fixes for actionresult returning a domain object representation.
can now pass in ?id=123 as well


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

Branch: refs/heads/dan/ISIS-233-ro
Commit: 584eb10a1f9854003fce94728f0418fa836c3670
Parents: b3a39bc
Author: Dan Haywood <da...@apache.org>
Authored: Wed Apr 24 07:31:27 2013 +0100
Committer: Dan Haywood <da...@apache.org>
Committed: Wed Apr 24 07:31:27 2013 +0100

----------------------------------------------------------------------
 .gitignore                                         |    4 +
 .../restfulobjects/applib/JsonRepresentation.java  |   16 +--
 .../applib/client/RestfulResponse.java             |    1 +
 .../restfulobjects/applib/util/JsonNodeUtils.java  |    8 +
 .../JsonRepresentationTest_getLink_isLink.java     |   22 +++
 .../domainobjects/ActionResultReprRenderer.java    |   62 +++++---
 .../restfulobjects/server/ResourceContext.java     |   41 +++++-
 .../server/resources/DomainResourceHelper.java     |   11 +-
 .../isis/viewer/restfulobjects/tck/Util.java       |    3 +
 ...Get_thenRepresentation_containsSelfLink_ok.java |   98 +++++++++++
 .../invoke/Get_whenList_thenRepresentation_ok.java |  112 -------------
 ...nseHeaders_ContentType_andContentLength_ok.java |  112 +++++++++++++
 ..._thenResponseHeaders_ContentLength_ok_TODO.java |   13 --
 ...st_thenResponseHeaders_ContentType_ok_TODO.java |   13 --
 ...nseHeaders_ContentType_andContentLength_ok.java |  125 +++++++++++++++
 ...et_whenObject_isNull_thenRepresentation_ok.java |   97 +++++++++++
 .../Get_whenObject_thenRepresentation_ok_TODO.java |   13 --
 ..._thenResponseHeaders_ContentLength_ok_TODO.java |   13 --
 ...ct_thenResponseHeaders_ContentType_ok_TODO.java |   13 --
 ...enRepresentation_doesNotContainSelfLink_ok.java |   93 +++++++++++
 ...enRepresentation_doesNotContainSelfLink_ok.java |   93 +++++++++++
 .../tck/dom/actions/ActionsEntityRepository.java   |   23 ++-
 22 files changed, 768 insertions(+), 218 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/isis/blob/584eb10a/.gitignore
----------------------------------------------------------------------
diff --git a/.gitignore b/.gitignore
index de717da..c88d318 100644
--- a/.gitignore
+++ b/.gitignore
@@ -21,6 +21,7 @@ component/security/sql/hsql-db/
 # log files
 datanucleus.log
 isis.log
+hs_err_pid*.log
 
 # Package Files #
 *.jar
@@ -29,3 +30,6 @@ isis.log
 
 pom.xml.tag
 pom.xml.releaseBackup
+
+*.jdproj
+JArchitectOut/

http://git-wip-us.apache.org/repos/asf/isis/blob/584eb10a/component/viewer/restfulobjects/applib/src/main/java/org/apache/isis/viewer/restfulobjects/applib/JsonRepresentation.java
----------------------------------------------------------------------
diff --git a/component/viewer/restfulobjects/applib/src/main/java/org/apache/isis/viewer/restfulobjects/applib/JsonRepresentation.java b/component/viewer/restfulobjects/applib/src/main/java/org/apache/isis/viewer/restfulobjects/applib/JsonRepresentation.java
index 2f6e52c..ac23b28 100644
--- a/component/viewer/restfulobjects/applib/src/main/java/org/apache/isis/viewer/restfulobjects/applib/JsonRepresentation.java
+++ b/component/viewer/restfulobjects/applib/src/main/java/org/apache/isis/viewer/restfulobjects/applib/JsonRepresentation.java
@@ -782,12 +782,8 @@ public class JsonRepresentation {
         final Function<JsonNode, ?> transformer = representationInstantiatorFor(requiredType);
         final ArrayNode arrayNode = (ArrayNode) jsonNode;
         final Iterator<JsonNode> iterator = arrayNode.iterator();
-        final Function<JsonNode, T> typedTransformer = asT(transformer); // necessary
-                                                                         // to
-                                                                         // do
-                                                                         // in
-                                                                         // two
-                                                                         // steps
+        // necessary to do in two steps
+        final Function<JsonNode, T> typedTransformer = asT(transformer); 
         return Iterators.transform(iterator, typedTransformer);
     }
 
@@ -797,12 +793,12 @@ public class JsonRepresentation {
     }
 
     public JsonRepresentation arrayGet(final int i) {
-        ensureIsAnArrayAtLeastAsLargeAs(i);
+        ensureIsAnArrayAtLeastAsLargeAs(i+1);
         return new JsonRepresentation(jsonNode.get(i));
     }
 
     public void arraySetElementAt(final int i, final JsonRepresentation objectRepr) {
-        ensureIsAnArrayAtLeastAsLargeAs(i);
+        ensureIsAnArrayAtLeastAsLargeAs(i+1);
         if (objectRepr.isArray()) {
             throw new IllegalArgumentException("Representation being set cannot be an array");
         }
@@ -815,8 +811,8 @@ public class JsonRepresentation {
         if (!jsonNode.isArray()) {
             throw new IllegalStateException("Is not an array");
         }
-        if (i >= size()) {
-            throw new IndexOutOfBoundsException("array has " + size() + " elements");
+        if (i > size()) {
+            throw new IndexOutOfBoundsException("array has only " + size() + " elements");
         }
     }
 

http://git-wip-us.apache.org/repos/asf/isis/blob/584eb10a/component/viewer/restfulobjects/applib/src/main/java/org/apache/isis/viewer/restfulobjects/applib/client/RestfulResponse.java
----------------------------------------------------------------------
diff --git a/component/viewer/restfulobjects/applib/src/main/java/org/apache/isis/viewer/restfulobjects/applib/client/RestfulResponse.java b/component/viewer/restfulobjects/applib/src/main/java/org/apache/isis/viewer/restfulobjects/applib/client/RestfulResponse.java
index 2562ef6..c137942 100644
--- a/component/viewer/restfulobjects/applib/src/main/java/org/apache/isis/viewer/restfulobjects/applib/client/RestfulResponse.java
+++ b/component/viewer/restfulobjects/applib/src/main/java/org/apache/isis/viewer/restfulobjects/applib/client/RestfulResponse.java
@@ -247,6 +247,7 @@ public class RestfulResponse<T> {
         public final static Header<Date> LAST_MODIFIED = new Header<Date>("Last-Modified", Parser.forDate());
         public final static Header<CacheControl> CACHE_CONTROL = new Header<CacheControl>("Cache-Control", Parser.forCacheControl());
         public final static Header<MediaType> CONTENT_TYPE = new Header<MediaType>("Content-Type", Parser.forJaxRsMediaType());
+        public final static Header<Integer> CONTENT_LENGTH = new Header<Integer>("Content-Length", Parser.forInteger());
         public final static Header<String> ETAG = new Header<String>("ETag", Parser.forETag());
 
         private final String name;

http://git-wip-us.apache.org/repos/asf/isis/blob/584eb10a/component/viewer/restfulobjects/applib/src/main/java/org/apache/isis/viewer/restfulobjects/applib/util/JsonNodeUtils.java
----------------------------------------------------------------------
diff --git a/component/viewer/restfulobjects/applib/src/main/java/org/apache/isis/viewer/restfulobjects/applib/util/JsonNodeUtils.java b/component/viewer/restfulobjects/applib/src/main/java/org/apache/isis/viewer/restfulobjects/applib/util/JsonNodeUtils.java
index 446bc3d..7f61f02 100644
--- a/component/viewer/restfulobjects/applib/src/main/java/org/apache/isis/viewer/restfulobjects/applib/util/JsonNodeUtils.java
+++ b/component/viewer/restfulobjects/applib/src/main/java/org/apache/isis/viewer/restfulobjects/applib/util/JsonNodeUtils.java
@@ -26,6 +26,8 @@ import org.codehaus.jackson.JsonNode;
 import org.codehaus.jackson.node.JsonNodeFactory;
 import org.codehaus.jackson.node.ObjectNode;
 
+import org.apache.isis.viewer.restfulobjects.applib.JsonRepresentation;
+
 import com.google.common.base.Charsets;
 
 public class JsonNodeUtils {
@@ -39,6 +41,12 @@ public class JsonNodeUtils {
         return new ByteArrayInputStream(bytes);
     }
 
+    public static InputStream asInputStream(final JsonRepresentation jsonRepresentation) {
+        final String jsonStr = jsonRepresentation.toString();
+        final byte[] bytes = jsonStr.getBytes(Charsets.UTF_8);
+        return new ByteArrayInputStream(bytes);
+    }
+
     /**
      * Walks the path, ensuring keys exist and are maps, or creating required
      * maps as it goes.

http://git-wip-us.apache.org/repos/asf/isis/blob/584eb10a/component/viewer/restfulobjects/applib/src/test/java/org/apache/isis/viewer/restfulobjects/applib/JsonRepresentationTest_getLink_isLink.java
----------------------------------------------------------------------
diff --git a/component/viewer/restfulobjects/applib/src/test/java/org/apache/isis/viewer/restfulobjects/applib/JsonRepresentationTest_getLink_isLink.java b/component/viewer/restfulobjects/applib/src/test/java/org/apache/isis/viewer/restfulobjects/applib/JsonRepresentationTest_getLink_isLink.java
index 7bc45b9..d05ee0e 100644
--- a/component/viewer/restfulobjects/applib/src/test/java/org/apache/isis/viewer/restfulobjects/applib/JsonRepresentationTest_getLink_isLink.java
+++ b/component/viewer/restfulobjects/applib/src/test/java/org/apache/isis/viewer/restfulobjects/applib/JsonRepresentationTest_getLink_isLink.java
@@ -19,6 +19,7 @@
 package org.apache.isis.viewer.restfulobjects.applib;
 
 import static org.apache.isis.viewer.restfulobjects.applib.JsonFixture.readJson;
+import static org.hamcrest.CoreMatchers.*;
 import static org.hamcrest.CoreMatchers.is;
 import static org.hamcrest.CoreMatchers.nullValue;
 import static org.junit.Assert.assertThat;
@@ -94,4 +95,25 @@ public class JsonRepresentationTest_getLink_isLink {
             assertThat(e.getMessage(), is("'aSubList' is an array that does not represent a link"));
         }
     }
+
+    @Test
+    public void withPredicate() throws JsonParseException, JsonMappingException, IOException {
+
+        // given
+        link = new LinkRepresentation().withRel(Rel.SELF).withHref("http://foo/bar").withMethod(RestfulHttpMethod.GET);
+        JsonRepresentation linkListRepr = JsonRepresentation.newArray();
+        linkListRepr.arrayAdd(link);
+
+        jsonRepresentation = JsonRepresentation.newMap();
+        jsonRepresentation.mapPut("links", linkListRepr);
+        
+        // when, then
+        assertThat(jsonRepresentation.isLink("links[rel=self]"), is(true));
+        assertThat(jsonRepresentation.getLink("links[rel=self]"), is(not(nullValue())));
+
+        assertThat(jsonRepresentation.isLink("links[rel=other]"), is(false));
+        assertThat(jsonRepresentation.getLink("links[rel=other]"), is(nullValue()));
+    }
+
+
 }

http://git-wip-us.apache.org/repos/asf/isis/blob/584eb10a/component/viewer/restfulobjects/rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/domainobjects/ActionResultReprRenderer.java
----------------------------------------------------------------------
diff --git a/component/viewer/restfulobjects/rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/domainobjects/ActionResultReprRenderer.java b/component/viewer/restfulobjects/rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/domainobjects/ActionResultReprRenderer.java
index 3623d81..978596a 100644
--- a/component/viewer/restfulobjects/rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/domainobjects/ActionResultReprRenderer.java
+++ b/component/viewer/restfulobjects/rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/domainobjects/ActionResultReprRenderer.java
@@ -19,6 +19,8 @@ package org.apache.isis.viewer.restfulobjects.rendering.domainobjects;
 import java.util.Collection;
 import java.util.Map;
 
+import org.codehaus.jackson.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;
@@ -41,9 +43,16 @@ public class ActionResultReprRenderer extends ReprRendererAbstract<ActionResultR
     private ObjectAction action;
     private JsonRepresentation arguments;
     private ObjectAdapter returnedAdapter;
+    private final SelfLink selfLink;
+
+
+    public enum SelfLink {
+        INCLUDED, EXCLUDED
+    }
 
-    public ActionResultReprRenderer(final RendererContext resourceContext, final LinkFollowSpecs linkFollower, final JsonRepresentation representation) {
-        super(resourceContext, linkFollower, RepresentationType.ACTION_RESULT, 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;
     }
 
     @Override
@@ -81,7 +90,11 @@ public class ActionResultReprRenderer extends ReprRendererAbstract<ActionResultR
 
         if (!resultType.isVoid()) {
             putResultType(representation, resultType);
-            representation.mapPut("result", result);
+            if(returnedAdapter != null) {
+                representation.mapPut("result", result);
+            } else {
+                representation.mapPut("result", NullNode.getInstance());
+            }
         }
     }
 
@@ -98,12 +111,14 @@ public class ActionResultReprRenderer extends ReprRendererAbstract<ActionResultR
         if (collectionFacet != null) {
             // collection
 
-            final Collection<ObjectAdapter> collectionAdapters = collectionFacet.collection(returnedAdapter);
-
-            final ListReprRenderer renderer = new ListReprRenderer(rendererContext, null, result);
-            renderer.with(collectionAdapters).withReturnType(action.getReturnType()).withElementType(returnedAdapter.getElementSpecification());
-
-            renderer.render();
+            if(returnedAdapter != null) {
+                final Collection<ObjectAdapter> collectionAdapters = collectionFacet.collection(returnedAdapter);
+    
+                final ListReprRenderer renderer = new ListReprRenderer(rendererContext, null, result);
+                renderer.with(collectionAdapters).withReturnType(action.getReturnType()).withElementType(returnedAdapter.getElementSpecification());
+    
+                renderer.render();
+            }
             return ResultType.LIST;
         }
 
@@ -111,21 +126,25 @@ public class ActionResultReprRenderer extends ReprRendererAbstract<ActionResultR
         if (encodableFacet != null) {
             // scalar
 
-            final ScalarValueReprRenderer renderer = new ScalarValueReprRenderer(rendererContext, null, result);
-            renderer.with(returnedAdapter).withReturnType(action.getReturnType());
-
-            renderer.render();
+            if(returnedAdapter != null) {
+                final ScalarValueReprRenderer renderer = new ScalarValueReprRenderer(rendererContext, null, result);
+                renderer.with(returnedAdapter).withReturnType(action.getReturnType());
+    
+                renderer.render();
+            }
             return ResultType.SCALAR_VALUE;
 
         }
 
         {
             // object
-            final DomainObjectReprRenderer renderer = new DomainObjectReprRenderer(rendererContext, null, result);
-
-            renderer.with(returnedAdapter).includesSelf();
-
-            renderer.render();
+            if(returnedAdapter != null) {
+                final DomainObjectReprRenderer renderer = new DomainObjectReprRenderer(rendererContext, null, result);
+                
+                renderer.with(returnedAdapter).includesSelf();
+                
+                renderer.render();
+            }
             return ResultType.DOMAIN_OBJECT;
         }
     }
@@ -134,10 +153,14 @@ public class ActionResultReprRenderer extends ReprRendererAbstract<ActionResultR
         representation.mapPut("resulttype", resultType.getValue());
     }
 
-    private JsonRepresentation representationWithSelfFor(final ObjectAction action, final JsonRepresentation bodyArgs) {
+    private void representationWithSelfFor(final ObjectAction action, final JsonRepresentation bodyArgs) {
         final JsonRepresentation links = JsonRepresentation.newArray();
         representation.mapPut("links", links);
 
+        if(selfLink == SelfLink.EXCLUDED) {
+            return;
+        }
+        
         final LinkBuilder selfLinkBuilder = adapterLinkTo.memberBuilder(Rel.SELF, MemberType.ACTION, action, RepresentationType.ACTION_RESULT, "invoke");
 
         // TODO: remove duplication with AbstractObjectMember#addLinkTo
@@ -152,7 +175,6 @@ public class ActionResultReprRenderer extends ReprRendererAbstract<ActionResultR
 
         links.arrayAdd(selfLink);
         selfLink.mapPut("args", bodyArgs);
-        return representation;
     }
 
 }
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/isis/blob/584eb10a/component/viewer/restfulobjects/server/src/main/java/org/apache/isis/viewer/restfulobjects/server/ResourceContext.java
----------------------------------------------------------------------
diff --git a/component/viewer/restfulobjects/server/src/main/java/org/apache/isis/viewer/restfulobjects/server/ResourceContext.java b/component/viewer/restfulobjects/server/src/main/java/org/apache/isis/viewer/restfulobjects/server/ResourceContext.java
index 27ec6c4..bf2fd54 100644
--- a/component/viewer/restfulobjects/server/src/main/java/org/apache/isis/viewer/restfulobjects/server/ResourceContext.java
+++ b/component/viewer/restfulobjects/server/src/main/java/org/apache/isis/viewer/restfulobjects/server/ResourceContext.java
@@ -21,6 +21,7 @@ package org.apache.isis.viewer.restfulobjects.server;
 import java.io.InputStream;
 import java.util.Collections;
 import java.util.List;
+import java.util.Map;
 
 import javax.servlet.http.HttpServletRequest;
 import javax.servlet.http.HttpServletResponse;
@@ -114,6 +115,8 @@ public class ResourceContext implements RendererContext {
 
     
     void init(final RepresentationType representationType) {
+        getQueryStringAsJsonRepr(); // force it to be cached
+        
         ensureCompatibleAcceptHeader(representationType);
         ensureDomainModelQueryParamSupported();
         
@@ -168,12 +171,48 @@ public class ResourceContext implements RendererContext {
     }
 
     public JsonRepresentation getQueryStringAsJsonRepr() {
+        
         if (readQueryStringAsMap == null) {
-            readQueryStringAsMap = DomainResourceHelper.readQueryStringAsMap(getQueryString());
+            readQueryStringAsMap = requestArgsAsMap();
         }
         return readQueryStringAsMap;
     }
 
+    protected JsonRepresentation requestArgsAsMap() {
+        @SuppressWarnings("unchecked")
+        final Map<String,String[]> params = httpServletRequest.getParameterMap();
+
+        if(simpleQueryArgs(params)) {
+            // try to process regular params and build up JSON repr 
+            final JsonRepresentation map = JsonRepresentation.newMap();
+            for(String paramName: params.keySet()) {
+                String paramValue = params.get(paramName)[0];
+                try {
+                    int paramValueAsInt = Integer.parseInt(paramValue);
+                    map.mapPut(paramName+".value", paramValueAsInt);
+                } catch(Exception ex) {
+                    map.mapPut(paramName+".value", paramValue);
+                }
+            }
+            return map;
+        } else {
+            return DomainResourceHelper.readQueryStringAsMap(getQueryString());
+        }
+    }
+
+    private static boolean simpleQueryArgs(Map<String, String[]> params) {
+        if(params.isEmpty()) {
+            return false;
+        }
+        for(String paramName: params.keySet()) {
+            if("x-isis-querystring".equals(paramName) || paramName.startsWith("{")) {
+                return false;
+            }
+        }
+        return true;
+    }
+
+
     public <Q> Q getArg(final RequestParameter<Q> requestParameter) {
         final JsonRepresentation queryStringJsonRepr = getQueryStringAsJsonRepr();
         return requestParameter.valueOf(queryStringJsonRepr);

http://git-wip-us.apache.org/repos/asf/isis/blob/584eb10a/component/viewer/restfulobjects/server/src/main/java/org/apache/isis/viewer/restfulobjects/server/resources/DomainResourceHelper.java
----------------------------------------------------------------------
diff --git a/component/viewer/restfulobjects/server/src/main/java/org/apache/isis/viewer/restfulobjects/server/resources/DomainResourceHelper.java b/component/viewer/restfulobjects/server/src/main/java/org/apache/isis/viewer/restfulobjects/server/resources/DomainResourceHelper.java
index d914f5f..af7a3af 100644
--- a/component/viewer/restfulobjects/server/src/main/java/org/apache/isis/viewer/restfulobjects/server/resources/DomainResourceHelper.java
+++ b/component/viewer/restfulobjects/server/src/main/java/org/apache/isis/viewer/restfulobjects/server/resources/DomainResourceHelper.java
@@ -50,6 +50,7 @@ import org.apache.isis.viewer.restfulobjects.applib.util.UrlEncodingUtils;
 import org.apache.isis.viewer.restfulobjects.rendering.RendererContext;
 import org.apache.isis.viewer.restfulobjects.rendering.domainobjects.AbstractObjectMemberReprRenderer;
 import org.apache.isis.viewer.restfulobjects.rendering.domainobjects.ActionResultReprRenderer;
+import org.apache.isis.viewer.restfulobjects.rendering.domainobjects.ActionResultReprRenderer.SelfLink;
 import org.apache.isis.viewer.restfulobjects.rendering.domainobjects.DomainObjectLinkTo;
 import org.apache.isis.viewer.restfulobjects.rendering.domainobjects.DomainObjectReprRenderer;
 import org.apache.isis.viewer.restfulobjects.rendering.domainobjects.JsonValueEncoder;
@@ -250,7 +251,7 @@ public final class DomainResourceHelper {
             throw RestfulObjectsApplicationException.createWithMessage(HttpStatusCode.METHOD_NOT_ALLOWED, "Method not allowed; action '%s' is not query only", action.getId());
         }
 
-        return invokeActionUsingAdapters(action, arguments);
+        return invokeActionUsingAdapters(action, arguments, SelfLink.INCLUDED);
     }
 
     Response invokeActionIdempotent(final String actionId, final JsonRepresentation arguments, Where where) {
@@ -261,16 +262,16 @@ public final class DomainResourceHelper {
         if (!actionSemantics.isIdempotentInNature()) {
             throw RestfulObjectsApplicationException.createWithMessage(HttpStatusCode.METHOD_NOT_ALLOWED, "Method not allowed; action '%s' is not idempotent", action.getId());
         }
-        return invokeActionUsingAdapters(action, arguments);
+        return invokeActionUsingAdapters(action, arguments, SelfLink.EXCLUDED);
     }
 
     Response invokeAction(final String actionId, final JsonRepresentation arguments, Where where) {
         final ObjectAction action = getObjectActionThatIsVisibleForIntent(actionId, Intent.MUTATE, where);
 
-        return invokeActionUsingAdapters(action, arguments);
+        return invokeActionUsingAdapters(action, arguments, SelfLink.EXCLUDED);
     }
 
-    private Response invokeActionUsingAdapters(final ObjectAction action, final JsonRepresentation arguments) {
+    private Response invokeActionUsingAdapters(final ObjectAction action, final JsonRepresentation arguments, SelfLink selfLink) {
 
         final List<ObjectAdapter> argAdapters = parseAndValidateArguments(action, arguments);
 
@@ -279,7 +280,7 @@ public final class DomainResourceHelper {
         final ObjectAdapter returnedAdapter = action.execute(objectAdapter, argArray2);
 
         // response (void)
-        final ActionResultReprRenderer renderer = new ActionResultReprRenderer(resourceContext, null, JsonRepresentation.newMap());
+        final ActionResultReprRenderer renderer = new ActionResultReprRenderer(resourceContext, null, selfLink, JsonRepresentation.newMap());
 
         renderer.with(new ObjectAndActionInvocation(objectAdapter, action, arguments, returnedAdapter)).using(adapterLinkTo);
 

http://git-wip-us.apache.org/repos/asf/isis/blob/584eb10a/component/viewer/restfulobjects/tck/src/test/java/org/apache/isis/viewer/restfulobjects/tck/Util.java
----------------------------------------------------------------------
diff --git a/component/viewer/restfulobjects/tck/src/test/java/org/apache/isis/viewer/restfulobjects/tck/Util.java b/component/viewer/restfulobjects/tck/src/test/java/org/apache/isis/viewer/restfulobjects/tck/Util.java
index f1fd706..6922169 100644
--- a/component/viewer/restfulobjects/tck/src/test/java/org/apache/isis/viewer/restfulobjects/tck/Util.java
+++ b/component/viewer/restfulobjects/tck/src/test/java/org/apache/isis/viewer/restfulobjects/tck/Util.java
@@ -21,7 +21,10 @@ package org.apache.isis.viewer.restfulobjects.tck;
 import static org.hamcrest.CoreMatchers.is;
 import static org.junit.Assert.assertThat;
 
+import java.io.ByteArrayInputStream;
 import java.io.IOException;
+import java.io.InputStream;
+import java.nio.charset.Charset;
 
 import javax.ws.rs.core.Response;
 

http://git-wip-us.apache.org/repos/asf/isis/blob/584eb10a/component/viewer/restfulobjects/tck/src/test/java/org/apache/isis/viewer/restfulobjects/tck/domainobjectorservice/id/action/invoke/Get_thenRepresentation_containsSelfLink_ok.java
----------------------------------------------------------------------
diff --git a/component/viewer/restfulobjects/tck/src/test/java/org/apache/isis/viewer/restfulobjects/tck/domainobjectorservice/id/action/invoke/Get_thenRepresentation_containsSelfLink_ok.java b/component/viewer/restfulobjects/tck/src/test/java/org/apache/isis/viewer/restfulobjects/tck/domainobjectorservice/id/action/invoke/Get_thenRepresentation_containsSelfLink_ok.java
new file mode 100644
index 0000000..8a639bc
--- /dev/null
+++ b/component/viewer/restfulobjects/tck/src/test/java/org/apache/isis/viewer/restfulobjects/tck/domainobjectorservice/id/action/invoke/Get_thenRepresentation_containsSelfLink_ok.java
@@ -0,0 +1,98 @@
+package org.apache.isis.viewer.restfulobjects.tck.domainobjectorservice.id.action.invoke;
+
+import static org.apache.isis.viewer.restfulobjects.tck.RestfulMatchers.assertThat;
+import static org.apache.isis.viewer.restfulobjects.tck.RestfulMatchers.isLink;
+import static org.hamcrest.CoreMatchers.endsWith;
+import static org.hamcrest.CoreMatchers.is;
+import static org.junit.Assert.assertThat;
+
+import java.io.IOException;
+
+import javax.ws.rs.core.Response;
+
+import org.codehaus.jackson.JsonParseException;
+import org.codehaus.jackson.map.JsonMappingException;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+
+import org.apache.isis.viewer.restfulobjects.applib.JsonRepresentation;
+import org.apache.isis.viewer.restfulobjects.applib.LinkRepresentation;
+import org.apache.isis.viewer.restfulobjects.applib.Rel;
+import org.apache.isis.viewer.restfulobjects.applib.RepresentationType;
+import org.apache.isis.viewer.restfulobjects.applib.RestfulHttpMethod;
+import org.apache.isis.viewer.restfulobjects.applib.client.RestfulClient;
+import org.apache.isis.viewer.restfulobjects.applib.client.RestfulResponse;
+import org.apache.isis.viewer.restfulobjects.applib.domainobjects.ActionResultRepresentation;
+import org.apache.isis.viewer.restfulobjects.applib.domainobjects.DomainServiceResource;
+import org.apache.isis.viewer.restfulobjects.applib.domainobjects.ObjectActionRepresentation;
+import org.apache.isis.viewer.restfulobjects.applib.util.UrlEncodingUtils;
+import org.apache.isis.viewer.restfulobjects.tck.IsisWebServerRule;
+import org.apache.isis.viewer.restfulobjects.tck.Util;
+
+public class Get_thenRepresentation_containsSelfLink_ok {
+
+    @Rule
+    public IsisWebServerRule webServerRule = new IsisWebServerRule();
+
+    private RestfulClient client;
+
+    private DomainServiceResource serviceResource;
+
+    @Before
+    public void setUp() throws Exception {
+        client = webServerRule.getClient();
+
+        serviceResource = client.getDomainServiceResource();
+    }
+
+    @Test
+    public void usingClientFollow() throws Exception {
+
+        // given
+        final JsonRepresentation givenAction = Util.givenAction(client, "ActionsEntities", "findById");
+        final ObjectActionRepresentation actionRepr = givenAction.as(ObjectActionRepresentation.class);
+
+        final LinkRepresentation invokeLink = actionRepr.getInvoke();
+        final JsonRepresentation args =invokeLink.getArguments();
+        
+        // when
+        args.mapPut("id.value", 1);
+
+        // when
+        final RestfulResponse<ActionResultRepresentation> restfulResponse = client.followT(invokeLink, args);
+        
+        // then
+        then(restfulResponse);
+    }
+
+    
+
+    @Test
+    public void usingResourceProxy() throws Exception {
+
+        // given, when
+        
+        JsonRepresentation args = JsonRepresentation.newMap();
+        args.mapPut("id.value", 1);
+
+        Response response = serviceResource.invokeActionQueryOnly("ActionsEntities", "findById", UrlEncodingUtils.urlEncode(args));
+        RestfulResponse<ActionResultRepresentation> restfulResponse = RestfulResponse.ofT(response);
+        
+        // then
+        then(restfulResponse);
+    }
+
+    private void then(RestfulResponse<ActionResultRepresentation> restfulResponse) throws Exception {
+        
+        final ActionResultRepresentation actionResultRepr = restfulResponse.getEntity();
+        
+        assertThat(actionResultRepr.getSelf(), isLink()
+                .rel(Rel.SELF)
+                .href(endsWith(":39393/services/ActionsEntities/actions/findById/invoke"))
+                .httpMethod(RestfulHttpMethod.GET)
+                .type(RepresentationType.ACTION_RESULT.getMediaType())
+                );
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/isis/blob/584eb10a/component/viewer/restfulobjects/tck/src/test/java/org/apache/isis/viewer/restfulobjects/tck/domainobjectorservice/id/action/invoke/Get_whenList_thenRepresentation_ok.java
----------------------------------------------------------------------
diff --git a/component/viewer/restfulobjects/tck/src/test/java/org/apache/isis/viewer/restfulobjects/tck/domainobjectorservice/id/action/invoke/Get_whenList_thenRepresentation_ok.java b/component/viewer/restfulobjects/tck/src/test/java/org/apache/isis/viewer/restfulobjects/tck/domainobjectorservice/id/action/invoke/Get_whenList_thenRepresentation_ok.java
deleted file mode 100644
index 0a7a054..0000000
--- a/component/viewer/restfulobjects/tck/src/test/java/org/apache/isis/viewer/restfulobjects/tck/domainobjectorservice/id/action/invoke/Get_whenList_thenRepresentation_ok.java
+++ /dev/null
@@ -1,112 +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.tck.domainobjectorservice.id.action.invoke;
-
-import static org.apache.isis.viewer.restfulobjects.tck.RestfulMatchers.hasProfile;
-import static org.apache.isis.viewer.restfulobjects.tck.RestfulMatchers.isLink;
-import static org.hamcrest.CoreMatchers.is;
-import static org.junit.Assert.assertThat;
-
-import java.io.IOException;
-
-import javax.ws.rs.core.Response;
-
-import org.apache.isis.viewer.restfulobjects.applib.JsonRepresentation;
-import org.apache.isis.viewer.restfulobjects.applib.LinkRepresentation;
-import org.apache.isis.viewer.restfulobjects.applib.Rel;
-import org.apache.isis.viewer.restfulobjects.applib.RestfulHttpMethod;
-import org.apache.isis.viewer.restfulobjects.applib.RestfulMediaType;
-import org.apache.isis.viewer.restfulobjects.applib.client.RestfulClient;
-import org.apache.isis.viewer.restfulobjects.applib.client.RestfulResponse;
-import org.apache.isis.viewer.restfulobjects.applib.client.RestfulResponse.Header;
-import org.apache.isis.viewer.restfulobjects.applib.domainobjects.ActionResultRepresentation;
-import org.apache.isis.viewer.restfulobjects.applib.domainobjects.ActionResultRepresentation.ResultType;
-import org.apache.isis.viewer.restfulobjects.applib.domainobjects.DomainServiceResource;
-import org.apache.isis.viewer.restfulobjects.applib.domainobjects.ListRepresentation;
-import org.apache.isis.viewer.restfulobjects.applib.domainobjects.ObjectActionRepresentation;
-import org.apache.isis.viewer.restfulobjects.tck.IsisWebServerRule;
-import org.apache.isis.viewer.restfulobjects.tck.Util;
-import org.codehaus.jackson.JsonParseException;
-import org.codehaus.jackson.map.JsonMappingException;
-import org.hamcrest.Matchers;
-import org.junit.Before;
-import org.junit.Rule;
-import org.junit.Test;
-
-public class Get_whenList_thenRepresentation_ok {
-
-    @Rule
-    public IsisWebServerRule webServerRule = new IsisWebServerRule();
-
-    private RestfulClient client;
-
-    private DomainServiceResource serviceResource;
-
-    @Before
-    public void setUp() throws Exception {
-        client = webServerRule.getClient();
-
-        serviceResource = client.getDomainServiceResource();
-    }
-
-    @Test
-    public void usingClientFollow() throws Exception {
-
-        // given
-        final JsonRepresentation givenAction = Util.givenAction(client, "ActionsEntities", "list");
-        final ObjectActionRepresentation actionRepr = givenAction.as(ObjectActionRepresentation.class);
-
-        final LinkRepresentation invokeLink = actionRepr.getInvoke();
-
-        assertThat(invokeLink, isLink(client)
-                                    .rel(Rel.INVOKE)
-                                    .httpMethod(RestfulHttpMethod.GET)
-                                    .href(Matchers.endsWith(":39393/services/ActionsEntities/actions/list/invoke"))
-                                    .arguments(JsonRepresentation.newMap())
-                                    .build());
-        
-        // when
-        final RestfulResponse<ActionResultRepresentation> restfulResponse = client.followT(invokeLink);
-        
-        // then
-        then(restfulResponse);
-    }
-
-    private static void then(final RestfulResponse<ActionResultRepresentation> restfulResponse) throws JsonParseException, JsonMappingException, IOException {
-        
-        assertThat(restfulResponse.getHeader(Header.CONTENT_TYPE), hasProfile(RestfulMediaType.APPLICATION_JSON_ACTION_RESULT));
-        final ActionResultRepresentation actionResultRepr = restfulResponse.getEntity();
-        
-        assertThat(actionResultRepr.getResultType(), is(ResultType.LIST));
-        final ListRepresentation listRepr = actionResultRepr.getResult().as(ListRepresentation.class);
-        assertThat(listRepr.getValue().size(), is(5));
-    }
-
-    
-    @Test
-    public void usingResourceProxy() throws Exception {
-
-        // given, when
-        Response response = serviceResource.invokeActionQueryOnly("ActionsEntities", "list", null);
-        RestfulResponse<ActionResultRepresentation> restfulResponse = RestfulResponse.ofT(response);
-        
-        then(restfulResponse);
-    }
-
-}

http://git-wip-us.apache.org/repos/asf/isis/blob/584eb10a/component/viewer/restfulobjects/tck/src/test/java/org/apache/isis/viewer/restfulobjects/tck/domainobjectorservice/id/action/invoke/Get_whenList_thenRepresentation_ok_andResponseHeaders_ContentType_andContentLength_ok.java
----------------------------------------------------------------------
diff --git a/component/viewer/restfulobjects/tck/src/test/java/org/apache/isis/viewer/restfulobjects/tck/domainobjectorservice/id/action/invoke/Get_whenList_thenRepresentation_ok_andResponseHeaders_ContentType_andContentLength_ok.java b/component/viewer/restfulobjects/tck/src/test/java/org/apache/isis/viewer/restfulobjects/tck/domainobjectorservice/id/action/invoke/Get_whenList_thenRepresentation_ok_andResponseHeaders_ContentType_andContentLength_ok.java
new file mode 100644
index 0000000..5ac99c4
--- /dev/null
+++ b/component/viewer/restfulobjects/tck/src/test/java/org/apache/isis/viewer/restfulobjects/tck/domainobjectorservice/id/action/invoke/Get_whenList_thenRepresentation_ok_andResponseHeaders_ContentType_andContentLength_ok.java
@@ -0,0 +1,112 @@
+/*
+ *  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.tck.domainobjectorservice.id.action.invoke;
+
+import static org.apache.isis.viewer.restfulobjects.tck.RestfulMatchers.hasProfile;
+import static org.apache.isis.viewer.restfulobjects.tck.RestfulMatchers.isLink;
+import static org.hamcrest.CoreMatchers.is;
+import static org.junit.Assert.assertThat;
+
+import java.io.IOException;
+
+import javax.ws.rs.core.Response;
+
+import org.apache.isis.viewer.restfulobjects.applib.JsonRepresentation;
+import org.apache.isis.viewer.restfulobjects.applib.LinkRepresentation;
+import org.apache.isis.viewer.restfulobjects.applib.Rel;
+import org.apache.isis.viewer.restfulobjects.applib.RestfulHttpMethod;
+import org.apache.isis.viewer.restfulobjects.applib.RestfulMediaType;
+import org.apache.isis.viewer.restfulobjects.applib.client.RestfulClient;
+import org.apache.isis.viewer.restfulobjects.applib.client.RestfulResponse;
+import org.apache.isis.viewer.restfulobjects.applib.client.RestfulResponse.Header;
+import org.apache.isis.viewer.restfulobjects.applib.domainobjects.ActionResultRepresentation;
+import org.apache.isis.viewer.restfulobjects.applib.domainobjects.ActionResultRepresentation.ResultType;
+import org.apache.isis.viewer.restfulobjects.applib.domainobjects.DomainServiceResource;
+import org.apache.isis.viewer.restfulobjects.applib.domainobjects.ListRepresentation;
+import org.apache.isis.viewer.restfulobjects.applib.domainobjects.ObjectActionRepresentation;
+import org.apache.isis.viewer.restfulobjects.tck.IsisWebServerRule;
+import org.apache.isis.viewer.restfulobjects.tck.Util;
+import org.codehaus.jackson.JsonParseException;
+import org.codehaus.jackson.map.JsonMappingException;
+import org.hamcrest.Matchers;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+
+public class Get_whenList_thenRepresentation_ok_andResponseHeaders_ContentType_andContentLength_ok {
+
+    @Rule
+    public IsisWebServerRule webServerRule = new IsisWebServerRule();
+
+    private RestfulClient client;
+
+    private DomainServiceResource serviceResource;
+
+    @Before
+    public void setUp() throws Exception {
+        client = webServerRule.getClient();
+
+        serviceResource = client.getDomainServiceResource();
+    }
+
+    @Test
+    public void usingClientFollow() throws Exception {
+
+        // given
+        final JsonRepresentation givenAction = Util.givenAction(client, "ActionsEntities", "list");
+        final ObjectActionRepresentation actionRepr = givenAction.as(ObjectActionRepresentation.class);
+
+        final LinkRepresentation invokeLink = actionRepr.getInvoke();
+
+        assertThat(invokeLink, isLink(client)
+                                    .rel(Rel.INVOKE)
+                                    .httpMethod(RestfulHttpMethod.GET)
+                                    .href(Matchers.endsWith(":39393/services/ActionsEntities/actions/list/invoke"))
+                                    .arguments(JsonRepresentation.newMap())
+                                    .build());
+        
+        // when
+        final RestfulResponse<ActionResultRepresentation> restfulResponse = client.followT(invokeLink);
+        
+        // then
+        then(restfulResponse);
+    }
+
+    @Test
+    public void usingResourceProxy() throws Exception {
+
+        // given, when
+        Response response = serviceResource.invokeActionQueryOnly("ActionsEntities", "list", null);
+        RestfulResponse<ActionResultRepresentation> restfulResponse = RestfulResponse.ofT(response);
+        
+        then(restfulResponse);
+    }
+
+    private static void then(final RestfulResponse<ActionResultRepresentation> restfulResponse) throws JsonParseException, JsonMappingException, IOException {
+        
+        assertThat(restfulResponse.getHeader(Header.CONTENT_TYPE), hasProfile(RestfulMediaType.APPLICATION_JSON_ACTION_RESULT));
+        assertThat(restfulResponse.getHeader(Header.CONTENT_LENGTH), is(2245));
+        
+        final ActionResultRepresentation actionResultRepr = restfulResponse.getEntity();
+        
+        assertThat(actionResultRepr.getResultType(), is(ResultType.LIST));
+        final ListRepresentation listRepr = actionResultRepr.getResult().as(ListRepresentation.class);
+        assertThat(listRepr.getValue().size(), is(5));
+    }
+}

http://git-wip-us.apache.org/repos/asf/isis/blob/584eb10a/component/viewer/restfulobjects/tck/src/test/java/org/apache/isis/viewer/restfulobjects/tck/domainobjectorservice/id/action/invoke/Get_whenList_thenResponseHeaders_ContentLength_ok_TODO.java
----------------------------------------------------------------------
diff --git a/component/viewer/restfulobjects/tck/src/test/java/org/apache/isis/viewer/restfulobjects/tck/domainobjectorservice/id/action/invoke/Get_whenList_thenResponseHeaders_ContentLength_ok_TODO.java b/component/viewer/restfulobjects/tck/src/test/java/org/apache/isis/viewer/restfulobjects/tck/domainobjectorservice/id/action/invoke/Get_whenList_thenResponseHeaders_ContentLength_ok_TODO.java
deleted file mode 100644
index 1f4d3a9..0000000
--- a/component/viewer/restfulobjects/tck/src/test/java/org/apache/isis/viewer/restfulobjects/tck/domainobjectorservice/id/action/invoke/Get_whenList_thenResponseHeaders_ContentLength_ok_TODO.java
+++ /dev/null
@@ -1,13 +0,0 @@
-package org.apache.isis.viewer.restfulobjects.tck.domainobjectorservice.id.action.invoke;
-
-import org.junit.Ignore;
-import org.junit.Test;
-
-public class Get_whenList_thenResponseHeaders_ContentLength_ok_TODO {
-
-    @Ignore
-    @Test
-    public void todo() throws Exception {
-        
-    }
-}

http://git-wip-us.apache.org/repos/asf/isis/blob/584eb10a/component/viewer/restfulobjects/tck/src/test/java/org/apache/isis/viewer/restfulobjects/tck/domainobjectorservice/id/action/invoke/Get_whenList_thenResponseHeaders_ContentType_ok_TODO.java
----------------------------------------------------------------------
diff --git a/component/viewer/restfulobjects/tck/src/test/java/org/apache/isis/viewer/restfulobjects/tck/domainobjectorservice/id/action/invoke/Get_whenList_thenResponseHeaders_ContentType_ok_TODO.java b/component/viewer/restfulobjects/tck/src/test/java/org/apache/isis/viewer/restfulobjects/tck/domainobjectorservice/id/action/invoke/Get_whenList_thenResponseHeaders_ContentType_ok_TODO.java
deleted file mode 100644
index 2f2153d..0000000
--- a/component/viewer/restfulobjects/tck/src/test/java/org/apache/isis/viewer/restfulobjects/tck/domainobjectorservice/id/action/invoke/Get_whenList_thenResponseHeaders_ContentType_ok_TODO.java
+++ /dev/null
@@ -1,13 +0,0 @@
-package org.apache.isis.viewer.restfulobjects.tck.domainobjectorservice.id.action.invoke;
-
-import org.junit.Ignore;
-import org.junit.Test;
-
-public class Get_whenList_thenResponseHeaders_ContentType_ok_TODO {
-
-    @Ignore
-    @Test
-    public void todo() throws Exception {
-        
-    }
-}

http://git-wip-us.apache.org/repos/asf/isis/blob/584eb10a/component/viewer/restfulobjects/tck/src/test/java/org/apache/isis/viewer/restfulobjects/tck/domainobjectorservice/id/action/invoke/Get_whenObject_isNotNull_thenRepresentation_ok_andResponseHeaders_ContentType_andContentLength_ok.java
----------------------------------------------------------------------
diff --git a/component/viewer/restfulobjects/tck/src/test/java/org/apache/isis/viewer/restfulobjects/tck/domainobjectorservice/id/action/invoke/Get_whenObject_isNotNull_thenRepresentation_ok_andResponseHeaders_ContentType_andContentLength_ok.java b/component/viewer/restfulobjects/tck/src/test/java/org/apache/isis/viewer/restfulobjects/tck/domainobjectorservice/id/action/invoke/Get_whenObject_isNotNull_thenRepresentation_ok_andResponseHeaders_ContentType_andContentLength_ok.java
new file mode 100644
index 0000000..92d5e58
--- /dev/null
+++ b/component/viewer/restfulobjects/tck/src/test/java/org/apache/isis/viewer/restfulobjects/tck/domainobjectorservice/id/action/invoke/Get_whenObject_isNotNull_thenRepresentation_ok_andResponseHeaders_ContentType_andContentLength_ok.java
@@ -0,0 +1,125 @@
+package org.apache.isis.viewer.restfulobjects.tck.domainobjectorservice.id.action.invoke;
+
+import static org.apache.isis.viewer.restfulobjects.tck.RestfulMatchers.hasProfile;
+import static org.hamcrest.CoreMatchers.*;
+import static org.hamcrest.CoreMatchers.is;
+import static org.junit.Assert.assertThat;
+
+import java.io.IOException;
+
+import javax.ws.rs.core.Response;
+
+import org.codehaus.jackson.JsonParseException;
+import org.codehaus.jackson.map.JsonMappingException;
+import org.hamcrest.CoreMatchers;
+import org.hamcrest.Description;
+import org.hamcrest.Matcher;
+import org.hamcrest.TypeSafeMatcher;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+
+import org.apache.isis.viewer.restfulobjects.applib.JsonRepresentation;
+import org.apache.isis.viewer.restfulobjects.applib.LinkRepresentation;
+import org.apache.isis.viewer.restfulobjects.applib.RestfulMediaType;
+import org.apache.isis.viewer.restfulobjects.applib.client.RestfulClient;
+import org.apache.isis.viewer.restfulobjects.applib.client.RestfulResponse;
+import org.apache.isis.viewer.restfulobjects.applib.client.RestfulResponse.Header;
+import org.apache.isis.viewer.restfulobjects.applib.domainobjects.ActionResultRepresentation;
+import org.apache.isis.viewer.restfulobjects.applib.domainobjects.ActionResultRepresentation.ResultType;
+import org.apache.isis.viewer.restfulobjects.applib.domainobjects.DomainObjectRepresentation;
+import org.apache.isis.viewer.restfulobjects.applib.domainobjects.DomainServiceResource;
+import org.apache.isis.viewer.restfulobjects.applib.domainobjects.ObjectActionRepresentation;
+import org.apache.isis.viewer.restfulobjects.applib.util.UrlEncodingUtils;
+import org.apache.isis.viewer.restfulobjects.tck.IsisWebServerRule;
+import org.apache.isis.viewer.restfulobjects.tck.Util;
+
+public class Get_whenObject_isNotNull_thenRepresentation_ok_andResponseHeaders_ContentType_andContentLength_ok {
+
+    @Rule
+    public IsisWebServerRule webServerRule = new IsisWebServerRule();
+
+    private RestfulClient client;
+
+    private DomainServiceResource serviceResource;
+
+    @Before
+    public void setUp() throws Exception {
+        client = webServerRule.getClient();
+
+        serviceResource = client.getDomainServiceResource();
+    }
+
+    @Test
+    public void usingClientFollow() throws Exception {
+
+        // given
+        final JsonRepresentation givenAction = Util.givenAction(client, "ActionsEntities", "findById");
+        final ObjectActionRepresentation actionRepr = givenAction.as(ObjectActionRepresentation.class);
+
+        final LinkRepresentation invokeLink = actionRepr.getInvoke();
+        final JsonRepresentation args =invokeLink.getArguments();
+        
+        // when
+        args.mapPut("id.value", 1);
+
+        // when
+        final RestfulResponse<ActionResultRepresentation> restfulResponse = client.followT(invokeLink, args);
+        
+        // then
+        then(restfulResponse);
+    }
+
+    
+    @Test
+    public void usingResourceProxy() throws Exception {
+
+        // given, when
+        
+        JsonRepresentation args = JsonRepresentation.newMap();
+        args.mapPut("id.value", 1);
+
+        Response response = serviceResource.invokeActionQueryOnly("ActionsEntities", "findById", UrlEncodingUtils.urlEncode(args));
+        RestfulResponse<ActionResultRepresentation> restfulResponse = RestfulResponse.ofT(response);
+        
+        then(restfulResponse);
+    }
+
+    private static void then(final RestfulResponse<ActionResultRepresentation> restfulResponse) throws JsonParseException, JsonMappingException, IOException {
+        
+        assertThat(restfulResponse.getHeader(Header.CONTENT_TYPE), hasProfile(RestfulMediaType.APPLICATION_JSON_ACTION_RESULT));
+        assertThat(restfulResponse.getHeader(Header.CONTENT_LENGTH), is(3335));
+        
+        final ActionResultRepresentation actionResultRepr = restfulResponse.getEntity();
+
+        assertThat(actionResultRepr.getResultType(), is(ResultType.DOMAIN_OBJECT));
+        final DomainObjectRepresentation objRepr = actionResultRepr.getResult().as(DomainObjectRepresentation.class);
+        
+        assertThat(objRepr.getMembers(), is(not(nullValue())));
+        assertThat(objRepr.getMembers().size(), is(greaterThan(0)));
+        
+        assertThat(objRepr.getTitle(), is(not(nullValue())));
+        
+        assertThat(objRepr.getLinks(), is(not(nullValue())));
+        assertThat(objRepr.getMembers().size(), is(greaterThan(0)));
+        
+        assertThat(objRepr.getExtensions(), is(not(nullValue())));
+    }
+
+    private static Matcher<Integer> greaterThan(final int i) {
+        return new TypeSafeMatcher<Integer>() {
+
+            @Override
+            public void describeTo(Description description) {
+                description.appendText("greater than " + i);
+            }
+
+            @Override
+            protected boolean matchesSafely(Integer item) {
+                return item > i;
+            }
+        };
+    }
+
+    
+}

http://git-wip-us.apache.org/repos/asf/isis/blob/584eb10a/component/viewer/restfulobjects/tck/src/test/java/org/apache/isis/viewer/restfulobjects/tck/domainobjectorservice/id/action/invoke/Get_whenObject_isNull_thenRepresentation_ok.java
----------------------------------------------------------------------
diff --git a/component/viewer/restfulobjects/tck/src/test/java/org/apache/isis/viewer/restfulobjects/tck/domainobjectorservice/id/action/invoke/Get_whenObject_isNull_thenRepresentation_ok.java b/component/viewer/restfulobjects/tck/src/test/java/org/apache/isis/viewer/restfulobjects/tck/domainobjectorservice/id/action/invoke/Get_whenObject_isNull_thenRepresentation_ok.java
new file mode 100644
index 0000000..74a0633
--- /dev/null
+++ b/component/viewer/restfulobjects/tck/src/test/java/org/apache/isis/viewer/restfulobjects/tck/domainobjectorservice/id/action/invoke/Get_whenObject_isNull_thenRepresentation_ok.java
@@ -0,0 +1,97 @@
+package org.apache.isis.viewer.restfulobjects.tck.domainobjectorservice.id.action.invoke;
+
+import static org.apache.isis.viewer.restfulobjects.tck.RestfulMatchers.hasProfile;
+import static org.hamcrest.CoreMatchers.*;
+import static org.hamcrest.CoreMatchers.is;
+import static org.junit.Assert.assertThat;
+
+import java.io.IOException;
+
+import javax.ws.rs.core.Response;
+
+import org.codehaus.jackson.JsonParseException;
+import org.codehaus.jackson.map.JsonMappingException;
+import org.hamcrest.CoreMatchers;
+import org.hamcrest.Description;
+import org.hamcrest.Matcher;
+import org.hamcrest.TypeSafeMatcher;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+
+import org.apache.isis.viewer.restfulobjects.applib.JsonRepresentation;
+import org.apache.isis.viewer.restfulobjects.applib.LinkRepresentation;
+import org.apache.isis.viewer.restfulobjects.applib.RestfulMediaType;
+import org.apache.isis.viewer.restfulobjects.applib.client.RestfulClient;
+import org.apache.isis.viewer.restfulobjects.applib.client.RestfulResponse;
+import org.apache.isis.viewer.restfulobjects.applib.client.RestfulResponse.Header;
+import org.apache.isis.viewer.restfulobjects.applib.domainobjects.ActionResultRepresentation;
+import org.apache.isis.viewer.restfulobjects.applib.domainobjects.ActionResultRepresentation.ResultType;
+import org.apache.isis.viewer.restfulobjects.applib.domainobjects.DomainObjectRepresentation;
+import org.apache.isis.viewer.restfulobjects.applib.domainobjects.DomainServiceResource;
+import org.apache.isis.viewer.restfulobjects.applib.domainobjects.ObjectActionRepresentation;
+import org.apache.isis.viewer.restfulobjects.applib.util.UrlEncodingUtils;
+import org.apache.isis.viewer.restfulobjects.tck.IsisWebServerRule;
+import org.apache.isis.viewer.restfulobjects.tck.Util;
+
+public class Get_whenObject_isNull_thenRepresentation_ok {
+
+    @Rule
+    public IsisWebServerRule webServerRule = new IsisWebServerRule();
+
+    private RestfulClient client;
+
+    private DomainServiceResource serviceResource;
+
+    @Before
+    public void setUp() throws Exception {
+        client = webServerRule.getClient();
+
+        serviceResource = client.getDomainServiceResource();
+    }
+
+    @Test
+    public void usingClientFollow() throws Exception {
+
+        // given
+        final JsonRepresentation givenAction = Util.givenAction(client, "ActionsEntities", "findById");
+        final ObjectActionRepresentation actionRepr = givenAction.as(ObjectActionRepresentation.class);
+
+        final LinkRepresentation invokeLink = actionRepr.getInvoke();
+        final JsonRepresentation args =invokeLink.getArguments();
+        
+        // when
+        args.mapPut("id.value", 999);
+
+        // when
+        final RestfulResponse<ActionResultRepresentation> restfulResponse = client.followT(invokeLink, args);
+        
+        // then
+        then(restfulResponse);
+    }
+
+    
+    @Test
+    public void usingResourceProxy() throws Exception {
+
+        // given, when
+        
+        JsonRepresentation args = JsonRepresentation.newMap();
+        args.mapPut("id.value", 999);
+
+        Response response = serviceResource.invokeActionQueryOnly("ActionsEntities", "findById", UrlEncodingUtils.urlEncode(args));
+        RestfulResponse<ActionResultRepresentation> restfulResponse = RestfulResponse.ofT(response);
+        
+        then(restfulResponse);
+    }
+
+    private static void then(final RestfulResponse<ActionResultRepresentation> restfulResponse) throws JsonParseException, JsonMappingException, IOException {
+        
+        assertThat(restfulResponse.getHeader(Header.CONTENT_TYPE), hasProfile(RestfulMediaType.APPLICATION_JSON_ACTION_RESULT));
+        final ActionResultRepresentation actionResultRepr = restfulResponse.getEntity();
+
+        assertThat(actionResultRepr.getResultType(), is(ResultType.DOMAIN_OBJECT));
+        assertThat(actionResultRepr.getResult(), is(nullValue()));
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/isis/blob/584eb10a/component/viewer/restfulobjects/tck/src/test/java/org/apache/isis/viewer/restfulobjects/tck/domainobjectorservice/id/action/invoke/Get_whenObject_thenRepresentation_ok_TODO.java
----------------------------------------------------------------------
diff --git a/component/viewer/restfulobjects/tck/src/test/java/org/apache/isis/viewer/restfulobjects/tck/domainobjectorservice/id/action/invoke/Get_whenObject_thenRepresentation_ok_TODO.java b/component/viewer/restfulobjects/tck/src/test/java/org/apache/isis/viewer/restfulobjects/tck/domainobjectorservice/id/action/invoke/Get_whenObject_thenRepresentation_ok_TODO.java
deleted file mode 100644
index c86172c..0000000
--- a/component/viewer/restfulobjects/tck/src/test/java/org/apache/isis/viewer/restfulobjects/tck/domainobjectorservice/id/action/invoke/Get_whenObject_thenRepresentation_ok_TODO.java
+++ /dev/null
@@ -1,13 +0,0 @@
-package org.apache.isis.viewer.restfulobjects.tck.domainobjectorservice.id.action.invoke;
-
-import org.junit.Ignore;
-import org.junit.Test;
-
-public class Get_whenObject_thenRepresentation_ok_TODO {
-
-    @Ignore
-    @Test
-    public void todo() throws Exception {
-        
-    }
-}

http://git-wip-us.apache.org/repos/asf/isis/blob/584eb10a/component/viewer/restfulobjects/tck/src/test/java/org/apache/isis/viewer/restfulobjects/tck/domainobjectorservice/id/action/invoke/Get_whenObject_thenResponseHeaders_ContentLength_ok_TODO.java
----------------------------------------------------------------------
diff --git a/component/viewer/restfulobjects/tck/src/test/java/org/apache/isis/viewer/restfulobjects/tck/domainobjectorservice/id/action/invoke/Get_whenObject_thenResponseHeaders_ContentLength_ok_TODO.java b/component/viewer/restfulobjects/tck/src/test/java/org/apache/isis/viewer/restfulobjects/tck/domainobjectorservice/id/action/invoke/Get_whenObject_thenResponseHeaders_ContentLength_ok_TODO.java
deleted file mode 100644
index bb10774..0000000
--- a/component/viewer/restfulobjects/tck/src/test/java/org/apache/isis/viewer/restfulobjects/tck/domainobjectorservice/id/action/invoke/Get_whenObject_thenResponseHeaders_ContentLength_ok_TODO.java
+++ /dev/null
@@ -1,13 +0,0 @@
-package org.apache.isis.viewer.restfulobjects.tck.domainobjectorservice.id.action.invoke;
-
-import org.junit.Ignore;
-import org.junit.Test;
-
-public class Get_whenObject_thenResponseHeaders_ContentLength_ok_TODO {
-
-    @Ignore
-    @Test
-    public void todo() throws Exception {
-        
-    }
-}

http://git-wip-us.apache.org/repos/asf/isis/blob/584eb10a/component/viewer/restfulobjects/tck/src/test/java/org/apache/isis/viewer/restfulobjects/tck/domainobjectorservice/id/action/invoke/Get_whenObject_thenResponseHeaders_ContentType_ok_TODO.java
----------------------------------------------------------------------
diff --git a/component/viewer/restfulobjects/tck/src/test/java/org/apache/isis/viewer/restfulobjects/tck/domainobjectorservice/id/action/invoke/Get_whenObject_thenResponseHeaders_ContentType_ok_TODO.java b/component/viewer/restfulobjects/tck/src/test/java/org/apache/isis/viewer/restfulobjects/tck/domainobjectorservice/id/action/invoke/Get_whenObject_thenResponseHeaders_ContentType_ok_TODO.java
deleted file mode 100644
index 18ead99..0000000
--- a/component/viewer/restfulobjects/tck/src/test/java/org/apache/isis/viewer/restfulobjects/tck/domainobjectorservice/id/action/invoke/Get_whenObject_thenResponseHeaders_ContentType_ok_TODO.java
+++ /dev/null
@@ -1,13 +0,0 @@
-package org.apache.isis.viewer.restfulobjects.tck.domainobjectorservice.id.action.invoke;
-
-import org.junit.Ignore;
-import org.junit.Test;
-
-public class Get_whenObject_thenResponseHeaders_ContentType_ok_TODO {
-
-    @Ignore
-    @Test
-    public void todo() throws Exception {
-        
-    }
-}

http://git-wip-us.apache.org/repos/asf/isis/blob/584eb10a/component/viewer/restfulobjects/tck/src/test/java/org/apache/isis/viewer/restfulobjects/tck/domainobjectorservice/id/action/invoke/Post_thenRepresentation_doesNotContainSelfLink_ok.java
----------------------------------------------------------------------
diff --git a/component/viewer/restfulobjects/tck/src/test/java/org/apache/isis/viewer/restfulobjects/tck/domainobjectorservice/id/action/invoke/Post_thenRepresentation_doesNotContainSelfLink_ok.java b/component/viewer/restfulobjects/tck/src/test/java/org/apache/isis/viewer/restfulobjects/tck/domainobjectorservice/id/action/invoke/Post_thenRepresentation_doesNotContainSelfLink_ok.java
new file mode 100644
index 0000000..0e3b9ce
--- /dev/null
+++ b/component/viewer/restfulobjects/tck/src/test/java/org/apache/isis/viewer/restfulobjects/tck/domainobjectorservice/id/action/invoke/Post_thenRepresentation_doesNotContainSelfLink_ok.java
@@ -0,0 +1,93 @@
+package org.apache.isis.viewer.restfulobjects.tck.domainobjectorservice.id.action.invoke;
+
+import static org.apache.isis.viewer.restfulobjects.tck.RestfulMatchers.assertThat;
+import static org.apache.isis.viewer.restfulobjects.tck.RestfulMatchers.isLink;
+import static org.hamcrest.CoreMatchers.*;
+import static org.hamcrest.CoreMatchers.endsWith;
+import static org.junit.Assert.assertThat;
+
+import java.io.IOException;
+import java.io.InputStream;
+
+import javax.ws.rs.core.Response;
+
+import org.codehaus.jackson.JsonParseException;
+import org.codehaus.jackson.map.JsonMappingException;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+
+import org.apache.isis.viewer.restfulobjects.applib.JsonRepresentation;
+import org.apache.isis.viewer.restfulobjects.applib.LinkRepresentation;
+import org.apache.isis.viewer.restfulobjects.applib.Rel;
+import org.apache.isis.viewer.restfulobjects.applib.RepresentationType;
+import org.apache.isis.viewer.restfulobjects.applib.RestfulHttpMethod;
+import org.apache.isis.viewer.restfulobjects.applib.client.RestfulClient;
+import org.apache.isis.viewer.restfulobjects.applib.client.RestfulResponse;
+import org.apache.isis.viewer.restfulobjects.applib.domainobjects.ActionResultRepresentation;
+import org.apache.isis.viewer.restfulobjects.applib.domainobjects.DomainServiceResource;
+import org.apache.isis.viewer.restfulobjects.applib.domainobjects.ObjectActionRepresentation;
+import org.apache.isis.viewer.restfulobjects.applib.util.JsonNodeUtils;
+import org.apache.isis.viewer.restfulobjects.applib.util.UrlEncodingUtils;
+import org.apache.isis.viewer.restfulobjects.tck.IsisWebServerRule;
+import org.apache.isis.viewer.restfulobjects.tck.Util;
+
+public class Post_thenRepresentation_doesNotContainSelfLink_ok {
+
+    @Rule
+    public IsisWebServerRule webServerRule = new IsisWebServerRule();
+
+    private RestfulClient client;
+
+    private DomainServiceResource serviceResource;
+
+    @Before
+    public void setUp() throws Exception {
+        client = webServerRule.getClient();
+
+        serviceResource = client.getDomainServiceResource();
+    }
+
+    @Test
+    public void usingClientFollow() throws Exception {
+
+        // given
+        final JsonRepresentation givenAction = Util.givenAction(client, "ActionsEntities", "findByIdNotIdempotent");
+        final ObjectActionRepresentation actionRepr = givenAction.as(ObjectActionRepresentation.class);
+
+        final LinkRepresentation invokeLink = actionRepr.getInvoke();
+        final JsonRepresentation args =invokeLink.getArguments();
+        
+        // when
+        args.mapPut("id.value", 1);
+
+        // when
+        final RestfulResponse<ActionResultRepresentation> restfulResponse = client.followT(invokeLink, args);
+        
+        // then
+        then(restfulResponse);
+    }
+
+    
+
+    @Test
+    public void usingResourceProxy() throws Exception {
+
+        // given, when
+        final JsonRepresentation args = JsonRepresentation.newMap();
+        args.mapPut("id.value", 1);
+
+        final Response response = serviceResource.invokeAction("ActionsEntities", "findByIdNotIdempotent", JsonNodeUtils.asInputStream(args));
+        final RestfulResponse<ActionResultRepresentation> restfulResponse = RestfulResponse.ofT(response);
+        
+        // then
+        then(restfulResponse);
+        
+    }
+
+    private void then(RestfulResponse<ActionResultRepresentation> restfulResponse) throws Exception {
+        final ActionResultRepresentation actionResultRepr = restfulResponse.getEntity();
+        assertThat(actionResultRepr.mapHas("links[rel=self]"), is(false));
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/isis/blob/584eb10a/component/viewer/restfulobjects/tck/src/test/java/org/apache/isis/viewer/restfulobjects/tck/domainobjectorservice/id/action/invoke/Put_thenRepresentation_doesNotContainSelfLink_ok.java
----------------------------------------------------------------------
diff --git a/component/viewer/restfulobjects/tck/src/test/java/org/apache/isis/viewer/restfulobjects/tck/domainobjectorservice/id/action/invoke/Put_thenRepresentation_doesNotContainSelfLink_ok.java b/component/viewer/restfulobjects/tck/src/test/java/org/apache/isis/viewer/restfulobjects/tck/domainobjectorservice/id/action/invoke/Put_thenRepresentation_doesNotContainSelfLink_ok.java
new file mode 100644
index 0000000..70f09d2
--- /dev/null
+++ b/component/viewer/restfulobjects/tck/src/test/java/org/apache/isis/viewer/restfulobjects/tck/domainobjectorservice/id/action/invoke/Put_thenRepresentation_doesNotContainSelfLink_ok.java
@@ -0,0 +1,93 @@
+package org.apache.isis.viewer.restfulobjects.tck.domainobjectorservice.id.action.invoke;
+
+import static org.apache.isis.viewer.restfulobjects.tck.RestfulMatchers.assertThat;
+import static org.apache.isis.viewer.restfulobjects.tck.RestfulMatchers.isLink;
+import static org.hamcrest.CoreMatchers.*;
+import static org.hamcrest.CoreMatchers.endsWith;
+import static org.junit.Assert.assertThat;
+
+import java.io.IOException;
+import java.io.InputStream;
+
+import javax.ws.rs.core.Response;
+
+import org.codehaus.jackson.JsonParseException;
+import org.codehaus.jackson.map.JsonMappingException;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+
+import org.apache.isis.viewer.restfulobjects.applib.JsonRepresentation;
+import org.apache.isis.viewer.restfulobjects.applib.LinkRepresentation;
+import org.apache.isis.viewer.restfulobjects.applib.Rel;
+import org.apache.isis.viewer.restfulobjects.applib.RepresentationType;
+import org.apache.isis.viewer.restfulobjects.applib.RestfulHttpMethod;
+import org.apache.isis.viewer.restfulobjects.applib.client.RestfulClient;
+import org.apache.isis.viewer.restfulobjects.applib.client.RestfulResponse;
+import org.apache.isis.viewer.restfulobjects.applib.domainobjects.ActionResultRepresentation;
+import org.apache.isis.viewer.restfulobjects.applib.domainobjects.DomainServiceResource;
+import org.apache.isis.viewer.restfulobjects.applib.domainobjects.ObjectActionRepresentation;
+import org.apache.isis.viewer.restfulobjects.applib.util.JsonNodeUtils;
+import org.apache.isis.viewer.restfulobjects.applib.util.UrlEncodingUtils;
+import org.apache.isis.viewer.restfulobjects.tck.IsisWebServerRule;
+import org.apache.isis.viewer.restfulobjects.tck.Util;
+
+public class Put_thenRepresentation_doesNotContainSelfLink_ok {
+
+    @Rule
+    public IsisWebServerRule webServerRule = new IsisWebServerRule();
+
+    private RestfulClient client;
+
+    private DomainServiceResource serviceResource;
+
+    @Before
+    public void setUp() throws Exception {
+        client = webServerRule.getClient();
+
+        serviceResource = client.getDomainServiceResource();
+    }
+
+    @Test
+    public void usingClientFollow() throws Exception {
+
+        // given
+        final JsonRepresentation givenAction = Util.givenAction(client, "ActionsEntities", "findByIdIdempotent");
+        final ObjectActionRepresentation actionRepr = givenAction.as(ObjectActionRepresentation.class);
+
+        final LinkRepresentation invokeLink = actionRepr.getInvoke();
+        final JsonRepresentation args =invokeLink.getArguments();
+        
+        // when
+        args.mapPut("id.value", 1);
+
+        // when
+        final RestfulResponse<ActionResultRepresentation> restfulResponse = client.followT(invokeLink, args);
+        
+        // then
+        then(restfulResponse);
+    }
+
+    
+
+    @Test
+    public void usingResourceProxy() throws Exception {
+
+        // given, when
+        final JsonRepresentation args = JsonRepresentation.newMap();
+        args.mapPut("id.value", 1);
+
+        final Response response = serviceResource.invokeActionIdempotent("ActionsEntities", "findByIdIdempotent", JsonNodeUtils.asInputStream(args));
+        final RestfulResponse<ActionResultRepresentation> restfulResponse = RestfulResponse.ofT(response);
+        
+        // then
+        then(restfulResponse);
+        
+    }
+
+    private void then(RestfulResponse<ActionResultRepresentation> restfulResponse) throws Exception {
+        final ActionResultRepresentation actionResultRepr = restfulResponse.getEntity();
+        assertThat(actionResultRepr.getSelf(), is(nullValue()));
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/isis/blob/584eb10a/core/tck/tck-dom/src/main/java/org/apache/isis/core/tck/dom/actions/ActionsEntityRepository.java
----------------------------------------------------------------------
diff --git a/core/tck/tck-dom/src/main/java/org/apache/isis/core/tck/dom/actions/ActionsEntityRepository.java b/core/tck/tck-dom/src/main/java/org/apache/isis/core/tck/dom/actions/ActionsEntityRepository.java
index 676f04b..65c07f7 100644
--- a/core/tck/tck-dom/src/main/java/org/apache/isis/core/tck/dom/actions/ActionsEntityRepository.java
+++ b/core/tck/tck-dom/src/main/java/org/apache/isis/core/tck/dom/actions/ActionsEntityRepository.java
@@ -28,8 +28,6 @@ import org.apache.isis.applib.annotation.MustSatisfy;
 import org.apache.isis.applib.annotation.Named;
 import org.apache.isis.applib.annotation.ObjectType;
 import org.apache.isis.applib.annotation.Optional;
-import org.apache.isis.applib.query.Query;
-import org.apache.isis.applib.query.QueryDefault;
 import org.apache.isis.applib.spec.Specification;
 import org.apache.isis.core.tck.dom.AbstractEntityRepository;
 
@@ -44,9 +42,24 @@ public class ActionsEntityRepository extends AbstractEntityRepository<ActionsEnt
     @ActionSemantics(Of.SAFE)
     @MemberOrder(sequence = "1")
     public ActionsEntity findById(@Named("id") int id) {
-        final Query<ActionsEntity> query = 
-                new QueryDefault<ActionsEntity>(ActionsEntity.class, ActionsEntity.class.getName() + "#pk", "id", id);
-        return this.firstMatch(query);
+        return findByIdIfAny(id);
+    }
+
+    @ActionSemantics(Of.IDEMPOTENT)
+    @MemberOrder(sequence = "1")
+    public ActionsEntity findByIdIdempotent(@Named("id") int id) {
+        return findByIdIfAny(id);
+    }
+
+    @ActionSemantics(Of.NON_IDEMPOTENT)
+    @MemberOrder(sequence = "1")
+    public ActionsEntity findByIdNotIdempotent(@Named("id") int id) {
+        return findByIdIfAny(id);
+    }
+
+    private ActionsEntity findByIdIfAny(int id) {
+        List<ActionsEntity> subList = subList(id, id+1);
+        return subList.isEmpty()?null:subList.get(0);
     }
 
     @ActionSemantics(Of.SAFE)