isis-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From danhayw...@apache.org
Subject svn commit: r1170062 [1/2] - in /incubator/isis/trunk/framework/viewer/json: json-tck/src/test/java/org/apache/isis/viewer/json/tck/ json-viewer/src/main/java/org/apache/isis/viewer/json/viewer/ json-viewer/src/main/java/org/apache/isis/viewer/json/vie...
Date Tue, 13 Sep 2011 06:59:12 GMT
Author: danhaywood
Date: Tue Sep 13 06:59:11 2011
New Revision: 1170062

URL: http://svn.apache.org/viewvc?rev=1170062&view=rev
Log:
ISIS-109: refactor of domain object/service rep builders

Added:
    incubator/isis/trunk/framework/viewer/json/json-viewer/src/main/java/org/apache/isis/viewer/json/viewer/HasHttpStatusCode.java
    incubator/isis/trunk/framework/viewer/json/json-viewer/src/main/java/org/apache/isis/viewer/json/viewer/representations/AbstractRepresentationBuilder.java
      - copied, changed from r1167069, incubator/isis/trunk/framework/viewer/json/json-viewer/src/main/java/org/apache/isis/viewer/json/viewer/representations/RepresentationBuilder.java
    incubator/isis/trunk/framework/viewer/json/json-viewer/src/main/java/org/apache/isis/viewer/json/viewer/representations/LinkToBuilder.java
      - copied, changed from r1167069, incubator/isis/trunk/framework/viewer/json/json-viewer/src/main/java/org/apache/isis/viewer/json/viewer/representations/LinkBuilder.java
    incubator/isis/trunk/framework/viewer/json/json-viewer/src/main/java/org/apache/isis/viewer/json/viewer/representations/RepBuilder.java
    incubator/isis/trunk/framework/viewer/json/json-viewer/src/main/java/org/apache/isis/viewer/json/viewer/resources/domain/
    incubator/isis/trunk/framework/viewer/json/json-viewer/src/main/java/org/apache/isis/viewer/json/viewer/resources/domain/objects/
    incubator/isis/trunk/framework/viewer/json/json-viewer/src/main/java/org/apache/isis/viewer/json/viewer/resources/domain/services/
    incubator/isis/trunk/framework/viewer/json/json-viewer/src/main/java/org/apache/isis/viewer/json/viewer/resources/domainobjects/AbstractObjectMemberRepBuilder.java
    incubator/isis/trunk/framework/viewer/json/json-viewer/src/main/java/org/apache/isis/viewer/json/viewer/resources/domainobjects/BodyArgs.java
    incubator/isis/trunk/framework/viewer/json/json-viewer/src/main/java/org/apache/isis/viewer/json/viewer/resources/domainobjects/DomainObjectLinkToBuilder.java
    incubator/isis/trunk/framework/viewer/json/json-viewer/src/main/java/org/apache/isis/viewer/json/viewer/resources/domainobjects/DomainObjectListRepBuilder.java
    incubator/isis/trunk/framework/viewer/json/json-viewer/src/main/java/org/apache/isis/viewer/json/viewer/resources/domainobjects/DomainObjectRepBuilder.java
    incubator/isis/trunk/framework/viewer/json/json-viewer/src/main/java/org/apache/isis/viewer/json/viewer/resources/domainobjects/DomainObjectResourceServerside.java
    incubator/isis/trunk/framework/viewer/json/json-viewer/src/main/java/org/apache/isis/viewer/json/viewer/resources/domainobjects/DomainServiceLinkToBuilder.java
    incubator/isis/trunk/framework/viewer/json/json-viewer/src/main/java/org/apache/isis/viewer/json/viewer/resources/domainobjects/DomainServiceResourceServerside.java
      - copied, changed from r1167411, incubator/isis/trunk/framework/viewer/json/json-viewer/src/main/java/org/apache/isis/viewer/json/viewer/resources/domainservices/DomainServiceResourceServerside.java
    incubator/isis/trunk/framework/viewer/json/json-viewer/src/main/java/org/apache/isis/viewer/json/viewer/resources/domainobjects/MemberSelfRepBuilder.java
    incubator/isis/trunk/framework/viewer/json/json-viewer/src/main/java/org/apache/isis/viewer/json/viewer/resources/domainobjects/MemberType.java
    incubator/isis/trunk/framework/viewer/json/json-viewer/src/main/java/org/apache/isis/viewer/json/viewer/resources/domainobjects/MutatorSpec.java
    incubator/isis/trunk/framework/viewer/json/json-viewer/src/main/java/org/apache/isis/viewer/json/viewer/resources/domainobjects/ObjectActionRepBuilder.java
    incubator/isis/trunk/framework/viewer/json/json-viewer/src/main/java/org/apache/isis/viewer/json/viewer/resources/domainobjects/ObjectAdapterLinkToBuilder.java
    incubator/isis/trunk/framework/viewer/json/json-viewer/src/main/java/org/apache/isis/viewer/json/viewer/resources/domainobjects/ObjectCollectionRepBuilder.java
    incubator/isis/trunk/framework/viewer/json/json-viewer/src/main/java/org/apache/isis/viewer/json/viewer/resources/domainobjects/ObjectPropertyRepBuilder.java
Modified:
    incubator/isis/trunk/framework/viewer/json/json-tck/src/test/java/org/apache/isis/viewer/json/tck/DomainObjectResourceTest.java
    incubator/isis/trunk/framework/viewer/json/json-tck/src/test/java/org/apache/isis/viewer/json/tck/DomainServiceResourceTest_service_serviceId.java
    incubator/isis/trunk/framework/viewer/json/json-viewer/src/main/java/org/apache/isis/viewer/json/viewer/JsonApplication.java
    incubator/isis/trunk/framework/viewer/json/json-viewer/src/main/java/org/apache/isis/viewer/json/viewer/JsonApplicationException.java
    incubator/isis/trunk/framework/viewer/json/json-viewer/src/main/java/org/apache/isis/viewer/json/viewer/JsonApplicationExceptionMapper.java
    incubator/isis/trunk/framework/viewer/json/json-viewer/src/main/java/org/apache/isis/viewer/json/viewer/representations/LinkBuilder.java
    incubator/isis/trunk/framework/viewer/json/json-viewer/src/main/java/org/apache/isis/viewer/json/viewer/representations/RepresentationBuilder.java
    incubator/isis/trunk/framework/viewer/json/json-viewer/src/main/java/org/apache/isis/viewer/json/viewer/resources/ResourceAbstract.java
    incubator/isis/trunk/framework/viewer/json/json-viewer/src/main/java/org/apache/isis/viewer/json/viewer/resources/capabilities/CapabilitiesResourceServerside.java
    incubator/isis/trunk/framework/viewer/json/json-viewer/src/main/java/org/apache/isis/viewer/json/viewer/resources/domainservices/DomainServiceListRepBuilder.java
    incubator/isis/trunk/framework/viewer/json/json-viewer/src/main/java/org/apache/isis/viewer/json/viewer/resources/domainservices/DomainServiceRepBuilder.java
    incubator/isis/trunk/framework/viewer/json/json-viewer/src/main/java/org/apache/isis/viewer/json/viewer/resources/domainservices/DomainServiceResourceServerside.java
    incubator/isis/trunk/framework/viewer/json/json-viewer/src/main/java/org/apache/isis/viewer/json/viewer/resources/domaintypes/AbstractTypeMemberRepBuilder.java
    incubator/isis/trunk/framework/viewer/json/json-viewer/src/main/java/org/apache/isis/viewer/json/viewer/resources/domaintypes/DomainTypeRepBuilder.java
    incubator/isis/trunk/framework/viewer/json/json-viewer/src/main/java/org/apache/isis/viewer/json/viewer/resources/domaintypes/DomainTypeResourceServerside.java
    incubator/isis/trunk/framework/viewer/json/json-viewer/src/main/java/org/apache/isis/viewer/json/viewer/resources/domaintypes/TypeActionRepBuilder.java
    incubator/isis/trunk/framework/viewer/json/json-viewer/src/main/java/org/apache/isis/viewer/json/viewer/resources/home/HomePageResourceServerside.java
    incubator/isis/trunk/framework/viewer/json/json-viewer/src/main/java/org/apache/isis/viewer/json/viewer/resources/user/UserRepBuilder.java

Modified: incubator/isis/trunk/framework/viewer/json/json-tck/src/test/java/org/apache/isis/viewer/json/tck/DomainObjectResourceTest.java
URL: http://svn.apache.org/viewvc/incubator/isis/trunk/framework/viewer/json/json-tck/src/test/java/org/apache/isis/viewer/json/tck/DomainObjectResourceTest.java?rev=1170062&r1=1170061&r2=1170062&view=diff
==============================================================================
--- incubator/isis/trunk/framework/viewer/json/json-tck/src/test/java/org/apache/isis/viewer/json/tck/DomainObjectResourceTest.java (original)
+++ incubator/isis/trunk/framework/viewer/json/json-tck/src/test/java/org/apache/isis/viewer/json/tck/DomainObjectResourceTest.java Tue Sep 13 06:59:11 2011
@@ -68,7 +68,7 @@ public class DomainObjectResourceTest {
         assertThat(domainObjectRepr.getTitle(), is("ApplibValues"));
         assertThat(domainObjectRepr.getOid(), is("OID:1"));
 
-        // _self.icon
+        // self.icon
         Link selfIcon = domainObjectRepr.getLink("_self.icon");
         // TODO: shouldn't really be present since no icon available; or should point to a default, perhaps
         assertThat(selfIcon, isLink().rel("icon").href(matches(".+" + "/images/" + "null\\.png")).method(Method.GET));

Modified: incubator/isis/trunk/framework/viewer/json/json-tck/src/test/java/org/apache/isis/viewer/json/tck/DomainServiceResourceTest_service_serviceId.java
URL: http://svn.apache.org/viewvc/incubator/isis/trunk/framework/viewer/json/json-tck/src/test/java/org/apache/isis/viewer/json/tck/DomainServiceResourceTest_service_serviceId.java?rev=1170062&r1=1170061&r2=1170062&view=diff
==============================================================================
--- incubator/isis/trunk/framework/viewer/json/json-tck/src/test/java/org/apache/isis/viewer/json/tck/DomainServiceResourceTest_service_serviceId.java (original)
+++ incubator/isis/trunk/framework/viewer/json/json-tck/src/test/java/org/apache/isis/viewer/json/tck/DomainServiceResourceTest_service_serviceId.java Tue Sep 13 06:59:11 2011
@@ -120,6 +120,7 @@ public class DomainServiceResourceTest_s
 
         ObjectActionRepresentation listActionDetailsRepr = listActionDetailsJsonResp.getEntity();
         
+        
     }
 
     @Ignore("TODO - need to add fixture data")

Added: incubator/isis/trunk/framework/viewer/json/json-viewer/src/main/java/org/apache/isis/viewer/json/viewer/HasHttpStatusCode.java
URL: http://svn.apache.org/viewvc/incubator/isis/trunk/framework/viewer/json/json-viewer/src/main/java/org/apache/isis/viewer/json/viewer/HasHttpStatusCode.java?rev=1170062&view=auto
==============================================================================
--- incubator/isis/trunk/framework/viewer/json/json-viewer/src/main/java/org/apache/isis/viewer/json/viewer/HasHttpStatusCode.java (added)
+++ incubator/isis/trunk/framework/viewer/json/json-viewer/src/main/java/org/apache/isis/viewer/json/viewer/HasHttpStatusCode.java Tue Sep 13 06:59:11 2011
@@ -0,0 +1,8 @@
+package org.apache.isis.viewer.json.viewer;
+
+import org.apache.isis.viewer.json.applib.RestfulResponse.HttpStatusCode;
+
+public interface HasHttpStatusCode {
+
+    HttpStatusCode getHttpStatusCode();
+}

Modified: incubator/isis/trunk/framework/viewer/json/json-viewer/src/main/java/org/apache/isis/viewer/json/viewer/JsonApplication.java
URL: http://svn.apache.org/viewvc/incubator/isis/trunk/framework/viewer/json/json-viewer/src/main/java/org/apache/isis/viewer/json/viewer/JsonApplication.java?rev=1170062&r1=1170061&r2=1170062&view=diff
==============================================================================
--- incubator/isis/trunk/framework/viewer/json/json-viewer/src/main/java/org/apache/isis/viewer/json/viewer/JsonApplication.java (original)
+++ incubator/isis/trunk/framework/viewer/json/json-viewer/src/main/java/org/apache/isis/viewer/json/viewer/JsonApplication.java Tue Sep 13 06:59:11 2011
@@ -20,7 +20,7 @@ package org.apache.isis.viewer.json.view
 
 import org.apache.isis.viewer.json.viewer.resources.capabilities.CapabilitiesResourceServerside;
 import org.apache.isis.viewer.json.viewer.resources.domainobjects.DomainObjectResourceServerside;
-import org.apache.isis.viewer.json.viewer.resources.domainservices.DomainServiceResourceServerside;
+import org.apache.isis.viewer.json.viewer.resources.domainobjects.DomainServiceResourceServerside;
 import org.apache.isis.viewer.json.viewer.resources.domaintypes.DomainTypeResourceServerside;
 import org.apache.isis.viewer.json.viewer.resources.home.HomePageResourceServerside;
 import org.apache.isis.viewer.json.viewer.resources.user.UserResourceServerside;

Modified: incubator/isis/trunk/framework/viewer/json/json-viewer/src/main/java/org/apache/isis/viewer/json/viewer/JsonApplicationException.java
URL: http://svn.apache.org/viewvc/incubator/isis/trunk/framework/viewer/json/json-viewer/src/main/java/org/apache/isis/viewer/json/viewer/JsonApplicationException.java?rev=1170062&r1=1170061&r2=1170062&view=diff
==============================================================================
--- incubator/isis/trunk/framework/viewer/json/json-viewer/src/main/java/org/apache/isis/viewer/json/viewer/JsonApplicationException.java (original)
+++ incubator/isis/trunk/framework/viewer/json/json-viewer/src/main/java/org/apache/isis/viewer/json/viewer/JsonApplicationException.java Tue Sep 13 06:59:11 2011
@@ -1,10 +1,8 @@
 package org.apache.isis.viewer.json.viewer;
 
-import javax.ws.rs.WebApplicationException;
-
 import org.apache.isis.viewer.json.applib.RestfulResponse.HttpStatusCode;
 
-public class JsonApplicationException extends RuntimeException {
+public class JsonApplicationException extends RuntimeException implements HasHttpStatusCode {
 
     public static final JsonApplicationException create(HttpStatusCode httpStatusCode) {
         return create(httpStatusCode, null);

Modified: incubator/isis/trunk/framework/viewer/json/json-viewer/src/main/java/org/apache/isis/viewer/json/viewer/JsonApplicationExceptionMapper.java
URL: http://svn.apache.org/viewvc/incubator/isis/trunk/framework/viewer/json/json-viewer/src/main/java/org/apache/isis/viewer/json/viewer/JsonApplicationExceptionMapper.java?rev=1170062&r1=1170061&r2=1170062&view=diff
==============================================================================
--- incubator/isis/trunk/framework/viewer/json/json-viewer/src/main/java/org/apache/isis/viewer/json/viewer/JsonApplicationExceptionMapper.java (original)
+++ incubator/isis/trunk/framework/viewer/json/json-viewer/src/main/java/org/apache/isis/viewer/json/viewer/JsonApplicationExceptionMapper.java Tue Sep 13 06:59:11 2011
@@ -41,11 +41,13 @@ public class JsonApplicationExceptionMap
             return stackTraceElement.toString();
         }
 
+        private final int httpStatusCode;
         private final String message;
         private final List<String> stackTrace = Lists.newArrayList();
         private ExceptionPojo causedBy;
 
         public ExceptionPojo(Throwable ex) {
+            httpStatusCode = getHttpStatusCodeIfAny(ex);
             this.message = ex.getMessage();
             StackTraceElement[] stackTraceElements = ex.getStackTrace();
             for (StackTraceElement stackTraceElement : stackTraceElements) {
@@ -56,15 +58,31 @@ public class JsonApplicationExceptionMap
                 this.causedBy = new ExceptionPojo(cause);
             }
         }
+
+        private int getHttpStatusCodeIfAny(Throwable ex) {
+            if(!(ex instanceof HasHttpStatusCode)) {
+                return 0;
+            } 
+            HasHttpStatusCode hasHttpStatusCode = (HasHttpStatusCode) ex;
+            return hasHttpStatusCode.getHttpStatusCode().getStatusCode();
+        }
+        
+        @SuppressWarnings("unused")
+        public int getHttpStatusCode() {
+            return httpStatusCode;
+        }
         
+        @SuppressWarnings("unused")
         public String getMessage() {
             return message;
         }
         
+        @SuppressWarnings("unused")
         public List<String> getStackTrace() {
             return stackTrace;
         }
         
+        @SuppressWarnings("unused")
         public ExceptionPojo getCausedBy() {
             return causedBy;
         }

Copied: incubator/isis/trunk/framework/viewer/json/json-viewer/src/main/java/org/apache/isis/viewer/json/viewer/representations/AbstractRepresentationBuilder.java (from r1167069, incubator/isis/trunk/framework/viewer/json/json-viewer/src/main/java/org/apache/isis/viewer/json/viewer/representations/RepresentationBuilder.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/AbstractRepresentationBuilder.java?p2=incubator/isis/trunk/framework/viewer/json/json-viewer/src/main/java/org/apache/isis/viewer/json/viewer/representations/AbstractRepresentationBuilder.java&p1=incubator/isis/trunk/framework/viewer/json/json-viewer/src/main/java/org/apache/isis/viewer/json/viewer/representations/RepresentationBuilder.java&r1=1167069&r2=1170062&rev=1170062&view=diff
==============================================================================
--- incubator/isis/trunk/framework/viewer/json/json-viewer/src/main/java/org/apache/isis/viewer/json/viewer/representations/RepresentationBuilder.java (original)
+++ incubator/isis/trunk/framework/viewer/json/json-viewer/src/main/java/org/apache/isis/viewer/json/viewer/representations/AbstractRepresentationBuilder.java Tue Sep 13 06:59:11 2011
@@ -25,22 +25,22 @@ import org.apache.isis.runtimes.dflt.run
 import org.apache.isis.viewer.json.applib.JsonRepresentation;
 import org.apache.isis.viewer.json.viewer.ResourceContext;
 
-public abstract class RepresentationBuilder<T extends RepresentationBuilder<T>> {
+public abstract class AbstractRepresentationBuilder<T extends AbstractRepresentationBuilder<T>> implements RepBuilder {
 
     protected final ResourceContext resourceContext;
     protected final JsonRepresentation representation = JsonRepresentation.newMap();
     
-    public RepresentationBuilder(ResourceContext resourceContext) {
+    public AbstractRepresentationBuilder(ResourceContext resourceContext) {
         this.resourceContext = resourceContext;
     }
 
 
     public T withSelf(String href) {
-        representation.mapPut("self", LinkBuilder.newBuilder(resourceContext, "self", href).build());
+        representation.mapPut("self", LinkToBuilder.newBuilder(resourceContext, "self", href).build());
         return cast(this);
     }
 
-    public RepresentationBuilder<T> withLinks() {
+    public AbstractRepresentationBuilder<T> withLinks() {
         return withLinks(JsonRepresentation.newArray());
     }
 
@@ -65,7 +65,7 @@ public abstract class RepresentationBuil
     }
 
     @SuppressWarnings("unchecked")
-    protected static <T extends RepresentationBuilder<T>> T cast(RepresentationBuilder<T> builder) {
+    protected static <T extends AbstractRepresentationBuilder<T>> T cast(AbstractRepresentationBuilder<T> builder) {
         return (T) builder;
     }
 

Copied: incubator/isis/trunk/framework/viewer/json/json-viewer/src/main/java/org/apache/isis/viewer/json/viewer/representations/LinkToBuilder.java (from r1167069, incubator/isis/trunk/framework/viewer/json/json-viewer/src/main/java/org/apache/isis/viewer/json/viewer/representations/LinkBuilder.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/LinkToBuilder.java?p2=incubator/isis/trunk/framework/viewer/json/json-viewer/src/main/java/org/apache/isis/viewer/json/viewer/representations/LinkToBuilder.java&p1=incubator/isis/trunk/framework/viewer/json/json-viewer/src/main/java/org/apache/isis/viewer/json/viewer/representations/LinkBuilder.java&r1=1167069&r2=1170062&rev=1170062&view=diff
==============================================================================
--- incubator/isis/trunk/framework/viewer/json/json-viewer/src/main/java/org/apache/isis/viewer/json/viewer/representations/LinkBuilder.java (original)
+++ incubator/isis/trunk/framework/viewer/json/json-viewer/src/main/java/org/apache/isis/viewer/json/viewer/representations/LinkToBuilder.java Tue Sep 13 06:59:11 2011
@@ -19,10 +19,10 @@ package org.apache.isis.viewer.json.view
 import org.apache.isis.viewer.json.applib.JsonRepresentation;
 import org.apache.isis.viewer.json.viewer.ResourceContext;
 
-public class LinkBuilder extends RepresentationBuilder<LinkBuilder> {
+public class LinkToBuilder extends AbstractRepresentationBuilder<LinkToBuilder> {
 
-    public static LinkBuilder newBuilder(ResourceContext resourceContext, String rel, String hrefFormat, Object... args) {
-        return new LinkBuilder(resourceContext, rel, String.format(hrefFormat, args));
+    public static LinkToBuilder newBuilder(ResourceContext resourceContext, String rel, String hrefFormat, Object... args) {
+        return new LinkToBuilder(resourceContext, rel, String.format(hrefFormat, args));
     }
 
 	private final String rel;
@@ -32,20 +32,20 @@ public class LinkBuilder extends Represe
     private String title;
     private JsonRepresentation arguments;
     
-    private LinkBuilder(ResourceContext resourceContext, String rel, String href) {
+    protected LinkToBuilder(ResourceContext resourceContext, String rel, String href) {
         super(resourceContext);
         this.rel = rel;
         this.href = href;
     }
-    public LinkBuilder withHttpMethod(HttpMethod method) {
+    public LinkToBuilder withHttpMethod(HttpMethod method) {
         this.method = method;
         return this;
     }
-    public LinkBuilder withTitle(String title) {
+    public LinkToBuilder withTitle(String title) {
         this.title = title;
         return this;
     }
-    public LinkBuilder withArguments(JsonRepresentation arguments) {
+    public LinkToBuilder withArguments(JsonRepresentation arguments) {
         this.arguments = arguments;
         return this;
     }

Added: incubator/isis/trunk/framework/viewer/json/json-viewer/src/main/java/org/apache/isis/viewer/json/viewer/representations/RepBuilder.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/RepBuilder.java?rev=1170062&view=auto
==============================================================================
--- incubator/isis/trunk/framework/viewer/json/json-viewer/src/main/java/org/apache/isis/viewer/json/viewer/representations/RepBuilder.java (added)
+++ incubator/isis/trunk/framework/viewer/json/json-viewer/src/main/java/org/apache/isis/viewer/json/viewer/representations/RepBuilder.java Tue Sep 13 06:59:11 2011
@@ -0,0 +1,25 @@
+/**
+ *  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.viewer.representations;
+
+import org.apache.isis.viewer.json.applib.JsonRepresentation;
+
+public interface RepBuilder {
+
+    public JsonRepresentation build();
+
+}
\ 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/ResourceAbstract.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/ResourceAbstract.java?rev=1170062&r1=1170061&r2=1170062&view=diff
==============================================================================
--- incubator/isis/trunk/framework/viewer/json/json-viewer/src/main/java/org/apache/isis/viewer/json/viewer/resources/ResourceAbstract.java (original)
+++ incubator/isis/trunk/framework/viewer/json/json-viewer/src/main/java/org/apache/isis/viewer/json/viewer/resources/ResourceAbstract.java Tue Sep 13 06:59:11 2011
@@ -52,7 +52,7 @@ import org.apache.isis.viewer.json.appli
 import org.apache.isis.viewer.json.applib.util.JsonMapper;
 import org.apache.isis.viewer.json.viewer.JsonApplicationException;
 import org.apache.isis.viewer.json.viewer.ResourceContext;
-import org.apache.isis.viewer.json.viewer.representations.RepresentationBuilder;
+import org.apache.isis.viewer.json.viewer.representations.AbstractRepresentationBuilder;
 import org.apache.isis.viewer.json.viewer.resources.domainobjects.DomainObjectRepBuilder;
 import org.apache.isis.viewer.json.viewer.util.OidUtils;
 import org.apache.isis.viewer.json.viewer.util.UrlDecoderUtils;
@@ -139,7 +139,7 @@ public abstract class ResourceAbstract {
     // Rendering
     // //////////////////////////////////////////////////////////////
 
-    protected String jsonFrom(RepresentationBuilder<?> builder) {
+    protected String jsonFrom(AbstractRepresentationBuilder<?> builder) {
         JsonRepresentation representation = builder.build();
         return jsonFor(representation);
     }
@@ -171,11 +171,9 @@ public abstract class ResourceAbstract {
 	private Function<ObjectAdapter, JsonRepresentation> toObjectSelfRepresentation() {
 		final ResourceContext representationContext = getResourceContext();
         
-        Function<ObjectAdapter, JsonRepresentation> objectSelfRepresentation = 
-            Functions.compose(
-                DomainObjectRepBuilder.selfOf(), 
-                DomainObjectRepBuilder.fromAdapter(representationContext));
-		return objectSelfRepresentation;
+        return Functions.compose(
+            DomainObjectRepBuilder.selfOf(), 
+            DomainObjectRepBuilder.fromAdapter(representationContext));
 	}
 
 

Modified: incubator/isis/trunk/framework/viewer/json/json-viewer/src/main/java/org/apache/isis/viewer/json/viewer/resources/capabilities/CapabilitiesResourceServerside.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/capabilities/CapabilitiesResourceServerside.java?rev=1170062&r1=1170061&r2=1170062&view=diff
==============================================================================
--- incubator/isis/trunk/framework/viewer/json/json-viewer/src/main/java/org/apache/isis/viewer/json/viewer/resources/capabilities/CapabilitiesResourceServerside.java (original)
+++ incubator/isis/trunk/framework/viewer/json/json-viewer/src/main/java/org/apache/isis/viewer/json/viewer/resources/capabilities/CapabilitiesResourceServerside.java Tue Sep 13 06:59:11 2011
@@ -26,7 +26,7 @@ import javax.ws.rs.core.Response;
 
 import org.apache.isis.viewer.json.applib.JsonRepresentation;
 import org.apache.isis.viewer.json.applib.capabilities.CapabilitiesResource;
-import org.apache.isis.viewer.json.viewer.representations.LinkBuilder;
+import org.apache.isis.viewer.json.viewer.representations.LinkToBuilder;
 import org.apache.isis.viewer.json.viewer.resources.ResourceAbstract;
 
 /**
@@ -43,7 +43,7 @@ public class CapabilitiesResourceServers
         init();
 
         JsonRepresentation representation = JsonRepresentation.newMap();
-        representation.mapPut("self", LinkBuilder.newBuilder(getResourceContext(), "self", "capabilities/").build());
+        representation.mapPut("self", LinkToBuilder.newBuilder(getResourceContext(), "self", "capabilities/").build());
         
         JsonRepresentation capabilities = JsonRepresentation.newMap();
         representation.mapPut("capabilities", capabilities);

Added: incubator/isis/trunk/framework/viewer/json/json-viewer/src/main/java/org/apache/isis/viewer/json/viewer/resources/domainobjects/AbstractObjectMemberRepBuilder.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/AbstractObjectMemberRepBuilder.java?rev=1170062&view=auto
==============================================================================
--- incubator/isis/trunk/framework/viewer/json/json-viewer/src/main/java/org/apache/isis/viewer/json/viewer/resources/domainobjects/AbstractObjectMemberRepBuilder.java (added)
+++ incubator/isis/trunk/framework/viewer/json/json-viewer/src/main/java/org/apache/isis/viewer/json/viewer/resources/domainobjects/AbstractObjectMemberRepBuilder.java Tue Sep 13 06:59:11 2011
@@ -0,0 +1,174 @@
+/**
+ *  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.viewer.resources.domainobjects;
+
+import java.util.Map;
+
+import org.apache.isis.core.metamodel.adapter.ObjectAdapter;
+import org.apache.isis.core.metamodel.adapter.oid.stringable.OidStringifier;
+import org.apache.isis.core.metamodel.consent.Consent;
+import org.apache.isis.core.metamodel.facetapi.Facet;
+import org.apache.isis.core.metamodel.spec.ObjectSpecification;
+import org.apache.isis.core.metamodel.spec.feature.ObjectMember;
+import org.apache.isis.viewer.json.applib.JsonRepresentation;
+import org.apache.isis.viewer.json.viewer.ResourceContext;
+import org.apache.isis.viewer.json.viewer.representations.LinkToBuilder;
+import org.apache.isis.viewer.json.viewer.representations.AbstractRepresentationBuilder;
+
+public abstract class AbstractObjectMemberRepBuilder<R extends AbstractRepresentationBuilder<R>, T extends ObjectMember> extends AbstractRepresentationBuilder<R> {
+
+    protected final ObjectAdapter objectAdapter;
+    protected final MemberType memberType;
+    protected final T objectMember;
+
+    public AbstractObjectMemberRepBuilder(ResourceContext resourceContext, ObjectAdapter objectAdapter, MemberType memberType, T objectMember) {
+        super(resourceContext);
+        this.objectAdapter = objectAdapter;
+        this.memberType = memberType;
+        this.objectMember = objectMember;
+    }
+
+    public R withSelf() {
+        String url = AbstractObjectMemberRepBuilder.urlForMember(objectAdapter, memberType, objectMember, getOidStringifier());
+        JsonRepresentation self = LinkToBuilder.newBuilder(resourceContext, "self", url).build();
+        representation.mapPut("self", self);
+        
+        return cast(this);
+    }
+
+    protected void putMemberType() {
+        representation.mapPut("memberType", memberType.getName());
+    }
+
+    protected void putId() {
+        representation.mapPut(memberType.getJsProp(), objectMember.getId());
+    }
+
+    public R withMutatorsIfEnabled() {
+        if(usability().isVetoed()) {
+            return cast(this);
+        }
+        Map<String, MutatorSpec> mutators = memberType.getMutators();
+        for(String mutator: mutators.keySet()) {
+            MutatorSpec mutatorSpec = mutators.get(mutator);
+            if(hasMemberFacet(mutatorSpec.mutatorFacetType)) {
+                String urlForMember = urlForMember(mutatorSpec.suffix);
+                JsonRepresentation arguments = mutatorArgs(mutatorSpec);
+                JsonRepresentation detailsLink = 
+                    LinkToBuilder.newBuilder(resourceContext, mutator, urlForMember)
+                        .withHttpMethod(mutatorSpec.httpMethod)
+                        .withArguments(arguments)
+                        .build();
+                representation.mapPut(mutator, detailsLink);
+            }
+        }
+        return cast(this);
+    }
+
+    private JsonRepresentation mutatorArgs(MutatorSpec mutatorSpec) {
+    	return appendMutatorArgs(mutatorSpec);
+    }
+
+    protected JsonRepresentation appendMutatorArgs(MutatorSpec mutatorSpec) {
+		if(mutatorSpec.arguments.isNone()) {
+    		return JsonRepresentation.newMap();
+    	}
+        if(mutatorSpec.arguments.isOne()) {
+            JsonRepresentation argValues = JsonRepresentation.newArray(1);
+            return argValues;
+        }
+        throw new UnsupportedOperationException("should be overridden if bodyArgs is not 0 or 1");
+	}
+
+    
+    protected R withValue() {
+        representation.mapPut("value", valueRep());
+        return cast(this);
+    }
+
+    /**
+     * Members that can provide a value should override.
+     */
+    protected Object valueRep() {
+        return null;
+    }
+
+    protected final void putDisabledReasonIfDisabled() {
+        String disabledReasonRep = usability().getReason();
+        representation.mapPut("disabledReason", disabledReasonRep);
+    }
+
+    public R withDetailsLink() {
+        String urlForMember = urlForMember();
+        JsonRepresentation detailsLink = LinkToBuilder.newBuilder(resourceContext, memberType.getDetailsRel(), urlForMember).build();
+        representation.mapPut(memberType.getDetailsRel(), detailsLink);
+        
+        return cast(this);
+    }
+
+    /**
+     * For Resources to call.
+     */
+    public boolean isMemberVisible() {
+        return visibility().isAllowed();
+    }
+
+
+    protected <F extends Facet> F getMemberSpecFacet(Class<F> facetType) {
+        ObjectSpecification otoaSpec = objectMember.getSpecification();
+        return otoaSpec.getFacet(facetType);
+    }
+
+    protected boolean hasMemberFacet(Class<? extends Facet> facetType) {
+        return objectMember.getFacet(facetType) != null;
+    }
+
+
+    protected String urlForMember(String... parts) {
+        return urlForMember(objectAdapter, memberType, objectMember, getOidStringifier(), parts);
+    }
+
+    protected Consent usability() {
+        return objectMember.isUsable(getSession(), objectAdapter);
+    }
+
+    protected Consent visibility() {
+        return objectMember.isVisible(getSession(), objectAdapter);
+    }
+
+    
+    /////////////////////////////////////////////////////////////////
+    // statics
+    /////////////////////////////////////////////////////////////////
+
+    public static String urlForMember(ObjectAdapter objectAdapter, MemberType memberType, ObjectMember objectMember,
+        OidStringifier oidStringifier, String... parts) {
+        String oidStr = oidStringifier.enString(objectAdapter.getOid());
+        StringBuilder buf = new StringBuilder();
+        buf.append("objects/").append(oidStr);
+        buf.append("/").append(memberType.urlPart()).append(objectMember.getId());
+        for(String part: parts) {
+            if(part == null) {
+                continue;
+            }
+            buf.append("/").append(part);
+        }
+        return buf.toString();
+    }
+
+    
+}
\ No newline at end of file

Added: incubator/isis/trunk/framework/viewer/json/json-viewer/src/main/java/org/apache/isis/viewer/json/viewer/resources/domainobjects/BodyArgs.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/BodyArgs.java?rev=1170062&view=auto
==============================================================================
--- incubator/isis/trunk/framework/viewer/json/json-viewer/src/main/java/org/apache/isis/viewer/json/viewer/resources/domainobjects/BodyArgs.java (added)
+++ incubator/isis/trunk/framework/viewer/json/json-viewer/src/main/java/org/apache/isis/viewer/json/viewer/resources/domainobjects/BodyArgs.java Tue Sep 13 06:59:11 2011
@@ -0,0 +1,41 @@
+/**
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+package org.apache.isis.viewer.json.viewer.resources.domainobjects;
+
+public enum BodyArgs {
+    /**
+     * eg property clear
+     */
+    NONE,
+    /**
+     * eg property modify, collection addto/remove
+     */
+    ONE,
+    /**
+     * eg action invoke
+     */
+    MANY;
+
+    public boolean isOne() {
+        return this == ONE;
+    }
+
+	public boolean isNone() {
+		return this == NONE;
+	}
+
+}

Added: incubator/isis/trunk/framework/viewer/json/json-viewer/src/main/java/org/apache/isis/viewer/json/viewer/resources/domainobjects/DomainObjectLinkToBuilder.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/DomainObjectLinkToBuilder.java?rev=1170062&view=auto
==============================================================================
--- incubator/isis/trunk/framework/viewer/json/json-viewer/src/main/java/org/apache/isis/viewer/json/viewer/resources/domainobjects/DomainObjectLinkToBuilder.java (added)
+++ incubator/isis/trunk/framework/viewer/json/json-viewer/src/main/java/org/apache/isis/viewer/json/viewer/resources/domainobjects/DomainObjectLinkToBuilder.java Tue Sep 13 06:59:11 2011
@@ -0,0 +1,66 @@
+/**
+ *  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.viewer.resources.domainobjects;
+
+import org.apache.isis.core.metamodel.adapter.ObjectAdapter;
+import org.apache.isis.core.metamodel.adapter.oid.stringable.OidStringifier;
+import org.apache.isis.runtimes.dflt.runtime.system.context.IsisContext;
+import org.apache.isis.runtimes.dflt.runtime.system.persistence.OidGenerator;
+import org.apache.isis.runtimes.dflt.runtime.system.persistence.PersistenceSession;
+import org.apache.isis.viewer.json.applib.JsonRepresentation;
+import org.apache.isis.viewer.json.viewer.ResourceContext;
+import org.apache.isis.viewer.json.viewer.representations.LinkToBuilder;
+
+public class DomainObjectLinkToBuilder implements ObjectAdapterLinkToBuilder {
+
+    private ObjectAdapter objectAdapter;
+    private ResourceContext resourceContext;
+
+    @Override
+    public ObjectAdapterLinkToBuilder with(ObjectAdapter objectAdapter) {
+        this.objectAdapter = objectAdapter;
+        return this;
+    }
+
+    @Override
+    public DomainObjectLinkToBuilder usingResourceContext(ResourceContext resourceContext) {
+        this.resourceContext = resourceContext;
+        return this;
+    }
+
+    @Override
+    public JsonRepresentation build() {
+        String oidStr = getOidStringifier().enString(objectAdapter.getOid());
+        String url = "objects/" + oidStr;
+        LinkToBuilder newLinkToBuilder = LinkToBuilder.newBuilder(resourceContext, "object", url);
+        return newLinkToBuilder.build();
+    }
+    
+    protected OidStringifier getOidStringifier() {
+        return getOidGenerator().getOidStringifier();
+    }
+
+    protected OidGenerator getOidGenerator() {
+        return getPersistenceSession().getOidGenerator();
+    }
+
+    protected PersistenceSession getPersistenceSession() {
+        return IsisContext.getPersistenceSession();
+    }
+
+
+}
\ No newline at end of file

Added: incubator/isis/trunk/framework/viewer/json/json-viewer/src/main/java/org/apache/isis/viewer/json/viewer/resources/domainobjects/DomainObjectListRepBuilder.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/DomainObjectListRepBuilder.java?rev=1170062&view=auto
==============================================================================
--- incubator/isis/trunk/framework/viewer/json/json-viewer/src/main/java/org/apache/isis/viewer/json/viewer/resources/domainobjects/DomainObjectListRepBuilder.java (added)
+++ incubator/isis/trunk/framework/viewer/json/json-viewer/src/main/java/org/apache/isis/viewer/json/viewer/resources/domainobjects/DomainObjectListRepBuilder.java Tue Sep 13 06:59:11 2011
@@ -0,0 +1,63 @@
+/**
+ *  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.viewer.resources.domainobjects;
+
+import java.util.List;
+
+import org.apache.isis.core.metamodel.adapter.ObjectAdapter;
+import org.apache.isis.viewer.json.applib.JsonRepresentation;
+import org.apache.isis.viewer.json.viewer.ResourceContext;
+import org.apache.isis.viewer.json.viewer.representations.AbstractRepresentationBuilder;
+
+public class DomainObjectListRepBuilder extends AbstractRepresentationBuilder<DomainObjectListRepBuilder> {
+
+    private ObjectAdapterLinkToBuilder objectAdapterLinkToBuilder;
+    
+    public static DomainObjectListRepBuilder newBuilder(ResourceContext resourceContext) {
+        return new DomainObjectListRepBuilder(resourceContext);
+    }
+
+    private DomainObjectListRepBuilder(ResourceContext resourceContext) {
+        super(resourceContext);
+        usingLinkToBuilder(new DomainObjectLinkToBuilder());
+    }
+    
+    public DomainObjectListRepBuilder usingLinkToBuilder(ObjectAdapterLinkToBuilder objectAdapterLinkToBuilder) {
+        this.objectAdapterLinkToBuilder = objectAdapterLinkToBuilder.usingResourceContext(resourceContext);
+        return this;
+    }
+
+    public DomainObjectListRepBuilder withAdapters(List<ObjectAdapter> objectAdapters) {
+        JsonRepresentation list = JsonRepresentation.newArray();
+        for(ObjectAdapter adapter: objectAdapters) {
+            JsonRepresentation linkToObject = objectAdapterLinkToBuilder.with(adapter).build();
+            list.arrayAdd(linkToObject);
+        }
+        representation.mapPut("values", list);
+        return this;
+    }
+
+
+    public JsonRepresentation build() {
+        withLinks();
+        withExtensions();
+
+        return representation;
+    }
+
+
+}
\ No newline at end of file

Added: incubator/isis/trunk/framework/viewer/json/json-viewer/src/main/java/org/apache/isis/viewer/json/viewer/resources/domainobjects/DomainObjectRepBuilder.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/DomainObjectRepBuilder.java?rev=1170062&view=auto
==============================================================================
--- incubator/isis/trunk/framework/viewer/json/json-viewer/src/main/java/org/apache/isis/viewer/json/viewer/resources/domainobjects/DomainObjectRepBuilder.java (added)
+++ incubator/isis/trunk/framework/viewer/json/json-viewer/src/main/java/org/apache/isis/viewer/json/viewer/resources/domainobjects/DomainObjectRepBuilder.java Tue Sep 13 06:59:11 2011
@@ -0,0 +1,187 @@
+/**
+ *  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.viewer.resources.domainobjects;
+
+import java.util.List;
+
+import org.apache.isis.applib.profiles.Localization;
+import org.apache.isis.core.metamodel.adapter.ObjectAdapter;
+import org.apache.isis.core.metamodel.adapter.oid.stringable.OidStringifier;
+import org.apache.isis.core.metamodel.consent.Consent;
+import org.apache.isis.core.metamodel.facets.object.encodeable.EncodableFacet;
+import org.apache.isis.core.metamodel.facets.object.title.TitleFacet;
+import org.apache.isis.core.metamodel.facets.object.value.ValueFacet;
+import org.apache.isis.core.metamodel.spec.ObjectActionSet;
+import org.apache.isis.core.metamodel.spec.ObjectSpecification;
+import org.apache.isis.core.metamodel.spec.feature.ObjectAction;
+import org.apache.isis.core.metamodel.spec.feature.ObjectActionContainer.Contributed;
+import org.apache.isis.core.metamodel.spec.feature.ObjectAssociation;
+import org.apache.isis.core.metamodel.spec.feature.OneToManyAssociation;
+import org.apache.isis.core.metamodel.spec.feature.OneToOneAssociation;
+import org.apache.isis.viewer.json.applib.JsonRepresentation;
+import org.apache.isis.viewer.json.viewer.ResourceContext;
+import org.apache.isis.viewer.json.viewer.representations.LinkToBuilder;
+import org.apache.isis.viewer.json.viewer.representations.AbstractRepresentationBuilder;
+import org.apache.isis.viewer.json.viewer.util.OidUtils;
+
+import com.google.common.base.Function;
+
+public class DomainObjectRepBuilder extends AbstractRepresentationBuilder<DomainObjectRepBuilder> {
+
+    public static DomainObjectRepBuilder newBuilder(ResourceContext representationContext) {
+        return new DomainObjectRepBuilder(representationContext);
+    }
+
+    public static LinkToBuilder newLinkToBuilder(ResourceContext resourceContext, String rel, ObjectAdapter elementAdapter, OidStringifier oidStringifier) {
+        String oidStr = oidStringifier.enString(elementAdapter.getOid());
+        String url = "objects/" + oidStr;
+        return LinkToBuilder.newBuilder(resourceContext, rel, url);
+    }
+
+    private ObjectAdapterLinkToBuilder linkToBuilder;
+
+    public DomainObjectRepBuilder(ResourceContext resourceContext) {
+        super(resourceContext);
+        usingLinkToBuilder(new DomainObjectLinkToBuilder());
+    }
+
+    /**
+     * Override the default {@link ObjectAdapterLinkToBuilder} (that is used for generating links in
+     * {@link #linkTo(ObjectAdapter)}).
+     */
+    public DomainObjectRepBuilder usingLinkToBuilder(ObjectAdapterLinkToBuilder objectAdapterLinkToBuilder) {
+        this.linkToBuilder = objectAdapterLinkToBuilder.usingResourceContext(resourceContext);
+        return this;
+    }
+
+    public DomainObjectRepBuilder withAdapter(ObjectAdapter objectAdapter) {
+        JsonRepresentation self = linkToBuilder.with(objectAdapter).build();
+        representation.mapPut("self", self);
+
+        String title = objectAdapter.titleString();
+        representation.mapPut("oid", OidUtils.getOidStr(objectAdapter, getOidStringifier()));
+        representation.mapPut("title", title);
+        withMembers(objectAdapter);
+        return this;
+    }
+
+    private DomainObjectRepBuilder withMembers(ObjectAdapter objectAdapter) {
+        JsonRepresentation members = JsonRepresentation.newArray();
+        List<ObjectAssociation> associations = objectAdapter.getSpecification().getAssociations();
+        addAssociations(objectAdapter, members, associations);
+        
+        List<ObjectAction> actions = objectAdapter.getSpecification().getObjectActions(Contributed.INCLUDED);
+        addActions(objectAdapter, actions, members);
+        representation.mapPut("members", members);
+        return this;
+    }
+
+    private void addAssociations(ObjectAdapter objectAdapter, JsonRepresentation members, List<ObjectAssociation> associations) {
+        for (ObjectAssociation assoc : associations) {
+            Consent visibility = assoc.isVisible(getSession(), objectAdapter);
+            if(!visibility.isAllowed()) {
+                continue;
+            } 
+            if(assoc instanceof OneToOneAssociation) {
+                OneToOneAssociation property = (OneToOneAssociation)assoc;
+                JsonRepresentation propertyRep = 
+                        ObjectPropertyRepBuilder.newBuilder(resourceContext, objectAdapter, property)
+                        .withDetailsLink()
+                        .build();
+                members.arrayAdd(propertyRep);
+            }
+            if(assoc instanceof OneToManyAssociation) {
+                OneToManyAssociation collection = (OneToManyAssociation) assoc;
+                JsonRepresentation collectionRep = 
+                        ObjectCollectionRepBuilder.newBuilder(resourceContext, objectAdapter, collection)
+                        .withDetailsLink()
+                        .build();
+                members.arrayAdd(collectionRep);
+            }
+        }
+    }
+
+    private void addActions(final ObjectAdapter objectAdapter,
+			List<ObjectAction> actions, JsonRepresentation members) {
+		for (ObjectAction action : actions) {
+            Consent visibility = action.isVisible(getSession(), objectAdapter);
+            if(!visibility.isAllowed()) {
+                continue;
+            } 
+        	if(action.getType().isSet()) {
+        		ObjectActionSet objectActionSet = (ObjectActionSet) action;
+        		List<ObjectAction> subactions = objectActionSet.getActions();
+        		addActions(objectAdapter, subactions, members);
+        	} else {
+                JsonRepresentation actionRep = 
+                        ObjectActionRepBuilder.newBuilder(resourceContext, objectAdapter, action)
+                        .withDetailsLink()
+                        .build();
+                members.arrayAdd(actionRep);
+        	}
+        }
+	}
+
+    public JsonRepresentation build() {
+        withLinks();
+        withExtensions();
+        return representation;
+    }
+
+    
+    /////////////////////////////////////////////////////////////////////
+    //
+    /////////////////////////////////////////////////////////////////////
+
+    public static Function<ObjectAdapter, JsonRepresentation> fromAdapter(final ResourceContext resourceContext) {
+        return new Function<ObjectAdapter, JsonRepresentation>() {
+            @Override
+            public JsonRepresentation apply(ObjectAdapter adapter) {
+                return newBuilder(resourceContext).withAdapter(adapter).build();
+            }
+        };
+    }
+
+    public static Function<JsonRepresentation, JsonRepresentation> selfOf() {
+        return new Function<JsonRepresentation, JsonRepresentation>() {
+            @Override
+            public JsonRepresentation apply(JsonRepresentation input) {
+                return input.getRepresentation("self");
+            }
+        };
+    }
+
+
+    /////////////////////////////////////////////////////////////////////
+    //
+    /////////////////////////////////////////////////////////////////////
+
+    public static Object valueOrRef(ResourceContext resourceContext,
+			final ObjectAdapter objectAdapter, ObjectSpecification objectSpec, OidStringifier oidStringifier, Localization localization) {
+		ValueFacet valueFacet = objectSpec.getFacet(ValueFacet.class);
+		if(valueFacet != null) {
+			EncodableFacet encodeableFacet = objectSpec.getFacet(EncodableFacet.class);
+			return encodeableFacet.toEncodedString(objectAdapter);
+		}
+		TitleFacet titleFacet = objectSpec.getFacet(TitleFacet.class);
+		String title = titleFacet.title(objectAdapter, localization);
+		return DomainObjectRepBuilder.newLinkToBuilder(resourceContext, "object", objectAdapter, oidStringifier).withTitle(title).build();
+	}
+
+
+
+}
\ No newline at end of file

Added: incubator/isis/trunk/framework/viewer/json/json-viewer/src/main/java/org/apache/isis/viewer/json/viewer/resources/domainobjects/DomainObjectResourceServerside.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/DomainObjectResourceServerside.java?rev=1170062&view=auto
==============================================================================
--- incubator/isis/trunk/framework/viewer/json/json-viewer/src/main/java/org/apache/isis/viewer/json/viewer/resources/domainobjects/DomainObjectResourceServerside.java (added)
+++ incubator/isis/trunk/framework/viewer/json/json-viewer/src/main/java/org/apache/isis/viewer/json/viewer/resources/domainobjects/DomainObjectResourceServerside.java Tue Sep 13 06:59:11 2011
@@ -0,0 +1,626 @@
+/**
+ *  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.viewer.resources.domainobjects;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.Collection;
+import java.util.List;
+import java.util.Map;
+
+import javax.ws.rs.Consumes;
+import javax.ws.rs.DELETE;
+import javax.ws.rs.GET;
+import javax.ws.rs.POST;
+import javax.ws.rs.PUT;
+import javax.ws.rs.Path;
+import javax.ws.rs.PathParam;
+import javax.ws.rs.Produces;
+import javax.ws.rs.QueryParam;
+import javax.ws.rs.WebApplicationException;
+import javax.ws.rs.core.MediaType;
+import javax.ws.rs.core.Response;
+
+import org.apache.isis.core.metamodel.adapter.ObjectAdapter;
+import org.apache.isis.core.metamodel.consent.Consent;
+import org.apache.isis.core.metamodel.facets.collections.modify.CollectionFacet;
+import org.apache.isis.core.metamodel.facets.object.encodeable.EncodableFacet;
+import org.apache.isis.core.metamodel.facets.object.value.ValueFacet;
+import org.apache.isis.core.metamodel.spec.ObjectSpecification;
+import org.apache.isis.core.metamodel.spec.feature.ObjectAction;
+import org.apache.isis.core.metamodel.spec.feature.ObjectActionParameter;
+import org.apache.isis.core.metamodel.spec.feature.ObjectAssociation;
+import org.apache.isis.core.metamodel.spec.feature.ObjectMember;
+import org.apache.isis.core.metamodel.spec.feature.OneToManyAssociation;
+import org.apache.isis.core.metamodel.spec.feature.OneToOneAssociation;
+import org.apache.isis.viewer.json.applib.RestfulResponse.HttpStatusCode;
+import org.apache.isis.viewer.json.applib.domainobjects.DomainObjectResource;
+import org.apache.isis.viewer.json.applib.util.JsonMapper;
+import org.apache.isis.viewer.json.viewer.JsonApplicationException;
+import org.apache.isis.viewer.json.viewer.representations.AbstractRepresentationBuilder;
+import org.apache.isis.viewer.json.viewer.resources.ResourceAbstract;
+import org.apache.isis.viewer.json.viewer.util.UrlDecoderUtils;
+import org.codehaus.jackson.JsonParseException;
+import org.codehaus.jackson.map.JsonMappingException;
+
+import com.google.common.base.Charsets;
+import com.google.common.collect.Lists;
+import com.google.common.io.ByteStreams;
+
+@Path("/objects")
+public class DomainObjectResourceServerside extends ResourceAbstract implements
+        DomainObjectResource {
+    
+    ////////////////////////////////////////////////////////////
+    // domain object
+    ////////////////////////////////////////////////////////////
+    
+    @GET
+    @Path("/{oid}")
+    @Produces({ MediaType.APPLICATION_JSON })
+    public Response object(@PathParam("oid") final String oidStr) {
+
+        final ObjectAdapter objectAdapter = getObjectAdapter(oidStr);
+        final AbstractRepresentationBuilder<?> builder = 
+                DomainObjectRepBuilder.newBuilder(getResourceContext())
+                .withAdapter(objectAdapter);
+        return responseOfOk(jsonFrom(builder));
+    }
+
+    @PUT
+    @Path("/{oid}")
+    @Consumes({ MediaType.APPLICATION_JSON })
+    @Produces({ MediaType.APPLICATION_JSON })
+    public Response object(
+        @PathParam("oid") final String oidStr, 
+        final InputStream arguments) {
+        
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    ////////////////////////////////////////////////////////////
+    // domain object property
+    ////////////////////////////////////////////////////////////
+
+    @GET
+    @Path("/{oid}/properties/{propertyId}")
+    @Produces({ MediaType.APPLICATION_JSON })
+    public Response propertyDetails(
+        @PathParam("oid") final String oidStr,
+        @PathParam("propertyId") final String propertyId) {
+
+        final ObjectAdapter objectAdapter = getObjectAdapter(oidStr);
+        final OneToOneAssociation property = getPropertyThatIsVisibleAndUsable(
+                objectAdapter, propertyId, Intent.ACCESS);
+
+        final ObjectPropertyRepBuilder builder = ObjectPropertyRepBuilder.newBuilder(
+                getResourceContext(), objectAdapter, property);
+        return responseOfOk(jsonFrom(builder));
+    }
+
+    @PUT
+    @Path("/{oid}/properties/{propertyId}")
+    @Produces({ MediaType.APPLICATION_JSON })
+    public Response modifyProperty(@PathParam("oid") final String oidStr,
+        @PathParam("propertyId") final String propertyId,
+        final InputStream body) {
+
+        final ObjectAdapter objectAdapter = getObjectAdapter(oidStr);
+        final OneToOneAssociation property = getPropertyThatIsVisibleAndUsable(
+                objectAdapter, propertyId, Intent.MUTATE);
+
+        ObjectSpecification propertySpec = property.getSpecification();
+
+        ObjectAdapter argAdapter = parseBody(propertySpec, body);
+
+        Consent consent = property.isAssociationValid(objectAdapter, argAdapter);
+        if (consent.isVetoed()) {
+            return responseOfUnauthorized(consent);
+        }
+
+        property.set(objectAdapter, argAdapter);
+
+        return responseOfNoContent();
+    }
+
+    @DELETE
+    @Path("/{oid}/properties/{propertyId}")
+    @Produces({ MediaType.APPLICATION_JSON })
+    public Response clearProperty(
+        @PathParam("oid") final String oidStr,
+        @PathParam("propertyId") final String propertyId) {
+
+        final ObjectAdapter objectAdapter = getObjectAdapter(oidStr);
+        final OneToOneAssociation property = getPropertyThatIsVisibleAndUsable(
+                objectAdapter, propertyId, Intent.MUTATE);
+
+        Consent consent = property.isAssociationValid(objectAdapter, null);
+        if (consent.isVetoed()) {
+            return responseOfUnauthorized(consent);
+        }
+
+        property.set(objectAdapter, null);
+
+        return responseOfNoContent();
+    }
+
+
+    ////////////////////////////////////////////////////////////
+    // domain object collection
+    ////////////////////////////////////////////////////////////
+
+    @GET
+    @Path("/{oid}/collections/{collectionId}")
+    @Produces({ MediaType.APPLICATION_JSON })
+    public Response accessCollection(
+        @PathParam("oid") final String oidStr,
+        @PathParam("collectionId") final String collectionId) {
+
+        final ObjectAdapter objectAdapter = getObjectAdapter(oidStr);
+        final OneToManyAssociation collection = getCollectionThatIsVisibleAndUsable(
+                objectAdapter, collectionId, Intent.ACCESS);
+
+        final ObjectCollectionRepBuilder builder = ObjectCollectionRepBuilder.newBuilder(
+                getResourceContext(), objectAdapter, collection);
+        return responseOfOk(jsonFrom(builder));
+    }
+
+    @PUT
+    @Path("/{oid}/collections/{collectionId}")
+    @Produces({ MediaType.APPLICATION_JSON })
+    public Response addToSet(
+        @PathParam("oid") final String oidStr,
+        @PathParam("collectionId") final String collectionId,
+        final InputStream body) {
+
+        final ObjectAdapter objectAdapter = getObjectAdapter(oidStr);
+        final OneToManyAssociation collection = getCollectionThatIsVisibleAndUsable(
+                objectAdapter, collectionId, Intent.MUTATE);
+
+        if (!collection.getCollectionSemantics().isSet()) {
+            return responseOf(HttpStatusCode.BAD_REQUEST, 
+                    "Collection '' does not have set semantics", collectionId);
+        }
+
+        ObjectSpecification collectionSpec = collection.getSpecification();
+        ObjectAdapter argAdapter = parseBody(collectionSpec, body);
+
+        Consent consent = collection.isValidToAdd(objectAdapter, argAdapter);
+        if (consent.isVetoed()) {
+            return responseOfUnauthorized(consent);
+        }
+
+        collection.addElement(objectAdapter, argAdapter);
+        
+        return responseOfNoContent();
+    }
+
+    @POST
+    @Path("/{oid}/collections/{collectionId}")
+    @Produces({ MediaType.APPLICATION_JSON })
+    public Response addToList(
+        @PathParam("oid") final String oidStr,
+        @PathParam("collectionId") final String collectionId,
+        final InputStream body) {
+
+        final ObjectAdapter objectAdapter = getObjectAdapter(oidStr);
+        final OneToManyAssociation collection = getCollectionThatIsVisibleAndUsable(
+                objectAdapter, collectionId, Intent.MUTATE);
+
+        if (!collection.getCollectionSemantics().isListOrArray()) {
+            return responseOf(HttpStatusCode.METHOD_NOT_ALLOWED, 
+                    "Collection '%s' does not have list or array semantics", collectionId);
+        }
+
+        ObjectSpecification collectionSpec = collection.getSpecification();
+        ObjectAdapter argAdapter = parseBody(collectionSpec, body);
+
+        Consent consent = collection.isValidToAdd(objectAdapter, argAdapter);
+        if (consent.isVetoed()) {
+            return responseOfUnauthorized(consent);
+        }
+
+        collection.addElement(objectAdapter, argAdapter);
+        
+        return responseOfNoContent();
+    }
+
+    @DELETE
+    @Path("/{oid}/collections/{collectionId}")
+    @Produces({ MediaType.APPLICATION_JSON })
+    public Response removeFromCollection(
+        @PathParam("oid") final String oidStr,
+        @PathParam("collectionId") final String collectionId,
+        final InputStream body) {
+
+        final ObjectAdapter objectAdapter = getObjectAdapter(oidStr);
+        final OneToManyAssociation collection = getCollectionThatIsVisibleAndUsable(
+                objectAdapter, collectionId, Intent.MUTATE);
+
+        ObjectSpecification collectionSpec = collection.getSpecification();
+        ObjectAdapter argAdapter = parseBody(collectionSpec, body);
+
+        Consent consent = collection.isValidToRemove(objectAdapter, argAdapter);
+        if (consent.isVetoed()) {
+            return responseOfUnauthorized(consent);
+        }
+
+        collection.removeElement(objectAdapter, argAdapter);
+        
+        return responseOfNoContent();
+    }
+
+
+    ////////////////////////////////////////////////////////////
+    // domain object action
+    ////////////////////////////////////////////////////////////
+
+    @GET
+    @Path("/{oid}/actions/{actionId}")
+    @Produces({ MediaType.APPLICATION_JSON })
+    public Response actionPrompt(
+        @PathParam("oid") final String oidStr,
+        @PathParam("actionId") final String actionId) {
+
+        final ObjectAdapter objectAdapter = getObjectAdapter(oidStr);
+        final ObjectAction action = getObjectActionThatIsVisibleAndUsable(
+                objectAdapter, actionId, Intent.ACCESS);
+
+        ObjectActionRepBuilder builder = ObjectActionRepBuilder.newBuilder(
+                getResourceContext(), objectAdapter, action);
+        return responseOfOk(jsonFrom(builder));
+    }
+
+    
+    ////////////////////////////////////////////////////////////
+    // domain object action invoke
+    ////////////////////////////////////////////////////////////
+
+    @GET
+    @Path("/{oid}/actions/{actionId}/invoke")
+    @Produces({ MediaType.APPLICATION_JSON })
+    public Response invokeActionQueryOnly(
+        @PathParam("oid") final String oidStr,
+        @PathParam("actionId") final String actionId,
+        @QueryParam("args") final String arguments) {
+
+        final ObjectAdapter objectAdapter = getObjectAdapter(oidStr);
+        final ObjectAction action = getObjectActionThatIsVisibleAndUsable(
+                objectAdapter, actionId, Intent.ACCESS);
+
+        if (!isQueryOnly(action)) {
+            throw JsonApplicationException.create(HttpStatusCode.METHOD_NOT_ALLOWED, 
+                    "Method not allowed; action '%s' is not query only", action.getId());
+        }
+
+        List<ObjectAdapter> argumentAdapters;
+        try {
+            argumentAdapters = argumentAdaptersFor(action, arguments);
+        } catch (IOException e) {
+            throw JsonApplicationException.create(HttpStatusCode.BAD_REQUEST, 
+                    "Action '%s' has query arguments that cannot be parsed as JSON", e, action.getId());
+        }
+
+        int numParameters = action.getParameterCount();
+        int argSize = argumentAdapters.size();
+        if(argSize != numParameters) {
+            return responseOf(HttpStatusCode.BAD_REQUEST, 
+                    "Action '%s' has %d parameters but received %d arguments", numParameters, argSize, action.getId());
+        }
+         
+        return invokeActionUsingAdapters(action, objectAdapter, argumentAdapters);
+    }
+
+
+    @PUT
+    @Path("/{oid}/actions/{actionId}/invoke")
+    @Produces({ MediaType.APPLICATION_JSON })
+    public Response invokeActionIdempotent(
+        @PathParam("oid") final String oidStr,
+        @PathParam("actionId") final String actionId,
+        final InputStream arguments) {
+
+        final ObjectAdapter objectAdapter = getObjectAdapter(oidStr);
+        final ObjectAction action = getObjectActionThatIsVisibleAndUsable(
+                objectAdapter, actionId, Intent.MUTATE);
+
+        if (!isIdempotent(action)) {
+            return responseOf(HttpStatusCode.METHOD_NOT_ALLOWED, 
+                    "Method not allowed; action '%s' is not idempotent", action.getId());
+        }
+
+        List<ObjectAdapter> argumentAdapters = parseBody(action, arguments);
+        return invokeActionUsingAdapters(action, objectAdapter,
+                argumentAdapters);
+    }
+
+
+    @POST
+    @Path("/{oid}/actions/{actionId}/invoke")
+    @Produces({ MediaType.APPLICATION_JSON })
+    public Response invokeAction(
+        @PathParam("oid") final String oidStr,
+        @PathParam("actionId") final String actionId,
+        final InputStream body) {
+
+        final ObjectAdapter objectAdapter = getObjectAdapter(oidStr);
+        final ObjectAction action = getObjectActionThatIsVisibleAndUsable(
+                objectAdapter, actionId, Intent.MUTATE);
+
+        List<ObjectAdapter> argumentAdapters = parseBody(action, body);
+        return invokeActionUsingAdapters(action, objectAdapter,
+                argumentAdapters);
+    }
+
+
+    private Response invokeActionUsingAdapters(final ObjectAction action,
+        final ObjectAdapter objectAdapter,
+        final List<ObjectAdapter> argAdapters) {
+
+        List<ObjectActionParameter> parameters = action.getParameters();
+        for (int i = 0; i < parameters.size(); i++) {
+            ObjectActionParameter parameter = parameters.get(i);
+            ObjectAdapter paramAdapter = argAdapters.get(i);
+            if (paramAdapter.getSpecification().containsFacet(ValueFacet.class)) {
+                Object arg = paramAdapter.getObject();
+                String reasonNotValid = parameter.isValid(objectAdapter, arg);
+                if (reasonNotValid != null) {
+                    throw JsonApplicationException.create(HttpStatusCode.NOT_ACCEPTABLE, reasonNotValid);
+                }
+            }
+        }
+        ObjectAdapter[] argArray = argAdapters.toArray(new ObjectAdapter[0]);
+        Consent consent = action.isProposedArgumentSetValid(objectAdapter,
+                argArray);
+        if (consent.isVetoed()) {
+            throw JsonApplicationException.create(HttpStatusCode.NOT_ACCEPTABLE, consent.getReason());
+        }
+
+        final ObjectAdapter returnedAdapter = action.execute(objectAdapter,
+                argArray);
+        if (returnedAdapter == null) {
+            return responseOfNoContent();
+        }
+        final CollectionFacet facet = returnedAdapter.getSpecification()
+                .getFacet(CollectionFacet.class);
+        if (facet != null) {
+            final Collection<ObjectAdapter> collectionAdapters = facet
+                    .collection(returnedAdapter);
+            return responseOfOk(jsonFor(collectionAdapters));
+        } else {
+            return responseOfOk(jsonFor(returnedAdapter));
+        }
+    }
+
+
+    ////////////////////////////////////////////////////////////
+    // helpers
+    ////////////////////////////////////////////////////////////
+
+    private boolean isQueryOnly(final ObjectAction action) {
+        // TODO: determine whether action is query only
+        return true;
+    }
+
+    private boolean isIdempotent(final ObjectAction action) {
+        // TODO: determine whether action is idempotent
+        return true;
+    }
+
+    private List<ObjectAdapter> argumentAdaptersFor(ObjectAction action,
+        String arguments) throws JsonParseException, JsonMappingException, IOException {
+        
+        List<ObjectAdapter> argumentAdapters = Lists.newArrayList();
+//        List<ObjectActionParameter> parameters = action.getParameters();
+//        for (int i = 0; i < parameters.size(); i++) {
+//            ObjectActionParameter parameter = parameters.get(i);
+//            ObjectSpecification paramSpc = parameter.getSpecification();
+//            String argument = arguments.get(i);
+//            argumentAdapters.add(objectAdapterFor(paramSpc, argument));
+//        }
+//
+        return argumentAdapters;
+    }
+
+    /**
+     * Similar to {@link #objectAdapterFor(ObjectSpecification, Object)},
+     * however the object being interpreted is a String holding URL encoded JSON
+     * (rather than having already been parsed into a List/Map representation).
+     */
+    private ObjectAdapter objectAdapterFor(ObjectSpecification spec,
+        String urlEncodedJson) throws JsonParseException, JsonMappingException, IOException  {
+        final String json = UrlDecoderUtils.urlDecode(urlEncodedJson);
+        if (spec.containsFacet(EncodableFacet.class)) {
+            EncodableFacet encodableFacet = spec.getFacet(EncodableFacet.class);
+            return encodableFacet.fromEncodedString(json);
+        } else {
+            Map<String, Object> representation = JsonMapper.instance().readAsMap(json);
+            return objectAdapterFor(spec, representation);
+        }
+    }
+
+
+    private List<ObjectAdapter> parseBody(final ObjectAction action,
+        final InputStream body) {
+        List<ObjectAdapter> argAdapters = Lists.newArrayList();
+        List<?> arguments = parseBody(body);
+
+        int numParameters = action.getParameterCount();
+        int numArguments = arguments.size();
+        if (numArguments != numParameters) {
+            throw new WebApplicationException(
+                responseOf(HttpStatusCode.BAD_REQUEST, 
+                        "Action '%s' has %d parameters but received %d arguments in body", 
+                        action.getId(), numParameters, numArguments));
+        }
+
+        for (int i = 0; i < numParameters; i++) {
+            ObjectAdapter argAdapter = objectAdapterFor(action, arguments, i);
+            argAdapters.add(argAdapter);
+        }
+        return argAdapters;
+
+    }
+
+    private ObjectAdapter objectAdapterFor(final ObjectAction action,
+        List<?> arguments, int i) {
+        List<ObjectActionParameter> parameters = action.getParameters();
+
+        ObjectSpecification paramSpec = parameters.get(i).getSpecification();
+        Object arg = arguments.get(i);
+
+        ObjectAdapter objectAdapter = objectAdapterFor(action, i, paramSpec, arg);
+        return objectAdapter;
+    }
+
+    private ObjectAdapter objectAdapterFor(final ObjectAction action, int i,
+        ObjectSpecification paramSpec, Object arg) {
+        try {
+            return objectAdapterFor(paramSpec, arg);
+        } catch (ExpectedStringRepresentingValueException e) {
+            throw new WebApplicationException(
+                    responseOf(HttpStatusCode.BAD_REQUEST, 
+                        "Action '%s', argument %d should be a URL encoded string representing a value of type %s",
+                        action.getId(), i, resourceFor(paramSpec)));
+        } catch (ExpectedMapRepresentingReferenceException e) {
+            throw new WebApplicationException(
+                    responseOf(HttpStatusCode.BAD_REQUEST, 
+                        "Action '%s', argument %d should be a map representing a link to reference of type %s",
+                        action.getId(), i, resourceFor(paramSpec)));
+        }
+    }
+
+    // ///////////////////////////////////////////////////////////////////
+    // helpers
+    // ///////////////////////////////////////////////////////////////////
+
+    private ObjectAdapter parseBody(ObjectSpecification objectSpec,
+        final InputStream body) {
+        List<?> arguments = parseBody(body);
+        if (arguments.size() != 1) {
+            throw new WebApplicationException(
+                    responseOf(HttpStatusCode.BAD_REQUEST, 
+                        "Body should contain 1 argument representing a value of type '%s'", 
+                        resourceFor(objectSpec)));
+        }
+
+        ObjectAdapter proposedValueAdapter = objectAdapterFor(objectSpec, arguments.get(0));
+        return proposedValueAdapter;
+    }
+
+    private List<?> parseBody(final InputStream body) {
+        try {
+            byte[] byteArray = ByteStreams.toByteArray(body);
+            String bodyAsString = new String(byteArray, Charsets.UTF_8);
+
+            List<?> arguments = jsonMapper.readAsList(bodyAsString);
+            return arguments;
+        } catch (JsonParseException e) {
+            throw new WebApplicationException(e,
+                    responseOf(HttpStatusCode.BAD_REQUEST, "could not parse body", e));
+        } catch (JsonMappingException e) {
+            throw new WebApplicationException(e,
+                    responseOf(HttpStatusCode.BAD_REQUEST, "could not map body to a Map structure", e));
+        } catch (IOException e) {
+            throw new WebApplicationException(e,
+                    responseOf(HttpStatusCode.BAD_REQUEST, "could not read body", e));
+        }
+    }
+
+    private static String resourceFor(ObjectSpecification objectSpec) {
+        // TODO: should return a string in the form
+        // http://localhost:8080/types/xxx
+        return objectSpec.getFullIdentifier();
+    }
+
+    private enum Intent {
+        ACCESS, MUTATE;
+
+        public boolean isMutate() {
+            return this == MUTATE;
+        }
+    }
+
+    private OneToOneAssociation getPropertyThatIsVisibleAndUsable(
+        final ObjectAdapter objectAdapter, final String propertyId,
+        final Intent intent) {
+        ObjectAssociation association = objectAdapter.getSpecification()
+                .getAssociation(propertyId);
+        if (association == null || !association.isOneToOneAssociation()) {
+            throwNotFoundException(propertyId, MemberType.OBJECT_PROPERTY);
+        }
+        OneToOneAssociation property = (OneToOneAssociation) association;
+        return ensureVisibleAndUsableForIntent(objectAdapter, property,
+                MemberType.OBJECT_PROPERTY, intent);
+    }
+
+    private OneToManyAssociation getCollectionThatIsVisibleAndUsable(
+        final ObjectAdapter objectAdapter, 
+        final String collectionId,
+        final Intent intent) {
+        
+        ObjectAssociation association = objectAdapter.getSpecification()
+                .getAssociation(collectionId);
+        if (association == null || !association.isOneToManyAssociation()) {
+            throwNotFoundException(collectionId, MemberType.OBJECT_COLLECTION);
+        }
+        OneToManyAssociation collection = (OneToManyAssociation) association;
+        return ensureVisibleAndUsableForIntent(objectAdapter, collection,
+                MemberType.OBJECT_COLLECTION, intent);
+    }
+
+    private ObjectAction getObjectActionThatIsVisibleAndUsable(
+        final ObjectAdapter objectAdapter,
+        final String actionId,
+        Intent intent) {
+        
+        ObjectAction action = objectAdapter.getSpecification().getObjectAction(actionId);
+        return ensureVisibleAndUsableForIntent(objectAdapter, action, MemberType.OBJECT_ACTION, intent);
+    }
+
+    public <T extends ObjectMember> T ensureVisibleAndUsableForIntent(
+        final ObjectAdapter objectAdapter, T objectMember,
+        MemberType memberType, Intent intent) {
+        String memberId = objectMember.getId();
+        if (objectMember.isVisible(getAuthenticationSession(), objectAdapter).isVetoed()) {
+            throwNotFoundException(memberId, memberType);
+        }
+        if (intent.isMutate()) {
+            Consent usable = objectMember.isUsable(getAuthenticationSession(), objectAdapter);
+            if (usable.isVetoed()) {
+                String memberTypeStr = memberType.name().toLowerCase();
+                throw new WebApplicationException(
+                        responseOf(HttpStatusCode.NOT_ACCEPTABLE, 
+                        "%s is not usable: '%s' (%s)", 
+                        memberTypeStr, memberId, usable.getReason()));
+            }
+        }
+        return objectMember;
+    }
+
+    private static void throwNotFoundException(
+            final String memberId, MemberType memberType) {
+        String memberTypeStr = memberType.name().toLowerCase();
+        throw new WebApplicationException(
+                responseOf(HttpStatusCode.NOT_FOUND, 
+                        "%s '%s' either does not exist or is not visible", 
+                        memberTypeStr, memberId));
+    }
+
+
+}

Added: incubator/isis/trunk/framework/viewer/json/json-viewer/src/main/java/org/apache/isis/viewer/json/viewer/resources/domainobjects/DomainServiceLinkToBuilder.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/DomainServiceLinkToBuilder.java?rev=1170062&view=auto
==============================================================================
--- incubator/isis/trunk/framework/viewer/json/json-viewer/src/main/java/org/apache/isis/viewer/json/viewer/resources/domainobjects/DomainServiceLinkToBuilder.java (added)
+++ incubator/isis/trunk/framework/viewer/json/json-viewer/src/main/java/org/apache/isis/viewer/json/viewer/resources/domainobjects/DomainServiceLinkToBuilder.java Tue Sep 13 06:59:11 2011
@@ -0,0 +1,50 @@
+/**
+ *  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.viewer.resources.domainobjects;
+
+import org.apache.isis.core.metamodel.adapter.ObjectAdapter;
+import org.apache.isis.core.metamodel.services.ServiceUtil;
+import org.apache.isis.viewer.json.applib.JsonRepresentation;
+import org.apache.isis.viewer.json.viewer.ResourceContext;
+import org.apache.isis.viewer.json.viewer.representations.LinkToBuilder;
+
+public class DomainServiceLinkToBuilder implements ObjectAdapterLinkToBuilder {
+
+    private ResourceContext resourceContext;
+    private ObjectAdapter objectAdapter;
+
+    public DomainServiceLinkToBuilder() {
+        super();
+    }
+
+    public ObjectAdapterLinkToBuilder with(ObjectAdapter objectAdapter) {
+        this.objectAdapter = objectAdapter;
+        return this;
+    }
+
+    public DomainServiceLinkToBuilder usingResourceContext(ResourceContext resourceContext) {
+        this.resourceContext = resourceContext;
+        return this;
+    }
+    
+    @Override
+    public JsonRepresentation build() {
+        String serviceId = ServiceUtil.id(objectAdapter.getObject());
+        return LinkToBuilder.newBuilder(resourceContext, "service", "services/%s", serviceId).build();
+    }
+
+}
\ No newline at end of file

Copied: incubator/isis/trunk/framework/viewer/json/json-viewer/src/main/java/org/apache/isis/viewer/json/viewer/resources/domainobjects/DomainServiceResourceServerside.java (from r1167411, incubator/isis/trunk/framework/viewer/json/json-viewer/src/main/java/org/apache/isis/viewer/json/viewer/resources/domainservices/DomainServiceResourceServerside.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/DomainServiceResourceServerside.java?p2=incubator/isis/trunk/framework/viewer/json/json-viewer/src/main/java/org/apache/isis/viewer/json/viewer/resources/domainobjects/DomainServiceResourceServerside.java&p1=incubator/isis/trunk/framework/viewer/json/json-viewer/src/main/java/org/apache/isis/viewer/json/viewer/resources/domainservices/DomainServiceResourceServerside.java&r1=1167411&r2=1170062&rev=1170062&view=diff
==============================================================================
--- incubator/isis/trunk/framework/viewer/json/json-viewer/src/main/java/org/apache/isis/viewer/json/viewer/resources/domainservices/DomainServiceResourceServerside.java (original)
+++ incubator/isis/trunk/framework/viewer/json/json-viewer/src/main/java/org/apache/isis/viewer/json/viewer/resources/domainobjects/DomainServiceResourceServerside.java Tue Sep 13 06:59:11 2011
@@ -14,7 +14,7 @@
  *  See the License for the specific language governing permissions and
  *  limitations under the License.
  */
-package org.apache.isis.viewer.json.viewer.resources.domainservices;
+package org.apache.isis.viewer.json.viewer.resources.domainobjects;
 
 import java.io.InputStream;
 import java.util.List;
@@ -36,10 +36,10 @@ import org.apache.isis.viewer.json.appli
 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.DomainServiceResource;
+import org.apache.isis.viewer.json.viewer.JsonApplicationException;
 import org.apache.isis.viewer.json.viewer.ResourceContext;
-import org.apache.isis.viewer.json.viewer.representations.RepresentationBuilder;
+import org.apache.isis.viewer.json.viewer.representations.AbstractRepresentationBuilder;
 import org.apache.isis.viewer.json.viewer.resources.ResourceAbstract;
-import org.apache.isis.viewer.json.viewer.resources.domainobjects.DomainObjectListRepBuilder;
 
 @Path("/services")
 public class DomainServiceResourceServerside extends ResourceAbstract implements
@@ -54,7 +54,8 @@ public class DomainServiceResourceServer
         final List<ObjectAdapter> serviceAdapters = getPersistenceSession().getServices();
 
         DomainObjectListRepBuilder builder = 
-                DomainServiceListRepBuilder.newBuilder(resourceContext)
+                DomainObjectListRepBuilder.newBuilder(resourceContext)
+                    .usingLinkToBuilder(new DomainServiceLinkToBuilder())
                     .withSelf("services")
                     .withAdapters(serviceAdapters);
         
@@ -76,22 +77,17 @@ public class DomainServiceResourceServer
     public Response service(@PathParam("serviceId") String serviceId) {
         init();
         
-        // TODO: figure out how to do exception handling generically
-
         final ObjectAdapter serviceAdapter = getServiceAdapter(serviceId);
         if(serviceAdapter == null) {
             Object[] args = { serviceId };
-            return Response
-                    .status(HttpStatusCode.NOT_FOUND.getJaxrsStatusType())
-                    .header(RestfulResponse.Header.WARNING.getName(), String.format("Could not locate service '%s'", args))
-                    .type(MediaType.APPLICATION_JSON_TYPE)
-                    .build();
+            throw JsonApplicationException.create(HttpStatusCode.NOT_FOUND, "Could not locate service '%s'", args);
         }
         ResourceContext resourceContext = getResourceContext();
 
-        RepresentationBuilder<?> builder = 
-                DomainServiceRepBuilder.newBuilder(resourceContext)
-                .withAdapter(serviceAdapter);
+        AbstractRepresentationBuilder<?> builder = 
+                DomainObjectRepBuilder.newBuilder(resourceContext)
+                    .usingLinkToBuilder(new DomainServiceLinkToBuilder())
+                    .withAdapter(serviceAdapter);
         
         return Response.ok()
                 .entity(jsonFrom(builder))



Mime
View raw message