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 2011/10/14 21:28:56 UTC

svn commit: r1183465 - in /incubator/isis/trunk/framework/viewer/json: json-applib/src/main/java/org/apache/isis/viewer/json/applib/ json-applib/src/main/java/org/apache/isis/viewer/json/applib/blocks/ json-applib/src/main/java/org/apache/isis/viewer/j...

Author: danhaywood
Date: Fri Oct 14 19:28:55 2011
New Revision: 1183465

URL: http://svn.apache.org/viewvc?rev=1183465&view=rev
Log:
ISIS-109: more on x-ro-follow-links for DomainServiceResource; work on argument maps for links and follow(...) client-side code

Added:
    incubator/isis/trunk/framework/viewer/json/json-applib/src/main/java/org/apache/isis/viewer/json/applib/util/UrlEncodingUtils.java
      - copied, changed from r1182226, incubator/isis/trunk/framework/viewer/json/json-applib/src/main/java/org/apache/isis/viewer/json/applib/util/UrlDecodeUtils.java
    incubator/isis/trunk/framework/viewer/json/json-applib/src/test/java/org/apache/isis/viewer/json/applib/JsonRepresentationTest_mapIterable.java
    incubator/isis/trunk/framework/viewer/json/json-applib/src/test/java/org/apache/isis/viewer/json/applib/JsonRepresentationTest_urlEncoding.java
      - copied, changed from r1182130, incubator/isis/trunk/framework/viewer/json/json-applib/src/test/java/org/apache/isis/viewer/json/applib/blocks/LinkTest_urlEncoding.java
    incubator/isis/trunk/framework/viewer/json/json-applib/src/test/java/org/apache/isis/viewer/json/applib/blocks/MethodTest_setUp.java
Removed:
    incubator/isis/trunk/framework/viewer/json/json-applib/src/main/java/org/apache/isis/viewer/json/applib/blocks/ArgumentList.java
    incubator/isis/trunk/framework/viewer/json/json-applib/src/main/java/org/apache/isis/viewer/json/applib/blocks/ArgumentMap.java
    incubator/isis/trunk/framework/viewer/json/json-applib/src/main/java/org/apache/isis/viewer/json/applib/blocks/ArgumentNode.java
    incubator/isis/trunk/framework/viewer/json/json-applib/src/main/java/org/apache/isis/viewer/json/applib/util/UrlDecodeUtils.java
    incubator/isis/trunk/framework/viewer/json/json-applib/src/test/java/org/apache/isis/viewer/json/applib/blocks/ArgumentListTest_urlEncoding.java
    incubator/isis/trunk/framework/viewer/json/json-applib/src/test/java/org/apache/isis/viewer/json/applib/blocks/LinkTest_urlEncoding.java
Modified:
    incubator/isis/trunk/framework/viewer/json/json-applib/src/main/java/org/apache/isis/viewer/json/applib/JsonRepresentation.java
    incubator/isis/trunk/framework/viewer/json/json-applib/src/main/java/org/apache/isis/viewer/json/applib/RestfulClient.java
    incubator/isis/trunk/framework/viewer/json/json-applib/src/main/java/org/apache/isis/viewer/json/applib/RestfulRequest.java
    incubator/isis/trunk/framework/viewer/json/json-applib/src/main/java/org/apache/isis/viewer/json/applib/blocks/Link.java
    incubator/isis/trunk/framework/viewer/json/json-applib/src/main/java/org/apache/isis/viewer/json/applib/blocks/Method.java
    incubator/isis/trunk/framework/viewer/json/json-applib/src/main/java/org/apache/isis/viewer/json/applib/domainobjects/ObjectActionRepresentation.java
    incubator/isis/trunk/framework/viewer/json/json-applib/src/main/java/org/apache/isis/viewer/json/applib/util/JsonNodeUtils.java
    incubator/isis/trunk/framework/viewer/json/json-applib/src/test/java/org/apache/isis/viewer/json/applib/RestfulClientTest_follow.java
    incubator/isis/trunk/framework/viewer/json/json-tck/src/test/java/org/apache/isis/viewer/json/tck/resources/service/invoke/DomainServiceResourceTest_invokeAction.java
    incubator/isis/trunk/framework/viewer/json/json-tck/src/test/java/org/apache/isis/viewer/json/tck/resources/service/serviceId/DomainServiceResourceTest_serviceId_xrofollowlinks.java
    incubator/isis/trunk/framework/viewer/json/json-viewer/src/main/java/org/apache/isis/viewer/json/viewer/representations/LinkFollower.java
    incubator/isis/trunk/framework/viewer/json/json-viewer/src/main/java/org/apache/isis/viewer/json/viewer/resources/domainobjects/AbstractObjectMemberReprRenderer.java
    incubator/isis/trunk/framework/viewer/json/json-viewer/src/main/java/org/apache/isis/viewer/json/viewer/resources/domainobjects/DomainObjectReprRenderer.java
    incubator/isis/trunk/framework/viewer/json/json-viewer/src/main/java/org/apache/isis/viewer/json/viewer/resources/domainobjects/ObjectActionReprRenderer.java
    incubator/isis/trunk/framework/viewer/json/json-viewer/src/main/java/org/apache/isis/viewer/json/viewer/resources/domainobjects/ObjectCollectionReprRenderer.java
    incubator/isis/trunk/framework/viewer/json/json-viewer/src/main/java/org/apache/isis/viewer/json/viewer/resources/domainobjects/ObjectPropertyReprRenderer.java
    incubator/isis/trunk/framework/viewer/json/json-viewer/src/test/java/org/apache/isis/viewer/json/viewer/representations/LinkFollowerTest_follow.java

Modified: incubator/isis/trunk/framework/viewer/json/json-applib/src/main/java/org/apache/isis/viewer/json/applib/JsonRepresentation.java
URL: http://svn.apache.org/viewvc/incubator/isis/trunk/framework/viewer/json/json-applib/src/main/java/org/apache/isis/viewer/json/applib/JsonRepresentation.java?rev=1183465&r1=1183464&r2=1183465&view=diff
==============================================================================
--- incubator/isis/trunk/framework/viewer/json/json-applib/src/main/java/org/apache/isis/viewer/json/applib/JsonRepresentation.java (original)
+++ incubator/isis/trunk/framework/viewer/json/json-applib/src/main/java/org/apache/isis/viewer/json/applib/JsonRepresentation.java Fri Oct 14 19:28:55 2011
@@ -12,6 +12,7 @@ import java.util.Collections;
 import java.util.Iterator;
 import java.util.List;
 import java.util.Map;
+import java.util.Map.Entry;
 
 import net.sf.json.JSON;
 import net.sf.json.JSONNull;
@@ -19,8 +20,10 @@ import net.sf.json.JSONSerializer;
 import net.sf.json.xml.XMLSerializer;
 
 import org.apache.isis.viewer.json.applib.blocks.Link;
+import org.apache.isis.viewer.json.applib.domainobjects.ObjectActionRepresentation;
 import org.apache.isis.viewer.json.applib.util.JsonMapper;
 import org.apache.isis.viewer.json.applib.util.JsonNodeUtils;
+import org.apache.isis.viewer.json.applib.util.UrlEncodingUtils;
 import org.codehaus.jackson.JsonNode;
 import org.codehaus.jackson.JsonParseException;
 import org.codehaus.jackson.map.JsonMappingException;
@@ -35,6 +38,7 @@ import org.jdom.output.XMLOutputter;
 import org.jdom.xpath.XPath;
 
 import com.google.common.base.Function;
+import com.google.common.collect.ImmutableMap;
 import com.google.common.collect.Iterators;
 import com.google.common.collect.Lists;
 import com.google.common.collect.Maps;
@@ -467,6 +471,14 @@ public class JsonRepresentation {
         return node.getTextValue();
     }
 
+    public String asArg() {
+        if(isValue()) {
+            return asJsonNode().getValueAsText();
+        } else {
+            return asJsonNode().toString();
+        }
+    }
+
     
     /////////////////////////////////////////////////////////////////////////
     // isLink, getLink, asLink
@@ -626,6 +638,24 @@ public class JsonRepresentation {
     }
 
 
+    
+    /////////////////////////////////////////////////////////////////////////
+    // asT
+    /////////////////////////////////////////////////////////////////////////
+
+    /**
+     * Convenience to simply downcast.
+     */
+    public <T extends JsonRepresentation> T as(Class<T> cls) {
+        try {
+            final Constructor<T> constructor = cls.getConstructor(JsonNode.class);
+            return (T)constructor.newInstance(jsonNode);
+        } catch (Exception e) {
+            throw new RuntimeException(e);
+        }
+    }
+
+    
     /////////////////////////////////////////////////////////////////////////
     // xpath support
     /////////////////////////////////////////////////////////////////////////
@@ -702,7 +732,7 @@ public class JsonRepresentation {
     }
 
     public String asUrlEncoded() {
-        return JsonNodeUtils.asUrlEncoded(asJsonNode());
+        return UrlEncodingUtils.asUrlEncoded(asJsonNode());
     }
 
 
@@ -957,8 +987,54 @@ public class JsonRepresentation {
     }
     
 
+    public Iterable<Map.Entry<String, JsonRepresentation>> mapIterable() {
+        ensureIsAMap();
+        return new Iterable<Map.Entry<String,JsonRepresentation>>() {
+            
+            @Override
+            public Iterator<Entry<String, JsonRepresentation>> iterator() {
+                return mapIterator();
+            }
+        };
+    }
+
+    public Iterator<Map.Entry<String, JsonRepresentation>> mapIterator() {
+        ensureIsAMap();
+        return Iterators.transform(jsonNode.getFields(), MAP_ENTRY_JSON_NODE_TO_JSON_REPRESENTATION);
+    }
+
+    private void ensureIsAMap() {
+        if (!jsonNode.isObject()) {
+            throw new IllegalStateException("Is not a map");
+        }
+    }
+
+    private final static Function<Entry<String, JsonNode>, Entry<String, JsonRepresentation>> MAP_ENTRY_JSON_NODE_TO_JSON_REPRESENTATION = new Function<Entry<String,JsonNode>, Entry<String,JsonRepresentation>>() {
+
+        @Override
+        public Entry<String, JsonRepresentation> apply(final Entry<String,JsonNode> input) {
+            return new Map.Entry<String, JsonRepresentation>() {
+
+                @Override
+                public String getKey() {
+                    return input.getKey();
+                }
+
+                @Override
+                public JsonRepresentation getValue() {
+                    return new JsonRepresentation(input.getValue());
+                }
+
+                @Override
+                public JsonRepresentation setValue(JsonRepresentation value) {
+                    final JsonNode setValue = input.setValue(value.asJsonNode());
+                    return new JsonRepresentation(setValue);
+                }
+            };
+        }
+    };
+
 
-    
     /////////////////////////////////////////////////////////////////////////
     // helpers
     /////////////////////////////////////////////////////////////////////////
@@ -1009,4 +1085,8 @@ public class JsonRepresentation {
 
 
 
+
+
+
+
 }

Modified: incubator/isis/trunk/framework/viewer/json/json-applib/src/main/java/org/apache/isis/viewer/json/applib/RestfulClient.java
URL: http://svn.apache.org/viewvc/incubator/isis/trunk/framework/viewer/json/json-applib/src/main/java/org/apache/isis/viewer/json/applib/RestfulClient.java?rev=1183465&r1=1183464&r2=1183465&view=diff
==============================================================================
--- incubator/isis/trunk/framework/viewer/json/json-applib/src/main/java/org/apache/isis/viewer/json/applib/RestfulClient.java (original)
+++ incubator/isis/trunk/framework/viewer/json/json-applib/src/main/java/org/apache/isis/viewer/json/applib/RestfulClient.java Fri Oct 14 19:28:55 2011
@@ -105,11 +105,12 @@ public class RestfulClient {
     }
 
     public Response follow(Link link) throws Exception {
-        return follow(link, null);
+        return follow(link, JsonRepresentation.newMap());
     }
 
-    public Response follow(Link link, JsonRepresentation requestBody) throws Exception {
-        Response response = link.follow(executor, requestBody);
+    // TODO: generalize into request args
+    public Response follow(Link link, JsonRepresentation requestArgs) throws Exception {
+        Response response = link.follow(executor, requestArgs);
         // this is a bit hacky
         @SuppressWarnings("unchecked")
         BaseClientResponse<String> restEasy = (BaseClientResponse<String>)response;

Modified: incubator/isis/trunk/framework/viewer/json/json-applib/src/main/java/org/apache/isis/viewer/json/applib/RestfulRequest.java
URL: http://svn.apache.org/viewvc/incubator/isis/trunk/framework/viewer/json/json-applib/src/main/java/org/apache/isis/viewer/json/applib/RestfulRequest.java?rev=1183465&r1=1183464&r2=1183465&view=diff
==============================================================================
--- incubator/isis/trunk/framework/viewer/json/json-applib/src/main/java/org/apache/isis/viewer/json/applib/RestfulRequest.java (original)
+++ incubator/isis/trunk/framework/viewer/json/json-applib/src/main/java/org/apache/isis/viewer/json/applib/RestfulRequest.java Fri Oct 14 19:28:55 2011
@@ -1,6 +1,6 @@
 package org.apache.isis.viewer.json.applib;
 
-import static org.apache.isis.viewer.json.applib.util.UrlDecodeUtils.*;
+import static org.apache.isis.viewer.json.applib.util.UrlEncodingUtils.*;
 
 import java.util.Arrays;
 import java.util.Collections;

Modified: incubator/isis/trunk/framework/viewer/json/json-applib/src/main/java/org/apache/isis/viewer/json/applib/blocks/Link.java
URL: http://svn.apache.org/viewvc/incubator/isis/trunk/framework/viewer/json/json-applib/src/main/java/org/apache/isis/viewer/json/applib/blocks/Link.java?rev=1183465&r1=1183464&r2=1183465&view=diff
==============================================================================
--- incubator/isis/trunk/framework/viewer/json/json-applib/src/main/java/org/apache/isis/viewer/json/applib/blocks/Link.java (original)
+++ incubator/isis/trunk/framework/viewer/json/json-applib/src/main/java/org/apache/isis/viewer/json/applib/blocks/Link.java Fri Oct 14 19:28:55 2011
@@ -80,13 +80,12 @@ public final class Link extends JsonRepr
         return follow(executor, null);
     }
 
-    public <T> Response follow(ClientExecutor executor, JsonRepresentation requestBody) throws Exception {
+    public <T> Response follow(ClientExecutor executor, JsonRepresentation requestArgs) throws Exception {
         ClientRequest restEasyRequest = executor.createRequest(getHref());
-        restEasyRequest.setHttpMethod(getMethod().name());
         restEasyRequest.accept(MediaType.APPLICATION_JSON_TYPE);
-        if(requestBody != null) {
-            restEasyRequest.body(MediaType.APPLICATION_JSON, requestBody.toString());
-        }
+        
+        getMethod().setUp(restEasyRequest, requestArgs);
+        
         @SuppressWarnings("unchecked")
         ClientResponse<T> restEasyResponse = executor.execute(restEasyRequest);
         return restEasyResponse;

Modified: incubator/isis/trunk/framework/viewer/json/json-applib/src/main/java/org/apache/isis/viewer/json/applib/blocks/Method.java
URL: http://svn.apache.org/viewvc/incubator/isis/trunk/framework/viewer/json/json-applib/src/main/java/org/apache/isis/viewer/json/applib/blocks/Method.java?rev=1183465&r1=1183464&r2=1183465&view=diff
==============================================================================
--- incubator/isis/trunk/framework/viewer/json/json-applib/src/main/java/org/apache/isis/viewer/json/applib/blocks/Method.java (original)
+++ incubator/isis/trunk/framework/viewer/json/json-applib/src/main/java/org/apache/isis/viewer/json/applib/blocks/Method.java Fri Oct 14 19:28:55 2011
@@ -1,8 +1,54 @@
 package org.apache.isis.viewer.json.applib.blocks;
 
+import java.util.Arrays;
+import java.util.Map;
+
+import javax.ws.rs.core.MediaType;
+import javax.ws.rs.core.MultivaluedMap;
+
+import org.apache.isis.viewer.json.applib.JsonRepresentation;
+import org.apache.isis.viewer.json.applib.util.UrlEncodingUtils;
+import org.jboss.resteasy.client.ClientRequest;
+
 public enum Method {
-    GET,
-    PUT,
-    POST,
-    DELETE
+    GET(ArgStrategy.QUERY_STRING),
+    PUT(ArgStrategy.BODY),
+    POST(ArgStrategy.BODY),
+    DELETE(ArgStrategy.QUERY_STRING);
+
+    private enum ArgStrategy {
+        QUERY_STRING,
+        BODY;
+        void setUpArgs(ClientRequest restEasyRequest, JsonRepresentation requestArgs) {
+            if(this == QUERY_STRING) {
+                final MultivaluedMap<String, String> queryParameters = restEasyRequest.getQueryParameters();
+                for(Map.Entry<String, JsonRepresentation> entry: requestArgs.mapIterable()) {
+                    final String param = entry.getKey();
+                    final JsonRepresentation argRepr = entry.getValue();
+                    final String arg = UrlEncodingUtils.asUrlEncoded(argRepr.asArg());
+                    queryParameters.add(param, arg);
+                }
+            } else {
+                restEasyRequest.body(MediaType.APPLICATION_JSON_TYPE, requestArgs.toString());
+            }
+        }
+    }
+    
+    private final ArgStrategy argStrategy;
+
+    private Method(ArgStrategy argStrategy) {
+        this.argStrategy = argStrategy;
+    }
+
+    public void setUp(ClientRequest restEasyRequest, JsonRepresentation requestArgs) {
+        restEasyRequest.setHttpMethod(name());
+        if(requestArgs == null) {
+            return;
+        }
+        if(!requestArgs.isMap()) {
+            throw new IllegalArgumentException("requestArgs must be a map; instead got: " + requestArgs);
+        }
+        argStrategy.setUpArgs(restEasyRequest, requestArgs);
+    }
+
 }

Modified: incubator/isis/trunk/framework/viewer/json/json-applib/src/main/java/org/apache/isis/viewer/json/applib/domainobjects/ObjectActionRepresentation.java
URL: http://svn.apache.org/viewvc/incubator/isis/trunk/framework/viewer/json/json-applib/src/main/java/org/apache/isis/viewer/json/applib/domainobjects/ObjectActionRepresentation.java?rev=1183465&r1=1183464&r2=1183465&view=diff
==============================================================================
--- incubator/isis/trunk/framework/viewer/json/json-applib/src/main/java/org/apache/isis/viewer/json/applib/domainobjects/ObjectActionRepresentation.java (original)
+++ incubator/isis/trunk/framework/viewer/json/json-applib/src/main/java/org/apache/isis/viewer/json/applib/domainobjects/ObjectActionRepresentation.java Fri Oct 14 19:28:55 2011
@@ -26,6 +26,10 @@ public class ObjectActionRepresentation 
         return getString("memberType");
     }
 
+    public Link getInvoke() {
+        return getLink("invoke");
+    }
+
     public String getActionId() {
         return getString("actionId");
     }

Modified: incubator/isis/trunk/framework/viewer/json/json-applib/src/main/java/org/apache/isis/viewer/json/applib/util/JsonNodeUtils.java
URL: http://svn.apache.org/viewvc/incubator/isis/trunk/framework/viewer/json/json-applib/src/main/java/org/apache/isis/viewer/json/applib/util/JsonNodeUtils.java?rev=1183465&r1=1183464&r2=1183465&view=diff
==============================================================================
--- incubator/isis/trunk/framework/viewer/json/json-applib/src/main/java/org/apache/isis/viewer/json/applib/util/JsonNodeUtils.java (original)
+++ incubator/isis/trunk/framework/viewer/json/json-applib/src/main/java/org/apache/isis/viewer/json/applib/util/JsonNodeUtils.java Fri Oct 14 19:28:55 2011
@@ -2,8 +2,6 @@ package org.apache.isis.viewer.json.appl
 
 import java.io.ByteArrayInputStream;
 import java.io.InputStream;
-import java.io.UnsupportedEncodingException;
-import java.net.URLEncoder;
 import java.util.List;
 
 import org.codehaus.jackson.JsonNode;
@@ -63,13 +61,4 @@ public class JsonNodeUtils {
         return (ObjectNode) node;
     }
 
-    public static String asUrlEncoded(JsonNode jsonNode) {
-        try {
-            return URLEncoder.encode(jsonNode.toString(), Charsets.UTF_8.name());
-        } catch (UnsupportedEncodingException e) {
-            // shouldn't happen
-            throw new RuntimeException(e);
-        }
-    }
-
 }

Copied: incubator/isis/trunk/framework/viewer/json/json-applib/src/main/java/org/apache/isis/viewer/json/applib/util/UrlEncodingUtils.java (from r1182226, incubator/isis/trunk/framework/viewer/json/json-applib/src/main/java/org/apache/isis/viewer/json/applib/util/UrlDecodeUtils.java)
URL: http://svn.apache.org/viewvc/incubator/isis/trunk/framework/viewer/json/json-applib/src/main/java/org/apache/isis/viewer/json/applib/util/UrlEncodingUtils.java?p2=incubator/isis/trunk/framework/viewer/json/json-applib/src/main/java/org/apache/isis/viewer/json/applib/util/UrlEncodingUtils.java&p1=incubator/isis/trunk/framework/viewer/json/json-applib/src/main/java/org/apache/isis/viewer/json/applib/util/UrlDecodeUtils.java&r1=1182226&r2=1183465&rev=1183465&view=diff
==============================================================================
--- incubator/isis/trunk/framework/viewer/json/json-applib/src/main/java/org/apache/isis/viewer/json/applib/util/UrlDecodeUtils.java (original)
+++ incubator/isis/trunk/framework/viewer/json/json-applib/src/main/java/org/apache/isis/viewer/json/applib/util/UrlEncodingUtils.java Fri Oct 14 19:28:55 2011
@@ -4,22 +4,15 @@ import java.io.UnsupportedEncodingExcept
 import java.net.URLDecoder;
 import java.net.URLEncoder;
 import java.util.Arrays;
-import java.util.Collections;
 import java.util.List;
-import java.util.Map;
 
-import javax.ws.rs.core.MediaType;
-import javax.ws.rs.core.Response;
-
-import org.jboss.resteasy.client.ClientRequest;
-import org.jboss.resteasy.util.URLUtils;
+import org.codehaus.jackson.JsonNode;
 
+import com.google.common.base.Charsets;
 import com.google.common.base.Function;
-import com.google.common.collect.Iterables;
 import com.google.common.collect.Lists;
-import com.google.common.collect.Maps;
 
-public final class UrlDecodeUtils {
+public final class UrlEncodingUtils {
 
     public final static Function<String, String> FUNCTION = new Function<String, String>() {
         
@@ -33,7 +26,7 @@ public final class UrlDecodeUtils {
         }
     };
 
-    private UrlDecodeUtils() {}
+    private UrlEncodingUtils() {}
 
     public static String urlDecode(String string) {
         return FUNCTION.apply(string);
@@ -48,4 +41,17 @@ public final class UrlDecodeUtils {
         return urlDecode(asList).toArray(new String[]{});
     }
 
+    public static String asUrlEncoded(JsonNode jsonNode) {
+        return UrlEncodingUtils.asUrlEncoded(jsonNode.toString());
+    }
+
+    public static String asUrlEncoded(final String str) {
+        try {
+            return URLEncoder.encode(str, Charsets.UTF_8.name());
+        } catch (UnsupportedEncodingException e) {
+            // shouldn't happen
+            throw new RuntimeException(e);
+        }
+    }
+
 }

Added: incubator/isis/trunk/framework/viewer/json/json-applib/src/test/java/org/apache/isis/viewer/json/applib/JsonRepresentationTest_mapIterable.java
URL: http://svn.apache.org/viewvc/incubator/isis/trunk/framework/viewer/json/json-applib/src/test/java/org/apache/isis/viewer/json/applib/JsonRepresentationTest_mapIterable.java?rev=1183465&view=auto
==============================================================================
--- incubator/isis/trunk/framework/viewer/json/json-applib/src/test/java/org/apache/isis/viewer/json/applib/JsonRepresentationTest_mapIterable.java (added)
+++ incubator/isis/trunk/framework/viewer/json/json-applib/src/test/java/org/apache/isis/viewer/json/applib/JsonRepresentationTest_mapIterable.java Fri Oct 14 19:28:55 2011
@@ -0,0 +1,53 @@
+/*
+ *  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.json.applib;
+
+import static org.apache.isis.viewer.json.applib.JsonUtils.readJson;
+import static org.hamcrest.CoreMatchers.is;
+import static org.hamcrest.CoreMatchers.not;
+import static org.hamcrest.CoreMatchers.nullValue;
+import static org.junit.Assert.assertThat;
+
+import java.io.IOException;
+import java.util.Iterator;
+import java.util.Map.Entry;
+
+import org.codehaus.jackson.JsonParseException;
+import org.codehaus.jackson.map.JsonMappingException;
+import org.junit.Test;
+
+public class JsonRepresentationTest_mapIterable {
+
+    private JsonRepresentation jsonRepresentation;
+    
+    @Test
+    public void forJsonRepresentation() throws JsonParseException, JsonMappingException, IOException {
+        jsonRepresentation = new JsonRepresentation(readJson("map.json"));
+        final Iterable<Entry<String, JsonRepresentation>> mapIterable = jsonRepresentation.mapIterable();
+        final Iterator<Entry<String, JsonRepresentation>> mapIterator = mapIterable.iterator();
+        
+        for(int i=0; i<jsonRepresentation.asJsonNode().size(); i++) {
+            assertThat(mapIterator.hasNext(), is(true));
+            assertThat(mapIterator.next().getKey(), is(not(nullValue())));
+        }
+        assertThat(mapIterator.hasNext(), is(false));
+    }
+
+
+}

Copied: incubator/isis/trunk/framework/viewer/json/json-applib/src/test/java/org/apache/isis/viewer/json/applib/JsonRepresentationTest_urlEncoding.java (from r1182130, incubator/isis/trunk/framework/viewer/json/json-applib/src/test/java/org/apache/isis/viewer/json/applib/blocks/LinkTest_urlEncoding.java)
URL: http://svn.apache.org/viewvc/incubator/isis/trunk/framework/viewer/json/json-applib/src/test/java/org/apache/isis/viewer/json/applib/JsonRepresentationTest_urlEncoding.java?p2=incubator/isis/trunk/framework/viewer/json/json-applib/src/test/java/org/apache/isis/viewer/json/applib/JsonRepresentationTest_urlEncoding.java&p1=incubator/isis/trunk/framework/viewer/json/json-applib/src/test/java/org/apache/isis/viewer/json/applib/blocks/LinkTest_urlEncoding.java&r1=1182130&r2=1183465&rev=1183465&view=diff
==============================================================================
--- incubator/isis/trunk/framework/viewer/json/json-applib/src/test/java/org/apache/isis/viewer/json/applib/blocks/LinkTest_urlEncoding.java (original)
+++ incubator/isis/trunk/framework/viewer/json/json-applib/src/test/java/org/apache/isis/viewer/json/applib/JsonRepresentationTest_urlEncoding.java Fri Oct 14 19:28:55 2011
@@ -1,4 +1,4 @@
-package org.apache.isis.viewer.json.applib.blocks;
+package org.apache.isis.viewer.json.applib;
 
 import static org.hamcrest.CoreMatchers.is;
 import static org.junit.Assert.assertThat;
@@ -6,11 +6,13 @@ import static org.junit.Assert.assertTha
 import java.io.UnsupportedEncodingException;
 import java.net.URLDecoder;
 
+import org.apache.isis.viewer.json.applib.blocks.Link;
+import org.apache.isis.viewer.json.applib.blocks.Method;
 import org.junit.Test;
 
 import com.google.common.base.Charsets;
 
-public class LinkTest_urlEncoding {
+public class JsonRepresentationTest_urlEncoding {
 
     @Test
     public void test() throws UnsupportedEncodingException {

Modified: incubator/isis/trunk/framework/viewer/json/json-applib/src/test/java/org/apache/isis/viewer/json/applib/RestfulClientTest_follow.java
URL: http://svn.apache.org/viewvc/incubator/isis/trunk/framework/viewer/json/json-applib/src/test/java/org/apache/isis/viewer/json/applib/RestfulClientTest_follow.java?rev=1183465&r1=1183464&r2=1183465&view=diff
==============================================================================
--- incubator/isis/trunk/framework/viewer/json/json-applib/src/test/java/org/apache/isis/viewer/json/applib/RestfulClientTest_follow.java (original)
+++ incubator/isis/trunk/framework/viewer/json/json-applib/src/test/java/org/apache/isis/viewer/json/applib/RestfulClientTest_follow.java Fri Oct 14 19:28:55 2011
@@ -68,24 +68,17 @@ public class RestfulClientTest_follow {
         Link getLink = jsonRepresentation.getLink("aLink");
 
         // when
-        final Sequence sequence = context.sequence("execution");
         context.checking(new Expectations() {
             {
                 one(mockExecutor).createRequest("http://foo/bar");
-                inSequence(sequence);
                 will(returnValue(mockClientRequest));
                 
-                one(mockClientRequest).setHttpMethod(Method.GET.name());
-                inSequence(sequence);
-                one(mockClientRequest).accept(MediaType.APPLICATION_JSON_TYPE);
-                inSequence(sequence);
+                ignoring(mockClientRequest);
 
                 one(mockExecutor).execute(mockClientRequest);
-                inSequence(sequence);
                 will(returnValue(mockClientResponse));
                 
                 one(mockClientResponse).setReturnType(String.class);
-                inSequence(sequence);
             }
         });
         client.follow(getLink);

Added: incubator/isis/trunk/framework/viewer/json/json-applib/src/test/java/org/apache/isis/viewer/json/applib/blocks/MethodTest_setUp.java
URL: http://svn.apache.org/viewvc/incubator/isis/trunk/framework/viewer/json/json-applib/src/test/java/org/apache/isis/viewer/json/applib/blocks/MethodTest_setUp.java?rev=1183465&view=auto
==============================================================================
--- incubator/isis/trunk/framework/viewer/json/json-applib/src/test/java/org/apache/isis/viewer/json/applib/blocks/MethodTest_setUp.java (added)
+++ incubator/isis/trunk/framework/viewer/json/json-applib/src/test/java/org/apache/isis/viewer/json/applib/blocks/MethodTest_setUp.java Fri Oct 14 19:28:55 2011
@@ -0,0 +1,152 @@
+package org.apache.isis.viewer.json.applib.blocks;
+
+import java.io.UnsupportedEncodingException;
+import java.net.URLEncoder;
+
+import javax.ws.rs.core.MediaType;
+import javax.ws.rs.core.MultivaluedMap;
+
+import org.apache.http.client.utils.URLEncodedUtils;
+import org.apache.isis.viewer.json.applib.JsonRepresentation;
+import org.jboss.resteasy.client.ClientRequest;
+import org.jmock.Expectations;
+import org.jmock.Mockery;
+import org.jmock.integration.junit4.JMock;
+import org.jmock.integration.junit4.JUnit4Mockery;
+import org.jmock.lib.legacy.ClassImposteriser;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+@RunWith(JMock.class)
+public class MethodTest_setUp {
+
+    private Mockery context = new JUnit4Mockery() {{
+        setImposteriser(ClassImposteriser.INSTANCE);
+    }};
+    
+    private ClientRequest request;
+    private MultivaluedMap<String,String> requestQueryArgs;
+
+    private JsonRepresentation emptyRepr;
+
+    private JsonRepresentation nonEmptyRepr;
+
+    @SuppressWarnings("unchecked")
+    @Before
+    public void setUp() throws Exception {
+        emptyRepr = JsonRepresentation.newMap();
+
+        nonEmptyRepr = JsonRepresentation.newMap();
+        nonEmptyRepr.mapPut("aString", "bar"); 
+        nonEmptyRepr.mapPut("anInt", 3); 
+        nonEmptyRepr.mapPut("aLong", 31231231L); 
+        nonEmptyRepr.mapPut("aBoolean", true); 
+        nonEmptyRepr.mapPut("aStringRequiringEncoding", "http://localhost:8080/somewhere");
+
+        request = context.mock(ClientRequest.class);
+        requestQueryArgs = context.mock(MultivaluedMap.class);      
+
+        context.checking(new Expectations() {
+            {
+                allowing(request).getQueryParameters();
+                will(returnValue(requestQueryArgs));
+            }
+        });
+
+    }
+    
+    @Test
+    public void GET_empty() throws Exception {
+        emptyQueryArgs(Method.GET);
+    }
+
+    @Test
+    public void DELETE_empty() throws Exception {
+        emptyQueryArgs(Method.DELETE);
+    }
+
+    @Test
+    public void POST_empty() throws Exception {
+        emptyBody(Method.POST);
+    }
+
+    @Test
+    public void PUT_empty() throws Exception {
+        emptyBody(Method.PUT);
+    }
+
+
+    @Test
+    public void GET_nonEmpty() throws Exception {
+        nonEmptyQueryArgs(Method.GET);
+    }
+
+    @Test
+    public void DELETE_nonEmpty() throws Exception {
+        nonEmptyQueryArgs(Method.DELETE);
+    }
+
+    @Test
+    public void POST_nonEmpty() throws Exception {
+        nonEmptyBody(Method.POST);
+    }
+
+    @Test
+    public void PUT_nonEmpty() throws Exception {
+        nonEmptyBody(Method.PUT);
+    }
+
+
+    private void emptyQueryArgs(final Method method) {
+        context.checking(new Expectations() {
+            {
+                one(request).setHttpMethod(method.name());
+                never(requestQueryArgs);
+            }
+        });
+        
+        method.setUp(request, emptyRepr);
+    }
+
+    private void emptyBody(final Method method) {
+        context.checking(new Expectations() {
+            {
+                one(request).setHttpMethod(method.name());
+                one(request).body(MediaType.APPLICATION_JSON_TYPE, emptyRepr.toString());
+            }
+        });
+        
+        method.setUp(request, emptyRepr);
+    }
+
+
+    private void nonEmptyQueryArgs(final Method method) throws UnsupportedEncodingException {
+        context.checking(new Expectations() {
+            {
+                one(request).setHttpMethod(method.name());
+                one(requestQueryArgs).add("aString", "bar");
+                one(requestQueryArgs).add("anInt", "3");
+                one(requestQueryArgs).add("aLong", "31231231");
+                one(requestQueryArgs).add("aBoolean", "true");
+                one(requestQueryArgs).add("aStringRequiringEncoding", URLEncoder.encode("http://localhost:8080/somewhere", "UTF-8"));
+            }
+        });
+        
+        method.setUp(request, nonEmptyRepr);
+    }
+
+    private void nonEmptyBody(final Method method) throws UnsupportedEncodingException {
+        final String expected = nonEmptyRepr.toString();
+        context.checking(new Expectations() {
+            {
+                one(request).setHttpMethod(method.name());
+                one(request).body(MediaType.APPLICATION_JSON_TYPE, expected);
+            }
+        });
+        
+        method.setUp(request, nonEmptyRepr);
+    }
+
+
+}

Modified: incubator/isis/trunk/framework/viewer/json/json-tck/src/test/java/org/apache/isis/viewer/json/tck/resources/service/invoke/DomainServiceResourceTest_invokeAction.java
URL: http://svn.apache.org/viewvc/incubator/isis/trunk/framework/viewer/json/json-tck/src/test/java/org/apache/isis/viewer/json/tck/resources/service/invoke/DomainServiceResourceTest_invokeAction.java?rev=1183465&r1=1183464&r2=1183465&view=diff
==============================================================================
--- incubator/isis/trunk/framework/viewer/json/json-tck/src/test/java/org/apache/isis/viewer/json/tck/resources/service/invoke/DomainServiceResourceTest_invokeAction.java (original)
+++ incubator/isis/trunk/framework/viewer/json/json-tck/src/test/java/org/apache/isis/viewer/json/tck/resources/service/invoke/DomainServiceResourceTest_invokeAction.java Fri Oct 14 19:28:55 2011
@@ -1,12 +1,29 @@
 package org.apache.isis.viewer.json.tck.resources.service.invoke;
 
+import static org.apache.isis.viewer.json.tck.RepresentationMatchers.isArray;
+import static org.hamcrest.CoreMatchers.*;
+import static org.hamcrest.CoreMatchers.is;
+import static org.hamcrest.CoreMatchers.not;
+import static org.hamcrest.CoreMatchers.nullValue;
+import static org.junit.Assert.assertThat;
+
 import java.io.IOException;
 
+import javax.ws.rs.core.Response;
+
 import org.apache.isis.runtimes.dflt.webserver.WebServer;
+import org.apache.isis.viewer.json.applib.HttpMethod;
+import org.apache.isis.viewer.json.applib.JsonRepresentation;
 import org.apache.isis.viewer.json.applib.RestfulClient;
+import org.apache.isis.viewer.json.applib.RestfulRequest;
 import org.apache.isis.viewer.json.applib.RestfulResponse;
+import org.apache.isis.viewer.json.applib.RestfulRequest.QueryParameter;
+import org.apache.isis.viewer.json.applib.RestfulResponse.HttpStatusCode;
+import org.apache.isis.viewer.json.applib.blocks.Link;
 import org.apache.isis.viewer.json.applib.domainobjects.DomainObjectRepresentation;
 import org.apache.isis.viewer.json.applib.domainobjects.DomainServiceResource;
+import org.apache.isis.viewer.json.applib.domainobjects.ListRepresentation;
+import org.apache.isis.viewer.json.applib.domainobjects.ObjectActionRepresentation;
 import org.apache.isis.viewer.json.tck.IsisWebServerRule;
 import org.codehaus.jackson.JsonParseException;
 import org.codehaus.jackson.map.JsonMappingException;
@@ -33,21 +50,45 @@ public class DomainServiceResourceTest_i
     }
 
 
-    // adding this just to be able to locate a domain object directly.
-    @Ignore
     @Test
-    public void happyCase() throws Exception {
-        DomainObjectRepresentation simplesService = givenRepresentation("simples");
+    public void invokeNoArg() throws Exception {
+        
+        JsonRepresentation givenAction = givenAction("simples", "list");
+        final ObjectActionRepresentation actionRepr = givenAction.as(ObjectActionRepresentation.class);
         
+        final Link invokeLink = actionRepr.getInvoke();
+        assertThat(invokeLink, is(not(nullValue())));
         
+        final Response response = client.follow(invokeLink);
+        RestfulResponse<ListRepresentation> restfulResponse = RestfulResponse.ofT(response);
+        final ListRepresentation listRepr = restfulResponse.getEntity();
+        
+        assertThat(listRepr.getValues().arraySize(), is(5));
     }
 
 
-    private DomainObjectRepresentation givenRepresentation(String serviceId) throws JsonParseException, JsonMappingException, IOException {
-        RestfulResponse<DomainObjectRepresentation> jsonResp = RestfulResponse.ofT(resource.service(serviceId));
-        return jsonResp.getEntity();
+    private JsonRepresentation givenAction(final String serviceId, final String actionId) throws JsonParseException, JsonMappingException, IOException {
+        final String href = givenHrefToService(serviceId);
+        
+        final RestfulRequest request = 
+                client.createRequest(HttpMethod.GET, href).withArg(QueryParameter.FOLLOW_LINKS, "members[actionId=%s].actionDetails", actionId);
+        final RestfulResponse<DomainObjectRepresentation> restfulResponse = request.executeT();
+
+        assertThat(restfulResponse.getStatus(), is(HttpStatusCode.OK));
+        final DomainObjectRepresentation repr = restfulResponse.getEntity();
+        
+        JsonRepresentation actionLinkRepr = repr.xpath("/members/e[actionId='%s']", actionId);
+        return actionLinkRepr.getRepresentation("e.actionDetails.value");
     }
 
 
+    private String givenHrefToService(String serviceId) throws JsonParseException, JsonMappingException, IOException {
+        final DomainServiceResource resource = client.getDomainServiceResource();
+        final Response response = resource.services();
+        final ListRepresentation services = RestfulResponse.<ListRepresentation>ofT(response).getEntity();
+
+        return services.xpath("//*[key='%s']", serviceId).getLink("e").getHref();
+    }
+
 }
     
\ No newline at end of file

Modified: incubator/isis/trunk/framework/viewer/json/json-tck/src/test/java/org/apache/isis/viewer/json/tck/resources/service/serviceId/DomainServiceResourceTest_serviceId_xrofollowlinks.java
URL: http://svn.apache.org/viewvc/incubator/isis/trunk/framework/viewer/json/json-tck/src/test/java/org/apache/isis/viewer/json/tck/resources/service/serviceId/DomainServiceResourceTest_serviceId_xrofollowlinks.java?rev=1183465&r1=1183464&r2=1183465&view=diff
==============================================================================
--- incubator/isis/trunk/framework/viewer/json/json-tck/src/test/java/org/apache/isis/viewer/json/tck/resources/service/serviceId/DomainServiceResourceTest_serviceId_xrofollowlinks.java (original)
+++ incubator/isis/trunk/framework/viewer/json/json-tck/src/test/java/org/apache/isis/viewer/json/tck/resources/service/serviceId/DomainServiceResourceTest_serviceId_xrofollowlinks.java Fri Oct 14 19:28:55 2011
@@ -1,7 +1,8 @@
 package org.apache.isis.viewer.json.tck.resources.service.serviceId;
 
-import static org.hamcrest.CoreMatchers.is;
+import static org.hamcrest.CoreMatchers.*;
 import static org.junit.Assert.assertThat;
+import static org.apache.isis.viewer.json.tck.RepresentationMatchers.*;
 
 import java.io.IOException;
 
@@ -9,14 +10,15 @@ import javax.ws.rs.core.Response;
 
 import org.apache.isis.runtimes.dflt.webserver.WebServer;
 import org.apache.isis.viewer.json.applib.HttpMethod;
+import org.apache.isis.viewer.json.applib.JsonRepresentation;
 import org.apache.isis.viewer.json.applib.RestfulClient;
 import org.apache.isis.viewer.json.applib.RestfulRequest;
 import org.apache.isis.viewer.json.applib.RestfulRequest.QueryParameter;
 import org.apache.isis.viewer.json.applib.RestfulResponse;
 import org.apache.isis.viewer.json.applib.RestfulResponse.HttpStatusCode;
+import org.apache.isis.viewer.json.applib.domainobjects.DomainObjectRepresentation;
 import org.apache.isis.viewer.json.applib.domainobjects.DomainServiceResource;
 import org.apache.isis.viewer.json.applib.domainobjects.ListRepresentation;
-import org.apache.isis.viewer.json.applib.domainobjects.ObjectActionRepresentation;
 import org.apache.isis.viewer.json.tck.IsisWebServerRule;
 import org.codehaus.jackson.JsonParseException;
 import org.codehaus.jackson.map.JsonMappingException;
@@ -38,24 +40,38 @@ public class DomainServiceResourceTest_s
     }
 
     @Test
-    public void usingXpath() throws Exception {
+    public void withCriteria() throws Exception {
 
-        final String href = givenLinkToService();
+        final String href = givenHrefToService("simples");
         
         final RestfulRequest request = 
-                client.createRequest(HttpMethod.GET, href).withArg(QueryParameter.FOLLOW_LINKS, "members[actionId='%s'].actionDetails", "list");
-        final RestfulResponse<ObjectActionRepresentation> restfulResponse = request.executeT();
+                client.createRequest(HttpMethod.GET, href).withArg(QueryParameter.FOLLOW_LINKS, "members[actionId=%s].actionDetails", "list");
+        final RestfulResponse<DomainObjectRepresentation> restfulResponse = request.executeT();
 
         assertThat(restfulResponse.getStatus(), is(HttpStatusCode.OK));
+        final DomainObjectRepresentation repr = restfulResponse.getEntity();
+        
+        JsonRepresentation membersList = repr.getMembers();
+        assertThat(membersList, isArray());
+        
+        JsonRepresentation actionRepr;
+        
+        actionRepr = membersList.xpath("/e[actionId='%s']", "list");
+        assertThat(actionRepr.getRepresentation("e.actionDetails"), is(not(nullValue())));
+        assertThat(actionRepr.getRepresentation("e.actionDetails.value"), is(not(nullValue()))); // followed
+        
+        actionRepr = membersList.xpath("/e[actionId='%s']", "newTransientEntity");
+        assertThat(actionRepr.getRepresentation("e.actionDetails"), is(not(nullValue())));
+        assertThat(actionRepr.getRepresentation("e.actionDetails.value"), is(nullValue())); // not followed
     }
 
 
-    private String givenLinkToService() throws JsonParseException, JsonMappingException, IOException {
+    private String givenHrefToService(String serviceId) throws JsonParseException, JsonMappingException, IOException {
         final DomainServiceResource resource = client.getDomainServiceResource();
         final Response response = resource.services();
         final ListRepresentation services = RestfulResponse.<ListRepresentation>ofT(response).getEntity();
 
-        return services.xpath("//*[key='%s']", "simples").getLink("e").getHref();
+        return services.xpath("//*[key='%s']", serviceId).getLink("e").getHref();
     }
 
 

Modified: incubator/isis/trunk/framework/viewer/json/json-viewer/src/main/java/org/apache/isis/viewer/json/viewer/representations/LinkFollower.java
URL: http://svn.apache.org/viewvc/incubator/isis/trunk/framework/viewer/json/json-viewer/src/main/java/org/apache/isis/viewer/json/viewer/representations/LinkFollower.java?rev=1183465&r1=1183464&r2=1183465&view=diff
==============================================================================
--- incubator/isis/trunk/framework/viewer/json/json-viewer/src/main/java/org/apache/isis/viewer/json/viewer/representations/LinkFollower.java (original)
+++ incubator/isis/trunk/framework/viewer/json/json-viewer/src/main/java/org/apache/isis/viewer/json/viewer/representations/LinkFollower.java Fri Oct 14 19:28:55 2011
@@ -99,8 +99,9 @@ public final class LinkFollower {
             return false;
         }
         for(Map.Entry<String,String> criterium: root.getCriteria().entrySet()) {
-            final String mapValue = map.getString(criterium.getKey());
-            if(mapValue != null && !Objects.equal(mapValue, criterium.getValue())) {
+            final String requiredValue = criterium.getValue();
+            final String actualValue = map.getString(criterium.getKey());
+            if(!Objects.equal(requiredValue, actualValue)) {
                 return false;
             }
         }

Modified: incubator/isis/trunk/framework/viewer/json/json-viewer/src/main/java/org/apache/isis/viewer/json/viewer/resources/domainobjects/AbstractObjectMemberReprRenderer.java
URL: http://svn.apache.org/viewvc/incubator/isis/trunk/framework/viewer/json/json-viewer/src/main/java/org/apache/isis/viewer/json/viewer/resources/domainobjects/AbstractObjectMemberReprRenderer.java?rev=1183465&r1=1183464&r2=1183465&view=diff
==============================================================================
--- incubator/isis/trunk/framework/viewer/json/json-viewer/src/main/java/org/apache/isis/viewer/json/viewer/resources/domainobjects/AbstractObjectMemberReprRenderer.java (original)
+++ incubator/isis/trunk/framework/viewer/json/json-viewer/src/main/java/org/apache/isis/viewer/json/viewer/resources/domainobjects/AbstractObjectMemberReprRenderer.java Fri Oct 14 19:28:55 2011
@@ -47,6 +47,11 @@ public abstract class AbstractObjectMemb
         this.objectMember = objectAndMember.getMember();
         this.memberType = MemberType.determineFrom(objectMember);
         usingLinkToBuilder(new DomainObjectLinkTo());
+
+        // done eagerly so can use as criteria for x-ro-follow-links
+        putId();
+        putMemberType();
+
         return cast(this);
     }
 
@@ -94,11 +99,19 @@ public abstract class AbstractObjectMemb
     }
 
     public R withDetailsLink() {
-        representation.mapPut(memberType.getDetailsRel(), 
-                linkToBuilder.linkToMember(memberType.getDetailsRel(), memberType, objectMember).build());
+        final JsonRepresentation link = 
+                linkToBuilder.linkToMember(memberType.getDetailsRel(), memberType, objectMember).build();
+        representation.mapPut(memberType.getDetailsRel(), link);
+        final LinkFollower membersLinkFollower = getLinkFollower();
+        final LinkFollower detailsLinkFollower = membersLinkFollower.follow(memberType.getDetailsRel());
+        if(membersLinkFollower.matches(representation) && detailsLinkFollower.matches(link)) {
+            followDetailsLink(link);
+        }
         return cast(this);
     }
 
+    protected abstract void followDetailsLink(JsonRepresentation detailsLink);
+
     /**
      * For Resources to call.
      */

Modified: incubator/isis/trunk/framework/viewer/json/json-viewer/src/main/java/org/apache/isis/viewer/json/viewer/resources/domainobjects/DomainObjectReprRenderer.java
URL: http://svn.apache.org/viewvc/incubator/isis/trunk/framework/viewer/json/json-viewer/src/main/java/org/apache/isis/viewer/json/viewer/resources/domainobjects/DomainObjectReprRenderer.java?rev=1183465&r1=1183464&r2=1183465&view=diff
==============================================================================
--- incubator/isis/trunk/framework/viewer/json/json-viewer/src/main/java/org/apache/isis/viewer/json/viewer/resources/domainobjects/DomainObjectReprRenderer.java (original)
+++ incubator/isis/trunk/framework/viewer/json/json-viewer/src/main/java/org/apache/isis/viewer/json/viewer/resources/domainobjects/DomainObjectReprRenderer.java Fri Oct 14 19:28:55 2011
@@ -126,10 +126,10 @@ public class DomainObjectReprRenderer ex
     }
 
     private void addAssociations(ObjectAdapter objectAdapter, JsonRepresentation members, List<ObjectAssociation> associations) {
-        for (ObjectAssociation assoc : associations) {
-            final LinkFollower follow = getLinkFollower().follow("members");
+        final LinkFollower linkFollower = getLinkFollower().follow("members");
+        for (final ObjectAssociation assoc : associations) {
             
-            Consent visibility = assoc.isVisible(getSession(), objectAdapter);
+            final Consent visibility = assoc.isVisible(getSession(), objectAdapter);
             if(!visibility.isAllowed()) {
                 continue;
             } 
@@ -138,7 +138,7 @@ public class DomainObjectReprRenderer ex
                 
                 RendererFactory factory = RendererFactoryRegistry.instance.find(RepresentationType.OBJECT_PROPERTY);
                 final ObjectPropertyReprRenderer renderer = 
-                        (ObjectPropertyReprRenderer) factory.newRenderer(getResourceContext(), null, JsonRepresentation.newMap());
+                        (ObjectPropertyReprRenderer) factory.newRenderer(getResourceContext(), linkFollower, JsonRepresentation.newMap());
                 
                 renderer.with(new ObjectAndProperty(objectAdapter, property))
                         .usingLinkToBuilder(linkToBuilder)
@@ -151,7 +151,7 @@ public class DomainObjectReprRenderer ex
 
                 RendererFactory factory = RendererFactoryRegistry.instance.find(RepresentationType.OBJECT_COLLECTION);
                 final ObjectCollectionReprRenderer renderer = 
-                        (ObjectCollectionReprRenderer) factory.newRenderer(getResourceContext(), null, JsonRepresentation.newMap());
+                        (ObjectCollectionReprRenderer) factory.newRenderer(getResourceContext(), linkFollower, JsonRepresentation.newMap());
 
                 renderer.with(new ObjectAndCollection(objectAdapter, collection))
                     .usingLinkToBuilder(linkToBuilder)
@@ -164,8 +164,9 @@ public class DomainObjectReprRenderer ex
 
     private void addActions(final ObjectAdapter objectAdapter,
             List<ObjectAction> actions, JsonRepresentation members) {
-        for (ObjectAction action : actions) {
-            Consent visibility = action.isVisible(getSession(), objectAdapter);
+        final LinkFollower linkFollower = getLinkFollower().follow("members");
+        for (final ObjectAction action : actions) {
+            final Consent visibility = action.isVisible(getSession(), objectAdapter);
             if(!visibility.isAllowed()) {
                 continue;
             } 
@@ -178,7 +179,7 @@ public class DomainObjectReprRenderer ex
                 
                 RendererFactory factory = RendererFactoryRegistry.instance.find(RepresentationType.OBJECT_ACTION);
                 final ObjectActionReprRenderer renderer = 
-                        (ObjectActionReprRenderer) factory.newRenderer(getResourceContext(), null, JsonRepresentation.newMap());
+                        (ObjectActionReprRenderer) factory.newRenderer(getResourceContext(), linkFollower, JsonRepresentation.newMap());
                 
                 renderer.with(new ObjectAndAction(objectAdapter, action))
                         .usingLinkToBuilder(linkToBuilder)

Modified: incubator/isis/trunk/framework/viewer/json/json-viewer/src/main/java/org/apache/isis/viewer/json/viewer/resources/domainobjects/ObjectActionReprRenderer.java
URL: http://svn.apache.org/viewvc/incubator/isis/trunk/framework/viewer/json/json-viewer/src/main/java/org/apache/isis/viewer/json/viewer/resources/domainobjects/ObjectActionReprRenderer.java?rev=1183465&r1=1183464&r2=1183465&view=diff
==============================================================================
--- incubator/isis/trunk/framework/viewer/json/json-viewer/src/main/java/org/apache/isis/viewer/json/viewer/resources/domainobjects/ObjectActionReprRenderer.java (original)
+++ incubator/isis/trunk/framework/viewer/json/json-viewer/src/main/java/org/apache/isis/viewer/json/viewer/resources/domainobjects/ObjectActionReprRenderer.java Fri Oct 14 19:28:55 2011
@@ -27,6 +27,8 @@ import org.apache.isis.viewer.json.appli
 import org.apache.isis.viewer.json.applib.RepresentationType;
 import org.apache.isis.viewer.json.viewer.ResourceContext;
 import org.apache.isis.viewer.json.viewer.representations.LinkFollower;
+import org.apache.isis.viewer.json.viewer.representations.RendererFactory;
+import org.apache.isis.viewer.json.viewer.representations.RendererFactoryRegistry;
 import org.apache.isis.viewer.json.viewer.representations.ReprRenderer;
 import org.apache.isis.viewer.json.viewer.representations.ReprRendererFactoryAbstract;
 import org.apache.isis.viewer.json.viewer.resources.domaintypes.DomainTypeReprRenderer;
@@ -54,8 +56,7 @@ public class ObjectActionReprRenderer ex
     }
 
     public JsonRepresentation render() {
-        putId();
-        putMemberType();
+        // id and memberType are put eagerly
         
         putDisabledReasonIfDisabled();
         
@@ -71,7 +72,23 @@ public class ObjectActionReprRenderer ex
         return representation;
     }
 
-    
+
+    /////////////////////////////////////////////////////
+    // details link
+    /////////////////////////////////////////////////////
+
+    /**
+     * Mandatory hook method to support x-ro-follow-links
+     */
+    @Override
+    protected void followDetailsLink(JsonRepresentation detailsLink) {
+        RendererFactory factory = RendererFactoryRegistry.instance.find(RepresentationType.OBJECT_ACTION);
+        final ObjectActionReprRenderer renderer = 
+                (ObjectActionReprRenderer) factory.newRenderer(getResourceContext(), getLinkFollower(), JsonRepresentation.newMap());
+        renderer.with(new ObjectAndAction(objectAdapter, objectMember)).withMutatorsIfEnabled();
+        detailsLink.mapPut("value", renderer.render());
+    }
+
     /////////////////////////////////////////////////////
     // mutators
     /////////////////////////////////////////////////////
@@ -219,4 +236,5 @@ public class ObjectActionReprRenderer ex
     }
 
 
+
 }
\ No newline at end of file

Modified: incubator/isis/trunk/framework/viewer/json/json-viewer/src/main/java/org/apache/isis/viewer/json/viewer/resources/domainobjects/ObjectCollectionReprRenderer.java
URL: http://svn.apache.org/viewvc/incubator/isis/trunk/framework/viewer/json/json-viewer/src/main/java/org/apache/isis/viewer/json/viewer/resources/domainobjects/ObjectCollectionReprRenderer.java?rev=1183465&r1=1183464&r2=1183465&view=diff
==============================================================================
--- incubator/isis/trunk/framework/viewer/json/json-viewer/src/main/java/org/apache/isis/viewer/json/viewer/resources/domainobjects/ObjectCollectionReprRenderer.java (original)
+++ incubator/isis/trunk/framework/viewer/json/json-viewer/src/main/java/org/apache/isis/viewer/json/viewer/resources/domainobjects/ObjectCollectionReprRenderer.java Fri Oct 14 19:28:55 2011
@@ -28,6 +28,8 @@ import org.apache.isis.viewer.json.appli
 import org.apache.isis.viewer.json.viewer.ResourceContext;
 import org.apache.isis.viewer.json.viewer.representations.LinkFollower;
 import org.apache.isis.viewer.json.viewer.representations.LinkBuilder;
+import org.apache.isis.viewer.json.viewer.representations.RendererFactory;
+import org.apache.isis.viewer.json.viewer.representations.RendererFactoryRegistry;
 import org.apache.isis.viewer.json.viewer.representations.ReprRenderer;
 import org.apache.isis.viewer.json.viewer.representations.ReprRendererFactoryAbstract;
 import org.apache.isis.viewer.json.viewer.resources.domaintypes.DomainTypeReprRenderer;
@@ -54,8 +56,7 @@ public class ObjectCollectionReprRendere
     }
     
     public JsonRepresentation render() {
-        putId();
-        putMemberType();
+        // id and memberType are put eagerly
         
         putDisabledReasonIfDisabled();
         
@@ -72,7 +73,23 @@ public class ObjectCollectionReprRendere
     }
 
 
-    
+
+    /////////////////////////////////////////////////////
+    // details link
+    /////////////////////////////////////////////////////
+
+    /**
+     * Mandatory hook method to support x-ro-follow-links
+     */
+    @Override
+    protected void followDetailsLink(JsonRepresentation detailsLink) {
+        RendererFactory factory = RendererFactoryRegistry.instance.find(RepresentationType.OBJECT_COLLECTION);
+        final ObjectCollectionReprRenderer renderer = 
+                (ObjectCollectionReprRenderer) factory.newRenderer(getResourceContext(), getLinkFollower(), JsonRepresentation.newMap());
+        renderer.with(new ObjectAndCollection(objectAdapter, objectMember));
+        detailsLink.mapPut("value", renderer.render());
+    }
+
     /////////////////////////////////////////////////////
     // mutators
     /////////////////////////////////////////////////////
@@ -149,4 +166,5 @@ public class ObjectCollectionReprRendere
     }
 
 
+
 }
\ No newline at end of file

Modified: incubator/isis/trunk/framework/viewer/json/json-viewer/src/main/java/org/apache/isis/viewer/json/viewer/resources/domainobjects/ObjectPropertyReprRenderer.java
URL: http://svn.apache.org/viewvc/incubator/isis/trunk/framework/viewer/json/json-viewer/src/main/java/org/apache/isis/viewer/json/viewer/resources/domainobjects/ObjectPropertyReprRenderer.java?rev=1183465&r1=1183464&r2=1183465&view=diff
==============================================================================
--- incubator/isis/trunk/framework/viewer/json/json-viewer/src/main/java/org/apache/isis/viewer/json/viewer/resources/domainobjects/ObjectPropertyReprRenderer.java (original)
+++ incubator/isis/trunk/framework/viewer/json/json-viewer/src/main/java/org/apache/isis/viewer/json/viewer/resources/domainobjects/ObjectPropertyReprRenderer.java Fri Oct 14 19:28:55 2011
@@ -26,6 +26,8 @@ import org.apache.isis.viewer.json.appli
 import org.apache.isis.viewer.json.applib.RepresentationType;
 import org.apache.isis.viewer.json.viewer.ResourceContext;
 import org.apache.isis.viewer.json.viewer.representations.LinkFollower;
+import org.apache.isis.viewer.json.viewer.representations.RendererFactory;
+import org.apache.isis.viewer.json.viewer.representations.RendererFactoryRegistry;
 import org.apache.isis.viewer.json.viewer.representations.ReprRenderer;
 import org.apache.isis.viewer.json.viewer.representations.ReprRendererFactoryAbstract;
 import org.apache.isis.viewer.json.viewer.resources.domaintypes.DomainTypeReprRenderer;
@@ -53,9 +55,8 @@ public class ObjectPropertyReprRenderer 
     }
 
     public JsonRepresentation render() {
-
-        putId();
-        putMemberType();
+        // id and memberType are put eagerly
+        
         withValue();
 
         putDisabledReasonIfDisabled();
@@ -72,7 +73,23 @@ public class ObjectPropertyReprRenderer 
         return representation;
     }
 
-    
+
+    /////////////////////////////////////////////////////
+    // details link
+    /////////////////////////////////////////////////////
+
+    /**
+     * Mandatory hook method to support x-ro-follow-links
+     */
+    @Override
+    protected void followDetailsLink(JsonRepresentation detailsLink) {
+        RendererFactory factory = RendererFactoryRegistry.instance.find(RepresentationType.OBJECT_PROPERTY);
+        final ObjectPropertyReprRenderer renderer = 
+                (ObjectPropertyReprRenderer) factory.newRenderer(getResourceContext(), getLinkFollower(), JsonRepresentation.newMap());
+        renderer.with(new ObjectAndProperty(objectAdapter, objectMember));
+        detailsLink.mapPut("value", renderer.render());
+    }
+
     /////////////////////////////////////////////////////
     // mutators
     /////////////////////////////////////////////////////
@@ -164,4 +181,5 @@ public class ObjectPropertyReprRenderer 
         links.arrayAdd(DomainTypeReprRenderer.newLinkToBuilder(resourceContext, "domainType", objectAdapter.getSpecification()).build());
     }
 
+
 }
\ No newline at end of file

Modified: incubator/isis/trunk/framework/viewer/json/json-viewer/src/test/java/org/apache/isis/viewer/json/viewer/representations/LinkFollowerTest_follow.java
URL: http://svn.apache.org/viewvc/incubator/isis/trunk/framework/viewer/json/json-viewer/src/test/java/org/apache/isis/viewer/json/viewer/representations/LinkFollowerTest_follow.java?rev=1183465&r1=1183464&r2=1183465&view=diff
==============================================================================
--- incubator/isis/trunk/framework/viewer/json/json-viewer/src/test/java/org/apache/isis/viewer/json/viewer/representations/LinkFollowerTest_follow.java (original)
+++ incubator/isis/trunk/framework/viewer/json/json-viewer/src/test/java/org/apache/isis/viewer/json/viewer/representations/LinkFollowerTest_follow.java Fri Oct 14 19:28:55 2011
@@ -69,7 +69,8 @@ public class LinkFollowerTest_follow {
         final Map<String,String> criteria = followA.criteria();
         assertThat(criteria.size(), is(1));
         assertThat(criteria.get("x"), is("y"));
-        assertThat(followA.matches(JsonRepresentation.newMap()), is(true));
+        assertThat(followA.matches(JsonRepresentation.newMap("x", "y")), is(true));
+        assertThat(followA.matches(JsonRepresentation.newMap()), is(false));
         assertThat(followA.matches(JsonRepresentation.newMap("x", "z")), is(false));
     }
 
@@ -89,9 +90,11 @@ public class LinkFollowerTest_follow {
         
         assertThat(criteria.get("x"), is("y"));
         assertThat(criteria.get("z"), is("w"));
-        assertThat(followA.matches(JsonRepresentation.newMap("x", "y")), is(true));
-        assertThat(followA.matches(JsonRepresentation.newMap("x", "y", "foo", "bar")), is(true));
         assertThat(followA.matches(JsonRepresentation.newMap("x", "y", "z", "w")), is(true));
+        assertThat(followA.matches(JsonRepresentation.newMap("x", "y", "z", "w", "foo", "bar")), is(true));
+        assertThat(followA.matches(JsonRepresentation.newMap()), is(false));
+        assertThat(followA.matches(JsonRepresentation.newMap("x", "y")), is(false));
+        assertThat(followA.matches(JsonRepresentation.newMap("x", "y", "foo", "bar")), is(false));
         assertThat(followA.matches(JsonRepresentation.newMap("x", "bad")), is(false));
         assertThat(followA.matches(JsonRepresentation.newMap("x", "y", "z", "bad")), is(false));
     }