From 8472cb7e4531c056f2d1ea59f9760b9d2dbd8667 Mon Sep 17 00:00:00 2001 From: Jens Pelzetter Date: Thu, 6 Aug 2020 16:21:30 +0200 Subject: [PATCH] Optmiziations for the RESTful API managing containers of page models --- .../libreccm/api/pagemodels/Containers.java | 61 +++++++------------ .../api/pagemodels/dto/ContainerModelDto.java | 8 +++ .../libreccm/pagemodel/ContainerModel.java | 19 ++++-- .../pagemodel/ContainerModelRepository.java | 49 +++++++++++++++ 4 files changed, 95 insertions(+), 42 deletions(-) diff --git a/ccm-core/src/main/java/org/libreccm/api/pagemodels/Containers.java b/ccm-core/src/main/java/org/libreccm/api/pagemodels/Containers.java index 169e2d249..7ea83562a 100644 --- a/ccm-core/src/main/java/org/libreccm/api/pagemodels/Containers.java +++ b/ccm-core/src/main/java/org/libreccm/api/pagemodels/Containers.java @@ -18,6 +18,8 @@ */ package org.libreccm.api.pagemodels; +import org.libreccm.api.dto.ListView; +import org.libreccm.api.pagemodels.dto.ContainerModelDto; import org.libreccm.core.CoreConstants; import org.libreccm.pagemodel.ContainerModel; import org.libreccm.pagemodel.ContainerModelRepository; @@ -29,21 +31,20 @@ import org.libreccm.web.CcmApplication; import java.net.URI; import java.util.Optional; +import java.util.stream.Collectors; import javax.enterprise.context.RequestScoped; import javax.inject.Inject; -import javax.json.Json; -import javax.json.JsonArray; -import javax.json.JsonArrayBuilder; -import javax.json.JsonObject; import javax.transaction.Transactional; import javax.ws.rs.Consumes; import javax.ws.rs.DELETE; +import javax.ws.rs.DefaultValue; import javax.ws.rs.GET; import javax.ws.rs.PUT; import javax.ws.rs.Path; import javax.ws.rs.PathParam; import javax.ws.rs.Produces; +import javax.ws.rs.QueryParam; import javax.ws.rs.core.MediaType; import javax.ws.rs.core.Response; @@ -73,6 +74,8 @@ public class Containers { * which the {@link PageModel} belongs. * @param pageModelName The name of the {@link PageModel} of which the * containers are retrieved. + * @param limit + * @param offset * * @return A JSON array containing the data of all {@link ContainerModel}s * of the {@link PageModel} identified by {@code pageModelName} of @@ -84,9 +87,11 @@ public class Containers { @Transactional(Transactional.TxType.REQUIRED) @AuthorizationRequired @RequiresPrivilege(CoreConstants.PRIVILEGE_ADMIN) - public JsonArray getContainers( + public ListView getContainers( @PathParam("appName") final String appName, - @PathParam("pageModelName") final String pageModelName + @PathParam("pageModelName") final String pageModelName, + @QueryParam("limit") @DefaultValue("20") final int limit, + @QueryParam("offset") @DefaultValue("0") final int offset ) { final CcmApplication app = controller.findCcmApplication( String.format("/%s/", appName) @@ -96,14 +101,15 @@ public class Containers { app, pageModelName ); - final JsonArrayBuilder arrayBuilder = Json.createArrayBuilder(); - pageModel - .getContainers() - .stream() - .map(containerModel -> mapContainerModelToJson(containerModel)) - .forEach(arrayBuilder::add); - - return arrayBuilder.build(); + return new ListView<>( + containerModelRepo + .findContainersOfPageModelAsStream(pageModel, 0, 0) + .map(model -> new ContainerModelDto(model)) + .collect(Collectors.toList()), + containerModelRepo.countContainersOfPageModel(pageModel), + limit, + offset + ); } /** @@ -124,7 +130,7 @@ public class Containers { @Transactional(Transactional.TxType.REQUIRED) @AuthorizationRequired @RequiresPrivilege(CoreConstants.PRIVILEGE_ADMIN) - public JsonObject getContainer( + public ContainerModelDto getContainer( @PathParam("appName") final String appName, @PathParam("pageModelName") final String pageModelName, @PathParam("containerKey") final String containerKey @@ -141,7 +147,7 @@ public class Containers { app, pageModel, containerKey ); - return mapContainerModelToJson(container); + return new ContainerModelDto(container); } /** @@ -176,7 +182,7 @@ public class Containers { @PathParam("appName") final String appName, @PathParam("pageModelName") final String pageModelName, @PathParam("containerKey") final String containerKey, - final JsonObject containerModelData + final ContainerModelDto containerModelData ) { final CcmApplication app = controller.findCcmApplication( String.format("/%s/", appName) @@ -277,25 +283,4 @@ public class Containers { ) ).build(); } - - /** - * Helper method for mapping a {@link ContainerModel} to JSON: - * - * @param containerModel The {@link ContainerModel} to map. - * - * @return A {@link JsonObject} containing the data of the - * {@link ContainerModel}. - */ - private JsonObject mapContainerModelToJson( - final ContainerModel containerModel) { - - return Json - .createObjectBuilder() - .add("containerId", Long.toString(containerModel.getContainerId())) - .add("uuid", containerModel.getUuid()) - .add("containerUuid", containerModel.getContainerUuid()) - .add("key", containerModel.getKey()) - .build(); - } - } diff --git a/ccm-core/src/main/java/org/libreccm/api/pagemodels/dto/ContainerModelDto.java b/ccm-core/src/main/java/org/libreccm/api/pagemodels/dto/ContainerModelDto.java index 391843fff..17dd1276f 100644 --- a/ccm-core/src/main/java/org/libreccm/api/pagemodels/dto/ContainerModelDto.java +++ b/ccm-core/src/main/java/org/libreccm/api/pagemodels/dto/ContainerModelDto.java @@ -45,6 +45,14 @@ public class ContainerModelDto { this.key = fromContainerModel.getKey(); } + public long getContainerId() { + return containerId; + } + + public void setContainerId(final long containerId) { + this.containerId = containerId; + } + public String getUuid() { return uuid; } diff --git a/ccm-core/src/main/java/org/libreccm/pagemodel/ContainerModel.java b/ccm-core/src/main/java/org/libreccm/pagemodel/ContainerModel.java index 2b18e1280..b05bfbdd2 100644 --- a/ccm-core/src/main/java/org/libreccm/pagemodel/ContainerModel.java +++ b/ccm-core/src/main/java/org/libreccm/pagemodel/ContainerModel.java @@ -59,10 +59,21 @@ import javax.xml.bind.annotation.XmlTransient; @Entity @Table(name = "PAGE_MODEL_CONTAINER_MODELS", schema = CoreConstants.DB_SCHEMA) @NamedQueries({ - @NamedQuery(name = "ContainerModel.findByKeyAndPage", - query = "SELECT c FROM ContainerModel c " - + "WHERE c.key = :key " - + "AND c.pageModel = :pageModel") + @NamedQuery( + name = "ContainerModel.findContainersOfPageModel", + query = "SELECT c FROM ContainerModel c WHERE c.pageModel = :pageModel" + ), + @NamedQuery( + name = "ContainerModel.countContainersOfPageModel", + query = "SELECT COUNT(c) FROM ContainerModel c " + + "WHERE c.pageModel = :pageModel" + ), + @NamedQuery( + name = "ContainerModel.findByKeyAndPage", + query = "SELECT c FROM ContainerModel c " + + "WHERE c.key = :key " + + "AND c.pageModel = :pageModel" + ) }) @XmlRootElement(name = "container-model") public class ContainerModel implements Serializable { diff --git a/ccm-core/src/main/java/org/libreccm/pagemodel/ContainerModelRepository.java b/ccm-core/src/main/java/org/libreccm/pagemodel/ContainerModelRepository.java index 7d5cb7a26..53565f5de 100644 --- a/ccm-core/src/main/java/org/libreccm/pagemodel/ContainerModelRepository.java +++ b/ccm-core/src/main/java/org/libreccm/pagemodel/ContainerModelRepository.java @@ -23,8 +23,10 @@ import org.libreccm.core.CoreConstants; import org.libreccm.security.AuthorizationRequired; import org.libreccm.security.RequiresPrivilege; +import java.util.List; import java.util.Optional; import java.util.UUID; +import java.util.stream.Stream; import javax.enterprise.context.RequestScoped; import javax.persistence.NoResultException; @@ -83,6 +85,53 @@ public class ContainerModelRepository } } + @Transactional(Transactional.TxType.REQUIRED) + public List findContainersOfPageModelAsList( + final PageModel pageModel, + final int limit, + final int offset + ) { + return getEntityManager() + .createNamedQuery( + "ContainerModel.findContainersOfPageModel", + ContainerModel.class + ) + .setParameter("pageModel", pageModel) + .setMaxResults(limit) + .setFirstResult(offset) + .getResultList(); + } + + @Transactional(Transactional.TxType.REQUIRED) + public Stream findContainersOfPageModelAsStream( + final PageModel pageModel, + final int limit, + final int offset + ) { + return getEntityManager() + .createNamedQuery( + "ContainerModel.findContainersOfPageModel", + ContainerModel.class + ) + .setParameter("pageModel", pageModel) + .setMaxResults(limit) + .setFirstResult(offset) + .getResultStream(); + } + + @Transactional(Transactional.TxType.REQUIRED) + public long countContainersOfPageModel( + final PageModel pageModel + ) { + return getEntityManager() + .createNamedQuery( + "ContainerModel.countContainersOfPageModel", + Long.class + ) + .setParameter("pageModel", pageModel) + .getSingleResult(); + } + @Transactional(Transactional.TxType.REQUIRED) public Optional findContainerByKeyAndPageModel( final String key, final PageModel pageModel) {