From acfa6b7b5b08a78100f2d4e5b90250d15d0a93a6 Mon Sep 17 00:00:00 2001 From: Jens Pelzetter Date: Sat, 6 Jun 2020 17:04:33 +0200 Subject: [PATCH] Some methods for the CategoriesApi Former-commit-id: 4e688e4fcf200be8770dc5946f755afae027bd0b --- .../admin/categorization/CategoriesApi.java | 209 ++++++++++++++---- .../api/admin/categorization/DomainsApi.java | 1 - .../org/libreccm/categorization/Category.java | 6 + .../categorization/CategoryRepository.java | 50 ++++- 4 files changed, 222 insertions(+), 44 deletions(-) diff --git a/ccm-core/src/main/java/org/libreccm/api/admin/categorization/CategoriesApi.java b/ccm-core/src/main/java/org/libreccm/api/admin/categorization/CategoriesApi.java index 9d5cae72a..893aeb3fb 100644 --- a/ccm-core/src/main/java/org/libreccm/api/admin/categorization/CategoriesApi.java +++ b/ccm-core/src/main/java/org/libreccm/api/admin/categorization/CategoriesApi.java @@ -21,12 +21,16 @@ package org.libreccm.api.admin.categorization; import org.libreccm.api.admin.categorization.dto.CategorizationData; import org.libreccm.api.admin.categorization.dto.CategoryData; import org.libreccm.api.dto.ListView; +import org.libreccm.categorization.Category; import org.libreccm.categorization.CategoryManager; import org.libreccm.categorization.CategoryRepository; +import org.libreccm.categorization.Domain; import org.libreccm.core.CoreConstants; import org.libreccm.security.AuthorizationRequired; import org.libreccm.security.RequiresPrivilege; +import java.util.stream.Collectors; + import javax.enterprise.context.RequestScoped; import javax.inject.Inject; import javax.transaction.Transactional; @@ -40,7 +44,11 @@ import javax.ws.rs.Path; import javax.ws.rs.PathParam; import javax.ws.rs.Produces; import javax.ws.rs.QueryParam; +import javax.ws.rs.WebApplicationException; +import javax.ws.rs.core.Context; import javax.ws.rs.core.MediaType; +import javax.ws.rs.core.Response; +import javax.ws.rs.core.UriInfo; /** * @@ -50,44 +58,17 @@ import javax.ws.rs.core.MediaType; @Path("/categories") public class CategoriesApi { + @Context + private UriInfo uriInfo; + @Inject private CategoryManager categoryManager; - + @Inject private CategoryRepository categoryRepository; - + @Inject private CategorizationApiRepository repository; - - @GET - @Path("/{domainIdentifier}/{path:^[\\w\\-/]+$}") - @Produces(MediaType.APPLICATION_JSON) - @AuthorizationRequired - @RequiresPrivilege(CoreConstants.PRIVILEGE_ADMIN) - @Transactional(Transactional.TxType.REQUIRED) - public ListView getCategories( - @PathParam("domainIdentifier") final String domainIdentifierParam, - @PathParam("path") final String categoryPathTokens - ) { - - - throw new UnsupportedOperationException(); - } - - @POST - @Path("/{domainIdentifier}/{path:^[\\w\\-/]+$}") - @Produces(MediaType.APPLICATION_JSON) - @Consumes(MediaType.APPLICATION_JSON) - @AuthorizationRequired - @RequiresPrivilege(CoreConstants.PRIVILEGE_ADMIN) - @Transactional(Transactional.TxType.REQUIRED) - public ListView addNewSubCategory( - @PathParam("domainIdentifier") final String domainIdentifierParam, - @PathParam("path") final String categoryPathTokens, - final CategoryData categoryData - ) { - throw new UnsupportedOperationException(); - } @GET @Path("/{domainIdentifier}/{path:^[\\w\\-/]+$}") @@ -97,9 +78,23 @@ public class CategoriesApi { @Transactional(Transactional.TxType.REQUIRED) public CategoryData getCategory( @PathParam("domainIdentifier") final String domainIdentifierParam, - @PathParam("path") final String categoryPathTokens + @PathParam("path") final String categoryPath ) { - throw new UnsupportedOperationException(); + final Domain domain = repository.findDomain(domainIdentifierParam); + final Category category = categoryRepository + .findByPath(domain, categoryPath) + .orElseThrow( + () -> new WebApplicationException( + String.format( + "No category with path %s in Domain %s found.", + categoryPath, + domain.getDomainKey() + ), + Response.Status.NOT_FOUND + ) + ); + + return new CategoryData(category); } @GET @@ -111,7 +106,18 @@ public class CategoriesApi { public CategoryData getCategory( @PathParam("categoryId") final long categoryId ) { - throw new UnsupportedOperationException(); + return new CategoryData( + categoryRepository + .findById(categoryId) + .orElseThrow( + () -> new WebApplicationException( + String.format( + "No Category with ID %d found.", + categoryId + ) + ) + ) + ); } @GET @@ -123,7 +129,18 @@ public class CategoriesApi { public CategoryData getCategory( @PathParam("categoryId") final String categoryUuid ) { - throw new UnsupportedOperationException(); + return new CategoryData( + categoryRepository + .findByUuid(categoryUuid) + .orElseThrow( + () -> new WebApplicationException( + String.format( + "No Category with UUID %s found.", + categoryUuid + ) + ) + ) + ); } @PUT @@ -215,11 +232,33 @@ public class CategoriesApi { @Transactional(Transactional.TxType.REQUIRED) public ListView getSubCategories( @PathParam("domainIdentifier") final String domainIdentifierParam, - @PathParam("path") final String categoryPathTokens, + @PathParam("path") final String categoryPath, @QueryParam("limit") @DefaultValue("20") final int limit, @QueryParam("offset") @DefaultValue("20") final int offset ) { - throw new UnsupportedOperationException(); + final Domain domain = repository.findDomain(domainIdentifierParam); + final Category category = categoryRepository + .findByPath(domain, categoryPath) + .orElseThrow( + () -> new WebApplicationException( + String.format( + "No category with path %s in Domain %s found.", + categoryPath, + domain.getDomainKey() + ), + Response.Status.NOT_FOUND + ) + ); + + return new ListView<>( + categoryRepository + .findSubCategoriesAsStream(category, limit, offset) + .map(CategoryData::new) + .collect(Collectors.toList()), + categoryRepository.countSubCategories(category), + limit, + offset + ); } @GET @@ -233,11 +272,30 @@ public class CategoriesApi { @QueryParam("limit") @DefaultValue("20") final int limit, @QueryParam("offset") @DefaultValue("20") final int offset ) { - throw new UnsupportedOperationException(); + final Category category = categoryRepository + .findById(categoryId) + .orElseThrow( + () -> new WebApplicationException( + String.format( + "No Category with ID %d found.", + categoryId + ) + ) + ); + + return new ListView<>( + categoryRepository + .findSubCategoriesAsStream(category, limit, offset) + .map(CategoryData::new) + .collect(Collectors.toList()), + categoryRepository.countSubCategories(category), + limit, + offset + ); } @GET - @Path("/UUID-{categoryId}/subcategories") + @Path("/UUID-{categoryUid}/subcategories") @Produces(MediaType.APPLICATION_JSON) @AuthorizationRequired @RequiresPrivilege(CoreConstants.PRIVILEGE_ADMIN) @@ -247,7 +305,76 @@ public class CategoriesApi { @QueryParam("limit") @DefaultValue("20") final int limit, @QueryParam("offset") @DefaultValue("20") final int offset ) { - throw new UnsupportedOperationException(); + final Category category = categoryRepository + .findByUuid(uuid) + .orElseThrow( + () -> new WebApplicationException( + String.format( + "No Category with UUID %s found.", uuid + ) + ) + ); + + return new ListView<>( + categoryRepository + .findSubCategoriesAsStream(category, limit, offset) + .map(CategoryData::new) + .collect(Collectors.toList()), + categoryRepository.countSubCategories(category), + limit, + offset + ); + } + + @POST + @Path("/{domainIdentifier}/{path:^[\\w\\-/]+$}/subcategories") + @Produces(MediaType.APPLICATION_JSON) + @Consumes(MediaType.APPLICATION_JSON) + @AuthorizationRequired + @RequiresPrivilege(CoreConstants.PRIVILEGE_ADMIN) + @Transactional(Transactional.TxType.REQUIRED) + public Response addNewSubCategory( + @PathParam("domainIdentifier") final String domainIdentifierParam, + @PathParam("path") final String categoryPath, + final CategoryData categoryData + ) { + final Domain domain = repository.findDomain(domainIdentifierParam); + final Category category = categoryRepository + .findByPath(domain, categoryPath) + .orElseThrow( + () -> new WebApplicationException( + String.format( + "No category with path %s in Domain %s found.", + categoryPath, + domain.getDomainKey() + ), + Response.Status.NOT_FOUND + ) + ); + + final Category newCategory = new Category(); + newCategory.setAbstractCategory(categoryData.isAbstractCategory()); + newCategory.setCategoryOrder(categoryData.getCategoryOrder()); + newCategory.setDescription(categoryData.getDescription()); + newCategory.setEnabled(categoryData.isEnabled()); + newCategory.setName(categoryData.getName()); + newCategory.setTitle(categoryData.getTitle()); + newCategory.setUniqueId(categoryData.getUniqueId()); + newCategory.setVisible(categoryData.isVisible()); + + categoryRepository.save(category); + categoryManager.addSubCategoryToCategory(newCategory, category); + + return Response + .created( + uriInfo + .getBaseUriBuilder() + .path(domain.getDomainKey()) + .path(categoryPath) + .path(newCategory.getName()) + .build() + ) + .build(); } @GET diff --git a/ccm-core/src/main/java/org/libreccm/api/admin/categorization/DomainsApi.java b/ccm-core/src/main/java/org/libreccm/api/admin/categorization/DomainsApi.java index 891484ae4..5603576c8 100644 --- a/ccm-core/src/main/java/org/libreccm/api/admin/categorization/DomainsApi.java +++ b/ccm-core/src/main/java/org/libreccm/api/admin/categorization/DomainsApi.java @@ -36,7 +36,6 @@ import java.time.Instant; import java.time.format.DateTimeFormatter; import java.time.temporal.TemporalAccessor; import java.util.Date; -import java.util.List; import java.util.stream.Collectors; import javax.enterprise.context.RequestScoped; diff --git a/ccm-core/src/main/java/org/libreccm/categorization/Category.java b/ccm-core/src/main/java/org/libreccm/categorization/Category.java index e69f58276..e004bad07 100644 --- a/ccm-core/src/main/java/org/libreccm/categorization/Category.java +++ b/ccm-core/src/main/java/org/libreccm/categorization/Category.java @@ -104,6 +104,12 @@ import javax.xml.bind.annotation.XmlRootElement; query = "SELECT (CASE WHEN COUNT(c) > 0 THEN true ELSE false END) " + "FROM Categorization c " + "WHERE c.category = :category"), + @NamedQuery( + name = "Category.findSubCategories", + query = "SELECT c FROM Category c " + + "WHERE c.parentCategory = :category " + + "ORDER BY c.categoryOrder" + ), @NamedQuery( name = "Category.countSubCategories", query = "SELECT COUNT(c) FROM Category c " diff --git a/ccm-core/src/main/java/org/libreccm/categorization/CategoryRepository.java b/ccm-core/src/main/java/org/libreccm/categorization/CategoryRepository.java index 4210d315f..a89a04a41 100644 --- a/ccm-core/src/main/java/org/libreccm/categorization/CategoryRepository.java +++ b/ccm-core/src/main/java/org/libreccm/categorization/CategoryRepository.java @@ -31,9 +31,12 @@ import javax.inject.Inject; import javax.persistence.NoResultException; import javax.persistence.TypedQuery; import javax.transaction.Transactional; + import java.util.List; +import java.util.Objects; import java.util.Optional; import java.util.UUID; +import java.util.stream.Stream; /** * Provides CRUB operations for {@link Category} objects. @@ -65,7 +68,7 @@ public class CategoryRepository extends AbstractEntityRepository public Class getEntityClass() { return Category.class; } - + @Override public String getIdAttributeName() { return "objectId"; @@ -75,7 +78,7 @@ public class CategoryRepository extends AbstractEntityRepository public Long getIdOfEntity(final Category entity) { return entity.getObjectId(); } - + @Override public boolean isNew(final Category entity) { return entity.getObjectId() == 0; @@ -197,6 +200,49 @@ public class CategoryRepository extends AbstractEntityRepository return Optional.of(current); } + @Transactional(Transactional.TxType.REQUIRED) + public List findSubCategories( + final Category ofCategory, final int limit, final int offset + ) { + return getEntityManager() + .createNamedQuery("Category.findSubCategories", Category.class) + .setParameter("category", ofCategory) + .setMaxResults(limit) + .setFirstResult(offset) + .getResultList(); + } + + @Transactional(Transactional.TxType.REQUIRED) + public Stream findSubCategoriesAsStream( + final Category ofCategory, final int limit, final int offset + ) { + return getEntityManager() + .createNamedQuery("Category.findSubCategories", Category.class) + .setParameter( + "category", + Objects.requireNonNull( + ofCategory, + "Can't retrieve subcategories for Category null." + ) + ) + .setMaxResults(limit) + .setFirstResult(offset) + .getResultStream(); + } + + @Transactional(Transactional.TxType.REQUIRED) + public long countSubCategories(final Category ofCategory) { + return getEntityManager() + .createNamedQuery("Category.countSubCategories", Long.class) + .setParameter( + "category", + Objects.requireNonNull( + ofCategory, + "Can't retrieve subcategories for Category null." + ) + ).getSingleResult(); + } + private boolean filterCategoryByName(final Category category, final String name) { LOGGER.debug("#findByPath(Domain, String): c = {}",