You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@causeway.apache.org by ah...@apache.org on 2025/07/04 19:52:15 UTC
(causeway) branch 3897-ro.spring created (now 077e960b254)
This is an automated email from the ASF dual-hosted git repository.
ahuber pushed a change to branch 3897-ro.spring
in repository https://gitbox.apache.org/repos/asf/causeway.git
at 077e960b254 CAUSEWAY-3897: [RO] Use Spring RestControllers instead of RestEasy (JBoss)
This branch includes the following new commits:
new e80d67b81c2 CAUSEWAY-3892: New Major Version 4 (Upgrade from Spring Boot 3.x to 4.x)
new 077e960b254 CAUSEWAY-3897: [RO] Use Spring RestControllers instead of RestEasy (JBoss)
The 2 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails. The revisions
listed as "add" were already present in the repository and have only
been added to this reference.
(causeway) 02/02: CAUSEWAY-3897: [RO] Use Spring RestControllers instead of RestEasy (JBoss)
Posted by ah...@apache.org.
This is an automated email from the ASF dual-hosted git repository.
ahuber pushed a commit to branch 3897-ro.spring
in repository https://gitbox.apache.org/repos/asf/causeway.git
commit 077e960b25468e7f7c84818b9b10669ae3460863
Author: Andi Huber <ah...@apache.org>
AuthorDate: Fri Jul 4 15:11:14 2025 +0200
CAUSEWAY-3897: [RO] Use Spring RestControllers instead of RestEasy
(JBoss)
initial commit (proof of concept)
---
.../client/RepresentationTypeSimplifiedV2.java | 40 +-
.../applib/src/main/java/module-info.java | 14 +-
.../restfulobjects/applib/RepresentationType.java | 2 +-
.../applib/boot/BootstrapResource.java | 10 +-
.../applib/domainobjects/DomainObjectResource.java | 231 ++++------
.../domainobjects/DomainServiceResource.java | 41 +-
.../applib/domaintypes/DomainTypeResource.java | 95 ++---
.../applib/health/HealthResource.java | 34 +-
.../applib/homepage/HomePageResource.java | 19 +-
.../applib/menubars/MenuBarsResource.java | 36 +-
.../restfulobjects/applib/user/UserResource.java | 38 +-
.../restfulobjects/applib/util/MediaTypes.java | 5 +-
.../applib/version/VersionResource.java | 34 +-
.../viewer/restfulobjects/rendering/Caching.java | 15 +-
.../CausewayModuleRestfulObjectsRendering.java | 9 +-
.../rendering/ExceptionWithBody.java | 2 +-
.../rendering/ExceptionWithHttpStatusCode.java | 4 +-
.../restfulobjects/rendering/ResponseFactory.java | 144 +++++++
.../viewer/restfulobjects/rendering/Responses.java | 121 ------
.../RestfulObjectsApplicationException.java | 53 +--
.../AbstractObjectMemberReprRenderer.java | 12 +-
.../domainobjects/ActionResultReprRenderer.java | 3 +-
.../domainobjects/DomainObjectReprRenderer.java | 3 +-
.../rendering/service/RepresentationService.java | 109 ++---
.../service/conneg/ContentNegotiationService.java | 49 +--
.../conneg/ContentNegotiationServiceAbstract.java | 28 +-
...entNegotiationServiceForRestfulObjectsV1_0.java | 154 +++----
...ntentNegotiationServiceOrgApacheCausewayV2.java | 76 ++--
.../ContentNegotiationServiceOrgApacheIsisV1.java | 21 +-
.../ContentNegotiationServiceXRoDomainType.java | 22 +-
.../rendering/util/RequestParams.java | 13 +-
...sewayViewerRestfulObjectsIntegTestAbstract.java | 5 +-
.../test/scenarios/Abstract_IntegTest.java | 4 +-
..._ensureCompatibleAcceptHeader_ContractTest.java | 6 +-
...tsApplicationExceptionMapper_Test_Contract.java | 55 ++-
.../viewer/src/main/java/module-info.java | 20 +-
.../CausewayModuleViewerRestfulObjectsViewer.java | 27 +-
.../viewer/context/ResourceContext.java | 31 +-
.../ExceptionMapperForRestfulObjects.java} | 40 +-
.../exhandling/ExceptionResponseFactory.java | 147 +++++++
.../{mappers => exhandling}/FailureUtil.java | 10 +-
.../entity/ExceptionDetail.java | 2 +-
.../entity/ExceptionPojo.java | 2 +-
.../viewer/mappers/ExceptionMapperAbstract.java | 170 --------
...xceptionMapperForRestfulObjectsApplication.java | 42 --
.../resources/DomainObjectResourceServerside.java | 328 +++++----------
.../resources/DomainServiceResourceServerside.java | 164 +++-----
.../resources/DomainTypeResourceServerside.java | 174 +++-----
.../resources/HomePageResourceServerside.java | 33 +-
.../viewer/resources/ImageResourceServerside.java | 62 ---
.../resources/InteractionFailureHandler.java | 17 +-
.../viewer/resources/JsonParserHelper.java | 6 +-
.../resources/MenuBarsResourceServerside.java | 47 +--
.../viewer/resources/ObjectActionArgHelper.java | 7 +-
.../viewer/resources/ResourceAbstract.java | 42 +-
.../viewer/resources/SwaggerSpecResource.java | 54 +--
.../viewer/resources/UserResourceServerside.java | 49 +--
.../resources/VersionResourceServerside.java | 39 +-
.../viewer/resources/_DomainResourceHelper.java | 22 +-
.../viewer/resources/_EndpointLogging.java | 26 +-
.../RequestHeaderUtil.java} | 34 +-
.../CausewayRestfulObjectsInteractionFilter2.java | 463 +++++++++++++++++++++
.../viewer/webmodule/WebModuleRestfulObjects.java | 132 ++++++
.../context/ResourceContext_getArg_Test.java | 7 +
...lObjectsSessionFilter_lookupPassThru_Test2.java | 76 ++++
65 files changed, 1955 insertions(+), 1825 deletions(-)
diff --git a/api/applib/src/main/java/org/apache/causeway/applib/client/RepresentationTypeSimplifiedV2.java b/api/applib/src/main/java/org/apache/causeway/applib/client/RepresentationTypeSimplifiedV2.java
index ef84ddc40e8..5af382eb7e0 100644
--- a/api/applib/src/main/java/org/apache/causeway/applib/client/RepresentationTypeSimplifiedV2.java
+++ b/api/applib/src/main/java/org/apache/causeway/applib/client/RepresentationTypeSimplifiedV2.java
@@ -18,17 +18,20 @@
*/
package org.apache.causeway.applib.client;
+import java.util.Map;
import java.util.Objects;
import java.util.Optional;
import java.util.stream.Stream;
+import org.jspecify.annotations.NonNull;
import org.jspecify.annotations.Nullable;
+import org.springframework.http.MediaType;
+
import org.apache.causeway.commons.internal.base._Strings;
import org.apache.causeway.commons.internal.base._Strings.KeyValuePair;
import lombok.Getter;
-import org.jspecify.annotations.NonNull;
import lombok.RequiredArgsConstructor;
/**
@@ -87,12 +90,19 @@ public enum RepresentationTypeSimplifiedV2 {
public boolean isValues() { return this == VALUES; }
public boolean isVoid() { return this == VOID; }
- public String getContentTypeHeaderValue(final String profileName) {
- return "application/json;"
- + "profile=\"" + profileName + "\""
- + ";repr-type=\"" + typeLiteral + "\"";
+ public MediaType getResponseContentType(final String profileName) {
+ return new MediaType("application", "json", Map.of(
+ "profile", profileName,
+ "repr-type", typeLiteral));
}
+//TODO[causeway-applib-CAUSEWAY-3892] remove
+// private String contentTypeValue(final String profileName) {
+// return "application/json;"
+// + "profile=\"" + profileName + "\""
+// + ";repr-type=\"" + typeLiteral + "\"";
+// }
+
public static Optional<RepresentationTypeSimplifiedV2> parse(
final @Nullable String typeLiteral) {
return Stream.of(RepresentationTypeSimplifiedV2.values())
@@ -125,16 +135,16 @@ private static Optional<String> extractReprType(final @NonNull Stream<String> st
return stringStream
//.peek(System.err::println)//debug
- .map(String::trim)
- .filter(_Strings::isNotEmpty)
- //.map(s->s.replace("profile=\"urn:org.restfulobjects:repr-types/", "repr-type=\""))
- .filter(s->s.startsWith("repr-type"))
- .map(s->_Strings.parseKeyValuePair(s, '=').orElse(null))
- .filter(Objects::nonNull)
- .map(KeyValuePair::value)
- .filter(_Strings::isNotEmpty)
- .findAny()
- .map(RepresentationTypeSimplifiedV2::trimQuotesIfAny);
+ .map(String::trim)
+ .filter(_Strings::isNotEmpty)
+ //.map(s->s.replace("profile=\"urn:org.restfulobjects:repr-types/", "repr-type=\""))
+ .filter(s->s.startsWith("repr-type"))
+ .map(s->_Strings.parseKeyValuePair(s, '=').orElse(null))
+ .filter(Objects::nonNull)
+ .map(KeyValuePair::value)
+ .filter(_Strings::isNotEmpty)
+ .findAny()
+ .map(RepresentationTypeSimplifiedV2::trimQuotesIfAny);
}
}
diff --git a/viewers/restfulobjects/applib/src/main/java/module-info.java b/viewers/restfulobjects/applib/src/main/java/module-info.java
index 348004e0498..dab0319d4f8 100644
--- a/viewers/restfulobjects/applib/src/main/java/module-info.java
+++ b/viewers/restfulobjects/applib/src/main/java/module-info.java
@@ -17,18 +17,18 @@
* under the License.
*/
module org.apache.causeway.viewer.restfulobjects.applib {
- exports org.apache.causeway.viewer.restfulobjects.applib.homepage;
- exports org.apache.causeway.viewer.restfulobjects.applib.errors;
- exports org.apache.causeway.viewer.restfulobjects.applib.util;
+ exports org.apache.causeway.viewer.restfulobjects.applib;
+ exports org.apache.causeway.viewer.restfulobjects.applib.boot;
exports org.apache.causeway.viewer.restfulobjects.applib.domaintypes;
exports org.apache.causeway.viewer.restfulobjects.applib.domainobjects;
- exports org.apache.causeway.viewer.restfulobjects.applib.version;
- exports org.apache.causeway.viewer.restfulobjects.applib.boot;
- exports org.apache.causeway.viewer.restfulobjects.applib;
+ exports org.apache.causeway.viewer.restfulobjects.applib.dtos;
+ exports org.apache.causeway.viewer.restfulobjects.applib.errors;
exports org.apache.causeway.viewer.restfulobjects.applib.health;
+ exports org.apache.causeway.viewer.restfulobjects.applib.homepage;
exports org.apache.causeway.viewer.restfulobjects.applib.menubars;
exports org.apache.causeway.viewer.restfulobjects.applib.user;
- exports org.apache.causeway.viewer.restfulobjects.applib.dtos;
+ exports org.apache.causeway.viewer.restfulobjects.applib.util;
+ exports org.apache.causeway.viewer.restfulobjects.applib.version;
requires static lombok;
diff --git a/viewers/restfulobjects/applib/src/main/java/org/apache/causeway/viewer/restfulobjects/applib/RepresentationType.java b/viewers/restfulobjects/applib/src/main/java/org/apache/causeway/viewer/restfulobjects/applib/RepresentationType.java
index 20eb30d31e9..847898cb4a1 100644
--- a/viewers/restfulobjects/applib/src/main/java/org/apache/causeway/viewer/restfulobjects/applib/RepresentationType.java
+++ b/viewers/restfulobjects/applib/src/main/java/org/apache/causeway/viewer/restfulobjects/applib/RepresentationType.java
@@ -196,7 +196,7 @@ public MediaType getMediaType(final String parameter, final String paramValue) {
}
public MediaType getJsonMediaType(final Map<String, String> mediaTypeParams) {
- Map<String, String> parameters = new HashMap<>(jsonMediaType.getParameters());
+ var parameters = new HashMap<>(jsonMediaType.getParameters());
parameters.putAll(mediaTypeParams);
return new MediaType(jsonMediaType.getType(), jsonMediaType.getSubtype(), parameters);
}
diff --git a/viewers/restfulobjects/applib/src/main/java/org/apache/causeway/viewer/restfulobjects/applib/boot/BootstrapResource.java b/viewers/restfulobjects/applib/src/main/java/org/apache/causeway/viewer/restfulobjects/applib/boot/BootstrapResource.java
index 659f524d81f..e6b011116ea 100644
--- a/viewers/restfulobjects/applib/src/main/java/org/apache/causeway/viewer/restfulobjects/applib/boot/BootstrapResource.java
+++ b/viewers/restfulobjects/applib/src/main/java/org/apache/causeway/viewer/restfulobjects/applib/boot/BootstrapResource.java
@@ -18,19 +18,17 @@
*/
package org.apache.causeway.viewer.restfulobjects.applib.boot;
-import jakarta.ws.rs.GET;
-import jakarta.ws.rs.Path;
-import jakarta.ws.rs.Produces;
import org.springframework.http.MediaType;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.RequestMapping;
/**
* @since 1.x {@index}
*/
-@Path("/boot")
+@RequestMapping("${causeway.viewer.restfulobjects.path-prefix}/boot")
public interface BootstrapResource {
- @GET
- @Produces({ MediaType.TEXT_HTML_VALUE })
+ @GetMapping(path = "/", produces = {MediaType.TEXT_HTML_VALUE})
public String bootstrap();
}
diff --git a/viewers/restfulobjects/applib/src/main/java/org/apache/causeway/viewer/restfulobjects/applib/domainobjects/DomainObjectResource.java b/viewers/restfulobjects/applib/src/main/java/org/apache/causeway/viewer/restfulobjects/applib/domainobjects/DomainObjectResource.java
index 828587033f6..15a61c27de5 100644
--- a/viewers/restfulobjects/applib/src/main/java/org/apache/causeway/viewer/restfulobjects/applib/domainobjects/DomainObjectResource.java
+++ b/viewers/restfulobjects/applib/src/main/java/org/apache/causeway/viewer/restfulobjects/applib/domainobjects/DomainObjectResource.java
@@ -20,195 +20,146 @@
import java.io.InputStream;
-import jakarta.ws.rs.DELETE;
-import jakarta.ws.rs.GET;
-import jakarta.ws.rs.POST;
-import jakarta.ws.rs.PUT;
-import jakarta.ws.rs.Path;
-import jakarta.ws.rs.PathParam;
-import jakarta.ws.rs.Produces;
-import jakarta.ws.rs.QueryParam;
import org.springframework.http.MediaType;
+import org.springframework.http.ResponseEntity;
+import org.springframework.web.bind.annotation.DeleteMapping;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestMapping;
-
-import jakarta.ws.rs.core.Response;
+import org.springframework.web.bind.annotation.RequestParam;
import org.apache.causeway.viewer.restfulobjects.applib.RestfulMediaType;
/**
* @since 1.x {@index}
*/
-@RequestMapping("${roPrefix}/objects")
+@RequestMapping("${causeway.viewer.restfulobjects.path-prefix}/objects")
public interface DomainObjectResource {
- @POST
- @Path("/{domainType}")
- //@Consumes({ MediaType.WILDCARD })
- @Produces({
- MediaType.APPLICATION_JSON_VALUE, RestfulMediaType.APPLICATION_JSON_OBJECT, RestfulMediaType.APPLICATION_JSON_ERROR,
- MediaType.APPLICATION_XML_VALUE, RestfulMediaType.APPLICATION_XML_OBJECT, RestfulMediaType.APPLICATION_XML_ERROR
+ @PostMapping(path = "/{domainType}", produces = {
+ MediaType.APPLICATION_JSON_VALUE, RestfulMediaType.APPLICATION_JSON_OBJECT, RestfulMediaType.APPLICATION_JSON_ERROR,
+ MediaType.APPLICATION_XML_VALUE, RestfulMediaType.APPLICATION_XML_OBJECT, RestfulMediaType.APPLICATION_XML_ERROR
})
- public Response persist(@PathParam("domainType") String domainType, final InputStream object);
+ public ResponseEntity<Object> persist(@PathVariable String domainType, InputStream object);
// -- DOMAIN OBJECT
- @GET
- @Path("/{domainType}/{instanceId}")
- //@Consumes({ MediaType.WILDCARD })
- @Produces({
- MediaType.APPLICATION_JSON_VALUE, RestfulMediaType.APPLICATION_JSON_OBJECT, RestfulMediaType.APPLICATION_JSON_ERROR,
- MediaType.APPLICATION_XML_VALUE, RestfulMediaType.APPLICATION_XML_OBJECT, RestfulMediaType.APPLICATION_XML_ERROR
- })
- public Response object(@PathParam("domainType") String domainType, @PathParam("instanceId") final String instanceId);
-
- @PUT
- @Path("/{domainType}/{instanceId}")
- //@Consumes({ MediaType.WILDCARD })
- @Produces({
- MediaType.APPLICATION_JSON_VALUE, RestfulMediaType.APPLICATION_JSON_OBJECT, RestfulMediaType.APPLICATION_JSON_ERROR,
- MediaType.APPLICATION_XML_VALUE, RestfulMediaType.APPLICATION_XML_OBJECT, RestfulMediaType.APPLICATION_XML_ERROR
+ @GetMapping(path = "/{domainType}/{instanceId}", produces = {
+ MediaType.APPLICATION_JSON_VALUE, RestfulMediaType.APPLICATION_JSON_OBJECT, RestfulMediaType.APPLICATION_JSON_ERROR,
+ MediaType.APPLICATION_XML_VALUE, RestfulMediaType.APPLICATION_XML_OBJECT, RestfulMediaType.APPLICATION_XML_ERROR
+ })
+ public ResponseEntity<Object> object(@PathVariable String domainType, @PathVariable String instanceId);
+
+ @PutMapping(path = "/{domainType}/{instanceId}", produces = {
+ MediaType.APPLICATION_JSON_VALUE, RestfulMediaType.APPLICATION_JSON_OBJECT, RestfulMediaType.APPLICATION_JSON_ERROR,
+ MediaType.APPLICATION_XML_VALUE, RestfulMediaType.APPLICATION_XML_OBJECT, RestfulMediaType.APPLICATION_XML_ERROR
})
- public Response object(@PathParam("domainType") String domainType, @PathParam("instanceId") final String instanceId, final InputStream arguments);
+ public ResponseEntity<Object> object(@PathVariable String domainType, @PathVariable String instanceId, InputStream arguments);
- @DELETE
- @Path("/{domainType}/{instanceId}")
- public Response deleteMethodNotSupported(@PathParam("domainType") String domainType, @PathParam("instanceId") final String instanceId);
+ @DeleteMapping(path = "/{domainType}/{instanceId}")
+ public ResponseEntity<Object> deleteMethodNotSupported(@PathVariable String domainType, @PathVariable String instanceId);
- @POST
- @Path("/{domainType}/{instanceId}")
- public Response postMethodNotAllowed(@PathParam("domainType") String domainType, @PathParam("instanceId") final String instanceId);
+ @PostMapping(path = "/{domainType}/{instanceId}")
+ public ResponseEntity<Object> postMethodNotAllowed(@PathVariable String domainType, @PathVariable String instanceId);
// -- DOMAIN OBJECT IMAGE
- @GET
- @Path("/{domainType}/{instanceId}/image")
- //@Consumes({ MediaType.WILDCARD })
- @Produces({
- "image/png",
- "image/gif",
- "image/jpeg",
- "image/jpg",
- "image/svg+xml"
+ @GetMapping(path = "/{domainType}/{instanceId}/image", produces = {
+ "image/png",
+ "image/gif",
+ "image/jpeg",
+ "image/jpg",
+ "image/svg+xml"
})
- public Response image(
- @PathParam("domainType")
- final String domainType,
- @PathParam("instanceId")
- final String instanceId);
+ public ResponseEntity<Object> image(
+ @PathVariable
+ String domainType,
+ @PathVariable
+ String instanceId);
// -- DOMAIN OBJECT LAYOUT
- @GET
- @Path("/{domainType}/{instanceId}/object-layout")
- //@Consumes({ MediaType.WILDCARD })
- @Produces({
- MediaType.APPLICATION_JSON_VALUE, RestfulMediaType.APPLICATION_JSON_OBJECT_LAYOUT_BS,
- MediaType.APPLICATION_XML_VALUE, RestfulMediaType.APPLICATION_XML_OBJECT_LAYOUT_BS
+ @GetMapping(path = "/{domainType}/{instanceId}/object-layout", produces = {
+ MediaType.APPLICATION_JSON_VALUE, RestfulMediaType.APPLICATION_JSON_OBJECT_LAYOUT_BS,
+ MediaType.APPLICATION_XML_VALUE, RestfulMediaType.APPLICATION_XML_OBJECT_LAYOUT_BS
})
- public Response layout(
- @PathParam("domainType")
- final String domainType,
- @PathParam("instanceId")
- final String instanceId);
+ public ResponseEntity<Object> layout(
+ @PathVariable
+ String domainType,
+ @PathVariable
+ String instanceId);
// -- DOMAIN OBJECT PROPERTY
- @GET
- @Path("/{domainType}/{instanceId}/properties/{propertyId}")
- //@Consumes({ MediaType.WILDCARD })
- @Produces({
- MediaType.APPLICATION_JSON_VALUE, RestfulMediaType.APPLICATION_JSON_OBJECT_PROPERTY, RestfulMediaType.APPLICATION_JSON_ERROR,
- MediaType.APPLICATION_XML_VALUE, RestfulMediaType.APPLICATION_XML_OBJECT_PROPERTY, RestfulMediaType.APPLICATION_XML_ERROR
+ @GetMapping(path = "/{domainType}/{instanceId}/properties/{propertyId}", produces = {
+ MediaType.APPLICATION_JSON_VALUE, RestfulMediaType.APPLICATION_JSON_OBJECT_PROPERTY, RestfulMediaType.APPLICATION_JSON_ERROR,
+ MediaType.APPLICATION_XML_VALUE, RestfulMediaType.APPLICATION_XML_OBJECT_PROPERTY, RestfulMediaType.APPLICATION_XML_ERROR
})
- public Response propertyDetails(@PathParam("domainType") String domainType, @PathParam("instanceId") final String instanceId, @PathParam("propertyId") final String propertyId);
-
- @PUT
- @Path("/{domainType}/{instanceId}/properties/{propertyId}")
- //@Consumes({ MediaType.WILDCARD })
- @Produces({
- MediaType.APPLICATION_JSON_VALUE, RestfulMediaType.APPLICATION_JSON_OBJECT_PROPERTY, RestfulMediaType.APPLICATION_JSON_ERROR,
- MediaType.APPLICATION_XML_VALUE, RestfulMediaType.APPLICATION_XML_OBJECT_PROPERTY, RestfulMediaType.APPLICATION_XML_ERROR
+ public ResponseEntity<Object> propertyDetails(@PathVariable String domainType, @PathVariable String instanceId, @PathVariable String propertyId);
+
+ @PutMapping(path = "/{domainType}/{instanceId}/properties/{propertyId}", produces = {
+ MediaType.APPLICATION_JSON_VALUE, RestfulMediaType.APPLICATION_JSON_OBJECT_PROPERTY, RestfulMediaType.APPLICATION_JSON_ERROR,
+ MediaType.APPLICATION_XML_VALUE, RestfulMediaType.APPLICATION_XML_OBJECT_PROPERTY, RestfulMediaType.APPLICATION_XML_ERROR
})
- public Response modifyProperty(@PathParam("domainType") String domainType, @PathParam("instanceId") final String instanceId, @PathParam("propertyId") final String propertyId, final InputStream arguments);
-
- @DELETE
- @Path("/{domainType}/{instanceId}/properties/{propertyId}")
- //@Consumes({ MediaType.WILDCARD })
- @Produces({
- MediaType.APPLICATION_JSON_VALUE, RestfulMediaType.APPLICATION_JSON_OBJECT_PROPERTY, RestfulMediaType.APPLICATION_JSON_ERROR,
- MediaType.APPLICATION_XML_VALUE, RestfulMediaType.APPLICATION_XML_OBJECT_PROPERTY, RestfulMediaType.APPLICATION_XML_ERROR
+ public ResponseEntity<Object> modifyProperty(@PathVariable String domainType, @PathVariable String instanceId, @PathVariable String propertyId, InputStream arguments);
+
+ @DeleteMapping(path = "/{domainType}/{instanceId}/properties/{propertyId}", produces = {
+ MediaType.APPLICATION_JSON_VALUE, RestfulMediaType.APPLICATION_JSON_OBJECT_PROPERTY, RestfulMediaType.APPLICATION_JSON_ERROR,
+ MediaType.APPLICATION_XML_VALUE, RestfulMediaType.APPLICATION_XML_OBJECT_PROPERTY, RestfulMediaType.APPLICATION_XML_ERROR
})
- public Response clearProperty(@PathParam("domainType") String domainType, @PathParam("instanceId") final String instanceId, @PathParam("propertyId") final String propertyId);
+ public ResponseEntity<Object> clearProperty(@PathVariable String domainType, @PathVariable String instanceId, @PathVariable String propertyId);
- @POST
- @Path("/{domainType}/{instanceId}/properties/{propertyId}")
- public Response postPropertyNotAllowed(@PathParam("domainType") String domainType, @PathParam("instanceId") final String instanceId, @PathParam("propertyId") final String propertyId);
+ @PostMapping(path = "/{domainType}/{instanceId}/properties/{propertyId}")
+ public ResponseEntity<Object> postPropertyNotAllowed(@PathVariable String domainType, @PathVariable String instanceId, @PathVariable String propertyId);
// -- DOMAIN OBJECT COLLECTION
- @GET
- @Path("/{domainType}/{instanceId}/collections/{collectionId}")
- //@Consumes({ MediaType.WILDCARD })
- @Produces({
- MediaType.APPLICATION_JSON_VALUE, RestfulMediaType.APPLICATION_JSON_OBJECT_COLLECTION, RestfulMediaType.APPLICATION_JSON_ERROR,
- MediaType.APPLICATION_XML_VALUE, RestfulMediaType.APPLICATION_XML_OBJECT_COLLECTION, RestfulMediaType.APPLICATION_XML_ERROR
+ @GetMapping(path = "/{domainType}/{instanceId}/collections/{collectionId}", produces = {
+ MediaType.APPLICATION_JSON_VALUE, RestfulMediaType.APPLICATION_JSON_OBJECT_COLLECTION, RestfulMediaType.APPLICATION_JSON_ERROR,
+ MediaType.APPLICATION_XML_VALUE, RestfulMediaType.APPLICATION_XML_OBJECT_COLLECTION, RestfulMediaType.APPLICATION_XML_ERROR
})
- public Response accessCollection(@PathParam("domainType") String domainType, @PathParam("instanceId") final String instanceId, @PathParam("collectionId") final String collectionId);
+ public ResponseEntity<Object> accessCollection(@PathVariable String domainType, @PathVariable String instanceId, @PathVariable String collectionId);
// -- DOMAIN OBJECT ACTION
- @GET
- @Path("/{domainType}/{instanceId}/actions/{actionId}")
- //@Consumes({ MediaType.WILDCARD })
- @Produces({
- MediaType.APPLICATION_JSON_VALUE, RestfulMediaType.APPLICATION_JSON_OBJECT_ACTION, RestfulMediaType.APPLICATION_JSON_ERROR,
- MediaType.APPLICATION_XML_VALUE, RestfulMediaType.APPLICATION_XML_OBJECT_ACTION, RestfulMediaType.APPLICATION_XML_ERROR
+ @GetMapping(path = "/{domainType}/{instanceId}/actions/{actionId}", produces = {
+ MediaType.APPLICATION_JSON_VALUE, RestfulMediaType.APPLICATION_JSON_OBJECT_ACTION, RestfulMediaType.APPLICATION_JSON_ERROR,
+ MediaType.APPLICATION_XML_VALUE, RestfulMediaType.APPLICATION_XML_OBJECT_ACTION, RestfulMediaType.APPLICATION_XML_ERROR
})
- public Response actionPrompt(@PathParam("domainType") String domainType, @PathParam("instanceId") final String instanceId, @PathParam("actionId") final String actionId);
+ public ResponseEntity<Object> actionPrompt(@PathVariable String domainType, @PathVariable String instanceId, @PathVariable String actionId);
- @DELETE
- @Path("/{domainType}/{instanceId}/actions/{actionId}")
- public Response deleteActionPromptNotAllowed(@PathParam("domainType") String domainType, @PathParam("instanceId") final String instanceId, @PathParam("actionId") final String actionId);
+ @DeleteMapping(path = "/{domainType}/{instanceId}/actions/{actionId}")
+ public ResponseEntity<Object> deleteActionPromptNotAllowed(@PathVariable String domainType, @PathVariable String instanceId, @PathVariable String actionId);
- @PUT
- @Path("/{domainType}/{instanceId}/actions/{actionId}")
- public Response putActionPromptNotAllowed(@PathParam("domainType") String domainType, @PathParam("instanceId") final String instanceId, @PathParam("actionId") final String actionId);
+ @PutMapping(path = "/{domainType}/{instanceId}/actions/{actionId}")
+ public ResponseEntity<Object> putActionPromptNotAllowed(@PathVariable String domainType, @PathVariable String instanceId, @PathVariable String actionId);
- @POST
- @Path("/{domainType}/{instanceId}/actions/{actionId}")
- public Response postActionPromptNotAllowed(@PathParam("domainType") String domainType, @PathParam("instanceId") final String instanceId, @PathParam("actionId") final String actionId);
+ @PostMapping(path = "/{domainType}/{instanceId}/actions/{actionId}")
+ public ResponseEntity<Object> postActionPromptNotAllowed(@PathVariable String domainType, @PathVariable String instanceId, @PathVariable String actionId);
// -- DOMAIN OBJECT ACTION INVOKE
- @GET
- @Path("/{domainType}/{instanceId}/actions/{actionId}/invoke")
- //@Consumes({ MediaType.WILDCARD })
- @Produces({
- MediaType.APPLICATION_JSON_VALUE, RestfulMediaType.APPLICATION_JSON_ACTION_RESULT, RestfulMediaType.APPLICATION_JSON_ERROR,
- MediaType.APPLICATION_XML_VALUE, RestfulMediaType.APPLICATION_XML_ACTION_RESULT, RestfulMediaType.APPLICATION_XML_ERROR
+ @GetMapping(path = "/{domainType}/{instanceId}/actions/{actionId}/invoke", produces = {
+ MediaType.APPLICATION_JSON_VALUE, RestfulMediaType.APPLICATION_JSON_ACTION_RESULT, RestfulMediaType.APPLICATION_JSON_ERROR,
+ MediaType.APPLICATION_XML_VALUE, RestfulMediaType.APPLICATION_XML_ACTION_RESULT, RestfulMediaType.APPLICATION_XML_ERROR
})
- public Response invokeActionQueryOnly(@PathParam("domainType") String domainType, @PathParam("instanceId") final String instanceId, @PathParam("actionId") final String actionId, @QueryParam("x-causeway-querystring") final String xCausewayQueryString);
-
- @PUT
- @Path("/{domainType}/{instanceId}/actions/{actionId}/invoke")
- //@Consumes({ MediaType.WILDCARD })
- @Produces({
- MediaType.APPLICATION_JSON_VALUE, RestfulMediaType.APPLICATION_JSON_ACTION_RESULT, RestfulMediaType.APPLICATION_JSON_ERROR,
- MediaType.APPLICATION_XML_VALUE, RestfulMediaType.APPLICATION_XML_ACTION_RESULT, RestfulMediaType.APPLICATION_XML_ERROR
+ public ResponseEntity<Object> invokeActionQueryOnly(@PathVariable String domainType, @PathVariable String instanceId, @PathVariable String actionId, @RequestParam("x-causeway-querystring") String xCausewayQueryString);
+
+ @PutMapping(path = "/{domainType}/{instanceId}/actions/{actionId}/invoke", produces = {
+ MediaType.APPLICATION_JSON_VALUE, RestfulMediaType.APPLICATION_JSON_ACTION_RESULT, RestfulMediaType.APPLICATION_JSON_ERROR,
+ MediaType.APPLICATION_XML_VALUE, RestfulMediaType.APPLICATION_XML_ACTION_RESULT, RestfulMediaType.APPLICATION_XML_ERROR
})
- public Response invokeActionIdempotent(@PathParam("domainType") String domainType, @PathParam("instanceId") final String instanceId, @PathParam("actionId") final String actionId, final InputStream arguments);
-
- @POST
- @Path("/{domainType}/{instanceId}/actions/{actionId}/invoke")
- //@Consumes({ MediaType.WILDCARD })
- @Produces({
- MediaType.APPLICATION_JSON_VALUE, RestfulMediaType.APPLICATION_JSON_ACTION_RESULT, RestfulMediaType.APPLICATION_JSON_ERROR,
- MediaType.APPLICATION_XML_VALUE, RestfulMediaType.APPLICATION_XML_ACTION_RESULT, RestfulMediaType.APPLICATION_XML_ERROR
+ public ResponseEntity<Object> invokeActionIdempotent(@PathVariable String domainType, @PathVariable String instanceId, @PathVariable String actionId, InputStream arguments);
+
+ @PostMapping(path = "/{domainType}/{instanceId}/actions/{actionId}/invoke", produces = {
+ MediaType.APPLICATION_JSON_VALUE, RestfulMediaType.APPLICATION_JSON_ACTION_RESULT, RestfulMediaType.APPLICATION_JSON_ERROR,
+ MediaType.APPLICATION_XML_VALUE, RestfulMediaType.APPLICATION_XML_ACTION_RESULT, RestfulMediaType.APPLICATION_XML_ERROR
})
- public Response invokeAction(@PathParam("domainType") String domainType, @PathParam("instanceId") final String instanceId, @PathParam("actionId") final String actionId, final InputStream arguments);
+ public ResponseEntity<Object> invokeAction(@PathVariable String domainType, @PathVariable String instanceId, @PathVariable String actionId, InputStream arguments);
- @DELETE
- @Path("/{domainType}/{instanceId}/actions/{actionId}/invoke")
- public Response deleteInvokeActionNotAllowed(@PathParam("domainType") String domainType, @PathParam("instanceId") final String instanceId, @PathParam("actionId") final String actionId);
+ @DeleteMapping(path = "/{domainType}/{instanceId}/actions/{actionId}/invoke")
+ public ResponseEntity<Object> deleteInvokeActionNotAllowed(@PathVariable String domainType, @PathVariable String instanceId, @PathVariable String actionId);
}
diff --git a/viewers/restfulobjects/applib/src/main/java/org/apache/causeway/viewer/restfulobjects/applib/domainobjects/DomainServiceResource.java b/viewers/restfulobjects/applib/src/main/java/org/apache/causeway/viewer/restfulobjects/applib/domainobjects/DomainServiceResource.java
index debf186151e..72e9baeadc2 100644
--- a/viewers/restfulobjects/applib/src/main/java/org/apache/causeway/viewer/restfulobjects/applib/domainobjects/DomainServiceResource.java
+++ b/viewers/restfulobjects/applib/src/main/java/org/apache/causeway/viewer/restfulobjects/applib/domainobjects/DomainServiceResource.java
@@ -20,36 +20,35 @@
import java.io.InputStream;
-import jakarta.ws.rs.PathParam;
-import jakarta.ws.rs.QueryParam;
import org.springframework.http.MediaType;
+import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestMapping;
-
-import jakarta.ws.rs.core.Response;
+import org.springframework.web.bind.annotation.RequestParam;
import org.apache.causeway.viewer.restfulobjects.applib.RestfulMediaType;
/**
* @since 1.x {@index}
*/
-@RequestMapping("${roPrefix}/services")
+@RequestMapping("${causeway.viewer.restfulobjects.path-prefix}/services")
public interface DomainServiceResource {
@GetMapping(produces = { MediaType.APPLICATION_JSON_VALUE, RestfulMediaType.APPLICATION_JSON_LIST, RestfulMediaType.APPLICATION_JSON_ERROR })
- public Response services();
+ public ResponseEntity<Object> services();
@DeleteMapping
- public Response deleteServicesNotAllowed();
+ public ResponseEntity<Object> deleteServicesNotAllowed();
@PutMapping
- public Response putServicesNotAllowed();
+ public ResponseEntity<Object> putServicesNotAllowed();
@PostMapping
- public Response postServicesNotAllowed();
+ public ResponseEntity<Object> postServicesNotAllowed();
// -- DOMAIN SERVICE
@@ -59,16 +58,16 @@ public interface DomainServiceResource {
MediaType.APPLICATION_JSON_VALUE, RestfulMediaType.APPLICATION_JSON_OBJECT, RestfulMediaType.APPLICATION_JSON_ERROR,
MediaType.APPLICATION_XML_VALUE, RestfulMediaType.APPLICATION_XML_OBJECT, RestfulMediaType.APPLICATION_XML_ERROR
})
- public Response service(@PathParam("serviceId") final String serviceId);
+ public ResponseEntity<Object> service(@PathVariable String serviceId);
@DeleteMapping(path = "/{serviceId}")
- public Response deleteServiceNotAllowed(@PathParam("serviceId") final String serviceId);
+ public ResponseEntity<Object> deleteServiceNotAllowed(@PathVariable String serviceId);
@PutMapping(path = "/{serviceId}")
- public Response putServiceNotAllowed(@PathParam("serviceId") final String serviceId);
+ public ResponseEntity<Object> putServiceNotAllowed(@PathVariable String serviceId);
@PostMapping(path = "/{serviceId}")
- public Response postServiceNotAllowed(@PathParam("serviceId") final String serviceId);
+ public ResponseEntity<Object> postServiceNotAllowed(@PathVariable String serviceId);
// -- DOMAIN SERVICE ACTION
@@ -78,16 +77,16 @@ public interface DomainServiceResource {
MediaType.APPLICATION_JSON_VALUE, RestfulMediaType.APPLICATION_JSON_OBJECT_ACTION, RestfulMediaType.APPLICATION_JSON_ERROR,
MediaType.APPLICATION_XML_VALUE, RestfulMediaType.APPLICATION_XML_OBJECT_ACTION, RestfulMediaType.APPLICATION_XML_ERROR
})
- public Response actionPrompt(@PathParam("serviceId") final String serviceId, @PathParam("actionId") final String actionId);
+ public ResponseEntity<Object> actionPrompt(@PathVariable String serviceId, @PathVariable String actionId);
@DeleteMapping(path = "/{serviceId}/actions/{actionId}")
- public Response deleteActionPromptNotAllowed(@PathParam("serviceId") final String serviceId, @PathParam("actionId") final String actionId);
+ public ResponseEntity<Object> deleteActionPromptNotAllowed(@PathVariable String serviceId, @PathVariable String actionId);
@PutMapping(path = "/{serviceId}/actions/{actionId}")
- public Response putActionPromptNotAllowed(@PathParam("serviceId") final String serviceId, @PathParam("actionId") final String actionId);
+ public ResponseEntity<Object> putActionPromptNotAllowed(@PathVariable String serviceId, @PathVariable String actionId);
@PostMapping(path = "/{serviceId}/actions/{actionId}")
- public Response postActionPromptNotAllowed(@PathParam("serviceId") final String serviceId, @PathParam("actionId") final String actionId);
+ public ResponseEntity<Object> postActionPromptNotAllowed(@PathVariable String serviceId, @PathVariable String actionId);
// -- DOMAIN SERVICE ACTION INVOKE
@@ -103,7 +102,7 @@ public interface DomainServiceResource {
MediaType.APPLICATION_JSON_VALUE, RestfulMediaType.APPLICATION_JSON_ACTION_RESULT, RestfulMediaType.APPLICATION_JSON_ERROR,
MediaType.APPLICATION_XML_VALUE, RestfulMediaType.APPLICATION_XML_ACTION_RESULT, RestfulMediaType.APPLICATION_XML_ERROR
})
- public Response invokeActionQueryOnly(@PathParam("serviceId") final String serviceId, @PathParam("actionId") final String actionId, @QueryParam("x-causeway-querystring") final String xCausewayQueryString);
+ public ResponseEntity<Object> invokeActionQueryOnly(@PathVariable String serviceId, @PathVariable String actionId, @RequestParam("x-causeway-querystring") String xCausewayQueryString);
@PutMapping(
path = "/{serviceId}/actions/{actionId}/invoke",
@@ -111,15 +110,15 @@ public interface DomainServiceResource {
MediaType.APPLICATION_JSON_VALUE, RestfulMediaType.APPLICATION_JSON_ACTION_RESULT, RestfulMediaType.APPLICATION_JSON_ERROR,
MediaType.APPLICATION_XML_VALUE, RestfulMediaType.APPLICATION_XML_ACTION_RESULT, RestfulMediaType.APPLICATION_XML_ERROR
})
- public Response invokeActionIdempotent(@PathParam("serviceId") final String serviceId, @PathParam("actionId") final String actionId, final InputStream arguments);
+ public ResponseEntity<Object> invokeActionIdempotent(@PathVariable String serviceId, @PathVariable String actionId, InputStream arguments);
@PostMapping(path = "/{serviceId}/actions/{actionId}/invoke",
produces = {
MediaType.APPLICATION_JSON_VALUE, RestfulMediaType.APPLICATION_JSON_ACTION_RESULT, RestfulMediaType.APPLICATION_JSON_ERROR,
MediaType.APPLICATION_XML_VALUE, RestfulMediaType.APPLICATION_XML_ACTION_RESULT, RestfulMediaType.APPLICATION_XML_ERROR
})
- public Response invokeAction(@PathParam("serviceId") final String serviceId, @PathParam("actionId") final String actionId, final InputStream arguments);
+ public ResponseEntity<Object> invokeAction(@PathVariable String serviceId, @PathVariable String actionId, InputStream arguments);
@DeleteMapping(path = "/{serviceId}/actions/{actionId}/invoke")
- public Response deleteInvokeActionNotAllowed(@PathParam("serviceId") final String serviceId, @PathParam("actionId") final String actionId);
+ public ResponseEntity<Object> deleteInvokeActionNotAllowed(@PathVariable String serviceId, @PathVariable String actionId);
}
diff --git a/viewers/restfulobjects/applib/src/main/java/org/apache/causeway/viewer/restfulobjects/applib/domaintypes/DomainTypeResource.java b/viewers/restfulobjects/applib/src/main/java/org/apache/causeway/viewer/restfulobjects/applib/domaintypes/DomainTypeResource.java
index b8e808e8a1f..c38d710f006 100644
--- a/viewers/restfulobjects/applib/src/main/java/org/apache/causeway/viewer/restfulobjects/applib/domaintypes/DomainTypeResource.java
+++ b/viewers/restfulobjects/applib/src/main/java/org/apache/causeway/viewer/restfulobjects/applib/domaintypes/DomainTypeResource.java
@@ -18,75 +18,68 @@
*/
package org.apache.causeway.viewer.restfulobjects.applib.domaintypes;
-import jakarta.ws.rs.GET;
-import jakarta.ws.rs.Path;
-import jakarta.ws.rs.PathParam;
-import jakarta.ws.rs.Produces;
-import jakarta.ws.rs.QueryParam;
import org.springframework.http.MediaType;
-import jakarta.ws.rs.core.Response;
+import org.springframework.http.ResponseEntity;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestParam;
import org.apache.causeway.viewer.restfulobjects.applib.RestfulMediaType;
/**
* @since 1.x {@index}
*/
-@Path("/domain-types")
+@RequestMapping("${causeway.viewer.restfulobjects.path-prefix}/domain-types")
public interface DomainTypeResource {
- @GET
- @Path("/")
- @Produces({ MediaType.APPLICATION_JSON_VALUE, RestfulMediaType.APPLICATION_JSON_TYPE_LIST })
- public abstract Response domainTypes();
+ @GetMapping(path = "/", produces = {MediaType.APPLICATION_JSON_VALUE, RestfulMediaType.APPLICATION_JSON_TYPE_LIST})
+ ResponseEntity<Object> domainTypes();
- @GET
- @Path("/{domainType}")
- @Produces({ MediaType.APPLICATION_JSON_VALUE, RestfulMediaType.APPLICATION_JSON_DOMAIN_TYPE })
- public abstract Response domainType(@PathParam("domainType") final String domainType);
+ @GetMapping(path = "/{domainType}", produces = {MediaType.APPLICATION_JSON_VALUE, RestfulMediaType.APPLICATION_JSON_DOMAIN_TYPE})
+ ResponseEntity<Object> domainType(@PathVariable String domainType);
- @GET
- @Path("/{domainType}/layout")
- @Produces({
- MediaType.APPLICATION_JSON_VALUE, RestfulMediaType.APPLICATION_JSON_LAYOUT_BS,
- MediaType.APPLICATION_XML_VALUE, RestfulMediaType.APPLICATION_XML_LAYOUT_BS
+ @GetMapping(path = "/{domainType}/layout", produces = {
+ MediaType.APPLICATION_JSON_VALUE, RestfulMediaType.APPLICATION_JSON_LAYOUT_BS,
+ MediaType.APPLICATION_XML_VALUE, RestfulMediaType.APPLICATION_XML_LAYOUT_BS
})
- public abstract Response layout(@PathParam("domainType") final String domainType);
+ ResponseEntity<Object> layout(@PathVariable String domainType);
- @GET
- @Path("/{domainType}/properties/{propertyId}")
- @Produces({ MediaType.APPLICATION_JSON_VALUE, RestfulMediaType.APPLICATION_JSON_PROPERTY_DESCRIPTION })
- public abstract Response typeProperty(@PathParam("domainType") final String domainType, @PathParam("propertyId") final String propertyId);
+ @GetMapping(path = "/{domainType}/properties/{propertyId}", produces = {
+ MediaType.APPLICATION_JSON_VALUE, RestfulMediaType.APPLICATION_JSON_PROPERTY_DESCRIPTION
+ })
+ ResponseEntity<Object> typeProperty(@PathVariable String domainType, @PathVariable String propertyId);
- @GET
- @Path("/{domainType}/collections/{collectionId}")
- @Produces({ MediaType.APPLICATION_JSON_VALUE, RestfulMediaType.APPLICATION_JSON_COLLECTION_DESCRIPTION })
- public abstract Response typeCollection(@PathParam("domainType") final String domainType, @PathParam("collectionId") final String collectionId);
+ @GetMapping(path = "/{domainType}/collections/{collectionId}", produces = {
+ MediaType.APPLICATION_JSON_VALUE, RestfulMediaType.APPLICATION_JSON_COLLECTION_DESCRIPTION
+ })
+ ResponseEntity<Object> typeCollection(@PathVariable String domainType, @PathVariable String collectionId);
- @GET
- @Path("/{domainType}/actions/{actionId}")
- @Produces({ MediaType.APPLICATION_JSON_VALUE, RestfulMediaType.APPLICATION_JSON_ACTION_DESCRIPTION })
- public abstract Response typeAction(@PathParam("domainType") final String domainType, @PathParam("actionId") final String actionId);
+ @GetMapping(path = "/{domainType}/actions/{actionId}", produces = {
+ MediaType.APPLICATION_JSON_VALUE, RestfulMediaType.APPLICATION_JSON_ACTION_DESCRIPTION
+ })
+ ResponseEntity<Object> typeAction(@PathVariable String domainType, @PathVariable String actionId);
- @GET
- @Path("/{domainType}/actions/{actionId}/params/{paramId}")
- @Produces({ MediaType.APPLICATION_JSON_VALUE, RestfulMediaType.APPLICATION_JSON_ACTION_PARAMETER_DESCRIPTION })
- public abstract Response typeActionParam(@PathParam("domainType") final String domainType, @PathParam("actionId") final String actionId, @PathParam("paramId") final String paramId);
+ @GetMapping(path = "/{domainType}/actions/{actionId}/params/{paramId}", produces = {
+ MediaType.APPLICATION_JSON_VALUE, RestfulMediaType.APPLICATION_JSON_ACTION_PARAMETER_DESCRIPTION
+ })
+ ResponseEntity<Object> typeActionParam(@PathVariable String domainType, @PathVariable String actionId, @PathVariable String paramId);
- @GET
- @Path("/{domainType}/isSubtypeOf/invoke")
- @Produces({ MediaType.APPLICATION_JSON_VALUE, RestfulMediaType.APPLICATION_JSON_TYPE_ACTION_RESULT, RestfulMediaType.APPLICATION_JSON_ERROR })
- public abstract Response domainTypeIsSubtypeOf(
- @PathParam("domainType") final String domainType,
- @QueryParam("supertype") String superType, // simple style
- @QueryParam("args") final String argumentsQueryString // formal style
+ @GetMapping(path = "/{domainType}/isSubtypeOf/invoke", produces = {
+ MediaType.APPLICATION_JSON_VALUE, RestfulMediaType.APPLICATION_JSON_TYPE_ACTION_RESULT, RestfulMediaType.APPLICATION_JSON_ERROR
+ })
+ ResponseEntity<Object> domainTypeIsSubtypeOf(
+ @PathVariable String domainType,
+ @RequestParam("supertype") String superType, // simple style
+ @RequestParam("args") String argumentsQueryString // formal style
);
- @GET
- @Path("/{domainType}/isSupertypeOf/invoke")
- @Produces({ MediaType.APPLICATION_JSON_VALUE, RestfulMediaType.APPLICATION_JSON_TYPE_ACTION_RESULT, RestfulMediaType.APPLICATION_JSON_ERROR })
- public abstract Response domainTypeIsSupertypeOf(
- @PathParam("domainType") final String domainType,
- @QueryParam("supertype") String superType, // simple style
- @QueryParam("args") final String argumentsQueryString // formal style
+ @GetMapping(path = "/{domainType}/isSupertypeOf/invoke", produces = {
+ MediaType.APPLICATION_JSON_VALUE, RestfulMediaType.APPLICATION_JSON_TYPE_ACTION_RESULT, RestfulMediaType.APPLICATION_JSON_ERROR
+ })
+ ResponseEntity<Object> domainTypeIsSupertypeOf(
+ @PathVariable String domainType,
+ @RequestParam("supertype") String superType, // simple style
+ @RequestParam("args") String argumentsQueryString // formal style
);
}
diff --git a/viewers/restfulobjects/applib/src/main/java/org/apache/causeway/viewer/restfulobjects/applib/health/HealthResource.java b/viewers/restfulobjects/applib/src/main/java/org/apache/causeway/viewer/restfulobjects/applib/health/HealthResource.java
index 47b149a0d82..7a4c9fe7c05 100644
--- a/viewers/restfulobjects/applib/src/main/java/org/apache/causeway/viewer/restfulobjects/applib/health/HealthResource.java
+++ b/viewers/restfulobjects/applib/src/main/java/org/apache/causeway/viewer/restfulobjects/applib/health/HealthResource.java
@@ -18,34 +18,34 @@
*/
package org.apache.causeway.viewer.restfulobjects.applib.health;
-import jakarta.ws.rs.DELETE;
-import jakarta.ws.rs.GET;
-import jakarta.ws.rs.POST;
-import jakarta.ws.rs.PUT;
-import jakarta.ws.rs.Path;
-import jakarta.ws.rs.Produces;
import org.springframework.http.MediaType;
-import jakarta.ws.rs.core.Response;
+import org.springframework.http.ResponseEntity;
+import org.springframework.web.bind.annotation.DeleteMapping;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.PutMapping;
+import org.springframework.web.bind.annotation.RequestMapping;
import org.apache.causeway.viewer.restfulobjects.applib.RestfulMediaType;
/**
* @since 1.x {@index}
*/
-@Path("/health")
+@RequestMapping("${causeway.viewer.restfulobjects.path-prefix}/health")
public interface HealthResource {
- @GET
- @Produces({ MediaType.APPLICATION_JSON_VALUE, RestfulMediaType.APPLICATION_JSON_HEALTH })
- public Response health();
+ @GetMapping(path = "/", produces = {
+ MediaType.APPLICATION_JSON_VALUE, RestfulMediaType.APPLICATION_JSON_HEALTH
+ })
+ public ResponseEntity<Object> health();
- @DELETE
- public Response deleteHealthNotAllowed();
+ @DeleteMapping
+ public ResponseEntity<Object> deleteHealthNotAllowed();
- @PUT
- public Response putHealthNotAllowed();
+ @PutMapping
+ public ResponseEntity<Object> putHealthNotAllowed();
- @POST
- public Response postHealthNotAllowed();
+ @PostMapping
+ public ResponseEntity<Object> postHealthNotAllowed();
}
diff --git a/viewers/restfulobjects/applib/src/main/java/org/apache/causeway/viewer/restfulobjects/applib/homepage/HomePageResource.java b/viewers/restfulobjects/applib/src/main/java/org/apache/causeway/viewer/restfulobjects/applib/homepage/HomePageResource.java
index 19ae615661b..7480bcc183c 100644
--- a/viewers/restfulobjects/applib/src/main/java/org/apache/causeway/viewer/restfulobjects/applib/homepage/HomePageResource.java
+++ b/viewers/restfulobjects/applib/src/main/java/org/apache/causeway/viewer/restfulobjects/applib/homepage/HomePageResource.java
@@ -18,9 +18,8 @@
*/
package org.apache.causeway.viewer.restfulobjects.applib.homepage;
-import jakarta.ws.rs.core.Response;
-
import org.springframework.http.MediaType;
+import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
@@ -32,20 +31,22 @@
/**
* @since 1.x {@index}
*/
-@RequestMapping("${roPrefix}")
+@RequestMapping("${causeway.viewer.restfulobjects.path-prefix}")
public interface HomePageResource {
- @GetMapping(produces = { MediaType.APPLICATION_JSON_VALUE, RestfulMediaType.APPLICATION_JSON_HOME_PAGE })
- public Response homePage(/*@RequestHeader HttpHeaders headers*/);
+ @GetMapping(
+ path = "/",
+ produces = { MediaType.APPLICATION_JSON_VALUE, RestfulMediaType.APPLICATION_JSON_HOME_PAGE })
+ ResponseEntity<Object> homePage();
@DeleteMapping
- public Response deleteHomePageNotAllowed();
+ ResponseEntity<Object> deleteHomePageNotAllowed();
@PutMapping
- public Response putHomePageNotAllowed();
+ ResponseEntity<Object> putHomePageNotAllowed();
@PostMapping
- public Response postHomePageNotAllowed();
+ ResponseEntity<Object> postHomePageNotAllowed();
/**
* Not part of the RO spec; this resource always returns 401, and is
@@ -54,6 +55,6 @@ public interface HomePageResource {
@GetMapping(
path = "/notAuthenticated",
produces = { MediaType.APPLICATION_JSON_VALUE })
- public Response notAuthenticated();
+ ResponseEntity<Object> notAuthenticated();
}
diff --git a/viewers/restfulobjects/applib/src/main/java/org/apache/causeway/viewer/restfulobjects/applib/menubars/MenuBarsResource.java b/viewers/restfulobjects/applib/src/main/java/org/apache/causeway/viewer/restfulobjects/applib/menubars/MenuBarsResource.java
index 215fd971d32..bda5e04ce7e 100644
--- a/viewers/restfulobjects/applib/src/main/java/org/apache/causeway/viewer/restfulobjects/applib/menubars/MenuBarsResource.java
+++ b/viewers/restfulobjects/applib/src/main/java/org/apache/causeway/viewer/restfulobjects/applib/menubars/MenuBarsResource.java
@@ -18,14 +18,13 @@
*/
package org.apache.causeway.viewer.restfulobjects.applib.menubars;
-import jakarta.ws.rs.DELETE;
-import jakarta.ws.rs.GET;
-import jakarta.ws.rs.POST;
-import jakarta.ws.rs.PUT;
-import jakarta.ws.rs.Path;
-import jakarta.ws.rs.Produces;
import org.springframework.http.MediaType;
-import jakarta.ws.rs.core.Response;
+import org.springframework.http.ResponseEntity;
+import org.springframework.web.bind.annotation.DeleteMapping;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.PutMapping;
+import org.springframework.web.bind.annotation.RequestMapping;
import org.apache.causeway.viewer.restfulobjects.applib.RestfulMediaType;
@@ -34,35 +33,34 @@
*
* @since 1.x {@index}
*/
-@Path("/menuBars")
+@RequestMapping("${causeway.viewer.restfulobjects.path-prefix}/menuBars")
public interface MenuBarsResource {
/**
* Not part of the Restful Objects spec.
*/
- @GET
- @Produces({
- MediaType.APPLICATION_XML_VALUE, RestfulMediaType.APPLICATION_JSON_LAYOUT_MENUBARS,
- MediaType.APPLICATION_XML_VALUE, RestfulMediaType.APPLICATION_XML_LAYOUT_MENUBARS
+ @GetMapping(path = "/", produces = {
+ MediaType.APPLICATION_XML_VALUE, RestfulMediaType.APPLICATION_JSON_LAYOUT_MENUBARS,
+ MediaType.APPLICATION_XML_VALUE, RestfulMediaType.APPLICATION_XML_LAYOUT_MENUBARS
})
- public Response menuBars();
+ ResponseEntity<Object> menuBars();
/**
* Not part of the Restful Objects spec.
*/
- @DELETE
- public Response deleteMenuBarsNotAllowed();
+ @DeleteMapping
+ ResponseEntity<Object> deleteMenuBarsNotAllowed();
/**
* Not part of the Restful Objects spec.
*/
- @PUT
- public Response putMenuBarsNotAllowed();
+ @PutMapping
+ ResponseEntity<Object> putMenuBarsNotAllowed();
/**
* Not part of the Restful Objects spec.
*/
- @POST
- public Response postMenuBarsNotAllowed();
+ @PostMapping
+ ResponseEntity<Object> postMenuBarsNotAllowed();
}
diff --git a/viewers/restfulobjects/applib/src/main/java/org/apache/causeway/viewer/restfulobjects/applib/user/UserResource.java b/viewers/restfulobjects/applib/src/main/java/org/apache/causeway/viewer/restfulobjects/applib/user/UserResource.java
index 90d4ac3c87f..412708bbdd3 100644
--- a/viewers/restfulobjects/applib/src/main/java/org/apache/causeway/viewer/restfulobjects/applib/user/UserResource.java
+++ b/viewers/restfulobjects/applib/src/main/java/org/apache/causeway/viewer/restfulobjects/applib/user/UserResource.java
@@ -18,42 +18,38 @@
*/
package org.apache.causeway.viewer.restfulobjects.applib.user;
-import jakarta.ws.rs.DELETE;
-import jakarta.ws.rs.GET;
-import jakarta.ws.rs.POST;
-import jakarta.ws.rs.PUT;
-import jakarta.ws.rs.Path;
-import jakarta.ws.rs.Produces;
import org.springframework.http.MediaType;
-import jakarta.ws.rs.core.Response;
+import org.springframework.http.ResponseEntity;
+import org.springframework.web.bind.annotation.DeleteMapping;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.PutMapping;
+import org.springframework.web.bind.annotation.RequestMapping;
import org.apache.causeway.viewer.restfulobjects.applib.RestfulMediaType;
/**
* @since 1.x {@index}
*/
-@Path("/user")
+@RequestMapping("${causeway.viewer.restfulobjects.path-prefix}/user")
public interface UserResource {
- @GET
- @Produces({ MediaType.APPLICATION_JSON_VALUE, RestfulMediaType.APPLICATION_JSON_USER })
- public Response user();
+ @GetMapping(path = "/", produces = {MediaType.APPLICATION_JSON_VALUE, RestfulMediaType.APPLICATION_JSON_USER})
+ ResponseEntity<Object> user();
- @DELETE
- public Response deleteUserNotAllowed();
+ @DeleteMapping
+ ResponseEntity<Object> deleteUserNotAllowed();
- @PUT
- public Response putUserNotAllowed();
+ @PutMapping
+ ResponseEntity<Object> putUserNotAllowed();
- @POST
- public Response postUserNotAllowed();
+ @PostMapping
+ ResponseEntity<Object> postUserNotAllowed();
/**
* Not part of the Restful Objects spec.
*/
- @GET
- @Path("/logout")
- @Produces({ MediaType.APPLICATION_JSON_VALUE, RestfulMediaType.APPLICATION_JSON_HOME_PAGE })
- public Response logout();
+ @GetMapping(path = "/logout", produces = {MediaType.APPLICATION_JSON_VALUE, RestfulMediaType.APPLICATION_JSON_HOME_PAGE})
+ ResponseEntity<Object> logout();
}
diff --git a/viewers/restfulobjects/applib/src/main/java/org/apache/causeway/viewer/restfulobjects/applib/util/MediaTypes.java b/viewers/restfulobjects/applib/src/main/java/org/apache/causeway/viewer/restfulobjects/applib/util/MediaTypes.java
index ec2c88582be..e4f581f14a0 100644
--- a/viewers/restfulobjects/applib/src/main/java/org/apache/causeway/viewer/restfulobjects/applib/util/MediaTypes.java
+++ b/viewers/restfulobjects/applib/src/main/java/org/apache/causeway/viewer/restfulobjects/applib/util/MediaTypes.java
@@ -75,10 +75,11 @@ public MediaType parse(String type) {
//org.springframework.http.MediaType;
//jakarta.ws.rs.core.MediaType;
public jakarta.ws.rs.core.MediaType toJakarta(MediaType mediaType) {
- throw new UnsupportedOperationException();
+ return new jakarta.ws.rs.core.MediaType(mediaType.getType(), mediaType.getSubtype());
+
}
public MediaType fromJakarta(jakarta.ws.rs.core.MediaType mediaType) {
- throw new UnsupportedOperationException();
+ return new MediaType(mediaType.getType(), mediaType.getSubtype());
}
}
diff --git a/viewers/restfulobjects/applib/src/main/java/org/apache/causeway/viewer/restfulobjects/applib/version/VersionResource.java b/viewers/restfulobjects/applib/src/main/java/org/apache/causeway/viewer/restfulobjects/applib/version/VersionResource.java
index 382315ed7b4..91a9bbc38df 100644
--- a/viewers/restfulobjects/applib/src/main/java/org/apache/causeway/viewer/restfulobjects/applib/version/VersionResource.java
+++ b/viewers/restfulobjects/applib/src/main/java/org/apache/causeway/viewer/restfulobjects/applib/version/VersionResource.java
@@ -18,34 +18,34 @@
*/
package org.apache.causeway.viewer.restfulobjects.applib.version;
-import jakarta.ws.rs.DELETE;
-import jakarta.ws.rs.GET;
-import jakarta.ws.rs.POST;
-import jakarta.ws.rs.PUT;
-import jakarta.ws.rs.Path;
-import jakarta.ws.rs.Produces;
import org.springframework.http.MediaType;
-import jakarta.ws.rs.core.Response;
+import org.springframework.http.ResponseEntity;
+import org.springframework.web.bind.annotation.DeleteMapping;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.PutMapping;
+import org.springframework.web.bind.annotation.RequestMapping;
import org.apache.causeway.viewer.restfulobjects.applib.RestfulMediaType;
/**
* @since 1.x {@index}
*/
-@Path("/version")
+@RequestMapping("${causeway.viewer.restfulobjects.path-prefix}/version")
public interface VersionResource {
- @GET
- @Produces({ MediaType.APPLICATION_JSON_VALUE, RestfulMediaType.APPLICATION_JSON_VERSION })
- public Response version();
+ @GetMapping(
+ path = "/",
+ produces = {MediaType.APPLICATION_JSON_VALUE, RestfulMediaType.APPLICATION_JSON_VERSION})
+ ResponseEntity<Object> version();
- @DELETE
- public Response deleteVersionNotAllowed();
+ @DeleteMapping
+ ResponseEntity<Object> deleteVersionNotAllowed();
- @PUT
- public Response putVersionNotAllowed();
+ @PutMapping
+ ResponseEntity<Object> putVersionNotAllowed();
- @POST
- public Response postVersionNotAllowed();
+ @PostMapping
+ ResponseEntity<Object> postVersionNotAllowed();
}
diff --git a/viewers/restfulobjects/rendering/src/main/java/org/apache/causeway/viewer/restfulobjects/rendering/Caching.java b/viewers/restfulobjects/rendering/src/main/java/org/apache/causeway/viewer/restfulobjects/rendering/Caching.java
index 9eb96a5283a..298ef30d97d 100644
--- a/viewers/restfulobjects/rendering/src/main/java/org/apache/causeway/viewer/restfulobjects/rendering/Caching.java
+++ b/viewers/restfulobjects/rendering/src/main/java/org/apache/causeway/viewer/restfulobjects/rendering/Caching.java
@@ -18,7 +18,9 @@
*/
package org.apache.causeway.viewer.restfulobjects.rendering;
-import jakarta.ws.rs.core.CacheControl;
+import java.util.concurrent.TimeUnit;
+
+import org.springframework.http.CacheControl;
public enum Caching {
@@ -28,13 +30,10 @@ public enum Caching {
private final CacheControl cacheControl;
- Caching(final int maxAge) {
- this.cacheControl = new CacheControl();
- if (maxAge > 0) {
- cacheControl.setMaxAge(maxAge);
- } else {
- cacheControl.setNoCache(true);
- }
+ Caching(final int maxAgeSeconds) {
+ this.cacheControl = maxAgeSeconds > 0
+ ? CacheControl.maxAge(maxAgeSeconds, TimeUnit.SECONDS)
+ : CacheControl.noCache();
}
public CacheControl getCacheControl() {
diff --git a/viewers/restfulobjects/rendering/src/main/java/org/apache/causeway/viewer/restfulobjects/rendering/CausewayModuleRestfulObjectsRendering.java b/viewers/restfulobjects/rendering/src/main/java/org/apache/causeway/viewer/restfulobjects/rendering/CausewayModuleRestfulObjectsRendering.java
index ebe0a2e05e7..6ca0f8d308d 100644
--- a/viewers/restfulobjects/rendering/src/main/java/org/apache/causeway/viewer/restfulobjects/rendering/CausewayModuleRestfulObjectsRendering.java
+++ b/viewers/restfulobjects/rendering/src/main/java/org/apache/causeway/viewer/restfulobjects/rendering/CausewayModuleRestfulObjectsRendering.java
@@ -18,9 +18,11 @@
*/
package org.apache.causeway.viewer.restfulobjects.rendering;
+import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
+import org.apache.causeway.core.metamodel.context.MetaModelContext;
import org.apache.causeway.core.runtime.CausewayModuleCoreRuntime;
import org.apache.causeway.viewer.restfulobjects.applib.CausewayModuleViewerRestfulObjectsApplib;
import org.apache.causeway.viewer.restfulobjects.rendering.service.RepresentationService;
@@ -40,7 +42,7 @@
/**
* @since 1.x {@index}
*/
-@Configuration
+@Configuration(proxyBeanMethods = false)
@Import({
// Modules
CausewayModuleViewerRestfulObjectsApplib.class,
@@ -67,4 +69,9 @@
public class CausewayModuleRestfulObjectsRendering {
public static final String NAMESPACE = "causeway.viewer.roRendering";
+
+ @Bean
+ ResponseFactory responseFactory(MetaModelContext mmc) {
+ return new ResponseFactory(mmc);
+ }
}
diff --git a/viewers/restfulobjects/rendering/src/main/java/org/apache/causeway/viewer/restfulobjects/rendering/ExceptionWithBody.java b/viewers/restfulobjects/rendering/src/main/java/org/apache/causeway/viewer/restfulobjects/rendering/ExceptionWithBody.java
index 8893ba60712..317ee9e1471 100644
--- a/viewers/restfulobjects/rendering/src/main/java/org/apache/causeway/viewer/restfulobjects/rendering/ExceptionWithBody.java
+++ b/viewers/restfulobjects/rendering/src/main/java/org/apache/causeway/viewer/restfulobjects/rendering/ExceptionWithBody.java
@@ -22,5 +22,5 @@
public interface ExceptionWithBody {
- JsonRepresentation getBody();
+ JsonRepresentation body();
}
diff --git a/viewers/restfulobjects/rendering/src/main/java/org/apache/causeway/viewer/restfulobjects/rendering/ExceptionWithHttpStatusCode.java b/viewers/restfulobjects/rendering/src/main/java/org/apache/causeway/viewer/restfulobjects/rendering/ExceptionWithHttpStatusCode.java
index 0edb03dfac3..f0430d1503b 100644
--- a/viewers/restfulobjects/rendering/src/main/java/org/apache/causeway/viewer/restfulobjects/rendering/ExceptionWithHttpStatusCode.java
+++ b/viewers/restfulobjects/rendering/src/main/java/org/apache/causeway/viewer/restfulobjects/rendering/ExceptionWithHttpStatusCode.java
@@ -18,9 +18,9 @@
*/
package org.apache.causeway.viewer.restfulobjects.rendering;
-import org.apache.causeway.viewer.restfulobjects.applib.RestfulResponse.HttpStatusCode;
+import org.springframework.http.HttpStatus;
public interface ExceptionWithHttpStatusCode {
- HttpStatusCode getHttpStatusCode();
+ HttpStatus httpStatus();
}
diff --git a/viewers/restfulobjects/rendering/src/main/java/org/apache/causeway/viewer/restfulobjects/rendering/ResponseFactory.java b/viewers/restfulobjects/rendering/src/main/java/org/apache/causeway/viewer/restfulobjects/rendering/ResponseFactory.java
new file mode 100644
index 00000000000..6243800ac7a
--- /dev/null
+++ b/viewers/restfulobjects/rendering/src/main/java/org/apache/causeway/viewer/restfulobjects/rendering/ResponseFactory.java
@@ -0,0 +1,144 @@
+/*
+ * 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.causeway.viewer.restfulobjects.rendering;
+
+import java.net.URI;
+import java.text.SimpleDateFormat;
+import java.util.Date;
+import java.util.Locale;
+import java.util.TimeZone;
+
+import org.jspecify.annotations.Nullable;
+
+import org.springframework.http.HttpStatus;
+import org.springframework.http.MediaType;
+import org.springframework.http.ResponseEntity;
+
+import org.apache.causeway.applib.services.clock.ClockService;
+import org.apache.causeway.core.config.environment.CausewaySystemEnvironment;
+import org.apache.causeway.core.metamodel.context.MetaModelContext;
+import org.apache.causeway.viewer.restfulobjects.applib.JsonRepresentation;
+import org.apache.causeway.viewer.restfulobjects.applib.util.JsonMapper;
+import org.apache.causeway.viewer.restfulobjects.rendering.util.JsonWriterUtil;
+
+public record ResponseFactory(
+ @Nullable ClockService clockService,
+ JsonMapper.PrettyPrinting prettyPrinting) {
+
+ // non-canonical constructor
+ public ResponseFactory(MetaModelContext mmc) {
+ this(
+ mmc.getServiceRegistry().lookupService(ClockService.class).orElse(null),
+ prettyPrinting(mmc.getSystemEnvironment()));
+ }
+
+ public static ResponseEntity<Object> noContent() {
+ return ResponseEntity.status(HttpStatus.NO_CONTENT)
+ .body(null);
+ }
+
+ public static ResponseEntity<Object> notFound() {
+ return ResponseEntity.status(HttpStatus.NOT_FOUND)
+ .body(null);
+ }
+
+ public static ResponseEntity<Object> notImplemented() {
+ return ResponseEntity.status(HttpStatus.NOT_IMPLEMENTED)
+ .body(null);
+ }
+
+ public static ResponseEntity<Object> temporaryRedirect(URI location) {
+ return ResponseEntity.status(HttpStatus.TEMPORARY_REDIRECT)
+ .location(location)
+ .body(null);
+ }
+
+ /**
+ * @param rootRepresentation - if present, is used for entity;
+ * otherwise the renderer is used.
+ * The idea is that the renderer will be set up to render to some sub-node of root representation
+ */
+ public ResponseEntity<Object> of(
+ final HttpStatus httpStatus,
+ final ReprRenderer<?> renderer,
+ final Caching caching,
+ final @Nullable JsonRepresentation rootRepresentation,
+ final @Nullable MediaType mediaTypeOverride) {
+
+ // if a rootRepresentation is provided, then the assumption is that the rendered
+ // will be rendering to some submap of the rootRepresentation
+ final JsonRepresentation entityRepresentation = rootRepresentation != null
+ ? rootRepresentation
+ : renderer.render();
+
+ return ResponseEntity
+ .status(httpStatus)
+ .header("Date", now())
+ .contentType(mediaTypeOverride!=null ? mediaTypeOverride : renderer.getMediaType())
+ .cacheControl(caching.getCacheControl())
+ .body((Object)JsonWriterUtil.jsonFor(entityRepresentation, prettyPrinting()));
+ }
+
+ /**
+ * @param rootRepresentation - if present, is used for entity;
+ * otherwise the renderer is used.
+ * The idea is that the renderer will be set up to render to some sub-node of root representation
+ */
+ public ResponseEntity<Object> ok(
+ final ReprRenderer<?> renderer,
+ final Caching caching,
+ final @Nullable JsonRepresentation rootRepresentation,
+ final @Nullable MediaType mediaTypeOverride) {
+ return of(HttpStatus.OK, renderer, caching, rootRepresentation, mediaTypeOverride);
+ }
+
+ public ResponseEntity<Object> ok(
+ final ReprRenderer<?> renderer,
+ final Caching caching) {
+ return of(HttpStatus.OK, renderer, caching, null, null);
+ }
+
+ public ResponseEntity<Object> ok(Object mappedDomainObject, MediaType mediaType) {
+ return ResponseEntity.ok()
+ .contentType(mediaType)
+ .body(mappedDomainObject);
+ }
+
+ // -- HELPER
+
+ final static SimpleDateFormat DATE_FORMAT = new SimpleDateFormat("EEE, dd MMM yyyy HH:mm:ss z", Locale.US);
+ static {
+ DATE_FORMAT.setTimeZone(TimeZone.getTimeZone("GMT"));
+ }
+
+ private String now() {
+ var now = clockService!=null
+ ? clockService.getClock().nowAsJavaUtilDate()
+ : new Date();
+ return DATE_FORMAT.format(now);
+ }
+
+ private static JsonMapper.PrettyPrinting prettyPrinting(@Nullable CausewaySystemEnvironment env) {
+ return env!=null
+ && env.isPrototyping()
+ ? JsonMapper.PrettyPrinting.ENABLE
+ : JsonMapper.PrettyPrinting.DISABLE;
+ }
+
+}
diff --git a/viewers/restfulobjects/rendering/src/main/java/org/apache/causeway/viewer/restfulobjects/rendering/Responses.java b/viewers/restfulobjects/rendering/src/main/java/org/apache/causeway/viewer/restfulobjects/rendering/Responses.java
deleted file mode 100644
index 2bf9f076377..00000000000
--- a/viewers/restfulobjects/rendering/src/main/java/org/apache/causeway/viewer/restfulobjects/rendering/Responses.java
+++ /dev/null
@@ -1,121 +0,0 @@
-/*
- * 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.causeway.viewer.restfulobjects.rendering;
-
-import java.text.SimpleDateFormat;
-import java.util.Date;
-import java.util.Locale;
-import java.util.TimeZone;
-
-import org.springframework.http.MediaType;
-import jakarta.ws.rs.core.Response;
-
-import org.apache.causeway.applib.services.clock.ClockService;
-import org.apache.causeway.viewer.restfulobjects.applib.JsonRepresentation;
-import org.apache.causeway.viewer.restfulobjects.applib.RestfulResponse;
-import org.apache.causeway.viewer.restfulobjects.applib.util.JsonMapper;
-import org.apache.causeway.viewer.restfulobjects.applib.util.MediaTypes;
-import org.apache.causeway.viewer.restfulobjects.rendering.util.JsonWriterUtil;
-
-public final class Responses {
-
- private Responses(){}
-
- public static Response.ResponseBuilder ofNoContent() {
- return of(RestfulResponse.HttpStatusCode.NO_CONTENT);
- }
-
- public static Response.ResponseBuilder ofNotFound() {
- return of(RestfulResponse.HttpStatusCode.NOT_FOUND);
- }
-
- public static Response.ResponseBuilder ofNotImplemented() {
- return of(RestfulResponse.HttpStatusCode.NOT_IMPLEMENTED);
- }
-
- public static Response.ResponseBuilder ofOk(
- final ReprRenderer<?> renderer,
- final Caching caching) {
- return ofOk(renderer, caching, null);
- }
-
- /**
- * @param rootRepresentationIfAny - if specified, is used for entity; otherwise the renderer is used. The idea is that the renderer will be set up to render to some sub-node of root representation
- */
- public static Response.ResponseBuilder ofOk(
- final ReprRenderer<?> renderer,
- final Caching caching,
- final JsonRepresentation rootRepresentationIfAny) {
-
- final JsonRepresentation representation = renderer.render();
- // if a rootRepresentation is provided, then the assumption is that the rendered
- // will be rendering to some submap of the rootRepresentation
- final JsonRepresentation entityRepresentation =
- rootRepresentationIfAny != null? rootRepresentationIfAny : representation;
-
- final MediaType mediaType = renderer.getMediaType();
-
- final Date now = now(renderer);
- SimpleDateFormat dateFormat = new SimpleDateFormat("EEE, dd MMM yyyy HH:mm:ss z", Locale.US);
- dateFormat.setTimeZone(TimeZone.getTimeZone("GMT"));
-
- final Response.ResponseBuilder response =
- of(RestfulResponse.HttpStatusCode.OK)
- .header("Date", dateFormat.format(now))
- .type(MediaTypes.toJakarta(mediaType))
- .cacheControl(caching.getCacheControl())
- .entity(JsonWriterUtil.jsonFor(entityRepresentation, inferPrettyPrinting(renderer)));
-
- return response;
- }
-
- private static Date now(final ReprRenderer<?> renderer) {
- if(renderer instanceof ReprRendererAbstract) {
- ((ReprRendererAbstract<?>)renderer).getResourceContext().getMetaModelContext().getServiceRegistry()
- .lookupServiceElseFail(ClockService.class).getClock().nowAsJavaUtilDate();
- }
- return new Date();
- }
-
- protected static Response.ResponseBuilder of(final RestfulResponse.HttpStatusCode httpStatusCode) {
- return Response.status(httpStatusCode.getJaxrsStatusType()).type(MediaTypes.toJakarta(MediaType.APPLICATION_JSON));
- }
-
- public static Response.ResponseBuilder mediaType(
- final Response.ResponseBuilder responseBuilder,
- final MediaType mediaType) {
- responseBuilder.type(MediaTypes.toJakarta(mediaType));
- return responseBuilder;
- }
-
- public static JsonMapper.PrettyPrinting inferPrettyPrinting(final ReprRenderer<?> renderer) {
-
- if(renderer instanceof ReprRendererAbstract) {
- var systemEnvironment = ((ReprRendererAbstract<?>) renderer).getResourceContext()
- .getMetaModelContext().getSystemEnvironment();
- return systemEnvironment.isPrototyping()
- ? JsonMapper.PrettyPrinting.ENABLE
- : JsonMapper.PrettyPrinting.DISABLE;
- }
-
- return JsonMapper.PrettyPrinting.DISABLE;
-
- }
-
-}
diff --git a/viewers/restfulobjects/rendering/src/main/java/org/apache/causeway/viewer/restfulobjects/rendering/RestfulObjectsApplicationException.java b/viewers/restfulobjects/rendering/src/main/java/org/apache/causeway/viewer/restfulobjects/rendering/RestfulObjectsApplicationException.java
index f223ba5bd93..633fbc244c6 100644
--- a/viewers/restfulobjects/rendering/src/main/java/org/apache/causeway/viewer/restfulobjects/rendering/RestfulObjectsApplicationException.java
+++ b/viewers/restfulobjects/rendering/src/main/java/org/apache/causeway/viewer/restfulobjects/rendering/RestfulObjectsApplicationException.java
@@ -18,8 +18,11 @@
*/
package org.apache.causeway.viewer.restfulobjects.rendering;
+import org.springframework.http.HttpStatus;
+
import org.apache.causeway.viewer.restfulobjects.applib.JsonRepresentation;
-import org.apache.causeway.viewer.restfulobjects.applib.RestfulResponse.HttpStatusCode;
+import lombok.Getter;
+import lombok.experimental.Accessors;
public class RestfulObjectsApplicationException
extends RuntimeException
@@ -27,61 +30,47 @@ public class RestfulObjectsApplicationException
private static final long serialVersionUID = 1L;
- public static final RestfulObjectsApplicationException create(final HttpStatusCode httpStatusCode) {
- return createWithCause(httpStatusCode, null);
+ public static final RestfulObjectsApplicationException create(final HttpStatus httpStatus) {
+ return createWithCause(httpStatus, null);
}
public static RestfulObjectsApplicationException createWithMessage(
- final HttpStatusCode httpStatusCode,
- final String message, final Object... args) {
- return createWithCauseAndMessage(httpStatusCode, null, message, args);
+ final HttpStatus httpStatus,
+ final String message) {
+ return createWithCauseAndMessage(httpStatus, null, message);
}
public static RestfulObjectsApplicationException createWithCause(
- final HttpStatusCode httpStatusCode,
+ final HttpStatus httpStatus,
final Exception cause) {
- return createWithCauseAndMessage(httpStatusCode, cause, null);
+ return createWithCauseAndMessage(httpStatus, cause, null);
}
public static RestfulObjectsApplicationException createWithCauseAndMessage(
- final HttpStatusCode httpStatusCode,
+ final HttpStatus httpStatus,
final Exception cause,
- final String message, final Object... args) {
- return new RestfulObjectsApplicationException(httpStatusCode, formatString(message, args), cause, null);
+ final String message) {
+ return new RestfulObjectsApplicationException(httpStatus, message, cause, null);
}
public static RestfulObjectsApplicationException createWithBody(
- final HttpStatusCode httpStatusCode,
+ final HttpStatus httpStatus,
final JsonRepresentation body,
- final String message, final Object... args) {
- return new RestfulObjectsApplicationException(httpStatusCode, formatString(message, args), null, body);
- }
-
- private static String formatString(final String formatStr, final Object... args) {
- return formatStr != null ? String.format(formatStr, args) : null;
+ final String message) {
+ return new RestfulObjectsApplicationException(httpStatus, message, null, body);
}
- private final HttpStatusCode httpStatusCode;
- private final JsonRepresentation body;
+ @Getter(onMethod_={@Override}) @Accessors(fluent=true) private final HttpStatus httpStatus;
+ @Getter(onMethod_={@Override}) @Accessors(fluent=true) private final JsonRepresentation body;
protected RestfulObjectsApplicationException(
- final HttpStatusCode httpStatusCode,
+ final HttpStatus httpStatus,
final String message,
final Throwable cause,
final JsonRepresentation body) {
super(message, cause);
- this.httpStatusCode = httpStatusCode;
+ this.httpStatus = httpStatus;
this.body = body;
}
- @Override
- public HttpStatusCode getHttpStatusCode() {
- return httpStatusCode;
- }
-
- @Override
- public JsonRepresentation getBody() {
- return body;
- }
-
}
diff --git a/viewers/restfulobjects/rendering/src/main/java/org/apache/causeway/viewer/restfulobjects/rendering/domainobjects/AbstractObjectMemberReprRenderer.java b/viewers/restfulobjects/rendering/src/main/java/org/apache/causeway/viewer/restfulobjects/rendering/domainobjects/AbstractObjectMemberReprRenderer.java
index c49179eb4a2..cf6d3c64a30 100644
--- a/viewers/restfulobjects/rendering/src/main/java/org/apache/causeway/viewer/restfulobjects/rendering/domainobjects/AbstractObjectMemberReprRenderer.java
+++ b/viewers/restfulobjects/rendering/src/main/java/org/apache/causeway/viewer/restfulobjects/rendering/domainobjects/AbstractObjectMemberReprRenderer.java
@@ -198,12 +198,12 @@ protected void renderMemberContent() {
}
}
- public void withMemberMode(final ManagedMember.RepresentationMode memberMode) {
- if(memberMode.isWrite()) {
- this.asMutated();
- } else {
- this.asStandalone();
- }
+ public AbstractObjectMemberReprRenderer<T> withMemberMode(final ManagedMember.RepresentationMode memberMode) {
+ return switch (memberMode) {
+ case READ -> this.asStandalone();
+ case WRITE -> this.asMutated();
+ case AUTO -> this;
+ };
}
private void addLinkToSelf() {
diff --git a/viewers/restfulobjects/rendering/src/main/java/org/apache/causeway/viewer/restfulobjects/rendering/domainobjects/ActionResultReprRenderer.java b/viewers/restfulobjects/rendering/src/main/java/org/apache/causeway/viewer/restfulobjects/rendering/domainobjects/ActionResultReprRenderer.java
index 03bc07ea7dc..08293fbc59f 100644
--- a/viewers/restfulobjects/rendering/src/main/java/org/apache/causeway/viewer/restfulobjects/rendering/domainobjects/ActionResultReprRenderer.java
+++ b/viewers/restfulobjects/rendering/src/main/java/org/apache/causeway/viewer/restfulobjects/rendering/domainobjects/ActionResultReprRenderer.java
@@ -77,8 +77,9 @@ public ActionResultReprRenderer with(final ObjectAndActionInvocation objectAndAc
return this;
}
- public void using(final ObjectAdapterLinkTo adapterLinkTo) {
+ public ActionResultReprRenderer using(final ObjectAdapterLinkTo adapterLinkTo) {
this.adapterLinkTo = adapterLinkTo.with(objectAdapter);
+ return this;
}
@Override
diff --git a/viewers/restfulobjects/rendering/src/main/java/org/apache/causeway/viewer/restfulobjects/rendering/domainobjects/DomainObjectReprRenderer.java b/viewers/restfulobjects/rendering/src/main/java/org/apache/causeway/viewer/restfulobjects/rendering/domainobjects/DomainObjectReprRenderer.java
index c0a062348ff..6be824c08ed 100644
--- a/viewers/restfulobjects/rendering/src/main/java/org/apache/causeway/viewer/restfulobjects/rendering/domainobjects/DomainObjectReprRenderer.java
+++ b/viewers/restfulobjects/rendering/src/main/java/org/apache/causeway/viewer/restfulobjects/rendering/domainobjects/DomainObjectReprRenderer.java
@@ -23,6 +23,7 @@
import java.util.stream.Collectors;
import java.util.stream.Stream;
+import org.apache.causeway.commons.internal.base._Strings;
import org.apache.causeway.core.metamodel.consent.Consent;
import org.apache.causeway.core.metamodel.interactions.managed.ManagedAction;
import org.apache.causeway.core.metamodel.interactions.managed.ManagedCollection;
@@ -153,7 +154,7 @@ public DomainObjectReprRenderer with(final ManagedObject objectAdapter) {
objectAdapter.objSpec())
.build()
.getString("href");
- addMediaTypeParams(X_RO_DOMAIN_TYPE, domainTypeHref);
+ addMediaTypeParams(X_RO_DOMAIN_TYPE, _Strings.asDoubleQuoted.apply(domainTypeHref));
return this;
}
diff --git a/viewers/restfulobjects/rendering/src/main/java/org/apache/causeway/viewer/restfulobjects/rendering/service/RepresentationService.java b/viewers/restfulobjects/rendering/src/main/java/org/apache/causeway/viewer/restfulobjects/rendering/service/RepresentationService.java
index a3624aacf26..d76587a3c77 100644
--- a/viewers/restfulobjects/rendering/src/main/java/org/apache/causeway/viewer/restfulobjects/rendering/service/RepresentationService.java
+++ b/viewers/restfulobjects/rendering/src/main/java/org/apache/causeway/viewer/restfulobjects/rendering/service/RepresentationService.java
@@ -27,9 +27,11 @@
import jakarta.inject.Named;
import jakarta.ws.rs.core.Response;
+import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;
import org.apache.causeway.applib.annotation.PriorityPrecedence;
+import org.apache.causeway.commons.internal.exceptions._Exceptions;
import org.apache.causeway.core.metamodel.interactions.managed.ManagedAction;
import org.apache.causeway.core.metamodel.interactions.managed.ManagedCollection;
import org.apache.causeway.core.metamodel.interactions.managed.ManagedProperty;
@@ -46,21 +48,17 @@
* Configures the Restful Objects viewer to emit custom representations (rather than the
* standard representations defined in the RO spec).
*
- * <p>
- * The default implementations ultimately generate representations according
- * to the <a href="http://restfulobjects.org">Restful Objects spec</a> v1.0.
- * It does this through a level of abstraction by delegating to
- * implementations of the
- * {@link org.apache.causeway.viewer.restfulobjects.rendering.service.conneg.ContentNegotiationService}
- * SPI. This provides a mechanism for altering representations according
- * to the HTTP `Accept` header.
- * </p>
+ * <p>The default implementations ultimately generate representations according
+ * to the <a href="http://restfulobjects.org">Restful Objects spec</a> v1.0.
+ * It does this through a level of abstraction by delegating to
+ * implementations of the
+ * {@link org.apache.causeway.viewer.restfulobjects.rendering.service.conneg.ContentNegotiationService}
+ * SPI. This provides a mechanism for altering representations according
+ * to the HTTP `Accept` header.
*
- * <p>
- * This interface is EXPERIMENTAL and may change in the future.
- * </p>
+ * <p>This interface is EXPERIMENTAL and may change in the future.
*
- * @since 1.x {@index}
+ * @since 1.x revised for 4.0 {@index}
*/
@Service
@Named(CausewayModuleViewerRestfulObjectsApplib.NAMESPACE + ".RepresentationService")
@@ -76,7 +74,7 @@ public RepresentationService(final List<ContentNegotiationService> contentNegoti
}
/**
- * As returned by {@link IResourceContext#getIntent()}, applies only to the representation of
+ * As returned by {@link IResourceContext#intent()}, applies only to the representation of
* domain objects.
*/
public enum Intent {
@@ -97,117 +95,97 @@ public enum Intent {
/**
* Returns a representation of a single object.
*
- * <p>
- * By default this representation is as per section 14.4 of the
- * RO spec, v1.0.
- * </p>
+ * @apiNote By default this representation is as per section 14.4 of the RO spec, v1.0.
*/
- public Response objectRepresentation(
+ public ResponseEntity<Object> objectRepresentation(
final IResourceContext resourceContext,
final ManagedObject objectAdapter) {
- final Response.ResponseBuilder responseBuilder = buildResponse(
+ final var response = buildResponse(
connegService -> connegService.buildResponse(resourceContext, objectAdapter));
- assertContentNegotiationServiceHandled(responseBuilder);
- return buildResponse(responseBuilder);
+ return assertContentNegotiationServiceHandled(response);
}
/**
* Returns a representation of a single property of an object.
*
- * <p>
- * By default this representation is as per section 16.4 of the
- * RO spec, v1.0.
- * </p>
+ * @apiNote By default this representation is as per section 16.4 of theRO spec, v1.0.
*/
- public Response propertyDetails(
+ public ResponseEntity<Object> propertyDetails(
final IResourceContext resourceContext,
final ManagedProperty objectAndProperty) {
- final Response.ResponseBuilder responseBuilder = buildResponse(
+ final var response = buildResponse(
connegService -> connegService.buildResponse(resourceContext, objectAndProperty));
- assertContentNegotiationServiceHandled(responseBuilder);
- return buildResponse(responseBuilder);
+ return assertContentNegotiationServiceHandled(response);
}
/**
* Returns a representation of a single collection of an object.
*
- * <p>
- * By default this representation is as per section 17.5 of the
- * RO spec, v1.0.
- * </p>
+ * @apiNote By default this representation is as per section 17.5 of the RO spec, v1.0.
*/
- public Response collectionDetails(
+ public ResponseEntity<Object> collectionDetails(
final IResourceContext resourceContext,
final ManagedCollection objectAndCollection) {
- final Response.ResponseBuilder responseBuilder = buildResponse(
+ final var response = buildResponse(
connegService -> connegService.buildResponse(resourceContext, objectAndCollection));
- assertContentNegotiationServiceHandled(responseBuilder);
- return buildResponse(responseBuilder);
+ return assertContentNegotiationServiceHandled(response);
}
/**
* Returns a representation of a single action (prompt) of an object.
*
- * <p>
- * By default this representation is as per section 18.2 of the
- * RO spec, v1.0.
- * </p>
+ * @apiNote By default this representation is as per section 18.2 of the RO spec, v1.0.
*/
- public Response actionPrompt(
+ public ResponseEntity<Object> actionPrompt(
final IResourceContext resourceContext,
final ManagedAction objectAndAction) {
- final Response.ResponseBuilder responseBuilder = buildResponse(
+ final var response = buildResponse(
connegService -> connegService.buildResponse(resourceContext, objectAndAction));
- assertContentNegotiationServiceHandled(responseBuilder);
- return buildResponse(responseBuilder);
+ return assertContentNegotiationServiceHandled(response);
}
/**
* Returns a representation of a single action invocation of an object.
*
- * <p>
- * By default this representation is as per section 19.5 of the
- * RO spec, v1.0.
- * </p>
+ * @apiNote By default this representation is as per section 19.5 of the RO spec, v1.0.
*/
- public Response actionResult(
+ public ResponseEntity<Object> actionResult(
final IResourceContext resourceContext,
final ObjectAndActionInvocation objectAndActionInvocation) {
- final Response.ResponseBuilder responseBuilder = buildResponse(
+ final var response = buildResponse(
connegService -> connegService.buildResponse(resourceContext, objectAndActionInvocation));
- assertContentNegotiationServiceHandled(responseBuilder);
- return buildResponse(responseBuilder);
+ return assertContentNegotiationServiceHandled(response);
}
- void assertContentNegotiationServiceHandled(final Response.ResponseBuilder responseBuilder) {
+ <T> ResponseEntity<T> assertContentNegotiationServiceHandled(final ResponseEntity<T> responseBuilder) {
if (responseBuilder == null) {
- throw new IllegalStateException("Could not locate " + ContentNegotiationService.class.getSimpleName() + " to handle request");
+ throw _Exceptions.illegalState("Could not locate %s to handle request",
+ ContentNegotiationService.class.getSimpleName());
}
+ return responseBuilder;
}
/**
* Iterates over all {@link #contentNegotiationServices injected} {@link ContentNegotiationService}s to find one
* that returns a {@link Response.ResponseBuilder} using the provided function.
*
- * <p>
- * There will always be at least one such service, namely the
- * {@link ContentNegotiationServiceForRestfulObjectsV1_0}.
- * </p>
+ * <p>There will always be at least one such service, namely the
+ * {@link ContentNegotiationServiceForRestfulObjectsV1_0}.
*
* @param connegServiceBuildResponse - the function to ask of the {@link ContentNegotiationService}.
*/
- Response.ResponseBuilder buildResponse(
- final Function<ContentNegotiationService, Response.ResponseBuilder> connegServiceBuildResponse) {
+ ResponseEntity<Object> buildResponse(
+ final Function<ContentNegotiationService, ResponseEntity<Object>> connegServiceBuildResponse) {
if(log.isDebugEnabled()) {
log.debug("ContentNegotiationServices:\n{}", contentNegotiationServices.stream()
@@ -229,11 +207,4 @@ Response.ResponseBuilder buildResponse(
return null;
}
- /**
- * Override to allow further customization.
- */
- protected Response buildResponse(final Response.ResponseBuilder responseBuilder) {
- return responseBuilder.build();
- }
-
}
diff --git a/viewers/restfulobjects/rendering/src/main/java/org/apache/causeway/viewer/restfulobjects/rendering/service/conneg/ContentNegotiationService.java b/viewers/restfulobjects/rendering/src/main/java/org/apache/causeway/viewer/restfulobjects/rendering/service/conneg/ContentNegotiationService.java
index f7c031e2dbb..3ac54f8e220 100644
--- a/viewers/restfulobjects/rendering/src/main/java/org/apache/causeway/viewer/restfulobjects/rendering/service/conneg/ContentNegotiationService.java
+++ b/viewers/restfulobjects/rendering/src/main/java/org/apache/causeway/viewer/restfulobjects/rendering/service/conneg/ContentNegotiationService.java
@@ -18,7 +18,7 @@
*/
package org.apache.causeway.viewer.restfulobjects.rendering.service.conneg;
-import jakarta.ws.rs.core.Response;
+import org.springframework.http.ResponseEntity;
import org.apache.causeway.core.metamodel.interactions.managed.ManagedAction;
import org.apache.causeway.core.metamodel.interactions.managed.ManagedCollection;
@@ -30,81 +30,62 @@
/**
* Generates a representation according to HTTP `Accept` header of the request.
*
- * <p>
- * This idea is discussed in section 34.1 of the
- * <a href="http://restfulobjects.org">Restful Objects spec</a> v1.0.
- * </p>
+ * <p> This idea is discussed in section 34.1 of the
+ * <a href="http://restfulobjects.org">Restful Objects spec</a> v1.0.
*
- * <p>
- * The principal motivation is to allow more flexible representations to be
+ * <p> The principal motivation is to allow more flexible representations to be
* generated for REST clients that (perhaps through their use of a certain
* JavaScript library, say) expect, or at least works best with, a certain
* style of representation.
- * </p>
*
* @apiNote This domain service uses internal framework classes and so does not constitute a formal API/SPI for the framework
*
- * @since 1.x {@index}
+ * @since 1.x revised for 4.0 {@index}
*/
public interface ContentNegotiationService {
/**
* Returns a representation of a single object.
*
- * <p>
- * By default this representation is as per section 14.4 of the
- * RO spec, v1.0.
- * </p>
+ * @apiNote By default this representation is as per section 14.4 of the RO spec, v1.0.
*/
- public Response.ResponseBuilder buildResponse(
+ ResponseEntity<Object> buildResponse(
IResourceContext resourceContext,
ManagedObject objectAdapter);
/**
* Returns a representation of a single property of an object.
*
- * <p>
- * By default this representation is as per section 16.4 of the
- * RO spec, v1.0.
- * </p>
+ * @apiNote By default this representation is as per section 16.4 of the RO spec, v1.0.
*/
- public Response.ResponseBuilder buildResponse(
+ ResponseEntity<Object> buildResponse(
IResourceContext resourceContext,
ManagedProperty objectAndProperty);
/**
* Returns a representation of a single collection of an object.
*
- * <p>
- * By default this representation is as per section 17.5 of the
- * RO spec, v1.0.
- * </p>
+ * @apiNote By default this representation is as per section 17.5 of the RO spec, v1.0.
*/
- public Response.ResponseBuilder buildResponse(
+ ResponseEntity<Object> buildResponse(
IResourceContext resourceContext,
ManagedCollection objectAndCollection);
/**
* Returns a representation of a single action (prompt) of an object.
*
- * <p>
- * By default this representation is as per section 18.2 of the
- * RO spec, v1.0.
- * </p>
+ * @apiNote By default this representation is as per section 18.2 of the RO spec, v1.0.
*/
- public Response.ResponseBuilder buildResponse(
+ ResponseEntity<Object> buildResponse(
IResourceContext resourceContext,
ManagedAction objectAndAction);
/**
* Returns a representation of a single action invocation of an object.
*
- * <p>
- * By default this representation is as per section 19.5 of the
- * RO spec, v1.0.
- * </p>
+ * @apiNote By default this representation is as per section 19.5 of the RO spec, v1.0.
*/
- public Response.ResponseBuilder buildResponse(
+ ResponseEntity<Object> buildResponse(
IResourceContext resourceContext,
ObjectAndActionInvocation objectAndActionInvocation);
}
diff --git a/viewers/restfulobjects/rendering/src/main/java/org/apache/causeway/viewer/restfulobjects/rendering/service/conneg/ContentNegotiationServiceAbstract.java b/viewers/restfulobjects/rendering/src/main/java/org/apache/causeway/viewer/restfulobjects/rendering/service/conneg/ContentNegotiationServiceAbstract.java
index 769bea8e0e9..b6edb84b5b8 100644
--- a/viewers/restfulobjects/rendering/src/main/java/org/apache/causeway/viewer/restfulobjects/rendering/service/conneg/ContentNegotiationServiceAbstract.java
+++ b/viewers/restfulobjects/rendering/src/main/java/org/apache/causeway/viewer/restfulobjects/rendering/service/conneg/ContentNegotiationServiceAbstract.java
@@ -21,8 +21,10 @@
import java.util.List;
import java.util.Objects;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
-import jakarta.ws.rs.core.Response;
+import org.springframework.http.ResponseEntity;
import org.apache.causeway.commons.internal.base._Strings;
import org.apache.causeway.commons.internal.collections._Lists;
@@ -32,8 +34,8 @@
import org.apache.causeway.core.metamodel.interactions.managed.ManagedCollection;
import org.apache.causeway.core.metamodel.interactions.managed.ManagedProperty;
import org.apache.causeway.core.metamodel.object.ManagedObject;
-import org.apache.causeway.viewer.restfulobjects.applib.RestfulResponse;
import org.apache.causeway.viewer.restfulobjects.rendering.IResourceContext;
+import org.apache.causeway.viewer.restfulobjects.rendering.ResponseFactory;
import org.apache.causeway.viewer.restfulobjects.rendering.RestfulObjectsApplicationException;
import org.apache.causeway.viewer.restfulobjects.rendering.domainobjects.ObjectAndActionInvocation;
@@ -42,36 +44,38 @@
*/
public abstract class ContentNegotiationServiceAbstract implements ContentNegotiationService {
+ @Autowired protected ResponseFactory responseFactory;
+
@Override
- public Response.ResponseBuilder buildResponse(
+ public ResponseEntity<Object> buildResponse(
final IResourceContext resourceContext,
final ManagedObject objectAdapter) {
return null;
}
@Override
- public Response.ResponseBuilder buildResponse(
+ public ResponseEntity<Object> buildResponse(
final IResourceContext resourceContext,
final ManagedProperty objectAndProperty) {
return null;
}
@Override
- public Response.ResponseBuilder buildResponse(
+ public ResponseEntity<Object> buildResponse(
final IResourceContext resourceContext,
final ManagedCollection objectAndCollection) {
return null;
}
@Override
- public Response.ResponseBuilder buildResponse(
+ public ResponseEntity<Object> buildResponse(
final IResourceContext resourceContext,
final ManagedAction objectAndAction) {
return null;
}
@Override
- public Response.ResponseBuilder buildResponse(
+ public ResponseEntity<Object> buildResponse(
final IResourceContext resourceContext,
final ObjectAndActionInvocation objectAndActionInvocation) {
return null;
@@ -96,7 +100,7 @@ protected Class<?> loadClass(final String cls) {
try {
domainType = _InstanceUtil.loadClass(cls);
}catch (final Exception ex) {
- throw RestfulObjectsApplicationException.createWithCause(RestfulResponse.HttpStatusCode.BAD_REQUEST, ex);
+ throw RestfulObjectsApplicationException.createWithCause(HttpStatus.BAD_REQUEST, ex);
}
return domainType;
@@ -104,16 +108,16 @@ protected Class<?> loadClass(final String cls) {
protected void ensureJaxbAnnotated(final Class<?> domainType) {
if(!_ClassCache.getInstance().head(domainType).hasJaxbRootElementSemantics()) {
- throw RestfulObjectsApplicationException.createWithMessage(RestfulResponse.HttpStatusCode.BAD_REQUEST, "Requested domain Type '" + domainType.getName() + "' is not annotated with JAXB @XmlRootElement annotation");
+ throw RestfulObjectsApplicationException.createWithMessage(HttpStatus.BAD_REQUEST, "Requested domain Type '" + domainType.getName() + "' is not annotated with JAXB @XmlRootElement annotation");
}
}
protected void ensureDomainObjectAssignable(final String xRoDomainType, final Class<?> domainType, final Object domainObject) {
if(!domainType.isAssignableFrom(domainObject.getClass())) {
throw RestfulObjectsApplicationException.createWithMessage(
- RestfulResponse.HttpStatusCode.NOT_ACCEPTABLE,
- "Requested object of type '%s' however the object returned by the domain object is not assignable (is '%s')",
- xRoDomainType, domainObject.getClass().getName());
+ HttpStatus.NOT_ACCEPTABLE,
+ "Requested object of type '%s' however the object returned by the domain object is not assignable (is '%s')"
+ .formatted(xRoDomainType, domainObject.getClass().getName()));
}
}
diff --git a/viewers/restfulobjects/rendering/src/main/java/org/apache/causeway/viewer/restfulobjects/rendering/service/conneg/ContentNegotiationServiceForRestfulObjectsV1_0.java b/viewers/restfulobjects/rendering/src/main/java/org/apache/causeway/viewer/restfulobjects/rendering/service/conneg/ContentNegotiationServiceForRestfulObjectsV1_0.java
index 2ff0800d377..57ad6622728 100644
--- a/viewers/restfulobjects/rendering/src/main/java/org/apache/causeway/viewer/restfulobjects/rendering/service/conneg/ContentNegotiationServiceForRestfulObjectsV1_0.java
+++ b/viewers/restfulobjects/rendering/src/main/java/org/apache/causeway/viewer/restfulobjects/rendering/service/conneg/ContentNegotiationServiceForRestfulObjectsV1_0.java
@@ -25,9 +25,10 @@
import jakarta.annotation.Priority;
import jakarta.inject.Inject;
import jakarta.inject.Named;
+
+import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
-import jakarta.ws.rs.core.Response;
-import jakarta.ws.rs.core.Response.ResponseBuilder;
+import org.springframework.http.ResponseEntity;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Service;
@@ -46,10 +47,9 @@
import org.apache.causeway.viewer.restfulobjects.applib.CausewayModuleViewerRestfulObjectsApplib;
import org.apache.causeway.viewer.restfulobjects.applib.JsonRepresentation;
import org.apache.causeway.viewer.restfulobjects.applib.RepresentationType;
-import org.apache.causeway.viewer.restfulobjects.applib.RestfulResponse;
import org.apache.causeway.viewer.restfulobjects.rendering.Caching;
import org.apache.causeway.viewer.restfulobjects.rendering.IResourceContext;
-import org.apache.causeway.viewer.restfulobjects.rendering.Responses;
+import org.apache.causeway.viewer.restfulobjects.rendering.ResponseFactory;
import org.apache.causeway.viewer.restfulobjects.rendering.RestfulObjectsApplicationException;
import org.apache.causeway.viewer.restfulobjects.rendering.domainobjects.ActionResultReprRenderer;
import org.apache.causeway.viewer.restfulobjects.rendering.domainobjects.DomainObjectReprRenderer;
@@ -60,6 +60,7 @@
import org.apache.causeway.viewer.restfulobjects.rendering.service.RepresentationService;
import org.jspecify.annotations.NonNull;
+import org.jspecify.annotations.Nullable;
/**
* Returns representations according to the
@@ -78,119 +79,113 @@ public class ContentNegotiationServiceForRestfulObjectsV1_0
protected final SpecificationLoader specificationLoader;
private final AcceptChecking acceptChecking;
+ private final ResponseFactory responseFactory;
@Inject
public ContentNegotiationServiceForRestfulObjectsV1_0(
final CausewayConfiguration configuration,
- final SpecificationLoader specificationLoader) {
+ final SpecificationLoader specificationLoader,
+ final ResponseFactory responseFactory) {
this.configuration = configuration;
this.specificationLoader = specificationLoader;
+ this.responseFactory = responseFactory;
this.acceptChecking = AcceptChecking.fromConfig(configuration);
}
@Override
- public ResponseBuilder buildResponse(
+ public ResponseEntity<Object> buildResponse(
final IResourceContext resourceContext,
final ManagedObject objectAdapter) {
ensureCompatibleAcceptHeader(RepresentationType.DOMAIN_OBJECT, resourceContext);
- return responseBuilder(buildResponseTo(
- resourceContext, objectAdapter, JsonRepresentation.newMap(), null));
+ return buildResponseTo(
+ resourceContext, objectAdapter, JsonRepresentation.newMap(), null, null);
}
/**
* Not API
*/
- ResponseBuilder buildResponseTo(
+ ResponseEntity<Object> buildResponseTo(
final IResourceContext resourceContext,
final ManagedObject objectAdapter,
final JsonRepresentation representationIfAnyRequired,
- final JsonRepresentation rootRepresentation) {
+ final JsonRepresentation rootRepresentation,
+ final @Nullable MediaType mediaTypeOverride) {
final DomainObjectReprRenderer renderer =
new DomainObjectReprRenderer(resourceContext, null, representationIfAnyRequired)
.with(objectAdapter)
.includesSelf();
- final ResponseBuilder responseBuilder = Responses.ofOk(renderer, Caching.NONE, rootRepresentation);
-
- if(resourceContext.intent() == RepresentationService.Intent.JUST_CREATED) {
- responseBuilder.status(Response.Status.CREATED);
- }
+ var status = resourceContext.intent() == RepresentationService.Intent.JUST_CREATED
+ ? HttpStatus.CREATED
+ : HttpStatus.OK;
- return responseBuilder;
+ return responseFactory.of(status, renderer, Caching.NONE, rootRepresentation, mediaTypeOverride);
}
@Override
- public ResponseBuilder buildResponse(
+ public ResponseEntity<Object> buildResponse(
final IResourceContext resourceContext,
final ManagedProperty objectAndProperty) {
ensureCompatibleAcceptHeader(RepresentationType.OBJECT_PROPERTY, resourceContext);
- var renderer =
- new ObjectPropertyReprRenderer(resourceContext)
+ var renderer = new ObjectPropertyReprRenderer(resourceContext)
.with(objectAndProperty)
- .usingLinkTo(resourceContext.objectAdapterLinkTo());
-
- var repMode = objectAndProperty.getRepresentationMode();
- if(repMode.isExplicit()) {
- renderer.withMemberMode(repMode);
- }
+ .usingLinkTo(resourceContext.objectAdapterLinkTo())
+ .withMemberMode(objectAndProperty.getRepresentationMode());
- return Responses.ofOk(renderer, Caching.NONE);
+ return responseFactory.ok(renderer, Caching.NONE, null, null);
}
@Override
- public ResponseBuilder buildResponse(
+ public ResponseEntity<Object> buildResponse(
final IResourceContext resourceContext,
final ManagedCollection objectAndCollection) {
ensureCompatibleAcceptHeader(RepresentationType.OBJECT_COLLECTION, resourceContext);
- return responseBuilder(buildResponseTo(
- resourceContext, objectAndCollection, JsonRepresentation.newMap(), null));
+ return buildResponseTo(
+ resourceContext, objectAndCollection, JsonRepresentation.newMap(), null, null);
}
/**
* Not API
*/
- ResponseBuilder buildResponseTo(
+ ResponseEntity<Object> buildResponseTo(
final IResourceContext resourceContext,
final ManagedCollection objectAndCollection,
final JsonRepresentation representation,
- final JsonRepresentation rootRepresentation) {
- final ObjectCollectionReprRenderer renderer =
- new ObjectCollectionReprRenderer(resourceContext, null, null, representation);
- renderer.with(objectAndCollection)
- .usingLinkTo(resourceContext.objectAdapterLinkTo());
-
- if(objectAndCollection.getRepresentationMode().isExplicit()) {
- renderer.withMemberMode(objectAndCollection.getRepresentationMode());
- }
+ final JsonRepresentation rootRepresentation,
+ final @Nullable MediaType mediaTypeOverride) {
- return Responses.ofOk(renderer, Caching.NONE, rootRepresentation);
+ var renderer = new ObjectCollectionReprRenderer(resourceContext, null, null, representation)
+ .with(objectAndCollection)
+ .usingLinkTo(resourceContext.objectAdapterLinkTo())
+ .withMemberMode(objectAndCollection.getRepresentationMode());
+
+ return responseFactory.ok(renderer, Caching.NONE, rootRepresentation, mediaTypeOverride);
}
@Override
- public ResponseBuilder buildResponse(
+ public ResponseEntity<Object> buildResponse(
final IResourceContext resourceContext,
final ManagedAction objectAndAction) {
ensureCompatibleAcceptHeader(RepresentationType.OBJECT_ACTION, resourceContext);
- var renderer =
- new ObjectActionReprRenderer(resourceContext)
- .with(objectAndAction)
- .usingLinkTo(resourceContext.objectAdapterLinkTo())
- .asStandalone();
+ var renderer = new ObjectActionReprRenderer(resourceContext)
+ .with(objectAndAction)
+ .usingLinkTo(resourceContext.objectAdapterLinkTo())
+ .asStandalone();
- return responseBuilder(Responses.ofOk(renderer, Caching.NONE));
+ return responseFactory.ok(renderer, Caching.NONE, null, null);
}
@Override
- public ResponseBuilder buildResponse(
+ public ResponseEntity<Object> buildResponse(
final IResourceContext resourceContext,
final ObjectAndActionInvocation objectAndActionInvocation) {
@@ -206,10 +201,9 @@ && isAccepted(RepresentationType.DOMAIN_OBJECT, acceptableMediaTypes)) {
return objectAndActionInvocation.asEitherSingularOrPlural()
.fold(singularActionResult->{
- return responseBuilder(
- buildResponse(
+ return buildResponse(
resourceContext,
- singularActionResult));
+ singularActionResult);
}, pluralActionResult->{
final ObjectSpecification elementSpec =
objectAndActionInvocation.getAction().getElementType();
@@ -226,33 +220,23 @@ && isAccepted(RepresentationType.DOMAIN_OBJECT, acceptableMediaTypes)) {
"framework bug: DomainObjectList should be recognized as viewmodel"));
var listAdapter = ManagedObject.viewmodel(domainObjectListSpec, listAsViewmodel, Optional.empty());
- return responseBuilder(
- buildResponse(
+ return buildResponse(
resourceContext,
- listAdapter));
+ listAdapter);
});
}
if(isAccepted(RepresentationType.ACTION_RESULT, acceptableMediaTypes)) {
-
- return responseBuilder(
- buildResponseTo(
- resourceContext,
- objectAndActionInvocation,
- JsonRepresentation.newMap(),
- /*rootRepr*/null));
+ return buildResponseTo(
+ resourceContext,
+ objectAndActionInvocation,
+ JsonRepresentation.newMap(),
+ /*rootRepr*/null, null);
}
- throw RestfulObjectsApplicationException.create(RestfulResponse.HttpStatusCode.NOT_ACCEPTABLE);
-
- }
+ throw RestfulObjectsApplicationException.create(HttpStatus.NOT_ACCEPTABLE);
- /**
- * For easy sub-classing to further customize, eg additional headers
- */
- protected ResponseBuilder responseBuilder(final ResponseBuilder responseBuilder) {
- return responseBuilder;
}
// -- HELPER
@@ -280,9 +264,9 @@ private static String actionArgumentsFrom(final ObjectAndActionInvocation object
buf.append(",");
}
buf
- .append(param.getCanonicalFriendlyName())
- .append("=")
- .append(abbreviated(titleOf(argAdapter), 8));
+ .append(param.getCanonicalFriendlyName())
+ .append("=")
+ .append(abbreviated(titleOf(argAdapter), 8));
}
}
@@ -324,18 +308,17 @@ private static String titleFrom(
/**
* Not API
*/
- ResponseBuilder buildResponseTo(
+ ResponseEntity<Object> buildResponseTo(
final IResourceContext resourceContext,
final ObjectAndActionInvocation objectAndActionInvocation,
final JsonRepresentation representation,
- final JsonRepresentation rootRepresentation) {
- var renderer =
- new ActionResultReprRenderer(resourceContext, null, objectAndActionInvocation.getSelfLink(), representation);
- renderer
+ final JsonRepresentation rootRepresentation,
+ final @Nullable MediaType mediaTypeOverride) {
+ var renderer = new ActionResultReprRenderer(resourceContext, null, objectAndActionInvocation.getSelfLink(), representation)
.with(objectAndActionInvocation)
.using(resourceContext.objectAdapterLinkTo());
- return Responses.ofOk(renderer, Caching.NONE, rootRepresentation);
+ return responseFactory.ok(renderer, Caching.NONE, rootRepresentation, mediaTypeOverride);
}
private static enum AcceptChecking {
@@ -356,21 +339,16 @@ static AcceptChecking fromConfig(final CausewayConfiguration configuration) {
private void ensureCompatibleAcceptHeader(
final RepresentationType representationType,
final IResourceContext resourceContext) {
- if(acceptChecking.isRelaxed()) {
- return;
- }
- if (representationType == null) {
- return;
- }
+ if(acceptChecking.isRelaxed()) return;
+ if(representationType == null) return;
// RestEasy will check the basic media types...
// ... so we just need to check the profile parameter
final String producedProfile = representationType.getMediaTypeProfile();
- if (producedProfile == null) {
- return;
- }
+ if (producedProfile == null) return;
+
if(!isAccepted(producedProfile, resourceContext.acceptableMediaTypes())) {
- throw RestfulObjectsApplicationException.create(RestfulResponse.HttpStatusCode.NOT_ACCEPTABLE);
+ throw RestfulObjectsApplicationException.create(HttpStatus.NOT_ACCEPTABLE);
}
}
diff --git a/viewers/restfulobjects/rendering/src/main/java/org/apache/causeway/viewer/restfulobjects/rendering/service/conneg/ContentNegotiationServiceOrgApacheCausewayV2.java b/viewers/restfulobjects/rendering/src/main/java/org/apache/causeway/viewer/restfulobjects/rendering/service/conneg/ContentNegotiationServiceOrgApacheCausewayV2.java
index f3edeff6218..bb2a04ce37d 100644
--- a/viewers/restfulobjects/rendering/src/main/java/org/apache/causeway/viewer/restfulobjects/rendering/service/conneg/ContentNegotiationServiceOrgApacheCausewayV2.java
+++ b/viewers/restfulobjects/rendering/src/main/java/org/apache/causeway/viewer/restfulobjects/rendering/service/conneg/ContentNegotiationServiceOrgApacheCausewayV2.java
@@ -25,7 +25,7 @@
import jakarta.inject.Named;
import org.springframework.http.MediaType;
-import jakarta.ws.rs.core.Response;
+import org.springframework.http.ResponseEntity;
import com.fasterxml.jackson.databind.node.POJONode;
@@ -52,7 +52,7 @@
import org.apache.causeway.viewer.restfulobjects.applib.domainobjects.ActionResultRepresentation;
import org.apache.causeway.viewer.restfulobjects.applib.dtos.ScalarValueDtoV2;
import org.apache.causeway.viewer.restfulobjects.rendering.IResourceContext;
-import org.apache.causeway.viewer.restfulobjects.rendering.Responses;
+import org.apache.causeway.viewer.restfulobjects.rendering.ResponseFactory;
import org.apache.causeway.viewer.restfulobjects.rendering.domainobjects.ObjectAndActionInvocation;
import org.apache.causeway.viewer.restfulobjects.rendering.domainobjects.ObjectPropertyReprRenderer;
@@ -83,14 +83,11 @@ public class ContentNegotiationServiceOrgApacheCausewayV2
* within that map.
*/
@Override
- public Response.ResponseBuilder buildResponse(
+ public ResponseEntity<Object> buildResponse(
final IResourceContext resourceContext,
final ManagedObject objectAdapter) {
- boolean canAccept = canAccept(resourceContext);
- if(!canAccept) {
- return null;
- }
+ if(!canAccept(resourceContext)) return null;
final EnumSet<SuppressionType> suppression = suppress(resourceContext);
final boolean suppressRO = suppression.contains(SuppressionType.RO);
@@ -106,21 +103,16 @@ public Response.ResponseBuilder buildResponse(
} else {
$$roRepresentation = null;
}
- final Response.ResponseBuilder responseBuilder =
- restfulObjectsV1_0.buildResponseTo(
- resourceContext, objectAdapter, $$roRepresentation, rootRepresentation);
-
- responseBuilder.type(
- RepresentationTypeSimplifiedV2.OBJECT.getContentTypeHeaderValue(ACCEPT_PROFILE));
-
- return responseBuilder(responseBuilder);
+ return restfulObjectsV1_0.buildResponseTo(
+ resourceContext, objectAdapter, $$roRepresentation, rootRepresentation,
+ RepresentationTypeSimplifiedV2.OBJECT.getResponseContentType(ACCEPT_PROFILE));
}
/**
* Individual property of an object is not supported.
*/
@Override
- public Response.ResponseBuilder buildResponse(
+ public ResponseEntity<Object> buildResponse(
final IResourceContext resourceContext,
final ManagedProperty objectAndProperty) {
@@ -132,13 +124,12 @@ public Response.ResponseBuilder buildResponse(
* as an object in the list with a single property named '$$ro'
*/
@Override
- public Response.ResponseBuilder buildResponse(
+ public ResponseEntity<Object> buildResponse(
final IResourceContext resourceContext,
final ManagedCollection managedCollection) {
- if(!canAccept(resourceContext)) {
- return null;
- }
+ if(!canAccept(resourceContext)) return null;
+
final EnumSet<SuppressionType> suppression = suppress(resourceContext);
final boolean suppressRO = suppression.contains(SuppressionType.RO);
@@ -157,22 +148,16 @@ public Response.ResponseBuilder buildResponse(
} else {
$$roRepresentation = null;
}
-
- final Response.ResponseBuilder responseBuilder =
- restfulObjectsV1_0.buildResponseTo(
- resourceContext, managedCollection, $$roRepresentation, rootRepresentation);
-
- responseBuilder.type(
- RepresentationTypeSimplifiedV2.OBJECT_COLLECTION.getContentTypeHeaderValue(ACCEPT_PROFILE));
-
- return responseBuilder(responseBuilder);
+ return restfulObjectsV1_0.buildResponseTo(
+ resourceContext, managedCollection, $$roRepresentation, rootRepresentation,
+ RepresentationTypeSimplifiedV2.OBJECT_COLLECTION.getResponseContentType(ACCEPT_PROFILE));
}
/**
* Action prompt is not supported.
*/
@Override
- public Response.ResponseBuilder buildResponse(
+ public ResponseEntity<Object> buildResponse(
final IResourceContext resourceContext,
final ManagedAction objectAndAction) {
return null;
@@ -188,13 +173,12 @@ public Response.ResponseBuilder buildResponse(
* with a single '$$ro' property (similar to {@link #buildResponse(IResourceContext, ManagedCollection)})
*/
@Override
- public Response.ResponseBuilder buildResponse(
+ public ResponseEntity<Object> buildResponse(
final IResourceContext resourceContext,
final ObjectAndActionInvocation objectAndActionInvocation) {
- if(!canAccept(resourceContext)) {
- return null;
- }
+ if(!canAccept(resourceContext)) return null;
+
final EnumSet<SuppressionType> suppression = suppress(resourceContext);
final boolean suppressRO = suppression.contains(SuppressionType.RO);
@@ -216,7 +200,7 @@ public Response.ResponseBuilder buildResponse(
if(ManagedObjects.isNullOrUnspecifiedOrEmpty(returnedAdapter)) {
// 404 not found
- return Responses.ofNotFound();
+ return ResponseFactory.notFound();
} else {
rootRepresentation = JsonRepresentation.newMap();
@@ -231,7 +215,7 @@ public Response.ResponseBuilder buildResponse(
if(!objectAndActionInvocation.hasElements()) {
// 404 not found
- return Responses.ofNotFound();
+ return ResponseFactory.notFound();
}
@@ -256,7 +240,7 @@ public Response.ResponseBuilder buildResponse(
if(!objectAndActionInvocation.hasElements()) {
// 404 not found
- return Responses.ofNotFound();
+ return ResponseFactory.notFound();
}
@@ -278,7 +262,7 @@ public Response.ResponseBuilder buildResponse(
var dto = dtoForValue(returnedAdapter).orElse(null);
if(dto==null) {
// 404 not found
- return Responses.ofNotFound();
+ return ResponseFactory.notFound();
}
var jsonNode = new POJONode(dto);
@@ -295,12 +279,9 @@ public Response.ResponseBuilder buildResponse(
default:
throw _Exceptions.unmatchedCase(resultType);
}
-
- var responseBuilder = restfulObjectsV1_0
- .buildResponseTo(resourceContext, objectAndActionInvocation, $$roRepresentation, rootRepresentation)
- .type(headerContentType.getContentTypeHeaderValue(ACCEPT_PROFILE)); // set appropriate Content-Type
-
- return responseBuilder(responseBuilder);
+ return restfulObjectsV1_0.buildResponseTo(
+ resourceContext, objectAndActionInvocation, $$roRepresentation, rootRepresentation,
+ headerContentType.getResponseContentType(ACCEPT_PROFILE)); // set appropriate Content-Type
}
private Optional<Object> dtoForValue(final @Nullable ManagedObject valueObject) {
@@ -317,13 +298,6 @@ private Optional<Object> dtoForValue(final @Nullable ManagedObject valueObject)
return Optional.of(dto);
}
- /**
- * For easy subclassing to further customize, eg additional headers
- */
- protected Response.ResponseBuilder responseBuilder(final Response.ResponseBuilder responseBuilder) {
- return responseBuilder;
- }
-
boolean canAccept(final IResourceContext resourceContext) {
final List<MediaType> acceptableMediaTypes = resourceContext.acceptableMediaTypes();
return mediaTypeParameterMatches(acceptableMediaTypes, "profile", ACCEPT_PROFILE);
diff --git a/viewers/restfulobjects/rendering/src/main/java/org/apache/causeway/viewer/restfulobjects/rendering/service/conneg/ContentNegotiationServiceOrgApacheIsisV1.java b/viewers/restfulobjects/rendering/src/main/java/org/apache/causeway/viewer/restfulobjects/rendering/service/conneg/ContentNegotiationServiceOrgApacheIsisV1.java
index ab15591b23f..69e434385d8 100644
--- a/viewers/restfulobjects/rendering/src/main/java/org/apache/causeway/viewer/restfulobjects/rendering/service/conneg/ContentNegotiationServiceOrgApacheIsisV1.java
+++ b/viewers/restfulobjects/rendering/src/main/java/org/apache/causeway/viewer/restfulobjects/rendering/service/conneg/ContentNegotiationServiceOrgApacheIsisV1.java
@@ -21,11 +21,10 @@
import java.util.List;
import jakarta.inject.Named;
-import org.springframework.http.MediaType;
-import jakarta.ws.rs.core.Response;
-import jakarta.ws.rs.core.Response.ResponseBuilder;
import org.springframework.beans.factory.annotation.Qualifier;
+import org.springframework.http.MediaType;
+import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;
import org.apache.causeway.applib.annotation.PriorityPrecedence;
@@ -35,7 +34,7 @@
import org.apache.causeway.core.metamodel.object.ManagedObject;
import org.apache.causeway.viewer.restfulobjects.applib.CausewayModuleViewerRestfulObjectsApplib;
import org.apache.causeway.viewer.restfulobjects.rendering.IResourceContext;
-import org.apache.causeway.viewer.restfulobjects.rendering.Responses;
+import org.apache.causeway.viewer.restfulobjects.rendering.ResponseFactory;
import org.apache.causeway.viewer.restfulobjects.rendering.domainobjects.ObjectAndActionInvocation;
import lombok.extern.slf4j.Slf4j;
@@ -54,35 +53,35 @@ public class ContentNegotiationServiceOrgApacheIsisV1 extends ContentNegotiation
public static final String ACCEPT_PROFILE = "urn:org.apache.isis/v1";
@Override
- public Response.ResponseBuilder buildResponse(
+ public ResponseEntity<Object> buildResponse(
final IResourceContext resourceContext,
final ManagedObject objectAdapter) {
return whenV1ThenNotImplemented(resourceContext);
}
@Override
- public Response.ResponseBuilder buildResponse(
+ public ResponseEntity<Object> buildResponse(
final IResourceContext resourceContext,
final ManagedProperty objectAndProperty) {
return whenV1ThenNotImplemented(resourceContext);
}
@Override
- public Response.ResponseBuilder buildResponse(
+ public ResponseEntity<Object> buildResponse(
final IResourceContext resourceContext,
final ManagedCollection managedCollection) {
return whenV1ThenNotImplemented(resourceContext);
}
@Override
- public Response.ResponseBuilder buildResponse(
+ public ResponseEntity<Object> buildResponse(
final IResourceContext resourceContext,
final ManagedAction objectAndAction) {
return whenV1ThenNotImplemented(resourceContext);
}
@Override
- public Response.ResponseBuilder buildResponse(
+ public ResponseEntity<Object> buildResponse(
final IResourceContext resourceContext,
final ObjectAndActionInvocation objectAndActionInvocation) {
return whenV1ThenNotImplemented(resourceContext);
@@ -95,14 +94,14 @@ private boolean canAccept(final IResourceContext resourceContext) {
return mediaTypeParameterMatches(acceptableMediaTypes, "profile", ACCEPT_PROFILE);
}
- private ResponseBuilder whenV1ThenNotImplemented(final IResourceContext resourceContext) {
+ private ResponseEntity<Object> whenV1ThenNotImplemented(final IResourceContext resourceContext) {
if(!canAccept(resourceContext)) {
return null;
}
log.warn("profile '{}' is no longer supported use '{}' instead",
ACCEPT_PROFILE,
ContentNegotiationServiceOrgApacheCausewayV2.ACCEPT_PROFILE);
- return Responses.ofNotImplemented();
+ return ResponseFactory.notImplemented();
}
}
diff --git a/viewers/restfulobjects/rendering/src/main/java/org/apache/causeway/viewer/restfulobjects/rendering/service/conneg/ContentNegotiationServiceXRoDomainType.java b/viewers/restfulobjects/rendering/src/main/java/org/apache/causeway/viewer/restfulobjects/rendering/service/conneg/ContentNegotiationServiceXRoDomainType.java
index 80a41409f3a..ab809c3d7da 100644
--- a/viewers/restfulobjects/rendering/src/main/java/org/apache/causeway/viewer/restfulobjects/rendering/service/conneg/ContentNegotiationServiceXRoDomainType.java
+++ b/viewers/restfulobjects/rendering/src/main/java/org/apache/causeway/viewer/restfulobjects/rendering/service/conneg/ContentNegotiationServiceXRoDomainType.java
@@ -22,8 +22,10 @@
import jakarta.inject.Inject;
import jakarta.inject.Named;
+
+import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
-import jakarta.ws.rs.core.Response;
+import org.springframework.http.ResponseEntity;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Service;
@@ -33,8 +35,6 @@
import org.apache.causeway.core.metamodel.object.ManagedObject;
import org.apache.causeway.viewer.restfulobjects.applib.CausewayModuleViewerRestfulObjectsApplib;
import org.apache.causeway.viewer.restfulobjects.applib.RepresentationType;
-import org.apache.causeway.viewer.restfulobjects.applib.RestfulResponse;
-import org.apache.causeway.viewer.restfulobjects.applib.util.MediaTypes;
import org.apache.causeway.viewer.restfulobjects.rendering.IResourceContext;
import org.apache.causeway.viewer.restfulobjects.rendering.RestfulObjectsApplicationException;
import org.apache.causeway.viewer.restfulobjects.rendering.domainobjects.ObjectAndActionInvocation;
@@ -66,10 +66,11 @@ public class ContentNegotiationServiceXRoDomainType extends ContentNegotiationSe
@Inject private List<ContentMappingService> contentMappingServices;
/**
- * search for an accept header in form <code>application/xml;profile=urn:org.restfulobjects:repr-types/object;x-ro-domain-type=todoapp.dto.module.todoitem.ToDoItemDto</code>
+ * search for an accept header in form
+ * <code>application/xml;profile=urn:org.restfulobjects:repr-types/object;x-ro-domain-type=todoapp.dto.module.todoitem.ToDoItemDto</code>
*/
@Override
- public Response.ResponseBuilder buildResponse(
+ public ResponseEntity<Object> buildResponse(
final IResourceContext resourceContext,
final ManagedObject objectAdapter) {
@@ -99,10 +100,11 @@ protected MediaType mediaTypeFrom(
}
/**
- * search for an accept header in form <code>application/xml;profile=urn:org.restfulobjects:repr-types/action-result;x-ro-domain-type=todoapp.dto.module.todoitem.ToDoItemDto</code>
+ * search for an accept header in form
+ * <code>application/xml;profile=urn:org.restfulobjects:repr-types/action-result;x-ro-domain-type=todoapp.dto.module.todoitem.ToDoItemDto</code>
*/
@Override
- public Response.ResponseBuilder buildResponse(
+ public ResponseEntity<Object> buildResponse(
final IResourceContext resourceContext,
final ObjectAndActionInvocation objectAndActionInvocation) {
@@ -115,12 +117,12 @@ public Response.ResponseBuilder buildResponse(
final Object domainObject = returnedObjectOf(objectAndActionInvocation);
if(domainObject == null) {
- throw RestfulObjectsApplicationException.create(RestfulResponse.HttpStatusCode.NOT_FOUND);
+ throw RestfulObjectsApplicationException.create(HttpStatus.NOT_FOUND);
}
return buildResponse(resourceContext, domainObject, representationType);
}
- protected Response.ResponseBuilder buildResponse(
+ protected ResponseEntity<Object> buildResponse(
final IResourceContext renderContext,
final Object domainObject,
final RepresentationType representationType) {
@@ -143,7 +145,7 @@ protected Response.ResponseBuilder buildResponse(
ensureJaxbAnnotated(mappedDomainObject.getClass());
}
- return Response.ok(mappedDomainObject, MediaTypes.toJakarta(mediaType));
+ return responseFactory.ok(mappedDomainObject, mediaType);
}
/**
diff --git a/viewers/restfulobjects/rendering/src/main/java/org/apache/causeway/viewer/restfulobjects/rendering/util/RequestParams.java b/viewers/restfulobjects/rendering/src/main/java/org/apache/causeway/viewer/restfulobjects/rendering/util/RequestParams.java
index d167bb85523..b53441c0ffb 100644
--- a/viewers/restfulobjects/rendering/src/main/java/org/apache/causeway/viewer/restfulobjects/rendering/util/RequestParams.java
+++ b/viewers/restfulobjects/rendering/src/main/java/org/apache/causeway/viewer/restfulobjects/rendering/util/RequestParams.java
@@ -28,10 +28,11 @@
import org.jspecify.annotations.NonNull;
import org.jspecify.annotations.Nullable;
+import org.springframework.http.HttpStatus;
+
import org.apache.causeway.commons.internal.base._Bytes;
import org.apache.causeway.commons.internal.base._Strings;
import org.apache.causeway.viewer.restfulobjects.applib.JsonRepresentation;
-import org.apache.causeway.viewer.restfulobjects.applib.RestfulResponse;
import org.apache.causeway.viewer.restfulobjects.applib.util.JsonMapper;
import org.apache.causeway.viewer.restfulobjects.rendering.RestfulObjectsApplicationException;
@@ -70,7 +71,7 @@ private static String asStringUtf8(final InputStream body) {
return _Strings.ofBytes(_Bytes.of(body), StandardCharsets.UTF_8);
} catch (final IOException e) {
throw RestfulObjectsApplicationException
- .createWithCauseAndMessage(RestfulResponse.HttpStatusCode.BAD_REQUEST, e, "could not read body");
+ .createWithCauseAndMessage(HttpStatus.BAD_REQUEST, e, "could not read body");
}
}
@@ -90,18 +91,18 @@ private static JsonRepresentation readAsMap(final String rawArgs, final String a
final JsonRepresentation jsonRepr = JsonMapper.instance().read(rawArgs);
if (!jsonRepr.isMap()) {
throw RestfulObjectsApplicationException
- .createWithMessage(RestfulResponse.HttpStatusCode.BAD_REQUEST, "could not read %s as a JSON map", argsNature);
+ .createWithMessage(HttpStatus.BAD_REQUEST, "could not read %s as a JSON map".formatted(argsNature));
}
return jsonRepr;
} catch (final JsonParseException e) {
throw RestfulObjectsApplicationException
- .createWithCauseAndMessage(RestfulResponse.HttpStatusCode.BAD_REQUEST, e, "could not parse %s", argsNature);
+ .createWithCauseAndMessage(HttpStatus.BAD_REQUEST, e, "could not parse %s".formatted(argsNature));
} catch (final JsonMappingException e) {
throw RestfulObjectsApplicationException
- .createWithCauseAndMessage(RestfulResponse.HttpStatusCode.BAD_REQUEST, e, "could not read %s as JSON", argsNature);
+ .createWithCauseAndMessage(HttpStatus.BAD_REQUEST, e, "could not read %s as JSON".formatted(argsNature));
} catch (final IOException e) {
throw RestfulObjectsApplicationException
- .createWithCauseAndMessage(RestfulResponse.HttpStatusCode.BAD_REQUEST, e, "could not parse %s", argsNature);
+ .createWithCauseAndMessage(HttpStatus.BAD_REQUEST, e, "could not parse %s".formatted(argsNature));
}
}
diff --git a/viewers/restfulobjects/test/src/test/java/org/apache/causeway/viewer/restfulobjects/test/CausewayViewerRestfulObjectsIntegTestAbstract.java b/viewers/restfulobjects/test/src/test/java/org/apache/causeway/viewer/restfulobjects/test/CausewayViewerRestfulObjectsIntegTestAbstract.java
index 3940127dc9c..74e30339fa5 100644
--- a/viewers/restfulobjects/test/src/test/java/org/apache/causeway/viewer/restfulobjects/test/CausewayViewerRestfulObjectsIntegTestAbstract.java
+++ b/viewers/restfulobjects/test/src/test/java/org/apache/causeway/viewer/restfulobjects/test/CausewayViewerRestfulObjectsIntegTestAbstract.java
@@ -72,7 +72,10 @@
classes = {
CausewayViewerRestfulObjectsIntegTestManifest.class,
},
- webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT
+ webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT,
+ properties = {
+ "causeway.viewer.restfulobjects.path-prefix=/restful"
+ }
)
@TestInstance(TestInstance.Lifecycle.PER_CLASS)
diff --git a/viewers/restfulobjects/test/src/test/java/org/apache/causeway/viewer/restfulobjects/test/scenarios/Abstract_IntegTest.java b/viewers/restfulobjects/test/src/test/java/org/apache/causeway/viewer/restfulobjects/test/scenarios/Abstract_IntegTest.java
index 804a30befb2..cf906afbc10 100644
--- a/viewers/restfulobjects/test/src/test/java/org/apache/causeway/viewer/restfulobjects/test/scenarios/Abstract_IntegTest.java
+++ b/viewers/restfulobjects/test/src/test/java/org/apache/causeway/viewer/restfulobjects/test/scenarios/Abstract_IntegTest.java
@@ -47,7 +47,9 @@
UniversityModule.class,
CausewayModulePersistenceJpaEclipselink.class,
})
-@TestPropertySource(properties = "logging.level.org.apache.causeway.core.runtimeservices.session.InteractionServiceDefault=DEBUG")
+@TestPropertySource(properties = {
+ "logging.level.org.apache.causeway.core.runtimeservices.session.InteractionServiceDefault=DEBUG",
+ "logging.level.org.apache.causeway.viewer.restfulobjects.viewer.resources.DomainObjectResourceServerside=DEBUG"})
@DirtiesContext
public abstract class Abstract_IntegTest extends CausewayViewerRestfulObjectsIntegTestAbstract {
diff --git a/viewers/restfulobjects/testing/src/main/java/org/apache/causeway/viewer/restfulobjects/testing/ResourceContext_ensureCompatibleAcceptHeader_ContractTest.java b/viewers/restfulobjects/testing/src/main/java/org/apache/causeway/viewer/restfulobjects/testing/ResourceContext_ensureCompatibleAcceptHeader_ContractTest.java
index df911ce2a6b..420abc1ad6c 100644
--- a/viewers/restfulobjects/testing/src/main/java/org/apache/causeway/viewer/restfulobjects/testing/ResourceContext_ensureCompatibleAcceptHeader_ContractTest.java
+++ b/viewers/restfulobjects/testing/src/main/java/org/apache/causeway/viewer/restfulobjects/testing/ResourceContext_ensureCompatibleAcceptHeader_ContractTest.java
@@ -138,7 +138,7 @@ public void nonMatching() throws Exception {
try {
instantiateResourceContext(representationType);
} catch(RestfulObjectsApplicationException ex ) {
- assertThat(ex.getHttpStatusCode(), is(HttpStatusCode.NOT_ACCEPTABLE));
+ assertThat(ex.httpStatus(), is(HttpStatusCode.NOT_ACCEPTABLE));
}
}
@@ -150,7 +150,7 @@ public void nonMatchingProfile() throws Exception {
try {
instantiateResourceContext(representationType);
} catch(RestfulObjectsApplicationException ex ) {
- assertThat(ex.getHttpStatusCode(), is(HttpStatusCode.NOT_ACCEPTABLE));
+ assertThat(ex.httpStatus(), is(HttpStatusCode.NOT_ACCEPTABLE));
}
}
@@ -162,7 +162,7 @@ public void nonMatchingProfile_ignoreGeneric() throws Exception {
try {
instantiateResourceContext(representationType);
} catch(RestfulObjectsApplicationException ex ) {
- assertThat(ex.getHttpStatusCode(), is(HttpStatusCode.NOT_ACCEPTABLE));
+ assertThat(ex.httpStatus(), is(HttpStatusCode.NOT_ACCEPTABLE));
}
}
diff --git a/viewers/restfulobjects/testing/src/main/java/org/apache/causeway/viewer/restfulobjects/testing/RestfulObjectsApplicationExceptionMapper_Test_Contract.java b/viewers/restfulobjects/testing/src/main/java/org/apache/causeway/viewer/restfulobjects/testing/RestfulObjectsApplicationExceptionMapper_Test_Contract.java
index 3fb245efaef..9243fb27c2a 100644
--- a/viewers/restfulobjects/testing/src/main/java/org/apache/causeway/viewer/restfulobjects/testing/RestfulObjectsApplicationExceptionMapper_Test_Contract.java
+++ b/viewers/restfulobjects/testing/src/main/java/org/apache/causeway/viewer/restfulobjects/testing/RestfulObjectsApplicationExceptionMapper_Test_Contract.java
@@ -18,8 +18,7 @@
*/
package org.apache.causeway.viewer.restfulobjects.testing;
-import jakarta.ws.rs.core.HttpHeaders;
-import jakarta.ws.rs.core.Response;
+import java.util.List;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
@@ -30,48 +29,44 @@
import static org.hamcrest.CoreMatchers.nullValue;
import static org.hamcrest.MatcherAssert.assertThat;
+import org.springframework.http.HttpHeaders;
+import org.springframework.http.HttpStatus;
+
import org.apache.causeway.viewer.restfulobjects.applib.JsonRepresentation;
-import org.apache.causeway.viewer.restfulobjects.applib.RestfulResponse.HttpStatusCode;
import org.apache.causeway.viewer.restfulobjects.applib.util.JsonMapper;
import org.apache.causeway.viewer.restfulobjects.rendering.RestfulObjectsApplicationException;
-import org.apache.causeway.viewer.restfulobjects.viewer.mappers.ExceptionMapperForRestfulObjectsApplication;
+import org.apache.causeway.viewer.restfulobjects.viewer.exhandling.ExceptionResponseFactory;
/**
* contract test.
*/
public abstract class RestfulObjectsApplicationExceptionMapper_Test_Contract {
- private ExceptionMapperForRestfulObjectsApplication exceptionMapper;
+ private ExceptionResponseFactory exceptionMapper;
- HttpHeaders mockHttpHeaders = Mockito.mock(HttpHeaders.class);
+ final HttpHeaders mockHttpHeaders = Mockito.mock(HttpHeaders.class);
@BeforeEach
public void setUp() throws Exception {
- /*sonar-ignore-on*/
- exceptionMapper = new ExceptionMapperForRestfulObjectsApplication() {
- {
- httpHeaders = mockHttpHeaders;
- }
- };
- /*sonar-ignore-off*/
+ exceptionMapper = new ExceptionResponseFactory(List.of());
}
@Test
public void simpleNoMessage() throws Exception {
// given
- final HttpStatusCode status = HttpStatusCode.BAD_REQUEST;
+ final var status = HttpStatus.BAD_REQUEST;
final RestfulObjectsApplicationException ex = RestfulObjectsApplicationException.create(status);
// when
- final Response response = exceptionMapper.toResponse(ex);
+ var response = exceptionMapper.buildResponse(ex, mockHttpHeaders);
// then
- assertThat(HttpStatusCode.lookup(response.getStatus()), is(status));
- assertThat(response.getMetadata().get("Warning"), is(nullValue()));
+ assertThat(HttpStatus.valueOf(response.getStatusCode().value()), is(status));
+ assertThat(response.getHeaders().get("Warning"), is(nullValue()));
// and then
- final String entity = (String) response.getEntity();
+ final String entity = (String) response.getBody();
assertThat(entity, is(not(nullValue())));
}
@@ -80,16 +75,16 @@ public void entity_withMessage() throws Exception {
// givens
final RestfulObjectsApplicationException ex =
- RestfulObjectsApplicationException.createWithMessage(HttpStatusCode.BAD_REQUEST, "foobar");
+ RestfulObjectsApplicationException.createWithMessage(HttpStatus.BAD_REQUEST, "foobar");
// when
- final Response response = exceptionMapper.toResponse(ex);
+ var response = exceptionMapper.buildResponse(ex, mockHttpHeaders);
// then
- assertThat((String) response.getMetadata().get("Warning").get(0), is("199 RestfulObjects " + ex.getMessage()));
+ assertThat(response.getHeaders().get("Warning").get(0), is("199 RestfulObjects " + ex.getMessage()));
// and then
- final String entity = (String) response.getEntity();
+ final String entity = (String) response.getBody();
assertThat(entity, is(not(nullValue())));
}
@@ -99,16 +94,16 @@ public void entity_forException() throws Exception {
// given
final Exception exception = new Exception("barfoo");
final RestfulObjectsApplicationException ex =
- RestfulObjectsApplicationException.createWithCauseAndMessage(HttpStatusCode.BAD_REQUEST, exception, "foobar");
+ RestfulObjectsApplicationException.createWithCauseAndMessage(HttpStatus.BAD_REQUEST, exception, "foobar");
// when
- final Response response = exceptionMapper.toResponse(ex);
- final String entity = (String) response.getEntity();
+ var response = exceptionMapper.buildResponse(ex, mockHttpHeaders);
+ final String entity = (String) response.getBody();
assertThat(entity, is(not(nullValue())));
final JsonRepresentation jsonRepr = JsonMapper.instance().read(entity, JsonRepresentation.class);
// then
- assertThat((String) response.getMetadata().get("Warning").get(0), is("199 RestfulObjects foobar"));
+ assertThat(response.getHeaders().get("Warning").get(0), is("199 RestfulObjects foobar"));
assertThat(jsonRepr.getString("message"), is("foobar"));
final JsonRepresentation causedByRepr = jsonRepr.getRepresentation("causedBy");
assertThat(causedByRepr, is(nullValue()));
@@ -120,16 +115,16 @@ public void entity_forExceptionWithCause() throws Exception {
// given
var cause = new Exception("barfoo", new Exception("root-cause-message"));
var ex = RestfulObjectsApplicationException
- .createWithCauseAndMessage(HttpStatusCode.BAD_REQUEST, cause, "foobar");
+ .createWithCauseAndMessage(HttpStatus.BAD_REQUEST, cause, "foobar");
// when
- final Response response = exceptionMapper.toResponse(ex);
- final String entity = (String) response.getEntity();
+ var response = exceptionMapper.buildResponse(ex, mockHttpHeaders);
+ final String entity = (String) response.getBody();
assertThat(entity, is(not(nullValue())));
final JsonRepresentation jsonRepr = JsonMapper.instance().read(entity, JsonRepresentation.class);
// then
- assertThat((String) response.getMetadata().get("Warning").get(0), is("199 RestfulObjects foobar"));
+ assertThat(response.getHeaders().get("Warning").get(0), is("199 RestfulObjects foobar"));
assertThat(jsonRepr.getString("message"), is("foobar"));
var detailJson = jsonRepr.getRepresentation("detail");
assertThat(detailJson, is(not(nullValue())));
diff --git a/viewers/restfulobjects/viewer/src/main/java/module-info.java b/viewers/restfulobjects/viewer/src/main/java/module-info.java
index 7ee872baf7f..ab8d2185a34 100644
--- a/viewers/restfulobjects/viewer/src/main/java/module-info.java
+++ b/viewers/restfulobjects/viewer/src/main/java/module-info.java
@@ -17,26 +17,28 @@
* under the License.
*/
module org.apache.causeway.viewer.restfulobjects.viewer {
- exports org.apache.causeway.viewer.restfulobjects.viewer.jaxrsapp;
- exports org.apache.causeway.viewer.restfulobjects.viewer.webmodule;
- exports org.apache.causeway.viewer.restfulobjects.viewer.context;
+
exports org.apache.causeway.viewer.restfulobjects.viewer;
- exports org.apache.causeway.viewer.restfulobjects.viewer.webmodule.auth;
+ exports org.apache.causeway.viewer.restfulobjects.viewer.context;
+ exports org.apache.causeway.viewer.restfulobjects.viewer.exhandling;
+ exports org.apache.causeway.viewer.restfulobjects.viewer.exhandling.entity;
+ exports org.apache.causeway.viewer.restfulobjects.viewer.jaxrsapp;
exports org.apache.causeway.viewer.restfulobjects.viewer.resources;
- exports org.apache.causeway.viewer.restfulobjects.viewer.util;
- exports org.apache.causeway.viewer.restfulobjects.viewer.mappers.entity;
- exports org.apache.causeway.viewer.restfulobjects.viewer.mappers;
exports org.apache.causeway.viewer.restfulobjects.viewer.resources.serialization;
+ exports org.apache.causeway.viewer.restfulobjects.viewer.util;
+ exports org.apache.causeway.viewer.restfulobjects.viewer.webmodule;
+ exports org.apache.causeway.viewer.restfulobjects.viewer.webmodule.auth;
+
+ requires static lombok;
requires com.fasterxml.jackson.core;
requires com.fasterxml.jackson.databind;
requires jakarta.annotation;
requires jakarta.inject;
requires jakarta.transaction;
- requires jakarta.ws.rs;
+ requires jakarta.ws.rs; //FIXME remove
requires jakarta.xml.bind;
requires jakarta.servlet;
- requires static lombok;
requires org.apache.causeway.applib;
requires org.apache.causeway.commons;
requires org.apache.causeway.core.config;
diff --git a/viewers/restfulobjects/viewer/src/main/java/org/apache/causeway/viewer/restfulobjects/viewer/CausewayModuleViewerRestfulObjectsViewer.java b/viewers/restfulobjects/viewer/src/main/java/org/apache/causeway/viewer/restfulobjects/viewer/CausewayModuleViewerRestfulObjectsViewer.java
index cec4ac8c0ea..f2d0fbe95ef 100644
--- a/viewers/restfulobjects/viewer/src/main/java/org/apache/causeway/viewer/restfulobjects/viewer/CausewayModuleViewerRestfulObjectsViewer.java
+++ b/viewers/restfulobjects/viewer/src/main/java/org/apache/causeway/viewer/restfulobjects/viewer/CausewayModuleViewerRestfulObjectsViewer.java
@@ -18,30 +18,34 @@
*/
package org.apache.causeway.viewer.restfulobjects.viewer;
+import java.util.List;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
+import org.apache.causeway.applib.services.exceprecog.RootCauseFinder;
import org.apache.causeway.core.webapp.CausewayModuleCoreWebapp;
import org.apache.causeway.viewer.commons.services.CausewayModuleViewerCommonsServices;
import org.apache.causeway.viewer.restfulobjects.rendering.CausewayModuleRestfulObjectsRendering;
import org.apache.causeway.viewer.restfulobjects.rendering.service.acceptheader.AcceptHeaderServiceForRest;
-import org.apache.causeway.viewer.restfulobjects.viewer.mappers.ExceptionMapperForObjectNotFound;
-import org.apache.causeway.viewer.restfulobjects.viewer.mappers.ExceptionMapperForRestfulObjectsApplication;
-import org.apache.causeway.viewer.restfulobjects.viewer.mappers.ExceptionMapperForRuntimeException;
+import org.apache.causeway.viewer.restfulobjects.viewer.exhandling.ExceptionMapperForRestfulObjects;
+import org.apache.causeway.viewer.restfulobjects.viewer.exhandling.ExceptionResponseFactory;
import org.apache.causeway.viewer.restfulobjects.viewer.resources.DomainObjectResourceServerside;
import org.apache.causeway.viewer.restfulobjects.viewer.resources.DomainServiceResourceServerside;
import org.apache.causeway.viewer.restfulobjects.viewer.resources.DomainTypeResourceServerside;
import org.apache.causeway.viewer.restfulobjects.viewer.resources.HomePageResourceServerside;
-import org.apache.causeway.viewer.restfulobjects.viewer.resources.ImageResourceServerside;
import org.apache.causeway.viewer.restfulobjects.viewer.resources.MenuBarsResourceServerside;
import org.apache.causeway.viewer.restfulobjects.viewer.resources.SwaggerSpecResource;
import org.apache.causeway.viewer.restfulobjects.viewer.resources.UserResourceServerside;
import org.apache.causeway.viewer.restfulobjects.viewer.resources.VersionResourceServerside;
+import org.apache.causeway.viewer.restfulobjects.viewer.webmodule.WebModuleRestfulObjects;
/**
* @since 1.x {@index}
*/
-@Configuration
+@Configuration(proxyBeanMethods = false)
@Import({
// Modules
CausewayModuleCoreWebapp.class,
@@ -53,19 +57,24 @@
DomainTypeResourceServerside.class,
UserResourceServerside.class,
MenuBarsResourceServerside.class,
- ImageResourceServerside.class,
DomainObjectResourceServerside.class,
DomainServiceResourceServerside.class,
VersionResourceServerside.class,
SwaggerSpecResource.class,
- ExceptionMapperForRestfulObjectsApplication.class,
- ExceptionMapperForRuntimeException.class,
- ExceptionMapperForObjectNotFound.class,
+ ExceptionMapperForRestfulObjects.class,
AcceptHeaderServiceForRest.RequestFilter.class,
AcceptHeaderServiceForRest.ResponseFilter.class,
+ //CausewayRestfulObjectsInteractionFilter2.class
+ WebModuleRestfulObjects.class
+
})
public class CausewayModuleViewerRestfulObjectsViewer {
+ @Bean
+ ExceptionResponseFactory exceptionResponseFactory(@Autowired(required = false) List<RootCauseFinder> rootCauseFinders) {
+ return new ExceptionResponseFactory(rootCauseFinders!=null ? rootCauseFinders : List.of());
+ }
+
}
diff --git a/viewers/restfulobjects/viewer/src/main/java/org/apache/causeway/viewer/restfulobjects/viewer/context/ResourceContext.java b/viewers/restfulobjects/viewer/src/main/java/org/apache/causeway/viewer/restfulobjects/viewer/context/ResourceContext.java
index f870617f20c..678a8f896c3 100644
--- a/viewers/restfulobjects/viewer/src/main/java/org/apache/causeway/viewer/restfulobjects/viewer/context/ResourceContext.java
+++ b/viewers/restfulobjects/viewer/src/main/java/org/apache/causeway/viewer/restfulobjects/viewer/context/ResourceContext.java
@@ -19,7 +19,6 @@
package org.apache.causeway.viewer.restfulobjects.viewer.context;
import java.util.Collections;
-import java.util.Enumeration;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
@@ -33,6 +32,7 @@
import org.jspecify.annotations.Nullable;
import org.springframework.http.HttpHeaders;
+import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.apache.causeway.applib.annotation.Where;
@@ -49,7 +49,6 @@
import org.apache.causeway.viewer.restfulobjects.applib.JsonRepresentation;
import org.apache.causeway.viewer.restfulobjects.applib.RestfulRequest.DomainModel;
import org.apache.causeway.viewer.restfulobjects.applib.RestfulRequest.RequestParameter;
-import org.apache.causeway.viewer.restfulobjects.applib.RestfulResponse.HttpStatusCode;
import org.apache.causeway.viewer.restfulobjects.rendering.IResourceContext;
import org.apache.causeway.viewer.restfulobjects.rendering.RestfulObjectsApplicationException;
import org.apache.causeway.viewer.restfulobjects.rendering.domainobjects.DomainObjectLinkTo;
@@ -59,6 +58,7 @@
import org.apache.causeway.viewer.restfulobjects.rendering.util.RequestParams;
import org.apache.causeway.viewer.restfulobjects.viewer.resources.ResourceDescriptor;
import org.apache.causeway.viewer.restfulobjects.viewer.resources.serialization.SerializationStrategy;
+import org.apache.causeway.viewer.restfulobjects.viewer.util.RequestHeaderUtil;
public record ResourceContext(
MetaModelContext metaModelContext,
@@ -112,7 +112,7 @@ private ResourceContext(
final JsonRepresentation requestArgsAsMap) {
this(metaModelContext, resourceDescriptor,
- httpHeadersFromServletRequest(httpServletRequest),
+ RequestHeaderUtil.httpHeadersFromServletRequest(httpServletRequest),
httpServletRequest, httpServletResponse,
_Strings.suffix(applicationAbsoluteBase, "/"),
_Strings.suffix(restfulAbsoluteBase, "/"),
@@ -144,8 +144,8 @@ private ResourceContext(
private void ensureDomainModelQueryParamSupported() {
final DomainModel domainModel = arg(queryStringAsJsonRepr(), RequestParameter.DOMAIN_MODEL);
if(domainModel != DomainModel.FORMAL) {
- throw RestfulObjectsApplicationException.createWithMessage(HttpStatusCode.BAD_REQUEST,
- "x-ro-domain-model of '%s' is not supported", domainModel);
+ throw RestfulObjectsApplicationException.createWithMessage(HttpStatus.BAD_REQUEST,
+ "x-ro-domain-model of '%s' is not supported".formatted(domainModel));
}
}
@@ -241,8 +241,8 @@ public ManagedObject lookupServiceAdapterElseFail(
.orElse(null);
if(serviceAdapter==null) {
- throw RestfulObjectsApplicationException.createWithMessage(HttpStatusCode.NOT_FOUND,
- "Could not locate service '%s'", serviceIdOrAlias);
+ throw RestfulObjectsApplicationException.createWithMessage(HttpStatus.NOT_FOUND,
+ "Could not locate service '%s'".formatted(serviceIdOrAlias));
}
return serviceAdapter;
}
@@ -264,21 +264,4 @@ public static ResourceContext forTesting(
throw _Exceptions.notImplemented();
}
- // -- HELPER
-
- static HttpHeaders httpHeadersFromServletRequest(HttpServletRequest request) {
- var headers = new HttpHeaders();
- Enumeration<String> headerNames = request.getHeaderNames();
- while (headerNames.hasMoreElements()) {
- String name = headerNames.nextElement();
- Enumeration<String> values = request.getHeaders(name);
- while (values.hasMoreElements()) {
- headers.add(name, values.nextElement());
- }
- }
- return headers;
- }
-
-
-
}
diff --git a/viewers/restfulobjects/viewer/src/main/java/org/apache/causeway/viewer/restfulobjects/viewer/mappers/ExceptionMapperForObjectNotFound.java b/viewers/restfulobjects/viewer/src/main/java/org/apache/causeway/viewer/restfulobjects/viewer/exhandling/ExceptionMapperForRestfulObjects.java
similarity index 53%
rename from viewers/restfulobjects/viewer/src/main/java/org/apache/causeway/viewer/restfulobjects/viewer/mappers/ExceptionMapperForObjectNotFound.java
rename to viewers/restfulobjects/viewer/src/main/java/org/apache/causeway/viewer/restfulobjects/viewer/exhandling/ExceptionMapperForRestfulObjects.java
index 5a37750b5b2..ca4cd4b6c0d 100644
--- a/viewers/restfulobjects/viewer/src/main/java/org/apache/causeway/viewer/restfulobjects/viewer/mappers/ExceptionMapperForObjectNotFound.java
+++ b/viewers/restfulobjects/viewer/src/main/java/org/apache/causeway/viewer/restfulobjects/viewer/exhandling/ExceptionMapperForRestfulObjects.java
@@ -16,13 +16,13 @@
* specific language governing permissions and limitations
* under the License.
*/
-package org.apache.causeway.viewer.restfulobjects.viewer.mappers;
+package org.apache.causeway.viewer.restfulobjects.viewer.exhandling;
-//import jakarta.inject.Singleton;
-//import jakarta.ws.rs.core.Response;
-//import jakarta.ws.rs.ext.Provider;
+import jakarta.servlet.http.HttpServletRequest;
+import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
+import org.springframework.http.ResponseEntity;
//import org.springframework.stereotype.Component;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseStatus;
@@ -30,37 +30,33 @@
//import org.apache.causeway.applib.annotation.PriorityPrecedence;
import org.apache.causeway.applib.exceptions.unrecoverable.ObjectNotFoundException;
+import org.apache.causeway.viewer.restfulobjects.rendering.RestfulObjectsApplicationException;
+import org.apache.causeway.viewer.restfulobjects.viewer.util.RequestHeaderUtil;
import lombok.extern.slf4j.Slf4j;
-//import org.apache.causeway.viewer.restfulobjects.applib.RestfulResponse;
-//@Component
-//@Provider
-//@Singleton
-//@jakarta.annotation.Priority(PriorityPrecedence.MIDPOINT)
@RestControllerAdvice
@Slf4j
-public class ExceptionMapperForObjectNotFound
-//extends ExceptionMapperAbstract<ObjectNotFoundException>
-{
+public class ExceptionMapperForRestfulObjects {
- //TODO[causeway-viewer-restfulobjects-viewer-CAUSEWAY-3892] convert
-// @Override
-// public Response toResponse(final ObjectNotFoundException ex) {
-// return buildResponse(ex, RestfulResponse.HttpStatusCode.NOT_FOUND);
-// }
+ @Autowired protected ExceptionResponseFactory exceptionResponseFactory;
+ //@Autowired protected HttpServletRequest httpServletRequest;
@ExceptionHandler(ObjectNotFoundException.class)
@ResponseStatus(HttpStatus.NOT_FOUND)
- String objectNotFoundHandler(ObjectNotFoundException ex) {
- return ex.getMessage();
+ ResponseEntity<Object> objectNotFound(ObjectNotFoundException ex, HttpServletRequest httpServletRequest) {
+ return exceptionResponseFactory.buildResponse(ex, RequestHeaderUtil.httpHeadersFromServletRequest(httpServletRequest));
+ }
+
+ @ExceptionHandler(RestfulObjectsApplicationException.class)
+ ResponseEntity<Object> roException(RestfulObjectsApplicationException ex, HttpServletRequest httpServletRequest) {
+ return exceptionResponseFactory.buildResponse(ex, RequestHeaderUtil.httpHeadersFromServletRequest(httpServletRequest));
}
@ExceptionHandler(Exception.class)
- @ResponseStatus(HttpStatus.NOT_FOUND)
- String fallback(Exception ex) {
+ ResponseEntity<Object> fallback(Exception ex, HttpServletRequest httpServletRequest) {
log.error("not covered by any @ExceptionHandler", ex);
- return "[fallback] " + ex.getMessage();
+ return exceptionResponseFactory.buildResponse(ex, RequestHeaderUtil.httpHeadersFromServletRequest(httpServletRequest));
}
}
diff --git a/viewers/restfulobjects/viewer/src/main/java/org/apache/causeway/viewer/restfulobjects/viewer/exhandling/ExceptionResponseFactory.java b/viewers/restfulobjects/viewer/src/main/java/org/apache/causeway/viewer/restfulobjects/viewer/exhandling/ExceptionResponseFactory.java
new file mode 100644
index 00000000000..ade5b61187c
--- /dev/null
+++ b/viewers/restfulobjects/viewer/src/main/java/org/apache/causeway/viewer/restfulobjects/viewer/exhandling/ExceptionResponseFactory.java
@@ -0,0 +1,147 @@
+/*
+ * 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.causeway.viewer.restfulobjects.viewer.exhandling;
+
+import java.util.List;
+import java.util.Optional;
+
+import org.springframework.http.HttpHeaders;
+import org.springframework.http.HttpStatus;
+import org.springframework.http.MediaType;
+import org.springframework.http.ResponseEntity;
+
+import org.apache.causeway.applib.exceptions.RecoverableException;
+import org.apache.causeway.applib.services.exceprecog.RootCauseFinder;
+import org.apache.causeway.commons.internal.exceptions._Exceptions;
+import org.apache.causeway.viewer.restfulobjects.applib.JsonRepresentation;
+import org.apache.causeway.viewer.restfulobjects.applib.RepresentationType;
+import org.apache.causeway.viewer.restfulobjects.applib.RestfulResponse;
+import org.apache.causeway.viewer.restfulobjects.rendering.ExceptionWithBody;
+import org.apache.causeway.viewer.restfulobjects.rendering.ExceptionWithHttpStatusCode;
+import org.apache.causeway.viewer.restfulobjects.viewer.exhandling.entity.ExceptionDetail;
+import org.apache.causeway.viewer.restfulobjects.viewer.exhandling.entity.ExceptionPojo;
+import org.apache.causeway.viewer.restfulobjects.viewer.resources.serialization.SerializationStrategy;
+
+import static org.apache.causeway.commons.internal.base._NullSafe.stream;
+
+public record ExceptionResponseFactory(
+ List<RootCauseFinder> rootCauseFinders) {
+
+ public ResponseEntity<Object> buildResponse(final Exception ex, final HttpHeaders httpHeaders) {
+ return buildResponse(ex, determineStatusCode(ex), httpHeaders);
+ }
+
+ ResponseEntity<Object> buildResponse(final Exception ex, final HttpStatus httpStatus, final HttpHeaders httpHeaders) {
+ final String message = messageFor(ex);
+
+ if(ex instanceof ExceptionWithBody exceptionWithBody
+ && exceptionWithBody.body()!=null) {
+ return buildResponse(httpStatus, message, exceptionWithBody.body());
+ }
+
+ var exceptionPojo = new ExceptionPojo(
+ httpStatus.value(),
+ message,
+ detailIfRequired(httpStatus, ex));
+
+ return buildResponse(httpStatus, exceptionPojo, httpHeaders);
+ }
+
+ // -- HELPER
+
+ private ResponseEntity<Object> buildResponse(
+ final HttpStatus httpStatus,
+ final String message,
+ final JsonRepresentation body) {
+
+ var builder = ResponseEntity.status(httpStatus);
+
+ if (message != null) {
+ builder = builder.header(RestfulResponse.Header.WARNING.getName(), RestfulResponse.Header.WARNING.render(message));
+ }
+
+ // hmm; the mediaType doesn't seem to be specified in the RO spec
+ builder.contentType(SerializationStrategy.JSON.type(RepresentationType.GENERIC));
+ return builder.body((Object)body.toString());
+ }
+
+ private HttpStatus determineStatusCode(final Exception ex) {
+ var statusCode = FailureUtil.getFailureStatusCodeIfAny(ex);
+ if(statusCode!=null) return statusCode;
+
+ if(recoverableFor(ex).isPresent()) {
+ return HttpStatus.OK;
+ } else if(ex instanceof ExceptionWithHttpStatusCode exceptionWithHttpStatusCode) {
+ return exceptionWithHttpStatusCode.httpStatus();
+ }
+ return HttpStatus.INTERNAL_SERVER_ERROR;
+ }
+
+ private static String messageFor(final Throwable ex) {
+
+ final Optional<RecoverableException> recoverableIfAny = recoverableFor(ex);
+
+ return (recoverableIfAny.isPresent() ? recoverableIfAny.get() : ex).getMessage();
+ }
+
+ private static Optional<RecoverableException> recoverableFor(final Throwable ex) {
+ final List<Throwable> chain = _Exceptions.getCausalChain(ex);
+
+ final Optional<RecoverableException> recoverableIfAny = stream(chain)
+ .filter(t->t instanceof RecoverableException)
+ .map(t->(RecoverableException)t)
+ .findFirst();
+
+ return recoverableIfAny;
+ }
+
+ private ExceptionDetail detailIfRequired(
+ final HttpStatus httpStatus,
+ final Throwable ex) {
+
+ return httpStatus == HttpStatus.NOT_FOUND
+ || httpStatus == HttpStatus.OK
+ ? null
+ : new ExceptionDetail(ex, rootCauseFinders);
+ }
+
+ private ResponseEntity<Object> buildResponse(
+ final HttpStatus httpStatus,
+ final ExceptionPojo exceptionPojo,
+ final HttpHeaders httpHeaders) {
+
+ var builder = ResponseEntity.status(httpStatus);
+
+ var acceptableMediaTypes = httpHeaders.getAccept();
+ var serializationStrategy = acceptableMediaTypes.contains(MediaType.APPLICATION_XML)
+ || acceptableMediaTypes.contains(RepresentationType.OBJECT_LAYOUT.getXmlMediaType())
+ ? SerializationStrategy.XML
+ : SerializationStrategy.JSON;
+
+ final String message = exceptionPojo.getMessage();
+ if (message != null) {
+ builder = builder.header(RestfulResponse.Header.WARNING.getName(), RestfulResponse.Header.WARNING.render(message));
+ }
+
+ return builder
+ .contentType(serializationStrategy.type(RepresentationType.ERROR))
+ .body(serializationStrategy.entity(exceptionPojo));
+ }
+
+}
diff --git a/viewers/restfulobjects/viewer/src/main/java/org/apache/causeway/viewer/restfulobjects/viewer/mappers/FailureUtil.java b/viewers/restfulobjects/viewer/src/main/java/org/apache/causeway/viewer/restfulobjects/viewer/exhandling/FailureUtil.java
similarity index 82%
rename from viewers/restfulobjects/viewer/src/main/java/org/apache/causeway/viewer/restfulobjects/viewer/mappers/FailureUtil.java
rename to viewers/restfulobjects/viewer/src/main/java/org/apache/causeway/viewer/restfulobjects/viewer/exhandling/FailureUtil.java
index bf9cffe900d..78fee7c8924 100644
--- a/viewers/restfulobjects/viewer/src/main/java/org/apache/causeway/viewer/restfulobjects/viewer/mappers/FailureUtil.java
+++ b/viewers/restfulobjects/viewer/src/main/java/org/apache/causeway/viewer/restfulobjects/viewer/exhandling/FailureUtil.java
@@ -16,23 +16,23 @@
* specific language governing permissions and limitations
* under the License.
*/
-package org.apache.causeway.viewer.restfulobjects.viewer.mappers;
+package org.apache.causeway.viewer.restfulobjects.viewer.exhandling;
import java.util.Optional;
+import org.springframework.http.HttpStatus;
+
import org.apache.causeway.commons.collections.Can;
import org.apache.causeway.commons.functional.Try;
import org.apache.causeway.commons.internal.reflection._Reflect;
import org.apache.causeway.core.metamodel.methods.MethodFinder;
-import org.apache.causeway.viewer.restfulobjects.applib.RestfulResponse;
-import org.apache.causeway.viewer.restfulobjects.applib.RestfulResponse.HttpStatusCode;
import lombok.experimental.UtilityClass;
@UtilityClass
final class FailureUtil {
- public static HttpStatusCode getFailureStatusCodeIfAny(final Throwable ex) {
+ public static HttpStatus getFailureStatusCodeIfAny(final Throwable ex) {
return MethodFinder
.publicOnly(ex.getClass(), Can.ofSingleton("getErrorCode"))
@@ -44,7 +44,7 @@ public static HttpStatusCode getFailureStatusCodeIfAny(final Throwable ex) {
.map(Optional::stream)
.filter(Integer.class::isInstance)
.map(Integer.class::cast)
- .map(RestfulResponse.HttpStatusCode::statusFor)
+ .map(HttpStatus::valueOf)
.orElse(null);
}
diff --git a/viewers/restfulobjects/viewer/src/main/java/org/apache/causeway/viewer/restfulobjects/viewer/mappers/entity/ExceptionDetail.java b/viewers/restfulobjects/viewer/src/main/java/org/apache/causeway/viewer/restfulobjects/viewer/exhandling/entity/ExceptionDetail.java
similarity index 97%
rename from viewers/restfulobjects/viewer/src/main/java/org/apache/causeway/viewer/restfulobjects/viewer/mappers/entity/ExceptionDetail.java
rename to viewers/restfulobjects/viewer/src/main/java/org/apache/causeway/viewer/restfulobjects/viewer/exhandling/entity/ExceptionDetail.java
index e8e0200af03..4736f596719 100644
--- a/viewers/restfulobjects/viewer/src/main/java/org/apache/causeway/viewer/restfulobjects/viewer/mappers/entity/ExceptionDetail.java
+++ b/viewers/restfulobjects/viewer/src/main/java/org/apache/causeway/viewer/restfulobjects/viewer/exhandling/entity/ExceptionDetail.java
@@ -16,7 +16,7 @@
* specific language governing permissions and limitations
* under the License.
*/
-package org.apache.causeway.viewer.restfulobjects.viewer.mappers.entity;
+package org.apache.causeway.viewer.restfulobjects.viewer.exhandling.entity;
import java.util.List;
import java.util.stream.Stream;
diff --git a/viewers/restfulobjects/viewer/src/main/java/org/apache/causeway/viewer/restfulobjects/viewer/mappers/entity/ExceptionPojo.java b/viewers/restfulobjects/viewer/src/main/java/org/apache/causeway/viewer/restfulobjects/viewer/exhandling/entity/ExceptionPojo.java
similarity index 95%
rename from viewers/restfulobjects/viewer/src/main/java/org/apache/causeway/viewer/restfulobjects/viewer/mappers/entity/ExceptionPojo.java
rename to viewers/restfulobjects/viewer/src/main/java/org/apache/causeway/viewer/restfulobjects/viewer/exhandling/entity/ExceptionPojo.java
index ce8d0cf3261..56d996148fc 100644
--- a/viewers/restfulobjects/viewer/src/main/java/org/apache/causeway/viewer/restfulobjects/viewer/mappers/entity/ExceptionPojo.java
+++ b/viewers/restfulobjects/viewer/src/main/java/org/apache/causeway/viewer/restfulobjects/viewer/exhandling/entity/ExceptionPojo.java
@@ -16,7 +16,7 @@
* specific language governing permissions and limitations
* under the License.
*/
-package org.apache.causeway.viewer.restfulobjects.viewer.mappers.entity;
+package org.apache.causeway.viewer.restfulobjects.viewer.exhandling.entity;
import jakarta.xml.bind.annotation.XmlAccessType;
import jakarta.xml.bind.annotation.XmlAccessorType;
diff --git a/viewers/restfulobjects/viewer/src/main/java/org/apache/causeway/viewer/restfulobjects/viewer/mappers/ExceptionMapperAbstract.java b/viewers/restfulobjects/viewer/src/main/java/org/apache/causeway/viewer/restfulobjects/viewer/mappers/ExceptionMapperAbstract.java
deleted file mode 100644
index 927d6ed6bed..00000000000
--- a/viewers/restfulobjects/viewer/src/main/java/org/apache/causeway/viewer/restfulobjects/viewer/mappers/ExceptionMapperAbstract.java
+++ /dev/null
@@ -1,170 +0,0 @@
-/*
- * 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.causeway.viewer.restfulobjects.viewer.mappers;
-
-import java.util.List;
-import java.util.Optional;
-
-import jakarta.ws.rs.core.Context;
-import jakarta.ws.rs.core.HttpHeaders;
-import org.springframework.http.MediaType;
-import jakarta.ws.rs.core.Response;
-import jakarta.ws.rs.core.Response.ResponseBuilder;
-import jakarta.ws.rs.ext.ExceptionMapper;
-
-import org.springframework.beans.factory.annotation.Autowired;
-
-import org.apache.causeway.applib.exceptions.RecoverableException;
-import org.apache.causeway.applib.services.exceprecog.RootCauseFinder;
-import org.apache.causeway.commons.internal.exceptions._Exceptions;
-import org.apache.causeway.viewer.restfulobjects.applib.JsonRepresentation;
-import org.apache.causeway.viewer.restfulobjects.applib.RepresentationType;
-import org.apache.causeway.viewer.restfulobjects.applib.RestfulResponse;
-import org.apache.causeway.viewer.restfulobjects.applib.util.MediaTypes;
-import org.apache.causeway.viewer.restfulobjects.rendering.ExceptionWithBody;
-import org.apache.causeway.viewer.restfulobjects.rendering.ExceptionWithHttpStatusCode;
-import org.apache.causeway.viewer.restfulobjects.viewer.mappers.entity.ExceptionDetail;
-import org.apache.causeway.viewer.restfulobjects.viewer.mappers.entity.ExceptionPojo;
-import org.apache.causeway.viewer.restfulobjects.viewer.resources.serialization.SerializationStrategy;
-
-import static org.apache.causeway.commons.internal.base._NullSafe.stream;
-
-public abstract class ExceptionMapperAbstract<T extends Throwable> implements ExceptionMapper<T> {
-
- @Context protected HttpHeaders httpHeaders;
- @Autowired(required = false) protected List<RootCauseFinder> rootCauseFinders;
-
- Response buildResponse(final T ex) {
- return buildResponse(ex, determineStatusCode(ex));
- }
-
- Response buildResponse(final T ex, final RestfulResponse.HttpStatusCode httpStatusCode) {
- 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,
- detailIfRequired(httpStatusCode, 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(MediaTypes.toJakarta(serializationStrategy.type(RepresentationType.GENERIC)));
- builder.entity(body.toString());
-
- return builder.build();
- }
-
- private RestfulResponse.HttpStatusCode determineStatusCode(final T ex) {
-
- RestfulResponse.HttpStatusCode statusCode;
-
- statusCode = FailureUtil.getFailureStatusCodeIfAny(ex);
- if(statusCode!=null) {
- return statusCode;
- }
-
- final Optional<RecoverableException> recoverableIfAny = recoverableFor(ex);
-
- if(recoverableIfAny.isPresent()) {
- statusCode = RestfulResponse.HttpStatusCode.OK;
- } else if(ex instanceof ExceptionWithHttpStatusCode) {
- ExceptionWithHttpStatusCode exceptionWithHttpStatusCode = (ExceptionWithHttpStatusCode) ex;
- statusCode = exceptionWithHttpStatusCode.getHttpStatusCode();
- } else {
- statusCode = RestfulResponse.HttpStatusCode.INTERNAL_SERVER_ERROR;
- }
- return statusCode;
- }
-
- private static String messageFor(final Throwable ex) {
-
- final Optional<RecoverableException> recoverableIfAny = recoverableFor(ex);
-
- return (recoverableIfAny.isPresent() ? recoverableIfAny.get() : ex).getMessage();
- }
-
- private static Optional<RecoverableException> recoverableFor(final Throwable ex) {
- final List<Throwable> chain = _Exceptions.getCausalChain(ex);
-
- final Optional<RecoverableException> recoverableIfAny = stream(chain)
- .filter(t->t instanceof RecoverableException)
- .map(t->(RecoverableException)t)
- .findFirst();
-
- return recoverableIfAny;
- }
-
- private ExceptionDetail detailIfRequired(
- final RestfulResponse.HttpStatusCode httpStatusCode,
- final Throwable ex) {
-
- return httpStatusCode == RestfulResponse.HttpStatusCode.NOT_FOUND ||
- httpStatusCode == RestfulResponse.HttpStatusCode.OK
- ? null
- : new ExceptionDetail(ex, rootCauseFinders);
- }
-
- private Response buildResponse(
- final RestfulResponse.HttpStatusCode httpStatusCode,
- final ExceptionPojo exceptionPojo) {
- final ResponseBuilder builder = Response.status(httpStatusCode.getJaxrsStatusType());
-
- var acceptableMediaTypes = httpHeaders.getAcceptableMediaTypes()
- .stream()
- .map(MediaTypes::fromJakarta)
- .toList();
- var serializationStrategy = acceptableMediaTypes.contains(MediaType.APPLICATION_XML)
- || acceptableMediaTypes.contains(RepresentationType.OBJECT_LAYOUT.getXmlMediaType())
- ? SerializationStrategy.XML
- : SerializationStrategy.JSON;
-
- final String message = exceptionPojo.getMessage();
- if (message != null) {
- builder.header(RestfulResponse.Header.WARNING.getName(), RestfulResponse.Header.WARNING.render(message));
- }
-
- builder.type(MediaTypes.toJakarta(serializationStrategy.type(RepresentationType.ERROR)));
- builder.entity(serializationStrategy.entity(exceptionPojo));
-
- return builder.build();
- }
-
-}
diff --git a/viewers/restfulobjects/viewer/src/main/java/org/apache/causeway/viewer/restfulobjects/viewer/mappers/ExceptionMapperForRestfulObjectsApplication.java b/viewers/restfulobjects/viewer/src/main/java/org/apache/causeway/viewer/restfulobjects/viewer/mappers/ExceptionMapperForRestfulObjectsApplication.java
deleted file mode 100644
index d6f86c37997..00000000000
--- a/viewers/restfulobjects/viewer/src/main/java/org/apache/causeway/viewer/restfulobjects/viewer/mappers/ExceptionMapperForRestfulObjectsApplication.java
+++ /dev/null
@@ -1,42 +0,0 @@
-/*
- * 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.causeway.viewer.restfulobjects.viewer.mappers;
-
-import jakarta.inject.Singleton;
-import jakarta.ws.rs.core.Response;
-import jakarta.ws.rs.ext.Provider;
-
-import org.springframework.stereotype.Component;
-
-import org.apache.causeway.applib.annotation.PriorityPrecedence;
-import org.apache.causeway.viewer.restfulobjects.rendering.RestfulObjectsApplicationException;
-
-@Component
-@Provider
-@Singleton
-@jakarta.annotation.Priority(PriorityPrecedence.MIDPOINT)
-public class ExceptionMapperForRestfulObjectsApplication
-extends ExceptionMapperAbstract<RestfulObjectsApplicationException> {
-
- @Override
- public Response toResponse(final RestfulObjectsApplicationException ex) {
- return buildResponse(ex);
- }
-
-}
diff --git a/viewers/restfulobjects/viewer/src/main/java/org/apache/causeway/viewer/restfulobjects/viewer/resources/DomainObjectResourceServerside.java b/viewers/restfulobjects/viewer/src/main/java/org/apache/causeway/viewer/restfulobjects/viewer/resources/DomainObjectResourceServerside.java
index 158abd111f3..970d1d10e9e 100644
--- a/viewers/restfulobjects/viewer/src/main/java/org/apache/causeway/viewer/restfulobjects/viewer/resources/DomainObjectResourceServerside.java
+++ b/viewers/restfulobjects/viewer/src/main/java/org/apache/causeway/viewer/restfulobjects/viewer/resources/DomainObjectResourceServerside.java
@@ -22,14 +22,11 @@
import java.util.Optional;
import jakarta.ws.rs.HttpMethod;
-import jakarta.ws.rs.Path;
-import jakarta.ws.rs.PathParam;
-import jakarta.ws.rs.QueryParam;
-import jakarta.ws.rs.core.Response;
-import org.jspecify.annotations.NonNull;
-
-import org.springframework.stereotype.Component;
+import org.springframework.http.HttpStatus;
+import org.springframework.http.MediaType;
+import org.springframework.http.ResponseEntity;
+import org.springframework.web.bind.annotation.RestController;
import org.apache.causeway.applib.annotation.Where;
import org.apache.causeway.applib.layout.component.ActionLayoutData;
@@ -41,7 +38,6 @@
import org.apache.causeway.commons.io.UrlUtils;
import org.apache.causeway.core.metamodel.consent.Consent;
import org.apache.causeway.core.metamodel.consent.InteractionInitiatedBy;
-import org.apache.causeway.core.metamodel.facets.object.icon.ObjectIcon;
import org.apache.causeway.core.metamodel.interactions.managed.ManagedMember;
import org.apache.causeway.core.metamodel.interactions.managed.MemberInteraction.AccessIntent;
import org.apache.causeway.core.metamodel.interactions.managed.PropertyInteraction;
@@ -51,11 +47,8 @@
import org.apache.causeway.viewer.restfulobjects.applib.JsonRepresentation;
import org.apache.causeway.viewer.restfulobjects.applib.Rel;
import org.apache.causeway.viewer.restfulobjects.applib.RepresentationType;
-import org.apache.causeway.viewer.restfulobjects.applib.RestfulResponse;
-import org.apache.causeway.viewer.restfulobjects.applib.RestfulResponse.HttpStatusCode;
import org.apache.causeway.viewer.restfulobjects.applib.domainobjects.DomainObjectResource;
-import org.apache.causeway.viewer.restfulobjects.applib.util.MediaTypes;
-import org.apache.causeway.viewer.restfulobjects.rendering.Responses;
+import org.apache.causeway.viewer.restfulobjects.rendering.ResponseFactory;
import org.apache.causeway.viewer.restfulobjects.rendering.RestfulObjectsApplicationException;
import org.apache.causeway.viewer.restfulobjects.rendering.service.RepresentationService;
import org.apache.causeway.viewer.restfulobjects.rendering.util.RequestParams;
@@ -64,8 +57,7 @@
import lombok.extern.slf4j.Slf4j;
-@Component
-@Path("/objects")
+@RestController
@Slf4j
public class DomainObjectResourceServerside
extends ResourceAbstract
@@ -79,15 +71,8 @@ public DomainObjectResourceServerside() {
// PERSIST
@Override
-// @POST
-// @Path("/{domainType}")
-// @Consumes({ MediaType.WILDCARD })
-// @Produces({
-// MediaType.APPLICATION_JSON, RestfulMediaType.APPLICATION_JSON_OBJECT, RestfulMediaType.APPLICATION_JSON_ERROR,
-// MediaType.APPLICATION_XML, RestfulMediaType.APPLICATION_XML_OBJECT, RestfulMediaType.APPLICATION_XML_ERROR
-// })
- public Response persist(
- @PathParam("domainType") final String domainType,
+ public ResponseEntity<Object> persist(
+ final String domainType,
final InputStream object) {
var resourceContext = createResourceContext(new ResourceDescriptor(
@@ -98,7 +83,7 @@ public Response persist(
if (!objectRepr.isMap()) {
throw _EndpointLogging.error(log, "POST /objects/{}", domainType,
RestfulObjectsApplicationException
- .createWithMessage(HttpStatusCode.BAD_REQUEST, "Body is not a map; got %s", objectRepr));
+ .createWithMessage(HttpStatus.BAD_REQUEST, "Body is not a map; got %s".formatted(objectRepr)));
}
var domainTypeSpec = getSpecificationLoader().specForLogicalTypeName(domainType)
@@ -107,7 +92,8 @@ public Response persist(
if (domainTypeSpec == null) {
throw _EndpointLogging.error(log, "POST /objects/{}", domainType,
RestfulObjectsApplicationException
- .createWithMessage(HttpStatusCode.BAD_REQUEST, "Could not determine type of domain object to persist (no class with domainType Id of '%s')", domainType));
+ .createWithMessage(HttpStatus.BAD_REQUEST,
+ "Could not determine type of domain object to persist (no class with domainType Id of '%s')".formatted(domainType)));
}
final ManagedObject adapter = domainTypeSpec.createObject();
@@ -118,20 +104,20 @@ public Response persist(
if (membersMap == null) {
throw _EndpointLogging.error(log, "POST /objects/{}", domainType,
RestfulObjectsApplicationException
- .createWithMessage(HttpStatusCode.BAD_REQUEST, "Could not find members map; got %s", objectRepr));
+ .createWithMessage(HttpStatus.BAD_REQUEST, "Could not find members map; got %s".formatted(objectRepr)));
}
if (!updateHelper.copyOverProperties(membersMap, ObjectAdapterUpdateHelper.Intent.PERSISTING_NEW)) {
throw _EndpointLogging.error(log, "POST /objects/{}", domainType,
RestfulObjectsApplicationException
- .createWithBody(HttpStatusCode.BAD_REQUEST, objectRepr, "Illegal property value"));
+ .createWithBody(HttpStatus.BAD_REQUEST, objectRepr, "Illegal property value"));
}
final Consent validity = adapter.objSpec().isValid(adapter, InteractionInitiatedBy.USER);
if (validity.isVetoed()) {
throw _EndpointLogging.error(log, "POST /objects/{}", domainType,
RestfulObjectsApplicationException
- .createWithBody(HttpStatusCode.BAD_REQUEST, objectRepr, validity.getReasonAsString().orElse(null)));
+ .createWithBody(HttpStatus.BAD_REQUEST, objectRepr, validity.getReasonAsString().orElse(null)));
}
MmEntityUtils.persistInCurrentTransaction(adapter);
@@ -145,16 +131,9 @@ public Response persist(
// DOMAIN OBJECT
@Override
-// @GET
-// @Path("/{domainType}/{instanceId}")
-// @Consumes({ MediaType.WILDCARD })
-// @Produces({
-// MediaType.APPLICATION_JSON, RestfulMediaType.APPLICATION_JSON_OBJECT, RestfulMediaType.APPLICATION_JSON_ERROR,
-// MediaType.APPLICATION_XML, RestfulMediaType.APPLICATION_XML_OBJECT, RestfulMediaType.APPLICATION_XML_ERROR
-// })
- public Response object(
- @PathParam("domainType") final String domainType,
- @PathParam("instanceId") final String instanceId) {
+ public ResponseEntity<Object> object(
+ final String domainType,
+ final String instanceId) {
var resourceContext = createResourceContext(new ResourceDescriptor(
RepresentationType.DOMAIN_OBJECT, Where.OBJECT_FORMS,
@@ -169,16 +148,9 @@ public Response object(
}
@Override
-// @PUT
-// @Path("/{domainType}/{instanceId}")
-// @Consumes({ MediaType.WILDCARD })
-// @Produces({
-// MediaType.APPLICATION_JSON, RestfulMediaType.APPLICATION_JSON_OBJECT, RestfulMediaType.APPLICATION_JSON_ERROR,
-// MediaType.APPLICATION_XML, RestfulMediaType.APPLICATION_XML_OBJECT, RestfulMediaType.APPLICATION_XML_ERROR
-// })
- public Response object(
- @PathParam("domainType") final String domainType,
- @PathParam("instanceId") final String instanceId,
+ public ResponseEntity<Object> object(
+ final String domainType,
+ final String instanceId,
final InputStream object) {
var resourceContext = createResourceContext(new ResourceDescriptor(
@@ -190,7 +162,7 @@ public Response object(
throw _EndpointLogging.error(log, "PUT /objects/{}/{}", domainType, instanceId,
RestfulObjectsApplicationException
.createWithMessage(
- HttpStatusCode.BAD_REQUEST, "Body is not a map; got %s", argRepr));
+ HttpStatus.BAD_REQUEST, "Body is not a map; got %s".formatted(argRepr)));
}
var objectAdapter = getObjectAdapterElseThrowNotFound(domainType, instanceId,
@@ -201,7 +173,7 @@ public Response object(
throw _EndpointLogging.error(log, "PUT /objects/{}/{}", domainType, instanceId,
RestfulObjectsApplicationException
.createWithBody(
- HttpStatusCode.BAD_REQUEST, argRepr, "Illegal property value"));
+ HttpStatus.BAD_REQUEST, argRepr, "Illegal property value"));
}
final Consent validity = objectAdapter.objSpec().isValid(objectAdapter, InteractionInitiatedBy.USER);
@@ -209,7 +181,7 @@ public Response object(
throw _EndpointLogging.error(log, "PUT /objects/{}/{}", domainType, instanceId,
RestfulObjectsApplicationException
.createWithBody(
- HttpStatusCode.BAD_REQUEST, argRepr, validity.getReasonAsString().orElse(null)));
+ HttpStatus.BAD_REQUEST, argRepr, validity.getReasonAsString().orElse(null)));
}
var domainResourceHelper = _DomainResourceHelper.ofObjectResource(resourceContext, objectAdapter);
@@ -218,78 +190,47 @@ public Response object(
domainResourceHelper.objectRepresentation());
}
-// @DELETE
-// @Path("/{domainType}/{instanceId}")
@Override
- public Response deleteMethodNotSupported(
- @PathParam("domainType") final String domainType,
- @PathParam("instanceId") final String instanceId) {
+ public ResponseEntity<Object> deleteMethodNotSupported(
+ final String domainType,
+ final String instanceId) {
throw _EndpointLogging.error(log, "DELETE /objects/{}/{}", domainType, instanceId,
RestfulObjectsApplicationException
.createWithMessage(
- HttpStatusCode.METHOD_NOT_ALLOWED, "Deleting objects is not supported."));
+ HttpStatus.METHOD_NOT_ALLOWED, "Deleting objects is not supported."));
}
-// @POST
-// @Path("/{domainType}/{instanceId}")
@Override
- public Response postMethodNotAllowed(
- @PathParam("domainType") final String domainType,
- @PathParam("instanceId") final String instanceId) {
+ public ResponseEntity<Object> postMethodNotAllowed(
+ final String domainType,
+ final String instanceId) {
throw _EndpointLogging.error(log, "POST /objects/{}/{}", domainType, instanceId,
RestfulObjectsApplicationException
.createWithMessage(
- HttpStatusCode.METHOD_NOT_ALLOWED, "Posting to object resource is not allowed."));
+ HttpStatus.METHOD_NOT_ALLOWED, "Posting to object resource is not allowed."));
}
// DOMAIN OBJECT LAYOUT
@Override
-// @GET
-// @Path("/{domainType}/{instanceId}/object-icon")
-// @Consumes({ MediaType.WILDCARD })
-// @Produces({
-// "image/png",
-// "image/gif",
-// "image/jpeg",
-// "image/jpg",
-// "image/svg+xml"
-// })
- public Response image(
- @PathParam("domainType") final String domainType,
- @PathParam("instanceId") final String instanceId) {
-
-// createResourceContext(
-// RepresentationType.OBJECT_ICON, Where.ANYWHERE, RepresentationService.Intent.NOT_APPLICABLE);
+ public ResponseEntity<Object> image(
+ final String domainType,
+ final String instanceId) {
var objectAdapter = getObjectAdapterElseThrowNotFound(domainType, instanceId,
roEx->_EndpointLogging.error(log, "GET /objects/{}/{}/object-icon", domainType, instanceId, roEx));
var objectIcon = objectAdapter.getIcon();
return _EndpointLogging.response(log, "GET /objects/{}/{}/object-icon", domainType, instanceId,
- Response
- .ok(
+ responseFactory.ok(
objectIcon.asBytes(),
- objectIcon.getMimeType().getBaseType())
- .build());
- }
-
- public Response.ResponseBuilder objectIconResponse(
- final @NonNull ObjectIcon objectIcon) {
- return Response.ok();
+ MediaType.parseMediaType(objectIcon.getMimeType().getBaseType())));
}
@Override
-// @GET
-// @Path("/{domainType}/{instanceId}/object-layout")
-// @Consumes({ MediaType.WILDCARD })
-// @Produces({
-// MediaType.APPLICATION_JSON, RestfulMediaType.APPLICATION_JSON_OBJECT_LAYOUT_BS,
-// MediaType.APPLICATION_XML, RestfulMediaType.APPLICATION_XML_OBJECT_LAYOUT_BS
-// })
- public Response layout(
- @PathParam("domainType") final String domainType,
- @PathParam("instanceId") final String instanceId) {
+ public ResponseEntity<Object> layout(
+ final String domainType,
+ final String instanceId) {
var resourceContext = createResourceContext(
RepresentationType.OBJECT_LAYOUT, Where.ANYWHERE, RepresentationService.Intent.NOT_APPLICABLE);
@@ -302,12 +243,11 @@ public Response layout(
addLinks(resourceContext, domainType, instanceId, grid);
- return Response.status(Response.Status.OK)
- .entity(serializationStrategy.entity(grid))
- .type(MediaTypes.toJakarta(serializationStrategy.type(RepresentationType.OBJECT_LAYOUT)));
+ return responseFactory.ok(
+ serializationStrategy.entity(grid),
+ serializationStrategy.type(RepresentationType.OBJECT_LAYOUT));
})
- .orElseGet(Responses::ofNotFound)
- .build());
+ .orElseGet(ResponseFactory::notFound));
}
private Optional<Grid> layoutAsGrid(
@@ -383,17 +323,10 @@ public void visit(final CollectionLayoutData collectionLayoutData) {
// DOMAIN OBJECT PROPERTY
@Override
-// @GET
-// @Path("/{domainType}/{instanceId}/properties/{propertyId}")
-// @Consumes({ MediaType.WILDCARD })
-// @Produces({
-// MediaType.APPLICATION_JSON, RestfulMediaType.APPLICATION_JSON_OBJECT_PROPERTY, RestfulMediaType.APPLICATION_JSON_ERROR,
-// MediaType.APPLICATION_XML, RestfulMediaType.APPLICATION_XML_OBJECT_PROPERTY, RestfulMediaType.APPLICATION_XML_ERROR
-// })
- public Response propertyDetails(
- @PathParam("domainType") final String domainType,
- @PathParam("instanceId") final String instanceId,
- @PathParam("propertyId") final String propertyId) {
+ public ResponseEntity<Object> propertyDetails(
+ final String domainType,
+ final String instanceId,
+ final String propertyId) {
var resourceContext = createResourceContext(new ResourceDescriptor(
RepresentationType.OBJECT_PROPERTY, Where.OBJECT_FORMS,
@@ -409,17 +342,10 @@ public Response propertyDetails(
}
@Override
-// @PUT
-// @Path("/{domainType}/{instanceId}/properties/{propertyId}")
-// @Consumes({ MediaType.WILDCARD })
-// @Produces({
-// MediaType.APPLICATION_JSON, RestfulMediaType.APPLICATION_JSON_OBJECT_PROPERTY, RestfulMediaType.APPLICATION_JSON_ERROR,
-// MediaType.APPLICATION_XML, RestfulMediaType.APPLICATION_XML_OBJECT_PROPERTY, RestfulMediaType.APPLICATION_XML_ERROR
-// })
- public Response modifyProperty(
- @PathParam("domainType") final String domainType,
- @PathParam("instanceId") final String instanceId,
- @PathParam("propertyId") final String propertyId,
+ public ResponseEntity<Object> modifyProperty(
+ final String domainType,
+ final String instanceId,
+ final String propertyId,
final InputStream body) {
var resourceContext = createResourceContext(new ResourceDescriptor(
@@ -449,17 +375,10 @@ public Response modifyProperty(
}
@Override
-// @DELETE
-// @Path("/{domainType}/{instanceId}/properties/{propertyId}")
-// @Consumes({ MediaType.WILDCARD })
-// @Produces({
-// MediaType.APPLICATION_JSON, RestfulMediaType.APPLICATION_JSON_OBJECT_PROPERTY, RestfulMediaType.APPLICATION_JSON_ERROR,
-// MediaType.APPLICATION_XML, RestfulMediaType.APPLICATION_XML_OBJECT_PROPERTY, RestfulMediaType.APPLICATION_XML_ERROR
-// })
- public Response clearProperty(
- @PathParam("domainType") final String domainType,
- @PathParam("instanceId") final String instanceId,
- @PathParam("propertyId") final String propertyId) {
+ public ResponseEntity<Object> clearProperty(
+ final String domainType,
+ final String instanceId,
+ final String propertyId) {
var resourceContext = createResourceContext(new ResourceDescriptor(
RepresentationType.GENERIC, Where.OBJECT_FORMS,
@@ -481,35 +400,26 @@ public Response clearProperty(
.propertyDetails(propertyId, ManagedMember.RepresentationMode.WRITE));
}
-// @POST
-// @Path("/{domainType}/{instanceId}/properties/{propertyId}")
@Override
- public Response postPropertyNotAllowed(
- @PathParam("domainType") final String domainType,
- @PathParam("instanceId") final String instanceId,
- @PathParam("propertyId") final String propertyId) {
+ public ResponseEntity<Object> postPropertyNotAllowed(
+ final String domainType,
+ final String instanceId,
+ final String propertyId) {
throw _EndpointLogging.error(log, "POST /objects/{}/{}/properties/{}", domainType, instanceId, propertyId,
RestfulObjectsApplicationException
.createWithMessage(
- HttpStatusCode.METHOD_NOT_ALLOWED,
+ HttpStatus.METHOD_NOT_ALLOWED,
"Posting to a property resource is not allowed."));
}
// DOMAIN OBJECT COLLECTION
@Override
-// @GET
-// @Path("/{domainType}/{instanceId}/collections/{collectionId}")
-// @Consumes({ MediaType.WILDCARD })
-// @Produces({
-// MediaType.APPLICATION_JSON, RestfulMediaType.APPLICATION_JSON_OBJECT_COLLECTION, RestfulMediaType.APPLICATION_JSON_ERROR,
-// MediaType.APPLICATION_XML, RestfulMediaType.APPLICATION_XML_OBJECT_COLLECTION, RestfulMediaType.APPLICATION_XML_ERROR
-// })
- public Response accessCollection(
- @PathParam("domainType") final String domainType,
- @PathParam("instanceId") final String instanceId,
- @PathParam("collectionId") final String collectionId) {
+ public ResponseEntity<Object> accessCollection(
+ final String domainType,
+ final String instanceId,
+ final String collectionId) {
var resourceContext = createResourceContext(new ResourceDescriptor(
RepresentationType.OBJECT_COLLECTION, Where.PARENTED_TABLES,
@@ -527,17 +437,10 @@ public Response accessCollection(
// DOMAIN OBJECT ACTION
@Override
-// @GET
-// @Path("/{domainType}/{instanceId}/actions/{actionId}")
-// @Consumes({ MediaType.WILDCARD })
-// @Produces({
-// MediaType.APPLICATION_JSON, RestfulMediaType.APPLICATION_JSON_OBJECT_ACTION, RestfulMediaType.APPLICATION_JSON_ERROR,
-// MediaType.APPLICATION_XML, RestfulMediaType.APPLICATION_XML_OBJECT_ACTION, RestfulMediaType.APPLICATION_XML_ERROR
-// })
- public Response actionPrompt(
- @PathParam("domainType") final String domainType,
- @PathParam("instanceId") final String instanceId,
- @PathParam("actionId") final String actionId) {
+ public ResponseEntity<Object> actionPrompt(
+ final String domainType,
+ final String instanceId,
+ final String actionId) {
var resourceContext = createResourceContext(new ResourceDescriptor(
RepresentationType.OBJECT_ACTION, Where.OBJECT_FORMS,
@@ -551,66 +454,53 @@ public Response actionPrompt(
domainResourceHelper.actionPrompt(actionId));
}
-// @DELETE
-// @Path("/{domainType}/{instanceId}/actions/{actionId}")
@Override
- public Response deleteActionPromptNotAllowed(
- @PathParam("domainType") final String domainType,
- @PathParam("instanceId") final String instanceId,
- @PathParam("actionId") final String actionId) {
+ public ResponseEntity<Object> deleteActionPromptNotAllowed(
+ final String domainType,
+ final String instanceId,
+ final String actionId) {
throw _EndpointLogging.error(log, "DELETE /objects/{}/{}/actions/{}", domainType, instanceId, actionId,
RestfulObjectsApplicationException
.createWithMessage(
- HttpStatusCode.METHOD_NOT_ALLOWED,
+ HttpStatus.METHOD_NOT_ALLOWED,
"Deleting action prompt resource is not allowed."));
}
-// @POST
-// @Path("/{domainType}/{instanceId}/actions/{actionId}")
@Override
- public Response postActionPromptNotAllowed(
- @PathParam("domainType") final String domainType,
- @PathParam("instanceId") final String instanceId,
- @PathParam("actionId") final String actionId) {
+ public ResponseEntity<Object> postActionPromptNotAllowed(
+ final String domainType,
+ final String instanceId,
+ final String actionId) {
throw _EndpointLogging.error(log, "POST /objects/{}/{}/actions/{}", domainType, instanceId, actionId,
RestfulObjectsApplicationException
.createWithMessage(
- HttpStatusCode.METHOD_NOT_ALLOWED,
+ HttpStatus.METHOD_NOT_ALLOWED,
"Posting to an action prompt resource is not allowed."));
}
-// @PUT
-// @Path("/{domainType}/{instanceId}/actions/{actionId}")
@Override
- public Response putActionPromptNotAllowed(
- @PathParam("domainType") final String domainType,
- @PathParam("instanceId") final String instanceId,
- @PathParam("actionId") final String actionId) {
+ public ResponseEntity<Object> putActionPromptNotAllowed(
+ final String domainType,
+ final String instanceId,
+ final String actionId) {
throw _EndpointLogging.error(log, "PUT /objects/{}/{}/actions/{}", domainType, instanceId, actionId,
RestfulObjectsApplicationException
.createWithMessage(
- HttpStatusCode.METHOD_NOT_ALLOWED,
+ HttpStatus.METHOD_NOT_ALLOWED,
"Putting to an action prompt resource is not allowed."));
}
// DOMAIN OBJECT ACTION INVOKE
@Override
-// @GET
-// @Path("/{domainType}/{instanceId}/actions/{actionId}/invoke")
-// @Consumes({ MediaType.WILDCARD })
-// @Produces({
-// MediaType.APPLICATION_JSON, RestfulMediaType.APPLICATION_JSON_ACTION_RESULT, RestfulMediaType.APPLICATION_JSON_ERROR,
-// MediaType.APPLICATION_XML, RestfulMediaType.APPLICATION_XML_ACTION_RESULT, RestfulMediaType.APPLICATION_XML_ERROR
-// })
- public Response invokeActionQueryOnly(
- final @PathParam("domainType") String domainType,
- final @PathParam("instanceId") String instanceId,
- final @PathParam("actionId") String actionId,
- final @QueryParam("x-causeway-querystring") String xCausewayUrlEncodedQueryString) {
+ public ResponseEntity<Object> invokeActionQueryOnly(
+ final String domainType,
+ final String instanceId,
+ final String actionId,
+ final String xCausewayUrlEncodedQueryString) {
final String urlUnencodedQueryString = UrlUtils.urlDecodeUtf8(
xCausewayUrlEncodedQueryString != null
@@ -632,17 +522,10 @@ public Response invokeActionQueryOnly(
}
@Override
-// @PUT
-// @Path("/{domainType}/{instanceId}/actions/{actionId}/invoke")
-// @Consumes({ MediaType.WILDCARD })
-// @Produces({
-// MediaType.APPLICATION_JSON, RestfulMediaType.APPLICATION_JSON_ACTION_RESULT, RestfulMediaType.APPLICATION_JSON_ERROR,
-// MediaType.APPLICATION_XML, RestfulMediaType.APPLICATION_XML_ACTION_RESULT, RestfulMediaType.APPLICATION_XML_ERROR
-// })
- public Response invokeActionIdempotent(
- final @PathParam("domainType") String domainType,
- final @PathParam("instanceId") String instanceId,
- final @PathParam("actionId") String actionId,
+ public ResponseEntity<Object> invokeActionIdempotent(
+ final String domainType,
+ final String instanceId,
+ final String actionId,
final InputStream body) {
var resourceContext = createResourceContext(
@@ -661,17 +544,10 @@ public Response invokeActionIdempotent(
}
@Override
-// @POST
-// @Path("/{domainType}/{instanceId}/actions/{actionId}/invoke")
-// @Consumes({ MediaType.WILDCARD })
-// @Produces({
-// MediaType.APPLICATION_JSON, RestfulMediaType.APPLICATION_JSON_ACTION_RESULT, RestfulMediaType.APPLICATION_JSON_ERROR,
-// MediaType.APPLICATION_XML, RestfulMediaType.APPLICATION_XML_ACTION_RESULT, RestfulMediaType.APPLICATION_XML_ERROR
-// })
- public Response invokeAction(
- @PathParam("domainType") final String domainType,
- @PathParam("instanceId") final String instanceId,
- @PathParam("actionId") final String actionId,
+ public ResponseEntity<Object> invokeAction(
+ final String domainType,
+ final String instanceId,
+ final String actionId,
final InputStream body) {
var resourceContext = createResourceContext(
@@ -689,18 +565,16 @@ public Response invokeAction(
domainResourceHelper.invokeAction(actionId, arguments));
}
-// @DELETE
-// @Path("/{domainType}/{instanceId}/actions/{actionId}/invoke")
@Override
- public Response deleteInvokeActionNotAllowed(
- @PathParam("domainType") final String domainType,
- @PathParam("instanceId") final String instanceId,
- @PathParam("actionId") final String actionId) {
+ public ResponseEntity<Object> deleteInvokeActionNotAllowed(
+ final String domainType,
+ final String instanceId,
+ final String actionId) {
throw _EndpointLogging.error(log, "DELETE /objects/{}/{}/actions/{}/invoke", domainType, instanceId, actionId,
RestfulObjectsApplicationException
.createWithMessage(
- RestfulResponse.HttpStatusCode.METHOD_NOT_ALLOWED,
+ HttpStatus.METHOD_NOT_ALLOWED,
"Deleting an action invocation resource is not allowed."));
}
diff --git a/viewers/restfulobjects/viewer/src/main/java/org/apache/causeway/viewer/restfulobjects/viewer/resources/DomainServiceResourceServerside.java b/viewers/restfulobjects/viewer/src/main/java/org/apache/causeway/viewer/restfulobjects/viewer/resources/DomainServiceResourceServerside.java
index 2bc2f69b20f..d3d4f2c4e4b 100644
--- a/viewers/restfulobjects/viewer/src/main/java/org/apache/causeway/viewer/restfulobjects/viewer/resources/DomainServiceResourceServerside.java
+++ b/viewers/restfulobjects/viewer/src/main/java/org/apache/causeway/viewer/restfulobjects/viewer/resources/DomainServiceResourceServerside.java
@@ -20,21 +20,16 @@
import java.io.InputStream;
-import jakarta.ws.rs.Path;
-import jakarta.ws.rs.PathParam;
-import jakarta.ws.rs.QueryParam;
-import jakarta.ws.rs.core.Response;
-
-import org.springframework.stereotype.Component;
+import org.springframework.http.HttpStatus;
+import org.springframework.http.ResponseEntity;
+import org.springframework.web.bind.annotation.RestController;
import org.apache.causeway.applib.annotation.Where;
import org.apache.causeway.commons.io.UrlUtils;
import org.apache.causeway.viewer.restfulobjects.applib.JsonRepresentation;
import org.apache.causeway.viewer.restfulobjects.applib.RepresentationType;
-import org.apache.causeway.viewer.restfulobjects.applib.RestfulResponse;
import org.apache.causeway.viewer.restfulobjects.applib.domainobjects.DomainServiceResource;
import org.apache.causeway.viewer.restfulobjects.rendering.Caching;
-import org.apache.causeway.viewer.restfulobjects.rendering.Responses;
import org.apache.causeway.viewer.restfulobjects.rendering.RestfulObjectsApplicationException;
import org.apache.causeway.viewer.restfulobjects.rendering.domainobjects.DomainObjectReprRenderer;
import org.apache.causeway.viewer.restfulobjects.rendering.domainobjects.DomainServiceLinkTo;
@@ -44,8 +39,7 @@
import lombok.extern.slf4j.Slf4j;
-@Component
-@Path("/services")
+@RestController
@Slf4j
public class DomainServiceResourceServerside
extends ResourceAbstract
@@ -57,13 +51,7 @@ public DomainServiceResourceServerside() {
}
@Override
-// @GET
-// @Path("/")
-// @Produces({
-// MediaType.APPLICATION_JSON,
-// RestfulMediaType.APPLICATION_JSON_LIST,
-// RestfulMediaType.APPLICATION_JSON_ERROR })
- public Response services() {
+ public ResponseEntity<Object> services() {
var resourceContext = createResourceContext(
RepresentationType.LIST, Where.STANDALONE_TABLES, RepresentationService.Intent.NOT_APPLICABLE);
@@ -76,47 +64,41 @@ public Response services() {
.with(resourceContext.streamServiceAdapters());
return _EndpointLogging.response(log, "GET /services/",
- Responses.ofOk(renderer, Caching.ONE_DAY).build());
+ responseFactory.ok(renderer, Caching.ONE_DAY));
}
@Override
- public Response deleteServicesNotAllowed() {
+ public ResponseEntity<Object> deleteServicesNotAllowed() {
throw _EndpointLogging.error(log, "DELETE /services",
RestfulObjectsApplicationException
.createWithMessage(
- RestfulResponse.HttpStatusCode.METHOD_NOT_ALLOWED,
+ HttpStatus.METHOD_NOT_ALLOWED,
"Deleting the services resource is not allowed."));
}
@Override
- public Response putServicesNotAllowed() {
+ public ResponseEntity<Object> putServicesNotAllowed() {
throw _EndpointLogging.error(log, "PUT /services",
RestfulObjectsApplicationException
.createWithMessage(
- RestfulResponse.HttpStatusCode.METHOD_NOT_ALLOWED,
+ HttpStatus.METHOD_NOT_ALLOWED,
"Putting to the services resource is not allowed."));
}
@Override
- public Response postServicesNotAllowed() {
+ public ResponseEntity<Object> postServicesNotAllowed() {
throw _EndpointLogging.error(log, "POST /services",
RestfulObjectsApplicationException
.createWithMessage(
- RestfulResponse.HttpStatusCode.METHOD_NOT_ALLOWED,
+ HttpStatus.METHOD_NOT_ALLOWED,
"Posting to the services resource is not allowed."));
}
// DOMAIN SERVICE
@Override
-// @GET
-// @Path("/{serviceId}")
-// @Produces({
-// MediaType.APPLICATION_JSON, RestfulMediaType.APPLICATION_JSON_OBJECT, RestfulMediaType.APPLICATION_JSON_ERROR,
-// MediaType.APPLICATION_XML, RestfulMediaType.APPLICATION_XML_OBJECT, RestfulMediaType.APPLICATION_XML_ERROR
-// })
- public Response service(
- @PathParam("serviceId") final String serviceId) {
+ public ResponseEntity<Object> service(
+ final String serviceId) {
var resourceContext = createResourceContext(new ResourceDescriptor(
RepresentationType.DOMAIN_OBJECT, Where.OBJECT_FORMS,
@@ -131,57 +113,45 @@ public Response service(
.includesSelf();
return _EndpointLogging.response(log, "GET /services/{}", serviceId,
- Responses.ofOk(renderer, Caching.ONE_DAY).build());
+ responseFactory.ok(renderer, Caching.ONE_DAY));
}
-// @DELETE
-// @Path("/{serviceId}")
@Override
- public Response deleteServiceNotAllowed(
- @PathParam("serviceId") final String serviceId) {
+ public ResponseEntity<Object> deleteServiceNotAllowed(
+ final String serviceId) {
throw _EndpointLogging.error(log, "DELETE /services/{}", serviceId,
RestfulObjectsApplicationException
.createWithMessage(
- RestfulResponse.HttpStatusCode.METHOD_NOT_ALLOWED,
+ HttpStatus.METHOD_NOT_ALLOWED,
"Deleting a service resource is not allowed."));
}
-// @PUT
-// @Path("/{serviceId}")
@Override
- public Response putServiceNotAllowed(
- @PathParam("serviceId") final String serviceId) {
+ public ResponseEntity<Object> putServiceNotAllowed(
+ final String serviceId) {
throw _EndpointLogging.error(log, "PUT /services/{}", serviceId,
RestfulObjectsApplicationException
.createWithMessage(
- RestfulResponse.HttpStatusCode.METHOD_NOT_ALLOWED,
+ HttpStatus.METHOD_NOT_ALLOWED,
"Putting to a service resource is not allowed."));
}
-// @POST
-// @Path("/{serviceId}")
@Override
- public Response postServiceNotAllowed(
- @PathParam("serviceId") final String serviceId) {
+ public ResponseEntity<Object> postServiceNotAllowed(
+ final String serviceId) {
throw _EndpointLogging.error(log, "POST /services/{}", serviceId,
RestfulObjectsApplicationException
.createWithMessage(
- RestfulResponse.HttpStatusCode.METHOD_NOT_ALLOWED,
+ HttpStatus.METHOD_NOT_ALLOWED,
"Posting to a service resource is not allowed."));
}
// DOMAIN SERVICE ACTION
@Override
-// @GET
-// @Path("/{serviceId}/actions/{actionId}")
-// @Produces({
-// MediaType.APPLICATION_JSON, RestfulMediaType.APPLICATION_JSON_OBJECT_ACTION, RestfulMediaType.APPLICATION_JSON_ERROR,
-// MediaType.APPLICATION_XML, RestfulMediaType.APPLICATION_XML_OBJECT_ACTION, RestfulMediaType.APPLICATION_XML_ERROR
-// })
- public Response actionPrompt(
- @PathParam("serviceId") final String serviceId,
- @PathParam("actionId") final String actionId) {
+ public ResponseEntity<Object> actionPrompt(
+ final String serviceId,
+ final String actionId) {
var resourceContext = createResourceContext(new ResourceDescriptor(
RepresentationType.OBJECT_ACTION, Where.OBJECT_FORMS,
@@ -193,58 +163,46 @@ public Response actionPrompt(
domainResourceHelper.actionPrompt(actionId));
}
-// @DELETE
-// @Path("/{serviceId}/actions/{actionId}")
@Override
- public Response deleteActionPromptNotAllowed(
- @PathParam("serviceId") final String serviceId,
- @PathParam("actionId") final String actionId) {
+ public ResponseEntity<Object> deleteActionPromptNotAllowed(
+ final String serviceId,
+ final String actionId) {
throw _EndpointLogging.error(log, "DELETE /services/{}/actions/{}", serviceId, actionId,
RestfulObjectsApplicationException
.createWithMessage(
- RestfulResponse.HttpStatusCode.METHOD_NOT_ALLOWED,
+ HttpStatus.METHOD_NOT_ALLOWED,
"Deleting action prompt resource is not allowed."));
}
-// @PUT
-// @Path("/{serviceId}/actions/{actionId}")
@Override
- public Response putActionPromptNotAllowed(
- @PathParam("serviceId") final String serviceId,
- @PathParam("actionId") final String actionId) {
+ public ResponseEntity<Object> putActionPromptNotAllowed(
+ final String serviceId,
+ final String actionId) {
throw _EndpointLogging.error(log, "PUT /services/{}/actions/{}", serviceId, actionId,
RestfulObjectsApplicationException
.createWithMessage(
- RestfulResponse.HttpStatusCode.METHOD_NOT_ALLOWED,
+ HttpStatus.METHOD_NOT_ALLOWED,
"Putting to an action prompt resource is not allowed."));
}
-// @POST
-// @Path("/{serviceId}/actions/{actionId}")
@Override
- public Response postActionPromptNotAllowed(
- @PathParam("serviceId") final String serviceId,
- @PathParam("actionId") final String actionId) {
+ public ResponseEntity<Object> postActionPromptNotAllowed(
+ final String serviceId,
+ final String actionId) {
throw _EndpointLogging.error(log, "POST /services/{}/actions/{}", serviceId, actionId,
RestfulObjectsApplicationException
.createWithMessage(
- RestfulResponse.HttpStatusCode.METHOD_NOT_ALLOWED,
+ HttpStatus.METHOD_NOT_ALLOWED,
"Posting to an action prompt resource is not allowed."));
}
// DOMAIN SERVICE ACTION INVOKE
@Override
-// @GET
-// @Path("/{serviceId}/actions/{actionId}/invoke")
-// @Produces({
-// MediaType.APPLICATION_JSON, RestfulMediaType.APPLICATION_JSON_ACTION_RESULT, RestfulMediaType.APPLICATION_JSON_ERROR,
-// MediaType.APPLICATION_XML, RestfulMediaType.APPLICATION_XML_ACTION_RESULT, RestfulMediaType.APPLICATION_XML_ERROR
-// })
- public Response invokeActionQueryOnly(
- final @PathParam("serviceId") String serviceId,
- final @PathParam("actionId") String actionId,
- final @QueryParam("x-causeway-querystring") String xCausewayUrlEncodedQueryString) {
+ public ResponseEntity<Object> invokeActionQueryOnly(
+ final String serviceId,
+ final String actionId,
+ final String xCausewayUrlEncodedQueryString) {
final String urlUnencodedQueryString = UrlUtils.urlDecodeUtf8(
xCausewayUrlEncodedQueryString != null
@@ -264,16 +222,9 @@ public Response invokeActionQueryOnly(
}
@Override
-// @PUT
-// @Path("/{serviceId}/actions/{actionId}/invoke")
-// //@Consumes({ MediaType.WILDCARD }) // to save the client having to specify a Content-Type: application/json
-// @Produces({
-// MediaType.APPLICATION_JSON, RestfulMediaType.APPLICATION_JSON_ACTION_RESULT, RestfulMediaType.APPLICATION_JSON_ERROR,
-// MediaType.APPLICATION_XML, RestfulMediaType.APPLICATION_XML_ACTION_RESULT, RestfulMediaType.APPLICATION_XML_ERROR
-// })
- public Response invokeActionIdempotent(
- final @PathParam("serviceId") String serviceId,
- final @PathParam("actionId") String actionId,
+ public ResponseEntity<Object> invokeActionIdempotent(
+ final String serviceId,
+ final String actionId,
final InputStream body) {
var resourceContext = createResourceContext(
@@ -290,16 +241,9 @@ public Response invokeActionIdempotent(
}
@Override
-// @POST
-// @Path("/{serviceId}/actions/{actionId}/invoke")
-// //@Consumes({ MediaType.WILDCARD }) // to save the client having to specify a Content-Type: application/json
-// @Produces({
-// MediaType.APPLICATION_JSON, RestfulMediaType.APPLICATION_JSON_ACTION_RESULT, RestfulMediaType.APPLICATION_JSON_ERROR,
-// MediaType.APPLICATION_XML, RestfulMediaType.APPLICATION_XML_ACTION_RESULT, RestfulMediaType.APPLICATION_XML_ERROR
-// })
- public Response invokeAction(
- @PathParam("serviceId") final String serviceId,
- @PathParam("actionId") final String actionId,
+ public ResponseEntity<Object> invokeAction(
+ final String serviceId,
+ final String actionId,
final InputStream body) {
var resourceContext = createResourceContext(
@@ -315,16 +259,14 @@ public Response invokeAction(
domainResourceHelper.invokeAction(actionId, arguments));
}
-// @DELETE
-// @Path("/{serviceId}/actions/{actionId}/invoke")
@Override
- public Response deleteInvokeActionNotAllowed(
- @PathParam("serviceId") final String serviceId,
- @PathParam("actionId") final String actionId) {
+ public ResponseEntity<Object> deleteInvokeActionNotAllowed(
+ final String serviceId,
+ final String actionId) {
throw _EndpointLogging.error(log, "DELETE /services/{}/actions/{}/invoke", serviceId, actionId,
RestfulObjectsApplicationException
.createWithMessage(
- RestfulResponse.HttpStatusCode.METHOD_NOT_ALLOWED,
+ HttpStatus.METHOD_NOT_ALLOWED,
"Deleting an action invocation resource is not allowed."));
}
diff --git a/viewers/restfulobjects/viewer/src/main/java/org/apache/causeway/viewer/restfulobjects/viewer/resources/DomainTypeResourceServerside.java b/viewers/restfulobjects/viewer/src/main/java/org/apache/causeway/viewer/restfulobjects/viewer/resources/DomainTypeResourceServerside.java
index a7fa28ef193..bd72c91c978 100644
--- a/viewers/restfulobjects/viewer/src/main/java/org/apache/causeway/viewer/restfulobjects/viewer/resources/DomainTypeResourceServerside.java
+++ b/viewers/restfulobjects/viewer/src/main/java/org/apache/causeway/viewer/restfulobjects/viewer/resources/DomainTypeResourceServerside.java
@@ -20,14 +20,11 @@
import java.util.function.UnaryOperator;
-import jakarta.ws.rs.Path;
-import jakarta.ws.rs.PathParam;
-import jakarta.ws.rs.QueryParam;
-import jakarta.ws.rs.core.Response;
-
import org.jspecify.annotations.NonNull;
-import org.springframework.stereotype.Component;
+import org.springframework.http.HttpStatus;
+import org.springframework.http.ResponseEntity;
+import org.springframework.web.bind.annotation.RestController;
import org.apache.causeway.applib.annotation.Where;
import org.apache.causeway.commons.internal.base._Strings;
@@ -38,13 +35,11 @@
import org.apache.causeway.viewer.restfulobjects.applib.JsonRepresentation;
import org.apache.causeway.viewer.restfulobjects.applib.Rel;
import org.apache.causeway.viewer.restfulobjects.applib.RepresentationType;
-import org.apache.causeway.viewer.restfulobjects.applib.RestfulResponse.HttpStatusCode;
import org.apache.causeway.viewer.restfulobjects.applib.domaintypes.DomainTypeResource;
-import org.apache.causeway.viewer.restfulobjects.applib.util.MediaTypes;
import org.apache.causeway.viewer.restfulobjects.applib.util.UrlEncodingUtils;
import org.apache.causeway.viewer.restfulobjects.rendering.Caching;
import org.apache.causeway.viewer.restfulobjects.rendering.LinkBuilder;
-import org.apache.causeway.viewer.restfulobjects.rendering.Responses;
+import org.apache.causeway.viewer.restfulobjects.rendering.ResponseFactory;
import org.apache.causeway.viewer.restfulobjects.rendering.RestfulObjectsApplicationException;
import org.apache.causeway.viewer.restfulobjects.rendering.domaintypes.ActionDescriptionReprRenderer;
import org.apache.causeway.viewer.restfulobjects.rendering.domaintypes.ActionParameterDescriptionReprRenderer;
@@ -64,13 +59,7 @@
import lombok.extern.slf4j.Slf4j;
-/**
- * Implementation note: it seems to be necessary to annotate the implementation
- * with {@link Path} rather than the interface (at least under RestEasy 1.0.2
- * and 1.1-RC2).
- */
-@Component
-@Path("/domain-types")
+@RestController
@Slf4j
public class DomainTypeResourceServerside
extends ResourceAbstract
@@ -82,12 +71,7 @@ public DomainTypeResourceServerside() {
}
@Override
-// @GET
-// @Path("/")
-// @Produces({
-// MediaType.APPLICATION_JSON,
-// RestfulMediaType.APPLICATION_JSON_TYPE_LIST })
- public Response domainTypes() {
+ public ResponseEntity<Object> domainTypes() {
var resourceContext = createResourceContext(
RepresentationType.TYPE_LIST, Where.ANYWHERE, RepresentationService.Intent.NOT_APPLICABLE);
@@ -95,22 +79,15 @@ public Response domainTypes() {
var domainTypeSpecifications = getSpecificationLoader().snapshotSpecifications()
.filter(spec->spec.isEntityOrViewModel()); // concrete types only, no abstract types
- final TypeListReprRenderer renderer =
- new TypeListReprRenderer(resourceContext, null, JsonRepresentation.newMap());
- renderer.with(domainTypeSpecifications).includesSelf();
+ final TypeListReprRenderer renderer = new TypeListReprRenderer(resourceContext, null, JsonRepresentation.newMap())
+ .with(domainTypeSpecifications).includesSelf();
return _EndpointLogging.response(log, "GET /domain-types/",
- Responses.ofOk(renderer, Caching.ONE_DAY).build());
+ responseFactory.ok(renderer, Caching.ONE_DAY));
}
@Override
-// @GET
-// @Path("/{domainType}")
-// @Produces({
-// MediaType.APPLICATION_JSON,
-// RestfulMediaType.APPLICATION_JSON_DOMAIN_TYPE })
- public Response domainType(
- @PathParam("domainType") final String domainType) {
+ public ResponseEntity<Object> domainType(final String domainType) {
var resourceContext = createResourceContext(
RepresentationType.DOMAIN_TYPE, Where.ANYWHERE, RepresentationService.Intent.NOT_APPLICABLE);
@@ -118,52 +95,37 @@ public Response domainType(
var objectSpec = getSpecificationLoader().specForLogicalTypeName(domainType).orElse(null);
if(objectSpec==null) {
throw _EndpointLogging.error(log, "GET /domain-types/{}", domainType,
- RestfulObjectsApplicationException.create(HttpStatusCode.NOT_FOUND));
+ RestfulObjectsApplicationException.create(HttpStatus.NOT_FOUND));
}
- var renderer = new DomainTypeReprRenderer(resourceContext, null, JsonRepresentation.newMap());
- renderer.with(objectSpec).includesSelf();
+ var renderer = new DomainTypeReprRenderer(resourceContext, null, JsonRepresentation.newMap())
+ .with(objectSpec).includesSelf();
return _EndpointLogging.response(log, "GET /domain-types/{}", domainType,
- Responses.ofOk(renderer, Caching.ONE_DAY).build());
+ responseFactory.ok(renderer, Caching.ONE_DAY));
}
@Override
-// @GET
-// @Path("/{domainType}/layout")
-// @Produces({
-// MediaType.APPLICATION_JSON, RestfulMediaType.APPLICATION_JSON_LAYOUT_BS,
-// MediaType.APPLICATION_XML, RestfulMediaType.APPLICATION_XML_LAYOUT_BS
-// })
- public Response layout(
- @PathParam("domainType") final String domainType) {
+ public ResponseEntity<Object> layout(final String domainType) {
var resourceContext = createResourceContext(
RepresentationType.LAYOUT, Where.ANYWHERE, RepresentationService.Intent.NOT_APPLICABLE);
var serializationStrategy = resourceContext.getSerializationStrategy();
- var responseBuilder = getSpecificationLoader().specForLogicalTypeName(domainType)
+ var response = getSpecificationLoader().specForLogicalTypeName(domainType)
.map(Facets::bootstrapGrid)
.map(grid ->
- Response.status(Response.Status.OK)
- .entity(serializationStrategy.entity(grid))
- .type(MediaTypes.toJakarta(serializationStrategy.type(RepresentationType.LAYOUT))))
- .orElse(Responses.ofNotFound());
+ responseFactory.ok(serializationStrategy.entity(grid),
+ serializationStrategy.type(RepresentationType.LAYOUT)))
+ .orElseGet(ResponseFactory::notFound);
return _EndpointLogging.response(log, "GET({}) /domain-types/{}/layout", serializationStrategy.name(), domainType,
- responseBuilder.build());
+ response);
}
@Override
-// @GET
-// @Path("/{domainType}/properties/{propertyId}")
-// @Produces({
-// MediaType.APPLICATION_JSON,
-// RestfulMediaType.APPLICATION_JSON_PROPERTY_DESCRIPTION })
- public Response typeProperty(
- @PathParam("domainType") final String domainType,
- @PathParam("propertyId") final String propertyId) {
+ public ResponseEntity<Object> typeProperty(final String domainType, final String propertyId) {
var resourceContext = createResourceContext(
RepresentationType.PROPERTY_DESCRIPTION, Where.ANYWHERE, RepresentationService.Intent.NOT_APPLICABLE);
@@ -171,17 +133,17 @@ public Response typeProperty(
var parentSpec = getSpecificationLoader().specForLogicalTypeName(domainType).orElse(null);
if (parentSpec == null) {
throw _EndpointLogging.error(log, "GET /domain-types/{}/properties/{}", domainType, propertyId,
- RestfulObjectsApplicationException.create(HttpStatusCode.NOT_FOUND));
+ RestfulObjectsApplicationException.create(HttpStatus.NOT_FOUND));
}
var objectMember = parentSpec.getAssociation(propertyId)
.orElseThrow(()->
_EndpointLogging.error(log, "GET /domain-types/{}/properties/{}", domainType, propertyId,
- RestfulObjectsApplicationException.create(HttpStatusCode.NOT_FOUND)));
+ RestfulObjectsApplicationException.create(HttpStatus.NOT_FOUND)));
if (objectMember.isOneToManyAssociation()) {
throw _EndpointLogging.error(log, "GET /domain-types/{}/properties/{}", domainType, propertyId,
- RestfulObjectsApplicationException.create(HttpStatusCode.NOT_FOUND));
+ RestfulObjectsApplicationException.create(HttpStatus.NOT_FOUND));
}
final OneToOneAssociation property = (OneToOneAssociation) objectMember;
@@ -189,18 +151,11 @@ public Response typeProperty(
renderer.with(new ParentSpecAndProperty(parentSpec, property)).includesSelf();
return _EndpointLogging.response(log, "GET /domain-types/{}/properties/{}", domainType, propertyId,
- Responses.ofOk(renderer, Caching.ONE_DAY).build());
+ responseFactory.ok(renderer, Caching.ONE_DAY));
}
@Override
-// @GET
-// @Path("/{domainType}/collections/{collectionId}")
-// @Produces({
-// MediaType.APPLICATION_JSON,
-// RestfulMediaType.APPLICATION_JSON_COLLECTION_DESCRIPTION })
- public Response typeCollection(
- @PathParam("domainType") final String domainType,
- @PathParam("collectionId") final String collectionId) {
+ public ResponseEntity<Object> typeCollection(final String domainType, final String collectionId) {
var resourceContext = createResourceContext(
RepresentationType.COLLECTION_DESCRIPTION, Where.ANYWHERE, RepresentationService.Intent.NOT_APPLICABLE);
@@ -208,17 +163,17 @@ public Response typeCollection(
var parentSpec = getSpecificationLoader().specForLogicalTypeName(domainType).orElse(null);
if (parentSpec == null) {
throw _EndpointLogging.error(log, "GET /domain-types/{}/collections/{}", domainType, collectionId,
- RestfulObjectsApplicationException.create(HttpStatusCode.NOT_FOUND));
+ RestfulObjectsApplicationException.create(HttpStatus.NOT_FOUND));
}
var objectMember = parentSpec.getAssociation(collectionId)
.orElseThrow(()->
_EndpointLogging.error(log, "GET /domain-types/{}/collections/{}", domainType, collectionId,
- RestfulObjectsApplicationException.create(HttpStatusCode.NOT_FOUND)));
+ RestfulObjectsApplicationException.create(HttpStatus.NOT_FOUND)));
if (objectMember.isOneToOneAssociation()) {
throw _EndpointLogging.error(log, "GET /domain-types/{}/collections/{}", domainType, collectionId,
- RestfulObjectsApplicationException.create(HttpStatusCode.NOT_FOUND));
+ RestfulObjectsApplicationException.create(HttpStatus.NOT_FOUND));
}
final OneToManyAssociation collection = (OneToManyAssociation) objectMember;
@@ -226,18 +181,11 @@ public Response typeCollection(
renderer.with(new ParentSpecAndCollection(parentSpec, collection)).includesSelf();
return _EndpointLogging.response(log, "GET /domain-types/{}/collections/{}", domainType, collectionId,
- Responses.ofOk(renderer, Caching.ONE_DAY).build());
+ responseFactory.ok(renderer, Caching.ONE_DAY));
}
@Override
-// @GET
-// @Path("/{domainType}/actions/{actionId}")
-// @Produces({
-// MediaType.APPLICATION_JSON,
-// RestfulMediaType.APPLICATION_JSON_ACTION_DESCRIPTION })
- public Response typeAction(
- @PathParam("domainType") final String domainType,
- @PathParam("actionId") final String actionId) {
+ public ResponseEntity<Object> typeAction(final String domainType, final String actionId) {
var resourceContext = createResourceContext(
RepresentationType.ACTION_DESCRIPTION, Where.ANYWHERE, RepresentationService.Intent.NOT_APPLICABLE);
@@ -245,30 +193,22 @@ public Response typeAction(
var parentSpec = getSpecificationLoader().specForLogicalTypeName(domainType).orElse(null);
if (parentSpec == null) {
throw _EndpointLogging.error(log, "GET /domain-types/{}/actions/{}", domainType, actionId,
- RestfulObjectsApplicationException.create(HttpStatusCode.NOT_FOUND));
+ RestfulObjectsApplicationException.create(HttpStatus.NOT_FOUND));
}
var action = parentSpec.getAction(actionId)
.orElseThrow(()->_EndpointLogging.error(log, "GET /domain-types/{}/actions/{}", domainType, actionId,
- RestfulObjectsApplicationException.create(HttpStatusCode.NOT_FOUND)));
+ RestfulObjectsApplicationException.create(HttpStatus.NOT_FOUND)));
final ActionDescriptionReprRenderer renderer = new ActionDescriptionReprRenderer(resourceContext, null, JsonRepresentation.newMap());
renderer.with(new ParentSpecAndAction(parentSpec, action)).includesSelf();
return _EndpointLogging.response(log, "GET /domain-types/{}/actions/{}", domainType, actionId,
- Responses.ofOk(renderer, Caching.ONE_DAY).build());
+ responseFactory.ok(renderer, Caching.ONE_DAY));
}
@Override
-// @GET
-// @Path("/{domainType}/actions/{actionId}/params/{paramId}")
-// @Produces({
-// MediaType.APPLICATION_JSON,
-// RestfulMediaType.APPLICATION_JSON_ACTION_PARAMETER_DESCRIPTION })
- public Response typeActionParam(
- @PathParam("domainType") final String domainType,
- @PathParam("actionId") final String actionId,
- @PathParam("paramId") final String paramId) {
+ public ResponseEntity<Object> typeActionParam(final String domainType, final String actionId, final String paramId) {
var resourceContext = createResourceContext(
RepresentationType.ACTION_PARAMETER_DESCRIPTION, Where.ANYWHERE, RepresentationService.Intent.NOT_APPLICABLE);
@@ -276,12 +216,12 @@ public Response typeActionParam(
var parentSpec = getSpecificationLoader().specForLogicalTypeName(domainType).orElse(null);
if (parentSpec == null) {
throw _EndpointLogging.error(log, "GET /domain-types/{}/actions/{}/params/{}", domainType, actionId, paramId,
- RestfulObjectsApplicationException.create(HttpStatusCode.NOT_FOUND));
+ RestfulObjectsApplicationException.create(HttpStatus.NOT_FOUND));
}
var parentAction = parentSpec.getAction(actionId)
.orElseThrow(()->_EndpointLogging.error(log, "GET /domain-types/{}/actions/{}/params/{}", domainType, actionId, paramId,
- RestfulObjectsApplicationException.create(HttpStatusCode.NOT_FOUND)));
+ RestfulObjectsApplicationException.create(HttpStatus.NOT_FOUND)));
final ObjectActionParameter actionParam = parentAction.getParameterById(paramId);
@@ -289,22 +229,16 @@ public Response typeActionParam(
renderer.with(new ParentSpecAndActionParam(parentSpec, actionParam)).includesSelf();
return _EndpointLogging.response(log, "GET /domain-types/{}/actions/{}/params/{}", domainType, actionId, paramId,
- Responses.ofOk(renderer, Caching.ONE_DAY).build());
+ responseFactory.ok(renderer, Caching.ONE_DAY));
}
// -- DOMAIN TYPE ACTIONS
@Override
-// @GET
-// @Path("/{domainType}/type-actions/isSubtypeOf/invoke")
-// @Produces({
-// MediaType.APPLICATION_JSON,
-// RestfulMediaType.APPLICATION_JSON_TYPE_ACTION_RESULT,
-// RestfulMediaType.APPLICATION_JSON_ERROR })
- public Response domainTypeIsSubtypeOf(
- @PathParam("domainType") final String domainType,
- @QueryParam("supertype") final String superTypeStr, // simple style
- @QueryParam("args") final String argsUrlEncoded // formal style
+ public ResponseEntity<Object> domainTypeIsSubtypeOf(
+ final String domainType,
+ final String superTypeStr, // simple style
+ final String argsUrlEncoded // formal style
) {
var resourceContext = createResourceContext(new ResourceDescriptor(
@@ -319,7 +253,7 @@ public Response domainTypeIsSubtypeOf(
if (domainTypeSpec == null
|| supertypeSpec == null) {
throw _EndpointLogging.error(log, "GET /domain-types/{}/type-actions/isSubtypeOf/invoke", domainType,
- RestfulObjectsApplicationException.create(HttpStatusCode.NOT_FOUND));
+ RestfulObjectsApplicationException.create(HttpStatus.NOT_FOUND));
}
final TypeActionResultReprRenderer renderer = new TypeActionResultReprRenderer(resourceContext, null, JsonRepresentation.newMap());
@@ -333,20 +267,14 @@ public Response domainTypeIsSubtypeOf(
renderer.with(domainTypeSpec).withSelf(selfLink).withValue(value);
return _EndpointLogging.response(log, "GET /domain-types/{}/type-actions/isSubtypeOf/invoke", domainType,
- Responses.ofOk(renderer, Caching.ONE_DAY).build());
+ responseFactory.ok(renderer, Caching.ONE_DAY));
}
@Override
-// @GET
-// @Path("/{domainType}/type-actions/isSupertypeOf/invoke")
-// @Produces({
-// MediaType.APPLICATION_JSON,
-// RestfulMediaType.APPLICATION_JSON_TYPE_ACTION_RESULT,
-// RestfulMediaType.APPLICATION_JSON_ERROR })
- public Response domainTypeIsSupertypeOf(
- @PathParam("domainType") final String domainType,
- @QueryParam("subtype") final String subTypeStr, // simple style
- @QueryParam("args") final String argsUrlEncoded // formal style
+ public ResponseEntity<Object> domainTypeIsSupertypeOf(
+ final String domainType,
+ final String subTypeStr, // simple style
+ final String argsUrlEncoded // formal style
) {
var resourceContext = createResourceContext(new ResourceDescriptor(
@@ -361,7 +289,7 @@ public Response domainTypeIsSupertypeOf(
if (domainTypeSpec == null
|| subtypeSpec == null) {
throw _EndpointLogging.error(log, "GET /domain-types/{}/type-actions/isSupertypeOf/invoke", domainType,
- RestfulObjectsApplicationException.create(HttpStatusCode.NOT_FOUND));
+ RestfulObjectsApplicationException.create(HttpStatus.NOT_FOUND));
}
final TypeActionResultReprRenderer renderer = new TypeActionResultReprRenderer(resourceContext, null, JsonRepresentation.newMap());
@@ -375,7 +303,7 @@ public Response domainTypeIsSupertypeOf(
renderer.with(domainTypeSpec).withSelf(selfLink).withValue(value);
return _EndpointLogging.response(log, "GET /domain-types/{}/type-actions/isSupertypeOf/invoke", domainType,
- Responses.ofOk(renderer, Caching.ONE_DAY).build());
+ responseFactory.ok(renderer, Caching.ONE_DAY));
}
private static String domainTypeFor(
@@ -402,7 +330,7 @@ private static String linkFromFormalArgs(
final JsonRepresentation arguments = requestParams.asMap();
if (!arguments.isLink(paramId)) {
throw onRoException.apply(RestfulObjectsApplicationException
- .createWithMessage(HttpStatusCode.BAD_REQUEST, "Args should contain a link '%s'", paramId));
+ .createWithMessage(HttpStatus.BAD_REQUEST, "Args should contain a link '%s'".formatted(paramId)));
}
return arguments.getLink(paramId).getHref();
diff --git a/viewers/restfulobjects/viewer/src/main/java/org/apache/causeway/viewer/restfulobjects/viewer/resources/HomePageResourceServerside.java b/viewers/restfulobjects/viewer/src/main/java/org/apache/causeway/viewer/restfulobjects/viewer/resources/HomePageResourceServerside.java
index eee5ed6cc35..037249ba811 100644
--- a/viewers/restfulobjects/viewer/src/main/java/org/apache/causeway/viewer/restfulobjects/viewer/resources/HomePageResourceServerside.java
+++ b/viewers/restfulobjects/viewer/src/main/java/org/apache/causeway/viewer/restfulobjects/viewer/resources/HomePageResourceServerside.java
@@ -18,18 +18,15 @@
*/
package org.apache.causeway.viewer.restfulobjects.viewer.resources;
-import jakarta.ws.rs.core.Response;
-
+import org.springframework.http.HttpStatus;
+import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.RestController;
import org.apache.causeway.applib.annotation.Where;
import org.apache.causeway.viewer.restfulobjects.applib.JsonRepresentation;
import org.apache.causeway.viewer.restfulobjects.applib.RepresentationType;
-import org.apache.causeway.viewer.restfulobjects.applib.RestfulResponse;
-import org.apache.causeway.viewer.restfulobjects.applib.RestfulResponse.HttpStatusCode;
import org.apache.causeway.viewer.restfulobjects.applib.homepage.HomePageResource;
import org.apache.causeway.viewer.restfulobjects.rendering.Caching;
-import org.apache.causeway.viewer.restfulobjects.rendering.Responses;
import org.apache.causeway.viewer.restfulobjects.rendering.RestfulObjectsApplicationException;
import org.apache.causeway.viewer.restfulobjects.rendering.service.RepresentationService;
@@ -47,10 +44,7 @@ public HomePageResourceServerside() {
}
@Override
-// @Produces({
-// MediaType.APPLICATION_JSON,
-// RestfulMediaType.APPLICATION_JSON_HOME_PAGE })
- public Response homePage() {
+ public ResponseEntity<Object> homePage() {
var resourceContext = createResourceContext(
RepresentationType.HOME_PAGE, Where.NOWHERE, RepresentationService.Intent.NOT_APPLICABLE);
@@ -59,43 +53,40 @@ public Response homePage() {
homePageReprRenderer.includesSelf();
return _EndpointLogging.response(log, "GET /",
- Responses.ofOk(homePageReprRenderer, Caching.ONE_DAY).build());
+ responseFactory.ok(homePageReprRenderer, Caching.ONE_DAY));
}
@Override
- public Response deleteHomePageNotAllowed() {
+ public ResponseEntity<Object> deleteHomePageNotAllowed() {
throw _EndpointLogging.error(log, "DELETE /",
RestfulObjectsApplicationException
.createWithMessage(
- RestfulResponse.HttpStatusCode.METHOD_NOT_ALLOWED,
+ HttpStatus.METHOD_NOT_ALLOWED,
"Deleting the home page resource is not allowed."));
}
@Override
- public Response putHomePageNotAllowed() {
+ public ResponseEntity<Object> putHomePageNotAllowed() {
throw _EndpointLogging.error(log, "PUT /",
RestfulObjectsApplicationException
.createWithMessage(
- RestfulResponse.HttpStatusCode.METHOD_NOT_ALLOWED,
+ HttpStatus.METHOD_NOT_ALLOWED,
"Putting to the home page resource is not allowed."));
}
@Override
- public Response postHomePageNotAllowed() {
+ public ResponseEntity<Object> postHomePageNotAllowed() {
throw _EndpointLogging.error(log, "POST /",
RestfulObjectsApplicationException
.createWithMessage(
- RestfulResponse.HttpStatusCode.METHOD_NOT_ALLOWED,
+ HttpStatus.METHOD_NOT_ALLOWED,
"Posting to the home page resource is not allowed."));
}
@Override
-// @GET
-// @Path("/notAuthenticated")
-// @Produces({ MediaType.APPLICATION_JSON })
- public Response notAuthenticated() {
+ public ResponseEntity<Object> notAuthenticated() {
throw _EndpointLogging.error(log, "GET /notAuthenticated",
- RestfulObjectsApplicationException.create(HttpStatusCode.UNAUTHORIZED));
+ RestfulObjectsApplicationException.create(HttpStatus.UNAUTHORIZED));
}
}
diff --git a/viewers/restfulobjects/viewer/src/main/java/org/apache/causeway/viewer/restfulobjects/viewer/resources/ImageResourceServerside.java b/viewers/restfulobjects/viewer/src/main/java/org/apache/causeway/viewer/restfulobjects/viewer/resources/ImageResourceServerside.java
deleted file mode 100644
index 0bc8a41964f..00000000000
--- a/viewers/restfulobjects/viewer/src/main/java/org/apache/causeway/viewer/restfulobjects/viewer/resources/ImageResourceServerside.java
+++ /dev/null
@@ -1,62 +0,0 @@
-/*
- * 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.causeway.viewer.restfulobjects.viewer.resources;
-
-import java.io.IOException;
-import java.io.InputStream;
-
-import jakarta.ws.rs.GET;
-import jakarta.ws.rs.Path;
-import jakarta.ws.rs.Produces;
-import jakarta.ws.rs.core.Response;
-
-import org.springframework.stereotype.Component;
-
-import org.apache.causeway.commons.internal.base._Bytes;
-import org.apache.causeway.commons.internal.resources._Resources;
-
-import lombok.extern.slf4j.Slf4j;
-
-@Component
-@Path("/image")
-@Slf4j
-public class ImageResourceServerside extends ResourceAbstract {
-
- public ImageResourceServerside() {
- super();
- log.debug("<init>");
- }
-
- @GET
- @Path("/")
- @Produces("image/png")
- public Response image() throws IOException {
-
- final InputStream resource = _Resources.load(getClass(), "SimpleObject.png");
- final byte[] bytes = _Bytes.of(resource);
-
- // Response.ResponseBuilder response = Response.ok(file);
- // response.header("Content-Disposition",
- // "attachment; filename=SimpleObject.png");
- // return response.build();
-
- return _EndpointLogging.response(log, "GET /image",
- Response.ok(bytes).build());
- }
-}
diff --git a/viewers/restfulobjects/viewer/src/main/java/org/apache/causeway/viewer/restfulobjects/viewer/resources/InteractionFailureHandler.java b/viewers/restfulobjects/viewer/src/main/java/org/apache/causeway/viewer/restfulobjects/viewer/resources/InteractionFailureHandler.java
index 80e201068d5..6b07fb1cc74 100644
--- a/viewers/restfulobjects/viewer/src/main/java/org/apache/causeway/viewer/restfulobjects/viewer/resources/InteractionFailureHandler.java
+++ b/viewers/restfulobjects/viewer/src/main/java/org/apache/causeway/viewer/restfulobjects/viewer/resources/InteractionFailureHandler.java
@@ -20,10 +20,11 @@
import org.jspecify.annotations.Nullable;
+import org.springframework.http.HttpStatus;
+
import org.apache.causeway.core.metamodel.interactions.managed.InteractionVeto;
import org.apache.causeway.core.metamodel.spec.feature.ObjectActionParameter;
import org.apache.causeway.viewer.restfulobjects.applib.JsonRepresentation;
-import org.apache.causeway.viewer.restfulobjects.applib.RestfulResponse;
import org.apache.causeway.viewer.restfulobjects.rendering.RestfulObjectsApplicationException;
import org.jspecify.annotations.NonNull;
@@ -35,7 +36,7 @@ public static RestfulObjectsApplicationException onFailure(
if(veto==null) {
return RestfulObjectsApplicationException
- .createWithMessage(RestfulResponse.HttpStatusCode.INTERNAL_SERVER_ERROR,
+ .createWithMessage(HttpStatus.INTERNAL_SERVER_ERROR,
"unexpected empty failure holder");
}
@@ -43,29 +44,29 @@ public static RestfulObjectsApplicationException onFailure(
case NOT_FOUND:
case HIDDEN:
return RestfulObjectsApplicationException
- .createWithMessage(RestfulResponse.HttpStatusCode.NOT_FOUND,
+ .createWithMessage(HttpStatus.NOT_FOUND,
veto.getReasonAsString().orElse(null));
case READONLY:
case INVALID:
return RestfulObjectsApplicationException
- .createWithMessage(RestfulResponse.HttpStatusCode.FORBIDDEN,
+ .createWithMessage(HttpStatus.FORBIDDEN,
veto.getReasonAsString().orElse(null));
case ACTION_NOT_SAFE:
case ACTION_NOT_IDEMPOTENT:
return RestfulObjectsApplicationException
- .createWithMessage(RestfulResponse.HttpStatusCode.METHOD_NOT_ALLOWED,
+ .createWithMessage(HttpStatus.METHOD_NOT_ALLOWED,
veto.getReasonAsString().orElse(null));
case ACTION_PARAM_INVALID:
return RestfulObjectsApplicationException
- .createWithMessage(RestfulResponse.HttpStatusCode.VALIDATION_FAILED,
+ .createWithMessage(HttpStatus.UNPROCESSABLE_ENTITY,
veto.getReasonAsString().orElse(null));
}
return RestfulObjectsApplicationException
- .createWithMessage(RestfulResponse.HttpStatusCode.INTERNAL_SERVER_ERROR,
+ .createWithMessage(HttpStatus.INTERNAL_SERVER_ERROR,
"unmatched veto type " + veto.vetoType());
}
@@ -78,7 +79,7 @@ public static RestfulObjectsApplicationException onParameterListInvalid(
arguments.mapPutString("x-ro-invalidReason", veto.getReasonAsString().orElse(null));
}
return RestfulObjectsApplicationException
- .createWithBody(RestfulResponse.HttpStatusCode.VALIDATION_FAILED,
+ .createWithBody(HttpStatus.UNPROCESSABLE_ENTITY,
arguments,
"Validation failed, see body for details");
}
diff --git a/viewers/restfulobjects/viewer/src/main/java/org/apache/causeway/viewer/restfulobjects/viewer/resources/JsonParserHelper.java b/viewers/restfulobjects/viewer/src/main/java/org/apache/causeway/viewer/restfulobjects/viewer/resources/JsonParserHelper.java
index ef1af167bfb..4233b3dbebc 100644
--- a/viewers/restfulobjects/viewer/src/main/java/org/apache/causeway/viewer/restfulobjects/viewer/resources/JsonParserHelper.java
+++ b/viewers/restfulobjects/viewer/src/main/java/org/apache/causeway/viewer/restfulobjects/viewer/resources/JsonParserHelper.java
@@ -21,11 +21,12 @@
import java.util.regex.Matcher;
import java.util.regex.Pattern;
+import org.springframework.http.HttpStatus;
+
import org.apache.causeway.applib.services.bookmark.Bookmark;
import org.apache.causeway.core.metamodel.object.ManagedObject;
import org.apache.causeway.core.metamodel.spec.ObjectSpecification;
import org.apache.causeway.viewer.restfulobjects.applib.JsonRepresentation;
-import org.apache.causeway.viewer.restfulobjects.applib.RestfulResponse;
import org.apache.causeway.viewer.restfulobjects.rendering.IResourceContext;
import org.apache.causeway.viewer.restfulobjects.rendering.RestfulObjectsApplicationException;
import org.apache.causeway.viewer.restfulobjects.rendering.service.valuerender.JsonValueEncoderService;
@@ -64,7 +65,8 @@ ManagedObject parseAsMapWithSingleValue(final RequestParams body) {
ManagedObject parseAsMapWithSingleValue(final JsonRepresentation arguments) {
final JsonRepresentation representation = arguments.getRepresentation("value");
if (arguments.size() != 1 || representation == null) {
- throw RestfulObjectsApplicationException.createWithMessage(RestfulResponse.HttpStatusCode.BAD_REQUEST, "Body should be a map with a single key 'value' whose value represents an instance of type '%s'", resourceFor(objectSpec));
+ throw RestfulObjectsApplicationException.createWithMessage(HttpStatus.BAD_REQUEST,
+ "Body should be a map with a single key 'value' whose value represents an instance of type '%s'".formatted(resourceFor(objectSpec)));
}
return objectAdapterFor(arguments);
diff --git a/viewers/restfulobjects/viewer/src/main/java/org/apache/causeway/viewer/restfulobjects/viewer/resources/MenuBarsResourceServerside.java b/viewers/restfulobjects/viewer/src/main/java/org/apache/causeway/viewer/restfulobjects/viewer/resources/MenuBarsResourceServerside.java
index d9e5f5a2d5f..ffbc8d58159 100644
--- a/viewers/restfulobjects/viewer/src/main/java/org/apache/causeway/viewer/restfulobjects/viewer/resources/MenuBarsResourceServerside.java
+++ b/viewers/restfulobjects/viewer/src/main/java/org/apache/causeway/viewer/restfulobjects/viewer/resources/MenuBarsResourceServerside.java
@@ -21,11 +21,10 @@
import java.util.function.Consumer;
import jakarta.ws.rs.HttpMethod;
-import jakarta.ws.rs.Produces;
-import org.springframework.http.MediaType;
-import jakarta.ws.rs.core.Response;
-import org.springframework.stereotype.Component;
+import org.springframework.http.HttpStatus;
+import org.springframework.http.ResponseEntity;
+import org.springframework.web.bind.annotation.RestController;
import org.apache.causeway.applib.annotation.Where;
import org.apache.causeway.applib.layout.component.ServiceActionLayoutData;
@@ -34,16 +33,17 @@
import org.apache.causeway.applib.services.menu.MenuBarsService;
import org.apache.causeway.viewer.restfulobjects.applib.Rel;
import org.apache.causeway.viewer.restfulobjects.applib.RepresentationType;
-import org.apache.causeway.viewer.restfulobjects.applib.RestfulMediaType;
-import org.apache.causeway.viewer.restfulobjects.applib.RestfulResponse;
import org.apache.causeway.viewer.restfulobjects.applib.menubars.MenuBarsResource;
-import org.apache.causeway.viewer.restfulobjects.applib.util.MediaTypes;
import org.apache.causeway.viewer.restfulobjects.rendering.RestfulObjectsApplicationException;
import org.apache.causeway.viewer.restfulobjects.rendering.service.RepresentationService;
import org.apache.causeway.viewer.restfulobjects.viewer.context.ResourceContext;
-@Component
-public class MenuBarsResourceServerside extends ResourceAbstract implements MenuBarsResource {
+import lombok.extern.slf4j.Slf4j;
+
+@RestController
+@Slf4j
+public class MenuBarsResourceServerside extends ResourceAbstract
+implements MenuBarsResource {
public static final String SERVICE_IDENTIFIER = "1";
@@ -52,11 +52,7 @@ public MenuBarsResourceServerside() {
}
@Override
- @Produces({
- MediaType.APPLICATION_JSON_VALUE, RestfulMediaType.APPLICATION_JSON_LAYOUT_MENUBARS,
- MediaType.APPLICATION_XML_VALUE, RestfulMediaType.APPLICATION_XML_LAYOUT_MENUBARS
- })
- public Response menuBars() {
+ public ResponseEntity<Object> menuBars() {
var resourceContext = createResourceContext(
RepresentationType.MENUBARS, Where.ANYWHERE, RepresentationService.Intent.NOT_APPLICABLE);
@@ -64,15 +60,14 @@ public Response menuBars() {
var serializationStrategy = resourceContext.getSerializationStrategy();
var menuBarsService = metaModelContext.getServiceRegistry().lookupServiceElseFail(MenuBarsService.class);
- final Response.ResponseBuilder builder;
final MenuBars menuBars = menuBarsService.menuBars();
addLinksForServiceActions(resourceContext, menuBars);
- builder = Response.status(Response.Status.OK)
- .entity(serializationStrategy.entity(menuBars))
- .type(MediaTypes.toJakarta(serializationStrategy.type(RepresentationType.MENUBARS)));
+ var response = responseFactory.ok(
+ serializationStrategy.entity(menuBars),
+ serializationStrategy.type(RepresentationType.MENUBARS));
- return builder.build();
+ return _EndpointLogging.response(log, "GET /menuBars", response);
}
void addLinksForServiceActions(final ResourceContext resourceContext, final MenuBars menuBars) {
@@ -97,20 +92,18 @@ public static Consumer<ServiceActionLayoutData> linksForServiceActionsAddingVisi
}
@Override
- public Response deleteMenuBarsNotAllowed() {
- throw RestfulObjectsApplicationException.createWithMessage(RestfulResponse.HttpStatusCode.METHOD_NOT_ALLOWED, "Deleting the menuBars resource is not allowed.");
-
+ public ResponseEntity<Object> deleteMenuBarsNotAllowed() {
+ throw RestfulObjectsApplicationException.createWithMessage(HttpStatus.METHOD_NOT_ALLOWED, "Deleting the menuBars resource is not allowed.");
}
@Override
- public Response putMenuBarsNotAllowed() {
- throw RestfulObjectsApplicationException.createWithMessage(RestfulResponse.HttpStatusCode.METHOD_NOT_ALLOWED, "Putting to the menuBars resource is not allowed.");
-
+ public ResponseEntity<Object> putMenuBarsNotAllowed() {
+ throw RestfulObjectsApplicationException.createWithMessage(HttpStatus.METHOD_NOT_ALLOWED, "Putting to the menuBars resource is not allowed.");
}
@Override
- public Response postMenuBarsNotAllowed() {
- throw RestfulObjectsApplicationException.createWithMessage(RestfulResponse.HttpStatusCode.METHOD_NOT_ALLOWED, "Posting to the menuBars resource is not allowed.");
+ public ResponseEntity<Object> postMenuBarsNotAllowed() {
+ throw RestfulObjectsApplicationException.createWithMessage(HttpStatus.METHOD_NOT_ALLOWED, "Posting to the menuBars resource is not allowed.");
}
}
diff --git a/viewers/restfulobjects/viewer/src/main/java/org/apache/causeway/viewer/restfulobjects/viewer/resources/ObjectActionArgHelper.java b/viewers/restfulobjects/viewer/src/main/java/org/apache/causeway/viewer/restfulobjects/viewer/resources/ObjectActionArgHelper.java
index 21195ebbb84..e04036f067b 100644
--- a/viewers/restfulobjects/viewer/src/main/java/org/apache/causeway/viewer/restfulobjects/viewer/resources/ObjectActionArgHelper.java
+++ b/viewers/restfulobjects/viewer/src/main/java/org/apache/causeway/viewer/restfulobjects/viewer/resources/ObjectActionArgHelper.java
@@ -22,6 +22,8 @@
import java.util.Map;
import java.util.stream.IntStream;
+import org.springframework.http.HttpStatus;
+
import org.apache.causeway.commons.collections.Can;
import org.apache.causeway.commons.functional.Railway;
import org.apache.causeway.commons.functional.Try;
@@ -31,7 +33,6 @@
import org.apache.causeway.core.metamodel.spec.feature.ObjectAction;
import org.apache.causeway.core.metamodel.spec.feature.ObjectActionParameter;
import org.apache.causeway.viewer.restfulobjects.applib.JsonRepresentation;
-import org.apache.causeway.viewer.restfulobjects.applib.RestfulResponse;
import org.apache.causeway.viewer.restfulobjects.rendering.IResourceContext;
import org.apache.causeway.viewer.restfulobjects.rendering.RestfulObjectsApplicationException;
@@ -93,7 +94,7 @@ private static List<JsonRepresentation> argListFor(
String reason = String.format("Argument '%s' found but no such parameter", argName);
arguments.mapPutString("x-ro-invalidReason", reason);
throw RestfulObjectsApplicationException
- .createWithBody(RestfulResponse.HttpStatusCode.BAD_REQUEST, arguments, reason);
+ .createWithBody(HttpStatus.BAD_REQUEST, arguments, reason);
}
});
@@ -109,7 +110,7 @@ private static List<JsonRepresentation> argListFor(
var reason = String.format("No argument found for (mandatory) parameter '%s'", paramId);
arguments.mapPutString("x-ro-invalidReason", reason);
throw RestfulObjectsApplicationException
- .createWithBody(RestfulResponse.HttpStatusCode.BAD_REQUEST, arguments, reason);
+ .createWithBody(HttpStatus.BAD_REQUEST, arguments, reason);
}
argList.add(argRepr);
}
diff --git a/viewers/restfulobjects/viewer/src/main/java/org/apache/causeway/viewer/restfulobjects/viewer/resources/ResourceAbstract.java b/viewers/restfulobjects/viewer/src/main/java/org/apache/causeway/viewer/restfulobjects/viewer/resources/ResourceAbstract.java
index 9b30f26c6bd..b911be2583d 100644
--- a/viewers/restfulobjects/viewer/src/main/java/org/apache/causeway/viewer/restfulobjects/viewer/resources/ResourceAbstract.java
+++ b/viewers/restfulobjects/viewer/src/main/java/org/apache/causeway/viewer/restfulobjects/viewer/resources/ResourceAbstract.java
@@ -19,15 +19,18 @@
package org.apache.causeway.viewer.restfulobjects.viewer.resources;
import java.io.InputStream;
+import java.net.URL;
import java.util.Map;
import java.util.function.UnaryOperator;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
+
import org.jspecify.annotations.NonNull;
import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.web.context.request.ServletWebRequest;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.http.HttpStatus;
import org.apache.causeway.applib.annotation.Where;
import org.apache.causeway.applib.services.bookmark.Bookmark;
@@ -42,7 +45,7 @@
import org.apache.causeway.core.metamodel.object.ManagedObject;
import org.apache.causeway.core.metamodel.object.ManagedObjects;
import org.apache.causeway.viewer.restfulobjects.applib.RepresentationType;
-import org.apache.causeway.viewer.restfulobjects.applib.RestfulResponse.HttpStatusCode;
+import org.apache.causeway.viewer.restfulobjects.rendering.ResponseFactory;
import org.apache.causeway.viewer.restfulobjects.rendering.RestfulObjectsApplicationException;
import org.apache.causeway.viewer.restfulobjects.rendering.UrlDecoderUtils;
import org.apache.causeway.viewer.restfulobjects.rendering.service.RepresentationService;
@@ -51,6 +54,7 @@
import org.apache.causeway.viewer.restfulobjects.viewer.resources.ResourceDescriptor.ResourceLink;
import lombok.Getter;
+import lombok.SneakyThrows;
public abstract class ResourceAbstract
implements HasMetaModelContext {
@@ -58,11 +62,11 @@ public abstract class ResourceAbstract
@Getter(onMethod_={@Override})
@Autowired protected MetaModelContext metaModelContext;
@Autowired protected WebAppContextPath webAppContextPath;
+ @Autowired protected ResponseFactory responseFactory;
- @Autowired ServletWebRequest servletWebRequest;
-
- @Deprecated @Autowired HttpServletRequest httpServletRequest;
- @Deprecated @Autowired HttpServletResponse httpServletResponse;
+ @Autowired protected HttpServletRequest httpServletRequest;
+ @Autowired protected HttpServletResponse httpServletResponse;
+ @Value("${causeway.viewer.restfulobjects.path-prefix}") String restfulPath;
protected ResourceAbstract() {
}
@@ -94,18 +98,17 @@ protected ResourceContext createResourceContext(
final RequestParams requestParams) {
if (!getInteractionService().isInInteraction()) {
- throw RestfulObjectsApplicationException.create(HttpStatusCode.UNAUTHORIZED);
+ throw RestfulObjectsApplicationException.create(HttpStatus.UNAUTHORIZED);
}
- var reqUrl = servletWebRequest.getRequest().getRequestURL().toString();
+ var requestUrl = parseUrl(httpServletRequest.getRequestURL().toString());
// eg. http://localhost:8080/ctx/restful/
final String restfulAbsoluteBase = getConfiguration().getViewer().getRestfulobjects().getBaseUri()
- //.orElseGet(()->uriInfo.getBaseUri().toString()) //FIXME[causeway-viewer-restfulobjects-viewer-CAUSEWAY-3892]
- .orElseGet(()->"TODO");
+ .orElseGet(()->restfulAbsoluteBase(requestUrl));
// eg. /ctx/restful/
- var restfulRelativeBase = "TODO"; //uriInfo.getBaseUri().getRawPath();
+ var restfulRelativeBase = requestUrl.getPath();
// eg. http://localhost:8080/
var serverAbsoluteBase =
@@ -148,13 +151,24 @@ protected ManagedObject getObjectAdapterElseThrowNotFound(
.filter(_Predicates.not(ManagedObjects::isNullOrUnspecifiedOrEmpty))
.orElseThrow(()->onRoException.apply(
RestfulObjectsApplicationException
- .createWithMessage(HttpStatusCode.NOT_FOUND,
- "Could not determine adapter for bookmark: '%s'",
- bookmark)));
+ .createWithMessage(HttpStatus.NOT_FOUND,
+ "Could not determine adapter for bookmark: '%s'".formatted(bookmark))));
}
// -- HELPER
+ @SneakyThrows
+ private URL parseUrl(String url) {
+ return new URL(url);
+ }
+
+ /** if not configured can be re-constructed */
+ @SneakyThrows
+ private String restfulAbsoluteBase(URL requestUrl) {
+ var base = webAppContextPath.prependContextPath(restfulPath);
+ return new URL(requestUrl.getProtocol(), requestUrl.getHost(), requestUrl.getPort(), base).toExternalForm();
+ }
+
private String getUrlDecodedQueryStringIfAny() {
final String queryStringIfAny = httpServletRequest.getQueryString();
return UrlUtils.urlDecodeUtf8(queryStringIfAny);
diff --git a/viewers/restfulobjects/viewer/src/main/java/org/apache/causeway/viewer/restfulobjects/viewer/resources/SwaggerSpecResource.java b/viewers/restfulobjects/viewer/src/main/java/org/apache/causeway/viewer/restfulobjects/viewer/resources/SwaggerSpecResource.java
index 0be6c03517c..3317a8364da 100644
--- a/viewers/restfulobjects/viewer/src/main/java/org/apache/causeway/viewer/restfulobjects/viewer/resources/SwaggerSpecResource.java
+++ b/viewers/restfulobjects/viewer/src/main/java/org/apache/causeway/viewer/restfulobjects/viewer/resources/SwaggerSpecResource.java
@@ -22,16 +22,12 @@
import jakarta.inject.Inject;
import jakarta.servlet.http.HttpServletRequest;
-import jakarta.ws.rs.GET;
-import jakarta.ws.rs.Path;
-import jakarta.ws.rs.Produces;
-import jakarta.ws.rs.core.Context;
-import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
-
-import org.springframework.stereotype.Component;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
import org.apache.causeway.applib.services.iactnlayer.InteractionService;
import org.apache.causeway.applib.services.swagger.Format;
@@ -40,54 +36,39 @@
import lombok.extern.slf4j.Slf4j;
-@Component
-@Path("/swagger")
+@RestController
+@RequestMapping("${causeway.viewer.restfulobjects.path-prefix}/swagger")
@Slf4j
public class SwaggerSpecResource {
private final SwaggerService swaggerService;
private final InteractionService interactionService;
-
- @Autowired HttpHeaders httpHeaders;
- @Autowired HttpServletRequest httpServletRequest;
+ private final HttpServletRequest httpServletRequest;
@Inject
public SwaggerSpecResource(
- final @Context SwaggerService swaggerService,
- final @Context InteractionService interactionService) {
+ final SwaggerService swaggerService,
+ final InteractionService interactionService,
+ final HttpServletRequest httpServletRequest) {
this.swaggerService = swaggerService;
this.interactionService = interactionService;
+ this.httpServletRequest = httpServletRequest;
log.debug("<init>");
}
- @Path("/private")
- @GET
- //@Consumes({ MediaType.WILDCARD, MediaType.APPLICATION_JSON, "text/yaml" })
- @Produces({
- MediaType.APPLICATION_JSON_VALUE, "text/yaml"
- })
+ @GetMapping(path = "/private", produces = {MediaType.APPLICATION_JSON_VALUE, "text/yaml"})
public String swaggerPrivate() {
return _EndpointLogging.stringResponse(log, "GET /swagger/private",
swagger(Visibility.PRIVATE));
}
- @Path("/prototyping")
- @GET
- //@Consumes({ MediaType.WILDCARD, MediaType.APPLICATION_JSON_VALUE, "text/yaml" })
- @Produces({
- MediaType.APPLICATION_JSON_VALUE, "text/yaml"
- })
+ @GetMapping(path = "/prototyping", produces = {MediaType.APPLICATION_JSON_VALUE, "text/yaml"})
public String swaggerPrototyping() {
return _EndpointLogging.stringResponse(log, "GET /swagger/prototyping",
swagger(Visibility.PRIVATE_WITH_PROTOTYPING));
}
- @Path("/public")
- @GET
- //@Consumes({ MediaType.WILDCARD, MediaType.APPLICATION_JSON_VALUE, "text/yaml" })
- @Produces({
- MediaType.APPLICATION_JSON_VALUE, "text/yaml"
- })
+ @GetMapping(path = "/public", produces = {MediaType.APPLICATION_JSON_VALUE, "text/yaml"})
public String swaggerPublic() {
return _EndpointLogging.stringResponse(log, "GET /swagger/public",
swagger(Visibility.PUBLIC));
@@ -96,16 +77,13 @@ public String swaggerPublic() {
// -- HELPER
private String swagger(final Visibility visibility) {
-
- var format = deriveFrom(httpHeaders);
- var callable = new MyCallable(swaggerService, visibility, format);
-
+ var callable = new MyCallable(swaggerService, visibility, formatFromRequest());
var spec = interactionService.callAnonymous(callable);
return spec;
}
- private Format deriveFrom(final HttpHeaders httpHeaders) {
- var acceptableMediaTypes = httpHeaders.getAccept();
+ private Format formatFromRequest() {
+ var acceptableMediaTypes = MediaType.parseMediaTypes(httpServletRequest.getHeader(HttpHeaders.ACCEPT));
for (MediaType acceptableMediaType : acceptableMediaTypes) {
if(acceptableMediaType.isCompatibleWith(MediaType.APPLICATION_JSON)) {
return Format.JSON;
diff --git a/viewers/restfulobjects/viewer/src/main/java/org/apache/causeway/viewer/restfulobjects/viewer/resources/UserResourceServerside.java b/viewers/restfulobjects/viewer/src/main/java/org/apache/causeway/viewer/restfulobjects/viewer/resources/UserResourceServerside.java
index cd9a4446cf9..04c09eb5628 100644
--- a/viewers/restfulobjects/viewer/src/main/java/org/apache/causeway/viewer/restfulobjects/viewer/resources/UserResourceServerside.java
+++ b/viewers/restfulobjects/viewer/src/main/java/org/apache/causeway/viewer/restfulobjects/viewer/resources/UserResourceServerside.java
@@ -19,32 +19,29 @@
package org.apache.causeway.viewer.restfulobjects.viewer.resources;
import java.net.URI;
-import java.net.URISyntaxException;
-import jakarta.ws.rs.Produces;
-import org.springframework.http.MediaType;
-import jakarta.ws.rs.core.Response;
-
-import org.springframework.stereotype.Component;
+import org.springframework.http.HttpStatus;
+import org.springframework.http.ResponseEntity;
+import org.springframework.web.bind.annotation.RestController;
import org.apache.causeway.applib.annotation.Where;
import org.apache.causeway.viewer.restfulobjects.applib.JsonRepresentation;
import org.apache.causeway.viewer.restfulobjects.applib.RepresentationType;
-import org.apache.causeway.viewer.restfulobjects.applib.RestfulMediaType;
-import org.apache.causeway.viewer.restfulobjects.applib.RestfulResponse;
import org.apache.causeway.viewer.restfulobjects.applib.user.UserResource;
import org.apache.causeway.viewer.restfulobjects.rendering.Caching;
-import org.apache.causeway.viewer.restfulobjects.rendering.Responses;
+import org.apache.causeway.viewer.restfulobjects.rendering.ResponseFactory;
import org.apache.causeway.viewer.restfulobjects.rendering.RestfulObjectsApplicationException;
import org.apache.causeway.viewer.restfulobjects.rendering.service.RepresentationService;
import org.apache.causeway.viewer.restfulobjects.viewer.context.ResourceContext;
import org.apache.causeway.viewer.restfulobjects.viewer.webmodule.CausewayRestfulObjectsInteractionFilter;
+import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
-@Component
+@RestController
@Slf4j
-public class UserResourceServerside extends ResourceAbstract implements UserResource {
+public class UserResourceServerside extends ResourceAbstract
+implements UserResource {
public UserResourceServerside() {
super();
@@ -52,8 +49,7 @@ public UserResourceServerside() {
}
@Override
- @Produces({ MediaType.APPLICATION_JSON_VALUE, RestfulMediaType.APPLICATION_JSON_USER })
- public Response user() {
+ public ResponseEntity<Object> user() {
var resourceContext = createResourceContext(
RepresentationType.USER, Where.NOWHERE, RepresentationService.Intent.NOT_APPLICABLE);
@@ -61,32 +57,32 @@ public Response user() {
final UserReprRenderer renderer = new UserReprRenderer(resourceContext, null, JsonRepresentation.newMap());
renderer.includesSelf().with(resourceContext.getInteractionService().currentInteractionContextElseFail());
- return Responses.ofOk(renderer, Caching.ONE_HOUR).build();
+ return _EndpointLogging.response(log, "GET /user", responseFactory.ok(renderer, Caching.ONE_HOUR));
}
@Override
- public Response deleteUserNotAllowed() {
- throw RestfulObjectsApplicationException.createWithMessage(RestfulResponse.HttpStatusCode.METHOD_NOT_ALLOWED, "Deleting the user resource is not allowed.");
+ public ResponseEntity<Object> deleteUserNotAllowed() {
+ throw RestfulObjectsApplicationException.createWithMessage(HttpStatus.METHOD_NOT_ALLOWED, "Deleting the user resource is not allowed.");
}
@Override
- public Response putUserNotAllowed() {
- throw RestfulObjectsApplicationException.createWithMessage(RestfulResponse.HttpStatusCode.METHOD_NOT_ALLOWED, "Putting to the user resource is not allowed.");
+ public ResponseEntity<Object> putUserNotAllowed() {
+ throw RestfulObjectsApplicationException.createWithMessage(HttpStatus.METHOD_NOT_ALLOWED, "Putting to the user resource is not allowed.");
}
@Override
- public Response postUserNotAllowed() {
- throw RestfulObjectsApplicationException.createWithMessage(RestfulResponse.HttpStatusCode.METHOD_NOT_ALLOWED, "Posting to the user resource is not allowed.");
+ public ResponseEntity<Object> postUserNotAllowed() {
+ throw RestfulObjectsApplicationException.createWithMessage(HttpStatus.METHOD_NOT_ALLOWED, "Posting to the user resource is not allowed.");
}
/**
* Not part of the Restful Objects spec.
*/
@Override
- @Produces({ MediaType.APPLICATION_JSON_VALUE, RestfulMediaType.APPLICATION_JSON_HOME_PAGE })
- public Response logout() {
+ @SneakyThrows
+ public ResponseEntity<Object> logout() {
var resourceContext = createResourceContext(
RepresentationType.HOME_PAGE, Where.NOWHERE, RepresentationService.Intent.NOT_APPLICABLE);
@@ -98,12 +94,9 @@ public Response logout() {
// we also redirect to home page with special query string; this allows the session filter
// to clear out any cookies/headers (eg if BASIC auth in use).
- try {
- final URI location = new URI("?" + CausewayRestfulObjectsInteractionFilter.CAUSEWAY_SESSION_FILTER_QUERY_STRING_FORCE_LOGOUT);
- return Response.temporaryRedirect(location).build();
- } catch (URISyntaxException e) {
- throw new RuntimeException(e);
- }
+
+ final URI location = new URI("?" + CausewayRestfulObjectsInteractionFilter.CAUSEWAY_SESSION_FILTER_QUERY_STRING_FORCE_LOGOUT);
+ return _EndpointLogging.response(log, "GET /user/logout", ResponseFactory.temporaryRedirect(location));
}
private void logout(final ResourceContext resourceContext) {
diff --git a/viewers/restfulobjects/viewer/src/main/java/org/apache/causeway/viewer/restfulobjects/viewer/resources/VersionResourceServerside.java b/viewers/restfulobjects/viewer/src/main/java/org/apache/causeway/viewer/restfulobjects/viewer/resources/VersionResourceServerside.java
index c46b78dc9b7..bf292d3cd19 100644
--- a/viewers/restfulobjects/viewer/src/main/java/org/apache/causeway/viewer/restfulobjects/viewer/resources/VersionResourceServerside.java
+++ b/viewers/restfulobjects/viewer/src/main/java/org/apache/causeway/viewer/restfulobjects/viewer/resources/VersionResourceServerside.java
@@ -21,32 +21,23 @@
import java.util.List;
import jakarta.inject.Inject;
-import jakarta.ws.rs.Path;
-import jakarta.ws.rs.core.Response;
-import org.springframework.stereotype.Component;
+import org.springframework.http.HttpStatus;
+import org.springframework.http.ResponseEntity;
+import org.springframework.web.bind.annotation.RestController;
import org.apache.causeway.applib.annotation.Where;
import org.apache.causeway.viewer.restfulobjects.applib.JsonRepresentation;
import org.apache.causeway.viewer.restfulobjects.applib.RepresentationType;
-import org.apache.causeway.viewer.restfulobjects.applib.RestfulResponse;
-import org.apache.causeway.viewer.restfulobjects.applib.RestfulResponse.HttpStatusCode;
import org.apache.causeway.viewer.restfulobjects.applib.version.VersionResource;
import org.apache.causeway.viewer.restfulobjects.rendering.Caching;
-import org.apache.causeway.viewer.restfulobjects.rendering.Responses;
import org.apache.causeway.viewer.restfulobjects.rendering.RestfulObjectsApplicationException;
import org.apache.causeway.viewer.restfulobjects.rendering.service.RepresentationService;
import org.apache.causeway.viewer.restfulobjects.viewer.context.ResourceContext;
import lombok.extern.slf4j.Slf4j;
-/**
- * Implementation note: it seems to be necessary to annotate the implementation
- * with {@link Path} rather than the interface (at least under RestEasy 1.0.2
- * and 1.1-RC2).
- */
-@Component
-@Path("/version")
+@RestController
@Slf4j
public class VersionResourceServerside
extends ResourceAbstract
@@ -59,9 +50,7 @@ public VersionResourceServerside() {
}
@Override
-// @GET
-// @Produces({ MediaType.APPLICATION_JSON_VALUE, RestfulMediaType.APPLICATION_JSON_VERSION })
- public Response version() {
+ public ResponseEntity<Object> version() {
var resourceContext = createResourceContext(
RepresentationType.VERSION, Where.NOWHERE, RepresentationService.Intent.NOT_APPLICABLE);
@@ -71,42 +60,44 @@ public Response version() {
renderer.includesSelf();
return _EndpointLogging.response(log, "GET /version",
- Responses.ofOk(renderer, Caching.ONE_DAY).build());
+ responseFactory.ok(renderer, Caching.ONE_DAY));
}
@Override
- public Response deleteVersionNotAllowed() {
+ public ResponseEntity<Object> deleteVersionNotAllowed() {
throw _EndpointLogging.error(log, "DELETE /version",
RestfulObjectsApplicationException
.createWithMessage(
- RestfulResponse.HttpStatusCode.METHOD_NOT_ALLOWED,
+ HttpStatus.METHOD_NOT_ALLOWED,
"Deleting the version resource is not allowed."));
}
@Override
- public Response putVersionNotAllowed() {
+ public ResponseEntity<Object> putVersionNotAllowed() {
throw _EndpointLogging.error(log, "PUT /version",
RestfulObjectsApplicationException
.createWithMessage(
- RestfulResponse.HttpStatusCode.METHOD_NOT_ALLOWED,
+ HttpStatus.METHOD_NOT_ALLOWED,
"Putting to the version resource is not allowed."));
}
@Override
- public Response postVersionNotAllowed() {
+ public ResponseEntity<Object> postVersionNotAllowed() {
throw _EndpointLogging.error(log, "POST /version",
RestfulObjectsApplicationException
.createWithMessage(
- RestfulResponse.HttpStatusCode.METHOD_NOT_ALLOWED,
+ HttpStatus.METHOD_NOT_ALLOWED,
"Posting to the version resource is not allowed."));
}
+ // -- HELPER
+
private void fakeRuntimeExceptionIfXFail(final ResourceContext resourceContext) {
var httpHeaders = resourceContext.httpHeaders();
final List<String> requestHeader = httpHeaders.getValuesAsList("X-Fail");
if (requestHeader != null && !requestHeader.isEmpty()) {
throw _EndpointLogging.error(log, "GET /version",
- RestfulObjectsApplicationException.create(HttpStatusCode.METHOD_FAILURE));
+ RestfulObjectsApplicationException.create(HttpStatus.PRECONDITION_FAILED));
}
}
diff --git a/viewers/restfulobjects/viewer/src/main/java/org/apache/causeway/viewer/restfulobjects/viewer/resources/_DomainResourceHelper.java b/viewers/restfulobjects/viewer/src/main/java/org/apache/causeway/viewer/restfulobjects/viewer/resources/_DomainResourceHelper.java
index a2cb246378f..caa9de62fc7 100644
--- a/viewers/restfulobjects/viewer/src/main/java/org/apache/causeway/viewer/restfulobjects/viewer/resources/_DomainResourceHelper.java
+++ b/viewers/restfulobjects/viewer/src/main/java/org/apache/causeway/viewer/restfulobjects/viewer/resources/_DomainResourceHelper.java
@@ -20,8 +20,6 @@
import java.util.concurrent.atomic.LongAdder;
-import jakarta.ws.rs.core.Response;
-
import org.apache.causeway.applib.Identifier;
import org.apache.causeway.applib.annotation.SemanticsOf;
import org.apache.causeway.applib.services.xactn.TransactionService;
@@ -44,6 +42,8 @@
import org.jspecify.annotations.NonNull;
+import org.springframework.http.ResponseEntity;
+
record _DomainResourceHelper(
ResourceContext resourceContext,
RepresentationService representationService,
@@ -90,7 +90,7 @@ private _DomainResourceHelper(
* Simply delegates to the {@link org.apache.causeway.viewer.restfulobjects.rendering.service.RepresentationService} to
* render a representation of the object.
*/
- public Response objectRepresentation() {
+ public ResponseEntity<Object> objectRepresentation() {
transactionService.flushTransaction();
return representationService
.objectRepresentation(resourceContext, objectAdapter);
@@ -101,7 +101,7 @@ public Response objectRepresentation() {
* {@link org.apache.causeway.viewer.restfulobjects.rendering.service.RepresentationService} to render a representation
* of that property.
*/
- public Response propertyDetails(
+ public ResponseEntity<Object> propertyDetails(
final String propertyId,
final ManagedMember.RepresentationMode representationMode) {
@@ -118,7 +118,7 @@ public Response propertyDetails(
* {@link org.apache.causeway.viewer.restfulobjects.rendering.service.RepresentationService} to render a representation
* of that collection.
*/
- public Response collectionDetails(
+ public ResponseEntity<Object> collectionDetails(
final String collectionId,
final ManagedMember.RepresentationMode representationMode) {
@@ -135,7 +135,7 @@ public Response collectionDetails(
* {@link org.apache.causeway.viewer.restfulobjects.rendering.service.RepresentationService} to render a representation
* of that object's action (arguments).
*/
- public Response actionPrompt(final String actionId) {
+ public ResponseEntity<Object> actionPrompt(final String actionId) {
var action = ObjectAdapterAccessHelper.of(resourceContext, objectAdapter)
.getObjectActionThatIsVisibleForIntentAndSemanticConstraint(
@@ -155,7 +155,7 @@ public Response actionPrompt(final String actionId) {
* otherwise an error response is thrown.
* </p>
*/
- public Response invokeActionQueryOnly(final String actionId, final JsonRepresentation arguments) {
+ public ResponseEntity<Object> invokeActionQueryOnly(final String actionId, final JsonRepresentation arguments) {
return invokeAction(
actionId, AccessIntent.MUTATE, SemanticConstraint.SAFE,
@@ -172,7 +172,7 @@ public Response invokeActionQueryOnly(final String actionId, final JsonRepresent
* semantics otherwise an error response is thrown.
* </p>
*/
- public Response invokeActionIdempotent(final String actionId, final JsonRepresentation arguments) {
+ public ResponseEntity<Object> invokeActionIdempotent(final String actionId, final JsonRepresentation arguments) {
return invokeAction(
actionId, AccessIntent.MUTATE, SemanticConstraint.IDEMPOTENT,
@@ -184,7 +184,7 @@ public Response invokeActionIdempotent(final String actionId, final JsonRepresen
* {@link org.apache.causeway.viewer.restfulobjects.rendering.service.RepresentationService} to render a representation
* of the result of that action.
*/
- public Response invokeAction(final String actionId, final JsonRepresentation arguments) {
+ public ResponseEntity<Object> invokeAction(final String actionId, final JsonRepresentation arguments) {
return invokeAction(
actionId, AccessIntent.MUTATE, SemanticConstraint.NONE,
@@ -193,7 +193,7 @@ public Response invokeAction(final String actionId, final JsonRepresentation arg
// -- HELPER
- private Response invokeAction(
+ private ResponseEntity<Object> invokeAction(
final @NonNull String actionId,
final @NonNull AccessIntent intent,
final @NonNull SemanticConstraint semanticConstraint,
@@ -275,7 +275,7 @@ private Response invokeAction(
}
if(resourceContext.isValidateOnly()) {
- return Response.noContent().build(); // do not progress any further
+ return ResponseEntity.noContent().build(); // do not progress any further
}
var resultOrVeto = actionInteraction.invokeWith(pendingArgs);
diff --git a/viewers/restfulobjects/viewer/src/main/java/org/apache/causeway/viewer/restfulobjects/viewer/resources/_EndpointLogging.java b/viewers/restfulobjects/viewer/src/main/java/org/apache/causeway/viewer/restfulobjects/viewer/resources/_EndpointLogging.java
index b347dc97046..44397fcfd97 100644
--- a/viewers/restfulobjects/viewer/src/main/java/org/apache/causeway/viewer/restfulobjects/viewer/resources/_EndpointLogging.java
+++ b/viewers/restfulobjects/viewer/src/main/java/org/apache/causeway/viewer/restfulobjects/viewer/resources/_EndpointLogging.java
@@ -20,10 +20,10 @@
import java.util.Optional;
-import jakarta.ws.rs.core.Response;
-
import org.slf4j.Logger;
+import org.springframework.http.ResponseEntity;
+
import org.apache.causeway.commons.functional.Try;
import org.apache.causeway.commons.internal.collections._Collections;
import org.apache.causeway.commons.io.JaxbUtils;
@@ -52,10 +52,10 @@ String stringResponse(
/**
* Returns given {@code Response} untampered.
*/
- Response response(
+ <T> ResponseEntity<T> response(
final Logger log,
final String format,
- final Response response) {
+ final ResponseEntity<T> response) {
if(log.isDebugEnabled()) {
logRequest(log, format);
logResponse(log, response);
@@ -66,11 +66,11 @@ Response response(
/**
* Returns given {@code Response} untampered.
*/
- Response response(
+ <T> ResponseEntity<T> response(
final Logger log,
final String format,
final String arg0,
- final Response response) {
+ final ResponseEntity<T> response) {
if(log.isDebugEnabled()) {
logRequest(log, format, arg0);
logResponse(log, response);
@@ -81,12 +81,12 @@ Response response(
/**
* Returns given {@code Response} untampered.
*/
- Response response(
+ <T> ResponseEntity<T> response(
final Logger log,
final String format,
final String arg0,
final String arg1,
- final Response response) {
+ final ResponseEntity<T> response) {
if(log.isDebugEnabled()) {
logRequest(log, format, arg0, arg1);
logResponse(log, response);
@@ -97,13 +97,13 @@ Response response(
/**
* Returns given {@code Response} untampered.
*/
- Response response(
+ <T> ResponseEntity<T> response(
final Logger log,
final String format,
final String arg0,
final String arg1,
final String arg2,
- final Response response) {
+ final ResponseEntity<T> response) {
if(log.isDebugEnabled()) {
logRequest(log, format, arg0, arg1, arg2);
logResponse(log, response);
@@ -180,10 +180,10 @@ private void logRequest(final Logger log, final String format, final Object... a
log.debug(format, args);
}
- private void logResponse(final Logger log, final Response response) {
+ private <T> void logResponse(final Logger log, final ResponseEntity<T> response) {
log.debug("<<< RESPONSE");
- var dto = response.getEntity();
+ var dto = response.getBody();
if(dto==null) {
log.debug("null");
} else if(dto instanceof String string) {
@@ -213,7 +213,7 @@ private void logResponse(final Logger log, final String stringResponse) {
private void logError(final Logger log, final RestfulObjectsApplicationException roException) {
log.debug("<<< ERROR");
- log.debug(Optional.ofNullable(roException.getBody()).map(JsonRepresentation::toString).orElse("null"));
+ log.debug(Optional.ofNullable(roException.body()).map(JsonRepresentation::toString).orElse("null"));
log.debug("--- END ERROR");
}
diff --git a/viewers/restfulobjects/viewer/src/main/java/org/apache/causeway/viewer/restfulobjects/viewer/mappers/ExceptionMapperForRuntimeException.java b/viewers/restfulobjects/viewer/src/main/java/org/apache/causeway/viewer/restfulobjects/viewer/util/RequestHeaderUtil.java
similarity index 51%
rename from viewers/restfulobjects/viewer/src/main/java/org/apache/causeway/viewer/restfulobjects/viewer/mappers/ExceptionMapperForRuntimeException.java
rename to viewers/restfulobjects/viewer/src/main/java/org/apache/causeway/viewer/restfulobjects/viewer/util/RequestHeaderUtil.java
index 258d2d6a506..ea4fd409108 100644
--- a/viewers/restfulobjects/viewer/src/main/java/org/apache/causeway/viewer/restfulobjects/viewer/mappers/ExceptionMapperForRuntimeException.java
+++ b/viewers/restfulobjects/viewer/src/main/java/org/apache/causeway/viewer/restfulobjects/viewer/util/RequestHeaderUtil.java
@@ -16,25 +16,29 @@
* specific language governing permissions and limitations
* under the License.
*/
-package org.apache.causeway.viewer.restfulobjects.viewer.mappers;
+package org.apache.causeway.viewer.restfulobjects.viewer.util;
-import jakarta.inject.Singleton;
-import jakarta.ws.rs.core.Response;
-import jakarta.ws.rs.ext.Provider;
+import java.util.Enumeration;
-import org.springframework.stereotype.Component;
+import jakarta.servlet.http.HttpServletRequest;
-import org.apache.causeway.applib.annotation.PriorityPrecedence;
+import org.springframework.http.HttpHeaders;
-@Component
-@Provider
-@Singleton
-@jakarta.annotation.Priority(PriorityPrecedence.LATE)
-public class ExceptionMapperForRuntimeException extends ExceptionMapperAbstract<RuntimeException> {
+import lombok.experimental.UtilityClass;
- @Override
- public Response toResponse(final RuntimeException ex) {
- return buildResponse(ex);
- }
+@UtilityClass
+public class RequestHeaderUtil {
+ public HttpHeaders httpHeadersFromServletRequest(HttpServletRequest request) {
+ var headers = new HttpHeaders();
+ Enumeration<String> headerNames = request.getHeaderNames();
+ while (headerNames.hasMoreElements()) {
+ String name = headerNames.nextElement();
+ Enumeration<String> values = request.getHeaders(name);
+ while (values.hasMoreElements()) {
+ headers.add(name, values.nextElement());
+ }
+ }
+ return headers;
+ }
}
diff --git a/viewers/restfulobjects/viewer/src/main/java/org/apache/causeway/viewer/restfulobjects/viewer/webmodule/CausewayRestfulObjectsInteractionFilter2.java b/viewers/restfulobjects/viewer/src/main/java/org/apache/causeway/viewer/restfulobjects/viewer/webmodule/CausewayRestfulObjectsInteractionFilter2.java
new file mode 100644
index 00000000000..e1ff2a49ff8
--- /dev/null
+++ b/viewers/restfulobjects/viewer/src/main/java/org/apache/causeway/viewer/restfulobjects/viewer/webmodule/CausewayRestfulObjectsInteractionFilter2.java
@@ -0,0 +1,463 @@
+/*
+ * 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.causeway.viewer.restfulobjects.viewer.webmodule;
+
+import java.io.IOException;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.List;
+import java.util.Objects;
+import java.util.function.Function;
+import java.util.regex.Pattern;
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
+
+import jakarta.servlet.FilterChain;
+import jakarta.servlet.ServletException;
+import jakarta.servlet.http.HttpServletRequest;
+import jakarta.servlet.http.HttpServletResponse;
+import jakarta.transaction.TransactionalException;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.stereotype.Component;
+import org.springframework.web.filter.OncePerRequestFilter;
+
+import org.apache.causeway.applib.services.iactnlayer.InteractionService;
+import org.apache.causeway.applib.services.xactn.TransactionService;
+import org.apache.causeway.commons.internal.base._Strings;
+import org.apache.causeway.commons.internal.exceptions._Exceptions;
+import org.apache.causeway.commons.internal.factory._InstanceUtil;
+import org.apache.causeway.commons.internal.resources._Resources;
+import org.apache.causeway.core.config.CausewayConfiguration;
+import org.apache.causeway.core.metamodel.specloader.SpecificationLoader;
+import org.apache.causeway.core.metamodel.specloader.validator.MetaModelInvalidException;
+import org.apache.causeway.core.webapp.modules.templresources.TemplateResourceCachingFilter;
+import org.apache.causeway.viewer.restfulobjects.viewer.webmodule.auth.AuthenticationStrategy;
+import org.apache.causeway.viewer.restfulobjects.viewer.webmodule.auth.AuthenticationStrategyUsingSession;
+
+import lombok.Builder;
+
+/**
+ * Filter for RestfulObjects.
+ *
+ * authenticate user, set up an Causeway session
+ */
+//@WebFilter(
+// servletNames={"RestfulObjectsRestEasyDispatcher"}, // this is mapped to the entire application;
+// // however the CausewayRestfulObjectsInteractionFilter will
+// // "notice" if the interaction filter has already been
+// // executed for the request pipeline, and if so will do nothing
+// initParams={
+// @WebInitParam(
+// name="authenticationStrategy",
+// value="org.apache.causeway.viewer.restfulobjects.server.authentication.AuthenticationStrategyBasicAuth"), // authentication required for REST
+// @WebInitParam(
+// name="whenNoSession", // what to do if no session was found ...
+// value="auto"), // ... 401 and a basic authentication challenge if request originates from web browser
+// @WebInitParam(name="passThru", value="/restful/swagger,/restful/health") //TODO[CAUSEWAY-1895] the restful path is configured elsewhere
+//})
+//TODO[causeway-viewer-restfulobjects-viewer-CAUSEWAY-3892] experimental
+@Component
+public class CausewayRestfulObjectsInteractionFilter2 extends OncePerRequestFilter {
+
+ public static final String AUTHENTICATION_SESSION_STRATEGY_DEFAULT = AuthenticationStrategyUsingSession.class.getName();
+
+ /**
+ * Somewhat hacky, add this to the query
+ */
+ public static final String CAUSEWAY_SESSION_FILTER_QUERY_STRING_FORCE_LOGOUT = "__causeway_force_logout";
+
+ private static final Function<String, Pattern> STRING_TO_PATTERN = (final String input) -> {
+ return Pattern.compile(".*\\." + input);
+ };
+
+ @Autowired private InteractionService interactionService;
+ @Autowired private SpecificationLoader specificationLoader;
+ @Autowired private TransactionService transactionService;
+ @Autowired private CausewayConfiguration causewayConfiguration;
+ @Value("${causeway.viewer.restfulobjects.path-prefix}") String restfulPath;
+
+ @Builder
+ record Config(
+ /**
+ * Recommended standard init parameter for filters and servlets to
+ * lookup an implementation of {@link AuthenticationStrategy}.
+ */
+ String authenticationStrategyClassName,
+ /**
+ * What to do if no session was found.
+ *
+ * <p> Valid values are:
+ * <ul>
+ * <li>unauthorized - issue a 401 response.
+ * <li>basicAuthChallenge - issue a basic auth 401 challenge. The idea here
+ * is that the configured logon strategy should handle the next request
+ * <li>restricted - allow access but only to a restricted (comma-separated)
+ * list of paths. Access elsewhere should be redirected to the first of
+ * these paths
+ * <li>continue - allow the request to continue (eg if there is no security requirements)
+ * </ul>
+ */
+ String whenNoSession,
+ /**
+ * Which URLs to ignore (eg <code>/restful/swagger</code> so that swagger specs can be accessed from the swagger-ui)
+ */
+ String passThru,
+ //TODO[causeway-viewer-restfulobjects-viewer-CAUSEWAY-3892] not applied just yet
+ String urlPattern) {
+
+ /**
+ * where to redirect to if an exception occurs
+ */
+ public String redirectToOnException() {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ /**
+ * Init parameter key for which extensions should be ignored (typically,
+ * mappings for other viewers within the webapp context).
+ *
+ * <p>It can also be used to specify ignored static resources (though putting
+ * the {@link TemplateResourceCachingFilter} first in the <tt>web.xml</tt>
+ * accomplishes the same thing).
+ *
+ * <p>The value is expected as a comma separated list.
+ */
+ public String ignoreExtensions() {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ /**
+ * Init parameter to read the restricted list of paths (if
+ * {@link #whenNoSession} is for {@link WhenNoSession#RESTRICTED}).
+ *
+ * <p>The servlets mapped to these paths are expected to be able to deal with
+ * there being no session. Typically they will be logon pages.
+ */
+ public String restricted() {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ /**
+ * Init parameter for backward compatibility; if logonPage set then
+ * assume 'restricted' handling.
+ */
+ public String logonPage() {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ }
+
+ private List<String> passThruList = Collections.emptyList();
+
+ static void redirect(final HttpServletRequest httpRequest, final HttpServletResponse httpResponse, final String redirectTo) throws IOException {
+ httpResponse.sendRedirect(_Resources.combinePath(httpRequest.getContextPath(), redirectTo));
+ }
+
+ public enum WhenNoSession {
+ UNAUTHORIZED("unauthorized") {
+ @Override
+ public void handle(final CausewayRestfulObjectsInteractionFilter2 filter, final HttpServletRequest httpRequest, final HttpServletResponse httpResponse, final FilterChain chain) throws IOException, ServletException {
+ httpResponse.sendError(401);
+ }
+ },
+ BASIC_AUTH_CHALLENGE("basicAuthChallenge") {
+ @Override
+ public void handle(final CausewayRestfulObjectsInteractionFilter2 filter, final HttpServletRequest httpRequest, final HttpServletResponse httpResponse, final FilterChain chain) throws IOException, ServletException {
+ httpResponse.setHeader("WWW-Authenticate", "Basic realm=\"Apache Causeway\"");
+ httpResponse.sendError(401);
+ }
+ },
+ AUTO("auto") {
+ @Override
+ public void handle(final CausewayRestfulObjectsInteractionFilter2 filter, final HttpServletRequest httpRequest, final HttpServletResponse httpResponse, final FilterChain chain) throws IOException, ServletException {
+ if(fromWebBrowser(httpRequest)) {
+ httpResponse.setHeader("WWW-Authenticate", "Basic realm=\"Apache Causeway\"");
+ }
+ httpResponse.sendError(401);
+ }
+
+ private boolean fromWebBrowser(final HttpServletRequest httpRequest) {
+ String accept = httpRequest.getHeader("Accept");
+ return accept.contains("text/html");
+ }
+ },
+ /**
+ * the destination servlet is expected to know that there will be no open session, and handle the case appropriately
+ */
+ CONTINUE("continue") {
+ @Override
+ public void handle(final CausewayRestfulObjectsInteractionFilter2 filter, final HttpServletRequest httpRequest, final HttpServletResponse httpResponse, final FilterChain chain) throws IOException, ServletException {
+ chain.doFilter(httpRequest, httpResponse);
+ }
+ },
+ /**
+ * Allow access to a restricted list of URLs (else redirect to the first of that list of URLs)
+ */
+ RESTRICTED("restricted") {
+ @Override
+ public void handle(final CausewayRestfulObjectsInteractionFilter2 filter, final HttpServletRequest httpRequest, final HttpServletResponse httpResponse, final FilterChain chain) throws IOException, ServletException {
+
+ if (filter.restrictedPaths.contains(httpRequest.getServletPath())) {
+ chain.doFilter(httpRequest, httpResponse);
+ return;
+ }
+ redirect(httpRequest, httpResponse, filter.restrictedPaths.get(0));
+ }
+
+ };
+ private final String initParamValue;
+
+ private WhenNoSession(final String initParamValue) {
+ this.initParamValue = initParamValue;
+ }
+
+ public static WhenNoSession lookup(final String whenNoSessionStr) {
+ for (final WhenNoSession wns : values()) {
+ if (wns.initParamValue.equals(whenNoSessionStr)) {
+ return wns;
+ }
+ }
+ throw new IllegalStateException("require an init-param of 'whenNoSession', "
+ + "taking a value of " + Arrays.toString(WhenNoSession.values()));
+ }
+
+ public abstract void handle(CausewayRestfulObjectsInteractionFilter2 filter, HttpServletRequest httpRequest, HttpServletResponse httpResponse, FilterChain chain) throws IOException, ServletException;
+ }
+
+ private AuthenticationStrategy authStrategy;
+ private List<String> restrictedPaths;
+ private WhenNoSession whenNotAuthenticated;
+ private String redirectToOnException;
+ private Collection<Pattern> ignoreExtensions;
+
+ @Override
+ public void initFilterBean() throws ServletException {
+ var config = createConfig();
+ this.authStrategy = lookup(config.authenticationStrategyClassName());
+ lookupWhenNoSession(config);
+ lookupPassThru(config);
+ lookupRedirectToOnException(config);
+ lookupIgnoreExtensions(config);
+ }
+
+ private Config createConfig() {
+
+ return new Config(
+ causewayConfiguration.getViewer().getRestfulobjects().getAuthentication().getStrategyClassName(),
+ "auto", // ... 401 and a basic authentication challenge if request originates from web browser
+ String.join(",",
+ this.restfulPath + "swagger",
+ this.restfulPath + "health"),
+ // this is mapped to the entire application;
+ // however the CausewayRestfulObjectsInteractionFilter will
+ // "notice" if the session filter has already been
+ // executed for the request pipeline, and if so will do nothing
+ this.restfulPath + "/*");
+ }
+
+ /**
+ * Public visibility so can also be used by servlets.
+ */
+ public static AuthenticationStrategy lookup(String authLookupStrategyClassName) {
+ if (authLookupStrategyClassName == null) {
+ authLookupStrategyClassName = AUTHENTICATION_SESSION_STRATEGY_DEFAULT;
+ }
+ return (AuthenticationStrategy) _InstanceUtil.createInstance(authLookupStrategyClassName);
+ }
+
+ private void lookupWhenNoSession(final Config config) {
+
+ final String whenNoSessionStr = config.whenNoSession();
+
+ // backward compatibility
+ final String logonPage = config.logonPage();
+ if (logonPage != null) {
+ if (whenNoSessionStr != null) {
+ throw new IllegalStateException(String.format(
+ "The init-param '%s' is only provided for backwards compatibility; "
+ + "remove if the init-param '%s' has been specified", "logonPage", "whenNoSession"));
+ } else {
+ // default whenNotAuthenticated and allow access through to the logonPage
+ whenNotAuthenticated = WhenNoSession.RESTRICTED;
+ this.restrictedPaths = List.of(logonPage);
+ return;
+ }
+ }
+
+ whenNotAuthenticated = WhenNoSession.lookup(whenNoSessionStr);
+ if (whenNotAuthenticated == WhenNoSession.RESTRICTED) {
+ final String restrictedPathsStr = config.restricted();
+ if (restrictedPathsStr == null) {
+ throw new IllegalStateException(String.format("Require an init-param of '%s' key to be set.", "restricted"));
+ }
+ this.restrictedPaths =
+ _Strings.splitThenStream(restrictedPathsStr, ",")
+ .collect(Collectors.toList());
+
+ }
+
+ }
+
+ void lookupPassThru(final Config config) {
+ this.passThruList = lookupAndParsePassThru(config);
+ }
+
+ List<String> lookupAndParsePassThru(final Config config) {
+ final String passThru = config.passThru();
+ return passThru != null && !passThru.equals("")
+ ? Arrays.asList(passThru.split(","))
+ : Collections.<String>emptyList();
+ }
+
+ private void lookupRedirectToOnException(final Config config) {
+ redirectToOnException = config.redirectToOnException();
+ }
+
+ private void lookupIgnoreExtensions(final Config config) {
+ ignoreExtensions = Collections.unmodifiableCollection(parseIgnorePatterns(config)
+ .collect(Collectors.toList()));
+ }
+
+ private Stream<Pattern> parseIgnorePatterns(final Config config) {
+ final String ignoreExtensionsStr = config.ignoreExtensions();
+ if (ignoreExtensionsStr != null) {
+ final Stream<String> ignoreExtensions = _Strings.splitThenStream(ignoreExtensionsStr, ",");
+ return ignoreExtensions.map(STRING_TO_PATTERN);
+ }
+ return Stream.empty();
+ }
+
+ @Override
+ public void destroy() {
+ }
+
+ @Override
+ public void doFilterInternal(
+ final HttpServletRequest httpServletRequest,
+ final HttpServletResponse httpServletResponse,
+ final FilterChain chain) throws IOException, ServletException {
+
+ Objects.requireNonNull(interactionService, "causewayInteractionFactory");
+ Objects.requireNonNull(specificationLoader, "specificationLoader");
+
+ // check that the app has bootstrapped; if it hasn't, then return a 503 (rather than a huge stack trace)
+ try {
+ ensureMetamodelIsValid(specificationLoader);
+ } catch (Exception ex) {
+ httpServletResponse.setStatus(HttpServletResponse.SC_SERVICE_UNAVAILABLE);
+ return;
+ }
+
+ try {
+ var queryString = httpServletRequest.getQueryString();
+ if (queryString != null && queryString
+ .contains(CAUSEWAY_SESSION_FILTER_QUERY_STRING_FORCE_LOGOUT)) {
+
+ authStrategy.invalidate(httpServletRequest, httpServletResponse);
+ return;
+ }
+
+ if (requestIsIgnoreExtension(this, httpServletRequest) ||
+ TemplateResourceCachingFilter.isCachedResource(httpServletRequest)) {
+ chain.doFilter(httpServletRequest, httpServletResponse);
+ return;
+ }
+
+ if(requestIsPassThru(httpServletRequest)) {
+ chain.doFilter(httpServletRequest, httpServletResponse);
+ return;
+ }
+
+ // authenticate
+ var authentication =
+ authStrategy.lookupValid(httpServletRequest, httpServletResponse);
+ if (authentication != null) {
+
+ authStrategy.bind(httpServletRequest, httpServletResponse, authentication);
+
+ interactionService.run(
+ authentication,
+ ()->{
+ transactionService.runWithinCurrentTransactionElseCreateNew(()->
+ chain.doFilter(httpServletRequest, httpServletResponse))
+ .mapFailure(e->new TransactionalException("", e))
+ .ifFailureFail();
+ });
+
+ return;
+ }
+
+ try {
+ whenNotAuthenticated.handle(this, httpServletRequest, httpServletResponse, chain);
+ } catch (final RuntimeException | IOException | ServletException ex) {
+ // in case the destination servlet cannot cope, but we've
+ // been told to redirect elsewhere
+ if (redirectToOnException != null) {
+ redirect(httpServletRequest, httpServletResponse, redirectToOnException);
+ return;
+ }
+ throw ex;
+ }
+
+ } finally {
+ interactionService.closeInteractionLayers();
+ }
+
+ }
+
+ private static void ensureMetamodelIsValid(final SpecificationLoader specificationLoader) {
+ // using side-effect free access to MM validation result
+ var validationResult = specificationLoader.getValidationResult()
+ .orElseThrow(()->_Exceptions.illegalState("Application is not fully initialized yet."));
+ if(validationResult.hasFailures()) {
+ throw new MetaModelInvalidException(validationResult.getAsLineNumberedString());
+ }
+ }
+
+ protected boolean requestIsPassThru(final HttpServletRequest httpServletRequest) {
+ final String requestURI = httpServletRequest.getRequestURI();
+ for (final String passThru : passThruList) {
+ if(requestURI.startsWith(passThru)) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ private boolean requestIsIgnoreExtension(
+ final CausewayRestfulObjectsInteractionFilter2 filter,
+ final HttpServletRequest httpRequest) {
+
+ var servletPath = httpRequest.getServletPath();
+ for (final Pattern extension : filter.ignoreExtensions) {
+ if (extension.matcher(servletPath).matches()) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+}
diff --git a/viewers/restfulobjects/viewer/src/main/java/org/apache/causeway/viewer/restfulobjects/viewer/webmodule/WebModuleRestfulObjects.java b/viewers/restfulobjects/viewer/src/main/java/org/apache/causeway/viewer/restfulobjects/viewer/webmodule/WebModuleRestfulObjects.java
new file mode 100644
index 00000000000..b4430dbdd2e
--- /dev/null
+++ b/viewers/restfulobjects/viewer/src/main/java/org/apache/causeway/viewer/restfulobjects/viewer/webmodule/WebModuleRestfulObjects.java
@@ -0,0 +1,132 @@
+/*
+ * 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.causeway.viewer.restfulobjects.viewer.webmodule;
+
+import jakarta.inject.Inject;
+import jakarta.inject.Named;
+import jakarta.servlet.ServletContext;
+import jakarta.servlet.ServletContextListener;
+import jakarta.servlet.ServletException;
+
+import org.springframework.beans.factory.annotation.Qualifier;
+import org.springframework.stereotype.Service;
+
+import org.apache.causeway.applib.annotation.PriorityPrecedence;
+import org.apache.causeway.applib.services.inject.ServiceInjector;
+import org.apache.causeway.commons.collections.Can;
+import org.apache.causeway.core.config.CausewayConfiguration;
+import org.apache.causeway.core.config.RestEasyConfiguration;
+import org.apache.causeway.core.webapp.modules.WebModuleAbstract;
+import org.apache.causeway.core.webapp.modules.WebModuleContext;
+import org.apache.causeway.viewer.restfulobjects.applib.CausewayModuleViewerRestfulObjectsApplib;
+import lombok.Getter;
+
+/**
+ * WebModule that provides the RestfulObjects Viewer.
+ *
+ * @since 2.0 {@index}
+ *
+ * @implNote CDI resolves injection points for any Servlet or Filter
+ * we register programmatically on the ServletContext.
+ * As long as injection points are considered to be resolved by Spring, we can workaround this fact:
+ * By replacing annotations {@code @Inject} with {@code @Autowire} for any Servlet or Filter,
+ * that get contributed by a WebModule, these will be ignored by CDI.
+ *
+ */
+@Service
+//CAUTION: SwaggerServiceMenu refers to this name
+@Named(CausewayModuleViewerRestfulObjectsApplib.NAMESPACE + ".WebModuleRestfulObjects")
+@jakarta.annotation.Priority(PriorityPrecedence.MIDPOINT - 80)
+@Qualifier("RestfulObjects")
+public final class WebModuleRestfulObjects extends WebModuleAbstract {
+
+ private static final String INTERACTION_FILTER_NAME = "CausewayRestfulObjectsInteractionFilter";
+
+ private final CausewayConfiguration causewayConfiguration;
+ private final RestEasyConfiguration restEasyConfiguration;
+
+ private final String restfulPath;
+ private final String urlPattern;
+
+ @Inject
+ public WebModuleRestfulObjects(
+ final CausewayConfiguration causewayConfiguration,
+ final RestEasyConfiguration restEasyConfiguration,
+ final ServiceInjector serviceInjector) {
+ super(serviceInjector);
+ this.causewayConfiguration = causewayConfiguration;
+ this.restEasyConfiguration = restEasyConfiguration;
+ this.restfulPath = this.restEasyConfiguration.getJaxrs().getDefaultPath() + "/";
+ this.urlPattern = this.restfulPath + "*";
+ }
+
+ @Getter
+ private final String name = "RestfulObjects";
+
+ @Override
+ public void prepare(final WebModuleContext ctx) {
+
+ // forces RuntimeDelegate.getInstance() to be provided by RestEasy
+ // (and not by eg. the JEE container if any)
+ //ResteasyProviderFactory.setInstance(new ResteasyProviderFactoryImpl());
+
+ super.prepare(ctx);
+
+ if(!isApplicable(ctx)) {
+ return;
+ }
+
+ ctx.addProtectedPath(urlPattern);
+ }
+
+ @Override
+ public Can<ServletContextListener> init(final ServletContext ctx) throws ServletException {
+
+ var authenticationStrategyClassName = causewayConfiguration.getViewer()
+ .getRestfulobjects().getAuthentication().getStrategyClassName();
+
+ registerFilter(ctx, INTERACTION_FILTER_NAME, CausewayRestfulObjectsInteractionFilter.class)
+ .ifPresent(filterReg -> {
+ // this is mapped to the entire application;
+ // however the CausewayRestfulObjectsInteractionFilter will
+ // "notice" if the session filter has already been
+ // executed for the request pipeline, and if so will do nothing
+ filterReg.addMappingForUrlPatterns(
+ null,
+ true,
+ this.urlPattern);
+
+ filterReg.setInitParameter(
+ "authenticationStrategy",
+ authenticationStrategyClassName);
+ filterReg.setInitParameter(
+ "whenNoSession", // what to do if no session was found ...
+ "auto"); // ... 401 and a basic authentication challenge if request originates from web browser
+ filterReg.setInitParameter(
+ "passThru",
+ String.join(",",
+ this.restfulPath + "swagger",
+ this.restfulPath + "health"));
+
+ } );
+
+ return Can.empty(); // registers no listeners
+ }
+
+}
diff --git a/viewers/restfulobjects/viewer/src/test/java/org/apache/causeway/viewer/restfulobjects/viewer/context/ResourceContext_getArg_Test.java b/viewers/restfulobjects/viewer/src/test/java/org/apache/causeway/viewer/restfulobjects/viewer/context/ResourceContext_getArg_Test.java
index d464b636583..e35e56b4710 100644
--- a/viewers/restfulobjects/viewer/src/test/java/org/apache/causeway/viewer/restfulobjects/viewer/context/ResourceContext_getArg_Test.java
+++ b/viewers/restfulobjects/viewer/src/test/java/org/apache/causeway/viewer/restfulobjects/viewer/context/ResourceContext_getArg_Test.java
@@ -18,6 +18,9 @@
*/
package org.apache.causeway.viewer.restfulobjects.viewer.context;
+import java.util.Collections;
+import java.util.List;
+
import jakarta.servlet.ServletContext;
import jakarta.servlet.http.HttpServletRequest;
@@ -87,6 +90,10 @@ void setUp() throws Exception {
.when(mockHttpServletRequest.getQueryString())
.thenReturn("");
+ Mockito
+ .when(mockHttpServletRequest.getHeaderNames())
+ .thenReturn(Collections.enumeration(List.of()));
+
}
@Test
diff --git a/viewers/restfulobjects/viewer/src/test/java/org/apache/causeway/viewer/restfulobjects/viewer/webmodule/CausewayRestfulObjectsSessionFilter_lookupPassThru_Test2.java b/viewers/restfulobjects/viewer/src/test/java/org/apache/causeway/viewer/restfulobjects/viewer/webmodule/CausewayRestfulObjectsSessionFilter_lookupPassThru_Test2.java
new file mode 100644
index 00000000000..c6792fe4e45
--- /dev/null
+++ b/viewers/restfulobjects/viewer/src/test/java/org/apache/causeway/viewer/restfulobjects/viewer/webmodule/CausewayRestfulObjectsSessionFilter_lookupPassThru_Test2.java
@@ -0,0 +1,76 @@
+/*
+ * 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.causeway.viewer.restfulobjects.viewer.webmodule;
+
+import java.util.List;
+
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+
+import org.apache.causeway.viewer.restfulobjects.viewer.webmodule.CausewayRestfulObjectsInteractionFilter2.Config;
+
+class CausewayRestfulObjectsSessionFilter_lookupPassThru_Test2 {
+
+ CausewayRestfulObjectsInteractionFilter2 causewayInteractionFilter;
+
+ CausewayRestfulObjectsInteractionFilter2.Config config;
+
+ @BeforeEach
+ void setUp() throws Exception {
+ causewayInteractionFilter = new CausewayRestfulObjectsInteractionFilter2();
+ }
+
+ @Test
+ void when_null() throws Exception {
+ config = Config.builder().passThru(null).build();
+
+ final List<String> x = causewayInteractionFilter.lookupAndParsePassThru(config);
+ assertEquals(0, x.size());
+ }
+
+ @Test
+ void when_none() throws Exception {
+ config = Config.builder().passThru("").build();
+
+ final List<String> x = causewayInteractionFilter.lookupAndParsePassThru(config);
+ assertEquals(0, x.size());
+ }
+
+ @Test
+ void when_one() throws Exception {
+ config = Config.builder().passThru("/abc").build();
+
+ final List<String> x = causewayInteractionFilter.lookupAndParsePassThru(config);
+ assertEquals(1, x.size());
+ assertEquals("/abc", x.get(0));
+ }
+
+ @Test
+ void when_several() throws Exception {
+ config = Config.builder().passThru("/abc,/def").build();
+
+ final List<String> x = causewayInteractionFilter.lookupAndParsePassThru(config);
+ assertEquals(2, x.size());
+ assertEquals("/abc", x.get(0));
+ assertEquals("/def", x.get(1));
+ }
+
+}
(causeway) 01/02: CAUSEWAY-3892: New Major Version 4 (Upgrade from Spring Boot 3.x to 4.x)
Posted by ah...@apache.org.
This is an automated email from the ASF dual-hosted git repository.
ahuber pushed a commit to branch 3897-ro.spring
in repository https://gitbox.apache.org/repos/asf/causeway.git
commit e80d67b81c22a2508331baaead2840062139f7ba
Author: Andi Huber <ah...@apache.org>
AuthorDate: Thu Jul 3 12:18:47 2025 +0200
CAUSEWAY-3892: New Major Version 4 (Upgrade from Spring Boot 3.x to 4.x)
---
api/applib/pom.xml | 6 +-
api/applib/src/main/java/module-info.java | 6 +-
.../services/acceptheader/AcceptHeaderService.java | 2 +-
.../conmap/ContentMappingServiceForCommandDto.java | 2 +-
.../ContentMappingServiceForCommandsDto.java | 2 +-
.../services/conmap/ContentMappingService.java | 2 +-
bom/pom.xml | 31 -
core/config/src/main/java/module-info.java | 1 -
.../ContentMappingServiceForOutboxEvents.java | 2 +-
extensions/core/executionoutbox/restclient/pom.xml | 27 +-
.../restclient/api/OutboxClient.java | 6 +-
.../integtests/OutboxRestClient_IntegTest.java | 6 +-
.../SpringBeanProcessorRegressionWorkaround.java | 423 +++----
.../core/commandreplay/secondary/pom.xml | 10 +-
.../secondary/fetch/CommandFetcher.java | 2 +-
regressiontests/base-jpa/pom.xml | 10 +-
.../jpa/rest/JpaRestEndpointService.java | 2 +-
regressiontests/base/pom.xml | 10 +-
regressiontests/rest-jpa/pom.xml | 10 +-
viewers/restfulobjects/applib/pom.xml | 27 +-
.../applib/src/main/java/module-info.java | 1 +
.../restfulobjects/applib/LinkRepresentation.java | 4 +-
.../restfulobjects/applib/RepresentationType.java | 7 +-
.../restfulobjects/applib/RestfulRequest.java | 16 +-
.../restfulobjects/applib/RestfulResponse.java | 3 +-
.../applib/boot/BootstrapResource.java | 4 +-
.../applib/domainobjects/DomainObjectResource.java | 143 +--
.../domainobjects/DomainServiceResource.java | 119 +-
.../applib/domaintypes/DomainTypeResource.java | 22 +-
.../applib/health/HealthResource.java | 4 +-
.../applib/homepage/HomePageResource.java | 33 +-
.../applib/menubars/MenuBarsResource.java | 6 +-
.../restfulobjects/applib/user/UserResource.java | 6 +-
.../restfulobjects/applib/util/MediaTypes.java | 17 +-
.../viewer/restfulobjects/applib/util/Parser.java | 3 +-
.../applib/version/VersionResource.java | 4 +-
.../client/RestfulClientMediaType.java | 2 +-
.../client/auth/oauth2/azure/TokenCache.java | 2 +-
viewers/restfulobjects/jaxrs-resteasy/pom.xml | 119 --
...wayModuleViewerRestfulObjectsJaxrsResteasy.java | 1326 ++++++++++----------
.../conneg/RestfulObjectsJaxbWriterForXml.java | 78 --
.../webmodule/WebModuleJaxrsResteasy.java | 5 +-
viewers/restfulobjects/pom.xml | 2 +-
.../restfulobjects/rendering/IResourceContext.java | 2 +-
.../restfulobjects/rendering/LinkBuilder.java | 2 +-
.../restfulobjects/rendering/ReprRenderer.java | 2 +-
.../rendering/ReprRendererAbstract.java | 2 +-
.../viewer/restfulobjects/rendering/Responses.java | 9 +-
.../domainobjects/ScalarValueReprRenderer.java | 2 +-
.../acceptheader/AcceptHeaderServiceForRest.java | 10 +-
.../conneg/ContentNegotiationServiceAbstract.java | 2 +-
...entNegotiationServiceForRestfulObjectsV1_0.java | 2 +-
...ntentNegotiationServiceOrgApacheCausewayV2.java | 2 +-
.../ContentNegotiationServiceOrgApacheIsisV1.java | 2 +-
.../ContentNegotiationServiceXRoDomainType.java | 5 +-
viewers/restfulobjects/test/pom.xml | 10 +-
...sewayViewerRestfulObjectsIntegTestManifest.java | 5 +-
.../Parser_forJaxRsMediaType_ContractTest.java | 12 +-
...RepresentationTypeTest_lookup_ContractTest.java | 4 +-
..._ensureCompatibleAcceptHeader_ContractTest.java | 18 +-
.../viewer/context/ResourceContext.java | 76 +-
.../viewer/mappers/ExceptionMapperAbstract.java | 19 +-
.../mappers/ExceptionMapperForObjectNotFound.java | 52 +-
.../resources/DomainObjectResourceServerside.java | 227 ++--
.../resources/DomainServiceResourceServerside.java | 113 +-
.../resources/DomainTypeResourceServerside.java | 107 +-
.../resources/HomePageResourceServerside.java | 21 +-
.../resources/MenuBarsResourceServerside.java | 9 +-
.../viewer/resources/ResourceAbstract.java | 46 +-
.../viewer/resources/SwaggerSpecResource.java | 45 +-
.../viewer/resources/UserResourceServerside.java | 6 +-
.../resources/VersionResourceServerside.java | 13 +-
.../serialization/SerializationStrategy.java | 6 +-
73 files changed, 1527 insertions(+), 1817 deletions(-)
diff --git a/api/applib/pom.xml b/api/applib/pom.xml
index 2f777923d74..81b7d98b061 100644
--- a/api/applib/pom.xml
+++ b/api/applib/pom.xml
@@ -65,9 +65,9 @@
</dependency>
<!-- provides MediaType for content negotiation -->
<dependency>
- <groupId>jakarta.ws.rs</groupId>
- <artifactId>jakarta.ws.rs-api</artifactId>
- </dependency>
+ <groupId>org.springframework</groupId>
+ <artifactId>spring-web</artifactId>
+ </dependency>
<!-- TEST -->
diff --git a/api/applib/src/main/java/module-info.java b/api/applib/src/main/java/module-info.java
index 0129be184ee..3fd0454a368 100644
--- a/api/applib/src/main/java/module-info.java
+++ b/api/applib/src/main/java/module-info.java
@@ -125,6 +125,8 @@
exports org.apache.causeway.applib.value;
exports org.apache.causeway.applib.value.semantics;
+ requires static lombok;
+
requires com.fasterxml.jackson.core;
requires com.fasterxml.jackson.databind;
requires transitive java.desktop;
@@ -133,14 +135,14 @@
requires transitive jakarta.annotation;
requires transitive jakarta.inject;
requires transitive jakarta.persistence;
- requires transitive jakarta.ws.rs;
requires transitive jakarta.xml.bind;
- requires static lombok;
+
requires transitive org.apache.causeway.commons;
requires transitive org.apache.causeway.schema;
requires transitive spring.beans;
requires transitive spring.context;
requires transitive spring.core;
+ requires transitive spring.web;
requires spring.tx;
requires org.slf4j;
diff --git a/api/applib/src/main/java/org/apache/causeway/applib/services/acceptheader/AcceptHeaderService.java b/api/applib/src/main/java/org/apache/causeway/applib/services/acceptheader/AcceptHeaderService.java
index 217ec19f0e0..47cae280bcb 100644
--- a/api/applib/src/main/java/org/apache/causeway/applib/services/acceptheader/AcceptHeaderService.java
+++ b/api/applib/src/main/java/org/apache/causeway/applib/services/acceptheader/AcceptHeaderService.java
@@ -20,7 +20,7 @@
import java.util.List;
-import jakarta.ws.rs.core.MediaType;
+import org.springframework.http.MediaType;
/**
* This service simply exposes the HTTP `Accept` header to the domain.
diff --git a/api/applib/src/main/java/org/apache/causeway/applib/services/commanddto/conmap/ContentMappingServiceForCommandDto.java b/api/applib/src/main/java/org/apache/causeway/applib/services/commanddto/conmap/ContentMappingServiceForCommandDto.java
index dcb5bc68dd3..5182a3f4a4c 100644
--- a/api/applib/src/main/java/org/apache/causeway/applib/services/commanddto/conmap/ContentMappingServiceForCommandDto.java
+++ b/api/applib/src/main/java/org/apache/causeway/applib/services/commanddto/conmap/ContentMappingServiceForCommandDto.java
@@ -23,7 +23,7 @@
import jakarta.annotation.Priority;
import jakarta.inject.Inject;
import jakarta.inject.Named;
-import jakarta.ws.rs.core.MediaType;
+import org.springframework.http.MediaType;
import org.springframework.beans.factory.annotation.Qualifier;
import org.jspecify.annotations.Nullable;
diff --git a/api/applib/src/main/java/org/apache/causeway/applib/services/commanddto/conmap/ContentMappingServiceForCommandsDto.java b/api/applib/src/main/java/org/apache/causeway/applib/services/commanddto/conmap/ContentMappingServiceForCommandsDto.java
index 014321c405d..b0b275aefb7 100644
--- a/api/applib/src/main/java/org/apache/causeway/applib/services/commanddto/conmap/ContentMappingServiceForCommandsDto.java
+++ b/api/applib/src/main/java/org/apache/causeway/applib/services/commanddto/conmap/ContentMappingServiceForCommandsDto.java
@@ -23,7 +23,7 @@
import jakarta.annotation.Priority;
import jakarta.inject.Inject;
import jakarta.inject.Named;
-import jakarta.ws.rs.core.MediaType;
+import org.springframework.http.MediaType;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Service;
diff --git a/api/applib/src/main/java/org/apache/causeway/applib/services/conmap/ContentMappingService.java b/api/applib/src/main/java/org/apache/causeway/applib/services/conmap/ContentMappingService.java
index 425bc6ff1fe..0c26aa1b95a 100644
--- a/api/applib/src/main/java/org/apache/causeway/applib/services/conmap/ContentMappingService.java
+++ b/api/applib/src/main/java/org/apache/causeway/applib/services/conmap/ContentMappingService.java
@@ -22,7 +22,7 @@
import java.util.Map;
import java.util.stream.Collectors;
-import jakarta.ws.rs.core.MediaType;
+import org.springframework.http.MediaType;
import org.apache.causeway.commons.internal.base._NullSafe;
diff --git a/bom/pom.xml b/bom/pom.xml
index 5f0e734349b..494f75323ea 100644
--- a/bom/pom.xml
+++ b/bom/pom.xml
@@ -137,13 +137,6 @@ identified
<quartz-scheduler.version>2.5.0</quartz-scheduler.version>
<querydsl.version>5.1.0</querydsl.version>
- <resteasy-spring-boot.version>6.0.0.Alpha2</resteasy-spring-boot.version>
- <resteasy-spring.version>3.2.0.Final</resteasy-spring.version>
- <resteasy.version>6.2.12.Final</resteasy.version> <!-- be awre of
- potential clashes with
- https://mvnrepository.com/artifact/org.jboss.resteasy/resteasy-spring-boot-starter -->
- <resteasy-jaxb-provider.version>6.2.2.Final</resteasy-jaxb-provider.version>
-
<select2.version>4.0.13</select2.version>
<simpleslackapi.version>1.4.0</simpleslackapi.version>
<slf4j-api.version>2.0.17</slf4j-api.version> <!-- also provided by
@@ -527,13 +520,6 @@ identified
<type>jar</type>
<scope>compile</scope>
</dependency>
- <dependency>
- <groupId>org.apache.causeway.viewer</groupId>
- <artifactId>causeway-viewer-restfulobjects-jaxrsresteasy</artifactId>
- <version>${project.version}</version>
- <type>jar</type>
- <scope>compile</scope>
- </dependency>
<dependency>
<groupId>org.apache.causeway.viewer</groupId>
<artifactId>causeway-viewer-restfulobjects-rendering</artifactId>
@@ -1839,23 +1825,6 @@ identified
<version>${jdom.version}</version>
</dependency>
-
- <dependency>
- <groupId>org.jboss.resteasy</groupId>
- <artifactId>resteasy-spring-boot-starter</artifactId>
- <version>${resteasy-spring-boot.version}</version>
- </dependency>
- <dependency>
- <groupId>org.jboss.resteasy.spring</groupId>
- <artifactId>resteasy-spring</artifactId>
- <version>${resteasy-spring.version}</version>
- </dependency>
- <dependency>
- <groupId>org.jboss.resteasy</groupId>
- <artifactId>resteasy-jaxb-provider</artifactId>
- <version>${resteasy.version}</version>
- </dependency>
-
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-quartz</artifactId>
diff --git a/core/config/src/main/java/module-info.java b/core/config/src/main/java/module-info.java
index 91930fc0f63..874c86f014a 100644
--- a/core/config/src/main/java/module-info.java
+++ b/core/config/src/main/java/module-info.java
@@ -42,7 +42,6 @@
requires jakarta.persistence;
requires java.sql;
requires jakarta.validation;
- requires jakarta.ws.rs;
requires jakarta.inject;
requires org.hibernate.validator;
requires spring.aop;
diff --git a/extensions/core/executionoutbox/applib/src/main/java/org/apache/causeway/extensions/executionoutbox/applib/spiimpl/ContentMappingServiceForOutboxEvents.java b/extensions/core/executionoutbox/applib/src/main/java/org/apache/causeway/extensions/executionoutbox/applib/spiimpl/ContentMappingServiceForOutboxEvents.java
index 43d45ec6637..ccf2c417191 100644
--- a/extensions/core/executionoutbox/applib/src/main/java/org/apache/causeway/extensions/executionoutbox/applib/spiimpl/ContentMappingServiceForOutboxEvents.java
+++ b/extensions/core/executionoutbox/applib/src/main/java/org/apache/causeway/extensions/executionoutbox/applib/spiimpl/ContentMappingServiceForOutboxEvents.java
@@ -23,7 +23,7 @@
import java.util.List;
import java.util.Objects;
-import jakarta.ws.rs.core.MediaType;
+import org.springframework.http.MediaType;
import org.springframework.stereotype.Service;
diff --git a/extensions/core/executionoutbox/restclient/pom.xml b/extensions/core/executionoutbox/restclient/pom.xml
index 2aeddf6b9f4..e0875af9716 100644
--- a/extensions/core/executionoutbox/restclient/pom.xml
+++ b/extensions/core/executionoutbox/restclient/pom.xml
@@ -40,25 +40,6 @@
</properties>
- <build>
- <resources>
- <resource>
- <filtering>false</filtering>
- <directory>src/main/resources</directory>
- </resource>
- <resource>
- <filtering>false</filtering>
- <directory>src/main/java</directory>
- <includes>
- <include>**</include>
- </includes>
- <excludes>
- <exclude>**/*.java</exclude>
- </excludes>
- </resource>
- </resources>
- </build>
-
<dependencies>
<dependency>
@@ -120,10 +101,10 @@
<type>pom</type>
<scope>test</scope>
</dependency>
- <dependency>
- <groupId>org.apache.causeway.viewer</groupId>
- <artifactId>causeway-viewer-restfulobjects-jaxrsresteasy</artifactId>
- </dependency>
+<!-- <dependency>-->
+<!-- <groupId>org.apache.causeway.viewer</groupId>-->
+<!-- <artifactId>causeway-viewer-restfulobjects-jaxrsresteasy</artifactId>-->
+<!-- </dependency>-->
<dependency>
<groupId>com.h2database</groupId>
diff --git a/extensions/core/executionoutbox/restclient/src/main/java/org/apache/causeway/extensions/executionoutbox/restclient/api/OutboxClient.java b/extensions/core/executionoutbox/restclient/src/main/java/org/apache/causeway/extensions/executionoutbox/restclient/api/OutboxClient.java
index 43712be9f0f..60f524374ef 100644
--- a/extensions/core/executionoutbox/restclient/src/main/java/org/apache/causeway/extensions/executionoutbox/restclient/api/OutboxClient.java
+++ b/extensions/core/executionoutbox/restclient/src/main/java/org/apache/causeway/extensions/executionoutbox/restclient/api/OutboxClient.java
@@ -25,7 +25,7 @@
import jakarta.ws.rs.client.Entity;
import jakarta.ws.rs.client.Invocation;
-import jakarta.ws.rs.core.MediaType;
+import org.springframework.http.MediaType;
import org.apache.causeway.applib.util.schema.InteractionsDtoUtils;
import org.apache.causeway.commons.functional.Try;
@@ -119,7 +119,7 @@ public OutboxClient withReadTimeoutInSecs(final int readTimeoutInSecs) {
public List<InteractionDto> pending() {
Invocation.Builder invocationBuilder = client.request(outboxClientConfig.getPendingUri())
- .accept(RestfulClientMediaType.RO_XML.mediaTypeFor(InteractionsDto.class));
+ .accept(RestfulClientMediaType.RO_XML.mediaTypeFor(InteractionsDto.class).getType());
var response = invocationBuilder.get();
final Try<InteractionsDto> digest = client.digest(response, InteractionsDto.class);
@@ -171,7 +171,7 @@ private void invoke(final String path, final Object dto) {
var invocationBuilder = client.request(path);
var invocation = invocationBuilder.buildPut(
- Entity.entity(JsonUtils.toStringUtf8(dto), MediaType.APPLICATION_JSON_TYPE));
+ Entity.entity(JsonUtils.toStringUtf8(dto), MediaType.APPLICATION_JSON_VALUE));
var response = invocation.invoke();
diff --git a/extensions/core/executionoutbox/restclient/src/test/java/org/apache/causeway/extensions/executionoutbox/restclient/integtests/OutboxRestClient_IntegTest.java b/extensions/core/executionoutbox/restclient/src/test/java/org/apache/causeway/extensions/executionoutbox/restclient/integtests/OutboxRestClient_IntegTest.java
index 029c7b7246e..e2fc971dd64 100644
--- a/extensions/core/executionoutbox/restclient/src/test/java/org/apache/causeway/extensions/executionoutbox/restclient/integtests/OutboxRestClient_IntegTest.java
+++ b/extensions/core/executionoutbox/restclient/src/test/java/org/apache/causeway/extensions/executionoutbox/restclient/integtests/OutboxRestClient_IntegTest.java
@@ -56,8 +56,6 @@
import org.apache.causeway.schema.ixn.v2.InteractionDto;
import org.apache.causeway.security.bypass.CausewayModuleSecurityBypass;
import org.apache.causeway.testing.fixtures.applib.CausewayModuleTestingFixturesApplib;
-import org.apache.causeway.viewer.restfulobjects.jaxrsresteasy.conneg.RestfulObjectsJaxbWriterForXml;
-import org.apache.causeway.viewer.restfulobjects.jaxrsresteasy.webmodule.WebModuleJaxrsResteasy;
import org.apache.causeway.viewer.restfulobjects.viewer.CausewayModuleViewerRestfulObjectsViewer;
@SpringBootTest(
@@ -73,8 +71,8 @@
//CausewayModuleViewerRestfulObjectsJaxrsResteasy.class, // replaced
SpringBeanProcessorRegressionWorkaround.class,
CausewayModuleViewerRestfulObjectsViewer.class,
- WebModuleJaxrsResteasy.class,
- RestfulObjectsJaxbWriterForXml.class,
+ //WebModuleJaxrsResteasy.class,
+ //RestfulObjectsJaxbWriterForXml.class,
// ---
CausewayModuleCoreWebapp.class,
diff --git a/extensions/core/executionoutbox/restclient/src/test/java/org/apache/causeway/extensions/executionoutbox/restclient/integtests/SpringBeanProcessorRegressionWorkaround.java b/extensions/core/executionoutbox/restclient/src/test/java/org/apache/causeway/extensions/executionoutbox/restclient/integtests/SpringBeanProcessorRegressionWorkaround.java
index 32f6a764d6d..0714a0516a7 100644
--- a/extensions/core/executionoutbox/restclient/src/test/java/org/apache/causeway/extensions/executionoutbox/restclient/integtests/SpringBeanProcessorRegressionWorkaround.java
+++ b/extensions/core/executionoutbox/restclient/src/test/java/org/apache/causeway/extensions/executionoutbox/restclient/integtests/SpringBeanProcessorRegressionWorkaround.java
@@ -18,50 +18,36 @@
*/
package org.apache.causeway.extensions.executionoutbox.restclient.integtests;
-import java.lang.annotation.Annotation;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Set;
+//import java.lang.annotation.Annotation;
+//import java.util.HashSet;
+//import java.util.List;
+//import java.util.Set;
+//
+//import jakarta.persistence.EntityManagerFactory;
+//import jakarta.servlet.ServletContext;
+//import jakarta.servlet.ServletContextEvent;
+//import jakarta.servlet.ServletContextListener;
+//import jakarta.ws.rs.Path;
+//import jakarta.ws.rs.ext.Provider;
+//
+//import org.springframework.beans.BeansException;
+//import org.springframework.beans.factory.annotation.Qualifier;
+//import org.springframework.beans.factory.config.BeanDefinition;
+//import org.springframework.beans.factory.config.BeanFactoryPostProcessor;
+//import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
+//import org.springframework.beans.factory.support.BeanDefinitionRegistry;
+//import org.springframework.beans.factory.support.GenericBeanDefinition;
+//import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
+//import org.springframework.context.annotation.Bean;
+//import org.springframework.context.annotation.ClassPathScanningCandidateComponentProvider;
+//import org.springframework.context.annotation.Configuration;
+//import org.springframework.context.annotation.Primary;
+//import org.springframework.core.PriorityOrdered;
+//import org.springframework.core.env.ConfigurableEnvironment;
+//import org.springframework.core.type.filter.AnnotationTypeFilter;
+//import org.springframework.util.ClassUtils;
-import jakarta.persistence.EntityManagerFactory;
-import jakarta.servlet.ServletContext;
-import jakarta.servlet.ServletContextEvent;
-import jakarta.servlet.ServletContextListener;
-import jakarta.ws.rs.Path;
-import jakarta.ws.rs.ext.Provider;
-import org.jboss.resteasy.core.AsynchronousDispatcher;
-import org.jboss.resteasy.core.ResourceMethodRegistry;
-import org.jboss.resteasy.core.ResteasyContext;
-import org.jboss.resteasy.core.SynchronousDispatcher;
-import org.jboss.resteasy.plugins.server.servlet.ListenerBootstrap;
-import org.jboss.resteasy.plugins.server.servlet.ResteasyBootstrap;
-import org.jboss.resteasy.plugins.spring.SpringBeanProcessor;
-import org.jboss.resteasy.spi.Dispatcher;
-import org.jboss.resteasy.spi.Registry;
-import org.jboss.resteasy.spi.ResteasyDeployment;
-import org.jboss.resteasy.spi.ResteasyProviderFactory;
-
-import org.springframework.beans.BeansException;
-import org.springframework.beans.factory.annotation.Qualifier;
-import org.springframework.beans.factory.config.BeanDefinition;
-import org.springframework.beans.factory.config.BeanFactoryPostProcessor;
-import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
-import org.springframework.beans.factory.support.BeanDefinitionRegistry;
-import org.springframework.beans.factory.support.GenericBeanDefinition;
-import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
-import org.springframework.context.annotation.Bean;
-import org.springframework.context.annotation.ClassPathScanningCandidateComponentProvider;
-import org.springframework.context.annotation.Configuration;
-import org.springframework.context.annotation.Primary;
-import org.springframework.core.PriorityOrdered;
-import org.springframework.core.env.ConfigurableEnvironment;
-import org.springframework.core.type.filter.AnnotationTypeFilter;
-import org.springframework.util.ClassUtils;
-
-import org.apache.causeway.viewer.restfulobjects.jaxrsresteasy.CausewayModuleViewerRestfulObjectsJaxrsResteasy;
-
-import lombok.extern.slf4j.Slf4j;
/**
* RESTEASY013015: could not find the type for bean named jpaSharedEM_entityManagerFactory
@@ -72,188 +58,183 @@
* If seeing this in production, we need to propagate the workaround to
* {@link CausewayModuleViewerRestfulObjectsJaxrsResteasy}.
*/
-@Configuration
-@Slf4j
+//@Configuration
+//@Slf4j
class SpringBeanProcessorRegressionWorkaround {
- @Bean @Primary
- @Qualifier("ResteasyProviderFactory")
- public static BeanFactoryPostProcessor springBeanProcessor() {
- var blackListed = List.of("jpaSharedEM_entityManagerFactory", "jpaSharedEM_AWC_entityManagerFactory");
-
- ResteasyProviderFactory resteasyProviderFactory = ResteasyProviderFactory.newInstance();
- ResourceMethodRegistry resourceMethodRegistry = new ResourceMethodRegistry(resteasyProviderFactory);
-
- SpringBeanProcessor springBeanProcessor = new SpringBeanProcessor() {
-
- @Override
- protected Class<?> processBean(final ConfigurableListableBeanFactory beanFactory,
- final List<String> dependsOnProviders, final String name, final BeanDefinition beanDef) {
-
- if(blackListed.contains(name)) {
- return EntityManagerFactory.class;
- }
-
- return super.processBean(beanFactory, dependsOnProviders, name, beanDef);
- }
-
- };
- springBeanProcessor.setProviderFactory(resteasyProviderFactory);
- springBeanProcessor.setRegistry(resourceMethodRegistry);
-
- return springBeanProcessor;
- }
-
- /**
- * Scanner bean factory post processor that is responsible for scanning classpath
- * (configured packages for JAX RS resources and providers).
- *
- * It's meant to run as on of the first bean factory post processors so others, especially
- * <code>org.jboss.resteasy.plugins.spring.SpringBeanProcessor</code> can find the bean definitions produced by this class.
- *
- * This class is not active unless <code>resteasy.jaxrs.scan-packages</code> property is set.
- *
- */
- public static class JAXRSResourcesAndProvidersScannerPostProcessor implements BeanFactoryPostProcessor, PriorityOrdered {
-
- private static final String JAXRS_SCAN_PACKAGES_PROPERTY = "resteasy.jaxrs.scan-packages";
-
- @Override
- public int getOrder() {
- return 0;
- }
-
- @Override
- public void postProcessBeanFactory(final ConfigurableListableBeanFactory beanFactory) throws BeansException {
- ConfigurableEnvironment configurableEnvironment = beanFactory.getBean(ConfigurableEnvironment.class);
- String jaxrsScanPackages = configurableEnvironment.getProperty(JAXRS_SCAN_PACKAGES_PROPERTY);
-
-
- Set<Class<?>> provicerClasses = findJaxrsResourcesOrProviderClasses(jaxrsScanPackages, Provider.class);
- for (Class<?> providerClazz : provicerClasses) {
- registerScannedBean(beanFactory, providerClazz);
- }
-
- Set<Class<?>> resourceClasses = findJaxrsResourcesOrProviderClasses(jaxrsScanPackages, Path.class);
- for (Class<?> resourceClazz : resourceClasses) {
- registerScannedBean(beanFactory, resourceClazz);
- }
-
- }
-
- /*
- * Creates singleton bean definition for found classes that represent either JAX RS resource or provider
- */
- private void registerScannedBean(final ConfigurableListableBeanFactory beanFactory, final Class<?> clazz) {
- BeanDefinitionRegistry registry = (BeanDefinitionRegistry) beanFactory;
-
- GenericBeanDefinition bean = new GenericBeanDefinition();
- bean.setBeanClass(clazz);
- bean.setAutowireCandidate(true);
- bean.setScope("singleton");
-
- registry.registerBeanDefinition(clazz.getName(), bean);
- }
-
- /*
- * Scan the classpath under the specified packages looking for JAX-RS resources and providers
- */
- private static Set<Class<?>> findJaxrsResourcesOrProviderClasses(final String packagesToBeScanned, final Class<? extends Annotation> annotationType) {
- log.info("Scanning classpath to find JAX-RS classes annotated with {}", annotationType);
-
- ClassPathScanningCandidateComponentProvider scanner = new ClassPathScanningCandidateComponentProvider(false);
- scanner.addIncludeFilter(new AnnotationTypeFilter(annotationType));
-
- Set<BeanDefinition> candidates = new HashSet<BeanDefinition>();
- Set<BeanDefinition> candidatesSubSet;
-
- for (String packageToScan : packagesToBeScanned.split(",")) {
- candidatesSubSet = scanner.findCandidateComponents(packageToScan.trim());
- candidates.addAll(candidatesSubSet);
- }
-
- Set<Class<?>> classes = new HashSet<>();
- ClassLoader classLoader = JAXRSResourcesAndProvidersScannerPostProcessor.class.getClassLoader();
- Class<?> type;
- for (BeanDefinition candidate : candidates) {
- try {
- type = ClassUtils.forName(candidate.getBeanClassName(), classLoader);
- classes.add(type);
- } catch (ClassNotFoundException e) {
- log.error("JAX-RS Resource/Provider could not be loaded", e);
- }
- }
- return classes;
- }
- }
-
-
- @Bean
- @ConditionalOnProperty(name="resteasy.jaxrs.scan-packages")
- public static JAXRSResourcesAndProvidersScannerPostProcessor providerScannerPostProcessor() {
- return new JAXRSResourcesAndProvidersScannerPostProcessor();
- }
-
- /**
- * This is a modified version of {@link ResteasyBootstrap}
- *
- * @return a ServletContextListener object that configures and start a ResteasyDeployment
- */
- @Bean
- public ServletContextListener resteasyBootstrapListener(@Qualifier("ResteasyProviderFactory") final BeanFactoryPostProcessor beanFactoryPostProcessor) {
- ServletContextListener servletContextListener = new ServletContextListener() {
-
- private SpringBeanProcessor springBeanProcessor = (SpringBeanProcessor) beanFactoryPostProcessor;
-
- protected ResteasyDeployment deployment;
-
- @Override
- public void contextInitialized(final ServletContextEvent sce) {
- ServletContext servletContext = sce.getServletContext();
- ResteasyContext.pushContext(ServletContext.class, servletContext);
- ListenerBootstrap config = new ListenerBootstrap(servletContext);
-
- ResteasyProviderFactory resteasyProviderFactory = springBeanProcessor.getProviderFactory();
- ResourceMethodRegistry resourceMethodRegistry = (ResourceMethodRegistry) springBeanProcessor.getRegistry();
-
- deployment = config.createDeployment();
-
- deployment.setProviderFactory(resteasyProviderFactory);
- deployment.setRegistry(resourceMethodRegistry);
-
- if (deployment.isAsyncJobServiceEnabled()) {
- AsynchronousDispatcher dispatcher = new AsynchronousDispatcher(resteasyProviderFactory, resourceMethodRegistry);
- deployment.setDispatcher(dispatcher);
- } else {
- SynchronousDispatcher dispatcher = new SynchronousDispatcher(resteasyProviderFactory, resourceMethodRegistry);
- deployment.setDispatcher(dispatcher);
- }
-
- deployment.start();
-
- servletContext.setAttribute(ResteasyProviderFactory.class.getName(), deployment.getProviderFactory());
- servletContext.setAttribute(Dispatcher.class.getName(), deployment.getDispatcher());
- servletContext.setAttribute(Registry.class.getName(), deployment.getRegistry());
- }
-
- @Override
- public void contextDestroyed(final ServletContextEvent sce) {
- try {
- if (deployment != null) {
- deployment.stop();
- }
- } finally {
- ResteasyContext.popContextData(ServletContext.class);
- }
- }
- };
-
- return servletContextListener;
- }
-
+// @Bean @Primary
+// @Qualifier("ResteasyProviderFactory")
+// public static BeanFactoryPostProcessor springBeanProcessor() {
+// var blackListed = List.of("jpaSharedEM_entityManagerFactory", "jpaSharedEM_AWC_entityManagerFactory");
+//
+// ResteasyProviderFactory resteasyProviderFactory = ResteasyProviderFactory.newInstance();
+// ResourceMethodRegistry resourceMethodRegistry = new ResourceMethodRegistry(resteasyProviderFactory);
+//
+// SpringBeanProcessor springBeanProcessor = new SpringBeanProcessor() {
+//
+// @Override
+// protected Class<?> processBean(final ConfigurableListableBeanFactory beanFactory,
+// final List<String> dependsOnProviders, final String name, final BeanDefinition beanDef) {
+//
+// if(blackListed.contains(name)) {
+// return EntityManagerFactory.class;
+// }
+//
+// return super.processBean(beanFactory, dependsOnProviders, name, beanDef);
+// }
+//
+// };
+// springBeanProcessor.setProviderFactory(resteasyProviderFactory);
+// springBeanProcessor.setRegistry(resourceMethodRegistry);
+//
+// return springBeanProcessor;
+// }
+//
+// /**
+// * Scanner bean factory post processor that is responsible for scanning classpath
+// * (configured packages for JAX RS resources and providers).
+// *
+// * It's meant to run as on of the first bean factory post processors so others, especially
+// * <code>org.jboss.resteasy.plugins.spring.SpringBeanProcessor</code> can find the bean definitions produced by this class.
+// *
+// * This class is not active unless <code>resteasy.jaxrs.scan-packages</code> property is set.
+// *
+// */
+// public static class JAXRSResourcesAndProvidersScannerPostProcessor implements BeanFactoryPostProcessor, PriorityOrdered {
+//
+// private static final String JAXRS_SCAN_PACKAGES_PROPERTY = "resteasy.jaxrs.scan-packages";
+//
+// @Override
+// public int getOrder() {
+// return 0;
+// }
+//
+// @Override
+// public void postProcessBeanFactory(final ConfigurableListableBeanFactory beanFactory) throws BeansException {
+// ConfigurableEnvironment configurableEnvironment = beanFactory.getBean(ConfigurableEnvironment.class);
+// String jaxrsScanPackages = configurableEnvironment.getProperty(JAXRS_SCAN_PACKAGES_PROPERTY);
+//
+//
+// Set<Class<?>> provicerClasses = findJaxrsResourcesOrProviderClasses(jaxrsScanPackages, Provider.class);
+// for (Class<?> providerClazz : provicerClasses) {
+// registerScannedBean(beanFactory, providerClazz);
+// }
+//
+// Set<Class<?>> resourceClasses = findJaxrsResourcesOrProviderClasses(jaxrsScanPackages, Path.class);
+// for (Class<?> resourceClazz : resourceClasses) {
+// registerScannedBean(beanFactory, resourceClazz);
+// }
+//
+// }
+//
+// /*
+// * Creates singleton bean definition for found classes that represent either JAX RS resource or provider
+// */
+// private void registerScannedBean(final ConfigurableListableBeanFactory beanFactory, final Class<?> clazz) {
+// BeanDefinitionRegistry registry = (BeanDefinitionRegistry) beanFactory;
+//
+// GenericBeanDefinition bean = new GenericBeanDefinition();
+// bean.setBeanClass(clazz);
+// bean.setAutowireCandidate(true);
+// bean.setScope("singleton");
+//
+// registry.registerBeanDefinition(clazz.getName(), bean);
+// }
+//
+// /*
+// * Scan the classpath under the specified packages looking for JAX-RS resources and providers
+// */
+// private static Set<Class<?>> findJaxrsResourcesOrProviderClasses(final String packagesToBeScanned, final Class<? extends Annotation> annotationType) {
+// log.info("Scanning classpath to find JAX-RS classes annotated with {}", annotationType);
+//
+// ClassPathScanningCandidateComponentProvider scanner = new ClassPathScanningCandidateComponentProvider(false);
+// scanner.addIncludeFilter(new AnnotationTypeFilter(annotationType));
+//
+// Set<BeanDefinition> candidates = new HashSet<BeanDefinition>();
+// Set<BeanDefinition> candidatesSubSet;
+//
+// for (String packageToScan : packagesToBeScanned.split(",")) {
+// candidatesSubSet = scanner.findCandidateComponents(packageToScan.trim());
+// candidates.addAll(candidatesSubSet);
+// }
+//
+// Set<Class<?>> classes = new HashSet<>();
+// ClassLoader classLoader = JAXRSResourcesAndProvidersScannerPostProcessor.class.getClassLoader();
+// Class<?> type;
+// for (BeanDefinition candidate : candidates) {
+// try {
+// type = ClassUtils.forName(candidate.getBeanClassName(), classLoader);
+// classes.add(type);
+// } catch (ClassNotFoundException e) {
+// log.error("JAX-RS Resource/Provider could not be loaded", e);
+// }
+// }
+// return classes;
+// }
+// }
+//
+//
+// @Bean
+// @ConditionalOnProperty(name="resteasy.jaxrs.scan-packages")
+// public static JAXRSResourcesAndProvidersScannerPostProcessor providerScannerPostProcessor() {
+// return new JAXRSResourcesAndProvidersScannerPostProcessor();
+// }
+//
+// /**
+// * This is a modified version of {@link ResteasyBootstrap}
+// *
+// * @return a ServletContextListener object that configures and start a ResteasyDeployment
+// */
// @Bean
-// public static ResteasyEmbeddedServletInitializer resteasyEmbeddedServletInitializer() {
-// return new ResteasyEmbeddedServletInitializer();
+// public ServletContextListener resteasyBootstrapListener(@Qualifier("ResteasyProviderFactory") final BeanFactoryPostProcessor beanFactoryPostProcessor) {
+// ServletContextListener servletContextListener = new ServletContextListener() {
+//
+// private SpringBeanProcessor springBeanProcessor = (SpringBeanProcessor) beanFactoryPostProcessor;
+//
+// protected ResteasyDeployment deployment;
+//
+// @Override
+// public void contextInitialized(final ServletContextEvent sce) {
+// ServletContext servletContext = sce.getServletContext();
+// ResteasyContext.pushContext(ServletContext.class, servletContext);
+// ListenerBootstrap config = new ListenerBootstrap(servletContext);
+//
+// ResteasyProviderFactory resteasyProviderFactory = springBeanProcessor.getProviderFactory();
+// ResourceMethodRegistry resourceMethodRegistry = (ResourceMethodRegistry) springBeanProcessor.getRegistry();
+//
+// deployment = config.createDeployment();
+//
+// deployment.setProviderFactory(resteasyProviderFactory);
+// deployment.setRegistry(resourceMethodRegistry);
+//
+// if (deployment.isAsyncJobServiceEnabled()) {
+// AsynchronousDispatcher dispatcher = new AsynchronousDispatcher(resteasyProviderFactory, resourceMethodRegistry);
+// deployment.setDispatcher(dispatcher);
+// } else {
+// SynchronousDispatcher dispatcher = new SynchronousDispatcher(resteasyProviderFactory, resourceMethodRegistry);
+// deployment.setDispatcher(dispatcher);
+// }
+//
+// deployment.start();
+//
+// servletContext.setAttribute(ResteasyProviderFactory.class.getName(), deployment.getProviderFactory());
+// servletContext.setAttribute(Dispatcher.class.getName(), deployment.getDispatcher());
+// servletContext.setAttribute(Registry.class.getName(), deployment.getRegistry());
+// }
+//
+// @Override
+// public void contextDestroyed(final ServletContextEvent sce) {
+// try {
+// if (deployment != null) {
+// deployment.stop();
+// }
+// } finally {
+// ResteasyContext.popContextData(ServletContext.class);
+// }
+// }
+// };
+//
+// return servletContextListener;
// }
}
diff --git a/incubator/extensions/core/commandreplay/secondary/pom.xml b/incubator/extensions/core/commandreplay/secondary/pom.xml
index 8fd632105c5..bda7590670c 100644
--- a/incubator/extensions/core/commandreplay/secondary/pom.xml
+++ b/incubator/extensions/core/commandreplay/secondary/pom.xml
@@ -83,11 +83,11 @@
<scope>test</scope>
</dependency>
- <dependency>
- <groupId>org.apache.causeway.viewer</groupId>
- <artifactId>causeway-viewer-restfulobjects-jaxrsresteasy</artifactId>
- <scope>test</scope>
- </dependency>
+<!-- <dependency>-->
+<!-- <groupId>org.apache.causeway.viewer</groupId>-->
+<!-- <artifactId>causeway-viewer-restfulobjects-jaxrsresteasy</artifactId>-->
+<!-- <scope>test</scope>-->
+<!-- </dependency>-->
<dependency>
<groupId>org.glassfish.jersey.ext</groupId>
diff --git a/incubator/extensions/core/commandreplay/secondary/src/main/java/org/apache/causeway/extensions/commandreplay/secondary/fetch/CommandFetcher.java b/incubator/extensions/core/commandreplay/secondary/src/main/java/org/apache/causeway/extensions/commandreplay/secondary/fetch/CommandFetcher.java
index 68bc6371b33..ea81d1d66b6 100644
--- a/incubator/extensions/core/commandreplay/secondary/src/main/java/org/apache/causeway/extensions/commandreplay/secondary/fetch/CommandFetcher.java
+++ b/incubator/extensions/core/commandreplay/secondary/src/main/java/org/apache/causeway/extensions/commandreplay/secondary/fetch/CommandFetcher.java
@@ -109,7 +109,7 @@ Can<CommandDto> callPrimary(final @Nullable UUID interactionId) throws StatusExc
var client = newClient(secondaryConfig, useRequestDebugLogging);
var request = client.request(URL_SUFFIX)
- .accept(RestfulClientMediaType.SIMPLE_JSON.mediaTypeFor(CommandDto.class, EnumSet.of(SuppressionType.RO)));
+ .accept(RestfulClientMediaType.SIMPLE_JSON.mediaTypeFor(CommandDto.class, EnumSet.of(SuppressionType.RO)).getType());
var args = client.arguments()
.addActionParameter("interactionId", interactionId!=null ? interactionId.toString() : null)
diff --git a/regressiontests/base-jpa/pom.xml b/regressiontests/base-jpa/pom.xml
index 24fd6ce4c11..ed8b478bc87 100644
--- a/regressiontests/base-jpa/pom.xml
+++ b/regressiontests/base-jpa/pom.xml
@@ -72,11 +72,11 @@
<type>pom</type>
<optional>true</optional>
</dependency>
- <dependency>
- <groupId>org.apache.causeway.viewer</groupId>
- <artifactId>causeway-viewer-restfulobjects-jaxrsresteasy</artifactId>
- <optional>true</optional>
- </dependency>
+<!-- <dependency>-->
+<!-- <groupId>org.apache.causeway.viewer</groupId>-->
+<!-- <artifactId>causeway-viewer-restfulobjects-jaxrsresteasy</artifactId>-->
+<!-- <optional>true</optional>-->
+<!-- </dependency>-->
<dependency>
<groupId>org.apache.causeway.viewer</groupId>
<artifactId>causeway-viewer-wicket-viewer</artifactId>
diff --git a/regressiontests/base-jpa/src/main/java/org/apache/causeway/testdomain/jpa/rest/JpaRestEndpointService.java b/regressiontests/base-jpa/src/main/java/org/apache/causeway/testdomain/jpa/rest/JpaRestEndpointService.java
index 67accf8c253..ce360c88b15 100644
--- a/regressiontests/base-jpa/src/main/java/org/apache/causeway/testdomain/jpa/rest/JpaRestEndpointService.java
+++ b/regressiontests/base-jpa/src/main/java/org/apache/causeway/testdomain/jpa/rest/JpaRestEndpointService.java
@@ -111,7 +111,7 @@ public RestfulClient newClient(
public Invocation.Builder newInvocationBuilder(final RestfulClient client, final String endpointPath) {
return client.request(endpointPath)
- .accept(RestfulClientMediaType.SIMPLE_JSON.mediaTypeFor(Object.class, SuppressionType.all()));
+ .accept(RestfulClientMediaType.SIMPLE_JSON.mediaTypeFor(Object.class, SuppressionType.all()).getType());
}
// -- ENDPOINTS
diff --git a/regressiontests/base/pom.xml b/regressiontests/base/pom.xml
index 67a0d63811e..7fa90587913 100644
--- a/regressiontests/base/pom.xml
+++ b/regressiontests/base/pom.xml
@@ -108,11 +108,11 @@
<type>pom</type>
<optional>true</optional>
</dependency>
- <dependency>
- <groupId>org.apache.causeway.viewer</groupId>
- <artifactId>causeway-viewer-restfulobjects-jaxrsresteasy</artifactId>
- <optional>true</optional>
- </dependency>
+<!-- <dependency>-->
+<!-- <groupId>org.apache.causeway.viewer</groupId>-->
+<!-- <artifactId>causeway-viewer-restfulobjects-jaxrsresteasy</artifactId>-->
+<!-- <optional>true</optional>-->
+<!-- </dependency>-->
<dependency>
<groupId>org.apache.causeway.viewer</groupId>
<artifactId>causeway-viewer-wicket-viewer</artifactId>
diff --git a/regressiontests/rest-jpa/pom.xml b/regressiontests/rest-jpa/pom.xml
index 71265b3a4d9..389463f6bf1 100644
--- a/regressiontests/rest-jpa/pom.xml
+++ b/regressiontests/rest-jpa/pom.xml
@@ -68,11 +68,11 @@
<artifactId>causeway-mavendeps-webapp</artifactId>
<type>pom</type>
</dependency>
- <dependency>
- <groupId>org.apache.causeway.viewer</groupId>
- <artifactId>causeway-viewer-restfulobjects-jaxrsresteasy</artifactId>
- <scope>test</scope>
- </dependency>
+<!-- <dependency>-->
+<!-- <groupId>org.apache.causeway.viewer</groupId>-->
+<!-- <artifactId>causeway-viewer-restfulobjects-jaxrsresteasy</artifactId>-->
+<!-- <scope>test</scope>-->
+<!-- </dependency>-->
<dependency>
<groupId>org.apache.causeway.extensions</groupId>
diff --git a/viewers/restfulobjects/applib/pom.xml b/viewers/restfulobjects/applib/pom.xml
index 3c2572d04ee..ca97ff18a94 100644
--- a/viewers/restfulobjects/applib/pom.xml
+++ b/viewers/restfulobjects/applib/pom.xml
@@ -17,7 +17,9 @@
specific language governing permissions and limitations
under the License.
-->
-<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
@@ -26,12 +28,14 @@
<version>${revision}</version>
</parent>
- <artifactId>causeway-viewer-restfulobjects-applib</artifactId>
- <name>Apache Causeway Viewer - RO (AppLib)</name>
+ <artifactId>causeway-viewer-restfulobjects-applib</artifactId>
+ <name>Apache Causeway Viewer - RO (AppLib)</name>
<properties>
- <jar-plugin.automaticModuleName>org.apache.causeway.viewer.restfulobjects.applib</jar-plugin.automaticModuleName>
- <git-plugin.propertiesDir>org/apache/causeway/viewer/restfulobjects/applib</git-plugin.propertiesDir>
+ <jar-plugin.automaticModuleName>
+ org.apache.causeway.viewer.restfulobjects.applib</jar-plugin.automaticModuleName>
+ <git-plugin.propertiesDir>
+ org/apache/causeway/viewer/restfulobjects/applib</git-plugin.propertiesDir>
</properties>
<dependencies>
@@ -40,12 +44,23 @@
<groupId>org.apache.causeway.core</groupId>
<artifactId>causeway-applib</artifactId>
</dependency>
-
+
<dependency>
<groupId>org.apache.causeway.commons</groupId>
<artifactId>causeway-commons</artifactId>
</dependency>
+<!-- TODO CAUSEWAY-3892 should no longer be required-->
+ <dependency>
+ <groupId>jakarta.ws.rs</groupId>
+ <artifactId>jakarta.ws.rs-api</artifactId>
+ </dependency>
+
+ <dependency>
+ <groupId>org.springframework</groupId>
+ <artifactId>spring-web</artifactId>
+ </dependency>
+
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
diff --git a/viewers/restfulobjects/applib/src/main/java/module-info.java b/viewers/restfulobjects/applib/src/main/java/module-info.java
index 7767d7d75e3..348004e0498 100644
--- a/viewers/restfulobjects/applib/src/main/java/module-info.java
+++ b/viewers/restfulobjects/applib/src/main/java/module-info.java
@@ -40,5 +40,6 @@
requires org.apache.causeway.commons;
requires spring.context;
requires spring.core;
+ requires spring.web;
requires com.fasterxml.jackson.datatype.jsr310;
}
\ No newline at end of file
diff --git a/viewers/restfulobjects/applib/src/main/java/org/apache/causeway/viewer/restfulobjects/applib/LinkRepresentation.java b/viewers/restfulobjects/applib/src/main/java/org/apache/causeway/viewer/restfulobjects/applib/LinkRepresentation.java
index 0d3f5671e14..d10106b2cbb 100644
--- a/viewers/restfulobjects/applib/src/main/java/org/apache/causeway/viewer/restfulobjects/applib/LinkRepresentation.java
+++ b/viewers/restfulobjects/applib/src/main/java/org/apache/causeway/viewer/restfulobjects/applib/LinkRepresentation.java
@@ -18,7 +18,7 @@
*/
package org.apache.causeway.viewer.restfulobjects.applib;
-import jakarta.ws.rs.core.MediaType;
+import org.springframework.http.MediaType;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.node.JsonNodeFactory;
@@ -81,7 +81,7 @@ public RestfulHttpMethod getHttpMethod() {
public MediaType getType() {
final String typeStr = asObjectNode().path("type").textValue();
if (typeStr == null) {
- return MediaType.APPLICATION_JSON_TYPE;
+ return MediaType.APPLICATION_JSON;
}
return MediaType.valueOf(typeStr);
}
diff --git a/viewers/restfulobjects/applib/src/main/java/org/apache/causeway/viewer/restfulobjects/applib/RepresentationType.java b/viewers/restfulobjects/applib/src/main/java/org/apache/causeway/viewer/restfulobjects/applib/RepresentationType.java
index 489414bfb61..20eb30d31e9 100644
--- a/viewers/restfulobjects/applib/src/main/java/org/apache/causeway/viewer/restfulobjects/applib/RepresentationType.java
+++ b/viewers/restfulobjects/applib/src/main/java/org/apache/causeway/viewer/restfulobjects/applib/RepresentationType.java
@@ -23,7 +23,7 @@
import java.util.List;
import java.util.Map;
-import jakarta.ws.rs.core.MediaType;
+import org.springframework.http.MediaType;
import org.apache.causeway.applib.util.Enums;
import org.apache.causeway.viewer.restfulobjects.applib.domainobjects.ActionResultRepresentation;
@@ -43,7 +43,6 @@
import org.apache.causeway.viewer.restfulobjects.applib.health.HealthRepresentation;
import org.apache.causeway.viewer.restfulobjects.applib.homepage.HomePageRepresentation;
import org.apache.causeway.viewer.restfulobjects.applib.user.UserRepresentation;
-import org.apache.causeway.viewer.restfulobjects.applib.util.MediaTypes;
import org.apache.causeway.viewer.restfulobjects.applib.util.Parser;
import org.apache.causeway.viewer.restfulobjects.applib.version.VersionRepresentation;
@@ -155,8 +154,8 @@ private RepresentationType(
final String xmlMediaTypeStr,
final Class<? extends JsonRepresentation> representationClass) {
- this( jsonMediaTypeStr != null ? MediaTypes.parse(jsonMediaTypeStr) : null,
- xmlMediaTypeStr != null ? MediaTypes.parse(xmlMediaTypeStr) : null,
+ this( jsonMediaTypeStr != null ? MediaType.parseMediaType(jsonMediaTypeStr) : null,
+ xmlMediaTypeStr != null ? MediaType.parseMediaType(xmlMediaTypeStr) : null,
representationClass
);
}
diff --git a/viewers/restfulobjects/applib/src/main/java/org/apache/causeway/viewer/restfulobjects/applib/RestfulRequest.java b/viewers/restfulobjects/applib/src/main/java/org/apache/causeway/viewer/restfulobjects/applib/RestfulRequest.java
index 5d43ba63a3f..13812a626db 100644
--- a/viewers/restfulobjects/applib/src/main/java/org/apache/causeway/viewer/restfulobjects/applib/RestfulRequest.java
+++ b/viewers/restfulobjects/applib/src/main/java/org/apache/causeway/viewer/restfulobjects/applib/RestfulRequest.java
@@ -23,7 +23,7 @@
import java.util.List;
import java.util.Map;
-import jakarta.ws.rs.core.MediaType;
+import org.springframework.http.MediaType;
import org.apache.causeway.viewer.restfulobjects.applib.util.Parser;
@@ -129,10 +129,6 @@ public Parser<X> getParser() {
return parser;
}
-// void setHeader(final ClientRequestConfigurer clientRequestConfigurer, final X t) {
-// clientRequestConfigurer.header(getName(), parser.asString(t));
-// }
-
@Override
public String toString() {
return getName();
@@ -141,16 +137,6 @@ public String toString() {
@Getter private final Map<RequestParameter<?>, Object> args = new LinkedHashMap<>();
-// public <T> RestfulRequest withHeader(final Header<T> header, final T t) {
-// header.setHeader(clientRequestConfigurer, t);
-// return this;
-// }
-//
-// @SuppressWarnings("unchecked")
-// public <T> RestfulRequest withHeader(final Header<List<T>> header, final T... ts) {
-// header.setHeader(clientRequestConfigurer, Arrays.asList(ts));
-// return this;
-// }
public <Q> RestfulRequest withArg(final RestfulRequest.RequestParameter<Q> queryParam, final String argStrFormat, final Object... args) {
final String argStr = String.format(argStrFormat, args);
diff --git a/viewers/restfulobjects/applib/src/main/java/org/apache/causeway/viewer/restfulobjects/applib/RestfulResponse.java b/viewers/restfulobjects/applib/src/main/java/org/apache/causeway/viewer/restfulobjects/applib/RestfulResponse.java
index 0cda4504fc5..9cb40301838 100644
--- a/viewers/restfulobjects/applib/src/main/java/org/apache/causeway/viewer/restfulobjects/applib/RestfulResponse.java
+++ b/viewers/restfulobjects/applib/src/main/java/org/apache/causeway/viewer/restfulobjects/applib/RestfulResponse.java
@@ -25,7 +25,6 @@
import java.util.Map;
import jakarta.ws.rs.core.CacheControl;
-import jakarta.ws.rs.core.MediaType;
import jakarta.ws.rs.core.MultivaluedMap;
import jakarta.ws.rs.core.Response;
import jakarta.ws.rs.core.Response.Status;
@@ -36,6 +35,8 @@
import com.fasterxml.jackson.databind.JsonMappingException;
import com.fasterxml.jackson.databind.JsonNode;
+import org.springframework.http.MediaType;
+
import org.apache.causeway.commons.internal.collections._Maps;
import org.apache.causeway.viewer.restfulobjects.applib.util.JsonMapper;
import org.apache.causeway.viewer.restfulobjects.applib.util.Parser;
diff --git a/viewers/restfulobjects/applib/src/main/java/org/apache/causeway/viewer/restfulobjects/applib/boot/BootstrapResource.java b/viewers/restfulobjects/applib/src/main/java/org/apache/causeway/viewer/restfulobjects/applib/boot/BootstrapResource.java
index 3284ef2455a..659f524d81f 100644
--- a/viewers/restfulobjects/applib/src/main/java/org/apache/causeway/viewer/restfulobjects/applib/boot/BootstrapResource.java
+++ b/viewers/restfulobjects/applib/src/main/java/org/apache/causeway/viewer/restfulobjects/applib/boot/BootstrapResource.java
@@ -21,7 +21,7 @@
import jakarta.ws.rs.GET;
import jakarta.ws.rs.Path;
import jakarta.ws.rs.Produces;
-import jakarta.ws.rs.core.MediaType;
+import org.springframework.http.MediaType;
/**
* @since 1.x {@index}
@@ -30,7 +30,7 @@
public interface BootstrapResource {
@GET
- @Produces({ MediaType.TEXT_HTML })
+ @Produces({ MediaType.TEXT_HTML_VALUE })
public String bootstrap();
}
diff --git a/viewers/restfulobjects/applib/src/main/java/org/apache/causeway/viewer/restfulobjects/applib/domainobjects/DomainObjectResource.java b/viewers/restfulobjects/applib/src/main/java/org/apache/causeway/viewer/restfulobjects/applib/domainobjects/DomainObjectResource.java
index 8218360e1db..828587033f6 100644
--- a/viewers/restfulobjects/applib/src/main/java/org/apache/causeway/viewer/restfulobjects/applib/domainobjects/DomainObjectResource.java
+++ b/viewers/restfulobjects/applib/src/main/java/org/apache/causeway/viewer/restfulobjects/applib/domainobjects/DomainObjectResource.java
@@ -20,7 +20,6 @@
import java.io.InputStream;
-import jakarta.ws.rs.Consumes;
import jakarta.ws.rs.DELETE;
import jakarta.ws.rs.GET;
import jakarta.ws.rs.POST;
@@ -29,7 +28,9 @@
import jakarta.ws.rs.PathParam;
import jakarta.ws.rs.Produces;
import jakarta.ws.rs.QueryParam;
-import jakarta.ws.rs.core.MediaType;
+import org.springframework.http.MediaType;
+import org.springframework.web.bind.annotation.RequestMapping;
+
import jakarta.ws.rs.core.Response;
import org.apache.causeway.viewer.restfulobjects.applib.RestfulMediaType;
@@ -37,37 +38,35 @@
/**
* @since 1.x {@index}
*/
-@Path("/objects")
+@RequestMapping("${roPrefix}/objects")
public interface DomainObjectResource {
@POST
@Path("/{domainType}")
- @Consumes({ MediaType.WILDCARD })
+ //@Consumes({ MediaType.WILDCARD })
@Produces({
- MediaType.APPLICATION_JSON, RestfulMediaType.APPLICATION_JSON_OBJECT, RestfulMediaType.APPLICATION_JSON_ERROR,
- MediaType.APPLICATION_XML, RestfulMediaType.APPLICATION_XML_OBJECT, RestfulMediaType.APPLICATION_XML_ERROR
+ MediaType.APPLICATION_JSON_VALUE, RestfulMediaType.APPLICATION_JSON_OBJECT, RestfulMediaType.APPLICATION_JSON_ERROR,
+ MediaType.APPLICATION_XML_VALUE, RestfulMediaType.APPLICATION_XML_OBJECT, RestfulMediaType.APPLICATION_XML_ERROR
})
public Response persist(@PathParam("domainType") String domainType, final InputStream object);
- // //////////////////////////////////////////////////////////
- // domain object
- // //////////////////////////////////////////////////////////
+ // -- DOMAIN OBJECT
@GET
@Path("/{domainType}/{instanceId}")
- @Consumes({ MediaType.WILDCARD })
+ //@Consumes({ MediaType.WILDCARD })
@Produces({
- MediaType.APPLICATION_JSON, RestfulMediaType.APPLICATION_JSON_OBJECT, RestfulMediaType.APPLICATION_JSON_ERROR,
- MediaType.APPLICATION_XML, RestfulMediaType.APPLICATION_XML_OBJECT, RestfulMediaType.APPLICATION_XML_ERROR
+ MediaType.APPLICATION_JSON_VALUE, RestfulMediaType.APPLICATION_JSON_OBJECT, RestfulMediaType.APPLICATION_JSON_ERROR,
+ MediaType.APPLICATION_XML_VALUE, RestfulMediaType.APPLICATION_XML_OBJECT, RestfulMediaType.APPLICATION_XML_ERROR
})
public Response object(@PathParam("domainType") String domainType, @PathParam("instanceId") final String instanceId);
@PUT
@Path("/{domainType}/{instanceId}")
- @Consumes({ MediaType.WILDCARD })
+ //@Consumes({ MediaType.WILDCARD })
@Produces({
- MediaType.APPLICATION_JSON, RestfulMediaType.APPLICATION_JSON_OBJECT, RestfulMediaType.APPLICATION_JSON_ERROR,
- MediaType.APPLICATION_XML, RestfulMediaType.APPLICATION_XML_OBJECT, RestfulMediaType.APPLICATION_XML_ERROR
+ MediaType.APPLICATION_JSON_VALUE, RestfulMediaType.APPLICATION_JSON_OBJECT, RestfulMediaType.APPLICATION_JSON_ERROR,
+ MediaType.APPLICATION_XML_VALUE, RestfulMediaType.APPLICATION_XML_OBJECT, RestfulMediaType.APPLICATION_XML_ERROR
})
public Response object(@PathParam("domainType") String domainType, @PathParam("instanceId") final String instanceId, final InputStream arguments);
@@ -79,15 +78,17 @@ public interface DomainObjectResource {
@Path("/{domainType}/{instanceId}")
public Response postMethodNotAllowed(@PathParam("domainType") String domainType, @PathParam("instanceId") final String instanceId);
- // //////////////////////////////////////////////////////////
- // domain object image
- // //////////////////////////////////////////////////////////
+ // -- DOMAIN OBJECT IMAGE
@GET
@Path("/{domainType}/{instanceId}/image")
- @Consumes({ MediaType.WILDCARD })
+ //@Consumes({ MediaType.WILDCARD })
@Produces({
- "image/png"
+ "image/png",
+ "image/gif",
+ "image/jpeg",
+ "image/jpg",
+ "image/svg+xml"
})
public Response image(
@PathParam("domainType")
@@ -95,16 +96,14 @@ public Response image(
@PathParam("instanceId")
final String instanceId);
- // //////////////////////////////////////////////////////////
- // domain object layout
- // //////////////////////////////////////////////////////////
+ // -- DOMAIN OBJECT LAYOUT
@GET
@Path("/{domainType}/{instanceId}/object-layout")
- @Consumes({ MediaType.WILDCARD })
+ //@Consumes({ MediaType.WILDCARD })
@Produces({
- MediaType.APPLICATION_JSON, RestfulMediaType.APPLICATION_JSON_OBJECT_LAYOUT_BS,
- MediaType.APPLICATION_XML, RestfulMediaType.APPLICATION_XML_OBJECT_LAYOUT_BS
+ MediaType.APPLICATION_JSON_VALUE, RestfulMediaType.APPLICATION_JSON_OBJECT_LAYOUT_BS,
+ MediaType.APPLICATION_XML_VALUE, RestfulMediaType.APPLICATION_XML_OBJECT_LAYOUT_BS
})
public Response layout(
@PathParam("domainType")
@@ -112,34 +111,32 @@ public Response layout(
@PathParam("instanceId")
final String instanceId);
- // //////////////////////////////////////////////////////////
- // domain object property
- // //////////////////////////////////////////////////////////
+ // -- DOMAIN OBJECT PROPERTY
@GET
@Path("/{domainType}/{instanceId}/properties/{propertyId}")
- @Consumes({ MediaType.WILDCARD })
+ //@Consumes({ MediaType.WILDCARD })
@Produces({
- MediaType.APPLICATION_JSON, RestfulMediaType.APPLICATION_JSON_OBJECT_PROPERTY, RestfulMediaType.APPLICATION_JSON_ERROR,
- MediaType.APPLICATION_XML, RestfulMediaType.APPLICATION_XML_OBJECT_PROPERTY, RestfulMediaType.APPLICATION_XML_ERROR
+ MediaType.APPLICATION_JSON_VALUE, RestfulMediaType.APPLICATION_JSON_OBJECT_PROPERTY, RestfulMediaType.APPLICATION_JSON_ERROR,
+ MediaType.APPLICATION_XML_VALUE, RestfulMediaType.APPLICATION_XML_OBJECT_PROPERTY, RestfulMediaType.APPLICATION_XML_ERROR
})
public Response propertyDetails(@PathParam("domainType") String domainType, @PathParam("instanceId") final String instanceId, @PathParam("propertyId") final String propertyId);
@PUT
@Path("/{domainType}/{instanceId}/properties/{propertyId}")
- @Consumes({ MediaType.WILDCARD })
+ //@Consumes({ MediaType.WILDCARD })
@Produces({
- MediaType.APPLICATION_JSON, RestfulMediaType.APPLICATION_JSON_OBJECT_PROPERTY, RestfulMediaType.APPLICATION_JSON_ERROR,
- MediaType.APPLICATION_XML, RestfulMediaType.APPLICATION_XML_OBJECT_PROPERTY, RestfulMediaType.APPLICATION_XML_ERROR
+ MediaType.APPLICATION_JSON_VALUE, RestfulMediaType.APPLICATION_JSON_OBJECT_PROPERTY, RestfulMediaType.APPLICATION_JSON_ERROR,
+ MediaType.APPLICATION_XML_VALUE, RestfulMediaType.APPLICATION_XML_OBJECT_PROPERTY, RestfulMediaType.APPLICATION_XML_ERROR
})
public Response modifyProperty(@PathParam("domainType") String domainType, @PathParam("instanceId") final String instanceId, @PathParam("propertyId") final String propertyId, final InputStream arguments);
@DELETE
@Path("/{domainType}/{instanceId}/properties/{propertyId}")
- @Consumes({ MediaType.WILDCARD })
+ //@Consumes({ MediaType.WILDCARD })
@Produces({
- MediaType.APPLICATION_JSON, RestfulMediaType.APPLICATION_JSON_OBJECT_PROPERTY, RestfulMediaType.APPLICATION_JSON_ERROR,
- MediaType.APPLICATION_XML, RestfulMediaType.APPLICATION_XML_OBJECT_PROPERTY, RestfulMediaType.APPLICATION_XML_ERROR
+ MediaType.APPLICATION_JSON_VALUE, RestfulMediaType.APPLICATION_JSON_OBJECT_PROPERTY, RestfulMediaType.APPLICATION_JSON_ERROR,
+ MediaType.APPLICATION_XML_VALUE, RestfulMediaType.APPLICATION_XML_OBJECT_PROPERTY, RestfulMediaType.APPLICATION_XML_ERROR
})
public Response clearProperty(@PathParam("domainType") String domainType, @PathParam("instanceId") final String instanceId, @PathParam("propertyId") final String propertyId);
@@ -147,57 +144,25 @@ public Response layout(
@Path("/{domainType}/{instanceId}/properties/{propertyId}")
public Response postPropertyNotAllowed(@PathParam("domainType") String domainType, @PathParam("instanceId") final String instanceId, @PathParam("propertyId") final String propertyId);
- // //////////////////////////////////////////////////////////
- // domain object collection
- // //////////////////////////////////////////////////////////
+ // -- DOMAIN OBJECT COLLECTION
@GET
@Path("/{domainType}/{instanceId}/collections/{collectionId}")
- @Consumes({ MediaType.WILDCARD })
+ //@Consumes({ MediaType.WILDCARD })
@Produces({
- MediaType.APPLICATION_JSON, RestfulMediaType.APPLICATION_JSON_OBJECT_COLLECTION, RestfulMediaType.APPLICATION_JSON_ERROR,
- MediaType.APPLICATION_XML, RestfulMediaType.APPLICATION_XML_OBJECT_COLLECTION, RestfulMediaType.APPLICATION_XML_ERROR
+ MediaType.APPLICATION_JSON_VALUE, RestfulMediaType.APPLICATION_JSON_OBJECT_COLLECTION, RestfulMediaType.APPLICATION_JSON_ERROR,
+ MediaType.APPLICATION_XML_VALUE, RestfulMediaType.APPLICATION_XML_OBJECT_COLLECTION, RestfulMediaType.APPLICATION_XML_ERROR
})
public Response accessCollection(@PathParam("domainType") String domainType, @PathParam("instanceId") final String instanceId, @PathParam("collectionId") final String collectionId);
-//XXX[CAUSEWAY-3084] - removal of (direct) collection modification - business logic should handle that via actions instead
-// @PUT
-// @Path("/{domainType}/{instanceId}/collections/{collectionId}")
-// @Consumes({ MediaType.WILDCARD })
-// @Produces({
-// MediaType.APPLICATION_JSON, RestfulMediaType.APPLICATION_JSON_OBJECT_COLLECTION, RestfulMediaType.APPLICATION_JSON_ERROR,
-// MediaType.APPLICATION_XML, RestfulMediaType.APPLICATION_XML_OBJECT_COLLECTION, RestfulMediaType.APPLICATION_XML_ERROR
-// })
-// public Response addToSet(@PathParam("domainType") String domainType, @PathParam("instanceId") final String instanceId, @PathParam("collectionId") final String collectionId, final InputStream arguments);
-//
-// @POST
-// @Path("/{domainType}/{instanceId}/collections/{collectionId}")
-// @Consumes({ MediaType.WILDCARD })
-// @Produces({
-// MediaType.APPLICATION_JSON, RestfulMediaType.APPLICATION_JSON_OBJECT_COLLECTION, RestfulMediaType.APPLICATION_JSON_ERROR,
-// MediaType.APPLICATION_XML, RestfulMediaType.APPLICATION_XML_OBJECT_COLLECTION, RestfulMediaType.APPLICATION_XML_ERROR
-// })
-// public Response addToList(@PathParam("domainType") String domainType, @PathParam("instanceId") final String instanceId, @PathParam("collectionId") final String collectionId, final InputStream arguments);
-//
-// @DELETE
-// @Path("/{domainType}/{instanceId}/collections/{collectionId}")
-// @Consumes({ MediaType.WILDCARD })
-// @Produces({
-// MediaType.APPLICATION_JSON, RestfulMediaType.APPLICATION_JSON_OBJECT_COLLECTION, RestfulMediaType.APPLICATION_JSON_ERROR,
-// MediaType.APPLICATION_XML, RestfulMediaType.APPLICATION_XML_OBJECT_COLLECTION, RestfulMediaType.APPLICATION_XML_ERROR
-// })
-// public Response removeFromCollection(@PathParam("domainType") String domainType, @PathParam("instanceId") final String instanceId, @PathParam("collectionId") final String collectionId);
-
- // //////////////////////////////////////////////////////////
- // domain object action
- // //////////////////////////////////////////////////////////
+ // -- DOMAIN OBJECT ACTION
@GET
@Path("/{domainType}/{instanceId}/actions/{actionId}")
- @Consumes({ MediaType.WILDCARD })
+ //@Consumes({ MediaType.WILDCARD })
@Produces({
- MediaType.APPLICATION_JSON, RestfulMediaType.APPLICATION_JSON_OBJECT_ACTION, RestfulMediaType.APPLICATION_JSON_ERROR,
- MediaType.APPLICATION_XML, RestfulMediaType.APPLICATION_XML_OBJECT_ACTION, RestfulMediaType.APPLICATION_XML_ERROR
+ MediaType.APPLICATION_JSON_VALUE, RestfulMediaType.APPLICATION_JSON_OBJECT_ACTION, RestfulMediaType.APPLICATION_JSON_ERROR,
+ MediaType.APPLICATION_XML_VALUE, RestfulMediaType.APPLICATION_XML_OBJECT_ACTION, RestfulMediaType.APPLICATION_XML_ERROR
})
public Response actionPrompt(@PathParam("domainType") String domainType, @PathParam("instanceId") final String instanceId, @PathParam("actionId") final String actionId);
@@ -213,34 +178,32 @@ public Response layout(
@Path("/{domainType}/{instanceId}/actions/{actionId}")
public Response postActionPromptNotAllowed(@PathParam("domainType") String domainType, @PathParam("instanceId") final String instanceId, @PathParam("actionId") final String actionId);
- // //////////////////////////////////////////////////////////
- // domain object action invoke
- // //////////////////////////////////////////////////////////
+ // -- DOMAIN OBJECT ACTION INVOKE
@GET
@Path("/{domainType}/{instanceId}/actions/{actionId}/invoke")
- @Consumes({ MediaType.WILDCARD })
+ //@Consumes({ MediaType.WILDCARD })
@Produces({
- MediaType.APPLICATION_JSON, RestfulMediaType.APPLICATION_JSON_ACTION_RESULT, RestfulMediaType.APPLICATION_JSON_ERROR,
- MediaType.APPLICATION_XML, RestfulMediaType.APPLICATION_XML_ACTION_RESULT, RestfulMediaType.APPLICATION_XML_ERROR
+ MediaType.APPLICATION_JSON_VALUE, RestfulMediaType.APPLICATION_JSON_ACTION_RESULT, RestfulMediaType.APPLICATION_JSON_ERROR,
+ MediaType.APPLICATION_XML_VALUE, RestfulMediaType.APPLICATION_XML_ACTION_RESULT, RestfulMediaType.APPLICATION_XML_ERROR
})
public Response invokeActionQueryOnly(@PathParam("domainType") String domainType, @PathParam("instanceId") final String instanceId, @PathParam("actionId") final String actionId, @QueryParam("x-causeway-querystring") final String xCausewayQueryString);
@PUT
@Path("/{domainType}/{instanceId}/actions/{actionId}/invoke")
- @Consumes({ MediaType.WILDCARD })
+ //@Consumes({ MediaType.WILDCARD })
@Produces({
- MediaType.APPLICATION_JSON, RestfulMediaType.APPLICATION_JSON_ACTION_RESULT, RestfulMediaType.APPLICATION_JSON_ERROR,
- MediaType.APPLICATION_XML, RestfulMediaType.APPLICATION_XML_ACTION_RESULT, RestfulMediaType.APPLICATION_XML_ERROR
+ MediaType.APPLICATION_JSON_VALUE, RestfulMediaType.APPLICATION_JSON_ACTION_RESULT, RestfulMediaType.APPLICATION_JSON_ERROR,
+ MediaType.APPLICATION_XML_VALUE, RestfulMediaType.APPLICATION_XML_ACTION_RESULT, RestfulMediaType.APPLICATION_XML_ERROR
})
public Response invokeActionIdempotent(@PathParam("domainType") String domainType, @PathParam("instanceId") final String instanceId, @PathParam("actionId") final String actionId, final InputStream arguments);
@POST
@Path("/{domainType}/{instanceId}/actions/{actionId}/invoke")
- @Consumes({ MediaType.WILDCARD })
+ //@Consumes({ MediaType.WILDCARD })
@Produces({
- MediaType.APPLICATION_JSON, RestfulMediaType.APPLICATION_JSON_ACTION_RESULT, RestfulMediaType.APPLICATION_JSON_ERROR,
- MediaType.APPLICATION_XML, RestfulMediaType.APPLICATION_XML_ACTION_RESULT, RestfulMediaType.APPLICATION_XML_ERROR
+ MediaType.APPLICATION_JSON_VALUE, RestfulMediaType.APPLICATION_JSON_ACTION_RESULT, RestfulMediaType.APPLICATION_JSON_ERROR,
+ MediaType.APPLICATION_XML_VALUE, RestfulMediaType.APPLICATION_XML_ACTION_RESULT, RestfulMediaType.APPLICATION_XML_ERROR
})
public Response invokeAction(@PathParam("domainType") String domainType, @PathParam("instanceId") final String instanceId, @PathParam("actionId") final String actionId, final InputStream arguments);
diff --git a/viewers/restfulobjects/applib/src/main/java/org/apache/causeway/viewer/restfulobjects/applib/domainobjects/DomainServiceResource.java b/viewers/restfulobjects/applib/src/main/java/org/apache/causeway/viewer/restfulobjects/applib/domainobjects/DomainServiceResource.java
index 5e1e180a05e..debf186151e 100644
--- a/viewers/restfulobjects/applib/src/main/java/org/apache/causeway/viewer/restfulobjects/applib/domainobjects/DomainServiceResource.java
+++ b/viewers/restfulobjects/applib/src/main/java/org/apache/causeway/viewer/restfulobjects/applib/domainobjects/DomainServiceResource.java
@@ -20,16 +20,15 @@
import java.io.InputStream;
-import jakarta.ws.rs.Consumes;
-import jakarta.ws.rs.DELETE;
-import jakarta.ws.rs.GET;
-import jakarta.ws.rs.POST;
-import jakarta.ws.rs.PUT;
-import jakarta.ws.rs.Path;
import jakarta.ws.rs.PathParam;
-import jakarta.ws.rs.Produces;
import jakarta.ws.rs.QueryParam;
-import jakarta.ws.rs.core.MediaType;
+import org.springframework.http.MediaType;
+import org.springframework.web.bind.annotation.DeleteMapping;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.PutMapping;
+import org.springframework.web.bind.annotation.RequestMapping;
+
import jakarta.ws.rs.core.Response;
import org.apache.causeway.viewer.restfulobjects.applib.RestfulMediaType;
@@ -37,114 +36,90 @@
/**
* @since 1.x {@index}
*/
-@Path("/services")
+@RequestMapping("${roPrefix}/services")
public interface DomainServiceResource {
- @GET
- @Path("/")
- @Produces({ MediaType.APPLICATION_JSON, RestfulMediaType.APPLICATION_JSON_LIST, RestfulMediaType.APPLICATION_JSON_ERROR })
+ @GetMapping(produces = { MediaType.APPLICATION_JSON_VALUE, RestfulMediaType.APPLICATION_JSON_LIST, RestfulMediaType.APPLICATION_JSON_ERROR })
public Response services();
- @DELETE
- @Path("/")
+ @DeleteMapping
public Response deleteServicesNotAllowed();
- @PUT
- @Path("/")
+ @PutMapping
public Response putServicesNotAllowed();
- @POST
- @Path("/")
+ @PostMapping
public Response postServicesNotAllowed();
- // //////////////////////////////////////////////////////////
- // domain service
- // //////////////////////////////////////////////////////////
+ // -- DOMAIN SERVICE
- @GET
- @Path("/{serviceId}")
- @Produces({
- MediaType.APPLICATION_JSON, RestfulMediaType.APPLICATION_JSON_OBJECT, RestfulMediaType.APPLICATION_JSON_ERROR,
- MediaType.APPLICATION_XML, RestfulMediaType.APPLICATION_XML_OBJECT, RestfulMediaType.APPLICATION_XML_ERROR
+ @GetMapping(
+ path = "/{serviceId}",
+ produces = {
+ MediaType.APPLICATION_JSON_VALUE, RestfulMediaType.APPLICATION_JSON_OBJECT, RestfulMediaType.APPLICATION_JSON_ERROR,
+ MediaType.APPLICATION_XML_VALUE, RestfulMediaType.APPLICATION_XML_OBJECT, RestfulMediaType.APPLICATION_XML_ERROR
})
public Response service(@PathParam("serviceId") final String serviceId);
- @DELETE
- @Path("/{serviceId}")
+ @DeleteMapping(path = "/{serviceId}")
public Response deleteServiceNotAllowed(@PathParam("serviceId") final String serviceId);
- @PUT
- @Path("/{serviceId}")
+ @PutMapping(path = "/{serviceId}")
public Response putServiceNotAllowed(@PathParam("serviceId") final String serviceId);
- @POST
- @Path("/{serviceId}")
+ @PostMapping(path = "/{serviceId}")
public Response postServiceNotAllowed(@PathParam("serviceId") final String serviceId);
- // //////////////////////////////////////////////////////////
- // domain service action
- // //////////////////////////////////////////////////////////
+ // -- DOMAIN SERVICE ACTION
- @GET
- @Path("/{serviceId}/actions/{actionId}")
- @Consumes({ MediaType.WILDCARD })
- @Produces({
- MediaType.APPLICATION_JSON, RestfulMediaType.APPLICATION_JSON_OBJECT_ACTION, RestfulMediaType.APPLICATION_JSON_ERROR,
- MediaType.APPLICATION_XML, RestfulMediaType.APPLICATION_XML_OBJECT_ACTION, RestfulMediaType.APPLICATION_XML_ERROR
+ @GetMapping(
+ path = "/{serviceId}/actions/{actionId}",
+ produces = {
+ MediaType.APPLICATION_JSON_VALUE, RestfulMediaType.APPLICATION_JSON_OBJECT_ACTION, RestfulMediaType.APPLICATION_JSON_ERROR,
+ MediaType.APPLICATION_XML_VALUE, RestfulMediaType.APPLICATION_XML_OBJECT_ACTION, RestfulMediaType.APPLICATION_XML_ERROR
})
public Response actionPrompt(@PathParam("serviceId") final String serviceId, @PathParam("actionId") final String actionId);
- @DELETE
- @Path("/{serviceId}/actions/{actionId}")
+ @DeleteMapping(path = "/{serviceId}/actions/{actionId}")
public Response deleteActionPromptNotAllowed(@PathParam("serviceId") final String serviceId, @PathParam("actionId") final String actionId);
- @PUT
- @Path("/{serviceId}/actions/{actionId}")
+ @PutMapping(path = "/{serviceId}/actions/{actionId}")
public Response putActionPromptNotAllowed(@PathParam("serviceId") final String serviceId, @PathParam("actionId") final String actionId);
- @POST
- @Path("/{serviceId}/actions/{actionId}")
+ @PostMapping(path = "/{serviceId}/actions/{actionId}")
public Response postActionPromptNotAllowed(@PathParam("serviceId") final String serviceId, @PathParam("actionId") final String actionId);
- // //////////////////////////////////////////////////////////
- // domain service action invoke
- // //////////////////////////////////////////////////////////
+ // -- DOMAIN SERVICE ACTION INVOKE
/**
* Because it isn't possible with the RestEasy client-side framework to specify a query string nor to pass arbitrary query params; instead
* we provide an additional syntax of passing an Causeway-defined query param <tt>x-causeway-querystring</tt>.
*
- * <p>
- * The content of this is taken to be the URL encoded map of arguments.
+ * <p>The content of this is taken to be the URL encoded map of arguments.
*/
- @GET
- @Path("/{serviceId}/actions/{actionId}/invoke")
- @Consumes({ MediaType.WILDCARD })
- @Produces({
- MediaType.APPLICATION_JSON, RestfulMediaType.APPLICATION_JSON_ACTION_RESULT, RestfulMediaType.APPLICATION_JSON_ERROR,
- MediaType.APPLICATION_XML, RestfulMediaType.APPLICATION_XML_ACTION_RESULT, RestfulMediaType.APPLICATION_XML_ERROR
+ @GetMapping(
+ path = "/{serviceId}/actions/{actionId}/invoke",
+ produces = {
+ MediaType.APPLICATION_JSON_VALUE, RestfulMediaType.APPLICATION_JSON_ACTION_RESULT, RestfulMediaType.APPLICATION_JSON_ERROR,
+ MediaType.APPLICATION_XML_VALUE, RestfulMediaType.APPLICATION_XML_ACTION_RESULT, RestfulMediaType.APPLICATION_XML_ERROR
})
public Response invokeActionQueryOnly(@PathParam("serviceId") final String serviceId, @PathParam("actionId") final String actionId, @QueryParam("x-causeway-querystring") final String xCausewayQueryString);
- @PUT
- @Path("/{serviceId}/actions/{actionId}/invoke")
- @Consumes({ MediaType.WILDCARD })
- @Produces({
- MediaType.APPLICATION_JSON, RestfulMediaType.APPLICATION_JSON_ACTION_RESULT, RestfulMediaType.APPLICATION_JSON_ERROR,
- MediaType.APPLICATION_XML, RestfulMediaType.APPLICATION_XML_ACTION_RESULT, RestfulMediaType.APPLICATION_XML_ERROR
+ @PutMapping(
+ path = "/{serviceId}/actions/{actionId}/invoke",
+ produces = {
+ MediaType.APPLICATION_JSON_VALUE, RestfulMediaType.APPLICATION_JSON_ACTION_RESULT, RestfulMediaType.APPLICATION_JSON_ERROR,
+ MediaType.APPLICATION_XML_VALUE, RestfulMediaType.APPLICATION_XML_ACTION_RESULT, RestfulMediaType.APPLICATION_XML_ERROR
})
public Response invokeActionIdempotent(@PathParam("serviceId") final String serviceId, @PathParam("actionId") final String actionId, final InputStream arguments);
- @POST
- @Path("/{serviceId}/actions/{actionId}/invoke")
- @Consumes({ MediaType.WILDCARD })
- @Produces({
- MediaType.APPLICATION_JSON, RestfulMediaType.APPLICATION_JSON_ACTION_RESULT, RestfulMediaType.APPLICATION_JSON_ERROR,
- MediaType.APPLICATION_XML, RestfulMediaType.APPLICATION_XML_ACTION_RESULT, RestfulMediaType.APPLICATION_XML_ERROR
+ @PostMapping(path = "/{serviceId}/actions/{actionId}/invoke",
+ produces = {
+ MediaType.APPLICATION_JSON_VALUE, RestfulMediaType.APPLICATION_JSON_ACTION_RESULT, RestfulMediaType.APPLICATION_JSON_ERROR,
+ MediaType.APPLICATION_XML_VALUE, RestfulMediaType.APPLICATION_XML_ACTION_RESULT, RestfulMediaType.APPLICATION_XML_ERROR
})
public Response invokeAction(@PathParam("serviceId") final String serviceId, @PathParam("actionId") final String actionId, final InputStream arguments);
- @DELETE
- @Path("/{serviceId}/actions/{actionId}/invoke")
+ @DeleteMapping(path = "/{serviceId}/actions/{actionId}/invoke")
public Response deleteInvokeActionNotAllowed(@PathParam("serviceId") final String serviceId, @PathParam("actionId") final String actionId);
}
diff --git a/viewers/restfulobjects/applib/src/main/java/org/apache/causeway/viewer/restfulobjects/applib/domaintypes/DomainTypeResource.java b/viewers/restfulobjects/applib/src/main/java/org/apache/causeway/viewer/restfulobjects/applib/domaintypes/DomainTypeResource.java
index 6de76f8ec3e..b8e808e8a1f 100644
--- a/viewers/restfulobjects/applib/src/main/java/org/apache/causeway/viewer/restfulobjects/applib/domaintypes/DomainTypeResource.java
+++ b/viewers/restfulobjects/applib/src/main/java/org/apache/causeway/viewer/restfulobjects/applib/domaintypes/DomainTypeResource.java
@@ -23,7 +23,7 @@
import jakarta.ws.rs.PathParam;
import jakarta.ws.rs.Produces;
import jakarta.ws.rs.QueryParam;
-import jakarta.ws.rs.core.MediaType;
+import org.springframework.http.MediaType;
import jakarta.ws.rs.core.Response;
import org.apache.causeway.viewer.restfulobjects.applib.RestfulMediaType;
@@ -36,45 +36,45 @@ public interface DomainTypeResource {
@GET
@Path("/")
- @Produces({ MediaType.APPLICATION_JSON, RestfulMediaType.APPLICATION_JSON_TYPE_LIST })
+ @Produces({ MediaType.APPLICATION_JSON_VALUE, RestfulMediaType.APPLICATION_JSON_TYPE_LIST })
public abstract Response domainTypes();
@GET
@Path("/{domainType}")
- @Produces({ MediaType.APPLICATION_JSON, RestfulMediaType.APPLICATION_JSON_DOMAIN_TYPE })
+ @Produces({ MediaType.APPLICATION_JSON_VALUE, RestfulMediaType.APPLICATION_JSON_DOMAIN_TYPE })
public abstract Response domainType(@PathParam("domainType") final String domainType);
@GET
@Path("/{domainType}/layout")
@Produces({
- MediaType.APPLICATION_JSON, RestfulMediaType.APPLICATION_JSON_LAYOUT_BS,
- MediaType.APPLICATION_XML, RestfulMediaType.APPLICATION_XML_LAYOUT_BS
+ MediaType.APPLICATION_JSON_VALUE, RestfulMediaType.APPLICATION_JSON_LAYOUT_BS,
+ MediaType.APPLICATION_XML_VALUE, RestfulMediaType.APPLICATION_XML_LAYOUT_BS
})
public abstract Response layout(@PathParam("domainType") final String domainType);
@GET
@Path("/{domainType}/properties/{propertyId}")
- @Produces({ MediaType.APPLICATION_JSON, RestfulMediaType.APPLICATION_JSON_PROPERTY_DESCRIPTION })
+ @Produces({ MediaType.APPLICATION_JSON_VALUE, RestfulMediaType.APPLICATION_JSON_PROPERTY_DESCRIPTION })
public abstract Response typeProperty(@PathParam("domainType") final String domainType, @PathParam("propertyId") final String propertyId);
@GET
@Path("/{domainType}/collections/{collectionId}")
- @Produces({ MediaType.APPLICATION_JSON, RestfulMediaType.APPLICATION_JSON_COLLECTION_DESCRIPTION })
+ @Produces({ MediaType.APPLICATION_JSON_VALUE, RestfulMediaType.APPLICATION_JSON_COLLECTION_DESCRIPTION })
public abstract Response typeCollection(@PathParam("domainType") final String domainType, @PathParam("collectionId") final String collectionId);
@GET
@Path("/{domainType}/actions/{actionId}")
- @Produces({ MediaType.APPLICATION_JSON, RestfulMediaType.APPLICATION_JSON_ACTION_DESCRIPTION })
+ @Produces({ MediaType.APPLICATION_JSON_VALUE, RestfulMediaType.APPLICATION_JSON_ACTION_DESCRIPTION })
public abstract Response typeAction(@PathParam("domainType") final String domainType, @PathParam("actionId") final String actionId);
@GET
@Path("/{domainType}/actions/{actionId}/params/{paramId}")
- @Produces({ MediaType.APPLICATION_JSON, RestfulMediaType.APPLICATION_JSON_ACTION_PARAMETER_DESCRIPTION })
+ @Produces({ MediaType.APPLICATION_JSON_VALUE, RestfulMediaType.APPLICATION_JSON_ACTION_PARAMETER_DESCRIPTION })
public abstract Response typeActionParam(@PathParam("domainType") final String domainType, @PathParam("actionId") final String actionId, @PathParam("paramId") final String paramId);
@GET
@Path("/{domainType}/isSubtypeOf/invoke")
- @Produces({ MediaType.APPLICATION_JSON, RestfulMediaType.APPLICATION_JSON_TYPE_ACTION_RESULT, RestfulMediaType.APPLICATION_JSON_ERROR })
+ @Produces({ MediaType.APPLICATION_JSON_VALUE, RestfulMediaType.APPLICATION_JSON_TYPE_ACTION_RESULT, RestfulMediaType.APPLICATION_JSON_ERROR })
public abstract Response domainTypeIsSubtypeOf(
@PathParam("domainType") final String domainType,
@QueryParam("supertype") String superType, // simple style
@@ -83,7 +83,7 @@ public abstract Response domainTypeIsSubtypeOf(
@GET
@Path("/{domainType}/isSupertypeOf/invoke")
- @Produces({ MediaType.APPLICATION_JSON, RestfulMediaType.APPLICATION_JSON_TYPE_ACTION_RESULT, RestfulMediaType.APPLICATION_JSON_ERROR })
+ @Produces({ MediaType.APPLICATION_JSON_VALUE, RestfulMediaType.APPLICATION_JSON_TYPE_ACTION_RESULT, RestfulMediaType.APPLICATION_JSON_ERROR })
public abstract Response domainTypeIsSupertypeOf(
@PathParam("domainType") final String domainType,
@QueryParam("supertype") String superType, // simple style
diff --git a/viewers/restfulobjects/applib/src/main/java/org/apache/causeway/viewer/restfulobjects/applib/health/HealthResource.java b/viewers/restfulobjects/applib/src/main/java/org/apache/causeway/viewer/restfulobjects/applib/health/HealthResource.java
index 45138e5a9bc..47b149a0d82 100644
--- a/viewers/restfulobjects/applib/src/main/java/org/apache/causeway/viewer/restfulobjects/applib/health/HealthResource.java
+++ b/viewers/restfulobjects/applib/src/main/java/org/apache/causeway/viewer/restfulobjects/applib/health/HealthResource.java
@@ -24,7 +24,7 @@
import jakarta.ws.rs.PUT;
import jakarta.ws.rs.Path;
import jakarta.ws.rs.Produces;
-import jakarta.ws.rs.core.MediaType;
+import org.springframework.http.MediaType;
import jakarta.ws.rs.core.Response;
import org.apache.causeway.viewer.restfulobjects.applib.RestfulMediaType;
@@ -36,7 +36,7 @@
public interface HealthResource {
@GET
- @Produces({ MediaType.APPLICATION_JSON, RestfulMediaType.APPLICATION_JSON_HEALTH })
+ @Produces({ MediaType.APPLICATION_JSON_VALUE, RestfulMediaType.APPLICATION_JSON_HEALTH })
public Response health();
@DELETE
diff --git a/viewers/restfulobjects/applib/src/main/java/org/apache/causeway/viewer/restfulobjects/applib/homepage/HomePageResource.java b/viewers/restfulobjects/applib/src/main/java/org/apache/causeway/viewer/restfulobjects/applib/homepage/HomePageResource.java
index 6ad00ada47c..19ae615661b 100644
--- a/viewers/restfulobjects/applib/src/main/java/org/apache/causeway/viewer/restfulobjects/applib/homepage/HomePageResource.java
+++ b/viewers/restfulobjects/applib/src/main/java/org/apache/causeway/viewer/restfulobjects/applib/homepage/HomePageResource.java
@@ -18,43 +18,42 @@
*/
package org.apache.causeway.viewer.restfulobjects.applib.homepage;
-import jakarta.ws.rs.DELETE;
-import jakarta.ws.rs.GET;
-import jakarta.ws.rs.POST;
-import jakarta.ws.rs.PUT;
-import jakarta.ws.rs.Path;
-import jakarta.ws.rs.Produces;
-import jakarta.ws.rs.core.MediaType;
import jakarta.ws.rs.core.Response;
+import org.springframework.http.MediaType;
+import org.springframework.web.bind.annotation.DeleteMapping;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.PutMapping;
+import org.springframework.web.bind.annotation.RequestMapping;
+
import org.apache.causeway.viewer.restfulobjects.applib.RestfulMediaType;
/**
* @since 1.x {@index}
*/
-@Path("/")
+@RequestMapping("${roPrefix}")
public interface HomePageResource {
- @GET
- @Produces({ MediaType.APPLICATION_JSON, RestfulMediaType.APPLICATION_JSON_HOME_PAGE })
- public Response homePage();
+ @GetMapping(produces = { MediaType.APPLICATION_JSON_VALUE, RestfulMediaType.APPLICATION_JSON_HOME_PAGE })
+ public Response homePage(/*@RequestHeader HttpHeaders headers*/);
- @DELETE
+ @DeleteMapping
public Response deleteHomePageNotAllowed();
- @PUT
+ @PutMapping
public Response putHomePageNotAllowed();
- @POST
+ @PostMapping
public Response postHomePageNotAllowed();
/**
* Not part of the RO spec; this resource always returns 401, and is
* intended to be redirected to if credentials cannot be obtained.
*/
- @GET
- @Path("/notAuthenticated")
- @Produces({ MediaType.APPLICATION_JSON })
+ @GetMapping(
+ path = "/notAuthenticated",
+ produces = { MediaType.APPLICATION_JSON_VALUE })
public Response notAuthenticated();
}
diff --git a/viewers/restfulobjects/applib/src/main/java/org/apache/causeway/viewer/restfulobjects/applib/menubars/MenuBarsResource.java b/viewers/restfulobjects/applib/src/main/java/org/apache/causeway/viewer/restfulobjects/applib/menubars/MenuBarsResource.java
index 0b7d427274f..215fd971d32 100644
--- a/viewers/restfulobjects/applib/src/main/java/org/apache/causeway/viewer/restfulobjects/applib/menubars/MenuBarsResource.java
+++ b/viewers/restfulobjects/applib/src/main/java/org/apache/causeway/viewer/restfulobjects/applib/menubars/MenuBarsResource.java
@@ -24,7 +24,7 @@
import jakarta.ws.rs.PUT;
import jakarta.ws.rs.Path;
import jakarta.ws.rs.Produces;
-import jakarta.ws.rs.core.MediaType;
+import org.springframework.http.MediaType;
import jakarta.ws.rs.core.Response;
import org.apache.causeway.viewer.restfulobjects.applib.RestfulMediaType;
@@ -42,8 +42,8 @@ public interface MenuBarsResource {
*/
@GET
@Produces({
- MediaType.APPLICATION_XML, RestfulMediaType.APPLICATION_JSON_LAYOUT_MENUBARS,
- MediaType.APPLICATION_XML, RestfulMediaType.APPLICATION_XML_LAYOUT_MENUBARS
+ MediaType.APPLICATION_XML_VALUE, RestfulMediaType.APPLICATION_JSON_LAYOUT_MENUBARS,
+ MediaType.APPLICATION_XML_VALUE, RestfulMediaType.APPLICATION_XML_LAYOUT_MENUBARS
})
public Response menuBars();
diff --git a/viewers/restfulobjects/applib/src/main/java/org/apache/causeway/viewer/restfulobjects/applib/user/UserResource.java b/viewers/restfulobjects/applib/src/main/java/org/apache/causeway/viewer/restfulobjects/applib/user/UserResource.java
index aa6e7a92809..90d4ac3c87f 100644
--- a/viewers/restfulobjects/applib/src/main/java/org/apache/causeway/viewer/restfulobjects/applib/user/UserResource.java
+++ b/viewers/restfulobjects/applib/src/main/java/org/apache/causeway/viewer/restfulobjects/applib/user/UserResource.java
@@ -24,7 +24,7 @@
import jakarta.ws.rs.PUT;
import jakarta.ws.rs.Path;
import jakarta.ws.rs.Produces;
-import jakarta.ws.rs.core.MediaType;
+import org.springframework.http.MediaType;
import jakarta.ws.rs.core.Response;
import org.apache.causeway.viewer.restfulobjects.applib.RestfulMediaType;
@@ -36,7 +36,7 @@
public interface UserResource {
@GET
- @Produces({ MediaType.APPLICATION_JSON, RestfulMediaType.APPLICATION_JSON_USER })
+ @Produces({ MediaType.APPLICATION_JSON_VALUE, RestfulMediaType.APPLICATION_JSON_USER })
public Response user();
@DELETE
@@ -53,7 +53,7 @@ public interface UserResource {
*/
@GET
@Path("/logout")
- @Produces({ MediaType.APPLICATION_JSON, RestfulMediaType.APPLICATION_JSON_HOME_PAGE })
+ @Produces({ MediaType.APPLICATION_JSON_VALUE, RestfulMediaType.APPLICATION_JSON_HOME_PAGE })
public Response logout();
}
diff --git a/viewers/restfulobjects/applib/src/main/java/org/apache/causeway/viewer/restfulobjects/applib/util/MediaTypes.java b/viewers/restfulobjects/applib/src/main/java/org/apache/causeway/viewer/restfulobjects/applib/util/MediaTypes.java
index d9ed12c8f13..ec2c88582be 100644
--- a/viewers/restfulobjects/applib/src/main/java/org/apache/causeway/viewer/restfulobjects/applib/util/MediaTypes.java
+++ b/viewers/restfulobjects/applib/src/main/java/org/apache/causeway/viewer/restfulobjects/applib/util/MediaTypes.java
@@ -21,13 +21,16 @@
import java.util.List;
import java.util.stream.Collectors;
-import jakarta.ws.rs.core.MediaType;
+import org.springframework.http.MediaType;
import org.apache.causeway.commons.internal.base._Strings;
+import lombok.experimental.UtilityClass;
+
/**
* @since 1.x {@index}
*/
+@UtilityClass
public class MediaTypes {
/**
@@ -38,7 +41,7 @@ public class MediaTypes {
*
* @param type
*/
- public static MediaType parse(String type) {
+ public MediaType parse(String type) {
if(type==null)
return MediaType.valueOf(null);
@@ -68,4 +71,14 @@ public static MediaType parse(String type) {
}
+ //TODO[causeway-viewer-restfulobjects-applib-CAUSEWAY-3892] remove
+ //org.springframework.http.MediaType;
+ //jakarta.ws.rs.core.MediaType;
+ public jakarta.ws.rs.core.MediaType toJakarta(MediaType mediaType) {
+ throw new UnsupportedOperationException();
+ }
+ public MediaType fromJakarta(jakarta.ws.rs.core.MediaType mediaType) {
+ throw new UnsupportedOperationException();
+ }
+
}
diff --git a/viewers/restfulobjects/applib/src/main/java/org/apache/causeway/viewer/restfulobjects/applib/util/Parser.java b/viewers/restfulobjects/applib/src/main/java/org/apache/causeway/viewer/restfulobjects/applib/util/Parser.java
index 2d84791604f..fb24faab1b4 100644
--- a/viewers/restfulobjects/applib/src/main/java/org/apache/causeway/viewer/restfulobjects/applib/util/Parser.java
+++ b/viewers/restfulobjects/applib/src/main/java/org/apache/causeway/viewer/restfulobjects/applib/util/Parser.java
@@ -27,9 +27,10 @@
import java.util.stream.Collectors;
import jakarta.ws.rs.core.CacheControl;
-import jakarta.ws.rs.core.MediaType;
import jakarta.ws.rs.ext.RuntimeDelegate;
+import org.springframework.http.MediaType;
+
import org.apache.causeway.commons.internal._Constants;
import org.apache.causeway.commons.internal.base._NullSafe;
import org.apache.causeway.commons.internal.base._Strings;
diff --git a/viewers/restfulobjects/applib/src/main/java/org/apache/causeway/viewer/restfulobjects/applib/version/VersionResource.java b/viewers/restfulobjects/applib/src/main/java/org/apache/causeway/viewer/restfulobjects/applib/version/VersionResource.java
index 1c776ec998a..382315ed7b4 100644
--- a/viewers/restfulobjects/applib/src/main/java/org/apache/causeway/viewer/restfulobjects/applib/version/VersionResource.java
+++ b/viewers/restfulobjects/applib/src/main/java/org/apache/causeway/viewer/restfulobjects/applib/version/VersionResource.java
@@ -24,7 +24,7 @@
import jakarta.ws.rs.PUT;
import jakarta.ws.rs.Path;
import jakarta.ws.rs.Produces;
-import jakarta.ws.rs.core.MediaType;
+import org.springframework.http.MediaType;
import jakarta.ws.rs.core.Response;
import org.apache.causeway.viewer.restfulobjects.applib.RestfulMediaType;
@@ -36,7 +36,7 @@
public interface VersionResource {
@GET
- @Produces({ MediaType.APPLICATION_JSON, RestfulMediaType.APPLICATION_JSON_VERSION })
+ @Produces({ MediaType.APPLICATION_JSON_VALUE, RestfulMediaType.APPLICATION_JSON_VERSION })
public Response version();
@DELETE
diff --git a/viewers/restfulobjects/client/src/main/java/org/apache/causeway/viewer/restfulobjects/client/RestfulClientMediaType.java b/viewers/restfulobjects/client/src/main/java/org/apache/causeway/viewer/restfulobjects/client/RestfulClientMediaType.java
index 9fb87a9c2ba..ccb4871486c 100644
--- a/viewers/restfulobjects/client/src/main/java/org/apache/causeway/viewer/restfulobjects/client/RestfulClientMediaType.java
+++ b/viewers/restfulobjects/client/src/main/java/org/apache/causeway/viewer/restfulobjects/client/RestfulClientMediaType.java
@@ -23,7 +23,7 @@
import java.util.Optional;
import java.util.stream.Collectors;
-import jakarta.ws.rs.core.MediaType;
+import org.springframework.http.MediaType;
import org.jspecify.annotations.Nullable;
diff --git a/viewers/restfulobjects/client/src/main/java/org/apache/causeway/viewer/restfulobjects/client/auth/oauth2/azure/TokenCache.java b/viewers/restfulobjects/client/src/main/java/org/apache/causeway/viewer/restfulobjects/client/auth/oauth2/azure/TokenCache.java
index 2567277df11..4fb3b228c29 100644
--- a/viewers/restfulobjects/client/src/main/java/org/apache/causeway/viewer/restfulobjects/client/auth/oauth2/azure/TokenCache.java
+++ b/viewers/restfulobjects/client/src/main/java/org/apache/causeway/viewer/restfulobjects/client/auth/oauth2/azure/TokenCache.java
@@ -60,7 +60,7 @@ public Railway<Exception, String> getToken() {
.param("client_secret", creds.clientSecret())
.param("grant_type", "client_credentials");
- var invocation = invocationBuilder.buildPost(Entity.entity(form, MediaType.APPLICATION_FORM_URLENCODED_TYPE));
+ var invocation = invocationBuilder.buildPost(Entity.entity(form, MediaType.APPLICATION_FORM_URLENCODED));
var response = invocation.invoke();
var entity = response.readEntity(String.class);
diff --git a/viewers/restfulobjects/jaxrs-resteasy/pom.xml b/viewers/restfulobjects/jaxrs-resteasy/pom.xml
index 44dfc89c477..d1b826418d7 100644
--- a/viewers/restfulobjects/jaxrs-resteasy/pom.xml
+++ b/viewers/restfulobjects/jaxrs-resteasy/pom.xml
@@ -32,25 +32,6 @@
<git-plugin.propertiesDir>org/apache/causeway/viewer.restfulobjects/jaxrsresteasy</git-plugin.propertiesDir>
</properties>
- <build>
- <resources>
- <resource>
- <filtering>false</filtering>
- <directory>src/main/resources</directory>
- </resource>
- <resource>
- <filtering>false</filtering>
- <directory>src/main/java</directory>
- <includes>
- <include>**</include>
- </includes>
- <excludes>
- <exclude>**/*.java</exclude>
- </excludes>
- </resource>
- </resources>
- </build>
-
<dependencies>
<!-- COMPILE DEPENDENCIES -->
@@ -58,12 +39,6 @@
<dependency>
<groupId>org.apache.causeway.viewer</groupId>
<artifactId>causeway-viewer-restfulobjects-rendering</artifactId>
- <exclusions>
- <exclusion>
- <groupId>org.jboss.logging</groupId>
- <artifactId>jboss-logging</artifactId>
- </exclusion>
- </exclusions>
</dependency>
<dependency>
@@ -76,100 +51,6 @@
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-webmvc</artifactId>
</dependency>
-
-
- <!-- RestEasy -->
-
-<!-- <dependency>-->
-<!-- <groupId>org.jboss.resteasy</groupId>-->
-<!-- <artifactId>resteasy-spring-boot-starter</artifactId>-->
-<!-- <exclusions>-->
-<!-- <exclusion>-->
-<!-- <groupId>org.jboss.logging</groupId>-->
-<!-- <artifactId>jboss-logging</artifactId>-->
-<!-- </exclusion>-->
-<!-- transitively provided by causeway-commons -->
-<!-- <exclusion>-->
-<!-- <groupId>org.ow2.asm</groupId>-->
-<!-- <artifactId>asm</artifactId>-->
-<!-- </exclusion>-->
-<!-- <exclusion>-->
-<!-- <groupId>org.jboss.resteasy</groupId>-->
-<!-- <artifactId>resteasy-servlet-initializer</artifactId>-->
-<!-- </exclusion>-->
-<!-- <exclusion>-->
-<!-- <groupId>org.jboss.resteasy</groupId>-->
-<!-- <artifactId>resteasy-jackson2-provider</artifactId>-->
-<!-- </exclusion>-->
-<!-- <exclusion>-->
-<!-- <groupId>com.fasterxml.jackson.module</groupId>-->
-<!-- <artifactId>jackson-module-jaxb-annotations</artifactId>-->
-<!-- </exclusion>-->
-<!-- <exclusion>-->
-<!-- <groupId>org.springframework.boot</groupId>-->
-<!-- <artifactId>spring-boot-starter-tomcat</artifactId>-->
-<!-- </exclusion>-->
-<!-- <exclusion>-->
-<!-- <groupId>org.jboss.resteasy.spring</groupId>-->
-<!-- <artifactId>resteasy-spring</artifactId>-->
-<!-- </exclusion>-->
-<!-- <exclusion>-->
-<!-- <groupId>org.jboss.resteasy</groupId>-->
-<!-- <artifactId>resteasy-core</artifactId>-->
-<!-- </exclusion>-->
-<!-- <exclusion>-->
-<!-- <groupId>org.jboss.resteasy</groupId>-->
-<!-- <artifactId>resteasy-core-spi</artifactId>-->
-<!-- </exclusion>-->
-<!-- </exclusions>-->
-<!-- </dependency>-->
-
- <dependency>
- <groupId>org.jboss.resteasy.spring</groupId>
- <artifactId>resteasy-spring</artifactId>
- <exclusions>
- <exclusion>
- <groupId>org.jboss.resteasy</groupId>
- <artifactId>resteasy-client</artifactId>
- </exclusion>
- </exclusions>
- </dependency>
- <dependency>
- <groupId>org.jboss.resteasy</groupId>
- <artifactId>resteasy-client</artifactId>
- <version>${resteasy.version}</version>
- <exclusions>
- <exclusion>
- <groupId>commons-logging</groupId>
- <artifactId>commons-logging</artifactId>
- </exclusion>
- </exclusions>
- </dependency>
- <dependency>
- <groupId>org.jboss.resteasy</groupId>
- <artifactId>resteasy-servlet-initializer</artifactId>
- <version>${resteasy.version}</version>
- </dependency>
- <dependency>
- <groupId>org.jboss.resteasy</groupId>
- <artifactId>resteasy-jackson2-provider</artifactId>
- <version>${resteasy.version}</version>
- </dependency>
-
- <dependency>
- <groupId>org.jboss.resteasy</groupId>
- <artifactId>resteasy-jaxb-provider</artifactId>
- <exclusions>
- <exclusion>
- <groupId>org.jboss.logging</groupId>
- <artifactId>jboss-logging</artifactId>
- </exclusion>
- <exclusion>
- <groupId>org.glassfish.jaxb</groupId>
- <artifactId>jaxb-runtime</artifactId>
- </exclusion>
- </exclusions>
- </dependency>
<!-- TESTING -->
diff --git a/viewers/restfulobjects/jaxrs-resteasy/src/main/java/org/apache/causeway/viewer/restfulobjects/jaxrsresteasy/CausewayModuleViewerRestfulObjectsJaxrsResteasy.java b/viewers/restfulobjects/jaxrs-resteasy/src/main/java/org/apache/causeway/viewer/restfulobjects/jaxrsresteasy/CausewayModuleViewerRestfulObjectsJaxrsResteasy.java
index 37868026832..35128cd9e69 100644
--- a/viewers/restfulobjects/jaxrs-resteasy/src/main/java/org/apache/causeway/viewer/restfulobjects/jaxrsresteasy/CausewayModuleViewerRestfulObjectsJaxrsResteasy.java
+++ b/viewers/restfulobjects/jaxrs-resteasy/src/main/java/org/apache/causeway/viewer/restfulobjects/jaxrsresteasy/CausewayModuleViewerRestfulObjectsJaxrsResteasy.java
@@ -18,68 +18,30 @@
*/
package org.apache.causeway.viewer.restfulobjects.jaxrsresteasy;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Map;
-import java.util.Objects;
-import java.util.Set;
-import java.util.stream.Collectors;
-import jakarta.servlet.Servlet;
-import jakarta.servlet.ServletContainerInitializer;
-import jakarta.servlet.ServletContext;
-import jakarta.servlet.ServletContextEvent;
-import jakarta.servlet.ServletContextListener;
-import jakarta.ws.rs.ApplicationPath;
-import jakarta.ws.rs.Path;
-import jakarta.ws.rs.core.Application;
-import jakarta.ws.rs.ext.Provider;
-import org.jboss.resteasy.core.AsynchronousDispatcher;
-import org.jboss.resteasy.core.ResourceMethodRegistry;
-import org.jboss.resteasy.core.SynchronousDispatcher;
-import org.jboss.resteasy.core.providerfactory.ResteasyProviderFactoryImpl;
-import org.jboss.resteasy.plugins.server.servlet.HttpServlet30Dispatcher;
-import org.jboss.resteasy.plugins.server.servlet.ListenerBootstrap;
-import org.jboss.resteasy.plugins.server.servlet.ResteasyBootstrap;
-import org.jboss.resteasy.plugins.server.servlet.ResteasyContextParameters;
-import org.jboss.resteasy.plugins.servlet.ResteasyServletInitializer;
-import org.jboss.resteasy.plugins.spring.SpringBeanProcessor;
-import org.jboss.resteasy.spi.Dispatcher;
-import org.jboss.resteasy.spi.Registry;
-import org.jboss.resteasy.spi.ResteasyDeployment;
-import org.jboss.resteasy.spi.ResteasyProviderFactory;
-import org.springframework.beans.BeansException;
-import org.springframework.beans.factory.BeanFactory;
-import org.springframework.beans.factory.annotation.Qualifier;
-import org.springframework.beans.factory.config.BeanDefinition;
-import org.springframework.beans.factory.config.BeanFactoryPostProcessor;
-import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
-import org.springframework.beans.factory.config.ConstructorArgumentValues;
-import org.springframework.beans.factory.support.BeanDefinitionRegistry;
-import org.springframework.beans.factory.support.GenericBeanDefinition;
-import org.springframework.boot.autoconfigure.AutoConfiguration;
-import org.springframework.boot.autoconfigure.AutoConfigurationPackages;
-import org.springframework.boot.context.properties.EnableConfigurationProperties;
-import org.springframework.boot.web.servlet.ServletRegistrationBean;
-import org.springframework.boot.webmvc.autoconfigure.WebMvcAutoConfiguration;
-import org.springframework.context.annotation.Bean;
-import org.springframework.context.annotation.ClassPathScanningCandidateComponentProvider;
+
+//import org.jboss.resteasy.core.AsynchronousDispatcher;
+//import org.jboss.resteasy.core.ResourceMethodRegistry;
+//import org.jboss.resteasy.core.SynchronousDispatcher;
+//import org.jboss.resteasy.core.providerfactory.ResteasyProviderFactoryImpl;
+//import org.jboss.resteasy.plugins.server.servlet.HttpServlet30Dispatcher;
+//import org.jboss.resteasy.plugins.server.servlet.ListenerBootstrap;
+//import org.jboss.resteasy.plugins.server.servlet.ResteasyBootstrap;
+//import org.jboss.resteasy.plugins.server.servlet.ResteasyContextParameters;
+//import org.jboss.resteasy.plugins.servlet.ResteasyServletInitializer;
+//import org.jboss.resteasy.plugins.spring.SpringBeanProcessor;
+//import org.jboss.resteasy.spi.Dispatcher;
+//import org.jboss.resteasy.spi.Registry;
+//import org.jboss.resteasy.spi.ResteasyDeployment;
+//import org.jboss.resteasy.spi.ResteasyProviderFactory;
+
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
-import org.springframework.core.annotation.AnnotationUtils;
-import org.springframework.core.env.ConfigurableEnvironment;
-import org.springframework.core.type.filter.AssignableTypeFilter;
-import org.springframework.util.ClassUtils;
-
-import org.apache.causeway.viewer.restfulobjects.jaxrsresteasy.conneg.RestfulObjectsJaxbWriterForXml;
import org.apache.causeway.viewer.restfulobjects.jaxrsresteasy.webmodule.WebModuleJaxrsResteasy;
import org.apache.causeway.viewer.restfulobjects.viewer.CausewayModuleViewerRestfulObjectsViewer;
-import lombok.extern.slf4j.Slf4j;
-
/**
* TODO[CAUSEWAY-3892] temporarily incorporates code from https://github.com/resteasy/resteasy-spring-boot
* which does not support Sprint Boot 4 yet
@@ -95,610 +57,666 @@
WebModuleJaxrsResteasy.class,
// @Component's
- RestfulObjectsJaxbWriterForXml.class,
+ //RestfulObjectsJaxbWriterForXml.class,
})
-@AutoConfiguration(after = WebMvcAutoConfiguration.class)
-@EnableConfigurationProperties
-@Slf4j
+//@AutoConfiguration(after = WebMvcAutoConfiguration.class)
+//@EnableConfigurationProperties
+//@Slf4j
public class CausewayModuleViewerRestfulObjectsJaxrsResteasy {
- /**
- * The main function of this class is to prepare, configure and initialize the core components of a RESTEasy deployment.
- */
- public static class DeploymentCustomizer {
-
- /**
- * Configures and initializes a resteasy deployment with:<br>
- * - A {@code org.jboss.resteasy.spi.Dispatcher}<br>
- * - A {@code org.jboss.resteasy.spi.ResteasyProviderFactory}<br>
- * - A {@code org.jboss.resteasy.core.ResourceMethodRegistry}
- *
- * @param resteasySpringBeanProcessor
- * - The spring bean processor to acquire the provider and resource factories from.
- * @param deployment
- * - The deployment to customize.
- * @param enableAsyncJob
- * - Indicates whether the async job service should be enabled.
- */
- public static void customizeRestEasyDeployment(final SpringBeanProcessor resteasySpringBeanProcessor, final ResteasyDeployment deployment, final boolean enableAsyncJob) {
-
- Objects.requireNonNull(resteasySpringBeanProcessor);
- Objects.requireNonNull(deployment);
-
- final ResteasyProviderFactory resteasyProviderFactory = resteasySpringBeanProcessor.getProviderFactory();
- final ResourceMethodRegistry resourceMethodRegistry = (ResourceMethodRegistry) resteasySpringBeanProcessor.getRegistry();
-
- deployment.setProviderFactory(resteasyProviderFactory);
- deployment.setRegistry(resourceMethodRegistry);
-
- if(enableAsyncJob) {
- deployment.setAsyncJobServiceEnabled(true);
- final AsynchronousDispatcher dispatcher = new AsynchronousDispatcher(resteasyProviderFactory, resourceMethodRegistry);
- deployment.setDispatcher(dispatcher);
- } else {
- final SynchronousDispatcher dispatcher = new SynchronousDispatcher(resteasyProviderFactory, resourceMethodRegistry);
- deployment.setDispatcher(dispatcher);
- }
-
- }
-
- }
-
- /**
- * This is a modified version of {@link ResteasyBootstrap}
- * @param resteasySpringBeanProcessor - A bean processor for Resteasy.
- *
- * @return a ServletContextListener object that configures and start a ResteasyDeployment
- */
- @Bean
- public ServletContextListener resteasyBootstrapListener(
- final @Qualifier("resteasySpringBeanProcessor") SpringBeanProcessor resteasySpringBeanProcessor) {
-
- ServletContextListener servletContextListener = new ServletContextListener() {
-
- protected ResteasyDeployment deployment;
-
- @Override
- public void contextInitialized(final ServletContextEvent sce) {
- ServletContext servletContext = sce.getServletContext();
-
- deployment = new ListenerBootstrap(servletContext).createDeployment();
- DeploymentCustomizer.customizeRestEasyDeployment(resteasySpringBeanProcessor, deployment,
- deployment.isAsyncJobServiceEnabled());
- deployment.start();
-
- servletContext.setAttribute(ResteasyProviderFactory.class.getName(), deployment.getProviderFactory());
- servletContext.setAttribute(Dispatcher.class.getName(), deployment.getDispatcher());
- servletContext.setAttribute(Registry.class.getName(), deployment.getRegistry());
- }
-
- @Override
- public void contextDestroyed(final ServletContextEvent sce) {
- if (deployment != null) {
- deployment.stop();
- }
- }
- };
-
- log.debug("ServletContextListener has been created");
-
- return servletContextListener;
- }
-
- /**
- * This class is the Spring Boot equivalent of {@link ResteasyServletInitializer},
- * which implements the Servlet API {@link ServletContainerInitializer} interface
- * to find all JAX-RS Application, Provider and Path classes in the classpath.
- *
- * As we all know, in Spring Boot we use an embedded servlet container. However,
- * the Servlet spec does not support embedded containers, and many portions of it
- * do not apply to embedded containers, and ServletContainerInitializer is one of them.
- *
- * This class fills in this gap.
- *
- * Notice that the JAX-RS Application classes are found in this RESTEasy starter by class
- * ResteasyEmbeddedServletInitializer, and that is done by scanning the classpath.
- *
- * The Path and Provider annotated classes are found by using Spring framework (instead of
- * scanning the classpath), since it is assumed those classes are ALWAYS necessarily
- * Spring beans (this starter is meant for Spring Boot applications that use RESTEasy
- * as the JAX-RS implementation)
- *
- * @author Fabio Carvalho (facarvalho@paypal.com or fabiocarvalho777@gmail.com)
- */
- @Slf4j
- public static class ResteasyApplicationBuilder {
-
- public static final String BEAN_NAME = "JaxrsApplicationServletBuilder";
-
- public ServletRegistrationBean build(final String applicationClassName, final String path, final Set<Class<?>> resources, final Set<Class<?>> providers) {
- Servlet servlet = new HttpServlet30Dispatcher();
-
- ServletRegistrationBean servletRegistrationBean = new ServletRegistrationBean(servlet);
-
- servletRegistrationBean.setName(applicationClassName);
- servletRegistrationBean.setLoadOnStartup(1);
- servletRegistrationBean.setAsyncSupported(true);
-// servletRegistrationBean.addInitParameter(Application.class.getTypeName(), applicationClassName);
- servletRegistrationBean.addInitParameter("jakarta.ws.rs.Application", applicationClassName);
-
- if (path != null) {
- String mapping = path;
- if (!mapping.startsWith("/"))
- mapping = "/" + mapping;
- String prefix = mapping;
- if (!"/".equals(prefix) && prefix.endsWith("/"))
- prefix = prefix.substring(0, prefix.length() - 1);
- if (mapping.endsWith("/"))
- mapping += "*";
- else
- mapping += "/*";
- servletRegistrationBean.addInitParameter("resteasy.servlet.mapping.prefix", prefix);
- servletRegistrationBean.addUrlMappings(mapping);
- }
-
- if (resources.size() > 0) {
- StringBuilder builder = new StringBuilder();
- boolean first = true;
- for (Class<?> resource : resources) {
- if (first) {
- first = false;
- } else {
- builder.append(",");
- }
-
- builder.append(resource.getName());
- }
- servletRegistrationBean.addInitParameter(ResteasyContextParameters.RESTEASY_SCANNED_RESOURCES, builder.toString());
- }
- if (providers.size() > 0) {
- StringBuilder builder = new StringBuilder();
- boolean first = true;
- for (Class<?> provider : providers) {
- if (first) {
- first = false;
- } else {
- builder.append(",");
- }
- builder.append(provider.getName());
- }
- servletRegistrationBean.addInitParameter(ResteasyContextParameters.RESTEASY_SCANNED_PROVIDERS, builder.toString());
- }
-
- log.debug("ServletRegistrationBean has just bean created for JAX-RS class " + applicationClassName);
-
- return servletRegistrationBean;
- }
-
- }
-
- @Bean(name = ResteasyApplicationBuilder.BEAN_NAME)
- public ResteasyApplicationBuilder resteasyApplicationBuilder() {
- return new ResteasyApplicationBuilder();
- }
-
- /**
- * Helper class to scan the classpath under the specified packages
- * searching for JAX-RS Application sub-classes
- *
- * @author Fabio Carvalho (facarvalho@paypal.com or fabiocarvalho777@gmail.com)
- */
- @Slf4j
- public static abstract class JaxrsApplicationScanner {
-
- private static Map<String, Set<Class<? extends Application>>> packagesToClassesMap = new HashMap<>();
-
- public static Set<Class<? extends Application>> getApplications(final List<String> packagesToBeScanned) {
- final String packagesKey = createPackagesKey(packagesToBeScanned);
- if(!packagesToClassesMap.containsKey(packagesKey)) {
- packagesToClassesMap.put(packagesKey, findJaxrsApplicationClasses(packagesToBeScanned));
- }
-
- return packagesToClassesMap.get(packagesKey);
- }
-
- private static String createPackagesKey(final List<String> packagesToBeScanned) {
- return String.join(",", packagesToBeScanned);
- }
-
- /*
- * Scan the classpath under the specified packages looking for JAX-RS Application sub-classes
- */
- private static Set<Class<? extends Application>> findJaxrsApplicationClasses(final List<String> packagesToBeScanned) {
- log.info("Scanning classpath to find JAX-RS Application classes");
-
- ClassPathScanningCandidateComponentProvider scanner = new ClassPathScanningCandidateComponentProvider(false);
- scanner.addIncludeFilter(new AssignableTypeFilter(Application.class));
-
- Set<BeanDefinition> candidates = new HashSet<BeanDefinition>();
- Set<BeanDefinition> candidatesSubSet;
-
- for (String packageToScan : packagesToBeScanned) {
- candidatesSubSet = scanner.findCandidateComponents(packageToScan);
- candidates.addAll(candidatesSubSet);
- }
-
- Set<Class<? extends Application>> classes = new HashSet<Class<? extends Application>>();
- ClassLoader classLoader = JaxrsApplicationScanner.class.getClassLoader();
- Class<? extends Application> type;
- for (BeanDefinition candidate : candidates) {
- try {
- type = (Class<? extends Application>) ClassUtils.forName(candidate.getBeanClassName(), classLoader);
- classes.add(type);
- } catch (ClassNotFoundException e) {
- log.error("JAX-RS Application subclass could not be loaded", e);
- }
- }
-
- // We don't want the JAX-RS Application class itself in there
- classes.remove(Application.class);
-
- return classes;
- }
-
- }
-
- /**
- * Helper class that finds JAX-RS classes annotated with {@link jakarta.ws.rs.Path} and with
- * {@link jakarta.ws.rs.ext.Provider}.
- */
- @Slf4j
- public static class ResteasyResourcesFinder {
-
- /**
- * This is how {@code JAXRS_APP_CLASSES_PROPERTY} was named originally. It conflicted with {@code resteasy.jaxrs.app.registration}<br>
- * in case of YAML files, since registration was a child of app from an YAML perspective, which is not allowed.<br>
- * Because of that its name was changed (the ".classes" suffix was added).
- * This legacy property has not been removed though, to keep backward compatibility, but it is marked as deprecated. It will be
- * available only for {@code .properties} files, but not for {@code YAML} files. It should be finally removed in a future major release.
- */
- private static final String JAXRS_APP_CLASSES_PROPERTY_LEGACY = "resteasy.jaxrs.app";
- private static final String JAXRS_APP_CLASSES_PROPERTY = "resteasy.jaxrs.app.classes";
- private static final String JAXRS_APP_CLASSES_DEFINITION_PROPERTY = "resteasy.jaxrs.app.registration";
-
-
- private enum JaxrsAppClassesRegistration {
- BEANS, PROPERTY, SCANNING, AUTO
- }
-
- private Set<Class<? extends Application>> applications = new HashSet<Class<? extends Application>>();
- private final Set<Class<?>> allResources = new HashSet<Class<?>>();
- private final Set<Class<?>> providers = new HashSet<Class<?>>();
-
- /*
- * Find the JAX-RS application classes.
- * This is done by one of these three options in this order:
- *
- * 1- By having them defined as Spring beans
- * 2- By setting property {@code resteasy.jaxrs.app.classes} via Spring Boot application properties file.
- * This property should contain a comma separated list of JAX-RS sub-classes
- * 3- Via classpath scanning (looking for javax.ws.rs.core.Application sub-classes)
- *
- * First try to find JAX-RS Application sub-classes defined as Spring beans. If that is existent,
- * the search stops, and those are the only JAX-RS applications to be registered.
- * If no JAX-RS application Spring beans are found, then see if Spring Boot property {@code resteasy.jaxrs.app.classes}
- * has been set. If it has, the search stops, and those are the only JAX-RS applications to be registered.
- * If not, then scan the classpath searching for JAX-RS applications.
- *
- * There is a way though to force one of the options above, which is by setting property
- * {@code resteasy.jaxrs.app.registration} via Spring Boot application properties file. The possible valid
- * values are {@code beans}, {@code property}, {@code scanning} or {@code auto}. If this property is not
- * present, the default value is {@code auto}, which means every approach will be tried in the order and way
- * explained earlier.
- *
- * @param beanFactory
- */
- public void findJaxrsApplications(final ConfigurableListableBeanFactory beanFactory) {
- log.info("Finding JAX-RS Application classes");
-
- final JaxrsAppClassesRegistration registration = getJaxrsAppClassesRegistration(beanFactory);
-
- switch (registration) {
- case AUTO:
- findJaxrsApplicationBeans(beanFactory);
- if(applications.isEmpty()) findJaxrsApplicationProperty(beanFactory);
- if(applications.isEmpty()) findJaxrsApplicationScanning(beanFactory);
- break;
- case BEANS:
- findJaxrsApplicationBeans(beanFactory);
- break;
- case PROPERTY:
- findJaxrsApplicationProperty(beanFactory);
- break;
- case SCANNING:
- findJaxrsApplicationScanning(beanFactory);
- break;
- default:
- log.error("JAX-RS application registration method (%s) not known, no application will be configured", registration.name());
- break;
- }
-
- applications = applications.stream().filter(app -> {
- final ApplicationPath path = AnnotationUtils.findAnnotation(app, ApplicationPath.class);
- if (path == null) {
- log.warn("JAX-RS Application class {} has no ApplicationPath annotation, so it will not be configured", app.getName());
- } else {
- log.info("JAX-RS Application class found: {}", ((Class<Application>) app).getName());
- }
- return path != null;
- }).collect(Collectors.toSet());
-
- }
-
-
- private JaxrsAppClassesRegistration getJaxrsAppClassesRegistration(final ConfigurableListableBeanFactory beanFactory) {
- final ConfigurableEnvironment configurableEnvironment = beanFactory.getBean(ConfigurableEnvironment.class);
- final String jaxrsAppClassesRegistration = configurableEnvironment.getProperty(JAXRS_APP_CLASSES_DEFINITION_PROPERTY);
- JaxrsAppClassesRegistration registration = JaxrsAppClassesRegistration.AUTO;
-
- if(jaxrsAppClassesRegistration == null) {
- log.info("Property {} has not been set, JAX-RS Application classes registration is being set to AUTO", JAXRS_APP_CLASSES_DEFINITION_PROPERTY);
- } else {
- log.info("Property {} has been set to {}", JAXRS_APP_CLASSES_DEFINITION_PROPERTY, jaxrsAppClassesRegistration);
- try {
- registration = JaxrsAppClassesRegistration.valueOf(jaxrsAppClassesRegistration.toUpperCase());
- } catch(IllegalArgumentException ex) {
- final String errorMesage = String.format(
- "Property %s has not been properly set, value %s is invalid. JAX-RS Application classes registration is being set to AUTO.",
- JAXRS_APP_CLASSES_DEFINITION_PROPERTY, jaxrsAppClassesRegistration);
- log.error(errorMesage);
- throw new IllegalArgumentException(errorMesage, ex);
- }
- }
-
- return registration;
- }
-
- /*
- * Find JAX-RS application classes by searching for their related
- * Spring beans
- *
- * @param beanFactory
- */
- private void findJaxrsApplicationBeans(final ConfigurableListableBeanFactory beanFactory) {
- log.info("Searching for JAX-RS Application Spring beans");
-
- final Map<String, Application> applicationBeans = beanFactory.getBeansOfType(Application.class, true, false);
- if(applicationBeans == null || applicationBeans.isEmpty()) {
- log.info("No JAX-RS Application Spring beans found");
- return;
- }
-
- for (Application application : applicationBeans.values()) {
- applications.add(application.getClass());
- }
- }
-
- /*
- * Find JAX-RS application classes via property {@code resteasy.jaxrs.app.classes}
- */
- private void findJaxrsApplicationProperty(final ConfigurableListableBeanFactory beanFactory) {
- final ConfigurableEnvironment configurableEnvironment = beanFactory.getBean(ConfigurableEnvironment.class);
- String jaxrsAppsProperty = configurableEnvironment.getProperty(JAXRS_APP_CLASSES_PROPERTY);
- if(jaxrsAppsProperty == null) {
- jaxrsAppsProperty = configurableEnvironment.getProperty(JAXRS_APP_CLASSES_PROPERTY_LEGACY);
- if(jaxrsAppsProperty == null) {
- log.info("No JAX-RS Application set via property {}", JAXRS_APP_CLASSES_PROPERTY);
- return;
- }
- log.warn(
- "Property {} has been set. Notice that this property has been deprecated and will be removed soon. Please replace it by property {}",
- JAXRS_APP_CLASSES_PROPERTY_LEGACY, JAXRS_APP_CLASSES_PROPERTY);
- } else {
- log.info("Property {} has been set to {}", JAXRS_APP_CLASSES_PROPERTY, jaxrsAppsProperty);
- }
-
- final String[] jaxrsClassNames = jaxrsAppsProperty.split(",");
-
- for(String jaxrsClassName : jaxrsClassNames) {
- Class<? extends Application> jaxrsClass = null;
- try {
- jaxrsClass = (Class<? extends Application>) Class.forName(jaxrsClassName.trim());
- } catch (ClassNotFoundException e) {
- final String exceptionMessage = String.format("JAX-RS Application class %s has not been found", jaxrsClassName.trim());
- log.error(exceptionMessage, e);
- throw new BeansException(exceptionMessage, e){};
- }
- applications.add(jaxrsClass);
- }
- }
-
- /*
- * Find JAX-RS application classes by scanning the classpath under
- * packages already marked to be scanned by Spring framework
- */
- private void findJaxrsApplicationScanning(final BeanFactory beanFactory) {
- final List<String> packagesToBeScanned = getSpringApplicationPackages(beanFactory);
-
- final Set<Class<? extends Application>> applications = JaxrsApplicationScanner.getApplications(packagesToBeScanned);
- if(applications == null || applications.isEmpty()) {
- return;
- }
- this.applications.addAll(applications);
- }
-
- /*
- * Return the name of the packages to be scanned by Spring framework
- */
- private List<String> getSpringApplicationPackages(final BeanFactory beanFactory) {
- return AutoConfigurationPackages.get(beanFactory);
- }
-
- /*
- * Search for JAX-RS resource and provider Spring beans,
- * which are the ones whose classes are annotated with
- * {@link Path} or {@link Provider} respectively
- *
- * @param beanFactory
- */
- public void findJaxrsResourcesAndProviderClasses(final ConfigurableListableBeanFactory beanFactory) {
- log.debug("Finding JAX-RS resources and providers Spring bean classes");
-
- final String[] resourceBeans = beanFactory.getBeanNamesForAnnotation(Path.class);
- final String[] providerBeans = beanFactory.getBeanNamesForAnnotation(Provider.class);
-
- if(resourceBeans != null) {
- for(String resourceBean : resourceBeans) {
- allResources.add(beanFactory.getType(resourceBean));
- }
- }
-
- if (this.getAllResources().isEmpty()) {
- log.warn("No JAX-RS resource Spring beans have been found");
- }
-
- if(providerBeans != null) {
- for(String providerBean : providerBeans) {
- providers.add(beanFactory.getType(providerBean));
- }
- }
-
- if(log.isDebugEnabled()) {
- for (Object resourceClass : allResources.toArray()) {
- log.debug("JAX-RS resource class found: {}", ((Class) resourceClass).getName());
- }
- }
- if(log.isDebugEnabled()) {
- for (Object providerClass: providers.toArray()) {
- log.debug("JAX-RS provider class found: {}", ((Class) providerClass).getName());
- }
- }
- }
-
- public Set<Class<? extends Application>> getApplications() {
- return this.applications;
- }
-
- public Set<Class<?>> getAllResources() {
- return this.allResources;
- }
-
- public Set<Class<?>> getProviders() {
- return this.providers;
- }
-
- }
-
- /**
- * This is a Spring version of {@link ResteasyServletInitializer}.
- * It does not register the servlets though, that is done by {@link ResteasyApplicationBuilder}
- * It only finds the JAX-RS Application classes (by scanning the classpath), and
- * the JAX-RS Path and Provider annotated Spring beans, and then register the
- * Spring bean definitions that represent each servlet registration.
- *
- * @author Fabio Carvalho (facarvalho@paypal.com or fabiocarvalho777@gmail.com)
- */
- @Slf4j
- public static class ResteasyBeanProcessorTomcat extends ResteasyResourcesFinder implements BeanFactoryPostProcessor {
-
- private static final String JAXRS_DEFAULT_PATH = "resteasy.jaxrs.defaultPath";
- private static final String DEFAULT_BASE_APP_PATH = "/";
-
- @Override
- public void postProcessBeanFactory(final ConfigurableListableBeanFactory beanFactory) throws BeansException {
-
- log.debug("Post process bean factory has been called");
-
- findJaxrsApplications(beanFactory);
-
- // This is done by finding their related Spring beans
- findJaxrsResourcesAndProviderClasses(beanFactory);
-
- if (getApplications().size() == 0) {
- registerDefaultJaxrsApp(beanFactory);
- return;
- }
-
- BeanDefinitionRegistry registry = (BeanDefinitionRegistry) beanFactory;
-
- for (Class<? extends Application> applicationClass : getApplications()) {
-
- ApplicationPath path = AnnotationUtils.findAnnotation(applicationClass, ApplicationPath.class);
- log.debug("registering JAX-RS application class " + applicationClass.getName());
- GenericBeanDefinition applicationServletBean = createApplicationServlet(applicationClass, path.value());
- registry.registerBeanDefinition(applicationClass.getName(), applicationServletBean);
-
- }
-
- }
-
- /**
- * Register a default JAX-RS application, in case no other is present in the application.
- * Read section 2.3.2 in JAX-RS 2.0 specification.
- *
- * @param beanFactory
- */
- private void registerDefaultJaxrsApp(final ConfigurableListableBeanFactory beanFactory) {
- BeanDefinitionRegistry registry = (BeanDefinitionRegistry) beanFactory;
- ConfigurableEnvironment configurableEnvironment = beanFactory.getBean(ConfigurableEnvironment.class);
- String path = configurableEnvironment.getProperty(JAXRS_DEFAULT_PATH, DEFAULT_BASE_APP_PATH);
- GenericBeanDefinition applicationServletBean =
- createApplicationServlet(Application.class, path);
-
- log.info("No JAX-RS Application classes have been found. A default, one mapped to '{}', will be registered.", path);
- registry.registerBeanDefinition(Application.class.getName(), applicationServletBean);
- }
-
- /**
- * Creates a Servlet bean definition for the given JAX-RS application
- *
- * @param applicationClass
- * @param path
- * @return a Servlet bean definition for the given JAX-RS application
- */
- private GenericBeanDefinition createApplicationServlet(final Class<? extends Application> applicationClass, final String path) {
- GenericBeanDefinition applicationServletBean = new GenericBeanDefinition();
- applicationServletBean.setFactoryBeanName(ResteasyApplicationBuilder.BEAN_NAME);
- applicationServletBean.setFactoryMethodName("build");
-
- Set<Class<?>> resources = getAllResources();
-
- ConstructorArgumentValues values = new ConstructorArgumentValues();
- values.addIndexedArgumentValue(0, applicationClass.getName());
- values.addIndexedArgumentValue(1, path);
- values.addIndexedArgumentValue(2, resources);
- values.addIndexedArgumentValue(3, getProviders());
- applicationServletBean.setConstructorArgumentValues(values);
-
- applicationServletBean.setAutowireCandidate(false);
- applicationServletBean.setScope("singleton");
-
- return applicationServletBean;
- }
-
- }
-
- @Bean
- public static ResteasyBeanProcessorTomcat resteasyBeanProcessorTomcat() {
- return new ResteasyBeanProcessorTomcat();
- }
-
- /**
- * Class that creates a spring bean processor for Resteasy. See
- * {@link org.jboss.resteasy.plugins.spring.SpringBeanProcessor}.
- */
- @Slf4j
- public static class ResteasyBeanProcessorFactory {
-
- public static SpringBeanProcessor resteasySpringBeanProcessor() {
- ResteasyProviderFactory resteasyProviderFactory = new ResteasyProviderFactoryImpl();
- ResourceMethodRegistry resourceMethodRegistry = new ResourceMethodRegistry(resteasyProviderFactory);
-
- SpringBeanProcessor resteasySpringBeanProcessor = new SpringBeanProcessor();
- resteasySpringBeanProcessor.setProviderFactory(resteasyProviderFactory);
- resteasySpringBeanProcessor.setRegistry(resourceMethodRegistry);
-
- log.debug("Resteasy Spring Bean Processor has been created");
-
- return resteasySpringBeanProcessor;
- }
-
- }
- @Bean("resteasySpringBeanProcessor")
- public static SpringBeanProcessor resteasySpringBeanProcessor() {
- return ResteasyBeanProcessorFactory.resteasySpringBeanProcessor();
- }
+// import java.lang.annotation.Annotation;
+// import java.lang.reflect.Type;
+//
+// import jakarta.inject.Inject;
+// import jakarta.ws.rs.Produces;
+// import org.springframework.http.MediaType;
+// import jakarta.ws.rs.ext.Provider;
+// import jakarta.xml.bind.Marshaller;
+//
+// import org.jboss.resteasy.plugins.providers.jaxb.JAXBXmlRootElementProvider;
+//
+// import org.springframework.stereotype.Component;
+//
+// import org.apache.causeway.applib.jaxb.PersistentEntityAdapter;
+// import org.apache.causeway.applib.services.inject.ServiceInjector;
+// @Component
+// @Provider
+// @Produces({"application/xml", "application/*+xml", "text/*+xml"})
+// public static class RestfulObjectsJaxbWriterForXml extends JAXBXmlRootElementProvider {
+//
+// @Inject private ServiceInjector serviceInjector;
+//
+// @Override
+// protected boolean isReadWritable(
+// final Class<?> type,
+// final Type genericType,
+// final Annotation[] annotations,
+// final MediaType mediaType) {
+//
+// return super.isReadWritable(type, genericType, annotations, mediaType) &&
+// hasXRoDomainTypeParameter(mediaType);
+// }
+//
+// @Override
+// protected Marshaller getMarshaller(
+// final Class<?> type,
+// final Annotation[] annotations,
+// final MediaType mediaType) {
+//
+// var adapter = serviceInjector.injectServicesInto(new PersistentEntityAdapter());
+//
+// var marshaller = super.getMarshaller(type, annotations, mediaType);
+// marshaller.setAdapter(PersistentEntityAdapter.class, adapter);
+// return marshaller;
+// }
+//
+// // HELPER
+//
+// private static boolean hasXRoDomainTypeParameter(final MediaType mediaType) {
+// final boolean retval = mediaType.getParameters().containsKey("x-ro-domain-type");
+// return retval;
+// }
+//
+// }
+
+// /**
+// * The main function of this class is to prepare, configure and initialize the core components of a RESTEasy deployment.
+// */
+// public static class DeploymentCustomizer {
+//
+// /**
+// * Configures and initializes a resteasy deployment with:<br>
+// * - A {@code org.jboss.resteasy.spi.Dispatcher}<br>
+// * - A {@code org.jboss.resteasy.spi.ResteasyProviderFactory}<br>
+// * - A {@code org.jboss.resteasy.core.ResourceMethodRegistry}
+// *
+// * @param resteasySpringBeanProcessor
+// * - The spring bean processor to acquire the provider and resource factories from.
+// * @param deployment
+// * - The deployment to customize.
+// * @param enableAsyncJob
+// * - Indicates whether the async job service should be enabled.
+// */
+// public static void customizeRestEasyDeployment(final SpringBeanProcessor resteasySpringBeanProcessor, final ResteasyDeployment deployment, final boolean enableAsyncJob) {
+//
+// Objects.requireNonNull(resteasySpringBeanProcessor);
+// Objects.requireNonNull(deployment);
+//
+// final ResteasyProviderFactory resteasyProviderFactory = resteasySpringBeanProcessor.getProviderFactory();
+// final ResourceMethodRegistry resourceMethodRegistry = (ResourceMethodRegistry) resteasySpringBeanProcessor.getRegistry();
+//
+// deployment.setProviderFactory(resteasyProviderFactory);
+// deployment.setRegistry(resourceMethodRegistry);
+//
+// if(enableAsyncJob) {
+// deployment.setAsyncJobServiceEnabled(true);
+// final AsynchronousDispatcher dispatcher = new AsynchronousDispatcher(resteasyProviderFactory, resourceMethodRegistry);
+// deployment.setDispatcher(dispatcher);
+// } else {
+// final SynchronousDispatcher dispatcher = new SynchronousDispatcher(resteasyProviderFactory, resourceMethodRegistry);
+// deployment.setDispatcher(dispatcher);
+// }
+//
+// }
+//
+// }
+//
+// /**
+// * This is a modified version of {@link ResteasyBootstrap}
+// * @param resteasySpringBeanProcessor - A bean processor for Resteasy.
+// *
+// * @return a ServletContextListener object that configures and start a ResteasyDeployment
+// */
+// @Bean
+// public ServletContextListener resteasyBootstrapListener(
+// final @Qualifier("resteasySpringBeanProcessor") SpringBeanProcessor resteasySpringBeanProcessor) {
+//
+// ServletContextListener servletContextListener = new ServletContextListener() {
+//
+// protected ResteasyDeployment deployment;
+//
+// @Override
+// public void contextInitialized(final ServletContextEvent sce) {
+// ServletContext servletContext = sce.getServletContext();
+//
+// deployment = new ListenerBootstrap(servletContext).createDeployment();
+// DeploymentCustomizer.customizeRestEasyDeployment(resteasySpringBeanProcessor, deployment,
+// deployment.isAsyncJobServiceEnabled());
+// deployment.start();
+//
+// servletContext.setAttribute(ResteasyProviderFactory.class.getName(), deployment.getProviderFactory());
+// servletContext.setAttribute(Dispatcher.class.getName(), deployment.getDispatcher());
+// servletContext.setAttribute(Registry.class.getName(), deployment.getRegistry());
+// }
+//
+// @Override
+// public void contextDestroyed(final ServletContextEvent sce) {
+// if (deployment != null) {
+// deployment.stop();
+// }
+// }
+// };
+//
+// log.debug("ServletContextListener has been created");
+//
+// return servletContextListener;
+// }
+//
+// /**
+// * This class is the Spring Boot equivalent of {@link ResteasyServletInitializer},
+// * which implements the Servlet API {@link ServletContainerInitializer} interface
+// * to find all JAX-RS Application, Provider and Path classes in the classpath.
+// *
+// * As we all know, in Spring Boot we use an embedded servlet container. However,
+// * the Servlet spec does not support embedded containers, and many portions of it
+// * do not apply to embedded containers, and ServletContainerInitializer is one of them.
+// *
+// * This class fills in this gap.
+// *
+// * Notice that the JAX-RS Application classes are found in this RESTEasy starter by class
+// * ResteasyEmbeddedServletInitializer, and that is done by scanning the classpath.
+// *
+// * The Path and Provider annotated classes are found by using Spring framework (instead of
+// * scanning the classpath), since it is assumed those classes are ALWAYS necessarily
+// * Spring beans (this starter is meant for Spring Boot applications that use RESTEasy
+// * as the JAX-RS implementation)
+// *
+// * @author Fabio Carvalho (facarvalho@paypal.com or fabiocarvalho777@gmail.com)
+// */
+// @Slf4j
+// public static class ResteasyApplicationBuilder {
+//
+// public static final String BEAN_NAME = "JaxrsApplicationServletBuilder";
+//
+// public ServletRegistrationBean build(final String applicationClassName, final String path, final Set<Class<?>> resources, final Set<Class<?>> providers) {
+// Servlet servlet = new HttpServlet30Dispatcher();
+//
+// ServletRegistrationBean servletRegistrationBean = new ServletRegistrationBean(servlet);
+//
+// servletRegistrationBean.setName(applicationClassName);
+// servletRegistrationBean.setLoadOnStartup(1);
+// servletRegistrationBean.setAsyncSupported(true);
+//// servletRegistrationBean.addInitParameter(Application.class.getTypeName(), applicationClassName);
+// servletRegistrationBean.addInitParameter("jakarta.ws.rs.Application", applicationClassName);
+//
+// if (path != null) {
+// String mapping = path;
+// if (!mapping.startsWith("/"))
+// mapping = "/" + mapping;
+// String prefix = mapping;
+// if (!"/".equals(prefix) && prefix.endsWith("/"))
+// prefix = prefix.substring(0, prefix.length() - 1);
+// if (mapping.endsWith("/"))
+// mapping += "*";
+// else
+// mapping += "/*";
+// servletRegistrationBean.addInitParameter("resteasy.servlet.mapping.prefix", prefix);
+// servletRegistrationBean.addUrlMappings(mapping);
+// }
+//
+// if (resources.size() > 0) {
+// StringBuilder builder = new StringBuilder();
+// boolean first = true;
+// for (Class<?> resource : resources) {
+// if (first) {
+// first = false;
+// } else {
+// builder.append(",");
+// }
+//
+// builder.append(resource.getName());
+// }
+// servletRegistrationBean.addInitParameter(ResteasyContextParameters.RESTEASY_SCANNED_RESOURCES, builder.toString());
+// }
+// if (providers.size() > 0) {
+// StringBuilder builder = new StringBuilder();
+// boolean first = true;
+// for (Class<?> provider : providers) {
+// if (first) {
+// first = false;
+// } else {
+// builder.append(",");
+// }
+// builder.append(provider.getName());
+// }
+// servletRegistrationBean.addInitParameter(ResteasyContextParameters.RESTEASY_SCANNED_PROVIDERS, builder.toString());
+// }
+//
+// log.debug("ServletRegistrationBean has just bean created for JAX-RS class " + applicationClassName);
+//
+// return servletRegistrationBean;
+// }
+//
+// }
+//
+// @Bean(name = ResteasyApplicationBuilder.BEAN_NAME)
+// public ResteasyApplicationBuilder resteasyApplicationBuilder() {
+// return new ResteasyApplicationBuilder();
+// }
+//
+// /**
+// * Helper class to scan the classpath under the specified packages
+// * searching for JAX-RS Application sub-classes
+// *
+// * @author Fabio Carvalho (facarvalho@paypal.com or fabiocarvalho777@gmail.com)
+// */
+// @Slf4j
+// public static abstract class JaxrsApplicationScanner {
+//
+// private static Map<String, Set<Class<? extends Application>>> packagesToClassesMap = new HashMap<>();
+//
+// public static Set<Class<? extends Application>> getApplications(final List<String> packagesToBeScanned) {
+// final String packagesKey = createPackagesKey(packagesToBeScanned);
+// if(!packagesToClassesMap.containsKey(packagesKey)) {
+// packagesToClassesMap.put(packagesKey, findJaxrsApplicationClasses(packagesToBeScanned));
+// }
+//
+// return packagesToClassesMap.get(packagesKey);
+// }
+//
+// private static String createPackagesKey(final List<String> packagesToBeScanned) {
+// return String.join(",", packagesToBeScanned);
+// }
+//
+// /*
+// * Scan the classpath under the specified packages looking for JAX-RS Application sub-classes
+// */
+// private static Set<Class<? extends Application>> findJaxrsApplicationClasses(final List<String> packagesToBeScanned) {
+// log.info("Scanning classpath to find JAX-RS Application classes");
+//
+// ClassPathScanningCandidateComponentProvider scanner = new ClassPathScanningCandidateComponentProvider(false);
+// scanner.addIncludeFilter(new AssignableTypeFilter(Application.class));
+//
+// Set<BeanDefinition> candidates = new HashSet<BeanDefinition>();
+// Set<BeanDefinition> candidatesSubSet;
+//
+// for (String packageToScan : packagesToBeScanned) {
+// candidatesSubSet = scanner.findCandidateComponents(packageToScan);
+// candidates.addAll(candidatesSubSet);
+// }
+//
+// Set<Class<? extends Application>> classes = new HashSet<Class<? extends Application>>();
+// ClassLoader classLoader = JaxrsApplicationScanner.class.getClassLoader();
+// Class<? extends Application> type;
+// for (BeanDefinition candidate : candidates) {
+// try {
+// type = (Class<? extends Application>) ClassUtils.forName(candidate.getBeanClassName(), classLoader);
+// classes.add(type);
+// } catch (ClassNotFoundException e) {
+// log.error("JAX-RS Application subclass could not be loaded", e);
+// }
+// }
+//
+// // We don't want the JAX-RS Application class itself in there
+// classes.remove(Application.class);
+//
+// return classes;
+// }
+//
+// }
+//
+// /**
+// * Helper class that finds JAX-RS classes annotated with {@link jakarta.ws.rs.Path} and with
+// * {@link jakarta.ws.rs.ext.Provider}.
+// */
+// @Slf4j
+// public static class ResteasyResourcesFinder {
+//
+// /**
+// * This is how {@code JAXRS_APP_CLASSES_PROPERTY} was named originally. It conflicted with {@code resteasy.jaxrs.app.registration}<br>
+// * in case of YAML files, since registration was a child of app from an YAML perspective, which is not allowed.<br>
+// * Because of that its name was changed (the ".classes" suffix was added).
+// * This legacy property has not been removed though, to keep backward compatibility, but it is marked as deprecated. It will be
+// * available only for {@code .properties} files, but not for {@code YAML} files. It should be finally removed in a future major release.
+// */
+// private static final String JAXRS_APP_CLASSES_PROPERTY_LEGACY = "resteasy.jaxrs.app";
+// private static final String JAXRS_APP_CLASSES_PROPERTY = "resteasy.jaxrs.app.classes";
+// private static final String JAXRS_APP_CLASSES_DEFINITION_PROPERTY = "resteasy.jaxrs.app.registration";
+//
+//
+// private enum JaxrsAppClassesRegistration {
+// BEANS, PROPERTY, SCANNING, AUTO
+// }
+//
+// private Set<Class<? extends Application>> applications = new HashSet<Class<? extends Application>>();
+// private final Set<Class<?>> allResources = new HashSet<Class<?>>();
+// private final Set<Class<?>> providers = new HashSet<Class<?>>();
+//
+// /*
+// * Find the JAX-RS application classes.
+// * This is done by one of these three options in this order:
+// *
+// * 1- By having them defined as Spring beans
+// * 2- By setting property {@code resteasy.jaxrs.app.classes} via Spring Boot application properties file.
+// * This property should contain a comma separated list of JAX-RS sub-classes
+// * 3- Via classpath scanning (looking for javax.ws.rs.core.Application sub-classes)
+// *
+// * First try to find JAX-RS Application sub-classes defined as Spring beans. If that is existent,
+// * the search stops, and those are the only JAX-RS applications to be registered.
+// * If no JAX-RS application Spring beans are found, then see if Spring Boot property {@code resteasy.jaxrs.app.classes}
+// * has been set. If it has, the search stops, and those are the only JAX-RS applications to be registered.
+// * If not, then scan the classpath searching for JAX-RS applications.
+// *
+// * There is a way though to force one of the options above, which is by setting property
+// * {@code resteasy.jaxrs.app.registration} via Spring Boot application properties file. The possible valid
+// * values are {@code beans}, {@code property}, {@code scanning} or {@code auto}. If this property is not
+// * present, the default value is {@code auto}, which means every approach will be tried in the order and way
+// * explained earlier.
+// *
+// * @param beanFactory
+// */
+// public void findJaxrsApplications(final ConfigurableListableBeanFactory beanFactory) {
+// log.info("Finding JAX-RS Application classes");
+//
+// final JaxrsAppClassesRegistration registration = getJaxrsAppClassesRegistration(beanFactory);
+//
+// switch (registration) {
+// case AUTO:
+// findJaxrsApplicationBeans(beanFactory);
+// if(applications.isEmpty()) findJaxrsApplicationProperty(beanFactory);
+// if(applications.isEmpty()) findJaxrsApplicationScanning(beanFactory);
+// break;
+// case BEANS:
+// findJaxrsApplicationBeans(beanFactory);
+// break;
+// case PROPERTY:
+// findJaxrsApplicationProperty(beanFactory);
+// break;
+// case SCANNING:
+// findJaxrsApplicationScanning(beanFactory);
+// break;
+// default:
+// log.error("JAX-RS application registration method (%s) not known, no application will be configured", registration.name());
+// break;
+// }
+//
+// applications = applications.stream().filter(app -> {
+// final ApplicationPath path = AnnotationUtils.findAnnotation(app, ApplicationPath.class);
+// if (path == null) {
+// log.warn("JAX-RS Application class {} has no ApplicationPath annotation, so it will not be configured", app.getName());
+// } else {
+// log.info("JAX-RS Application class found: {}", ((Class<Application>) app).getName());
+// }
+// return path != null;
+// }).collect(Collectors.toSet());
+//
+// }
+//
+//
+// private JaxrsAppClassesRegistration getJaxrsAppClassesRegistration(final ConfigurableListableBeanFactory beanFactory) {
+// final ConfigurableEnvironment configurableEnvironment = beanFactory.getBean(ConfigurableEnvironment.class);
+// final String jaxrsAppClassesRegistration = configurableEnvironment.getProperty(JAXRS_APP_CLASSES_DEFINITION_PROPERTY);
+// JaxrsAppClassesRegistration registration = JaxrsAppClassesRegistration.AUTO;
+//
+// if(jaxrsAppClassesRegistration == null) {
+// log.info("Property {} has not been set, JAX-RS Application classes registration is being set to AUTO", JAXRS_APP_CLASSES_DEFINITION_PROPERTY);
+// } else {
+// log.info("Property {} has been set to {}", JAXRS_APP_CLASSES_DEFINITION_PROPERTY, jaxrsAppClassesRegistration);
+// try {
+// registration = JaxrsAppClassesRegistration.valueOf(jaxrsAppClassesRegistration.toUpperCase());
+// } catch(IllegalArgumentException ex) {
+// final String errorMesage = String.format(
+// "Property %s has not been properly set, value %s is invalid. JAX-RS Application classes registration is being set to AUTO.",
+// JAXRS_APP_CLASSES_DEFINITION_PROPERTY, jaxrsAppClassesRegistration);
+// log.error(errorMesage);
+// throw new IllegalArgumentException(errorMesage, ex);
+// }
+// }
+//
+// return registration;
+// }
+//
+// /*
+// * Find JAX-RS application classes by searching for their related
+// * Spring beans
+// *
+// * @param beanFactory
+// */
+// private void findJaxrsApplicationBeans(final ConfigurableListableBeanFactory beanFactory) {
+// log.info("Searching for JAX-RS Application Spring beans");
+//
+// final Map<String, Application> applicationBeans = beanFactory.getBeansOfType(Application.class, true, false);
+// if(applicationBeans == null || applicationBeans.isEmpty()) {
+// log.info("No JAX-RS Application Spring beans found");
+// return;
+// }
+//
+// for (Application application : applicationBeans.values()) {
+// applications.add(application.getClass());
+// }
+// }
+//
+// /*
+// * Find JAX-RS application classes via property {@code resteasy.jaxrs.app.classes}
+// */
+// private void findJaxrsApplicationProperty(final ConfigurableListableBeanFactory beanFactory) {
+// final ConfigurableEnvironment configurableEnvironment = beanFactory.getBean(ConfigurableEnvironment.class);
+// String jaxrsAppsProperty = configurableEnvironment.getProperty(JAXRS_APP_CLASSES_PROPERTY);
+// if(jaxrsAppsProperty == null) {
+// jaxrsAppsProperty = configurableEnvironment.getProperty(JAXRS_APP_CLASSES_PROPERTY_LEGACY);
+// if(jaxrsAppsProperty == null) {
+// log.info("No JAX-RS Application set via property {}", JAXRS_APP_CLASSES_PROPERTY);
+// return;
+// }
+// log.warn(
+// "Property {} has been set. Notice that this property has been deprecated and will be removed soon. Please replace it by property {}",
+// JAXRS_APP_CLASSES_PROPERTY_LEGACY, JAXRS_APP_CLASSES_PROPERTY);
+// } else {
+// log.info("Property {} has been set to {}", JAXRS_APP_CLASSES_PROPERTY, jaxrsAppsProperty);
+// }
+//
+// final String[] jaxrsClassNames = jaxrsAppsProperty.split(",");
+//
+// for(String jaxrsClassName : jaxrsClassNames) {
+// Class<? extends Application> jaxrsClass = null;
+// try {
+// jaxrsClass = (Class<? extends Application>) Class.forName(jaxrsClassName.trim());
+// } catch (ClassNotFoundException e) {
+// final String exceptionMessage = String.format("JAX-RS Application class %s has not been found", jaxrsClassName.trim());
+// log.error(exceptionMessage, e);
+// throw new BeansException(exceptionMessage, e){};
+// }
+// applications.add(jaxrsClass);
+// }
+// }
+//
+// /*
+// * Find JAX-RS application classes by scanning the classpath under
+// * packages already marked to be scanned by Spring framework
+// */
+// private void findJaxrsApplicationScanning(final BeanFactory beanFactory) {
+// final List<String> packagesToBeScanned = getSpringApplicationPackages(beanFactory);
+//
+// final Set<Class<? extends Application>> applications = JaxrsApplicationScanner.getApplications(packagesToBeScanned);
+// if(applications == null || applications.isEmpty()) {
+// return;
+// }
+// this.applications.addAll(applications);
+// }
+//
+// /*
+// * Return the name of the packages to be scanned by Spring framework
+// */
+// private List<String> getSpringApplicationPackages(final BeanFactory beanFactory) {
+// return AutoConfigurationPackages.get(beanFactory);
+// }
+//
+// /*
+// * Search for JAX-RS resource and provider Spring beans,
+// * which are the ones whose classes are annotated with
+// * {@link Path} or {@link Provider} respectively
+// *
+// * @param beanFactory
+// */
+// public void findJaxrsResourcesAndProviderClasses(final ConfigurableListableBeanFactory beanFactory) {
+// log.debug("Finding JAX-RS resources and providers Spring bean classes");
+//
+// final String[] resourceBeans = beanFactory.getBeanNamesForAnnotation(Path.class);
+// final String[] providerBeans = beanFactory.getBeanNamesForAnnotation(Provider.class);
+//
+// if(resourceBeans != null) {
+// for(String resourceBean : resourceBeans) {
+// allResources.add(beanFactory.getType(resourceBean));
+// }
+// }
+//
+// if (this.getAllResources().isEmpty()) {
+// log.warn("No JAX-RS resource Spring beans have been found");
+// }
+//
+// if(providerBeans != null) {
+// for(String providerBean : providerBeans) {
+// providers.add(beanFactory.getType(providerBean));
+// }
+// }
+//
+// if(log.isDebugEnabled()) {
+// for (Object resourceClass : allResources.toArray()) {
+// log.debug("JAX-RS resource class found: {}", ((Class) resourceClass).getName());
+// }
+// }
+// if(log.isDebugEnabled()) {
+// for (Object providerClass: providers.toArray()) {
+// log.debug("JAX-RS provider class found: {}", ((Class) providerClass).getName());
+// }
+// }
+// }
+//
+// public Set<Class<? extends Application>> getApplications() {
+// return this.applications;
+// }
+//
+// public Set<Class<?>> getAllResources() {
+// return this.allResources;
+// }
+//
+// public Set<Class<?>> getProviders() {
+// return this.providers;
+// }
+//
+// }
+//
+// /**
+// * This is a Spring version of {@link ResteasyServletInitializer}.
+// * It does not register the servlets though, that is done by {@link ResteasyApplicationBuilder}
+// * It only finds the JAX-RS Application classes (by scanning the classpath), and
+// * the JAX-RS Path and Provider annotated Spring beans, and then register the
+// * Spring bean definitions that represent each servlet registration.
+// *
+// * @author Fabio Carvalho (facarvalho@paypal.com or fabiocarvalho777@gmail.com)
+// */
+// @Slf4j
+// public static class ResteasyBeanProcessorTomcat extends ResteasyResourcesFinder implements BeanFactoryPostProcessor {
+//
+// private static final String JAXRS_DEFAULT_PATH = "resteasy.jaxrs.defaultPath";
+// private static final String DEFAULT_BASE_APP_PATH = "/";
+//
+// @Override
+// public void postProcessBeanFactory(final ConfigurableListableBeanFactory beanFactory) throws BeansException {
+//
+// log.debug("Post process bean factory has been called");
+//
+// findJaxrsApplications(beanFactory);
+//
+// // This is done by finding their related Spring beans
+// findJaxrsResourcesAndProviderClasses(beanFactory);
+//
+// if (getApplications().size() == 0) {
+// registerDefaultJaxrsApp(beanFactory);
+// return;
+// }
+//
+// BeanDefinitionRegistry registry = (BeanDefinitionRegistry) beanFactory;
+//
+// for (Class<? extends Application> applicationClass : getApplications()) {
+//
+// ApplicationPath path = AnnotationUtils.findAnnotation(applicationClass, ApplicationPath.class);
+// log.debug("registering JAX-RS application class " + applicationClass.getName());
+// GenericBeanDefinition applicationServletBean = createApplicationServlet(applicationClass, path.value());
+// registry.registerBeanDefinition(applicationClass.getName(), applicationServletBean);
+//
+// }
+//
+// }
+//
+// /**
+// * Register a default JAX-RS application, in case no other is present in the application.
+// * Read section 2.3.2 in JAX-RS 2.0 specification.
+// *
+// * @param beanFactory
+// */
+// private void registerDefaultJaxrsApp(final ConfigurableListableBeanFactory beanFactory) {
+// BeanDefinitionRegistry registry = (BeanDefinitionRegistry) beanFactory;
+// ConfigurableEnvironment configurableEnvironment = beanFactory.getBean(ConfigurableEnvironment.class);
+// String path = configurableEnvironment.getProperty(JAXRS_DEFAULT_PATH, DEFAULT_BASE_APP_PATH);
+// GenericBeanDefinition applicationServletBean =
+// createApplicationServlet(Application.class, path);
+//
+// log.info("No JAX-RS Application classes have been found. A default, one mapped to '{}', will be registered.", path);
+// registry.registerBeanDefinition(Application.class.getName(), applicationServletBean);
+// }
+//
+// /**
+// * Creates a Servlet bean definition for the given JAX-RS application
+// *
+// * @param applicationClass
+// * @param path
+// * @return a Servlet bean definition for the given JAX-RS application
+// */
+// private GenericBeanDefinition createApplicationServlet(final Class<? extends Application> applicationClass, final String path) {
+// GenericBeanDefinition applicationServletBean = new GenericBeanDefinition();
+// applicationServletBean.setFactoryBeanName(ResteasyApplicationBuilder.BEAN_NAME);
+// applicationServletBean.setFactoryMethodName("build");
+//
+// Set<Class<?>> resources = getAllResources();
+//
+// ConstructorArgumentValues values = new ConstructorArgumentValues();
+// values.addIndexedArgumentValue(0, applicationClass.getName());
+// values.addIndexedArgumentValue(1, path);
+// values.addIndexedArgumentValue(2, resources);
+// values.addIndexedArgumentValue(3, getProviders());
+// applicationServletBean.setConstructorArgumentValues(values);
+//
+// applicationServletBean.setAutowireCandidate(false);
+// applicationServletBean.setScope("singleton");
+//
+// return applicationServletBean;
+// }
+//
+// }
+//
+// @Bean
+// public static ResteasyBeanProcessorTomcat resteasyBeanProcessorTomcat() {
+// return new ResteasyBeanProcessorTomcat();
+// }
+//
+// /**
+// * Class that creates a spring bean processor for Resteasy. See
+// * {@link org.jboss.resteasy.plugins.spring.SpringBeanProcessor}.
+// */
+// @Slf4j
+// public static class ResteasyBeanProcessorFactory {
+//
+// public static SpringBeanProcessor resteasySpringBeanProcessor() {
+// ResteasyProviderFactory resteasyProviderFactory = new ResteasyProviderFactoryImpl();
+// ResourceMethodRegistry resourceMethodRegistry = new ResourceMethodRegistry(resteasyProviderFactory);
+//
+// SpringBeanProcessor resteasySpringBeanProcessor = new SpringBeanProcessor();
+// resteasySpringBeanProcessor.setProviderFactory(resteasyProviderFactory);
+// resteasySpringBeanProcessor.setRegistry(resourceMethodRegistry);
+//
+// log.debug("Resteasy Spring Bean Processor has been created");
+//
+// return resteasySpringBeanProcessor;
+// }
+//
+// }
+//
+// @Bean("resteasySpringBeanProcessor")
+// public static SpringBeanProcessor resteasySpringBeanProcessor() {
+// return ResteasyBeanProcessorFactory.resteasySpringBeanProcessor();
+// }
}
diff --git a/viewers/restfulobjects/jaxrs-resteasy/src/main/java/org/apache/causeway/viewer/restfulobjects/jaxrsresteasy/conneg/RestfulObjectsJaxbWriterForXml.java b/viewers/restfulobjects/jaxrs-resteasy/src/main/java/org/apache/causeway/viewer/restfulobjects/jaxrsresteasy/conneg/RestfulObjectsJaxbWriterForXml.java
deleted file mode 100644
index 0c16dc30ca5..00000000000
--- a/viewers/restfulobjects/jaxrs-resteasy/src/main/java/org/apache/causeway/viewer/restfulobjects/jaxrsresteasy/conneg/RestfulObjectsJaxbWriterForXml.java
+++ /dev/null
@@ -1,78 +0,0 @@
-/*
- * 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.causeway.viewer.restfulobjects.jaxrsresteasy.conneg;
-
-import java.lang.annotation.Annotation;
-import java.lang.reflect.Type;
-
-import jakarta.inject.Inject;
-import jakarta.ws.rs.Produces;
-import jakarta.ws.rs.core.MediaType;
-import jakarta.ws.rs.ext.Provider;
-import jakarta.xml.bind.Marshaller;
-
-import org.jboss.resteasy.plugins.providers.jaxb.JAXBXmlRootElementProvider;
-
-import org.springframework.stereotype.Component;
-
-import org.apache.causeway.applib.jaxb.PersistentEntityAdapter;
-import org.apache.causeway.applib.services.inject.ServiceInjector;
-
-/**
- * @since 1.x {@index}
- */
-@Component
-@Provider
-@Produces({"application/xml", "application/*+xml", "text/*+xml"})
-public class RestfulObjectsJaxbWriterForXml extends JAXBXmlRootElementProvider {
-
- @Inject private ServiceInjector serviceInjector;
-
- @Override
- protected boolean isReadWritable(
- final Class<?> type,
- final Type genericType,
- final Annotation[] annotations,
- final MediaType mediaType) {
-
- return super.isReadWritable(type, genericType, annotations, mediaType) &&
- hasXRoDomainTypeParameter(mediaType);
- }
-
- @Override
- protected Marshaller getMarshaller(
- final Class<?> type,
- final Annotation[] annotations,
- final MediaType mediaType) {
-
- var adapter = serviceInjector.injectServicesInto(new PersistentEntityAdapter());
-
- var marshaller = super.getMarshaller(type, annotations, mediaType);
- marshaller.setAdapter(PersistentEntityAdapter.class, adapter);
- return marshaller;
- }
-
- // HELPER
-
- private static boolean hasXRoDomainTypeParameter(final MediaType mediaType) {
- final boolean retval = mediaType.getParameters().containsKey("x-ro-domain-type");
- return retval;
- }
-
-}
diff --git a/viewers/restfulobjects/jaxrs-resteasy/src/main/java/org/apache/causeway/viewer/restfulobjects/jaxrsresteasy/webmodule/WebModuleJaxrsResteasy.java b/viewers/restfulobjects/jaxrs-resteasy/src/main/java/org/apache/causeway/viewer/restfulobjects/jaxrsresteasy/webmodule/WebModuleJaxrsResteasy.java
index 1b4bb955438..89fef6ac7b2 100644
--- a/viewers/restfulobjects/jaxrs-resteasy/src/main/java/org/apache/causeway/viewer/restfulobjects/jaxrsresteasy/webmodule/WebModuleJaxrsResteasy.java
+++ b/viewers/restfulobjects/jaxrs-resteasy/src/main/java/org/apache/causeway/viewer/restfulobjects/jaxrsresteasy/webmodule/WebModuleJaxrsResteasy.java
@@ -24,9 +24,6 @@
import jakarta.servlet.ServletContextListener;
import jakarta.servlet.ServletException;
-import org.jboss.resteasy.core.providerfactory.ResteasyProviderFactoryImpl;
-import org.jboss.resteasy.spi.ResteasyProviderFactory;
-
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Service;
@@ -89,7 +86,7 @@ public void prepare(final WebModuleContext ctx) {
// forces RuntimeDelegate.getInstance() to be provided by RestEasy
// (and not by eg. the JEE container if any)
- ResteasyProviderFactory.setInstance(new ResteasyProviderFactoryImpl());
+ //ResteasyProviderFactory.setInstance(new ResteasyProviderFactoryImpl());
super.prepare(ctx);
diff --git a/viewers/restfulobjects/pom.xml b/viewers/restfulobjects/pom.xml
index 5bb4965ab07..728a0cd8bff 100644
--- a/viewers/restfulobjects/pom.xml
+++ b/viewers/restfulobjects/pom.xml
@@ -40,7 +40,7 @@
<module>viewer</module>
<module>test</module>
<module>testing</module>
- <module>jaxrs-resteasy</module>
+<!-- <module>jaxrs-resteasy</module>-->
</modules>
</project>
diff --git a/viewers/restfulobjects/rendering/src/main/java/org/apache/causeway/viewer/restfulobjects/rendering/IResourceContext.java b/viewers/restfulobjects/rendering/src/main/java/org/apache/causeway/viewer/restfulobjects/rendering/IResourceContext.java
index d403309556e..5a8533e6708 100644
--- a/viewers/restfulobjects/rendering/src/main/java/org/apache/causeway/viewer/restfulobjects/rendering/IResourceContext.java
+++ b/viewers/restfulobjects/rendering/src/main/java/org/apache/causeway/viewer/restfulobjects/rendering/IResourceContext.java
@@ -22,7 +22,7 @@
import java.util.Optional;
import jakarta.ws.rs.core.HttpHeaders;
-import jakarta.ws.rs.core.MediaType;
+import org.springframework.http.MediaType;
import org.apache.causeway.applib.annotation.Where;
import org.apache.causeway.applib.services.bookmark.Bookmark;
diff --git a/viewers/restfulobjects/rendering/src/main/java/org/apache/causeway/viewer/restfulobjects/rendering/LinkBuilder.java b/viewers/restfulobjects/rendering/src/main/java/org/apache/causeway/viewer/restfulobjects/rendering/LinkBuilder.java
index d97bc1faa14..d2bfea27857 100644
--- a/viewers/restfulobjects/rendering/src/main/java/org/apache/causeway/viewer/restfulobjects/rendering/LinkBuilder.java
+++ b/viewers/restfulobjects/rendering/src/main/java/org/apache/causeway/viewer/restfulobjects/rendering/LinkBuilder.java
@@ -18,7 +18,7 @@
*/
package org.apache.causeway.viewer.restfulobjects.rendering;
-import jakarta.ws.rs.core.MediaType;
+import org.springframework.http.MediaType;
import org.apache.causeway.viewer.restfulobjects.applib.JsonRepresentation;
import org.apache.causeway.viewer.restfulobjects.applib.RepresentationType;
diff --git a/viewers/restfulobjects/rendering/src/main/java/org/apache/causeway/viewer/restfulobjects/rendering/ReprRenderer.java b/viewers/restfulobjects/rendering/src/main/java/org/apache/causeway/viewer/restfulobjects/rendering/ReprRenderer.java
index 2dfb7668c97..cacac8e942c 100644
--- a/viewers/restfulobjects/rendering/src/main/java/org/apache/causeway/viewer/restfulobjects/rendering/ReprRenderer.java
+++ b/viewers/restfulobjects/rendering/src/main/java/org/apache/causeway/viewer/restfulobjects/rendering/ReprRenderer.java
@@ -18,7 +18,7 @@
*/
package org.apache.causeway.viewer.restfulobjects.rendering;
-import jakarta.ws.rs.core.MediaType;
+import org.springframework.http.MediaType;
import org.apache.causeway.viewer.restfulobjects.applib.JsonRepresentation;
diff --git a/viewers/restfulobjects/rendering/src/main/java/org/apache/causeway/viewer/restfulobjects/rendering/ReprRendererAbstract.java b/viewers/restfulobjects/rendering/src/main/java/org/apache/causeway/viewer/restfulobjects/rendering/ReprRendererAbstract.java
index 1df4f9232aa..5795181d4b4 100644
--- a/viewers/restfulobjects/rendering/src/main/java/org/apache/causeway/viewer/restfulobjects/rendering/ReprRendererAbstract.java
+++ b/viewers/restfulobjects/rendering/src/main/java/org/apache/causeway/viewer/restfulobjects/rendering/ReprRendererAbstract.java
@@ -21,7 +21,7 @@
import java.util.List;
import java.util.Map;
-import jakarta.ws.rs.core.MediaType;
+import org.springframework.http.MediaType;
import org.apache.causeway.commons.internal.base._Casts;
import org.apache.causeway.commons.internal.collections._Lists;
diff --git a/viewers/restfulobjects/rendering/src/main/java/org/apache/causeway/viewer/restfulobjects/rendering/Responses.java b/viewers/restfulobjects/rendering/src/main/java/org/apache/causeway/viewer/restfulobjects/rendering/Responses.java
index f94ed2d68f5..2bf9f076377 100644
--- a/viewers/restfulobjects/rendering/src/main/java/org/apache/causeway/viewer/restfulobjects/rendering/Responses.java
+++ b/viewers/restfulobjects/rendering/src/main/java/org/apache/causeway/viewer/restfulobjects/rendering/Responses.java
@@ -23,13 +23,14 @@
import java.util.Locale;
import java.util.TimeZone;
-import jakarta.ws.rs.core.MediaType;
+import org.springframework.http.MediaType;
import jakarta.ws.rs.core.Response;
import org.apache.causeway.applib.services.clock.ClockService;
import org.apache.causeway.viewer.restfulobjects.applib.JsonRepresentation;
import org.apache.causeway.viewer.restfulobjects.applib.RestfulResponse;
import org.apache.causeway.viewer.restfulobjects.applib.util.JsonMapper;
+import org.apache.causeway.viewer.restfulobjects.applib.util.MediaTypes;
import org.apache.causeway.viewer.restfulobjects.rendering.util.JsonWriterUtil;
public final class Responses {
@@ -77,7 +78,7 @@ public static Response.ResponseBuilder ofOk(
final Response.ResponseBuilder response =
of(RestfulResponse.HttpStatusCode.OK)
.header("Date", dateFormat.format(now))
- .type(mediaType)
+ .type(MediaTypes.toJakarta(mediaType))
.cacheControl(caching.getCacheControl())
.entity(JsonWriterUtil.jsonFor(entityRepresentation, inferPrettyPrinting(renderer)));
@@ -93,13 +94,13 @@ private static Date now(final ReprRenderer<?> renderer) {
}
protected static Response.ResponseBuilder of(final RestfulResponse.HttpStatusCode httpStatusCode) {
- return Response.status(httpStatusCode.getJaxrsStatusType()).type(MediaType.APPLICATION_JSON_TYPE);
+ return Response.status(httpStatusCode.getJaxrsStatusType()).type(MediaTypes.toJakarta(MediaType.APPLICATION_JSON));
}
public static Response.ResponseBuilder mediaType(
final Response.ResponseBuilder responseBuilder,
final MediaType mediaType) {
- responseBuilder.type(mediaType);
+ responseBuilder.type(MediaTypes.toJakarta(mediaType));
return responseBuilder;
}
diff --git a/viewers/restfulobjects/rendering/src/main/java/org/apache/causeway/viewer/restfulobjects/rendering/domainobjects/ScalarValueReprRenderer.java b/viewers/restfulobjects/rendering/src/main/java/org/apache/causeway/viewer/restfulobjects/rendering/domainobjects/ScalarValueReprRenderer.java
index 0fe99019738..77c0d971a10 100644
--- a/viewers/restfulobjects/rendering/src/main/java/org/apache/causeway/viewer/restfulobjects/rendering/domainobjects/ScalarValueReprRenderer.java
+++ b/viewers/restfulobjects/rendering/src/main/java/org/apache/causeway/viewer/restfulobjects/rendering/domainobjects/ScalarValueReprRenderer.java
@@ -18,7 +18,7 @@
*/
package org.apache.causeway.viewer.restfulobjects.rendering.domainobjects;
-import jakarta.ws.rs.core.MediaType;
+import org.springframework.http.MediaType;
import org.apache.causeway.core.metamodel.object.ManagedObject;
import org.apache.causeway.core.metamodel.spec.ObjectSpecification;
diff --git a/viewers/restfulobjects/rendering/src/main/java/org/apache/causeway/viewer/restfulobjects/rendering/service/acceptheader/AcceptHeaderServiceForRest.java b/viewers/restfulobjects/rendering/src/main/java/org/apache/causeway/viewer/restfulobjects/rendering/service/acceptheader/AcceptHeaderServiceForRest.java
index 567c541aa69..a4cb165e3a9 100644
--- a/viewers/restfulobjects/rendering/src/main/java/org/apache/causeway/viewer/restfulobjects/rendering/service/acceptheader/AcceptHeaderServiceForRest.java
+++ b/viewers/restfulobjects/rendering/src/main/java/org/apache/causeway/viewer/restfulobjects/rendering/service/acceptheader/AcceptHeaderServiceForRest.java
@@ -20,14 +20,12 @@
import java.io.IOException;
import java.util.List;
-import java.util.stream.Collectors;
-
import jakarta.inject.Named;
import jakarta.ws.rs.container.ContainerRequestContext;
import jakarta.ws.rs.container.ContainerRequestFilter;
import jakarta.ws.rs.container.ContainerResponseContext;
import jakarta.ws.rs.container.ContainerResponseFilter;
-import jakarta.ws.rs.core.MediaType;
+import org.springframework.http.MediaType;
import jakarta.ws.rs.ext.Provider;
import org.springframework.beans.factory.annotation.Qualifier;
@@ -39,6 +37,7 @@
import org.apache.causeway.applib.services.acceptheader.AcceptHeaderService;
import org.apache.causeway.commons.internal.base._NullSafe;
import org.apache.causeway.viewer.restfulobjects.applib.CausewayModuleViewerRestfulObjectsApplib;
+import org.apache.causeway.viewer.restfulobjects.applib.util.MediaTypes;
import static org.apache.causeway.commons.internal.base._NullSafe.stream;
@@ -80,11 +79,12 @@ public List<MediaType> getAcceptableMediaTypes() {
public static class RequestFilter implements ContainerRequestFilter {
@Override
public void filter(final ContainerRequestContext requestContext) throws IOException {
- final List<MediaType> acceptableMediaTypes = requestContext.getAcceptableMediaTypes();
+ var acceptableMediaTypes = requestContext.getAcceptableMediaTypes();
final List<MediaType> mediaTypes = stream(acceptableMediaTypes)
.filter(_NullSafe::isPresent)
- .collect(Collectors.toList());
+ .map(MediaTypes::fromJakarta)
+ .toList();
setMediaTypes(mediaTypes);
}
diff --git a/viewers/restfulobjects/rendering/src/main/java/org/apache/causeway/viewer/restfulobjects/rendering/service/conneg/ContentNegotiationServiceAbstract.java b/viewers/restfulobjects/rendering/src/main/java/org/apache/causeway/viewer/restfulobjects/rendering/service/conneg/ContentNegotiationServiceAbstract.java
index b3b2d518a7e..769bea8e0e9 100644
--- a/viewers/restfulobjects/rendering/src/main/java/org/apache/causeway/viewer/restfulobjects/rendering/service/conneg/ContentNegotiationServiceAbstract.java
+++ b/viewers/restfulobjects/rendering/src/main/java/org/apache/causeway/viewer/restfulobjects/rendering/service/conneg/ContentNegotiationServiceAbstract.java
@@ -21,7 +21,7 @@
import java.util.List;
import java.util.Objects;
-import jakarta.ws.rs.core.MediaType;
+import org.springframework.http.MediaType;
import jakarta.ws.rs.core.Response;
import org.apache.causeway.commons.internal.base._Strings;
diff --git a/viewers/restfulobjects/rendering/src/main/java/org/apache/causeway/viewer/restfulobjects/rendering/service/conneg/ContentNegotiationServiceForRestfulObjectsV1_0.java b/viewers/restfulobjects/rendering/src/main/java/org/apache/causeway/viewer/restfulobjects/rendering/service/conneg/ContentNegotiationServiceForRestfulObjectsV1_0.java
index f5d5018dc2f..2ff0800d377 100644
--- a/viewers/restfulobjects/rendering/src/main/java/org/apache/causeway/viewer/restfulobjects/rendering/service/conneg/ContentNegotiationServiceForRestfulObjectsV1_0.java
+++ b/viewers/restfulobjects/rendering/src/main/java/org/apache/causeway/viewer/restfulobjects/rendering/service/conneg/ContentNegotiationServiceForRestfulObjectsV1_0.java
@@ -25,7 +25,7 @@
import jakarta.annotation.Priority;
import jakarta.inject.Inject;
import jakarta.inject.Named;
-import jakarta.ws.rs.core.MediaType;
+import org.springframework.http.MediaType;
import jakarta.ws.rs.core.Response;
import jakarta.ws.rs.core.Response.ResponseBuilder;
diff --git a/viewers/restfulobjects/rendering/src/main/java/org/apache/causeway/viewer/restfulobjects/rendering/service/conneg/ContentNegotiationServiceOrgApacheCausewayV2.java b/viewers/restfulobjects/rendering/src/main/java/org/apache/causeway/viewer/restfulobjects/rendering/service/conneg/ContentNegotiationServiceOrgApacheCausewayV2.java
index 6b0332c6e94..f3edeff6218 100644
--- a/viewers/restfulobjects/rendering/src/main/java/org/apache/causeway/viewer/restfulobjects/rendering/service/conneg/ContentNegotiationServiceOrgApacheCausewayV2.java
+++ b/viewers/restfulobjects/rendering/src/main/java/org/apache/causeway/viewer/restfulobjects/rendering/service/conneg/ContentNegotiationServiceOrgApacheCausewayV2.java
@@ -24,7 +24,7 @@
import java.util.stream.Stream;
import jakarta.inject.Named;
-import jakarta.ws.rs.core.MediaType;
+import org.springframework.http.MediaType;
import jakarta.ws.rs.core.Response;
import com.fasterxml.jackson.databind.node.POJONode;
diff --git a/viewers/restfulobjects/rendering/src/main/java/org/apache/causeway/viewer/restfulobjects/rendering/service/conneg/ContentNegotiationServiceOrgApacheIsisV1.java b/viewers/restfulobjects/rendering/src/main/java/org/apache/causeway/viewer/restfulobjects/rendering/service/conneg/ContentNegotiationServiceOrgApacheIsisV1.java
index fdd4a8a3bdf..ab15591b23f 100644
--- a/viewers/restfulobjects/rendering/src/main/java/org/apache/causeway/viewer/restfulobjects/rendering/service/conneg/ContentNegotiationServiceOrgApacheIsisV1.java
+++ b/viewers/restfulobjects/rendering/src/main/java/org/apache/causeway/viewer/restfulobjects/rendering/service/conneg/ContentNegotiationServiceOrgApacheIsisV1.java
@@ -21,7 +21,7 @@
import java.util.List;
import jakarta.inject.Named;
-import jakarta.ws.rs.core.MediaType;
+import org.springframework.http.MediaType;
import jakarta.ws.rs.core.Response;
import jakarta.ws.rs.core.Response.ResponseBuilder;
diff --git a/viewers/restfulobjects/rendering/src/main/java/org/apache/causeway/viewer/restfulobjects/rendering/service/conneg/ContentNegotiationServiceXRoDomainType.java b/viewers/restfulobjects/rendering/src/main/java/org/apache/causeway/viewer/restfulobjects/rendering/service/conneg/ContentNegotiationServiceXRoDomainType.java
index e4ab65a4404..80a41409f3a 100644
--- a/viewers/restfulobjects/rendering/src/main/java/org/apache/causeway/viewer/restfulobjects/rendering/service/conneg/ContentNegotiationServiceXRoDomainType.java
+++ b/viewers/restfulobjects/rendering/src/main/java/org/apache/causeway/viewer/restfulobjects/rendering/service/conneg/ContentNegotiationServiceXRoDomainType.java
@@ -22,7 +22,7 @@
import jakarta.inject.Inject;
import jakarta.inject.Named;
-import jakarta.ws.rs.core.MediaType;
+import org.springframework.http.MediaType;
import jakarta.ws.rs.core.Response;
import org.springframework.beans.factory.annotation.Qualifier;
@@ -34,6 +34,7 @@
import org.apache.causeway.viewer.restfulobjects.applib.CausewayModuleViewerRestfulObjectsApplib;
import org.apache.causeway.viewer.restfulobjects.applib.RepresentationType;
import org.apache.causeway.viewer.restfulobjects.applib.RestfulResponse;
+import org.apache.causeway.viewer.restfulobjects.applib.util.MediaTypes;
import org.apache.causeway.viewer.restfulobjects.rendering.IResourceContext;
import org.apache.causeway.viewer.restfulobjects.rendering.RestfulObjectsApplicationException;
import org.apache.causeway.viewer.restfulobjects.rendering.domainobjects.ObjectAndActionInvocation;
@@ -142,7 +143,7 @@ protected Response.ResponseBuilder buildResponse(
ensureJaxbAnnotated(mappedDomainObject.getClass());
}
- return Response.ok(mappedDomainObject, mediaType);
+ return Response.ok(mappedDomainObject, MediaTypes.toJakarta(mediaType));
}
/**
diff --git a/viewers/restfulobjects/test/pom.xml b/viewers/restfulobjects/test/pom.xml
index 8c5c71349fa..b770bd5393a 100644
--- a/viewers/restfulobjects/test/pom.xml
+++ b/viewers/restfulobjects/test/pom.xml
@@ -117,11 +117,11 @@
<artifactId>causeway-viewer-restfulobjects-viewer</artifactId>
<scope>test</scope>
</dependency>
- <dependency>
- <groupId>org.apache.causeway.viewer</groupId>
- <artifactId>causeway-viewer-restfulobjects-jaxrsresteasy</artifactId>
- <scope>test</scope>
- </dependency>
+<!-- <dependency>-->
+<!-- <groupId>org.apache.causeway.viewer</groupId>-->
+<!-- <artifactId>causeway-viewer-restfulobjects-jaxrsresteasy</artifactId>-->
+<!-- <scope>test</scope>-->
+<!-- </dependency>-->
<dependency>
diff --git a/viewers/restfulobjects/test/src/test/java/org/apache/causeway/viewer/restfulobjects/test/CausewayViewerRestfulObjectsIntegTestManifest.java b/viewers/restfulobjects/test/src/test/java/org/apache/causeway/viewer/restfulobjects/test/CausewayViewerRestfulObjectsIntegTestManifest.java
index 62a36585acc..c7a7b96b95f 100644
--- a/viewers/restfulobjects/test/src/test/java/org/apache/causeway/viewer/restfulobjects/test/CausewayViewerRestfulObjectsIntegTestManifest.java
+++ b/viewers/restfulobjects/test/src/test/java/org/apache/causeway/viewer/restfulobjects/test/CausewayViewerRestfulObjectsIntegTestManifest.java
@@ -28,7 +28,7 @@
import org.apache.causeway.core.runtimeservices.CausewayModuleCoreRuntimeServices;
import org.apache.causeway.security.bypass.CausewayModuleSecurityBypass;
import org.apache.causeway.testing.fixtures.applib.CausewayModuleTestingFixturesApplib;
-import org.apache.causeway.viewer.restfulobjects.jaxrsresteasy.CausewayModuleViewerRestfulObjectsJaxrsResteasy;
+import org.apache.causeway.viewer.restfulobjects.viewer.CausewayModuleViewerRestfulObjectsViewer;
/**
* Compared to the production app manifest <code>domainapp.webapp.AppManifest</code>,
@@ -40,7 +40,8 @@
CausewayModuleCoreRuntimeServices.class,
CausewayModuleSecurityBypass.class,
CausewayModuleTestingFixturesApplib.class,
- CausewayModuleViewerRestfulObjectsJaxrsResteasy.class,
+ CausewayModuleViewerRestfulObjectsViewer.class
+ //CausewayModuleViewerRestfulObjectsJaxrsResteasy.class,
})
@PropertySources({
@PropertySource(CausewayPresets.H2InMemory_withUniqueSchema),
diff --git a/viewers/restfulobjects/testing/src/main/java/org/apache/causeway/viewer/restfulobjects/testing/Parser_forJaxRsMediaType_ContractTest.java b/viewers/restfulobjects/testing/src/main/java/org/apache/causeway/viewer/restfulobjects/testing/Parser_forJaxRsMediaType_ContractTest.java
index a28228b2c37..3fba20790d3 100644
--- a/viewers/restfulobjects/testing/src/main/java/org/apache/causeway/viewer/restfulobjects/testing/Parser_forJaxRsMediaType_ContractTest.java
+++ b/viewers/restfulobjects/testing/src/main/java/org/apache/causeway/viewer/restfulobjects/testing/Parser_forJaxRsMediaType_ContractTest.java
@@ -32,16 +32,16 @@ public abstract class Parser_forJaxRsMediaType_ContractTest {
@Test
public void forJaxRsMediaType() {
- final Parser<jakarta.ws.rs.core.MediaType> parser = Parser.forJaxRsMediaType();
+ final Parser<org.springframework.http.MediaType> parser = Parser.forJaxRsMediaType();
- for (final jakarta.ws.rs.core.MediaType v : new jakarta.ws.rs.core.MediaType[] {
- jakarta.ws.rs.core.MediaType.APPLICATION_ATOM_XML_TYPE,
- jakarta.ws.rs.core.MediaType.APPLICATION_JSON_TYPE,
- jakarta.ws.rs.core.MediaType.APPLICATION_XHTML_XML_TYPE,
+ for (final org.springframework.http.MediaType v : new org.springframework.http.MediaType[] {
+ org.springframework.http.MediaType.APPLICATION_ATOM_XML,
+ org.springframework.http.MediaType.APPLICATION_JSON,
+ org.springframework.http.MediaType.APPLICATION_XHTML_XML,
MediaTypes.parse(RestfulMediaType.APPLICATION_JSON_OBJECT)
}) {
final String asString = parser.asString(v);
- final jakarta.ws.rs.core.MediaType valueOf = parser.valueOf(asString);
+ final org.springframework.http.MediaType valueOf = parser.valueOf(asString);
assertThat(v, is(equalTo(valueOf)));
}
}
diff --git a/viewers/restfulobjects/testing/src/main/java/org/apache/causeway/viewer/restfulobjects/testing/RepresentationTypeTest_lookup_ContractTest.java b/viewers/restfulobjects/testing/src/main/java/org/apache/causeway/viewer/restfulobjects/testing/RepresentationTypeTest_lookup_ContractTest.java
index 51fb281dd56..df33fc19b00 100644
--- a/viewers/restfulobjects/testing/src/main/java/org/apache/causeway/viewer/restfulobjects/testing/RepresentationTypeTest_lookup_ContractTest.java
+++ b/viewers/restfulobjects/testing/src/main/java/org/apache/causeway/viewer/restfulobjects/testing/RepresentationTypeTest_lookup_ContractTest.java
@@ -18,7 +18,7 @@
*/
package org.apache.causeway.viewer.restfulobjects.testing;
-import jakarta.ws.rs.core.MediaType;
+import org.springframework.http.MediaType;
import org.junit.jupiter.api.Test;
@@ -53,7 +53,7 @@ public void roundtrip_overloaded() {
@Test
public void whenUnknown() {
- assertThat(RepresentationType.lookup(MediaType.APPLICATION_SVG_XML), is(RepresentationType.GENERIC));
+ assertThat(RepresentationType.lookup("application/svg+xml"), is(RepresentationType.GENERIC));
assertThat(RepresentationType.lookup("foobar"), is(RepresentationType.GENERIC));
}
diff --git a/viewers/restfulobjects/testing/src/main/java/org/apache/causeway/viewer/restfulobjects/testing/ResourceContext_ensureCompatibleAcceptHeader_ContractTest.java b/viewers/restfulobjects/testing/src/main/java/org/apache/causeway/viewer/restfulobjects/testing/ResourceContext_ensureCompatibleAcceptHeader_ContractTest.java
index 0bc4a92d28f..df911ce2a6b 100644
--- a/viewers/restfulobjects/testing/src/main/java/org/apache/causeway/viewer/restfulobjects/testing/ResourceContext_ensureCompatibleAcceptHeader_ContractTest.java
+++ b/viewers/restfulobjects/testing/src/main/java/org/apache/causeway/viewer/restfulobjects/testing/ResourceContext_ensureCompatibleAcceptHeader_ContractTest.java
@@ -23,8 +23,6 @@
import jakarta.servlet.ServletContext;
import jakarta.servlet.http.HttpServletRequest;
-import jakarta.ws.rs.core.HttpHeaders;
-import jakarta.ws.rs.core.MediaType;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
@@ -33,6 +31,8 @@
import static org.hamcrest.CoreMatchers.is;
import static org.hamcrest.MatcherAssert.assertThat;
+import org.springframework.http.HttpHeaders;
+import org.springframework.http.MediaType;
import org.springframework.web.context.WebApplicationContext;
import org.apache.causeway.applib.services.iactn.Interaction;
@@ -117,7 +117,7 @@ public void happyCase() throws Exception {
@Test
public void acceptGenericAndProduceGeneric() throws Exception {
final RepresentationType representationType = RepresentationType.GENERIC;
- givenHttpHeadersGetAcceptableMediaTypesReturns(List.of(MediaType.APPLICATION_JSON_TYPE));
+ givenHttpHeadersGetAcceptableMediaTypesReturns(List.of(MediaType.APPLICATION_JSON));
instantiateResourceContext(representationType);
}
@@ -125,7 +125,7 @@ public void acceptGenericAndProduceGeneric() throws Exception {
@Test
public void acceptGenericAndProduceSpecific() throws Exception {
final RepresentationType representationType = RepresentationType.HOME_PAGE;
- givenHttpHeadersGetAcceptableMediaTypesReturns(List.of(MediaType.APPLICATION_JSON_TYPE));
+ givenHttpHeadersGetAcceptableMediaTypesReturns(List.of(MediaType.APPLICATION_JSON));
instantiateResourceContext(representationType);
}
@@ -133,7 +133,7 @@ public void acceptGenericAndProduceSpecific() throws Exception {
@Test
public void nonMatching() throws Exception {
final RepresentationType representationType = RepresentationType.HOME_PAGE;
- givenHttpHeadersGetAcceptableMediaTypesReturns(Arrays.<MediaType> asList(MediaType.APPLICATION_ATOM_XML_TYPE));
+ givenHttpHeadersGetAcceptableMediaTypesReturns(Arrays.<MediaType> asList(MediaType.APPLICATION_ATOM_XML));
try {
instantiateResourceContext(representationType);
@@ -157,7 +157,7 @@ public void nonMatchingProfile() throws Exception {
@Test
public void nonMatchingProfile_ignoreGeneric() throws Exception {
final RepresentationType representationType = RepresentationType.HOME_PAGE;
- givenHttpHeadersGetAcceptableMediaTypesReturns(List.of(RepresentationType.USER.getJsonMediaType(), MediaType.APPLICATION_JSON_TYPE));
+ givenHttpHeadersGetAcceptableMediaTypesReturns(List.of(RepresentationType.USER.getJsonMediaType(), MediaType.APPLICATION_JSON));
try {
instantiateResourceContext(representationType);
@@ -176,7 +176,7 @@ public void emptyList_isOK() throws Exception {
private void givenHttpHeadersGetAcceptableMediaTypesReturns(final List<MediaType> mediaTypes) {
Mockito
- .when(mockHttpHeaders.getAcceptableMediaTypes())
+ .when(mockHttpHeaders.getAccept())
.thenReturn(mediaTypes);
}
@@ -185,9 +185,7 @@ private ResourceContext instantiateResourceContext(
var resourceDescriptor = new ResourceDescriptor(representationType, null, null, ResourceLink.NONE);
- return new ResourceContext(resourceDescriptor, mockHttpHeaders, null, null, null, null, null,
- mockHttpServletRequest, null, null,
- metaModelContext, null, null);
+ return ResourceContext.forTesting(resourceDescriptor, mockHttpServletRequest, mockHttpHeaders);
}
/*sonar-ignore-off*/
diff --git a/viewers/restfulobjects/viewer/src/main/java/org/apache/causeway/viewer/restfulobjects/viewer/context/ResourceContext.java b/viewers/restfulobjects/viewer/src/main/java/org/apache/causeway/viewer/restfulobjects/viewer/context/ResourceContext.java
index e43e524156f..f870617f20c 100644
--- a/viewers/restfulobjects/viewer/src/main/java/org/apache/causeway/viewer/restfulobjects/viewer/context/ResourceContext.java
+++ b/viewers/restfulobjects/viewer/src/main/java/org/apache/causeway/viewer/restfulobjects/viewer/context/ResourceContext.java
@@ -19,6 +19,7 @@
package org.apache.causeway.viewer.restfulobjects.viewer.context;
import java.util.Collections;
+import java.util.Enumeration;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
@@ -27,16 +28,18 @@
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
-import jakarta.ws.rs.core.HttpHeaders;
-import jakarta.ws.rs.core.MediaType;
-import jakarta.ws.rs.core.Request;
-import jakarta.ws.rs.core.SecurityContext;
-import jakarta.ws.rs.ext.Providers;
+
+import org.jspecify.annotations.NonNull;
+import org.jspecify.annotations.Nullable;
+
+import org.springframework.http.HttpHeaders;
+import org.springframework.http.MediaType;
import org.apache.causeway.applib.annotation.Where;
import org.apache.causeway.applib.id.LogicalType;
import org.apache.causeway.applib.services.bookmark.Bookmark;
import org.apache.causeway.commons.internal.base._Strings;
+import org.apache.causeway.commons.internal.exceptions._Exceptions;
import org.apache.causeway.commons.internal.primitives._Ints;
import org.apache.causeway.commons.io.UrlUtils;
import org.apache.causeway.core.metamodel.consent.InteractionInitiatedBy;
@@ -57,17 +60,12 @@
import org.apache.causeway.viewer.restfulobjects.viewer.resources.ResourceDescriptor;
import org.apache.causeway.viewer.restfulobjects.viewer.resources.serialization.SerializationStrategy;
-import org.jspecify.annotations.NonNull;
-import org.jspecify.annotations.Nullable;
-
public record ResourceContext(
MetaModelContext metaModelContext,
ResourceDescriptor resourceDescriptor,
HttpHeaders httpHeaders,
- Request request,
HttpServletRequest httpServletRequest,
HttpServletResponse httpServletResponse,
- SecurityContext securityContext,
String applicationAbsoluteBase,
String restfulAbsoluteBase,
@@ -85,40 +83,37 @@ public record ResourceContext(
// -- NON CANONICAL CONSTRUCTORS
public ResourceContext(
+ final MetaModelContext metaModelContext,
final ResourceDescriptor resourceDescriptor,
- final HttpHeaders httpHeaders,
- final Providers providers,
- final Request request,
final String applicationAbsoluteBase,
final String restfulAbsoluteBase,
final RequestParams urlUnencodedQueryString,
final HttpServletRequest httpServletRequest,
final HttpServletResponse httpServletResponse,
- final SecurityContext securityContext,
- final MetaModelContext metaModelContext,
final InteractionInitiatedBy interactionInitiatedBy,
final Map<String, String[]> requestParams) {
- this(resourceDescriptor, httpHeaders, providers, request, applicationAbsoluteBase, restfulAbsoluteBase,
- httpServletRequest, httpServletResponse, securityContext, metaModelContext, interactionInitiatedBy,
+ this(
+ metaModelContext,
+ resourceDescriptor,
+ applicationAbsoluteBase, restfulAbsoluteBase,
+ httpServletRequest, httpServletResponse, interactionInitiatedBy,
requestArgsAsMap(requestParams, urlUnencodedQueryString));
}
private ResourceContext(
+ final MetaModelContext metaModelContext,
final ResourceDescriptor resourceDescriptor,
- final HttpHeaders httpHeaders,
- final Providers providers,
- final Request request,
final String applicationAbsoluteBase,
final String restfulAbsoluteBase,
final HttpServletRequest httpServletRequest,
final HttpServletResponse httpServletResponse,
- final SecurityContext securityContext,
- final MetaModelContext metaModelContext,
final InteractionInitiatedBy interactionInitiatedBy,
final JsonRepresentation requestArgsAsMap) {
- this(metaModelContext, resourceDescriptor, httpHeaders, request, httpServletRequest, httpServletResponse, securityContext,
+ this(metaModelContext, resourceDescriptor,
+ httpHeadersFromServletRequest(httpServletRequest),
+ httpServletRequest, httpServletResponse,
_Strings.suffix(applicationAbsoluteBase, "/"),
_Strings.suffix(restfulAbsoluteBase, "/"),
Collections.unmodifiableList(arg(requestArgsAsMap, RequestParameter.FOLLOW_LINKS)),
@@ -231,7 +226,7 @@ public String applicationUrlFor(final @NonNull String url) {
@Override
public List<MediaType> acceptableMediaTypes() {
- return httpHeaders.getAcceptableMediaTypes();
+ return httpHeaders.getAccept();
}
// -- UTIL
@@ -254,11 +249,36 @@ public ManagedObject lookupServiceAdapterElseFail(
// -- JUNIT
- static ResourceContext forTesting(String queryString, HttpServletRequest servletRequest) {
- return new ResourceContext(ResourceDescriptor.empty(), null, null, null, null, null,
+ public static ResourceContext forTesting(String queryString, HttpServletRequest servletRequest) {
+ return new ResourceContext(MetaModelContext.instanceNullable(),
+ ResourceDescriptor.empty(), null, null,
RequestParams.ofQueryString(UrlUtils.urlDecodeUtf8(queryString)),
- servletRequest, null, null,
- MetaModelContext.instanceElseFail(), null, (Map<String, String[]>)null);
+ servletRequest, null,
+ null, (Map<String, String[]>)null);
+ }
+
+ public static ResourceContext forTesting(
+ ResourceDescriptor resourceDescriptor,
+ HttpServletRequest httpServletRequest,
+ HttpHeaders httpHeaders) {
+ throw _Exceptions.notImplemented();
+ }
+
+ // -- HELPER
+
+ static HttpHeaders httpHeadersFromServletRequest(HttpServletRequest request) {
+ var headers = new HttpHeaders();
+ Enumeration<String> headerNames = request.getHeaderNames();
+ while (headerNames.hasMoreElements()) {
+ String name = headerNames.nextElement();
+ Enumeration<String> values = request.getHeaders(name);
+ while (values.hasMoreElements()) {
+ headers.add(name, values.nextElement());
+ }
+ }
+ return headers;
}
+
+
}
diff --git a/viewers/restfulobjects/viewer/src/main/java/org/apache/causeway/viewer/restfulobjects/viewer/mappers/ExceptionMapperAbstract.java b/viewers/restfulobjects/viewer/src/main/java/org/apache/causeway/viewer/restfulobjects/viewer/mappers/ExceptionMapperAbstract.java
index 1c8594c0a7c..927d6ed6bed 100644
--- a/viewers/restfulobjects/viewer/src/main/java/org/apache/causeway/viewer/restfulobjects/viewer/mappers/ExceptionMapperAbstract.java
+++ b/viewers/restfulobjects/viewer/src/main/java/org/apache/causeway/viewer/restfulobjects/viewer/mappers/ExceptionMapperAbstract.java
@@ -23,7 +23,7 @@
import jakarta.ws.rs.core.Context;
import jakarta.ws.rs.core.HttpHeaders;
-import jakarta.ws.rs.core.MediaType;
+import org.springframework.http.MediaType;
import jakarta.ws.rs.core.Response;
import jakarta.ws.rs.core.Response.ResponseBuilder;
import jakarta.ws.rs.ext.ExceptionMapper;
@@ -36,6 +36,7 @@
import org.apache.causeway.viewer.restfulobjects.applib.JsonRepresentation;
import org.apache.causeway.viewer.restfulobjects.applib.RepresentationType;
import org.apache.causeway.viewer.restfulobjects.applib.RestfulResponse;
+import org.apache.causeway.viewer.restfulobjects.applib.util.MediaTypes;
import org.apache.causeway.viewer.restfulobjects.rendering.ExceptionWithBody;
import org.apache.causeway.viewer.restfulobjects.rendering.ExceptionWithHttpStatusCode;
import org.apache.causeway.viewer.restfulobjects.viewer.mappers.entity.ExceptionDetail;
@@ -85,7 +86,7 @@ private Response buildResponse(
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.type(MediaTypes.toJakarta(serializationStrategy.type(RepresentationType.GENERIC)));
builder.entity(body.toString());
return builder.build();
@@ -146,19 +147,21 @@ private Response buildResponse(
final ExceptionPojo exceptionPojo) {
final ResponseBuilder builder = Response.status(httpStatusCode.getJaxrsStatusType());
- final List<MediaType> acceptableMediaTypes = httpHeaders.getAcceptableMediaTypes();
- final SerializationStrategy serializationStrategy =
- acceptableMediaTypes.contains(MediaType.APPLICATION_XML_TYPE) ||
- acceptableMediaTypes.contains(RepresentationType.OBJECT_LAYOUT.getXmlMediaType())
+ var acceptableMediaTypes = httpHeaders.getAcceptableMediaTypes()
+ .stream()
+ .map(MediaTypes::fromJakarta)
+ .toList();
+ var serializationStrategy = acceptableMediaTypes.contains(MediaType.APPLICATION_XML)
+ || acceptableMediaTypes.contains(RepresentationType.OBJECT_LAYOUT.getXmlMediaType())
? SerializationStrategy.XML
- : SerializationStrategy.JSON;
+ : SerializationStrategy.JSON;
final String message = exceptionPojo.getMessage();
if (message != null) {
builder.header(RestfulResponse.Header.WARNING.getName(), RestfulResponse.Header.WARNING.render(message));
}
- builder.type(serializationStrategy.type(RepresentationType.ERROR));
+ builder.type(MediaTypes.toJakarta(serializationStrategy.type(RepresentationType.ERROR)));
builder.entity(serializationStrategy.entity(exceptionPojo));
return builder.build();
diff --git a/viewers/restfulobjects/viewer/src/main/java/org/apache/causeway/viewer/restfulobjects/viewer/mappers/ExceptionMapperForObjectNotFound.java b/viewers/restfulobjects/viewer/src/main/java/org/apache/causeway/viewer/restfulobjects/viewer/mappers/ExceptionMapperForObjectNotFound.java
index 86676c65209..5a37750b5b2 100644
--- a/viewers/restfulobjects/viewer/src/main/java/org/apache/causeway/viewer/restfulobjects/viewer/mappers/ExceptionMapperForObjectNotFound.java
+++ b/viewers/restfulobjects/viewer/src/main/java/org/apache/causeway/viewer/restfulobjects/viewer/mappers/ExceptionMapperForObjectNotFound.java
@@ -18,25 +18,49 @@
*/
package org.apache.causeway.viewer.restfulobjects.viewer.mappers;
-import jakarta.inject.Singleton;
-import jakarta.ws.rs.core.Response;
-import jakarta.ws.rs.ext.Provider;
+//import jakarta.inject.Singleton;
+//import jakarta.ws.rs.core.Response;
+//import jakarta.ws.rs.ext.Provider;
-import org.springframework.stereotype.Component;
+import org.springframework.http.HttpStatus;
+//import org.springframework.stereotype.Component;
+import org.springframework.web.bind.annotation.ExceptionHandler;
+import org.springframework.web.bind.annotation.ResponseStatus;
+import org.springframework.web.bind.annotation.RestControllerAdvice;
-import org.apache.causeway.applib.annotation.PriorityPrecedence;
+//import org.apache.causeway.applib.annotation.PriorityPrecedence;
import org.apache.causeway.applib.exceptions.unrecoverable.ObjectNotFoundException;
-import org.apache.causeway.viewer.restfulobjects.applib.RestfulResponse;
-@Component
-@Provider
-@Singleton
-@jakarta.annotation.Priority(PriorityPrecedence.MIDPOINT)
-public class ExceptionMapperForObjectNotFound extends ExceptionMapperAbstract<ObjectNotFoundException> {
+import lombok.extern.slf4j.Slf4j;
+//import org.apache.causeway.viewer.restfulobjects.applib.RestfulResponse;
- @Override
- public Response toResponse(final ObjectNotFoundException ex) {
- return buildResponse(ex, RestfulResponse.HttpStatusCode.NOT_FOUND);
+//@Component
+//@Provider
+//@Singleton
+//@jakarta.annotation.Priority(PriorityPrecedence.MIDPOINT)
+@RestControllerAdvice
+@Slf4j
+public class ExceptionMapperForObjectNotFound
+//extends ExceptionMapperAbstract<ObjectNotFoundException>
+{
+
+ //TODO[causeway-viewer-restfulobjects-viewer-CAUSEWAY-3892] convert
+// @Override
+// public Response toResponse(final ObjectNotFoundException ex) {
+// return buildResponse(ex, RestfulResponse.HttpStatusCode.NOT_FOUND);
+// }
+
+ @ExceptionHandler(ObjectNotFoundException.class)
+ @ResponseStatus(HttpStatus.NOT_FOUND)
+ String objectNotFoundHandler(ObjectNotFoundException ex) {
+ return ex.getMessage();
+ }
+
+ @ExceptionHandler(Exception.class)
+ @ResponseStatus(HttpStatus.NOT_FOUND)
+ String fallback(Exception ex) {
+ log.error("not covered by any @ExceptionHandler", ex);
+ return "[fallback] " + ex.getMessage();
}
}
diff --git a/viewers/restfulobjects/viewer/src/main/java/org/apache/causeway/viewer/restfulobjects/viewer/resources/DomainObjectResourceServerside.java b/viewers/restfulobjects/viewer/src/main/java/org/apache/causeway/viewer/restfulobjects/viewer/resources/DomainObjectResourceServerside.java
index 1f3d699868f..158abd111f3 100644
--- a/viewers/restfulobjects/viewer/src/main/java/org/apache/causeway/viewer/restfulobjects/viewer/resources/DomainObjectResourceServerside.java
+++ b/viewers/restfulobjects/viewer/src/main/java/org/apache/causeway/viewer/restfulobjects/viewer/resources/DomainObjectResourceServerside.java
@@ -21,17 +21,10 @@
import java.io.InputStream;
import java.util.Optional;
-import jakarta.ws.rs.Consumes;
-import jakarta.ws.rs.DELETE;
-import jakarta.ws.rs.GET;
import jakarta.ws.rs.HttpMethod;
-import jakarta.ws.rs.POST;
-import jakarta.ws.rs.PUT;
import jakarta.ws.rs.Path;
import jakarta.ws.rs.PathParam;
-import jakarta.ws.rs.Produces;
import jakarta.ws.rs.QueryParam;
-import jakarta.ws.rs.core.MediaType;
import jakarta.ws.rs.core.Response;
import org.jspecify.annotations.NonNull;
@@ -58,10 +51,10 @@
import org.apache.causeway.viewer.restfulobjects.applib.JsonRepresentation;
import org.apache.causeway.viewer.restfulobjects.applib.Rel;
import org.apache.causeway.viewer.restfulobjects.applib.RepresentationType;
-import org.apache.causeway.viewer.restfulobjects.applib.RestfulMediaType;
import org.apache.causeway.viewer.restfulobjects.applib.RestfulResponse;
import org.apache.causeway.viewer.restfulobjects.applib.RestfulResponse.HttpStatusCode;
import org.apache.causeway.viewer.restfulobjects.applib.domainobjects.DomainObjectResource;
+import org.apache.causeway.viewer.restfulobjects.applib.util.MediaTypes;
import org.apache.causeway.viewer.restfulobjects.rendering.Responses;
import org.apache.causeway.viewer.restfulobjects.rendering.RestfulObjectsApplicationException;
import org.apache.causeway.viewer.restfulobjects.rendering.service.RepresentationService;
@@ -86,13 +79,13 @@ public DomainObjectResourceServerside() {
// PERSIST
@Override
- @POST
- @Path("/{domainType}")
- @Consumes({ MediaType.WILDCARD })
- @Produces({
- MediaType.APPLICATION_JSON, RestfulMediaType.APPLICATION_JSON_OBJECT, RestfulMediaType.APPLICATION_JSON_ERROR,
- MediaType.APPLICATION_XML, RestfulMediaType.APPLICATION_XML_OBJECT, RestfulMediaType.APPLICATION_XML_ERROR
- })
+// @POST
+// @Path("/{domainType}")
+// @Consumes({ MediaType.WILDCARD })
+// @Produces({
+// MediaType.APPLICATION_JSON, RestfulMediaType.APPLICATION_JSON_OBJECT, RestfulMediaType.APPLICATION_JSON_ERROR,
+// MediaType.APPLICATION_XML, RestfulMediaType.APPLICATION_XML_OBJECT, RestfulMediaType.APPLICATION_XML_ERROR
+// })
public Response persist(
@PathParam("domainType") final String domainType,
final InputStream object) {
@@ -152,13 +145,13 @@ public Response persist(
// DOMAIN OBJECT
@Override
- @GET
- @Path("/{domainType}/{instanceId}")
- @Consumes({ MediaType.WILDCARD })
- @Produces({
- MediaType.APPLICATION_JSON, RestfulMediaType.APPLICATION_JSON_OBJECT, RestfulMediaType.APPLICATION_JSON_ERROR,
- MediaType.APPLICATION_XML, RestfulMediaType.APPLICATION_XML_OBJECT, RestfulMediaType.APPLICATION_XML_ERROR
- })
+// @GET
+// @Path("/{domainType}/{instanceId}")
+// @Consumes({ MediaType.WILDCARD })
+// @Produces({
+// MediaType.APPLICATION_JSON, RestfulMediaType.APPLICATION_JSON_OBJECT, RestfulMediaType.APPLICATION_JSON_ERROR,
+// MediaType.APPLICATION_XML, RestfulMediaType.APPLICATION_XML_OBJECT, RestfulMediaType.APPLICATION_XML_ERROR
+// })
public Response object(
@PathParam("domainType") final String domainType,
@PathParam("instanceId") final String instanceId) {
@@ -176,13 +169,13 @@ public Response object(
}
@Override
- @PUT
- @Path("/{domainType}/{instanceId}")
- @Consumes({ MediaType.WILDCARD })
- @Produces({
- MediaType.APPLICATION_JSON, RestfulMediaType.APPLICATION_JSON_OBJECT, RestfulMediaType.APPLICATION_JSON_ERROR,
- MediaType.APPLICATION_XML, RestfulMediaType.APPLICATION_XML_OBJECT, RestfulMediaType.APPLICATION_XML_ERROR
- })
+// @PUT
+// @Path("/{domainType}/{instanceId}")
+// @Consumes({ MediaType.WILDCARD })
+// @Produces({
+// MediaType.APPLICATION_JSON, RestfulMediaType.APPLICATION_JSON_OBJECT, RestfulMediaType.APPLICATION_JSON_ERROR,
+// MediaType.APPLICATION_XML, RestfulMediaType.APPLICATION_XML_OBJECT, RestfulMediaType.APPLICATION_XML_ERROR
+// })
public Response object(
@PathParam("domainType") final String domainType,
@PathParam("instanceId") final String instanceId,
@@ -225,8 +218,8 @@ public Response object(
domainResourceHelper.objectRepresentation());
}
- @DELETE
- @Path("/{domainType}/{instanceId}")
+// @DELETE
+// @Path("/{domainType}/{instanceId}")
@Override
public Response deleteMethodNotSupported(
@PathParam("domainType") final String domainType,
@@ -237,8 +230,8 @@ public Response deleteMethodNotSupported(
HttpStatusCode.METHOD_NOT_ALLOWED, "Deleting objects is not supported."));
}
- @POST
- @Path("/{domainType}/{instanceId}")
+// @POST
+// @Path("/{domainType}/{instanceId}")
@Override
public Response postMethodNotAllowed(
@PathParam("domainType") final String domainType,
@@ -252,16 +245,16 @@ public Response postMethodNotAllowed(
// DOMAIN OBJECT LAYOUT
@Override
- @GET
- @Path("/{domainType}/{instanceId}/object-icon")
- @Consumes({ MediaType.WILDCARD })
- @Produces({
- "image/png",
- "image/gif",
- "image/jpeg",
- "image/jpg",
- "image/svg+xml"
- })
+// @GET
+// @Path("/{domainType}/{instanceId}/object-icon")
+// @Consumes({ MediaType.WILDCARD })
+// @Produces({
+// "image/png",
+// "image/gif",
+// "image/jpeg",
+// "image/jpg",
+// "image/svg+xml"
+// })
public Response image(
@PathParam("domainType") final String domainType,
@PathParam("instanceId") final String instanceId) {
@@ -287,13 +280,13 @@ public Response.ResponseBuilder objectIconResponse(
}
@Override
- @GET
- @Path("/{domainType}/{instanceId}/object-layout")
- @Consumes({ MediaType.WILDCARD })
- @Produces({
- MediaType.APPLICATION_JSON, RestfulMediaType.APPLICATION_JSON_OBJECT_LAYOUT_BS,
- MediaType.APPLICATION_XML, RestfulMediaType.APPLICATION_XML_OBJECT_LAYOUT_BS
- })
+// @GET
+// @Path("/{domainType}/{instanceId}/object-layout")
+// @Consumes({ MediaType.WILDCARD })
+// @Produces({
+// MediaType.APPLICATION_JSON, RestfulMediaType.APPLICATION_JSON_OBJECT_LAYOUT_BS,
+// MediaType.APPLICATION_XML, RestfulMediaType.APPLICATION_XML_OBJECT_LAYOUT_BS
+// })
public Response layout(
@PathParam("domainType") final String domainType,
@PathParam("instanceId") final String instanceId) {
@@ -311,7 +304,7 @@ public Response layout(
return Response.status(Response.Status.OK)
.entity(serializationStrategy.entity(grid))
- .type(serializationStrategy.type(RepresentationType.OBJECT_LAYOUT));
+ .type(MediaTypes.toJakarta(serializationStrategy.type(RepresentationType.OBJECT_LAYOUT)));
})
.orElseGet(Responses::ofNotFound)
.build());
@@ -390,13 +383,13 @@ public void visit(final CollectionLayoutData collectionLayoutData) {
// DOMAIN OBJECT PROPERTY
@Override
- @GET
- @Path("/{domainType}/{instanceId}/properties/{propertyId}")
- @Consumes({ MediaType.WILDCARD })
- @Produces({
- MediaType.APPLICATION_JSON, RestfulMediaType.APPLICATION_JSON_OBJECT_PROPERTY, RestfulMediaType.APPLICATION_JSON_ERROR,
- MediaType.APPLICATION_XML, RestfulMediaType.APPLICATION_XML_OBJECT_PROPERTY, RestfulMediaType.APPLICATION_XML_ERROR
- })
+// @GET
+// @Path("/{domainType}/{instanceId}/properties/{propertyId}")
+// @Consumes({ MediaType.WILDCARD })
+// @Produces({
+// MediaType.APPLICATION_JSON, RestfulMediaType.APPLICATION_JSON_OBJECT_PROPERTY, RestfulMediaType.APPLICATION_JSON_ERROR,
+// MediaType.APPLICATION_XML, RestfulMediaType.APPLICATION_XML_OBJECT_PROPERTY, RestfulMediaType.APPLICATION_XML_ERROR
+// })
public Response propertyDetails(
@PathParam("domainType") final String domainType,
@PathParam("instanceId") final String instanceId,
@@ -416,13 +409,13 @@ public Response propertyDetails(
}
@Override
- @PUT
- @Path("/{domainType}/{instanceId}/properties/{propertyId}")
- @Consumes({ MediaType.WILDCARD })
- @Produces({
- MediaType.APPLICATION_JSON, RestfulMediaType.APPLICATION_JSON_OBJECT_PROPERTY, RestfulMediaType.APPLICATION_JSON_ERROR,
- MediaType.APPLICATION_XML, RestfulMediaType.APPLICATION_XML_OBJECT_PROPERTY, RestfulMediaType.APPLICATION_XML_ERROR
- })
+// @PUT
+// @Path("/{domainType}/{instanceId}/properties/{propertyId}")
+// @Consumes({ MediaType.WILDCARD })
+// @Produces({
+// MediaType.APPLICATION_JSON, RestfulMediaType.APPLICATION_JSON_OBJECT_PROPERTY, RestfulMediaType.APPLICATION_JSON_ERROR,
+// MediaType.APPLICATION_XML, RestfulMediaType.APPLICATION_XML_OBJECT_PROPERTY, RestfulMediaType.APPLICATION_XML_ERROR
+// })
public Response modifyProperty(
@PathParam("domainType") final String domainType,
@PathParam("instanceId") final String instanceId,
@@ -456,13 +449,13 @@ public Response modifyProperty(
}
@Override
- @DELETE
- @Path("/{domainType}/{instanceId}/properties/{propertyId}")
- @Consumes({ MediaType.WILDCARD })
- @Produces({
- MediaType.APPLICATION_JSON, RestfulMediaType.APPLICATION_JSON_OBJECT_PROPERTY, RestfulMediaType.APPLICATION_JSON_ERROR,
- MediaType.APPLICATION_XML, RestfulMediaType.APPLICATION_XML_OBJECT_PROPERTY, RestfulMediaType.APPLICATION_XML_ERROR
- })
+// @DELETE
+// @Path("/{domainType}/{instanceId}/properties/{propertyId}")
+// @Consumes({ MediaType.WILDCARD })
+// @Produces({
+// MediaType.APPLICATION_JSON, RestfulMediaType.APPLICATION_JSON_OBJECT_PROPERTY, RestfulMediaType.APPLICATION_JSON_ERROR,
+// MediaType.APPLICATION_XML, RestfulMediaType.APPLICATION_XML_OBJECT_PROPERTY, RestfulMediaType.APPLICATION_XML_ERROR
+// })
public Response clearProperty(
@PathParam("domainType") final String domainType,
@PathParam("instanceId") final String instanceId,
@@ -488,8 +481,8 @@ public Response clearProperty(
.propertyDetails(propertyId, ManagedMember.RepresentationMode.WRITE));
}
- @POST
- @Path("/{domainType}/{instanceId}/properties/{propertyId}")
+// @POST
+// @Path("/{domainType}/{instanceId}/properties/{propertyId}")
@Override
public Response postPropertyNotAllowed(
@PathParam("domainType") final String domainType,
@@ -506,13 +499,13 @@ public Response postPropertyNotAllowed(
// DOMAIN OBJECT COLLECTION
@Override
- @GET
- @Path("/{domainType}/{instanceId}/collections/{collectionId}")
- @Consumes({ MediaType.WILDCARD })
- @Produces({
- MediaType.APPLICATION_JSON, RestfulMediaType.APPLICATION_JSON_OBJECT_COLLECTION, RestfulMediaType.APPLICATION_JSON_ERROR,
- MediaType.APPLICATION_XML, RestfulMediaType.APPLICATION_XML_OBJECT_COLLECTION, RestfulMediaType.APPLICATION_XML_ERROR
- })
+// @GET
+// @Path("/{domainType}/{instanceId}/collections/{collectionId}")
+// @Consumes({ MediaType.WILDCARD })
+// @Produces({
+// MediaType.APPLICATION_JSON, RestfulMediaType.APPLICATION_JSON_OBJECT_COLLECTION, RestfulMediaType.APPLICATION_JSON_ERROR,
+// MediaType.APPLICATION_XML, RestfulMediaType.APPLICATION_XML_OBJECT_COLLECTION, RestfulMediaType.APPLICATION_XML_ERROR
+// })
public Response accessCollection(
@PathParam("domainType") final String domainType,
@PathParam("instanceId") final String instanceId,
@@ -534,13 +527,13 @@ public Response accessCollection(
// DOMAIN OBJECT ACTION
@Override
- @GET
- @Path("/{domainType}/{instanceId}/actions/{actionId}")
- @Consumes({ MediaType.WILDCARD })
- @Produces({
- MediaType.APPLICATION_JSON, RestfulMediaType.APPLICATION_JSON_OBJECT_ACTION, RestfulMediaType.APPLICATION_JSON_ERROR,
- MediaType.APPLICATION_XML, RestfulMediaType.APPLICATION_XML_OBJECT_ACTION, RestfulMediaType.APPLICATION_XML_ERROR
- })
+// @GET
+// @Path("/{domainType}/{instanceId}/actions/{actionId}")
+// @Consumes({ MediaType.WILDCARD })
+// @Produces({
+// MediaType.APPLICATION_JSON, RestfulMediaType.APPLICATION_JSON_OBJECT_ACTION, RestfulMediaType.APPLICATION_JSON_ERROR,
+// MediaType.APPLICATION_XML, RestfulMediaType.APPLICATION_XML_OBJECT_ACTION, RestfulMediaType.APPLICATION_XML_ERROR
+// })
public Response actionPrompt(
@PathParam("domainType") final String domainType,
@PathParam("instanceId") final String instanceId,
@@ -558,8 +551,8 @@ public Response actionPrompt(
domainResourceHelper.actionPrompt(actionId));
}
- @DELETE
- @Path("/{domainType}/{instanceId}/actions/{actionId}")
+// @DELETE
+// @Path("/{domainType}/{instanceId}/actions/{actionId}")
@Override
public Response deleteActionPromptNotAllowed(
@PathParam("domainType") final String domainType,
@@ -573,8 +566,8 @@ public Response deleteActionPromptNotAllowed(
"Deleting action prompt resource is not allowed."));
}
- @POST
- @Path("/{domainType}/{instanceId}/actions/{actionId}")
+// @POST
+// @Path("/{domainType}/{instanceId}/actions/{actionId}")
@Override
public Response postActionPromptNotAllowed(
@PathParam("domainType") final String domainType,
@@ -588,8 +581,8 @@ public Response postActionPromptNotAllowed(
"Posting to an action prompt resource is not allowed."));
}
- @PUT
- @Path("/{domainType}/{instanceId}/actions/{actionId}")
+// @PUT
+// @Path("/{domainType}/{instanceId}/actions/{actionId}")
@Override
public Response putActionPromptNotAllowed(
@PathParam("domainType") final String domainType,
@@ -606,13 +599,13 @@ public Response putActionPromptNotAllowed(
// DOMAIN OBJECT ACTION INVOKE
@Override
- @GET
- @Path("/{domainType}/{instanceId}/actions/{actionId}/invoke")
- @Consumes({ MediaType.WILDCARD })
- @Produces({
- MediaType.APPLICATION_JSON, RestfulMediaType.APPLICATION_JSON_ACTION_RESULT, RestfulMediaType.APPLICATION_JSON_ERROR,
- MediaType.APPLICATION_XML, RestfulMediaType.APPLICATION_XML_ACTION_RESULT, RestfulMediaType.APPLICATION_XML_ERROR
- })
+// @GET
+// @Path("/{domainType}/{instanceId}/actions/{actionId}/invoke")
+// @Consumes({ MediaType.WILDCARD })
+// @Produces({
+// MediaType.APPLICATION_JSON, RestfulMediaType.APPLICATION_JSON_ACTION_RESULT, RestfulMediaType.APPLICATION_JSON_ERROR,
+// MediaType.APPLICATION_XML, RestfulMediaType.APPLICATION_XML_ACTION_RESULT, RestfulMediaType.APPLICATION_XML_ERROR
+// })
public Response invokeActionQueryOnly(
final @PathParam("domainType") String domainType,
final @PathParam("instanceId") String instanceId,
@@ -639,13 +632,13 @@ public Response invokeActionQueryOnly(
}
@Override
- @PUT
- @Path("/{domainType}/{instanceId}/actions/{actionId}/invoke")
- @Consumes({ MediaType.WILDCARD })
- @Produces({
- MediaType.APPLICATION_JSON, RestfulMediaType.APPLICATION_JSON_ACTION_RESULT, RestfulMediaType.APPLICATION_JSON_ERROR,
- MediaType.APPLICATION_XML, RestfulMediaType.APPLICATION_XML_ACTION_RESULT, RestfulMediaType.APPLICATION_XML_ERROR
- })
+// @PUT
+// @Path("/{domainType}/{instanceId}/actions/{actionId}/invoke")
+// @Consumes({ MediaType.WILDCARD })
+// @Produces({
+// MediaType.APPLICATION_JSON, RestfulMediaType.APPLICATION_JSON_ACTION_RESULT, RestfulMediaType.APPLICATION_JSON_ERROR,
+// MediaType.APPLICATION_XML, RestfulMediaType.APPLICATION_XML_ACTION_RESULT, RestfulMediaType.APPLICATION_XML_ERROR
+// })
public Response invokeActionIdempotent(
final @PathParam("domainType") String domainType,
final @PathParam("instanceId") String instanceId,
@@ -668,13 +661,13 @@ public Response invokeActionIdempotent(
}
@Override
- @POST
- @Path("/{domainType}/{instanceId}/actions/{actionId}/invoke")
- @Consumes({ MediaType.WILDCARD })
- @Produces({
- MediaType.APPLICATION_JSON, RestfulMediaType.APPLICATION_JSON_ACTION_RESULT, RestfulMediaType.APPLICATION_JSON_ERROR,
- MediaType.APPLICATION_XML, RestfulMediaType.APPLICATION_XML_ACTION_RESULT, RestfulMediaType.APPLICATION_XML_ERROR
- })
+// @POST
+// @Path("/{domainType}/{instanceId}/actions/{actionId}/invoke")
+// @Consumes({ MediaType.WILDCARD })
+// @Produces({
+// MediaType.APPLICATION_JSON, RestfulMediaType.APPLICATION_JSON_ACTION_RESULT, RestfulMediaType.APPLICATION_JSON_ERROR,
+// MediaType.APPLICATION_XML, RestfulMediaType.APPLICATION_XML_ACTION_RESULT, RestfulMediaType.APPLICATION_XML_ERROR
+// })
public Response invokeAction(
@PathParam("domainType") final String domainType,
@PathParam("instanceId") final String instanceId,
@@ -696,8 +689,8 @@ public Response invokeAction(
domainResourceHelper.invokeAction(actionId, arguments));
}
- @DELETE
- @Path("/{domainType}/{instanceId}/actions/{actionId}/invoke")
+// @DELETE
+// @Path("/{domainType}/{instanceId}/actions/{actionId}/invoke")
@Override
public Response deleteInvokeActionNotAllowed(
@PathParam("domainType") final String domainType,
diff --git a/viewers/restfulobjects/viewer/src/main/java/org/apache/causeway/viewer/restfulobjects/viewer/resources/DomainServiceResourceServerside.java b/viewers/restfulobjects/viewer/src/main/java/org/apache/causeway/viewer/restfulobjects/viewer/resources/DomainServiceResourceServerside.java
index dee4c5bdd71..2bc2f69b20f 100644
--- a/viewers/restfulobjects/viewer/src/main/java/org/apache/causeway/viewer/restfulobjects/viewer/resources/DomainServiceResourceServerside.java
+++ b/viewers/restfulobjects/viewer/src/main/java/org/apache/causeway/viewer/restfulobjects/viewer/resources/DomainServiceResourceServerside.java
@@ -19,16 +19,10 @@
package org.apache.causeway.viewer.restfulobjects.viewer.resources;
import java.io.InputStream;
-import jakarta.ws.rs.Consumes;
-import jakarta.ws.rs.DELETE;
-import jakarta.ws.rs.GET;
-import jakarta.ws.rs.POST;
-import jakarta.ws.rs.PUT;
+
import jakarta.ws.rs.Path;
import jakarta.ws.rs.PathParam;
-import jakarta.ws.rs.Produces;
import jakarta.ws.rs.QueryParam;
-import jakarta.ws.rs.core.MediaType;
import jakarta.ws.rs.core.Response;
import org.springframework.stereotype.Component;
@@ -37,7 +31,6 @@
import org.apache.causeway.commons.io.UrlUtils;
import org.apache.causeway.viewer.restfulobjects.applib.JsonRepresentation;
import org.apache.causeway.viewer.restfulobjects.applib.RepresentationType;
-import org.apache.causeway.viewer.restfulobjects.applib.RestfulMediaType;
import org.apache.causeway.viewer.restfulobjects.applib.RestfulResponse;
import org.apache.causeway.viewer.restfulobjects.applib.domainobjects.DomainServiceResource;
import org.apache.causeway.viewer.restfulobjects.rendering.Caching;
@@ -64,12 +57,12 @@ public DomainServiceResourceServerside() {
}
@Override
- @GET
- @Path("/")
- @Produces({
- MediaType.APPLICATION_JSON,
- RestfulMediaType.APPLICATION_JSON_LIST,
- RestfulMediaType.APPLICATION_JSON_ERROR })
+// @GET
+// @Path("/")
+// @Produces({
+// MediaType.APPLICATION_JSON,
+// RestfulMediaType.APPLICATION_JSON_LIST,
+// RestfulMediaType.APPLICATION_JSON_ERROR })
public Response services() {
var resourceContext = createResourceContext(
@@ -116,12 +109,12 @@ public Response postServicesNotAllowed() {
// DOMAIN SERVICE
@Override
- @GET
- @Path("/{serviceId}")
- @Produces({
- MediaType.APPLICATION_JSON, RestfulMediaType.APPLICATION_JSON_OBJECT, RestfulMediaType.APPLICATION_JSON_ERROR,
- MediaType.APPLICATION_XML, RestfulMediaType.APPLICATION_XML_OBJECT, RestfulMediaType.APPLICATION_XML_ERROR
- })
+// @GET
+// @Path("/{serviceId}")
+// @Produces({
+// MediaType.APPLICATION_JSON, RestfulMediaType.APPLICATION_JSON_OBJECT, RestfulMediaType.APPLICATION_JSON_ERROR,
+// MediaType.APPLICATION_XML, RestfulMediaType.APPLICATION_XML_OBJECT, RestfulMediaType.APPLICATION_XML_ERROR
+// })
public Response service(
@PathParam("serviceId") final String serviceId) {
@@ -141,8 +134,8 @@ public Response service(
Responses.ofOk(renderer, Caching.ONE_DAY).build());
}
- @DELETE
- @Path("/{serviceId}")
+// @DELETE
+// @Path("/{serviceId}")
@Override
public Response deleteServiceNotAllowed(
@PathParam("serviceId") final String serviceId) {
@@ -153,8 +146,8 @@ public Response deleteServiceNotAllowed(
"Deleting a service resource is not allowed."));
}
- @PUT
- @Path("/{serviceId}")
+// @PUT
+// @Path("/{serviceId}")
@Override
public Response putServiceNotAllowed(
@PathParam("serviceId") final String serviceId) {
@@ -165,8 +158,8 @@ public Response putServiceNotAllowed(
"Putting to a service resource is not allowed."));
}
- @POST
- @Path("/{serviceId}")
+// @POST
+// @Path("/{serviceId}")
@Override
public Response postServiceNotAllowed(
@PathParam("serviceId") final String serviceId) {
@@ -180,12 +173,12 @@ public Response postServiceNotAllowed(
// DOMAIN SERVICE ACTION
@Override
- @GET
- @Path("/{serviceId}/actions/{actionId}")
- @Produces({
- MediaType.APPLICATION_JSON, RestfulMediaType.APPLICATION_JSON_OBJECT_ACTION, RestfulMediaType.APPLICATION_JSON_ERROR,
- MediaType.APPLICATION_XML, RestfulMediaType.APPLICATION_XML_OBJECT_ACTION, RestfulMediaType.APPLICATION_XML_ERROR
- })
+// @GET
+// @Path("/{serviceId}/actions/{actionId}")
+// @Produces({
+// MediaType.APPLICATION_JSON, RestfulMediaType.APPLICATION_JSON_OBJECT_ACTION, RestfulMediaType.APPLICATION_JSON_ERROR,
+// MediaType.APPLICATION_XML, RestfulMediaType.APPLICATION_XML_OBJECT_ACTION, RestfulMediaType.APPLICATION_XML_ERROR
+// })
public Response actionPrompt(
@PathParam("serviceId") final String serviceId,
@PathParam("actionId") final String actionId) {
@@ -200,8 +193,8 @@ public Response actionPrompt(
domainResourceHelper.actionPrompt(actionId));
}
- @DELETE
- @Path("/{serviceId}/actions/{actionId}")
+// @DELETE
+// @Path("/{serviceId}/actions/{actionId}")
@Override
public Response deleteActionPromptNotAllowed(
@PathParam("serviceId") final String serviceId,
@@ -213,8 +206,8 @@ public Response deleteActionPromptNotAllowed(
"Deleting action prompt resource is not allowed."));
}
- @PUT
- @Path("/{serviceId}/actions/{actionId}")
+// @PUT
+// @Path("/{serviceId}/actions/{actionId}")
@Override
public Response putActionPromptNotAllowed(
@PathParam("serviceId") final String serviceId,
@@ -226,8 +219,8 @@ public Response putActionPromptNotAllowed(
"Putting to an action prompt resource is not allowed."));
}
- @POST
- @Path("/{serviceId}/actions/{actionId}")
+// @POST
+// @Path("/{serviceId}/actions/{actionId}")
@Override
public Response postActionPromptNotAllowed(
@PathParam("serviceId") final String serviceId,
@@ -242,12 +235,12 @@ public Response postActionPromptNotAllowed(
// DOMAIN SERVICE ACTION INVOKE
@Override
- @GET
- @Path("/{serviceId}/actions/{actionId}/invoke")
- @Produces({
- MediaType.APPLICATION_JSON, RestfulMediaType.APPLICATION_JSON_ACTION_RESULT, RestfulMediaType.APPLICATION_JSON_ERROR,
- MediaType.APPLICATION_XML, RestfulMediaType.APPLICATION_XML_ACTION_RESULT, RestfulMediaType.APPLICATION_XML_ERROR
- })
+// @GET
+// @Path("/{serviceId}/actions/{actionId}/invoke")
+// @Produces({
+// MediaType.APPLICATION_JSON, RestfulMediaType.APPLICATION_JSON_ACTION_RESULT, RestfulMediaType.APPLICATION_JSON_ERROR,
+// MediaType.APPLICATION_XML, RestfulMediaType.APPLICATION_XML_ACTION_RESULT, RestfulMediaType.APPLICATION_XML_ERROR
+// })
public Response invokeActionQueryOnly(
final @PathParam("serviceId") String serviceId,
final @PathParam("actionId") String actionId,
@@ -271,13 +264,13 @@ public Response invokeActionQueryOnly(
}
@Override
- @PUT
- @Path("/{serviceId}/actions/{actionId}/invoke")
- @Consumes({ MediaType.WILDCARD }) // to save the client having to specify a Content-Type: application/json
- @Produces({
- MediaType.APPLICATION_JSON, RestfulMediaType.APPLICATION_JSON_ACTION_RESULT, RestfulMediaType.APPLICATION_JSON_ERROR,
- MediaType.APPLICATION_XML, RestfulMediaType.APPLICATION_XML_ACTION_RESULT, RestfulMediaType.APPLICATION_XML_ERROR
- })
+// @PUT
+// @Path("/{serviceId}/actions/{actionId}/invoke")
+// //@Consumes({ MediaType.WILDCARD }) // to save the client having to specify a Content-Type: application/json
+// @Produces({
+// MediaType.APPLICATION_JSON, RestfulMediaType.APPLICATION_JSON_ACTION_RESULT, RestfulMediaType.APPLICATION_JSON_ERROR,
+// MediaType.APPLICATION_XML, RestfulMediaType.APPLICATION_XML_ACTION_RESULT, RestfulMediaType.APPLICATION_XML_ERROR
+// })
public Response invokeActionIdempotent(
final @PathParam("serviceId") String serviceId,
final @PathParam("actionId") String actionId,
@@ -297,13 +290,13 @@ public Response invokeActionIdempotent(
}
@Override
- @POST
- @Path("/{serviceId}/actions/{actionId}/invoke")
- @Consumes({ MediaType.WILDCARD }) // to save the client having to specify a Content-Type: application/json
- @Produces({
- MediaType.APPLICATION_JSON, RestfulMediaType.APPLICATION_JSON_ACTION_RESULT, RestfulMediaType.APPLICATION_JSON_ERROR,
- MediaType.APPLICATION_XML, RestfulMediaType.APPLICATION_XML_ACTION_RESULT, RestfulMediaType.APPLICATION_XML_ERROR
- })
+// @POST
+// @Path("/{serviceId}/actions/{actionId}/invoke")
+// //@Consumes({ MediaType.WILDCARD }) // to save the client having to specify a Content-Type: application/json
+// @Produces({
+// MediaType.APPLICATION_JSON, RestfulMediaType.APPLICATION_JSON_ACTION_RESULT, RestfulMediaType.APPLICATION_JSON_ERROR,
+// MediaType.APPLICATION_XML, RestfulMediaType.APPLICATION_XML_ACTION_RESULT, RestfulMediaType.APPLICATION_XML_ERROR
+// })
public Response invokeAction(
@PathParam("serviceId") final String serviceId,
@PathParam("actionId") final String actionId,
@@ -322,8 +315,8 @@ public Response invokeAction(
domainResourceHelper.invokeAction(actionId, arguments));
}
- @DELETE
- @Path("/{serviceId}/actions/{actionId}/invoke")
+// @DELETE
+// @Path("/{serviceId}/actions/{actionId}/invoke")
@Override
public Response deleteInvokeActionNotAllowed(
@PathParam("serviceId") final String serviceId,
diff --git a/viewers/restfulobjects/viewer/src/main/java/org/apache/causeway/viewer/restfulobjects/viewer/resources/DomainTypeResourceServerside.java b/viewers/restfulobjects/viewer/src/main/java/org/apache/causeway/viewer/restfulobjects/viewer/resources/DomainTypeResourceServerside.java
index bf11a3c82df..a7fa28ef193 100644
--- a/viewers/restfulobjects/viewer/src/main/java/org/apache/causeway/viewer/restfulobjects/viewer/resources/DomainTypeResourceServerside.java
+++ b/viewers/restfulobjects/viewer/src/main/java/org/apache/causeway/viewer/restfulobjects/viewer/resources/DomainTypeResourceServerside.java
@@ -20,12 +20,9 @@
import java.util.function.UnaryOperator;
-import jakarta.ws.rs.GET;
import jakarta.ws.rs.Path;
import jakarta.ws.rs.PathParam;
-import jakarta.ws.rs.Produces;
import jakarta.ws.rs.QueryParam;
-import jakarta.ws.rs.core.MediaType;
import jakarta.ws.rs.core.Response;
import org.jspecify.annotations.NonNull;
@@ -41,9 +38,9 @@
import org.apache.causeway.viewer.restfulobjects.applib.JsonRepresentation;
import org.apache.causeway.viewer.restfulobjects.applib.Rel;
import org.apache.causeway.viewer.restfulobjects.applib.RepresentationType;
-import org.apache.causeway.viewer.restfulobjects.applib.RestfulMediaType;
import org.apache.causeway.viewer.restfulobjects.applib.RestfulResponse.HttpStatusCode;
import org.apache.causeway.viewer.restfulobjects.applib.domaintypes.DomainTypeResource;
+import org.apache.causeway.viewer.restfulobjects.applib.util.MediaTypes;
import org.apache.causeway.viewer.restfulobjects.applib.util.UrlEncodingUtils;
import org.apache.causeway.viewer.restfulobjects.rendering.Caching;
import org.apache.causeway.viewer.restfulobjects.rendering.LinkBuilder;
@@ -85,11 +82,11 @@ public DomainTypeResourceServerside() {
}
@Override
- @GET
- @Path("/")
- @Produces({
- MediaType.APPLICATION_JSON,
- RestfulMediaType.APPLICATION_JSON_TYPE_LIST })
+// @GET
+// @Path("/")
+// @Produces({
+// MediaType.APPLICATION_JSON,
+// RestfulMediaType.APPLICATION_JSON_TYPE_LIST })
public Response domainTypes() {
var resourceContext = createResourceContext(
@@ -107,11 +104,11 @@ public Response domainTypes() {
}
@Override
- @GET
- @Path("/{domainType}")
- @Produces({
- MediaType.APPLICATION_JSON,
- RestfulMediaType.APPLICATION_JSON_DOMAIN_TYPE })
+// @GET
+// @Path("/{domainType}")
+// @Produces({
+// MediaType.APPLICATION_JSON,
+// RestfulMediaType.APPLICATION_JSON_DOMAIN_TYPE })
public Response domainType(
@PathParam("domainType") final String domainType) {
@@ -132,12 +129,12 @@ public Response domainType(
}
@Override
- @GET
- @Path("/{domainType}/layout")
- @Produces({
- MediaType.APPLICATION_JSON, RestfulMediaType.APPLICATION_JSON_LAYOUT_BS,
- MediaType.APPLICATION_XML, RestfulMediaType.APPLICATION_XML_LAYOUT_BS
- })
+// @GET
+// @Path("/{domainType}/layout")
+// @Produces({
+// MediaType.APPLICATION_JSON, RestfulMediaType.APPLICATION_JSON_LAYOUT_BS,
+// MediaType.APPLICATION_XML, RestfulMediaType.APPLICATION_XML_LAYOUT_BS
+// })
public Response layout(
@PathParam("domainType") final String domainType) {
@@ -151,7 +148,7 @@ public Response layout(
.map(grid ->
Response.status(Response.Status.OK)
.entity(serializationStrategy.entity(grid))
- .type(serializationStrategy.type(RepresentationType.LAYOUT)))
+ .type(MediaTypes.toJakarta(serializationStrategy.type(RepresentationType.LAYOUT))))
.orElse(Responses.ofNotFound());
return _EndpointLogging.response(log, "GET({}) /domain-types/{}/layout", serializationStrategy.name(), domainType,
@@ -159,11 +156,11 @@ public Response layout(
}
@Override
- @GET
- @Path("/{domainType}/properties/{propertyId}")
- @Produces({
- MediaType.APPLICATION_JSON,
- RestfulMediaType.APPLICATION_JSON_PROPERTY_DESCRIPTION })
+// @GET
+// @Path("/{domainType}/properties/{propertyId}")
+// @Produces({
+// MediaType.APPLICATION_JSON,
+// RestfulMediaType.APPLICATION_JSON_PROPERTY_DESCRIPTION })
public Response typeProperty(
@PathParam("domainType") final String domainType,
@PathParam("propertyId") final String propertyId) {
@@ -196,11 +193,11 @@ public Response typeProperty(
}
@Override
- @GET
- @Path("/{domainType}/collections/{collectionId}")
- @Produces({
- MediaType.APPLICATION_JSON,
- RestfulMediaType.APPLICATION_JSON_COLLECTION_DESCRIPTION })
+// @GET
+// @Path("/{domainType}/collections/{collectionId}")
+// @Produces({
+// MediaType.APPLICATION_JSON,
+// RestfulMediaType.APPLICATION_JSON_COLLECTION_DESCRIPTION })
public Response typeCollection(
@PathParam("domainType") final String domainType,
@PathParam("collectionId") final String collectionId) {
@@ -233,11 +230,11 @@ public Response typeCollection(
}
@Override
- @GET
- @Path("/{domainType}/actions/{actionId}")
- @Produces({
- MediaType.APPLICATION_JSON,
- RestfulMediaType.APPLICATION_JSON_ACTION_DESCRIPTION })
+// @GET
+// @Path("/{domainType}/actions/{actionId}")
+// @Produces({
+// MediaType.APPLICATION_JSON,
+// RestfulMediaType.APPLICATION_JSON_ACTION_DESCRIPTION })
public Response typeAction(
@PathParam("domainType") final String domainType,
@PathParam("actionId") final String actionId) {
@@ -263,11 +260,11 @@ public Response typeAction(
}
@Override
- @GET
- @Path("/{domainType}/actions/{actionId}/params/{paramId}")
- @Produces({
- MediaType.APPLICATION_JSON,
- RestfulMediaType.APPLICATION_JSON_ACTION_PARAMETER_DESCRIPTION })
+// @GET
+// @Path("/{domainType}/actions/{actionId}/params/{paramId}")
+// @Produces({
+// MediaType.APPLICATION_JSON,
+// RestfulMediaType.APPLICATION_JSON_ACTION_PARAMETER_DESCRIPTION })
public Response typeActionParam(
@PathParam("domainType") final String domainType,
@PathParam("actionId") final String actionId,
@@ -295,17 +292,15 @@ public Response typeActionParam(
Responses.ofOk(renderer, Caching.ONE_DAY).build());
}
- // //////////////////////////////////////////////////////////
- // domain type actions
- // //////////////////////////////////////////////////////////
+ // -- DOMAIN TYPE ACTIONS
@Override
- @GET
- @Path("/{domainType}/type-actions/isSubtypeOf/invoke")
- @Produces({
- MediaType.APPLICATION_JSON,
- RestfulMediaType.APPLICATION_JSON_TYPE_ACTION_RESULT,
- RestfulMediaType.APPLICATION_JSON_ERROR })
+// @GET
+// @Path("/{domainType}/type-actions/isSubtypeOf/invoke")
+// @Produces({
+// MediaType.APPLICATION_JSON,
+// RestfulMediaType.APPLICATION_JSON_TYPE_ACTION_RESULT,
+// RestfulMediaType.APPLICATION_JSON_ERROR })
public Response domainTypeIsSubtypeOf(
@PathParam("domainType") final String domainType,
@QueryParam("supertype") final String superTypeStr, // simple style
@@ -342,12 +337,12 @@ public Response domainTypeIsSubtypeOf(
}
@Override
- @GET
- @Path("/{domainType}/type-actions/isSupertypeOf/invoke")
- @Produces({
- MediaType.APPLICATION_JSON,
- RestfulMediaType.APPLICATION_JSON_TYPE_ACTION_RESULT,
- RestfulMediaType.APPLICATION_JSON_ERROR })
+// @GET
+// @Path("/{domainType}/type-actions/isSupertypeOf/invoke")
+// @Produces({
+// MediaType.APPLICATION_JSON,
+// RestfulMediaType.APPLICATION_JSON_TYPE_ACTION_RESULT,
+// RestfulMediaType.APPLICATION_JSON_ERROR })
public Response domainTypeIsSupertypeOf(
@PathParam("domainType") final String domainType,
@QueryParam("subtype") final String subTypeStr, // simple style
diff --git a/viewers/restfulobjects/viewer/src/main/java/org/apache/causeway/viewer/restfulobjects/viewer/resources/HomePageResourceServerside.java b/viewers/restfulobjects/viewer/src/main/java/org/apache/causeway/viewer/restfulobjects/viewer/resources/HomePageResourceServerside.java
index 04dfd78789b..eee5ed6cc35 100644
--- a/viewers/restfulobjects/viewer/src/main/java/org/apache/causeway/viewer/restfulobjects/viewer/resources/HomePageResourceServerside.java
+++ b/viewers/restfulobjects/viewer/src/main/java/org/apache/causeway/viewer/restfulobjects/viewer/resources/HomePageResourceServerside.java
@@ -18,18 +18,13 @@
*/
package org.apache.causeway.viewer.restfulobjects.viewer.resources;
-import jakarta.ws.rs.GET;
-import jakarta.ws.rs.Path;
-import jakarta.ws.rs.Produces;
-import jakarta.ws.rs.core.MediaType;
import jakarta.ws.rs.core.Response;
-import org.springframework.stereotype.Component;
+import org.springframework.web.bind.annotation.RestController;
import org.apache.causeway.applib.annotation.Where;
import org.apache.causeway.viewer.restfulobjects.applib.JsonRepresentation;
import org.apache.causeway.viewer.restfulobjects.applib.RepresentationType;
-import org.apache.causeway.viewer.restfulobjects.applib.RestfulMediaType;
import org.apache.causeway.viewer.restfulobjects.applib.RestfulResponse;
import org.apache.causeway.viewer.restfulobjects.applib.RestfulResponse.HttpStatusCode;
import org.apache.causeway.viewer.restfulobjects.applib.homepage.HomePageResource;
@@ -40,7 +35,7 @@
import lombok.extern.slf4j.Slf4j;
-@Component
+@RestController
@Slf4j
public class HomePageResourceServerside
extends ResourceAbstract
@@ -52,9 +47,9 @@ public HomePageResourceServerside() {
}
@Override
- @Produces({
- MediaType.APPLICATION_JSON,
- RestfulMediaType.APPLICATION_JSON_HOME_PAGE })
+// @Produces({
+// MediaType.APPLICATION_JSON,
+// RestfulMediaType.APPLICATION_JSON_HOME_PAGE })
public Response homePage() {
var resourceContext = createResourceContext(
@@ -95,9 +90,9 @@ public Response postHomePageNotAllowed() {
}
@Override
- @GET
- @Path("/notAuthenticated")
- @Produces({ MediaType.APPLICATION_JSON })
+// @GET
+// @Path("/notAuthenticated")
+// @Produces({ MediaType.APPLICATION_JSON })
public Response notAuthenticated() {
throw _EndpointLogging.error(log, "GET /notAuthenticated",
RestfulObjectsApplicationException.create(HttpStatusCode.UNAUTHORIZED));
diff --git a/viewers/restfulobjects/viewer/src/main/java/org/apache/causeway/viewer/restfulobjects/viewer/resources/MenuBarsResourceServerside.java b/viewers/restfulobjects/viewer/src/main/java/org/apache/causeway/viewer/restfulobjects/viewer/resources/MenuBarsResourceServerside.java
index c105853a720..d9e5f5a2d5f 100644
--- a/viewers/restfulobjects/viewer/src/main/java/org/apache/causeway/viewer/restfulobjects/viewer/resources/MenuBarsResourceServerside.java
+++ b/viewers/restfulobjects/viewer/src/main/java/org/apache/causeway/viewer/restfulobjects/viewer/resources/MenuBarsResourceServerside.java
@@ -22,7 +22,7 @@
import jakarta.ws.rs.HttpMethod;
import jakarta.ws.rs.Produces;
-import jakarta.ws.rs.core.MediaType;
+import org.springframework.http.MediaType;
import jakarta.ws.rs.core.Response;
import org.springframework.stereotype.Component;
@@ -37,6 +37,7 @@
import org.apache.causeway.viewer.restfulobjects.applib.RestfulMediaType;
import org.apache.causeway.viewer.restfulobjects.applib.RestfulResponse;
import org.apache.causeway.viewer.restfulobjects.applib.menubars.MenuBarsResource;
+import org.apache.causeway.viewer.restfulobjects.applib.util.MediaTypes;
import org.apache.causeway.viewer.restfulobjects.rendering.RestfulObjectsApplicationException;
import org.apache.causeway.viewer.restfulobjects.rendering.service.RepresentationService;
import org.apache.causeway.viewer.restfulobjects.viewer.context.ResourceContext;
@@ -52,8 +53,8 @@ public MenuBarsResourceServerside() {
@Override
@Produces({
- MediaType.APPLICATION_JSON, RestfulMediaType.APPLICATION_JSON_LAYOUT_MENUBARS,
- MediaType.APPLICATION_XML, RestfulMediaType.APPLICATION_XML_LAYOUT_MENUBARS
+ MediaType.APPLICATION_JSON_VALUE, RestfulMediaType.APPLICATION_JSON_LAYOUT_MENUBARS,
+ MediaType.APPLICATION_XML_VALUE, RestfulMediaType.APPLICATION_XML_LAYOUT_MENUBARS
})
public Response menuBars() {
@@ -69,7 +70,7 @@ public Response menuBars() {
builder = Response.status(Response.Status.OK)
.entity(serializationStrategy.entity(menuBars))
- .type(serializationStrategy.type(RepresentationType.MENUBARS));
+ .type(MediaTypes.toJakarta(serializationStrategy.type(RepresentationType.MENUBARS)));
return builder.build();
}
diff --git a/viewers/restfulobjects/viewer/src/main/java/org/apache/causeway/viewer/restfulobjects/viewer/resources/ResourceAbstract.java b/viewers/restfulobjects/viewer/src/main/java/org/apache/causeway/viewer/restfulobjects/viewer/resources/ResourceAbstract.java
index 9860981e8ca..9b30f26c6bd 100644
--- a/viewers/restfulobjects/viewer/src/main/java/org/apache/causeway/viewer/restfulobjects/viewer/resources/ResourceAbstract.java
+++ b/viewers/restfulobjects/viewer/src/main/java/org/apache/causeway/viewer/restfulobjects/viewer/resources/ResourceAbstract.java
@@ -24,14 +24,11 @@
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
-import jakarta.ws.rs.core.Context;
-import jakarta.ws.rs.core.HttpHeaders;
-import jakarta.ws.rs.core.Request;
-import jakarta.ws.rs.core.SecurityContext;
-import jakarta.ws.rs.core.UriInfo;
-import jakarta.ws.rs.ext.Providers;
+import org.jspecify.annotations.NonNull;
import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.context.request.ServletWebRequest;
+
import org.apache.causeway.applib.annotation.Where;
import org.apache.causeway.applib.services.bookmark.Bookmark;
import org.apache.causeway.commons.internal.base._Strings;
@@ -54,7 +51,6 @@
import org.apache.causeway.viewer.restfulobjects.viewer.resources.ResourceDescriptor.ResourceLink;
import lombok.Getter;
-import org.jspecify.annotations.NonNull;
public abstract class ResourceAbstract
implements HasMetaModelContext {
@@ -63,13 +59,10 @@ public abstract class ResourceAbstract
@Autowired protected MetaModelContext metaModelContext;
@Autowired protected WebAppContextPath webAppContextPath;
- @Context HttpHeaders httpHeaders;
- @Context UriInfo uriInfo;
- @Context Request request;
- @Context HttpServletRequest httpServletRequest;
- @Context HttpServletResponse httpServletResponse;
- @Context SecurityContext securityContext;
- @Context Providers providers;
+ @Autowired ServletWebRequest servletWebRequest;
+
+ @Deprecated @Autowired HttpServletRequest httpServletRequest;
+ @Deprecated @Autowired HttpServletResponse httpServletResponse;
protected ResourceAbstract() {
}
@@ -104,12 +97,15 @@ protected ResourceContext createResourceContext(
throw RestfulObjectsApplicationException.create(HttpStatusCode.UNAUTHORIZED);
}
+ var reqUrl = servletWebRequest.getRequest().getRequestURL().toString();
+
// eg. http://localhost:8080/ctx/restful/
final String restfulAbsoluteBase = getConfiguration().getViewer().getRestfulobjects().getBaseUri()
- .orElseGet(()->uriInfo.getBaseUri().toString());
+ //.orElseGet(()->uriInfo.getBaseUri().toString()) //FIXME[causeway-viewer-restfulobjects-viewer-CAUSEWAY-3892]
+ .orElseGet(()->"TODO");
// eg. /ctx/restful/
- var restfulRelativeBase = uriInfo.getBaseUri().getRawPath();
+ var restfulRelativeBase = "TODO"; //uriInfo.getBaseUri().getRawPath();
// eg. http://localhost:8080/
var serverAbsoluteBase =
@@ -172,16 +168,14 @@ private ResourceContext resourceContext(
final Map<String, String[]> requestParams) {
return new ResourceContext(
- resourceDescriptor,
- httpHeaders, providers, request,
- applicationAbsoluteBase,
- restfulAbsoluteBase,
- urlUnencodedQueryString,
- httpServletRequest, httpServletResponse,
- securityContext,
- metaModelContext,
- InteractionInitiatedBy.USER,
- requestParams);
+ metaModelContext,
+ resourceDescriptor,
+ applicationAbsoluteBase,
+ restfulAbsoluteBase,
+ urlUnencodedQueryString,
+ httpServletRequest, httpServletResponse,
+ InteractionInitiatedBy.USER,
+ requestParams);
}
}
diff --git a/viewers/restfulobjects/viewer/src/main/java/org/apache/causeway/viewer/restfulobjects/viewer/resources/SwaggerSpecResource.java b/viewers/restfulobjects/viewer/src/main/java/org/apache/causeway/viewer/restfulobjects/viewer/resources/SwaggerSpecResource.java
index e2775120f38..0be6c03517c 100644
--- a/viewers/restfulobjects/viewer/src/main/java/org/apache/causeway/viewer/restfulobjects/viewer/resources/SwaggerSpecResource.java
+++ b/viewers/restfulobjects/viewer/src/main/java/org/apache/causeway/viewer/restfulobjects/viewer/resources/SwaggerSpecResource.java
@@ -18,18 +18,18 @@
*/
package org.apache.causeway.viewer.restfulobjects.viewer.resources;
-import java.util.List;
import java.util.concurrent.Callable;
import jakarta.inject.Inject;
import jakarta.servlet.http.HttpServletRequest;
-import jakarta.ws.rs.Consumes;
import jakarta.ws.rs.GET;
import jakarta.ws.rs.Path;
import jakarta.ws.rs.Produces;
import jakarta.ws.rs.core.Context;
-import jakarta.ws.rs.core.HttpHeaders;
-import jakarta.ws.rs.core.MediaType;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.http.HttpHeaders;
+import org.springframework.http.MediaType;
import org.springframework.stereotype.Component;
@@ -38,7 +38,6 @@
import org.apache.causeway.applib.services.swagger.SwaggerService;
import org.apache.causeway.applib.services.swagger.Visibility;
-import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
@Component
@@ -49,8 +48,8 @@ public class SwaggerSpecResource {
private final SwaggerService swaggerService;
private final InteractionService interactionService;
- @Context HttpHeaders httpHeaders;
- @Context HttpServletRequest httpServletRequest;
+ @Autowired HttpHeaders httpHeaders;
+ @Autowired HttpServletRequest httpServletRequest;
@Inject
public SwaggerSpecResource(
@@ -63,9 +62,9 @@ public SwaggerSpecResource(
@Path("/private")
@GET
- @Consumes({ MediaType.WILDCARD, MediaType.APPLICATION_JSON, "text/yaml" })
+ //@Consumes({ MediaType.WILDCARD, MediaType.APPLICATION_JSON, "text/yaml" })
@Produces({
- MediaType.APPLICATION_JSON, "text/yaml"
+ MediaType.APPLICATION_JSON_VALUE, "text/yaml"
})
public String swaggerPrivate() {
return _EndpointLogging.stringResponse(log, "GET /swagger/private",
@@ -74,9 +73,9 @@ public String swaggerPrivate() {
@Path("/prototyping")
@GET
- @Consumes({ MediaType.WILDCARD, MediaType.APPLICATION_JSON, "text/yaml" })
+ //@Consumes({ MediaType.WILDCARD, MediaType.APPLICATION_JSON_VALUE, "text/yaml" })
@Produces({
- MediaType.APPLICATION_JSON, "text/yaml"
+ MediaType.APPLICATION_JSON_VALUE, "text/yaml"
})
public String swaggerPrototyping() {
return _EndpointLogging.stringResponse(log, "GET /swagger/prototyping",
@@ -85,9 +84,9 @@ public String swaggerPrototyping() {
@Path("/public")
@GET
- @Consumes({ MediaType.WILDCARD, MediaType.APPLICATION_JSON, "text/yaml" })
+ //@Consumes({ MediaType.WILDCARD, MediaType.APPLICATION_JSON_VALUE, "text/yaml" })
@Produces({
- MediaType.APPLICATION_JSON, "text/yaml"
+ MediaType.APPLICATION_JSON_VALUE, "text/yaml"
})
public String swaggerPublic() {
return _EndpointLogging.stringResponse(log, "GET /swagger/public",
@@ -106,37 +105,33 @@ private String swagger(final Visibility visibility) {
}
private Format deriveFrom(final HttpHeaders httpHeaders) {
- final List<MediaType> acceptableMediaTypes = httpHeaders.getAcceptableMediaTypes();
+ var acceptableMediaTypes = httpHeaders.getAccept();
for (MediaType acceptableMediaType : acceptableMediaTypes) {
- if(acceptableMediaType.isCompatible(MediaType.APPLICATION_JSON_TYPE)) {
+ if(acceptableMediaType.isCompatibleWith(MediaType.APPLICATION_JSON)) {
return Format.JSON;
}
}
final MediaType applYaml = new MediaType("application", "yaml");
final MediaType textYaml = new MediaType("text", "yaml");
for (MediaType acceptableMediaType : acceptableMediaTypes) {
- if (acceptableMediaType.isCompatible(applYaml) ||
- acceptableMediaType.isCompatible(textYaml)) {
+ if (acceptableMediaType.isCompatibleWith(applYaml) ||
+ acceptableMediaType.isCompatibleWith(textYaml)) {
return Format.YAML;
}
}
return Format.JSON;
}
- @RequiredArgsConstructor
- static class MyCallable implements Callable<String> {
-
- private final SwaggerService swaggerService;
- private final Visibility visibility;
- private final Format format;
+ record MyCallable(
+ SwaggerService swaggerService,
+ Visibility visibility,
+ Format format) implements Callable<String> {
@Override
public String call() throws Exception {
-
// return format==Format.YAML
// ? _Strings.readFromResource(SwaggerSpecGenerator.class, "openapi-sample.yaml", StandardCharsets.UTF_8)
// : _Strings.readFromResource(SwaggerSpecGenerator.class, "openapi-sample.json", StandardCharsets.UTF_8);
-
return swaggerService.generateSwaggerSpec(visibility, format);
}
diff --git a/viewers/restfulobjects/viewer/src/main/java/org/apache/causeway/viewer/restfulobjects/viewer/resources/UserResourceServerside.java b/viewers/restfulobjects/viewer/src/main/java/org/apache/causeway/viewer/restfulobjects/viewer/resources/UserResourceServerside.java
index 472384b9a1e..cd9a4446cf9 100644
--- a/viewers/restfulobjects/viewer/src/main/java/org/apache/causeway/viewer/restfulobjects/viewer/resources/UserResourceServerside.java
+++ b/viewers/restfulobjects/viewer/src/main/java/org/apache/causeway/viewer/restfulobjects/viewer/resources/UserResourceServerside.java
@@ -22,7 +22,7 @@
import java.net.URISyntaxException;
import jakarta.ws.rs.Produces;
-import jakarta.ws.rs.core.MediaType;
+import org.springframework.http.MediaType;
import jakarta.ws.rs.core.Response;
import org.springframework.stereotype.Component;
@@ -52,7 +52,7 @@ public UserResourceServerside() {
}
@Override
- @Produces({ MediaType.APPLICATION_JSON, RestfulMediaType.APPLICATION_JSON_USER })
+ @Produces({ MediaType.APPLICATION_JSON_VALUE, RestfulMediaType.APPLICATION_JSON_USER })
public Response user() {
var resourceContext = createResourceContext(
@@ -85,7 +85,7 @@ public Response postUserNotAllowed() {
* Not part of the Restful Objects spec.
*/
@Override
- @Produces({ MediaType.APPLICATION_JSON, RestfulMediaType.APPLICATION_JSON_HOME_PAGE })
+ @Produces({ MediaType.APPLICATION_JSON_VALUE, RestfulMediaType.APPLICATION_JSON_HOME_PAGE })
public Response logout() {
var resourceContext = createResourceContext(
diff --git a/viewers/restfulobjects/viewer/src/main/java/org/apache/causeway/viewer/restfulobjects/viewer/resources/VersionResourceServerside.java b/viewers/restfulobjects/viewer/src/main/java/org/apache/causeway/viewer/restfulobjects/viewer/resources/VersionResourceServerside.java
index 23c2b241c4d..c46b78dc9b7 100644
--- a/viewers/restfulobjects/viewer/src/main/java/org/apache/causeway/viewer/restfulobjects/viewer/resources/VersionResourceServerside.java
+++ b/viewers/restfulobjects/viewer/src/main/java/org/apache/causeway/viewer/restfulobjects/viewer/resources/VersionResourceServerside.java
@@ -21,11 +21,7 @@
import java.util.List;
import jakarta.inject.Inject;
-import jakarta.ws.rs.GET;
import jakarta.ws.rs.Path;
-import jakarta.ws.rs.Produces;
-import jakarta.ws.rs.core.HttpHeaders;
-import jakarta.ws.rs.core.MediaType;
import jakarta.ws.rs.core.Response;
import org.springframework.stereotype.Component;
@@ -33,7 +29,6 @@
import org.apache.causeway.applib.annotation.Where;
import org.apache.causeway.viewer.restfulobjects.applib.JsonRepresentation;
import org.apache.causeway.viewer.restfulobjects.applib.RepresentationType;
-import org.apache.causeway.viewer.restfulobjects.applib.RestfulMediaType;
import org.apache.causeway.viewer.restfulobjects.applib.RestfulResponse;
import org.apache.causeway.viewer.restfulobjects.applib.RestfulResponse.HttpStatusCode;
import org.apache.causeway.viewer.restfulobjects.applib.version.VersionResource;
@@ -64,8 +59,8 @@ public VersionResourceServerside() {
}
@Override
- @GET
- @Produces({ MediaType.APPLICATION_JSON, RestfulMediaType.APPLICATION_JSON_VERSION })
+// @GET
+// @Produces({ MediaType.APPLICATION_JSON_VALUE, RestfulMediaType.APPLICATION_JSON_VERSION })
public Response version() {
var resourceContext = createResourceContext(
@@ -107,8 +102,8 @@ public Response postVersionNotAllowed() {
}
private void fakeRuntimeExceptionIfXFail(final ResourceContext resourceContext) {
- final HttpHeaders httpHeaders = resourceContext.httpHeaders();
- final List<String> requestHeader = httpHeaders.getRequestHeader("X-Fail");
+ var httpHeaders = resourceContext.httpHeaders();
+ final List<String> requestHeader = httpHeaders.getValuesAsList("X-Fail");
if (requestHeader != null && !requestHeader.isEmpty()) {
throw _EndpointLogging.error(log, "GET /version",
RestfulObjectsApplicationException.create(HttpStatusCode.METHOD_FAILURE));
diff --git a/viewers/restfulobjects/viewer/src/main/java/org/apache/causeway/viewer/restfulobjects/viewer/resources/serialization/SerializationStrategy.java b/viewers/restfulobjects/viewer/src/main/java/org/apache/causeway/viewer/restfulobjects/viewer/resources/serialization/SerializationStrategy.java
index e4b0582dbf1..7f7c47894f7 100644
--- a/viewers/restfulobjects/viewer/src/main/java/org/apache/causeway/viewer/restfulobjects/viewer/resources/serialization/SerializationStrategy.java
+++ b/viewers/restfulobjects/viewer/src/main/java/org/apache/causeway/viewer/restfulobjects/viewer/resources/serialization/SerializationStrategy.java
@@ -20,7 +20,7 @@
import java.util.Collection;
-import jakarta.ws.rs.core.MediaType;
+import org.springframework.http.MediaType;
import org.apache.causeway.commons.io.JsonUtils;
import org.apache.causeway.viewer.restfulobjects.applib.RepresentationType;
@@ -64,10 +64,10 @@ public MediaType type(final RepresentationType representationType) {
public static SerializationStrategy determineFrom(final Collection<MediaType> acceptableMediaTypes) {
for (MediaType acceptableMediaType : acceptableMediaTypes) {
- if(acceptableMediaType.isCompatible(MediaType.APPLICATION_JSON_TYPE)) {
+ if(acceptableMediaType.isCompatibleWith(MediaType.APPLICATION_JSON)) {
return SerializationStrategy.JSON;
}
- if(acceptableMediaType.isCompatible(MediaType.APPLICATION_XML_TYPE)) {
+ if(acceptableMediaType.isCompatibleWith(MediaType.APPLICATION_XML)) {
return SerializationStrategy.XML;
}
}