incubator-isis-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From danhayw...@apache.org
Subject svn commit: r1139496 - in /incubator/isis/trunk: core/metamodel/src/main/java/org/apache/isis/core/metamodel/spec/ core/metamodel/src/main/java/org/apache/isis/core/metamodel/spec/feature/ core/metamodel/src/main/java/org/apache/isis/core/metamodel/spe...
Date Sat, 25 Jun 2011 06:58:01 GMT
Author: danhaywood
Date: Sat Jun 25 06:58:00 2011
New Revision: 1139496

URL: http://svn.apache.org/viewvc?rev=1139496&view=rev
Log:
more work on viewer2; added ability to look up ObjectAction just by Id ('placeOrder') rather than fully qualified Id 'placeOrder(..., ...)'

Added:
    incubator/isis/trunk/viewer/restful/applib2/src/main/java/org/apache/isis/viewer/restful/applib2/resources/DomainObjectResource.java
      - copied, changed from r1138673, incubator/isis/trunk/viewer/restful/applib2/src/main/java/org/apache/isis/viewer/restful/applib2/resources/ObjectResource.java
    incubator/isis/trunk/viewer/restful/viewer2/src/main/java/org/apache/isis/viewer/restful/viewer2/resources/objects/AbstractMemberRepBuilder.java
    incubator/isis/trunk/viewer/restful/viewer2/src/main/java/org/apache/isis/viewer/restful/viewer2/resources/objects/ActionRepBuilder.java
    incubator/isis/trunk/viewer/restful/viewer2/src/main/java/org/apache/isis/viewer/restful/viewer2/resources/objects/CollectionRepBuilder.java
    incubator/isis/trunk/viewer/restful/viewer2/src/main/java/org/apache/isis/viewer/restful/viewer2/resources/objects/MemberRepType.java
    incubator/isis/trunk/viewer/restful/viewer2/src/main/java/org/apache/isis/viewer/restful/viewer2/resources/objects/MemberType.java
    incubator/isis/trunk/viewer/restful/viewer2/src/main/java/org/apache/isis/viewer/restful/viewer2/resources/objects/MutatorSpec.java
Removed:
    incubator/isis/trunk/viewer/restful/applib2/src/main/java/org/apache/isis/viewer/restful/applib2/resources/ObjectResource.java
Modified:
    incubator/isis/trunk/core/metamodel/src/main/java/org/apache/isis/core/metamodel/spec/ActionType.java
    incubator/isis/trunk/core/metamodel/src/main/java/org/apache/isis/core/metamodel/spec/ObjectSpecification.java
    incubator/isis/trunk/core/metamodel/src/main/java/org/apache/isis/core/metamodel/spec/feature/ObjectActionContainer.java
    incubator/isis/trunk/core/metamodel/src/main/java/org/apache/isis/core/metamodel/specloader/specimpl/ObjectSpecificationAbstract.java
    incubator/isis/trunk/core/metamodel/src/main/java/org/apache/isis/core/metamodel/specloader/specimpl/dflt/ObjectSpecificationDefault.java
    incubator/isis/trunk/core/metamodel/src/main/java/org/apache/isis/core/metamodel/specloader/specimpl/objectlist/ObjectSpecificationForObjectList.java
    incubator/isis/trunk/core/metamodel/src/test/java/org/apache/isis/core/metamodel/testspec/TestProxySpecification.java
    incubator/isis/trunk/runtimes/dflt/runtime/src/test/java/org/apache/isis/runtimes/dflt/runtime/testsystem/TestSpecification.java
    incubator/isis/trunk/viewer/restful/viewer2/src/main/java/org/apache/isis/viewer/restful/viewer2/representations/LinkRepBuilder.java
    incubator/isis/trunk/viewer/restful/viewer2/src/main/java/org/apache/isis/viewer/restful/viewer2/representations/RepresentationBuilder.java
    incubator/isis/trunk/viewer/restful/viewer2/src/main/java/org/apache/isis/viewer/restful/viewer2/resources/ResourceAbstract.java
    incubator/isis/trunk/viewer/restful/viewer2/src/main/java/org/apache/isis/viewer/restful/viewer2/resources/objects/DomainObjectRepBuilder.java
    incubator/isis/trunk/viewer/restful/viewer2/src/main/java/org/apache/isis/viewer/restful/viewer2/resources/objects/DomainObjectResourceImpl.java
    incubator/isis/trunk/viewer/restful/viewer2/src/main/java/org/apache/isis/viewer/restful/viewer2/resources/objects/MemberSelfRepBuilder.java
    incubator/isis/trunk/viewer/restful/viewer2/src/main/java/org/apache/isis/viewer/restful/viewer2/resources/objects/PropertyRepBuilder.java
    incubator/isis/trunk/viewer/restful/viewer2/src/main/java/org/apache/isis/viewer/restful/viewer2/resources/services/ServicesResourceImpl.java
    incubator/isis/trunk/viewer/restful/viewer2/src/main/java/org/apache/isis/viewer/restful/viewer2/util/OidUtils.java

Modified: incubator/isis/trunk/core/metamodel/src/main/java/org/apache/isis/core/metamodel/spec/ActionType.java
URL: http://svn.apache.org/viewvc/incubator/isis/trunk/core/metamodel/src/main/java/org/apache/isis/core/metamodel/spec/ActionType.java?rev=1139496&r1=1139495&r2=1139496&view=diff
==============================================================================
--- incubator/isis/trunk/core/metamodel/src/main/java/org/apache/isis/core/metamodel/spec/ActionType.java (original)
+++ incubator/isis/trunk/core/metamodel/src/main/java/org/apache/isis/core/metamodel/spec/ActionType.java Sat Jun 25 06:58:00 2011
@@ -19,10 +19,16 @@
 
 package org.apache.isis.core.metamodel.spec;
 
+import org.apache.isis.core.metamodel.spec.feature.ObjectAction;
+
 public enum ActionType {
     DEBUG, SET, EXPLORATION, PROTOTYPE, USER;
 
     public String getName() {
         return name();
     }
+
+    public boolean matchesTypeOf(ObjectAction action) {
+        return this == null || action.getType().equals(this);
+    }
 }

Modified: incubator/isis/trunk/core/metamodel/src/main/java/org/apache/isis/core/metamodel/spec/ObjectSpecification.java
URL: http://svn.apache.org/viewvc/incubator/isis/trunk/core/metamodel/src/main/java/org/apache/isis/core/metamodel/spec/ObjectSpecification.java?rev=1139496&r1=1139495&r2=1139496&view=diff
==============================================================================
--- incubator/isis/trunk/core/metamodel/src/main/java/org/apache/isis/core/metamodel/spec/ObjectSpecification.java (original)
+++ incubator/isis/trunk/core/metamodel/src/main/java/org/apache/isis/core/metamodel/spec/ObjectSpecification.java Sat Jun 25 06:58:00 2011
@@ -344,4 +344,5 @@ public interface ObjectSpecification ext
 
     public boolean isIntrospected();
 
+
 }

Modified: incubator/isis/trunk/core/metamodel/src/main/java/org/apache/isis/core/metamodel/spec/feature/ObjectActionContainer.java
URL: http://svn.apache.org/viewvc/incubator/isis/trunk/core/metamodel/src/main/java/org/apache/isis/core/metamodel/spec/feature/ObjectActionContainer.java?rev=1139496&r1=1139495&r2=1139496&view=diff
==============================================================================
--- incubator/isis/trunk/core/metamodel/src/main/java/org/apache/isis/core/metamodel/spec/feature/ObjectActionContainer.java (original)
+++ incubator/isis/trunk/core/metamodel/src/main/java/org/apache/isis/core/metamodel/spec/feature/ObjectActionContainer.java Sat Jun 25 06:58:00 2011
@@ -27,9 +27,6 @@ import org.apache.isis.core.metamodel.sp
 
 public interface ObjectActionContainer {
 
-    /**
-     * TODO: convert to relatedResourceActions
-     */
     List<ObjectAction> getServiceActionsReturning(ActionType... type);
 
     /**
@@ -41,9 +38,25 @@ public interface ObjectActionContainer {
      * Get the action object represented by the specified identity string.
      * 
      * <p>
-     * The identity string should be {@link Identifier#toNameParmsIdentityString()}</tt>.
+     * The identity string can be either fully specified with parameters
+     * (as per {@link Identifier#toNameParmsIdentityString()} or in 
+     * abbreviated form ({@link Identifier#toNameIdentityString()}).
+     * 
+     * @see #getObjectAction(String)
+     */
+    ObjectAction getObjectAction(ActionType type, String id);
+
+    /**
+     * Get the action object represented by the specified identity string, irrespective of {@link ActionType}.
+     * 
+     * <p>
+     * The identity string can be either fully specified with parameters
+     * (as per {@link Identifier#toNameParmsIdentityString()} or in 
+     * abbreviated form ({@link Identifier#toNameIdentityString()}).
+     * 
+     * @see #getObjectAction(ActionType, String)
      */
-    ObjectAction getObjectAction(ActionType type, String nameAndParmsIdentityString);
+    ObjectAction getObjectAction(String id);
 
     /**
      * Returns an array of actions of the specified type(s), including any contributed actions.

Modified: incubator/isis/trunk/core/metamodel/src/main/java/org/apache/isis/core/metamodel/specloader/specimpl/ObjectSpecificationAbstract.java
URL: http://svn.apache.org/viewvc/incubator/isis/trunk/core/metamodel/src/main/java/org/apache/isis/core/metamodel/specloader/specimpl/ObjectSpecificationAbstract.java?rev=1139496&r1=1139495&r2=1139496&view=diff
==============================================================================
--- incubator/isis/trunk/core/metamodel/src/main/java/org/apache/isis/core/metamodel/specloader/specimpl/ObjectSpecificationAbstract.java (original)
+++ incubator/isis/trunk/core/metamodel/src/main/java/org/apache/isis/core/metamodel/specloader/specimpl/ObjectSpecificationAbstract.java Sat Jun 25 06:58:00 2011
@@ -658,14 +658,14 @@ public abstract class ObjectSpecificatio
                 final ObjectActionSet actionSet = (ObjectActionSet) action;
                 final List<ObjectAction> subActions = actionSet.getActions();
                 for (final ObjectAction subAction : subActions) {
-                    if (sameActionTypeOrNotSpecified(type, subAction)) {
+                    if (type.matchesTypeOf(subAction)) {
                         actions.add(subAction);
                         // REVIEW: why was there a break here?
                         // break;
                     }
                 }
             } else {
-                if (sameActionTypeOrNotSpecified(type, action)) {
+                if (type.matchesTypeOf(action)) {
                     actions.add(action);
                 }
             }
@@ -674,14 +674,6 @@ public abstract class ObjectSpecificatio
         return actions;
     }
 
-    protected boolean sameActionTypeOrNotSpecified(final ActionType type, final ObjectAction action) {
-        return type == null || action.getType().equals(type);
-    }
-
-    // //////////////////////////////////////////////////////////////////////
-    // service actions
-    // //////////////////////////////////////////////////////////////////////
-
     @Override
     public List<ObjectAction> getServiceActionsReturning(final ActionType... types) {
         final List<ObjectAction> serviceActions = Lists.newArrayList();
@@ -762,7 +754,7 @@ public abstract class ObjectSpecificatio
         }
         return contributedActionSets;
     }
-
+    
     private void addContributedActionsIfAny(final ObjectAdapter serviceAdapter, final ActionType actionType,
         final List<ObjectAction> contributedActionSetsToAppendTo) {
         final ObjectSpecification specification = serviceAdapter.getSpecification();

Modified: incubator/isis/trunk/core/metamodel/src/main/java/org/apache/isis/core/metamodel/specloader/specimpl/dflt/ObjectSpecificationDefault.java
URL: http://svn.apache.org/viewvc/incubator/isis/trunk/core/metamodel/src/main/java/org/apache/isis/core/metamodel/specloader/specimpl/dflt/ObjectSpecificationDefault.java?rev=1139496&r1=1139495&r2=1139496&view=diff
==============================================================================
--- incubator/isis/trunk/core/metamodel/src/main/java/org/apache/isis/core/metamodel/specloader/specimpl/dflt/ObjectSpecificationDefault.java (original)
+++ incubator/isis/trunk/core/metamodel/src/main/java/org/apache/isis/core/metamodel/specloader/specimpl/dflt/ObjectSpecificationDefault.java Sat Jun 25 06:58:00 2011
@@ -347,10 +347,21 @@ public class ObjectSpecificationDefault 
     }
 
     @Override
-    public ObjectAction getObjectAction(final ActionType type, final String nameParmsIdentityString) {
+    public ObjectAction getObjectAction(final ActionType type, final String id) {
         final List<ObjectAction> availableActions =
-            ListUtils.combine(getObjectActionsAll(), getContributedActions(type));
-        return getAction(availableActions, type, nameParmsIdentityString);
+            ListUtils.combine(getObjectActions(type), getContributedActions(type));
+        return getAction(availableActions, type, id);
+    }
+
+    @Override
+    public ObjectAction getObjectAction(final String id) {
+        for(ActionType type: ActionType.values()) {
+            ObjectAction action = getObjectAction(type, id);
+            if(action != null) {
+                return action;
+            }
+        }
+        return null;
     }
 
     private ObjectAction getAction(final List<ObjectAction> availableActions, final ActionType type,
@@ -386,27 +397,30 @@ public class ObjectSpecificationDefault 
     }
 
     private ObjectAction getAction(final List<ObjectAction> availableActions, final ActionType type,
-        final String nameParmsIdentityString) {
-        if (nameParmsIdentityString == null) {
+        final String id) {
+        if (id == null) {
             return null;
         }
         outer: for (int i = 0; i < availableActions.size(); i++) {
             final ObjectAction action = availableActions.get(i);
             if (action.getActions().size() > 0) {
                 // deal with action set
-                final ObjectAction a = getAction(action.getActions(), type, nameParmsIdentityString);
+                final ObjectAction a = getAction(action.getActions(), type, id);
                 if (a != null) {
                     return a;
                 }
             } else {
                 // regular action
-                if (!sameActionTypeOrNotSpecified(type, action)) {
+                if (!type.matchesTypeOf(action)) {
                     continue outer;
                 }
-                if (!nameParmsIdentityString.equals(action.getIdentifier().toNameParmsIdentityString())) {
-                    continue outer;
-                }
-                return action;
+                if (id.equals(action.getIdentifier().toNameParmsIdentityString())) {
+                    return action;
+                } 
+                if (id.equals(action.getIdentifier().toNameIdentityString())) {
+                    return action;
+                } 
+                continue outer;
             }
         }
         return null;

Modified: incubator/isis/trunk/core/metamodel/src/main/java/org/apache/isis/core/metamodel/specloader/specimpl/objectlist/ObjectSpecificationForObjectList.java
URL: http://svn.apache.org/viewvc/incubator/isis/trunk/core/metamodel/src/main/java/org/apache/isis/core/metamodel/specloader/specimpl/objectlist/ObjectSpecificationForObjectList.java?rev=1139496&r1=1139495&r2=1139496&view=diff
==============================================================================
--- incubator/isis/trunk/core/metamodel/src/main/java/org/apache/isis/core/metamodel/specloader/specimpl/objectlist/ObjectSpecificationForObjectList.java (original)
+++ incubator/isis/trunk/core/metamodel/src/main/java/org/apache/isis/core/metamodel/specloader/specimpl/objectlist/ObjectSpecificationForObjectList.java Sat Jun 25 06:58:00 2011
@@ -154,6 +154,15 @@ public class ObjectSpecificationForObjec
         return null;
     }
 
+    /**
+     * Review: is it necessary to override for this subclass?
+     */
+    @Override
+    public ObjectAction getObjectAction(final String nameParmsIdentityString) {
+        return null;
+    }
+
+
     // /////////////////////////////////////////////////////
     // Service Actions
     // /////////////////////////////////////////////////////

Modified: incubator/isis/trunk/core/metamodel/src/test/java/org/apache/isis/core/metamodel/testspec/TestProxySpecification.java
URL: http://svn.apache.org/viewvc/incubator/isis/trunk/core/metamodel/src/test/java/org/apache/isis/core/metamodel/testspec/TestProxySpecification.java?rev=1139496&r1=1139495&r2=1139496&view=diff
==============================================================================
--- incubator/isis/trunk/core/metamodel/src/test/java/org/apache/isis/core/metamodel/testspec/TestProxySpecification.java (original)
+++ incubator/isis/trunk/core/metamodel/src/test/java/org/apache/isis/core/metamodel/testspec/TestProxySpecification.java Sat Jun 25 06:58:00 2011
@@ -209,6 +209,17 @@ public class TestProxySpecification exte
     }
 
     @Override
+    public ObjectAction getObjectAction(final String nameParmsIdentityString) {
+        for(ActionType type: ActionType.values()) {
+            ObjectAction action = getObjectAction(type, nameParmsIdentityString);
+            if(action != null) {
+                return action;
+            }
+        }
+        return null;
+    }
+
+    @Override
     public String getPluralName() {
         return null;
     }

Modified: incubator/isis/trunk/runtimes/dflt/runtime/src/test/java/org/apache/isis/runtimes/dflt/runtime/testsystem/TestSpecification.java
URL: http://svn.apache.org/viewvc/incubator/isis/trunk/runtimes/dflt/runtime/src/test/java/org/apache/isis/runtimes/dflt/runtime/testsystem/TestSpecification.java?rev=1139496&r1=1139495&r2=1139496&view=diff
==============================================================================
--- incubator/isis/trunk/runtimes/dflt/runtime/src/test/java/org/apache/isis/runtimes/dflt/runtime/testsystem/TestSpecification.java (original)
+++ incubator/isis/trunk/runtimes/dflt/runtime/src/test/java/org/apache/isis/runtimes/dflt/runtime/testsystem/TestSpecification.java Sat Jun 25 06:58:00 2011
@@ -180,6 +180,11 @@ public class TestSpecification extends F
     }
 
     @Override
+    public ObjectAction getObjectAction(final String name) {
+        return null;
+    }
+
+    @Override
     public List<ObjectAction> getObjectActions(final ActionType... type) {
         return null;
     }

Copied: incubator/isis/trunk/viewer/restful/applib2/src/main/java/org/apache/isis/viewer/restful/applib2/resources/DomainObjectResource.java (from r1138673, incubator/isis/trunk/viewer/restful/applib2/src/main/java/org/apache/isis/viewer/restful/applib2/resources/ObjectResource.java)
URL: http://svn.apache.org/viewvc/incubator/isis/trunk/viewer/restful/applib2/src/main/java/org/apache/isis/viewer/restful/applib2/resources/DomainObjectResource.java?p2=incubator/isis/trunk/viewer/restful/applib2/src/main/java/org/apache/isis/viewer/restful/applib2/resources/DomainObjectResource.java&p1=incubator/isis/trunk/viewer/restful/applib2/src/main/java/org/apache/isis/viewer/restful/applib2/resources/ObjectResource.java&r1=1138673&r2=1139496&rev=1139496&view=diff
==============================================================================
--- incubator/isis/trunk/viewer/restful/applib2/src/main/java/org/apache/isis/viewer/restful/applib2/resources/ObjectResource.java (original)
+++ incubator/isis/trunk/viewer/restful/applib2/src/main/java/org/apache/isis/viewer/restful/applib2/resources/DomainObjectResource.java Sat Jun 25 06:58:00 2011
@@ -19,9 +19,12 @@
 package org.apache.isis.viewer.restful.applib2.resources;
 
 import java.io.InputStream;
+import java.util.List;
 
 import javax.ws.rs.DELETE;
+import javax.ws.rs.FormParam;
 import javax.ws.rs.GET;
+import javax.ws.rs.MatrixParam;
 import javax.ws.rs.POST;
 import javax.ws.rs.PUT;
 import javax.ws.rs.Path;
@@ -30,48 +33,80 @@ import javax.ws.rs.Produces;
 import javax.ws.rs.QueryParam;
 import javax.ws.rs.core.MediaType;
 
-public interface ObjectResource {
+// under /objects
+public interface DomainObjectResource {
 
     @GET
     @Path("/{oid}")
     @Produces({ MediaType.APPLICATION_JSON })
     public String object(@PathParam("oid") final String oidStr);
 
+    @GET
+    @Path("/{oid}/properties{propertyId}")
+    @Produces({ MediaType.APPLICATION_JSON })
+    public String propertyDetails(
+        @PathParam("oid") final String oidStr,
+        @PathParam("propertyId") final String propertyId);
+
     @PUT
-    @Path("/{oid}/property/{propertyId}")
+    @Path("/{oid}/properties{propertyId}")
     @Produces({ MediaType.APPLICATION_JSON })
-    public String modifyProperty(@PathParam("oid") final String oidStr,
-        @PathParam("propertyId") final String propertyId, @QueryParam("proposedValue") final String proposedValue);
+    public String modifyProperty(
+        @PathParam("oid") final String oidStr,
+        @PathParam("propertyId") final String propertyId, 
+        @FormParam("proposedValue") final String proposedValue);
 
     @DELETE
-    @Path("/{oid}/property/{propertyId}")
+    @Path("/{oid}/properties/{propertyId}")
     @Produces({ MediaType.APPLICATION_JSON })
-    public String clearProperty(@PathParam("oid") final String oidStr, @PathParam("propertyId") final String propertyId);
+    public String clearProperty(
+        @PathParam("oid") final String oidStr, 
+        @PathParam("propertyId") final String propertyId);
 
     @GET
-    @Path("/{oid}/collection/{collectionId}")
+    @Path("/{oid}/collections/{collectionId}")
     @Produces({ MediaType.APPLICATION_JSON })
-    public String accessCollection(@PathParam("oid") final String oidStr,
+    public String accessCollection(
+        @PathParam("oid") final String oidStr,
         @PathParam("collectionId") final String collectionId);
 
     @PUT
-    @Path("/{oid}/collection/{collectionId}")
+    @Path("/{oid}/collections/{collectionId}")
     @Produces({ MediaType.APPLICATION_JSON })
-    public String addToCollection(@PathParam("oid") final String oidStr,
+    public String addToCollection(
+        @PathParam("oid") final String oidStr,
         @PathParam("collectionId") final String collectionId,
-        @QueryParam("proposedValue") final String proposedValueOidStr);
+        @FormParam("proposedValue") final String proposedValueOidStr);
 
     @DELETE
-    @Path("/{oid}/collection/{collectionId}")
+    @Path("/{oid}/collections/{collectionId}")
     @Produces({ MediaType.APPLICATION_JSON })
-    public String removeFromCollection(@PathParam("oid") final String oidStr,
+    public String removeFromCollection(
+        @PathParam("oid") final String oidStr,
         @PathParam("collectionId") final String collectionId,
-        @QueryParam("proposedValue") final String proposedValueOidStr);
+        @FormParam("proposedValue") final String proposedValueOidStr);
+
+    @GET
+    @Path("/{oid}/actions/{actionId}")
+    @Produces({ MediaType.APPLICATION_JSON })
+    public String actionPrompt(
+        @PathParam("oid") final String oidStr, 
+        @PathParam("actionId") final String actionId);
 
     @POST
-    @Path("/{oid}/action/{actionId}")
+    @Path("/{oid}/actions/{actionId}/invoke")
     @Produces({ MediaType.APPLICATION_JSON })
-    public String invokeAction(@PathParam("oid") final String oidStr, @PathParam("actionId") final String actionId,
+    public String invokeAction(
+        @PathParam("oid") final String oidStr, 
+        @PathParam("actionId") final String actionId,
         final InputStream body);
 
+    @GET
+    @Path("/{oid}/actions/{actionId}/invoke")
+    @Produces({ MediaType.APPLICATION_JSON })
+    public String invokeActionIdempotent(
+        @PathParam("oid") final String oidStr, 
+        @PathParam("actionId") final String actionId,
+        @QueryParam("argument") final List<String> arguments);
+
 }
\ No newline at end of file

Modified: incubator/isis/trunk/viewer/restful/viewer2/src/main/java/org/apache/isis/viewer/restful/viewer2/representations/LinkRepBuilder.java
URL: http://svn.apache.org/viewvc/incubator/isis/trunk/viewer/restful/viewer2/src/main/java/org/apache/isis/viewer/restful/viewer2/representations/LinkRepBuilder.java?rev=1139496&r1=1139495&r2=1139496&view=diff
==============================================================================
--- incubator/isis/trunk/viewer/restful/viewer2/src/main/java/org/apache/isis/viewer/restful/viewer2/representations/LinkRepBuilder.java (original)
+++ incubator/isis/trunk/viewer/restful/viewer2/src/main/java/org/apache/isis/viewer/restful/viewer2/representations/LinkRepBuilder.java Sat Jun 25 06:58:00 2011
@@ -16,6 +16,8 @@
  */
 package org.apache.isis.viewer.restful.viewer2.representations;
 
+import java.util.List;
+
 import org.apache.isis.core.metamodel.spec.ObjectSpecification;
 import org.apache.isis.viewer.restful.viewer2.RepContext;
 
@@ -33,14 +35,14 @@ public class LinkRepBuilder extends Repr
     
     private HttpMethod method = HttpMethod.GET;
     private String title;
-    private String body;
+    private List<String> body;
     
     public LinkRepBuilder(RepContext repContext, String relSuffix, String url) {
         super(repContext);
         this.relSuffix = relSuffix;
         this.url = url;
     }
-    public LinkRepBuilder withMethod(HttpMethod method) {
+    public LinkRepBuilder withHttpMethod(HttpMethod method) {
         this.method = method;
         return this;
     }
@@ -48,7 +50,7 @@ public class LinkRepBuilder extends Repr
         this.title = title;
         return this;
     }
-    public LinkRepBuilder withBody(String body) {
+    public LinkRepBuilder withBody(List<String> body) {
         this.body = body;
         return this;
     }

Modified: incubator/isis/trunk/viewer/restful/viewer2/src/main/java/org/apache/isis/viewer/restful/viewer2/representations/RepresentationBuilder.java
URL: http://svn.apache.org/viewvc/incubator/isis/trunk/viewer/restful/viewer2/src/main/java/org/apache/isis/viewer/restful/viewer2/representations/RepresentationBuilder.java?rev=1139496&r1=1139495&r2=1139496&view=diff
==============================================================================
--- incubator/isis/trunk/viewer/restful/viewer2/src/main/java/org/apache/isis/viewer/restful/viewer2/representations/RepresentationBuilder.java (original)
+++ incubator/isis/trunk/viewer/restful/viewer2/src/main/java/org/apache/isis/viewer/restful/viewer2/representations/RepresentationBuilder.java Sat Jun 25 06:58:00 2011
@@ -33,6 +33,8 @@ public abstract class RepresentationBuil
         this.repContext = repContext;
     }
 
+    public abstract Representation build();
+    
     protected OidStringifier getOidStringifier() {
         return getOidGenerator().getOidStringifier();
     }

Modified: incubator/isis/trunk/viewer/restful/viewer2/src/main/java/org/apache/isis/viewer/restful/viewer2/resources/ResourceAbstract.java
URL: http://svn.apache.org/viewvc/incubator/isis/trunk/viewer/restful/viewer2/src/main/java/org/apache/isis/viewer/restful/viewer2/resources/ResourceAbstract.java?rev=1139496&r1=1139495&r2=1139496&view=diff
==============================================================================
--- incubator/isis/trunk/viewer/restful/viewer2/src/main/java/org/apache/isis/viewer/restful/viewer2/resources/ResourceAbstract.java (original)
+++ incubator/isis/trunk/viewer/restful/viewer2/src/main/java/org/apache/isis/viewer/restful/viewer2/resources/ResourceAbstract.java Sat Jun 25 06:58:00 2011
@@ -23,6 +23,7 @@ import java.util.List;
 
 import javax.servlet.http.HttpServletRequest;
 import javax.servlet.http.HttpServletResponse;
+import javax.ws.rs.WebApplicationException;
 import javax.ws.rs.core.Context;
 import javax.ws.rs.core.HttpHeaders;
 import javax.ws.rs.core.Request;
@@ -43,7 +44,10 @@ import org.apache.isis.runtimes.dflt.run
 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.restful.viewer2.ResourceContext;
+import org.apache.isis.viewer.restful.viewer2.representations.Representation;
+import org.apache.isis.viewer.restful.viewer2.representations.RepresentationBuilder;
 import org.apache.isis.viewer.restful.viewer2.util.OidUtils;
+import org.apache.isis.viewer.restful.viewer2.util.UrlDecoderUtils;
 import org.codehaus.jackson.JsonGenerationException;
 import org.codehaus.jackson.map.JsonMappingException;
 import org.codehaus.jackson.map.ObjectMapper;
@@ -91,6 +95,11 @@ public abstract class ResourceAbstract {
     // Rendering
     // //////////////////////////////////////////////////////////////
 
+    protected String jsonRepresentionFrom(RepresentationBuilder builder) {
+        Representation representation = builder.build();
+        return asJson(representation);
+    }
+
     protected String asJson(final Object object) {
         ObjectMapper objectMapper = new ObjectMapper();
         objectMapper.configure(SerializationConfig.Feature.INDENT_OUTPUT, true);
@@ -105,9 +114,6 @@ public abstract class ResourceAbstract {
         }
     }
 
-    protected String asJsonList(List<?> services) {
-        return asJson(services);
-    }
 
     // //////////////////////////////////////////////////////////////
     // Isis integration
@@ -118,11 +124,17 @@ public abstract class ResourceAbstract {
     }
 
     protected ObjectAdapter getObjectAdapter(final String oidEncodedStr) {
-        return OidUtils.getNakedObject(oidEncodedStr, getOidStringifier());
+        final ObjectAdapter objectAdapter = OidUtils.getObjectAdapter(oidEncodedStr, getOidStringifier());
+        
+        if (objectAdapter == null) {
+            final String oidStr = UrlDecoderUtils.urlDecode(oidEncodedStr);
+            throw new WebApplicationException(responseOfNotFound("could not determine adapter for OID: '" + oidStr + "'"));
+        }
+        return objectAdapter;
     }
 
-    protected String getOidStr(final ObjectAdapter nakedObject) {
-        return OidUtils.getOidStr(nakedObject, getOidStringifier());
+    protected String getOidStr(final ObjectAdapter objectAdapter) {
+        return OidUtils.getOidStr(objectAdapter, getOidStringifier());
     }
 
 

Added: incubator/isis/trunk/viewer/restful/viewer2/src/main/java/org/apache/isis/viewer/restful/viewer2/resources/objects/AbstractMemberRepBuilder.java
URL: http://svn.apache.org/viewvc/incubator/isis/trunk/viewer/restful/viewer2/src/main/java/org/apache/isis/viewer/restful/viewer2/resources/objects/AbstractMemberRepBuilder.java?rev=1139496&view=auto
==============================================================================
--- incubator/isis/trunk/viewer/restful/viewer2/src/main/java/org/apache/isis/viewer/restful/viewer2/resources/objects/AbstractMemberRepBuilder.java (added)
+++ incubator/isis/trunk/viewer/restful/viewer2/src/main/java/org/apache/isis/viewer/restful/viewer2/resources/objects/AbstractMemberRepBuilder.java Sat Jun 25 06:58:00 2011
@@ -0,0 +1,183 @@
+/**
+ *  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.restful.viewer2.resources.objects;
+
+import java.util.List;
+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.restful.viewer2.RepContext;
+import org.apache.isis.viewer.restful.viewer2.representations.LinkRepBuilder;
+import org.apache.isis.viewer.restful.viewer2.representations.Representation;
+import org.apache.isis.viewer.restful.viewer2.representations.RepresentationBuilder;
+
+import com.google.common.collect.Lists;
+
+public abstract class AbstractMemberRepBuilder<T extends ObjectMember> extends RepresentationBuilder {
+
+    protected final ObjectAdapter objectAdapter;
+    protected final MemberType memberType;
+    protected final T objectMember;
+    protected final MemberRepType memberRepType;
+
+    public AbstractMemberRepBuilder(RepContext repContext, ObjectAdapter objectAdapter, MemberType memberType, T objectMember) {
+        super(repContext);
+        this.objectAdapter = objectAdapter;
+        this.memberType = memberType;
+        this.objectMember = objectMember;
+        this.memberRepType = repContext.hasAttribute()?MemberRepType.INLINE:MemberRepType.STANDALONE;
+    }
+
+    protected void putSelfIfRequired() {
+        if(memberRepType.hasSelf()) {
+            Representation selfRep = MemberSelfRepBuilder.newBuilder(repContext, objectAdapter, memberType, objectMember).build();
+            representation.put("self", selfRep);
+        }
+    }
+
+    protected void putMemberTypeRep() {
+        representation.put("memberType", memberType);
+    }
+
+    protected void putTypeRep() {
+        Representation typeRep = LinkRepBuilder.newTypeBuilder(repContext, "type", memberType.specFor(objectMember)).build();
+        representation.put("type", typeRep);
+    }
+
+    protected void putMutatorsIfRequired() {
+        if(!memberRepType.hasMutators() || usability().isVetoed()) {
+            return;
+        }
+        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);
+                List<String> body = mutatorArgValues(mutatorSpec);
+                Representation detailsLink = 
+                    LinkRepBuilder.newBuilder(repContext, mutator, urlForMember)
+                        .withHttpMethod(mutatorSpec.httpMethod)
+                        .withBody(body)
+                        .build();
+                representation.put(mutator, detailsLink);
+            }
+        }
+    }
+
+    /**
+     * Can be optionally overridden by members that are able
+     * to provide argument values (eg contributed actions).
+     */
+    protected List<String> mutatorArgValues(MutatorSpec mutatorSpec) {
+        List<String> values = Lists.newArrayList();
+        if(mutatorSpec.argSpec.isOne()) {
+            values.add("{arg}");
+        }
+        return values;
+    }
+
+
+    protected void putValueIfRequired() {
+        if(!memberRepType.hasValue(memberType)) {
+            return;
+        } 
+        representation.put("value", valueRep());
+        return;
+    }
+
+    /**
+     * Members that can provide a value should override.
+     */
+    protected Object valueRep() {
+        return null;
+    }
+
+
+    protected final void putDisabledReason() {
+        String disabledReasonRep = usability().getReason();
+        representation.put("disabledReason", disabledReasonRep);
+    }
+
+    protected void putDetailsIfRequired() {
+        if(!memberRepType.hasLinkToDetails()) {
+            return;
+        } 
+        String urlForMember = urlForMember();
+        Representation detailsLink = LinkRepBuilder.newBuilder(repContext, "details", urlForMember).build();
+        representation.put("details", detailsLink);
+    }
+
+    /**
+     * 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 urlForObject() {
+        return DomainObjectRepBuilder.urlFor(objectAdapter, getOidStringifier());
+    }
+
+    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/viewer/restful/viewer2/src/main/java/org/apache/isis/viewer/restful/viewer2/resources/objects/ActionRepBuilder.java
URL: http://svn.apache.org/viewvc/incubator/isis/trunk/viewer/restful/viewer2/src/main/java/org/apache/isis/viewer/restful/viewer2/resources/objects/ActionRepBuilder.java?rev=1139496&view=auto
==============================================================================
--- incubator/isis/trunk/viewer/restful/viewer2/src/main/java/org/apache/isis/viewer/restful/viewer2/resources/objects/ActionRepBuilder.java (added)
+++ incubator/isis/trunk/viewer/restful/viewer2/src/main/java/org/apache/isis/viewer/restful/viewer2/resources/objects/ActionRepBuilder.java Sat Jun 25 06:58:00 2011
@@ -0,0 +1,64 @@
+/**
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+package org.apache.isis.viewer.restful.viewer2.resources.objects;
+
+import java.util.List;
+
+import org.apache.isis.core.metamodel.adapter.ObjectAdapter;
+import org.apache.isis.core.metamodel.spec.feature.ObjectAction;
+import org.apache.isis.viewer.restful.viewer2.RepContext;
+import org.apache.isis.viewer.restful.viewer2.representations.Representation;
+
+import com.google.common.collect.Lists;
+
+public class ActionRepBuilder extends AbstractMemberRepBuilder<ObjectAction> {
+
+    public static ActionRepBuilder newBuilder(RepContext repContext, ObjectAdapter objectAdapter, ObjectAction oa) {
+        return new ActionRepBuilder(repContext, objectAdapter, oa);
+    }
+
+    public ActionRepBuilder(RepContext repContext, ObjectAdapter objectAdapter, ObjectAction oa) {
+        super(repContext, objectAdapter, MemberType.ACTION, oa);
+    }
+
+    public Representation build() {
+        putSelfIfRequired();
+        putTypeRep();
+        putMemberTypeRep();
+        representation.put("actionType", objectMember.getType());
+        representation.put("numParameters", objectMember.getParameterCount());
+        putValueIfRequired();
+        putDisabledReason();
+        putMutatorsIfRequired();
+        putDetailsIfRequired();
+        return representation;
+    }
+    
+    protected List<String> mutatorArgValues(MutatorSpec mutatorSpec) {
+        List<String> values = Lists.newArrayList();
+        for(int i=0; i<objectMember.getParameterCount(); i++) {
+            values.add(argValueFor(i)); 
+        }
+        return values;
+    }
+
+    // TODO: expect in future to provide values for contributed actions.
+    private String argValueFor(int i) {
+        return "{arg" + i + "}";
+    }
+
+}
\ No newline at end of file

Added: incubator/isis/trunk/viewer/restful/viewer2/src/main/java/org/apache/isis/viewer/restful/viewer2/resources/objects/CollectionRepBuilder.java
URL: http://svn.apache.org/viewvc/incubator/isis/trunk/viewer/restful/viewer2/src/main/java/org/apache/isis/viewer/restful/viewer2/resources/objects/CollectionRepBuilder.java?rev=1139496&view=auto
==============================================================================
--- incubator/isis/trunk/viewer/restful/viewer2/src/main/java/org/apache/isis/viewer/restful/viewer2/resources/objects/CollectionRepBuilder.java (added)
+++ incubator/isis/trunk/viewer/restful/viewer2/src/main/java/org/apache/isis/viewer/restful/viewer2/resources/objects/CollectionRepBuilder.java Sat Jun 25 06:58:00 2011
@@ -0,0 +1,79 @@
+/**
+ *  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.restful.viewer2.resources.objects;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.isis.core.metamodel.adapter.ObjectAdapter;
+import org.apache.isis.core.metamodel.facets.collections.modify.CollectionFacet;
+import org.apache.isis.core.metamodel.facets.collections.modify.CollectionFacetUtils;
+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.feature.OneToManyAssociation;
+import org.apache.isis.core.progmodel.facets.CollectionUtils;
+import org.apache.isis.viewer.restful.viewer2.RepContext;
+import org.apache.isis.viewer.restful.viewer2.representations.LinkRepBuilder;
+import org.apache.isis.viewer.restful.viewer2.representations.Representation;
+
+import com.google.common.collect.Lists;
+
+public class CollectionRepBuilder extends AbstractMemberRepBuilder<OneToManyAssociation> {
+
+    public static CollectionRepBuilder newBuilder(RepContext repContext, ObjectAdapter objectAdapter, OneToManyAssociation otma) {
+        return new CollectionRepBuilder(repContext, objectAdapter, otma);
+    }
+
+    public CollectionRepBuilder(RepContext repContext, ObjectAdapter objectAdapter, OneToManyAssociation otma) {
+        super(repContext, objectAdapter, MemberType.COLLECTION, otma);
+    }
+
+    public Representation build() {
+        putSelfIfRequired();
+        putTypeRep();
+        putMemberTypeRep();
+        putValueIfRequired();
+        putDisabledReason();
+        putMutatorsIfRequired();
+        putDetailsIfRequired();
+        return representation;
+    }
+
+    protected List<String> mutatorArgValues(MutatorSpec mutatorSpec) {
+        List<String> values = Lists.newArrayList();
+        values.add(null);
+        return values;
+    }
+
+    @Override
+    protected Object valueRep() {
+        ObjectAdapter valueAdapter = objectMember.get(objectAdapter);
+        if(valueAdapter == null) {
+            return null;
+        }
+        final CollectionFacet facet = CollectionFacetUtils.getCollectionFacetFromSpec(valueAdapter);
+        List<Representation> list = Lists.newArrayList();
+        for (final ObjectAdapter elementAdapter : facet.iterable(valueAdapter)) {
+            String url = DomainObjectRepBuilder.urlFor(elementAdapter, getOidStringifier());
+            list.add(LinkRepBuilder.newBuilder(repContext, "value", url).build());
+        }
+        
+        return list;
+    }
+
+}
\ No newline at end of file

Modified: incubator/isis/trunk/viewer/restful/viewer2/src/main/java/org/apache/isis/viewer/restful/viewer2/resources/objects/DomainObjectRepBuilder.java
URL: http://svn.apache.org/viewvc/incubator/isis/trunk/viewer/restful/viewer2/src/main/java/org/apache/isis/viewer/restful/viewer2/resources/objects/DomainObjectRepBuilder.java?rev=1139496&r1=1139495&r2=1139496&view=diff
==============================================================================
--- incubator/isis/trunk/viewer/restful/viewer2/src/main/java/org/apache/isis/viewer/restful/viewer2/resources/objects/DomainObjectRepBuilder.java (original)
+++ incubator/isis/trunk/viewer/restful/viewer2/src/main/java/org/apache/isis/viewer/restful/viewer2/resources/objects/DomainObjectRepBuilder.java Sat Jun 25 06:58:00 2011
@@ -16,10 +16,16 @@
  */
 package org.apache.isis.viewer.restful.viewer2.resources.objects;
 
+import java.util.List;
 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.spec.feature.ObjectAction;
+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.restful.viewer2.RepContext;
 import org.apache.isis.viewer.restful.viewer2.representations.LinkRepBuilder;
 import org.apache.isis.viewer.restful.viewer2.representations.Representation;
@@ -28,7 +34,7 @@ import org.apache.isis.viewer.restful.vi
 import com.google.common.base.Function;
 import com.google.common.collect.Maps;
 
-public class DomainObjectRepBuilder extends RepresentationBuilder{
+public class DomainObjectRepBuilder extends RepresentationBuilder {
 
     public static DomainObjectRepBuilder newBuilder(RepContext representationContext, ObjectAdapter objectAdapter) {
         return new DomainObjectRepBuilder(representationContext, objectAdapter);
@@ -44,16 +50,17 @@ public class DomainObjectRepBuilder exte
     
     public Representation build() {
         RepContext repContext = this.repContext.underAttribute("_self");
-        Representation selfLink = LinkRepBuilder.newBuilder(repContext, "link", urlFor(objectAdapter)).build();
+        Representation selfLink = LinkRepBuilder.newBuilder(repContext, "link", url()).build();
         Representation selfType = LinkRepBuilder.newTypeBuilder(repContext, "type", objectAdapter.getSpecification()).build();
         String title = objectAdapter.titleString();
-        Representation iconLink = LinkRepBuilder.newBuilder(repContext, "icon", iconFor(objectAdapter)).build();
+        Representation iconLink = LinkRepBuilder.newBuilder(repContext, "icon", icon()).build();
         Representation self = new Representation();
         self.put("link", selfLink);
         self.put("type", selfType);
         self.put("title", title);
         self.put("icon", iconLink);
         representation.put("_self", self);
+        withAllMembers(objectAdapter);
         if(!members.isEmpty()) {
             for(Map.Entry<String, Representation> entry: members.entrySet()) {
                 String memberId = entry.getKey();
@@ -64,25 +71,67 @@ public class DomainObjectRepBuilder exte
         return representation;
     }
 
-    public void withProperty(String id, Representation propertyRep) {
-        members.put(id, propertyRep);
-    }
-
-    private String iconFor(ObjectAdapter objectAdapter) {
+    private String icon() {
         String iconName = objectAdapter.getIconName();
         return "images/" + iconName + ".png";
     }
 
-    private String urlFor(ObjectAdapter objectAdapter) {
+    private String url() {
         OidStringifier oidStringifier = getOidStringifier();
         return urlFor(objectAdapter, oidStringifier);
     }
 
+    private void withAllMembers(final ObjectAdapter objectAdapter) {
+        List<ObjectAssociation> associations = objectAdapter.getSpecification().getAssociations();
+        for (ObjectAssociation assoc : associations) {
+            Consent visibility = assoc.isVisible(getSession(), objectAdapter);
+            if(!visibility.isAllowed()) {
+                continue;
+            } 
+            String id = assoc.getId();
+            if(assoc instanceof OneToOneAssociation) {
+                OneToOneAssociation property = (OneToOneAssociation)assoc;
+                Representation propertyRep = PropertyRepBuilder.newBuilder(repContext.underAttribute(id), objectAdapter, property).build();
+                withMember(id, propertyRep);
+            }
+            if(assoc instanceof OneToManyAssociation) {
+                OneToManyAssociation collection = (OneToManyAssociation) assoc;
+                Representation collectionRep = CollectionRepBuilder.newBuilder(repContext.underAttribute(id), objectAdapter, collection).build();
+                withMember(id, collectionRep);
+            }
+        }
+        
+        List<ObjectAction> actions = objectAdapter.getSpecification().getObjectActionsAll();
+        for (ObjectAction action : actions) {
+            Consent visibility = action.isVisible(getSession(), objectAdapter);
+            if(!visibility.isAllowed()) {
+                continue;
+            } 
+            String id = action.getId();
+            Representation actionRep = ActionRepBuilder.newBuilder(repContext.underAttribute(id), objectAdapter, action).build();
+            withMember(id, actionRep);
+        }
+    }
+
+    private void withMember(String id, Representation propertyRep) {
+        members.put(id, propertyRep);
+    }
+    
+
+    /////////////////////////////////////////////////////////////////////
+    //
+    /////////////////////////////////////////////////////////////////////
+    
     public static String urlFor(ObjectAdapter objectAdapter, OidStringifier oidStringifier) {
         String oidStr = oidStringifier.enString(objectAdapter.getOid());
         return "objects/" + oidStr;
     }
 
+    
+    /////////////////////////////////////////////////////////////////////
+    //
+    /////////////////////////////////////////////////////////////////////
+
     public static Function<ObjectAdapter, Representation> fromAdapter(final RepContext repContext) {
         return new Function<ObjectAdapter, Representation>() {
             @Override

Modified: incubator/isis/trunk/viewer/restful/viewer2/src/main/java/org/apache/isis/viewer/restful/viewer2/resources/objects/DomainObjectResourceImpl.java
URL: http://svn.apache.org/viewvc/incubator/isis/trunk/viewer/restful/viewer2/src/main/java/org/apache/isis/viewer/restful/viewer2/resources/objects/DomainObjectResourceImpl.java?rev=1139496&r1=1139495&r2=1139496&view=diff
==============================================================================
--- incubator/isis/trunk/viewer/restful/viewer2/src/main/java/org/apache/isis/viewer/restful/viewer2/resources/objects/DomainObjectResourceImpl.java (original)
+++ incubator/isis/trunk/viewer/restful/viewer2/src/main/java/org/apache/isis/viewer/restful/viewer2/resources/objects/DomainObjectResourceImpl.java Sat Jun 25 06:58:00 2011
@@ -20,6 +20,7 @@ import java.io.InputStream;
 import java.util.List;
 
 import javax.ws.rs.DELETE;
+import javax.ws.rs.FormParam;
 import javax.ws.rs.GET;
 import javax.ws.rs.POST;
 import javax.ws.rs.PUT;
@@ -29,95 +30,193 @@ 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.Status;
 
 import org.apache.isis.core.metamodel.adapter.ObjectAdapter;
-import org.apache.isis.core.metamodel.consent.Consent;
+import org.apache.isis.core.metamodel.spec.feature.ObjectAction;
 import org.apache.isis.core.metamodel.spec.feature.ObjectAssociation;
 import org.apache.isis.core.metamodel.spec.feature.ObjectAssociationFilters;
+import org.apache.isis.core.metamodel.spec.feature.OneToManyAssociation;
 import org.apache.isis.core.metamodel.spec.feature.OneToOneAssociation;
-import org.apache.isis.viewer.restful.applib2.resources.ObjectResource;
+import org.apache.isis.viewer.restful.applib2.resources.DomainObjectResource;
 import org.apache.isis.viewer.restful.viewer2.representations.Representation;
+import org.apache.isis.viewer.restful.viewer2.representations.RepresentationBuilder;
 import org.apache.isis.viewer.restful.viewer2.resources.ResourceAbstract;
 import org.apache.isis.viewer.restful.viewer2.util.UrlDecoderUtils;
 
 @Path("/objects")
-public class DomainObjectResourceImpl extends ResourceAbstract implements ObjectResource {
+public class DomainObjectResourceImpl extends ResourceAbstract implements DomainObjectResource {
 
     @GET
     @Path("/{oid}")
     @Produces({ MediaType.APPLICATION_JSON })
-    public String object(@PathParam("oid") final String oidEncodedStr) {
+    public String object(@PathParam("oid") final String oidStr) {
         init();
-        final String oidStr = UrlDecoderUtils.urlDecode(oidEncodedStr);
-
         final ObjectAdapter objectAdapter = getObjectAdapter(oidStr);
-        if (objectAdapter == null) {
-            throw new WebApplicationException(responseOfGone("could not determine object"));
-        }
 
         DomainObjectRepBuilder builder = DomainObjectRepBuilder.newBuilder(getResourceContext().repContext(), objectAdapter);
-        
-        List<ObjectAssociation> properties = objectAdapter.getSpecification().getAssociations(ObjectAssociationFilters.PROPERTIES);
-        for (ObjectAssociation otoa : properties) {
-            Consent visibility = otoa.isVisible(getSession(), objectAdapter);
-            if(visibility.isAllowed()) {
-                String id = otoa.getId();
-                Representation propertyRep = PropertyRepBuilder.newBuilder(getResourceContext().repContext(id), objectAdapter, (OneToOneAssociation)otoa).build();
-                builder.withProperty(id, propertyRep);
-            }
+        return jsonRepresentionFrom(builder);
+    }
+
+    @GET
+    @Path("/{oid}/properties/{propertyId}")
+    @Produces({ MediaType.APPLICATION_JSON })
+    public String propertyDetails(
+        @PathParam("oid") final String oidStr,
+        @PathParam("propertyId") final String propertyId) {
+
+        init();
+        final ObjectAdapter objectAdapter = getObjectAdapter(oidStr);
+        ObjectAssociation association = objectAdapter.getSpecification().getAssociation(propertyId);
+        if(association == null || !association.isOneToOneAssociation()) { 
+            throwPropertyNotFoundException(propertyId);
         }
-        
-        Representation representation = builder.build();
-        return asJson(representation);
+        OneToOneAssociation property = (OneToOneAssociation) association;
+        PropertyRepBuilder builder = PropertyRepBuilder.newBuilder(getResourceContext().repContext(), objectAdapter, property);
+        if(!builder.isMemberVisible()) {
+            throwPropertyNotFoundException(propertyId);
+        }
+
+        return jsonRepresentionFrom(builder);
     }
 
     @PUT
-    @Path("/{oid}/property/{propertyId}")
+    @Path("/{oid}/properties/{propertyId}")
     @Produces({ MediaType.APPLICATION_JSON })
-    public String modifyProperty(@PathParam("oid") final String oidStr,
-        @PathParam("propertyId") final String propertyId, @QueryParam("proposedValue") final String proposedValue) {
+    public String modifyProperty(
+        @PathParam("oid") final String oidEncodedStr,
+        @PathParam("propertyId") final String propertyId, 
+        @FormParam("proposedValue") final String proposedValue) {
+
+        init();
+        final String oidStr = UrlDecoderUtils.urlDecode(oidEncodedStr);
+
         return null;
     }
 
     @DELETE
-    @Path("/{oid}/property/{propertyId}")
+    @Path("/{oid}/properties/{propertyId}")
     @Produces({ MediaType.APPLICATION_JSON })
-    public String clearProperty(@PathParam("oid") final String oidStr, @PathParam("propertyId") final String propertyId){
+    public String clearProperty(
+        @PathParam("oid") final String oidStr, 
+        @PathParam("propertyId") final String propertyId){
+        
         return null;
     }
 
     @GET
-    @Path("/{oid}/collection/{collectionId}")
+    @Path("/{oid}/collections/{collectionId}")
     @Produces({ MediaType.APPLICATION_JSON })
-    public String accessCollection(@PathParam("oid") final String oidStr,
+    public String accessCollection(
+        @PathParam("oid") final String oidStr,
         @PathParam("collectionId") final String collectionId){
-        return null;
+        
+        init();
+        final ObjectAdapter objectAdapter = getObjectAdapter(oidStr);
+        ObjectAssociation association = objectAdapter.getSpecification().getAssociation(collectionId);
+        if(association == null || !association.isOneToManyAssociation()) {
+            throwCollectionNotFoundException(collectionId);
+        }
+        OneToManyAssociation collection = (OneToManyAssociation) association;
+        CollectionRepBuilder builder = CollectionRepBuilder.newBuilder(getResourceContext().repContext(), objectAdapter, collection);
+        if(!builder.isMemberVisible()) {
+            throwCollectionNotFoundException(collectionId);
+        }
+
+        return jsonRepresentionFrom(builder);
     }
 
     @PUT
-    @Path("/{oid}/collection/{collectionId}")
+    @Path("/{oid}/collections/{collectionId}")
     @Produces({ MediaType.APPLICATION_JSON })
-    public String addToCollection(@PathParam("oid") final String oidStr,
+    public String addToCollection(
+        @PathParam("oid") final String oidStr,
         @PathParam("collectionId") final String collectionId,
-        @QueryParam("proposedValue") final String proposedValueOidStr){
+        @FormParam("proposedValue") final String proposedValueOidStr){
+        
         return null;
     }
 
     @DELETE
-    @Path("/{oid}/collection/{collectionId}")
+    @Path("/{oid}/collections/{collectionId}")
     @Produces({ MediaType.APPLICATION_JSON })
-    public String removeFromCollection(@PathParam("oid") final String oidStr,
+    public String removeFromCollection(
+        @PathParam("oid") final String oidStr,
         @PathParam("collectionId") final String collectionId,
-        @QueryParam("proposedValue") final String proposedValueOidStr){
+        @FormParam("proposedValue") final String proposedValueOidStr){
+        
         return null;
     }
 
+    @GET
+    @Path("/{oid}/actions/{actionId}")
+    @Produces({ MediaType.APPLICATION_JSON })
+    public String actionPrompt(
+        @PathParam("oid") final String oidStr, 
+        @PathParam("actionId") final String actionId) {
+
+        init();
+        final ObjectAdapter objectAdapter = getObjectAdapter(oidStr);
+        ObjectAction action = objectAdapter.getSpecification().getObjectAction(actionId);
+        if(action == null) {
+            throwActionNotFoundException(actionId);
+        }
+        ActionRepBuilder builder = ActionRepBuilder.newBuilder(getResourceContext().repContext(), objectAdapter, action);
+        if(!builder.isMemberVisible()) {
+            throwActionNotFoundException(actionId);
+        }
+
+        return jsonRepresentionFrom(builder);
+    }
+
     @POST
-    @Path("/{oid}/action/{actionId}")
+    @Path("/{oid}/actions/{actionId}/invoke")
     @Produces({ MediaType.APPLICATION_JSON })
-    public String invokeAction(@PathParam("oid") final String oidStr, @PathParam("actionId") final String actionId,
+    public String invokeAction(
+        @PathParam("oid") final String oidStr, 
+        @PathParam("actionId") final String actionId,
         final InputStream body){
+
+        return null;
+    }
+
+
+    @GET
+    @Path("/{oid}/actions/{actionId}/invoke")
+    @Produces({ MediaType.APPLICATION_JSON })
+    public String invokeActionIdempotent(
+        @PathParam("oid") String oidStr, 
+        @PathParam("actionId") String actionId, 
+        @QueryParam("argument") List<String> arguments) {
+
         return null;
     }
 
+
+    
+    /////////////////////////////////////////////////////////////////////
+    
+    private void throwPropertyNotFoundException(final String propertyId) {
+        throwNotFoundException(propertyId, MemberType.PROPERTY);
+    }
+
+    private void throwCollectionNotFoundException(final String collectionId) {
+        throwNotFoundException(collectionId, MemberType.COLLECTION);
+    }
+
+    private void throwActionNotFoundException(final String actionId) {
+        throwNotFoundException(actionId, MemberType.ACTION);
+    }
+
+
+    private void throwNotFoundException(final String propertyId, MemberType memberType) {
+        String memberTypeStr = memberType.name().toLowerCase();
+        throw new WebApplicationException(responseOfNotFound("No such " +
+                memberTypeStr +
+                "/" +
+                memberTypeStr +
+                " not visible: '" + propertyId + "'"));
+    }
+
+
 }

Added: incubator/isis/trunk/viewer/restful/viewer2/src/main/java/org/apache/isis/viewer/restful/viewer2/resources/objects/MemberRepType.java
URL: http://svn.apache.org/viewvc/incubator/isis/trunk/viewer/restful/viewer2/src/main/java/org/apache/isis/viewer/restful/viewer2/resources/objects/MemberRepType.java?rev=1139496&view=auto
==============================================================================
--- incubator/isis/trunk/viewer/restful/viewer2/src/main/java/org/apache/isis/viewer/restful/viewer2/resources/objects/MemberRepType.java (added)
+++ incubator/isis/trunk/viewer/restful/viewer2/src/main/java/org/apache/isis/viewer/restful/viewer2/resources/objects/MemberRepType.java Sat Jun 25 06:58:00 2011
@@ -0,0 +1,61 @@
+/**
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+package org.apache.isis.viewer.restful.viewer2.resources.objects;
+
+import org.apache.isis.core.metamodel.spec.feature.ObjectMember;
+import org.apache.isis.viewer.restful.applib2.resources.DomainObjectResource;
+
+/**
+ * Whether the representation of an {@link ObjectMember} (as generated by
+ * the subclasses of {@link AbstractMemberRepBuilder}) is to be a {@link #STANDALONE} (eg
+ * for {@link DomainObjectResource#propertyDetails(String, String)}, 
+ * {@link DomainObjectResource#accessCollection(String, String)}, or
+ * {@link DomainObjectResource#actionPrompt(String, String)}), or is
+ * {@link #INLINE} within the representation of the {@link DomainObjectResource#object(String)}).
+ * 
+ * <p>
+ * {@link #STANDALONE Standalone} representations are more detailed (eg contain links to
+ * describe how to modify the member), while {@link #INLINE inlined} representations
+ * contain links to the {@link #STANDALONE} representation. 
+ */
+public enum MemberRepType {
+    
+    STANDALONE,
+    INLINE;
+
+    public boolean hasSelf() {
+        return this == STANDALONE;
+    }
+
+    public boolean hasMutators() {
+        return this == STANDALONE;
+    }
+
+    public boolean hasLinkToDetails() {
+        return this == INLINE;
+    }
+
+    public boolean hasValue(MemberType memberType) {
+        return memberType.isProperty() || memberType.isCollection() && isStandalone();
+    }
+
+    private boolean isStandalone() {
+        return this == STANDALONE;
+    }
+
+
+}

Modified: incubator/isis/trunk/viewer/restful/viewer2/src/main/java/org/apache/isis/viewer/restful/viewer2/resources/objects/MemberSelfRepBuilder.java
URL: http://svn.apache.org/viewvc/incubator/isis/trunk/viewer/restful/viewer2/src/main/java/org/apache/isis/viewer/restful/viewer2/resources/objects/MemberSelfRepBuilder.java?rev=1139496&r1=1139495&r2=1139496&view=diff
==============================================================================
--- incubator/isis/trunk/viewer/restful/viewer2/src/main/java/org/apache/isis/viewer/restful/viewer2/resources/objects/MemberSelfRepBuilder.java (original)
+++ incubator/isis/trunk/viewer/restful/viewer2/src/main/java/org/apache/isis/viewer/restful/viewer2/resources/objects/MemberSelfRepBuilder.java Sat Jun 25 06:58:00 2011
@@ -19,10 +19,6 @@ package org.apache.isis.viewer.restful.v
 import org.apache.isis.core.metamodel.adapter.ObjectAdapter;
 import org.apache.isis.core.metamodel.adapter.oid.stringable.OidStringifier;
 import org.apache.isis.core.metamodel.spec.feature.ObjectMember;
-import org.apache.isis.core.metamodel.spec.feature.OneToOneAssociation;
-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.restful.viewer2.RepContext;
 import org.apache.isis.viewer.restful.viewer2.representations.LinkRepBuilder;
 import org.apache.isis.viewer.restful.viewer2.representations.Representation;
@@ -30,21 +26,35 @@ import org.apache.isis.viewer.restful.vi
 
 public class MemberSelfRepBuilder extends RepresentationBuilder {
 
-    public static MemberSelfRepBuilder newBuilder(RepContext repContext, ObjectAdapter objectAdapter, OneToOneAssociation otoa) {
-        return new MemberSelfRepBuilder(repContext, objectAdapter, otoa);
+    public static MemberSelfRepBuilder newBuilder(RepContext repContext, ObjectAdapter objectAdapter, MemberType memberType, ObjectMember objectMember) {
+        return new MemberSelfRepBuilder(repContext, objectAdapter, memberType, objectMember);
     }
 
     private final ObjectAdapter objectAdapter;
+    private final MemberType memberType;
     private final ObjectMember objectMember;
 
-    public MemberSelfRepBuilder(RepContext repContext, ObjectAdapter objectAdapter, ObjectMember objectMember) {
+    public MemberSelfRepBuilder(RepContext repContext, ObjectAdapter objectAdapter, MemberType memberType, ObjectMember objectMember) {
         super(repContext);
         this.objectAdapter = objectAdapter;
+        this.memberType = memberType;
         this.objectMember = objectMember;
     }
     
     public Representation build() {
-        representation.put("link", LinkRepBuilder.newBuilder(repContext, "link", DomainObjectRepBuilder.urlFor(objectAdapter, getOidStringifier())).build());
+        representation.put("link", memberLinkRep());
+        representation.put("object", domainObjectLinkRep());
         return representation;
     }
+
+    private Representation memberLinkRep() {
+        String url = AbstractMemberRepBuilder.urlForMember(objectAdapter, memberType, objectMember, getOidStringifier());
+        return LinkRepBuilder.newBuilder(repContext, "link", url).build();
+    }
+    
+    private Representation domainObjectLinkRep() {
+        String url = DomainObjectRepBuilder.urlFor(objectAdapter, getOidStringifier());
+        return LinkRepBuilder.newBuilder(repContext, "object", url).build();
+    }
+
 }
\ No newline at end of file

Added: incubator/isis/trunk/viewer/restful/viewer2/src/main/java/org/apache/isis/viewer/restful/viewer2/resources/objects/MemberType.java
URL: http://svn.apache.org/viewvc/incubator/isis/trunk/viewer/restful/viewer2/src/main/java/org/apache/isis/viewer/restful/viewer2/resources/objects/MemberType.java?rev=1139496&view=auto
==============================================================================
--- incubator/isis/trunk/viewer/restful/viewer2/src/main/java/org/apache/isis/viewer/restful/viewer2/resources/objects/MemberType.java (added)
+++ incubator/isis/trunk/viewer/restful/viewer2/src/main/java/org/apache/isis/viewer/restful/viewer2/resources/objects/MemberType.java Sat Jun 25 06:58:00 2011
@@ -0,0 +1,97 @@
+/**
+ *  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.restful.viewer2.resources.objects;
+
+import java.util.Map;
+
+import org.apache.isis.core.metamodel.facets.actions.invoke.ActionInvocationFacet;
+import org.apache.isis.core.metamodel.facets.collections.modify.CollectionAddToFacet;
+import org.apache.isis.core.metamodel.facets.collections.modify.CollectionRemoveFromFacet;
+import org.apache.isis.core.metamodel.facets.properties.modify.PropertyClearFacet;
+import org.apache.isis.core.metamodel.facets.properties.modify.PropertySetterFacet;
+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.ObjectMember;
+import org.apache.isis.core.progmodel.facets.actions.validate.ActionValidationFacet;
+import org.apache.isis.core.progmodel.facets.collections.validate.CollectionValidateAddToFacet;
+import org.apache.isis.core.progmodel.facets.collections.validate.CollectionValidateRemoveFromFacet;
+import org.apache.isis.core.progmodel.facets.properties.validate.PropertyValidateFacet;
+import org.apache.isis.viewer.restful.viewer2.representations.HttpMethod;
+
+import com.google.common.collect.ImmutableMap;
+
+public enum MemberType {
+
+    PROPERTY("properties/", ImmutableMap.of(
+            "modify", MutatorSpec.of(PropertyValidateFacet.class, PropertySetterFacet.class, HttpMethod.PUT, BodyArgs.ONE),
+            "clear", MutatorSpec.of(PropertyValidateFacet.class, PropertyClearFacet.class, HttpMethod.DELETE, BodyArgs.NONE)
+            )) {
+        @Override
+        public ObjectSpecification specFor(ObjectMember objectMember) {
+            return objectMember.getSpecification();
+        }
+    },
+    COLLECTION("collections/", ImmutableMap.of(
+            "addTo", MutatorSpec.of(CollectionValidateAddToFacet.class, CollectionAddToFacet.class, HttpMethod.PUT, BodyArgs.ONE),
+            "removeFrom", MutatorSpec.of(CollectionValidateRemoveFromFacet.class, CollectionRemoveFromFacet.class, HttpMethod.DELETE, BodyArgs.ONE)
+            )) {
+        @Override
+        public ObjectSpecification specFor(ObjectMember objectMember) {
+            return objectMember.getSpecification();
+        }
+    },
+    ACTION("actions/", ImmutableMap.of(
+            "invoke", MutatorSpec.of(ActionValidationFacet.class, ActionInvocationFacet.class, HttpMethod.PUT, BodyArgs.MANY, "invoke")
+            )) {
+        @Override
+        public ObjectSpecification specFor(ObjectMember objectMember) {
+            ObjectAction objectAction = (ObjectAction) objectMember;
+            return objectAction.getReturnType();
+        }
+    };
+
+    private final Map<String, MutatorSpec> mutators;
+    
+    private final String urlPart;
+    private MemberType(String urlPart, Map<String, MutatorSpec> mutators) {
+        this.urlPart = urlPart;
+        this.mutators = mutators;
+    }
+
+    public String urlPart() {
+        return urlPart;
+    }
+    
+    public Map<String, MutatorSpec> getMutators() {
+        return mutators;
+    }
+    
+    public abstract ObjectSpecification specFor(ObjectMember objectMember);
+
+    public boolean isProperty() {
+        return this == MemberType.PROPERTY;
+    }
+
+    public boolean isCollection() {
+        return this == MemberType.COLLECTION;
+    }
+
+    public boolean isAction() {
+        return this == MemberType.ACTION;
+    }
+
+}

Added: incubator/isis/trunk/viewer/restful/viewer2/src/main/java/org/apache/isis/viewer/restful/viewer2/resources/objects/MutatorSpec.java
URL: http://svn.apache.org/viewvc/incubator/isis/trunk/viewer/restful/viewer2/src/main/java/org/apache/isis/viewer/restful/viewer2/resources/objects/MutatorSpec.java?rev=1139496&view=auto
==============================================================================
--- incubator/isis/trunk/viewer/restful/viewer2/src/main/java/org/apache/isis/viewer/restful/viewer2/resources/objects/MutatorSpec.java (added)
+++ incubator/isis/trunk/viewer/restful/viewer2/src/main/java/org/apache/isis/viewer/restful/viewer2/resources/objects/MutatorSpec.java Sat Jun 25 06:58:00 2011
@@ -0,0 +1,47 @@
+/**
+ *  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.restful.viewer2.resources.objects;
+
+import org.apache.isis.core.metamodel.facetapi.Facet;
+import org.apache.isis.viewer.restful.viewer2.representations.HttpMethod;
+
+public class MutatorSpec {
+
+    
+    public static MutatorSpec of(Class<? extends Facet> validationFacetType, Class<? extends Facet> mutatorFacetType, HttpMethod httpMethod, BodyArgs argSpec) {
+        return of(validationFacetType, mutatorFacetType, httpMethod, argSpec, null);
+    }
+
+    public static MutatorSpec of(Class<? extends Facet> validationFacetType, Class<? extends Facet> mutatorFacetType, HttpMethod httpMethod, BodyArgs argSpec, String suffix) {
+        return new MutatorSpec(validationFacetType, mutatorFacetType, httpMethod, argSpec, suffix);
+    }
+
+    public final Class<? extends Facet> validationFacetType;
+    public final Class<? extends Facet> mutatorFacetType;
+    public final HttpMethod httpMethod;
+    public final String suffix;
+    public final BodyArgs argSpec;
+
+    private MutatorSpec(Class<? extends Facet> validationFacetType, Class<? extends Facet> mutatorFacetType, HttpMethod httpMethod, BodyArgs argSpec, String suffix) {
+        this.validationFacetType = validationFacetType;
+        this.mutatorFacetType = mutatorFacetType;
+        this.httpMethod = httpMethod;
+        this.argSpec = argSpec;
+        this.suffix = suffix;
+    }
+
+}
\ No newline at end of file

Modified: incubator/isis/trunk/viewer/restful/viewer2/src/main/java/org/apache/isis/viewer/restful/viewer2/resources/objects/PropertyRepBuilder.java
URL: http://svn.apache.org/viewvc/incubator/isis/trunk/viewer/restful/viewer2/src/main/java/org/apache/isis/viewer/restful/viewer2/resources/objects/PropertyRepBuilder.java?rev=1139496&r1=1139495&r2=1139496&view=diff
==============================================================================
--- incubator/isis/trunk/viewer/restful/viewer2/src/main/java/org/apache/isis/viewer/restful/viewer2/resources/objects/PropertyRepBuilder.java (original)
+++ incubator/isis/trunk/viewer/restful/viewer2/src/main/java/org/apache/isis/viewer/restful/viewer2/resources/objects/PropertyRepBuilder.java Sat Jun 25 06:58:00 2011
@@ -16,90 +16,59 @@
  */
 package org.apache.isis.viewer.restful.viewer2.resources.objects;
 
+import java.util.List;
+
 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.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.ObjectSpecification;
+import org.apache.isis.core.metamodel.facets.properties.modify.PropertyClearFacet;
+import org.apache.isis.core.metamodel.facets.properties.modify.PropertySetterFacet;
 import org.apache.isis.core.metamodel.spec.feature.OneToOneAssociation;
 import org.apache.isis.viewer.restful.viewer2.RepContext;
-import org.apache.isis.viewer.restful.viewer2.representations.HttpMethod;
 import org.apache.isis.viewer.restful.viewer2.representations.LinkRepBuilder;
 import org.apache.isis.viewer.restful.viewer2.representations.Representation;
-import org.apache.isis.viewer.restful.viewer2.representations.RepresentationBuilder;
 
-public class PropertyRepBuilder extends RepresentationBuilder {
+import com.google.common.collect.BiMap;
+import com.google.common.collect.Lists;
+
+public class PropertyRepBuilder extends AbstractMemberRepBuilder<OneToOneAssociation> {
 
     public static PropertyRepBuilder newBuilder(RepContext repContext, ObjectAdapter objectAdapter, OneToOneAssociation otoa) {
         return new PropertyRepBuilder(repContext, objectAdapter, otoa);
     }
 
-
-    private final ObjectAdapter objectAdapter;
-    private final OneToOneAssociation otoa;
-
     public PropertyRepBuilder(RepContext repContext, ObjectAdapter objectAdapter, OneToOneAssociation otoa) {
-        super(repContext);
-        this.objectAdapter = objectAdapter;
-        this.otoa = otoa;
+        super(repContext, objectAdapter, MemberType.PROPERTY, otoa);
     }
 
     public Representation build() {
-        if(addSelf()) {
-            Representation selfLink = LinkRepBuilder.newBuilder(repContext, "link", urlFor(objectAdapter, otoa)).build();
-            selfLink.put("method", HttpMethod.GET);
-            Representation selfRep = MemberSelfRepBuilder.newBuilder(repContext, objectAdapter, otoa).build();
-            representation.put("self", selfRep);
-        }
-        Representation type = LinkRepBuilder.newTypeBuilder(repContext, "type", otoa.getSpecification()).build();
-        representation.put("type", type);
-        representation.put("value", obtainValue());
-        Consent usability = otoa.isUsable(getSession(), objectAdapter);
-        representation.put("disabledReason", usability.getReason());
-        Representation detailsLink = LinkRepBuilder.newBuilder(repContext, "details", urlFor(objectAdapter, otoa)).build(); // TODO: same as self.link ???
-        representation.put("details", detailsLink);
+        putSelfIfRequired();
+        putTypeRep();
+        putMemberTypeRep();
+        putValueIfRequired();
+        putDisabledReason();
+        putMutatorsIfRequired();
+        putDetailsIfRequired();
         return representation;
     }
 
-    /**
-     * Only add the _self attribute if this representation is being
-     * generated in a context that is not 'under' an attribute of an
-     * owning {@link Representation representation}.
-     */
-    private boolean addSelf() {
-        return !repContext.hasAttribute();
-    }
 
-    private Object obtainValue() {
-        ObjectAdapter valueAdapter = otoa.get(objectAdapter);
+    @Override
+    protected Object valueRep() {
+        ObjectAdapter valueAdapter = objectMember.get(objectAdapter);
         if(valueAdapter == null) {
             return null;
         } 
-        ObjectSpecification otoaSpec = otoa.getSpecification();
-        ValueFacet valueFacet = otoaSpec.getFacet(ValueFacet.class);
+        ValueFacet valueFacet = getMemberSpecFacet(ValueFacet.class);
         if(valueFacet != null) {
-            EncodableFacet encodableFacet = otoaSpec.getFacet(EncodableFacet.class);
+            EncodableFacet encodableFacet = getMemberSpecFacet(EncodableFacet.class);
             return encodableFacet.toEncodedString(valueAdapter);
         } 
-        TitleFacet titleFacet = otoaSpec.getFacet(TitleFacet.class);
-        if (titleFacet == null) {
-            // fallback
-            titleFacet = otoaSpec.getFacet(TitleFacet.class);
-        }
+        TitleFacet titleFacet = getMemberSpecFacet(TitleFacet.class);
         String title = titleFacet.title(valueAdapter, getLocalization());
-        return LinkRepBuilder.newBuilder(repContext, "value", urlFor(valueAdapter)).withTitle(title).build();
-    }
-
-    private String urlFor(ObjectAdapter adapter) {
-        return DomainObjectRepBuilder.urlFor(adapter, getOidStringifier());
-    }
-
-    private String urlFor(ObjectAdapter objectAdapter, OneToOneAssociation otoa) {
-        OidStringifier oidStringifier = getOidStringifier();
-        String oidStr = oidStringifier.enString(objectAdapter.getOid());
-        return "objects/" + oidStr + "/property/" + otoa.getId();
+        return LinkRepBuilder.newBuilder(repContext, "value", urlForObject()).withTitle(title).build();
     }
 
 }
\ No newline at end of file

Modified: incubator/isis/trunk/viewer/restful/viewer2/src/main/java/org/apache/isis/viewer/restful/viewer2/resources/services/ServicesResourceImpl.java
URL: http://svn.apache.org/viewvc/incubator/isis/trunk/viewer/restful/viewer2/src/main/java/org/apache/isis/viewer/restful/viewer2/resources/services/ServicesResourceImpl.java?rev=1139496&r1=1139495&r2=1139496&view=diff
==============================================================================
--- incubator/isis/trunk/viewer/restful/viewer2/src/main/java/org/apache/isis/viewer/restful/viewer2/resources/services/ServicesResourceImpl.java (original)
+++ incubator/isis/trunk/viewer/restful/viewer2/src/main/java/org/apache/isis/viewer/restful/viewer2/resources/services/ServicesResourceImpl.java Sat Jun 25 06:58:00 2011
@@ -47,7 +47,7 @@ public class ServicesResourceImpl extend
     public String services() {
         init();
 
-        return asJsonList(serviceSelfRepresentations());
+        return asJson(serviceSelfRepresentations());
     }
 
     protected List<Representation> serviceSelfRepresentations() {

Modified: incubator/isis/trunk/viewer/restful/viewer2/src/main/java/org/apache/isis/viewer/restful/viewer2/util/OidUtils.java
URL: http://svn.apache.org/viewvc/incubator/isis/trunk/viewer/restful/viewer2/src/main/java/org/apache/isis/viewer/restful/viewer2/util/OidUtils.java?rev=1139496&r1=1139495&r2=1139496&view=diff
==============================================================================
--- incubator/isis/trunk/viewer/restful/viewer2/src/main/java/org/apache/isis/viewer/restful/viewer2/util/OidUtils.java (original)
+++ incubator/isis/trunk/viewer/restful/viewer2/src/main/java/org/apache/isis/viewer/restful/viewer2/util/OidUtils.java Sat Jun 25 06:58:00 2011
@@ -30,14 +30,14 @@ public final class OidUtils {
     private OidUtils() {
     }
 
-    public static ObjectAdapter getNakedObject(final String oidEncodedStr, final OidStringifier oidStringifier) {
+    public static ObjectAdapter getObjectAdapter(final String oidEncodedStr, final OidStringifier oidStringifier) {
         final String oidStr = UrlDecoderUtils.urlDecode(oidEncodedStr);
         final Oid oid = oidStringifier.deString(oidStr);
         return getAdapterManager().getAdapterFor(oid);
     }
 
-    public static String getOidStr(final ObjectAdapter nakedObject, final OidStringifier oidStringifier) {
-        final Oid oid = nakedObject.getOid();
+    public static String getOidStr(final ObjectAdapter objectAdapter, final OidStringifier oidStringifier) {
+        final Oid oid = objectAdapter.getOid();
         return oid != null ? oidStringifier.enString(oid) : null;
     }
 



Mime
View raw message