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 2018/11/26 23:27:33 UTC
[isis] 01/01: ISIS-2045, ISIS-2046: RO validations now supported
This is an automated email from the ASF dual-hosted git repository.
danhaywood pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/isis.git
commit 3c4daf4acdc8957522ede387be07319de29ee0ad
Author: danhaywood <da...@haywood-associates.co.uk>
AuthorDate: Mon Nov 26 23:19:17 2018 +0000
ISIS-2045, ISIS-2046: RO validations now supported
if validation fails, renders correct body in 422 client-side exception
x-ro-validate-only flag supported; returns 204 no content if validation passes.
---
.../core/metamodel/spec/feature/ObjectAction.java | 20 ++++++-
.../specimpl/ObjectActionContributee.java | 27 +++++++--
.../specloader/specimpl/ObjectActionDefault.java | 65 +++++++++++++++++++++-
.../viewer/restfulobjects/applib/util/Parser.java | 8 ++-
...sHttpStatusCode.java => ExceptionWithBody.java} | 6 +-
...sCode.java => ExceptionWithHttpStatusCode.java} | 2 +-
.../restfulobjects/rendering/RendererContext.java | 1 +
.../RestfulObjectsApplicationException.java | 34 ++++++++---
.../restfulobjects/server/ResourceContext.java | 6 ++
.../server/mappers/ExceptionMapperAbstract.java | 36 ++++++++++--
...xceptionMapperForRestfulObjectsApplication.java | 4 +-
.../resources/DomainObjectResourceServerside.java | 8 +++
.../server/resources/DomainResourceHelper.java | 11 ++++
.../server/resources/ObjectActionArgHelper.java | 12 ++--
.../modules/simple/dom/impl/SimpleObject.java | 1 -
15 files changed, 209 insertions(+), 32 deletions(-)
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/spec/feature/ObjectAction.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/spec/feature/ObjectAction.java
index 7f37494..60be7d1 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/spec/feature/ObjectAction.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/spec/feature/ObjectAction.java
@@ -128,16 +128,34 @@ public interface ObjectAction extends ObjectMember {
//endregion
- //region > isProposedArgumentSetValid
+ //region > isProposedArgumentSetValid, isEachIndividualArgumentValid, isArgumentSetValid
/**
* Whether the provided argument set is valid, represented as a {@link Consent}.
+ *
+ * <p>
+ * Basically just calls (the helper methods also called by) first
+ * {@link #isEachIndividualArgumentValid(ObjectAdapter, ObjectAdapter[], InteractionInitiatedBy)} and then
+ * {@link #isArgumentSetValid(ObjectAdapter, ObjectAdapter[], InteractionInitiatedBy)}. Those methods are
+ * separated out so that viewers have more fine-grained control.
+ * </p>
*/
Consent isProposedArgumentSetValid(
ObjectAdapter object,
ObjectAdapter[] proposedArguments,
final InteractionInitiatedBy interactionInitiatedBy);
+ Consent isEachIndividualArgumentValid(
+ ObjectAdapter objectAdapter,
+ ObjectAdapter[] proposedArguments,
+ InteractionInitiatedBy interactionInitiatedBy);
+
+ Consent isArgumentSetValid(
+ ObjectAdapter objectAdapter,
+ ObjectAdapter[] proposedArguments,
+ InteractionInitiatedBy interactionInitiatedBy);
+
+
//endregion
//region > Parameters (declarative)
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/specloader/specimpl/ObjectActionContributee.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/specloader/specimpl/ObjectActionContributee.java
index b0156e9..e47d74d 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/specloader/specimpl/ObjectActionContributee.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/specloader/specimpl/ObjectActionContributee.java
@@ -176,16 +176,35 @@ public class ObjectActionContributee extends ObjectActionDefault implements Cont
interactionInitiatedBy);
return removeElementFromArray(serviceChoices, contributeeParam, new ObjectAdapter[][]{});
}
-
+
+ @Override
public Consent isProposedArgumentSetValid(
final ObjectAdapter contributee,
final ObjectAdapter[] proposedArguments,
final InteractionInitiatedBy interactionInitiatedBy) {
- ObjectAdapter[] serviceArguments = argsPlusContributee(contributee, proposedArguments);
+ final ObjectAdapter[] serviceArguments = argsPlusContributee(contributee, proposedArguments);
return serviceAction.isProposedArgumentSetValid(getServiceAdapter(), serviceArguments, interactionInitiatedBy);
}
@Override
+ public Consent isEachIndividualArgumentValid(
+ final ObjectAdapter contributee,
+ final ObjectAdapter[] proposedArguments,
+ final InteractionInitiatedBy interactionInitiatedBy) {
+ final ObjectAdapter[] serviceArguments = argsPlusContributee(contributee, proposedArguments);
+ return serviceAction.isEachIndividualArgumentValid(getServiceAdapter(), serviceArguments, interactionInitiatedBy);
+ }
+
+ @Override
+ public Consent isArgumentSetValid(
+ final ObjectAdapter contributee,
+ final ObjectAdapter[] proposedArguments,
+ final InteractionInitiatedBy interactionInitiatedBy) {
+ final ObjectAdapter[] serviceArguments = argsPlusContributee(contributee, proposedArguments);
+ return serviceAction.isArgumentSetValid(getServiceAdapter(), serviceArguments, interactionInitiatedBy);
+ }
+
+ @Override
public ObjectAdapter execute(
final ObjectAdapter targetAdapter,
final ObjectAdapter mixedInAdapter,
@@ -194,9 +213,9 @@ public class ObjectActionContributee extends ObjectActionDefault implements Cont
setupCommand(targetAdapter, argumentAdapters);
+ final ObjectAdapter[] serviceArguments = argsPlusContributee(targetAdapter, argumentAdapters);
return serviceAction.executeInternal(
- getServiceAdapter(), mixedInAdapter, argsPlusContributee(targetAdapter, argumentAdapters),
- interactionInitiatedBy);
+ getServiceAdapter(), mixedInAdapter, serviceArguments, interactionInitiatedBy);
}
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/specloader/specimpl/ObjectActionDefault.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/specloader/specimpl/ObjectActionDefault.java
index bfc7097..8137b76 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/specloader/specimpl/ObjectActionDefault.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/specloader/specimpl/ObjectActionDefault.java
@@ -285,6 +285,18 @@ public class ObjectActionDefault extends ObjectMemberAbstract implements ObjectA
//region > validate
+ /**
+ * The Validates all arguments individually (by calling same helper that
+ * {@link #isEachIndividualArgumentValid(ObjectAdapter, ObjectAdapter[], InteractionInitiatedBy)} delegates to)
+ * and if there are no validation errors, then validates the entire argument
+ * set (by calling same helper that
+ * {@link #isArgumentSetValid(ObjectAdapter, ObjectAdapter[], InteractionInitiatedBy)} delegates to).
+ *
+ * <p>
+ * The two other validation methods mentioned above are separated out to allow viewers (such as the RO viewer) to
+ * call the validation phases separately.
+ * </p>
+ */
@Override
public Consent isProposedArgumentSetValid(
final ObjectAdapter targetObject,
@@ -302,7 +314,33 @@ public class ObjectActionDefault extends ObjectMemberAbstract implements ObjectA
return resultSet.createConsent();
}
- protected void validateArgumentsIndividually(
+ /**
+ * Normally action validation is all performed by
+ * {@link #isProposedArgumentSetValid(ObjectAdapter, ObjectAdapter[], InteractionInitiatedBy)}, which calls
+ * {@link #isEachIndividualArgumentValid(ObjectAdapter, ObjectAdapter[], InteractionInitiatedBy) this method} to
+ * validate arguments individually, and then
+ * {@link #isArgumentSetValid(ObjectAdapter, ObjectAdapter[], InteractionInitiatedBy) validate argument set}
+ * afterwards.
+ *
+ * <p>
+ * This method is in the API to allow viewers (eg the RO viewer) to call the different phases of validation
+ * individually.
+ * </p>
+ */
+ @Override
+ public Consent isEachIndividualArgumentValid(
+ final ObjectAdapter objectAdapter,
+ final ObjectAdapter[] proposedArguments,
+ final InteractionInitiatedBy interactionInitiatedBy) {
+
+ final InteractionResultSet resultSet = new InteractionResultSet();
+
+ validateArgumentsIndividually(objectAdapter, proposedArguments, interactionInitiatedBy, resultSet);
+
+ return resultSet.createConsent();
+ }
+
+ private void validateArgumentsIndividually(
final ObjectAdapter objectAdapter,
final ObjectAdapter[] proposedArguments,
final InteractionInitiatedBy interactionInitiatedBy,
@@ -319,6 +357,31 @@ public class ObjectActionDefault extends ObjectMemberAbstract implements ObjectA
}
}
+ /**
+ * Normally action validation is all performed by
+ * {@link #isProposedArgumentSetValid(ObjectAdapter, ObjectAdapter[], InteractionInitiatedBy)}, which calls
+ * {@link #isEachIndividualArgumentValid(ObjectAdapter, ObjectAdapter[], InteractionInitiatedBy)} to
+ * validate arguments individually, and then
+ * {@link #isArgumentSetValid(ObjectAdapter, ObjectAdapter[], InteractionInitiatedBy) this method} to
+ * validate the entire argument set afterwards.
+ *
+ * <p>
+ * This method is in the API to allow viewers (eg the RO viewer) to call the different phases of validation
+ * individually.
+ * </p>
+ */
+ @Override
+ public Consent isArgumentSetValid(
+ final ObjectAdapter objectAdapter,
+ final ObjectAdapter[] proposedArguments,
+ final InteractionInitiatedBy interactionInitiatedBy) {
+
+ final InteractionResultSet resultSet = new InteractionResultSet();
+ validateArgumentSet(objectAdapter, proposedArguments, interactionInitiatedBy, resultSet);
+
+ return resultSet.createConsent();
+ }
+
protected void validateArgumentSet(
final ObjectAdapter objectAdapter,
final ObjectAdapter[] proposedArguments,
diff --git a/core/viewer-restfulobjects-applib/src/main/java/org/apache/isis/viewer/restfulobjects/applib/util/Parser.java b/core/viewer-restfulobjects-applib/src/main/java/org/apache/isis/viewer/restfulobjects/applib/util/Parser.java
index d23e821..3e18b27 100644
--- a/core/viewer-restfulobjects-applib/src/main/java/org/apache/isis/viewer/restfulobjects/applib/util/Parser.java
+++ b/core/viewer-restfulobjects-applib/src/main/java/org/apache/isis/viewer/restfulobjects/applib/util/Parser.java
@@ -28,14 +28,14 @@ import java.util.List;
import javax.ws.rs.core.CacheControl;
import javax.ws.rs.core.MediaType;
-import org.apache.isis.viewer.restfulobjects.applib.JsonRepresentation;
-
import com.google.common.base.Function;
import com.google.common.base.Joiner;
import com.google.common.base.Splitter;
import com.google.common.collect.Iterables;
import com.google.common.collect.Lists;
+import org.apache.isis.viewer.restfulobjects.applib.JsonRepresentation;
+
public abstract class Parser<T> {
public T valueOf(final List<String> str) {
if (str == null) {
@@ -173,7 +173,9 @@ public abstract class Parser<T> {
if (str == null) {
return null;
}
- return str.equals("yes") ? Boolean.TRUE : Boolean.FALSE;
+ return "yes".equalsIgnoreCase(str) || "true".equalsIgnoreCase(str)
+ ? Boolean.TRUE
+ : Boolean.FALSE;
}
@Override
diff --git a/core/viewer-restfulobjects-rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/HasHttpStatusCode.java b/core/viewer-restfulobjects-rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/ExceptionWithBody.java
similarity index 84%
copy from core/viewer-restfulobjects-rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/HasHttpStatusCode.java
copy to core/viewer-restfulobjects-rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/ExceptionWithBody.java
index cb35092..821555f 100644
--- a/core/viewer-restfulobjects-rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/HasHttpStatusCode.java
+++ b/core/viewer-restfulobjects-rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/ExceptionWithBody.java
@@ -18,9 +18,9 @@
*/
package org.apache.isis.viewer.restfulobjects.rendering;
-import org.apache.isis.viewer.restfulobjects.applib.client.RestfulResponse.HttpStatusCode;
+import org.apache.isis.viewer.restfulobjects.applib.JsonRepresentation;
-public interface HasHttpStatusCode {
+public interface ExceptionWithBody {
- HttpStatusCode getHttpStatusCode();
+ JsonRepresentation getBody();
}
diff --git a/core/viewer-restfulobjects-rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/HasHttpStatusCode.java b/core/viewer-restfulobjects-rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/ExceptionWithHttpStatusCode.java
similarity index 95%
rename from core/viewer-restfulobjects-rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/HasHttpStatusCode.java
rename to core/viewer-restfulobjects-rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/ExceptionWithHttpStatusCode.java
index cb35092..c88d08e 100644
--- a/core/viewer-restfulobjects-rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/HasHttpStatusCode.java
+++ b/core/viewer-restfulobjects-rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/ExceptionWithHttpStatusCode.java
@@ -20,7 +20,7 @@ package org.apache.isis.viewer.restfulobjects.rendering;
import org.apache.isis.viewer.restfulobjects.applib.client.RestfulResponse.HttpStatusCode;
-public interface HasHttpStatusCode {
+public interface ExceptionWithHttpStatusCode {
HttpStatusCode getHttpStatusCode();
}
diff --git a/core/viewer-restfulobjects-rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/RendererContext.java b/core/viewer-restfulobjects-rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/RendererContext.java
index 460e0e4..55da602 100644
--- a/core/viewer-restfulobjects-rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/RendererContext.java
+++ b/core/viewer-restfulobjects-rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/RendererContext.java
@@ -48,6 +48,7 @@ public interface RendererContext {
Where getWhere();
List<List<String>> getFollowLinks();
+ boolean isValidateOnly();
boolean honorUiHints();
diff --git a/core/viewer-restfulobjects-rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/RestfulObjectsApplicationException.java b/core/viewer-restfulobjects-rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/RestfulObjectsApplicationException.java
index 77e3765..1e8af8f 100644
--- a/core/viewer-restfulobjects-rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/RestfulObjectsApplicationException.java
+++ b/core/viewer-restfulobjects-rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/RestfulObjectsApplicationException.java
@@ -21,25 +21,39 @@ package org.apache.isis.viewer.restfulobjects.rendering;
import org.apache.isis.viewer.restfulobjects.applib.JsonRepresentation;
import org.apache.isis.viewer.restfulobjects.applib.client.RestfulResponse.HttpStatusCode;
-public class RestfulObjectsApplicationException extends RuntimeException implements HasHttpStatusCode {
+public class RestfulObjectsApplicationException
+ extends RuntimeException
+ implements ExceptionWithHttpStatusCode, ExceptionWithBody {
+
+ private static final long serialVersionUID = 1L;
public static final RestfulObjectsApplicationException create(final HttpStatusCode httpStatusCode) {
return createWithCause(httpStatusCode, null);
}
- public static RestfulObjectsApplicationException createWithMessage(final HttpStatusCode httpStatusCode, final String message, final Object... args) {
- return createWithCauseAndMessage(httpStatusCode, (Exception) null, message, args);
+ public static RestfulObjectsApplicationException createWithMessage(
+ final HttpStatusCode httpStatusCode,
+ final String message, final Object... args) {
+ return createWithCauseAndMessage(httpStatusCode, null, message, args);
}
- public static RestfulObjectsApplicationException createWithCause(final HttpStatusCode httpStatusCode, final Exception cause) {
+ public static RestfulObjectsApplicationException createWithCause(
+ final HttpStatusCode httpStatusCode,
+ final Exception cause) {
return createWithCauseAndMessage(httpStatusCode, cause, null);
}
- public static RestfulObjectsApplicationException createWithCauseAndMessage(final HttpStatusCode httpStatusCode, final Exception cause, final String message, final Object... args) {
+ public static RestfulObjectsApplicationException createWithCauseAndMessage(
+ final HttpStatusCode httpStatusCode,
+ final Exception cause,
+ final String message, final Object... args) {
return new RestfulObjectsApplicationException(httpStatusCode, formatString(message, args), cause, null);
}
- public static RestfulObjectsApplicationException createWithBody(final HttpStatusCode httpStatusCode, final JsonRepresentation body, final String message, final Object... args) {
+ public static RestfulObjectsApplicationException createWithBody(
+ final HttpStatusCode httpStatusCode,
+ final JsonRepresentation body,
+ final String message, final Object... args) {
return new RestfulObjectsApplicationException(httpStatusCode, formatString(message, args), null, body);
}
@@ -47,11 +61,14 @@ public class RestfulObjectsApplicationException extends RuntimeException impleme
return formatStr != null ? String.format(formatStr, args) : null;
}
- private static final long serialVersionUID = 1L;
private final HttpStatusCode httpStatusCode;
private final JsonRepresentation body;
- protected RestfulObjectsApplicationException(final HttpStatusCode httpStatusCode, final String message, final Throwable cause, final JsonRepresentation body) {
+ protected RestfulObjectsApplicationException(
+ final HttpStatusCode httpStatusCode,
+ final String message,
+ final Throwable cause,
+ final JsonRepresentation body) {
super(message, cause);
this.httpStatusCode = httpStatusCode;
this.body = body;
@@ -62,6 +79,7 @@ public class RestfulObjectsApplicationException extends RuntimeException impleme
return httpStatusCode;
}
+ @Override
public JsonRepresentation getBody() {
return body;
}
diff --git a/core/viewer-restfulobjects-server/src/main/java/org/apache/isis/viewer/restfulobjects/server/ResourceContext.java b/core/viewer-restfulobjects-server/src/main/java/org/apache/isis/viewer/restfulobjects/server/ResourceContext.java
index 415f243..7992611 100644
--- a/core/viewer-restfulobjects-server/src/main/java/org/apache/isis/viewer/restfulobjects/server/ResourceContext.java
+++ b/core/viewer-restfulobjects-server/src/main/java/org/apache/isis/viewer/restfulobjects/server/ResourceContext.java
@@ -77,6 +77,7 @@ public class ResourceContext implements RendererContext6 {
private final PersistenceSession persistenceSession;
private List<List<String>> followLinks;
+ private boolean validateOnly;
private final Where where;
private final RepresentationService.Intent intent;
@@ -138,6 +139,7 @@ public class ResourceContext implements RendererContext6 {
ensureDomainModelQueryParamSupported();
this.followLinks = Collections.unmodifiableList(getArg(RequestParameter.FOLLOW_LINKS));
+ this.validateOnly = getArg(RequestParameter.VALIDATE_ONLY);
}
private void ensureDomainModelQueryParamSupported() {
@@ -265,6 +267,10 @@ public class ResourceContext implements RendererContext6 {
public List<List<String>> getFollowLinks() {
return followLinks;
}
+ @Override
+ public boolean isValidateOnly() {
+ return validateOnly;
+ }
@Override
public AuthenticationSession getAuthenticationSession() {
diff --git a/core/viewer-restfulobjects-server/src/main/java/org/apache/isis/viewer/restfulobjects/server/mappers/ExceptionMapperAbstract.java b/core/viewer-restfulobjects-server/src/main/java/org/apache/isis/viewer/restfulobjects/server/mappers/ExceptionMapperAbstract.java
index 0977835..1d73316 100644
--- a/core/viewer-restfulobjects-server/src/main/java/org/apache/isis/viewer/restfulobjects/server/mappers/ExceptionMapperAbstract.java
+++ b/core/viewer-restfulobjects-server/src/main/java/org/apache/isis/viewer/restfulobjects/server/mappers/ExceptionMapperAbstract.java
@@ -34,9 +34,11 @@ import com.google.common.collect.FluentIterable;
import org.jboss.resteasy.spi.Failure;
import org.apache.isis.applib.RecoverableException;
+import org.apache.isis.viewer.restfulobjects.applib.JsonRepresentation;
import org.apache.isis.viewer.restfulobjects.applib.RepresentationType;
import org.apache.isis.viewer.restfulobjects.applib.client.RestfulResponse;
-import org.apache.isis.viewer.restfulobjects.rendering.HasHttpStatusCode;
+import org.apache.isis.viewer.restfulobjects.rendering.ExceptionWithBody;
+import org.apache.isis.viewer.restfulobjects.rendering.ExceptionWithHttpStatusCode;
import org.apache.isis.viewer.restfulobjects.server.mappers.entity.ExceptionDetail;
import org.apache.isis.viewer.restfulobjects.server.mappers.entity.ExceptionPojo;
import org.apache.isis.viewer.restfulobjects.server.resources.serialization.SerializationStrategy;
@@ -50,6 +52,14 @@ public abstract class ExceptionMapperAbstract<T extends Throwable> implements Ex
final RestfulResponse.HttpStatusCode httpStatusCode = determineStatusCode(ex);
final String message = messageFor(ex);
+ if(ex instanceof ExceptionWithBody) {
+ final ExceptionWithBody exceptionWithBody = (ExceptionWithBody) ex;
+ final JsonRepresentation body = exceptionWithBody.getBody();
+ if(body != null) {
+ return buildResponse(httpStatusCode, message, body);
+ }
+ }
+
final ExceptionPojo exceptionPojo =
new ExceptionPojo(
httpStatusCode.getStatusCode(), message,
@@ -59,6 +69,24 @@ public abstract class ExceptionMapperAbstract<T extends Throwable> implements Ex
return buildResponse(httpStatusCode, exceptionPojo);
}
+ private Response buildResponse(
+ final RestfulResponse.HttpStatusCode httpStatusCode,
+ final String message,
+ final JsonRepresentation body) {
+ final ResponseBuilder builder = Response.status(httpStatusCode.getJaxrsStatusType());
+ if (message != null) {
+ builder.header(RestfulResponse.Header.WARNING.getName(), RestfulResponse.Header.WARNING.render(message));
+ }
+
+ final SerializationStrategy serializationStrategy = SerializationStrategy.JSON;
+
+ // hmm; the mediaType doesn't seem to be specified in the RO spec
+ builder.type(serializationStrategy.type(RepresentationType.GENERIC));
+ builder.entity(body.toString());
+
+ return builder.build();
+ }
+
private RestfulResponse.HttpStatusCode determineStatusCode(final T ex) {
final List<Throwable> chain = Throwables.getCausalChain(ex);
@@ -68,9 +96,9 @@ public abstract class ExceptionMapperAbstract<T extends Throwable> implements Ex
statusCode = RestfulResponse.HttpStatusCode.statusFor(failure.getErrorCode());
} else if(!FluentIterable.from(chain).filter(RecoverableException.class).isEmpty()) {
statusCode = RestfulResponse.HttpStatusCode.OK;
- } else if(ex instanceof HasHttpStatusCode) {
- HasHttpStatusCode hasHttpStatusCode = (HasHttpStatusCode) ex;
- statusCode = hasHttpStatusCode.getHttpStatusCode();
+ } else if(ex instanceof ExceptionWithHttpStatusCode) {
+ ExceptionWithHttpStatusCode exceptionWithHttpStatusCode = (ExceptionWithHttpStatusCode) ex;
+ statusCode = exceptionWithHttpStatusCode.getHttpStatusCode();
} else {
statusCode = RestfulResponse.HttpStatusCode.INTERNAL_SERVER_ERROR;
}
diff --git a/core/viewer-restfulobjects-server/src/main/java/org/apache/isis/viewer/restfulobjects/server/mappers/ExceptionMapperForRestfulObjectsApplication.java b/core/viewer-restfulobjects-server/src/main/java/org/apache/isis/viewer/restfulobjects/server/mappers/ExceptionMapperForRestfulObjectsApplication.java
index da04ffe..7b49d00 100644
--- a/core/viewer-restfulobjects-server/src/main/java/org/apache/isis/viewer/restfulobjects/server/mappers/ExceptionMapperForRestfulObjectsApplication.java
+++ b/core/viewer-restfulobjects-server/src/main/java/org/apache/isis/viewer/restfulobjects/server/mappers/ExceptionMapperForRestfulObjectsApplication.java
@@ -21,14 +21,16 @@ package org.apache.isis.viewer.restfulobjects.server.mappers;
import javax.ws.rs.core.Response;
import javax.ws.rs.ext.Provider;
+import org.apache.isis.viewer.restfulobjects.applib.JsonRepresentation;
import org.apache.isis.viewer.restfulobjects.rendering.RestfulObjectsApplicationException;
-//@Path("/") // FIXME: workaround for TomEE ... but breaks the RestEasy TCK tests so commented out:-(
@Provider
public class ExceptionMapperForRestfulObjectsApplication extends ExceptionMapperAbstract<RestfulObjectsApplicationException> {
@Override
public Response toResponse(final RestfulObjectsApplicationException ex) {
+ final JsonRepresentation body = ex.getBody();
+ final String bodyStr = body != null ? body.toString() : null;
return buildResponse(ex);
}
diff --git a/core/viewer-restfulobjects-server/src/main/java/org/apache/isis/viewer/restfulobjects/server/resources/DomainObjectResourceServerside.java b/core/viewer-restfulobjects-server/src/main/java/org/apache/isis/viewer/restfulobjects/server/resources/DomainObjectResourceServerside.java
index 853fcc9..5c7ee86 100644
--- a/core/viewer-restfulobjects-server/src/main/java/org/apache/isis/viewer/restfulobjects/server/resources/DomainObjectResourceServerside.java
+++ b/core/viewer-restfulobjects-server/src/main/java/org/apache/isis/viewer/restfulobjects/server/resources/DomainObjectResourceServerside.java
@@ -36,6 +36,8 @@ import javax.ws.rs.core.Response;
import com.google.common.base.Strings;
import com.google.common.io.Resources;
+import org.apache.log4j.Logger;
+
import org.apache.isis.applib.annotation.Where;
import org.apache.isis.applib.layout.component.ActionLayoutData;
import org.apache.isis.applib.layout.component.CollectionLayoutData;
@@ -72,6 +74,12 @@ import org.apache.isis.viewer.restfulobjects.server.resources.serialization.Seri
@Path("/objects")
public class DomainObjectResourceServerside extends ResourceAbstract implements DomainObjectResource {
+ private final static Logger LOG = Logger.getLogger(DomainObjectResourceServerside.class);
+
+ public DomainObjectResourceServerside() {
+ LOG.debug("<init>");
+ }
+
// //////////////////////////////////////////////////////////
// persist
// //////////////////////////////////////////////////////////
diff --git a/core/viewer-restfulobjects-server/src/main/java/org/apache/isis/viewer/restfulobjects/server/resources/DomainResourceHelper.java b/core/viewer-restfulobjects-server/src/main/java/org/apache/isis/viewer/restfulobjects/server/resources/DomainResourceHelper.java
index 40385c4..a7474ff 100644
--- a/core/viewer-restfulobjects-server/src/main/java/org/apache/isis/viewer/restfulobjects/server/resources/DomainResourceHelper.java
+++ b/core/viewer-restfulobjects-server/src/main/java/org/apache/isis/viewer/restfulobjects/server/resources/DomainResourceHelper.java
@@ -113,6 +113,11 @@ public class DomainResourceHelper {
}
@Override
+ public boolean isValidateOnly() {
+ return rendererContext.isValidateOnly();
+ }
+
+ @Override
public List<MediaType> getAcceptableMediaTypes() {
return rendererContext.getAcceptableMediaTypes();
}
@@ -364,6 +369,12 @@ public class DomainResourceHelper {
final List<ObjectAdapter> argAdapters = argHelper.parseAndValidateArguments(arguments);
+ if(rendererContext.isValidateOnly()) {
+ // nothing more to do.
+ // if there had been a validation error, then an exception would have been thrown above.
+ return Response.noContent().build();
+ }
+
// invoke
final ObjectAdapter mixedInAdapter = null; // action will automatically fill in if a mixin
final ObjectAdapter[] argAdapterArr = argAdapters.toArray(new ObjectAdapter[argAdapters.size()]);
diff --git a/core/viewer-restfulobjects-server/src/main/java/org/apache/isis/viewer/restfulobjects/server/resources/ObjectActionArgHelper.java b/core/viewer-restfulobjects-server/src/main/java/org/apache/isis/viewer/restfulobjects/server/resources/ObjectActionArgHelper.java
index 82d15f3..6361b43 100644
--- a/core/viewer-restfulobjects-server/src/main/java/org/apache/isis/viewer/restfulobjects/server/resources/ObjectActionArgHelper.java
+++ b/core/viewer-restfulobjects-server/src/main/java/org/apache/isis/viewer/restfulobjects/server/resources/ObjectActionArgHelper.java
@@ -65,8 +65,7 @@ public class ObjectActionArgHelper {
// validate individual arg
final ObjectActionParameter parameter = parameters.get(i);
final Object argPojo = argAdapter!=null?argAdapter.getObject():null;
- final String reasonNotValid = parameter.isValid(objectAdapter, argPojo, InteractionInitiatedBy.USER
- );
+ final String reasonNotValid = parameter.isValid(objectAdapter, argPojo, InteractionInitiatedBy.USER);
if (reasonNotValid != null) {
argRepr.mapPut("invalidReason", reasonNotValid);
valid = false;
@@ -77,16 +76,19 @@ public class ObjectActionArgHelper {
}
}
- // validate all args
+ // validate entire argument set
final ObjectAdapter[] argArray = argAdapters.toArray(new ObjectAdapter[0]);
- final Consent consent = action.isProposedArgumentSetValid(objectAdapter, argArray, InteractionInitiatedBy.USER);
+ final Consent consent = action.isArgumentSetValid(objectAdapter, argArray, InteractionInitiatedBy.USER);
if (consent.isVetoed()) {
arguments.mapPut("x-ro-invalidReason", consent.getReason());
valid = false;
}
if(!valid) {
- throw RestfulObjectsApplicationException.createWithBody(RestfulResponse.HttpStatusCode.VALIDATION_FAILED, arguments, "Validation failed, see body for details");
+ throw RestfulObjectsApplicationException.createWithBody(
+ RestfulResponse.HttpStatusCode.VALIDATION_FAILED,
+ arguments,
+ "Validation failed, see body for details");
}
return argAdapters;
diff --git a/example/application/simpleapp/module-simple/src/main/java/domainapp/modules/simple/dom/impl/SimpleObject.java b/example/application/simpleapp/module-simple/src/main/java/domainapp/modules/simple/dom/impl/SimpleObject.java
index 9c598d3..6b2b5b8 100644
--- a/example/application/simpleapp/module-simple/src/main/java/domainapp/modules/simple/dom/impl/SimpleObject.java
+++ b/example/application/simpleapp/module-simple/src/main/java/domainapp/modules/simple/dom/impl/SimpleObject.java
@@ -24,7 +24,6 @@ import javax.jdo.annotations.VersionStrategy;
import com.google.common.collect.ComparisonChain;
import org.apache.isis.applib.annotation.Action;
-import org.apache.isis.applib.annotation.ActionLayout;
import org.apache.isis.applib.annotation.Auditing;
import org.apache.isis.applib.annotation.CommandReification;
import org.apache.isis.applib.annotation.DomainObject;