You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@isis.apache.org by da...@apache.org on 2011/07/13 00:38:09 UTC

svn commit: r1145803 - in /incubator/isis/trunk/framework/viewer/json: applib/src/main/java/org/apache/isis/viewer/json/applib/resources/ viewer/src/main/java/org/apache/isis/viewer/json/viewer/resources/ viewer/src/main/java/org/apache/isis/viewer/jso...

Author: danhaywood
Date: Tue Jul 12 22:38:08 2011
New Revision: 1145803

URL: http://svn.apache.org/viewvc?rev=1145803&view=rev
Log:
json viewer: added validation of action parameters; can now modify a property value

Modified:
    incubator/isis/trunk/framework/viewer/json/applib/src/main/java/org/apache/isis/viewer/json/applib/resources/DomainObjectResource.java
    incubator/isis/trunk/framework/viewer/json/viewer/src/main/java/org/apache/isis/viewer/json/viewer/resources/ResourceAbstract.java
    incubator/isis/trunk/framework/viewer/json/viewer/src/main/java/org/apache/isis/viewer/json/viewer/resources/objects/DomainObjectResourceImpl.java

Modified: incubator/isis/trunk/framework/viewer/json/applib/src/main/java/org/apache/isis/viewer/json/applib/resources/DomainObjectResource.java
URL: http://svn.apache.org/viewvc/incubator/isis/trunk/framework/viewer/json/applib/src/main/java/org/apache/isis/viewer/json/applib/resources/DomainObjectResource.java?rev=1145803&r1=1145802&r2=1145803&view=diff
==============================================================================
--- incubator/isis/trunk/framework/viewer/json/applib/src/main/java/org/apache/isis/viewer/json/applib/resources/DomainObjectResource.java (original)
+++ incubator/isis/trunk/framework/viewer/json/applib/src/main/java/org/apache/isis/viewer/json/applib/resources/DomainObjectResource.java Tue Jul 12 22:38:08 2011
@@ -72,7 +72,7 @@ public interface DomainObjectResource {
     @PUT
     @Path("/{oid}/properties{propertyId}")
     @Produces({ MediaType.APPLICATION_JSON })
-    public String modifyProperty(
+    public Object modifyProperty(
         @PathParam("oid") final String oidStr,
         @PathParam("propertyId") final String propertyId, 
         @FormParam("proposedValue") final String proposedValue);

Modified: incubator/isis/trunk/framework/viewer/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/viewer/src/main/java/org/apache/isis/viewer/json/viewer/resources/ResourceAbstract.java?rev=1145803&r1=1145802&r2=1145803&view=diff
==============================================================================
--- incubator/isis/trunk/framework/viewer/json/viewer/src/main/java/org/apache/isis/viewer/json/viewer/resources/ResourceAbstract.java (original)
+++ incubator/isis/trunk/framework/viewer/json/viewer/src/main/java/org/apache/isis/viewer/json/viewer/resources/ResourceAbstract.java Tue Jul 12 22:38:08 2011
@@ -65,7 +65,10 @@ import com.google.common.collect.Lists;
 
 public abstract class ResourceAbstract {
 
-    protected final static ObjectMapper objectMapper = new ObjectMapper();
+    private static final String HEADER_X_RESTFUL_OBJECTS_REASON = "X-RestfulObjects-Reason";
+
+
+	protected final static ObjectMapper objectMapper = new ObjectMapper();
     static {
         objectMapper.configure(SerializationConfig.Feature.INDENT_OUTPUT, true);
     }
@@ -237,7 +240,7 @@ public abstract class ResourceAbstract {
     }
 
     protected static Response responseOfGone(final String reason) {
-        return Response.status(Status.GONE).header("isis-reason", reason).build();
+        return Response.status(Status.GONE).header(HEADER_X_RESTFUL_OBJECTS_REASON, reason).build();
     }
 
     protected static Response responseOfBadRequest(final Consent consent) {
@@ -245,11 +248,11 @@ public abstract class ResourceAbstract {
     }
 
     protected static Response responseOfNoContent(final String reason) {
-        return Response.status(Status.NO_CONTENT).header("isis-reason", reason).build();
+        return Response.status(Status.NO_CONTENT).header(HEADER_X_RESTFUL_OBJECTS_REASON, reason).build();
     }
 
     protected static Response responseOfBadRequest(final String reason) {
-        return Response.status(Status.BAD_REQUEST).header("isis-reason", reason).build();
+        return Response.status(Status.BAD_REQUEST).header(HEADER_X_RESTFUL_OBJECTS_REASON, reason).build();
     }
 
     protected static Response responseOfNotFound(final IllegalArgumentException e) {
@@ -257,15 +260,15 @@ public abstract class ResourceAbstract {
     }
 
     protected static Response responseOfNotFound(final String reason) {
-        return Response.status(Status.NOT_FOUND).header("isis-reason", reason).build();
+        return Response.status(Status.NOT_FOUND).header(HEADER_X_RESTFUL_OBJECTS_REASON, reason).build();
     }
 
     protected static Response responseOfPreconditionFailed(final String reason) {
-        return Response.status(StatusTypes.PRECONDITION_FAILED).header("isis-reason", reason).build();
+        return Response.status(StatusTypes.PRECONDITION_FAILED).header(HEADER_X_RESTFUL_OBJECTS_REASON, reason).build();
     }
 
     protected static Response responseOfMethodNotAllowed(final String reason) {
-        return Response.status(StatusTypes.METHOD_NOT_ALLOWED).header("isis-reason", reason).build();
+        return Response.status(StatusTypes.METHOD_NOT_ALLOWED).header(HEADER_X_RESTFUL_OBJECTS_REASON, reason).build();
     }
 
     protected static Response responseOfInternalServerError(final Exception ex) {
@@ -273,7 +276,7 @@ public abstract class ResourceAbstract {
     }
 
     protected static Response responseOfInternalServerError(final String reason) {
-        return Response.status(Status.INTERNAL_SERVER_ERROR).header("isis-reason", reason).build();
+        return Response.status(Status.INTERNAL_SERVER_ERROR).header(HEADER_X_RESTFUL_OBJECTS_REASON, reason).build();
     }
 
     // //////////////////////////////////////////////////////////////

Modified: incubator/isis/trunk/framework/viewer/json/viewer/src/main/java/org/apache/isis/viewer/json/viewer/resources/objects/DomainObjectResourceImpl.java
URL: http://svn.apache.org/viewvc/incubator/isis/trunk/framework/viewer/json/viewer/src/main/java/org/apache/isis/viewer/json/viewer/resources/objects/DomainObjectResourceImpl.java?rev=1145803&r1=1145802&r2=1145803&view=diff
==============================================================================
--- incubator/isis/trunk/framework/viewer/json/viewer/src/main/java/org/apache/isis/viewer/json/viewer/resources/objects/DomainObjectResourceImpl.java (original)
+++ incubator/isis/trunk/framework/viewer/json/viewer/src/main/java/org/apache/isis/viewer/json/viewer/resources/objects/DomainObjectResourceImpl.java Tue Jul 12 22:38:08 2011
@@ -38,8 +38,11 @@ import javax.ws.rs.core.MediaType;
 
 import org.apache.isis.core.metamodel.adapter.ObjectAdapter;
 import org.apache.isis.core.metamodel.consent.Consent;
+import org.apache.isis.core.metamodel.consent.InteractionInvocationMethod;
 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.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.ObjectActionParameter;
@@ -47,6 +50,7 @@ import org.apache.isis.core.metamodel.sp
 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.core.progmodel.facets.properties.modify.PropertyModifyFacetFactory;
 import org.apache.isis.viewer.json.applib.resources.DomainObjectResource;
 import org.apache.isis.viewer.json.viewer.resources.ResourceAbstract;
 import org.apache.isis.viewer.json.viewer.util.UrlDecoderUtils;
@@ -81,10 +85,9 @@ public class DomainObjectResourceImpl ex
         @PathParam("propertyId") final String propertyId) {
     	
         final ObjectAdapter objectAdapter = getObjectAdapter(oidStr);
-        final OneToOneAssociation property = getProperty(objectAdapter, propertyId, Intent.ACCESS);
+        final OneToOneAssociation property = getPropertyThatIsVisibleAndUsable(objectAdapter, propertyId, Intent.ACCESS);
         
         final PropertyRepBuilder builder = PropertyRepBuilder.newBuilder(getResourceContext().repContext(), objectAdapter, property);
-
         return jsonRepresentionFrom(builder);
     }
 
@@ -96,10 +99,9 @@ public class DomainObjectResourceImpl ex
         @PathParam("collectionId") final String collectionId){
     	
         final ObjectAdapter objectAdapter = getObjectAdapter(oidStr);
-        final OneToManyAssociation collection = getCollection(objectAdapter, collectionId, Intent.ACCESS);
+        final OneToManyAssociation collection = getCollectionThatIsVisibleAndUsable(objectAdapter, collectionId, Intent.ACCESS);
         
         final CollectionRepBuilder builder = CollectionRepBuilder.newBuilder(getResourceContext().repContext(), objectAdapter, collection);
-
         return jsonRepresentionFrom(builder);
     }
 
@@ -111,10 +113,9 @@ public class DomainObjectResourceImpl ex
         @PathParam("actionId") final String actionId) {
 
         final ObjectAdapter objectAdapter = getObjectAdapter(oidStr);
-        final ObjectAction action = getObjectAction(objectAdapter, actionId, Intent.ACCESS);
+        final ObjectAction action = getObjectActionThatIsVisibleAndUsable(objectAdapter, actionId, Intent.ACCESS);
         
         ActionRepBuilder builder = ActionRepBuilder.newBuilder(getResourceContext().repContext(), objectAdapter, action);
-
         return jsonRepresentionFrom(builder);
     }
 
@@ -127,7 +128,7 @@ public class DomainObjectResourceImpl ex
         @QueryParam("arg") final List<String> arguments) {
 
     	final ObjectAdapter objectAdapter = getObjectAdapter(oidStr);
-    	final ObjectAction action = getObjectAction(objectAdapter, actionId, Intent.ACCESS);
+    	final ObjectAction action = getObjectActionThatIsVisibleAndUsable(objectAdapter, actionId, Intent.ACCESS);
     	
     	if(!isIdempotent(action)) {
             throw new WebApplicationException(responseOfMethodNotAllowed(
@@ -187,19 +188,29 @@ public class DomainObjectResourceImpl ex
 	@PUT
     @Path("/{oid}/properties/{propertyId}")
     @Produces({ MediaType.APPLICATION_JSON })
-    public String modifyProperty(
+    public Object modifyProperty(
         @PathParam("oid") final String oidStr,
         @PathParam("propertyId") final String propertyId, 
-        @FormParam("proposedValue") final String proposedValue) {
-    	
+        @FormParam("arg") final String proposedValue) {
+
+		// TODO: replace @FormParam with body inputstream
+		
         final ObjectAdapter objectAdapter = getObjectAdapter(oidStr);
-        final OneToOneAssociation property = getProperty(objectAdapter, propertyId, Intent.MUTATE);
+        final OneToOneAssociation property = getPropertyThatIsVisibleAndUsable(objectAdapter, propertyId, Intent.MUTATE);
         
         ObjectSpecification objectSpec = property.getSpecification();
         
-		objectAdapterFor(objectSpec, proposedValue);
+		ObjectAdapter proposedValueAdapter = objectAdapterFor(objectSpec, proposedValue);
+		
+		Consent consent = property.isAssociationValid(objectAdapter, proposedValueAdapter);
+		if(consent.isVetoed()) {
+			throw new WebApplicationException(responseOfPreconditionFailed(consent.getReason()));
+		}
 
-        return null;
+		PropertySetterFacet setterFacet = property.getFacet(PropertySetterFacet.class);
+		setterFacet.setProperty(objectAdapter, proposedValueAdapter);
+
+        return responseOfOk();
     }
 
     @PUT
@@ -208,10 +219,10 @@ public class DomainObjectResourceImpl ex
     public String addToSet(
         @PathParam("oid") final String oidStr,
         @PathParam("collectionId") final String collectionId,
-        @FormParam("proposedValue") final String proposedValueOidStr){
+        @FormParam("arg") final String proposedValueOidStr){
     	
         final ObjectAdapter objectAdapter = getObjectAdapter(oidStr);
-        final OneToManyAssociation collection = getCollection(objectAdapter, collectionId, Intent.MUTATE);
+        final OneToManyAssociation collection = getCollectionThatIsVisibleAndUsable(objectAdapter, collectionId, Intent.MUTATE);
         
         return null;
     }
@@ -228,7 +239,7 @@ public class DomainObjectResourceImpl ex
         @PathParam("propertyId") final String propertyId){
     	
         final ObjectAdapter objectAdapter = getObjectAdapter(oidStr);
-        final OneToOneAssociation property = getProperty(objectAdapter, propertyId, Intent.MUTATE);
+        final OneToOneAssociation property = getPropertyThatIsVisibleAndUsable(objectAdapter, propertyId, Intent.MUTATE);
         
         return null;
     }
@@ -239,10 +250,10 @@ public class DomainObjectResourceImpl ex
     public String removeFromCollection(
         @PathParam("oid") final String oidStr,
         @PathParam("collectionId") final String collectionId,
-        @FormParam("proposedValue") final String proposedValueOidStr){
+        @FormParam("arg") final String proposedValueOidStr){
 
     	final ObjectAdapter objectAdapter = getObjectAdapter(oidStr);
-    	final OneToManyAssociation collection = getCollection(objectAdapter, collectionId, Intent.MUTATE);
+    	final OneToManyAssociation collection = getCollectionThatIsVisibleAndUsable(objectAdapter, collectionId, Intent.MUTATE);
         
         return null;
     }
@@ -258,10 +269,10 @@ public class DomainObjectResourceImpl ex
     public String addToList(
         @PathParam("oid") final String oidStr,
         @PathParam("collectionId") final String collectionId,
-        @FormParam("proposedValue") final String proposedValueOidStr){
+        @FormParam("arg") final String proposedValueOidStr){
 
         final ObjectAdapter objectAdapter = getObjectAdapter(oidStr);
-        final OneToManyAssociation collection = getCollection(objectAdapter, collectionId, Intent.MUTATE);
+        final OneToManyAssociation collection = getCollectionThatIsVisibleAndUsable(objectAdapter, collectionId, Intent.MUTATE);
         
         return null;
 	}
@@ -276,7 +287,7 @@ public class DomainObjectResourceImpl ex
         final InputStream body){
 
         final ObjectAdapter objectAdapter = getObjectAdapter(oidStr);
-        final ObjectAction action = getObjectAction(objectAdapter, actionId, Intent.MUTATE);
+        final ObjectAction action = getObjectActionThatIsVisibleAndUsable(objectAdapter, actionId, Intent.MUTATE);
 
 		List<ObjectAdapter> argumentAdapters = parseBody(action, body);
 		return invokeActionUsingAdapters(action, objectAdapter, argumentAdapters);
@@ -340,9 +351,27 @@ public class DomainObjectResourceImpl ex
 
 	private Object invokeActionUsingAdapters(final ObjectAction action,
 			final ObjectAdapter objectAdapter,
-			final List<ObjectAdapter> parameterAdapters) {
-		ObjectAdapter[] parameterArray = parameterAdapters.toArray(new ObjectAdapter[0]);
-		final ObjectAdapter returnedAdapter = action.execute(objectAdapter, parameterArray);
+			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 new WebApplicationException(responseOfPreconditionFailed(reasonNotValid));
+				}
+			}
+		}
+		ObjectAdapter[] argArray = argAdapters.toArray(new ObjectAdapter[0]);
+		Consent consent = action.isProposedArgumentSetValid(objectAdapter, argArray);
+		if(consent.isVetoed()) {
+			throw new WebApplicationException(responseOfPreconditionFailed(consent.getReason()));
+		}
+		
+		final ObjectAdapter returnedAdapter = action.execute(objectAdapter, argArray);
 		if(returnedAdapter == null) {
 	        return responseOfOk();
 		}
@@ -370,7 +399,7 @@ public class DomainObjectResourceImpl ex
 		}
 	}
 
-	private OneToOneAssociation getProperty(
+	private OneToOneAssociation getPropertyThatIsVisibleAndUsable(
 			final ObjectAdapter objectAdapter, final String propertyId, final Intent intent) {
 		ObjectAssociation association = objectAdapter.getSpecification().getAssociation(propertyId);
         if(association == null || !association.isOneToOneAssociation()) { 
@@ -380,7 +409,7 @@ public class DomainObjectResourceImpl ex
         return ensureVisibleAndUsableForIntent(objectAdapter, property, MemberType.PROPERTY, intent);
 	}
 
-	private OneToManyAssociation getCollection(
+	private OneToManyAssociation getCollectionThatIsVisibleAndUsable(
 			final ObjectAdapter objectAdapter, final String collectionId, final Intent intent) {
 		ObjectAssociation association = objectAdapter.getSpecification().getAssociation(collectionId);
         if(association == null || !association.isOneToManyAssociation()) {
@@ -390,7 +419,7 @@ public class DomainObjectResourceImpl ex
         return ensureVisibleAndUsableForIntent(objectAdapter, collection, MemberType.COLLECTION, intent);
 	}
 
-	private ObjectAction getObjectAction(final ObjectAdapter objectAdapter,
+	private ObjectAction getObjectActionThatIsVisibleAndUsable(final ObjectAdapter objectAdapter,
 			final String actionId, Intent intent) {
 		ObjectAction action = objectAdapter.getSpecification().getObjectAction(actionId);
 		return ensureVisibleAndUsableForIntent(objectAdapter, action, MemberType.ACTION, intent);