ResourceCategoryHelper.java

  1. /*
  2.  * The coLAB project
  3.  * Copyright (C) 2021-2023 AlbaSim, MEI, HEIG-VD, HES-SO
  4.  *
  5.  * Licensed under the MIT License
  6.  */
  7. package ch.colabproject.colab.api.controller.document;

  8. import ch.colabproject.colab.api.controller.RequestManager;
  9. import ch.colabproject.colab.api.controller.card.CardContentManager;
  10. import ch.colabproject.colab.api.controller.card.CardManager;
  11. import ch.colabproject.colab.api.controller.card.CardTypeManager;
  12. import ch.colabproject.colab.api.model.card.AbstractCardType;
  13. import ch.colabproject.colab.api.model.card.Card;
  14. import ch.colabproject.colab.api.model.card.CardContent;
  15. import ch.colabproject.colab.api.model.document.AbstractResource;
  16. import ch.colabproject.colab.api.model.document.ResourceRef;
  17. import ch.colabproject.colab.api.persistence.jpa.card.CardTypeDao;
  18. import ch.colabproject.colab.api.persistence.jpa.document.ResourceDao;
  19. import ch.colabproject.colab.generator.model.exceptions.HttpErrorMessage;
  20. import ch.colabproject.colab.generator.model.exceptions.MessageI18nKey;
  21. import java.util.List;
  22. import java.util.Objects;
  23. import javax.ejb.LocalBean;
  24. import javax.ejb.Stateless;
  25. import javax.inject.Inject;
  26. import org.apache.commons.lang3.StringUtils;
  27. import org.slf4j.Logger;
  28. import org.slf4j.LoggerFactory;

  29. /**
  30.  * Resource and resource reference category specific logic
  31.  *
  32.  * @author sandra
  33.  */
  34. @Stateless
  35. @LocalBean
  36. public class ResourceCategoryHelper {

  37.     /** logger */
  38.     private static final Logger logger = LoggerFactory.getLogger(ResourceCategoryHelper.class);

  39.     // *********************************************************************************************
  40.     // injections

  41.     /**
  42.      * Resource persistence handler
  43.      */
  44.     @Inject
  45.     private ResourceDao resourceDao;

  46.     /**
  47.      * Card type persistence handler
  48.      */
  49.     @Inject
  50.     private CardTypeDao cardTypeDao;

  51.     /**
  52.      * Resource / resource reference related logic
  53.      */
  54.     @Inject
  55.     private ResourceManager resourceManager;

  56.     /**
  57.      * Card type specific logic management
  58.      */
  59.     @Inject
  60.     private CardTypeManager cardTypeManager;

  61.     /**
  62.      * Card specific logic management
  63.      */
  64.     @Inject
  65.     private CardManager cardManager;

  66.     /**
  67.      * Card content specific logic management
  68.      */
  69.     @Inject
  70.     private CardContentManager cardContentManager;
  71.     /**
  72.      * TO sudo
  73.      */
  74.     @Inject
  75.     private RequestManager requestManager;

  76.     // *********************************************************************************************
  77.     // Category management
  78.     // *********************************************************************************************

  79.     /**
  80.      * Set the category of the resource.
  81.      * <p>
  82.      * Also update the resources that reference this one, as long as the category is synchronized
  83.      *
  84.      * @param resourceOrRefId the id of the resource / resource reference
  85.      * @param categoryName    the name of the category that apply to the resource / resource
  86.      *                        reference
  87.      */
  88.     public void changeCategory(Long resourceOrRefId, String categoryName) {
  89.         logger.debug("set category {} to abstract resource #{}", categoryName, resourceOrRefId);

  90.         AbstractResource resourceOrRef = resourceManager.assertAndGetResourceOrRef(resourceOrRefId);

  91.         String oldCategoryName = resourceOrRef.getCategory();
  92.         String newCategoryName = StringUtils.trimToNull(categoryName);

  93.         resourceOrRef.setCategory(newCategoryName);

  94.         requestManager.sudo(() -> {
  95.             // also change the resources based on the given one
  96.             // but only if the category is still synchronized
  97.             List<ResourceRef> directRefs = resourceDao.findDirectReferences(resourceOrRef);
  98.             for (ResourceRef ref : directRefs) {
  99.                 if (StringUtils.equals(ref.getCategory(), oldCategoryName)) {
  100.                     changeCategory(ref.getId(), newCategoryName);
  101.                 }

  102.             }
  103.         });
  104.     }

  105.     /**
  106.      * Set the category of a list of resources
  107.      *
  108.      * @param resourceOrRefIds the id of the resources / resource references
  109.      * @param categoryName     the name of the category that apply to the resource / resource
  110.      *                         reference
  111.      */
  112.     public void changeCategory(List<Long> resourceOrRefIds, String categoryName) {
  113.         logger.debug("set category {} to abstract resources #{}", categoryName, resourceOrRefIds);

  114.         if (resourceOrRefIds == null) {
  115.             throw HttpErrorMessage.dataError(MessageI18nKey.DATA_INTEGRITY_FAILURE);
  116.         }

  117.         resourceOrRefIds.stream().forEach(resOrRefId -> changeCategory(resOrRefId, categoryName));
  118.     }

  119.     /**
  120.      * Rename the category in a card type / card type reference
  121.      *
  122.      * @param cardTypeOrRefId the id of the card type / card type reference (scope of the renaming)
  123.      * @param oldName         the old name of the category
  124.      * @param newName         the new name of the category
  125.      */
  126.     public void renameCategoryInCardType(Long cardTypeOrRefId, String oldName,
  127.         String newName) {
  128.         logger.debug("rename category {} to {} in the abstract card type #{}", oldName, newName,
  129.             cardTypeOrRefId);

  130.         AbstractCardType cardTypeOrRef = cardTypeManager.assertAndGetCardTypeOrRef(cardTypeOrRefId);

  131.         requestManager.sudo(() -> {
  132.             renameCategory(cardTypeOrRef, oldName, newName);
  133.         });
  134.     }

  135.     /**
  136.      * Rename the category in a card
  137.      *
  138.      * @param cardId  the id of the card
  139.      * @param oldName the old name of the category
  140.      * @param newName the new name of the category
  141.      */
  142.     public void renameCategoryInCard(Long cardId, String oldName, String newName) {
  143.         logger.debug("rename category {} to {} in the card #{}", oldName, newName, cardId);

  144.         Card card = cardManager.assertAndGetCard(cardId);

  145.         requestManager.sudo(() -> {
  146.             renameCategory(card, oldName, newName);
  147.         });
  148.     }

  149.     /**
  150.      * Rename the category in a card content
  151.      *
  152.      * @param cardContentId the id of the card content
  153.      * @param oldName       the old name of the category
  154.      * @param newName       the new name of the category
  155.      */
  156.     public void renameCategoryInCardContent(Long cardContentId, String oldName, String newName) {
  157.         logger.debug("rename category {} to {} in the card content #{}", oldName, newName,
  158.             cardContentId);

  159.         CardContent cardContent = cardContentManager.assertAndGetCardContent(cardContentId);

  160.         requestManager.sudo(() -> {
  161.             renameCategory(cardContent, oldName, newName);
  162.         });
  163.     }

  164.     /**
  165.      * Rename the category in a card type / card type reference<br>
  166.      * And do it also for the implementing cards and for its reference card types
  167.      *
  168.      * @param cardTypeOrRef the card type / card type reference (scope of the renaming)
  169.      * @param oldName       the old name of the category
  170.      * @param newName       the new name of the category
  171.      */
  172.     private void renameCategory(AbstractCardType cardTypeOrRef,
  173.         String oldName, String newName) {
  174.         cardTypeOrRef.getDirectAbstractResources().stream()
  175.             .forEach(resourceOrRef -> renameCategoryIfMatch(resourceOrRef, oldName, newName));

  176.         cardTypeOrRef.getImplementingCards().stream()
  177.             .forEach(card -> renameCategory(card, oldName, newName));

  178.         cardTypeDao.findDirectReferences(cardTypeOrRef).stream()
  179.             .forEach(cardRef -> renameCategory(cardRef, oldName, newName));
  180.     }

  181.     /**
  182.      * Rename the category in a card<br>
  183.      * And do it also for each card's variants
  184.      *
  185.      * @param card    the card (scope of the renaming)
  186.      * @param oldName the old name of the category
  187.      * @param newName the new name of the category
  188.      */
  189.     private void renameCategory(Card card, String oldName, String newName) {
  190.         card.getDirectAbstractResources().stream()
  191.             .forEach(resourceOrRef -> renameCategoryIfMatch(resourceOrRef, oldName, newName));

  192.         card.getContentVariants().stream()
  193.             .forEach(cardContent -> renameCategory(cardContent, oldName, newName));
  194.     }

  195.     /**
  196.      * Rename the category in a card content<br>
  197.      * And do it also for each sub cards
  198.      *
  199.      * @param cardContent the card content (scope of the renaming)
  200.      * @param oldName     the old name of the category
  201.      * @param newName     the new name of the category
  202.      */
  203.     private void renameCategory(CardContent cardContent, String oldName, String newName) {
  204.         cardContent.getDirectAbstractResources().stream()
  205.             .forEach(resourceOrRef -> renameCategoryIfMatch(resourceOrRef, oldName, newName));

  206.         cardContent.getSubCards().stream().forEach(card -> renameCategory(card, oldName, newName));
  207.     }

  208.     /**
  209.      * Replace the category of the resource if it matches the oldName
  210.      *
  211.      * @param resourceOrRef the resource or resource reference
  212.      * @param oldName       the old name of the category
  213.      * @param newName       the new name of the category
  214.      */
  215.     private void renameCategoryIfMatch(AbstractResource resourceOrRef, String oldName,
  216.         String newName) {
  217.         if (Objects.equals(
  218.             StringUtils.trimToNull(resourceOrRef.getCategory()),
  219.             StringUtils.trimToNull(oldName))) {
  220.             resourceOrRef.setCategory(StringUtils.trimToNull(newName));
  221.         }
  222.     }
  223. }