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);