This is an automated email from the ASF dual-hosted git repository. danhaywood pushed a commit to branch CAUSEWAY-3676 in repository https://gitbox.apache.org/repos/asf/causeway.git
commit 4d3433f237fefa94677c2c7dc46989093e17bfba Author: danhaywood <[email protected]> AuthorDate: Sat Feb 17 12:21:32 2024 +0000 CAUSEWAY-3676: extends controller to download .layout grid --- .../viewer/controller/ResourceController.java | 55 +++++++++++++++++----- 1 file changed, 44 insertions(+), 11 deletions(-) diff --git a/viewers/graphql/viewer/src/main/java/org/apache/causeway/viewer/graphql/viewer/controller/ResourceController.java b/viewers/graphql/viewer/src/main/java/org/apache/causeway/viewer/graphql/viewer/controller/ResourceController.java index 2c596e135f..7f82ab8cf5 100644 --- a/viewers/graphql/viewer/src/main/java/org/apache/causeway/viewer/graphql/viewer/controller/ResourceController.java +++ b/viewers/graphql/viewer/src/main/java/org/apache/causeway/viewer/graphql/viewer/controller/ResourceController.java @@ -1,13 +1,19 @@ package org.apache.causeway.viewer.graphql.viewer.controller; +import java.util.Objects; import java.util.Optional; import javax.inject.Inject; +import org.apache.causeway.applib.layout.grid.Grid; +import org.apache.causeway.commons.io.JaxbUtils; +import org.apache.causeway.core.metamodel.facets.object.grid.GridFacet; + import org.springframework.http.ContentDisposition; import org.springframework.http.HttpHeaders; import org.springframework.http.MediaType; import org.springframework.http.ResponseEntity; +import org.springframework.lang.Nullable; import org.springframework.util.MimeType; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PathVariable; @@ -24,6 +30,7 @@ import org.apache.causeway.core.metamodel.spec.feature.OneToOneAssociation; import lombok.RequiredArgsConstructor; import lombok.Value; +import lombok.val; @RestController() @RequestMapping("/graphql/object") @@ -37,9 +44,9 @@ public class ResourceController { public ResponseEntity<byte[]> propertyBlobBytes( @PathVariable final String logicalTypeName, @PathVariable final String id, - @PathVariable final String propertyId) { - - return valueOf(logicalTypeName, id, propertyId) + @PathVariable final String propertyId + ) { + return valueOfProperty(logicalTypeName, id, propertyId) .filter(Blob.class::isInstance) .map(Blob.class::cast) .map(blob -> ResponseEntity.ok() @@ -54,9 +61,9 @@ public class ResourceController { public ResponseEntity<CharSequence> propertyClobChars( @PathVariable final String logicalTypeName, @PathVariable final String id, - @PathVariable final String propertyId) { - - return valueOf(logicalTypeName, id, propertyId) + @PathVariable final String propertyId + ) { + return valueOfProperty(logicalTypeName, id, propertyId) .filter(Clob.class::isInstance) .map(Clob.class::cast) .map(clob -> ResponseEntity.ok() @@ -67,9 +74,32 @@ public class ResourceController { .orElse(ResponseEntity.notFound().build()); } - private Optional<Object> valueOf(String logicalTypeName, String id, String propertyId) { - return bookmarkService.lookup(Bookmark.forLogicalTypeNameAndIdentifier(logicalTypeName, id)) - .map(objectManager::adapt) + @GetMapping(value = "/{logicalTypeName}:{id}/grid") + public ResponseEntity<String> grid( + @PathVariable final String logicalTypeName, + @PathVariable final String id + ) { + return lookup(logicalTypeName, id) + .map(ResourceController::gridOf) + .filter(Objects::nonNull) + .map(JaxbUtils::toStringUtf8) + .map(x -> x.replaceAll("(\r\n)", "\n")) + .map(gridText -> ResponseEntity.ok() + .contentType(MediaType.APPLICATION_XML) + .header(HttpHeaders.CONTENT_DISPOSITION, ContentDisposition.attachment().filename(logicalTypeName + ".layout.xml").build().toString()) + .contentLength(gridText.length()) + .body(gridText)) + .orElse(ResponseEntity.notFound().build()); + } + + @Nullable + private static Grid gridOf(ManagedObject managedObject) { + val facet = managedObject.getSpecification().getFacet(GridFacet.class); + return facet != null ? facet.getGrid(managedObject) : null; + } + + private Optional<Object> valueOfProperty(String logicalTypeName, String id, String propertyId) { + return lookup(logicalTypeName, id) .map(managedObject -> ManagedObjectAndPropertyIfAny.of(managedObject, managedObject.getSpecification().getProperty(propertyId))) .filter(ManagedObjectAndPropertyIfAny::isPropertyPresent) .map(ManagedObjectAndProperty::of) @@ -77,6 +107,11 @@ public class ResourceController { .map(ManagedObject::getPojo); } + private Optional<ManagedObject> lookup(String logicalTypeName, String id) { + return bookmarkService.lookup(Bookmark.forLogicalTypeNameAndIdentifier(logicalTypeName, id)) + .map(objectManager::adapt); + } + @Value(staticConstructor = "of") private static class ManagedObjectAndPropertyIfAny { ManagedObject owningObject; @@ -101,6 +136,4 @@ public class ResourceController { return property.get(owningObject); } } - - }
