package eu.dnetlib.uoamonitorservice.controllers; import eu.dnetlib.uoaadmintoolslibrary.handlers.utils.RolesUtils; import eu.dnetlib.uoamonitorservice.dao.*; import eu.dnetlib.uoamonitorservice.entities.*; import eu.dnetlib.uoamonitorservice.handlers.EntityNotFoundException; import eu.dnetlib.uoaadmintoolslibrary.handlers.ForbiddenException; import eu.dnetlib.uoamonitorservice.handlers.PathNotValidException; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.web.bind.annotation.*; import java.util.ArrayList; import java.util.Date; import java.util.Iterator; import java.util.List; @RestController @CrossOrigin(origins = "*") public class CategoryController { private final Logger log = LogManager.getLogger(this.getClass()); @Autowired private RolesUtils rolesUtils; @Autowired private StakeholderDAO stakeholderDAO; @Autowired private TopicDAO topicDAO; @Autowired private CategoryDAO categoryDAO; @Autowired private SubCategoryDAO subCategoryDAO; @Autowired private SubCategoryController subCategoryController; public Category buildCategory(Category categoryFull) { Category category = new Category<>(categoryFull); List subCategories = new ArrayList<>(); List subCategoriesFull = new ArrayList<>(); for(SubCategory> subCategory : categoryFull.getSubCategories()) { SubCategory> subcategoryFull = subCategoryController.buildSubCategory(subCategory); subCategoriesFull.add(subcategoryFull); subCategories.add(subcategoryFull.getId()); } categoryFull.setSubCategories(subCategoriesFull); category.setSubCategories(subCategories); Date date = new Date(); category.setCreationDate(date); category.setUpdateDate(date); categoryFull.setCreationDate(date); categoryFull.setUpdateDate(date); categoryDAO.save(category); categoryFull.setId(category.getId()); return categoryFull; } @PreAuthorize("isAuthenticated()") @RequestMapping(value = "/{stakeholderId}/{topicId}/save", method = RequestMethod.POST) public Category saveCategory(@PathVariable("stakeholderId") String stakeholderId, @PathVariable("topicId") String topicId, @RequestBody Category categoryFull) { log.debug("save category"); log.debug("Alias: "+categoryFull.getAlias() + " - Id: "+categoryFull.getId() + " - Stakeholder: "+stakeholderId + " - Topic: "+topicId); Stakeholder stakeholder = stakeholderDAO.findById(stakeholderId); if(stakeholder != null) { if(!rolesUtils.hasUpdateAuthority(stakeholder.getType(), stakeholder.getAlias())) { // EXCEPTION - Access denied throw new ForbiddenException("Save Category: You are not authorized to update stakeholder with id: "+stakeholderId); } Category oldCategory = null; if(categoryFull.getId() != null) { oldCategory = categoryDAO.findById(categoryFull.getId()); if(oldCategory == null) { // EXCEPTION - Category not found throw new EntityNotFoundException("save category: Category with id: " + categoryFull.getId() + " not found"); } } Topic topic = topicDAO.findById(topicId); if(topic != null) { if(stakeholder.getTopics().contains(topicId)) { Category category = new Category<>(categoryFull); Date date = new Date(); category.setUpdateDate(date); categoryFull.setUpdateDate(date); List subCategories = new ArrayList<>(); // if category not exists (no id), create a new default subcategory, identical to category if(categoryFull.getId() == null) { category.setCreationDate(date); categoryFull.setCreationDate(date); SubCategory subCategory = new SubCategory<>(); subCategory.createOverviewSubCategory(categoryFull); subCategoryDAO.save(subCategory); List subCategoriesFull = categoryFull.getSubCategories(); subCategoriesFull.add(subCategory); for(SubCategory oldSubCategory : subCategoriesFull) { subCategories.add(oldSubCategory.getId()); } } else { for(String subCategoryId : oldCategory.getSubCategories()) { SubCategory subCategory = subCategoryDAO.findById(subCategoryId); if (subCategory == null) { // EXCEPTION - SubCategory not found throw new EntityNotFoundException("Save category: SubCategory with id: "+subCategoryId+" not found (subcategory exists in category: "+category.getId()+")"); } subCategories.add(subCategory.getId()); } } category.setSubCategories(subCategories); if(stakeholder.getDefaultId() == null) { if(categoryFull.getId() == null) { categoryDAO.save(category); onSaveDefaultCategory(category, topicId); } else { onUpdateDefaultCategory(category, oldCategory); categoryDAO.save(category); } } else { categoryDAO.save(category); } List categories = topic.getCategories(); int index = categories.indexOf(category.getId()); if(index == -1) { categories.add(category.getId()); topicDAO.save(topic); log.debug("Category saved!"); categoryFull.setId(category.getId()); } subCategories = null; category = null; } else { // EXCEPTION - Topic not found in Stakeholder: stakeholder.getAlias(); throw new PathNotValidException("Save category: Topic with id: "+topicId+" not found in Stakeholder: "+stakeholderId); } } else { // EXCEPTION - Topic not found throw new EntityNotFoundException("Save category: Topic with id: "+topicId+" not found"); } } else { // EXCEPTION - Stakeholder not found throw new EntityNotFoundException("Save category: Stakeholder with id: "+stakeholderId+" not found"); } return categoryFull; } public void onSaveDefaultCategory(Category category, String topicId) { log.debug("On save default category"); List topics = topicDAO.findByDefaultId(topicId); for(Topic topic : topics) { Category categoryNew = new Category(); categoryNew.copyFromDefault(category); categoryDAO.save(categoryNew); List categories = topic.getCategories(); categories.add(categoryNew.getId()); topicDAO.save(topic); } String subCategoryOverviewId = category.getSubCategories().get(0); SubCategory subCategoryOverview = subCategoryDAO.findById(subCategoryOverviewId); subCategoryController.onSaveDefaultSubCategory(subCategoryOverview, category.getId()); } public void onUpdateDefaultCategory(Category category, Category oldCategory) { log.debug("On update default category"); List categories = categoryDAO.findByDefaultId(category.getId()); boolean changed = false; for(Category categoryBasedOnDefault : categories) { if(category.getName() != null && !category.getName().equals(categoryBasedOnDefault.getName()) && (oldCategory.getName() == null || oldCategory.getName().equals(categoryBasedOnDefault.getName()))) { categoryBasedOnDefault.setName(category.getName()); categoryBasedOnDefault.setAlias(category.getAlias()); changed = true; } if(category.getDescription() != null && !category.getDescription().equals(categoryBasedOnDefault.getDescription()) && (oldCategory.getDescription() == null || oldCategory.getDescription().equals(categoryBasedOnDefault.getDescription()))) { categoryBasedOnDefault.setDescription(category.getDescription()); changed = true; } if(!changed) { // break; continue; } // categoryBasedOnDefault.setName(category.getName()); // categoryBasedOnDefault.setDescription(category.getDescription()); categoryBasedOnDefault.setUpdateDate(category.getUpdateDate()); categoryDAO.save(categoryBasedOnDefault); } } @PreAuthorize("isAuthenticated()") @RequestMapping(value = "/{stakeholderId}/{topicId}/{categoryId}/delete", method = RequestMethod.DELETE) public boolean deleteCategory(@PathVariable("stakeholderId") String stakeholderId, @PathVariable("topicId") String topicId, @PathVariable("categoryId") String categoryId, @RequestParam(required = false) String children) { log.debug("delete category"); log.debug("Id: "+categoryId + " - Stakeholder: "+stakeholderId + " - Topic: "+topicId); Stakeholder stakeholder = stakeholderDAO.findById(stakeholderId); if(stakeholder != null) { if(!rolesUtils.hasUpdateAuthority(stakeholder.getType(), stakeholder.getAlias())) { // EXCEPTION - Access denied throw new ForbiddenException("Delete category: You are not authorized to update stakeholder with id: "+stakeholderId); } Topic topic = topicDAO.findById(topicId); if(topic != null) { if(stakeholder.getTopics().contains(topicId)) { Category category = categoryDAO.findById(categoryId); if(category != null) { if(category.getDefaultId() != null && !rolesUtils.hasCreateAndDeleteAuthority(stakeholder.getType())) { // EXCEPTION - Access denied throw new ForbiddenException("Delete category: You are not authorized to delete a default Category in stakeholder with id: "+stakeholderId); } List categories = topic.getCategories(); int index = categories.indexOf(categoryId); if(index != -1) { // this category belongs in default profile if(topic.getDefaultId() == null && children != null) { onDeleteDefaultCategory(categoryId, topicId, children); } // for(String subCategoryId : category.getSubCategories()) { // SubCategory subcategory = subCategoryDAO.findById(subCategoryId); // if(subcategory == null) { // // EXCEPTION - SubCategory not found // throw new EntityNotFoundException("Delete category: SubCategory with id: "+subCategoryId+" not found (subcategory exists in category: "+categoryId+")"); // } // // for(String chartSectionId : subcategory.getCharts()) { // Section chartSection = sectionDAO.findById(chartSectionId); // if (chartSection == null) { // // EXCEPTION - Section not found // throw new EntityNotFoundException("Delete topic: Section with id: "+chartSectionId+" not found (section exists in subcategory: "+subCategoryId+")"); // } // // for (String chartId : chartSection.getIndicators()) { // indicatorDAO.delete(chartId); // } // subcategory.setCharts(null); // sectionDAO.delete(chartSectionId); // } // // for(String numberSectionId : subcategory.getNumbers()) { // Section numberSection = sectionDAO.findById(numberSectionId); // if (numberSection == null) { // // EXCEPTION - Section not found // throw new EntityNotFoundException("Delete topic: Section with id: "+numberSectionId+" not found (section exists in subcategory: "+subCategoryId+")"); // } // // for (String numberId : numberSection.getIndicators()) { // indicatorDAO.delete(numberId); // } // subcategory.setNumbers(null); // sectionDAO.delete(numberSectionId); // } // // subCategoryDAO.delete(subCategoryId); // } subCategoryController.deleteTree(category); category.setSubCategories(null); categories.remove(index); topicDAO.save(topic); categoryDAO.delete(categoryId); log.debug("Category deleted!"); } else { // EXCEPTION - Category not found in Stakeholder: stakeholder.getAlias(); -> Topic: topic.getAlias(); throw new PathNotValidException("Delete category: Category with id: "+categoryId+" not found in Topic: "+topicId); } } else { // EXCEPTION - Category not found throw new EntityNotFoundException("Delete category: Category with id: "+categoryId+" not found"); } } else { // EXCEPTION - Topic not found in Stakeholder: stakeholder.getAlias(); throw new PathNotValidException("Delete category: Topic with id: "+topicId+" not found in Stakeholder: "+stakeholderId); } } else { // EXCEPTION - Topic not found throw new EntityNotFoundException("Delete category: Topic with id: "+topicId+" not found"); } } else { // EXCEPTION - Stakeholder not found throw new EntityNotFoundException("Delete category: Stakeholder with id: "+stakeholderId+" not found"); } return true; } public boolean onDeleteDefaultCategory(String defaultCategoryId, String defaultTopicId, String children) { if(children.equals("delete")) { List topics = topicDAO.findByDefaultId(defaultTopicId); List categories = categoryDAO.findByDefaultId(defaultCategoryId); for(Topic topic : topics) { Iterator categoriesIterator = categories.iterator(); while(categoriesIterator.hasNext()) { Category category = categoriesIterator.next(); String categoryId = category.getId(); if(topic.getCategories() != null && topic.getCategories().contains(categoryId)) { categoriesIterator.remove(); topic.getCategories().remove(categoryId); topicDAO.save(topic); subCategoryController.deleteTree(category); categoryDAO.delete(categoryId); log.debug("Category with id: "+categoryId+" deleted!"); break; } } } } else if(children.equals("disconnect")) { List categories = categoryDAO.findByDefaultId(defaultCategoryId); for(Category category : categories) { subCategoryController.disConnectTree(category); category.setDefaultId(null); categoryDAO.save(category); log.debug("DefaultId for Category with id: "+category.getId()+" empty!"); } } return true; } @PreAuthorize("isAuthenticated()") @RequestMapping(value = "/{stakeholderId}/{topicId}/reorder", method = RequestMethod.POST) public List reorderCategories(@PathVariable("stakeholderId") String stakeholderId, @PathVariable("topicId") String topicId, @RequestBody List categories) { log.debug("reorder categories"); log.debug("Stakeholder: "+stakeholderId + " - Topic: "+topicId); Topic topic = checkForExceptions(stakeholderId, topicId); List oldCategories = topic.getCategories(); for (String categoryId : oldCategories) { if (!categories.contains(categoryId)) { categories.add(categoryId); } } topic.setCategories(categories); List categoriesFull = new ArrayList<>(); for(String categoryId : categories) { Category category = categoryDAO.findById(categoryId); if(category == null) { // EXCEPTION - Category not found throw new EntityNotFoundException("Reorder Categories: Category with id: " + categoryId + " not found"); } categoriesFull.add(category); } topicDAO.save(topic); log.debug("Categories reordered!"); return categoriesFull; } // @RequestMapping(value = "/{stakeholderId}/{topicId}/{categoryId}/toggle-status", method = RequestMethod.POST) // public Boolean toggleCategoryStatus(@PathVariable("stakeholderId") String stakeholderId, // @PathVariable("topicId") String topicId, // @PathVariable("categoryId") String categoryId) { // log.debug("toggle category status (isActive)"); // log.debug("Stakeholder: "+stakeholderId + " - Topic: "+topicId + " - Category: "+categoryId); // // Category category = categoryDAO.findById(categoryId); // if (category == null) { // // EXCEPTION - Category not found // throw new EntityNotFoundException("Toggle category status: Category with id: "+categoryId+" not found"); // } // category.setIsActive(!category.getIsActive()); // // this.toggleCategory(stakeholderId, topicId, category); // // return category.getIsActive(); // } // // @RequestMapping(value = "/{stakeholderId}/{topicId}/{categoryId}/toggle-access", method = RequestMethod.POST) // public Boolean toggleCategoryAccess(@PathVariable("stakeholderId") String stakeholderId, // @PathVariable("topicId") String topicId, // @PathVariable("categoryId") String categoryId) { // log.debug("toggle category access (isPublic)"); // log.debug("Stakeholder: "+stakeholderId + " - Topic: "+topicId + " - Category: "+categoryId); // // Category category = categoryDAO.findById(categoryId); // if (category == null) { // // EXCEPTION - Category not found // throw new EntityNotFoundException("Toggle category access: Category with id: "+categoryId+" not found"); // } // category.setIsPublic(!category.getIsPublic()); // // this.toggleCategory(stakeholderId, topicId, category); // // return category.getIsPublic(); // } @PreAuthorize("isAuthenticated()") @RequestMapping(value = "/{stakeholderId}/{topicId}/{categoryId}/change-visibility", method = RequestMethod.POST) public Category changeCategoryVisibility(@PathVariable("stakeholderId") String stakeholderId, @PathVariable("topicId") String topicId, @PathVariable("categoryId") String categoryId, @RequestParam("visibility") Visibility visibility, @RequestParam(required = false) Boolean propagate) { log.debug("change category visibility: "+visibility + " - toggle propagate: "+((propagate != null && propagate) ? "true" : "false")); log.debug("Stakeholder: "+stakeholderId + " - Topic: "+topicId + " - Category: "+categoryId); Stakeholder stakeholder = stakeholderDAO.findById(stakeholderId); if (stakeholder != null) { if(!rolesUtils.hasUpdateAuthority(stakeholder.getType(), stakeholder.getAlias())) { // EXCEPTION - Access denied throw new ForbiddenException("Toggle category: You are not authorized to update stakeholder with id: "+stakeholderId); } Topic topic = topicDAO.findById(topicId); if (topic != null) { if (stakeholder.getTopics().contains(topicId)) { if (topic.getCategories().contains(categoryId)) { return changeVisibilityTree(categoryId, visibility, propagate); } else { // EXCEPTION - Category not found in Stakeholder: stakeholder.getAlias(); -> Topic: topic.getAlias(); throw new PathNotValidException("Toggle category: Category with id: "+categoryId+" not found in Topic: "+topicId); } } else { // EXCEPTION - Topic not found in Stakeholder: stakeholder.getAlias(); throw new PathNotValidException("Toggle category: Topic with id: "+topicId+" not found in Stakeholder: "+stakeholderId); } } else { // EXCEPTION - Topic not found throw new EntityNotFoundException("Toggle category: Topic with id: "+topicId+" not found"); } } else { // EXCEPTION - Stakeholder not found throw new EntityNotFoundException("Toggle category: Stakeholder with id: "+stakeholderId+" not found"); } } public Category changeVisibilityTree(String categoryId, Visibility visibility, Boolean propagate) { Category category = categoryDAO.findById(categoryId); if (category == null) { // EXCEPTION - Category not found throw new EntityNotFoundException("Change category visibility: Category with id: "+categoryId+" not found"); } Category categoryFull = new Category(category); List subCategoriesFull = new ArrayList<>(); if(propagate != null && propagate) { for (String subCategoryId : category.getSubCategories()) { subCategoriesFull.add(subCategoryController.changeVisibilityTree(subCategoryId, visibility, propagate)); } } category.setVisibility(visibility); categoryDAO.save(category); log.debug("Category toggled!"); categoryFull.setVisibility(visibility); categoryFull.setSubCategories(subCategoriesFull); return categoryFull; } private Topic checkForExceptions(String stakeholderId, String topicId) { Stakeholder stakeholder = stakeholderDAO.findById(stakeholderId); if(stakeholder == null) { // EXCEPTION - Stakeholder not found throw new EntityNotFoundException("checkForExceptions category: Stakeholder with id: " + stakeholderId + " not found"); } if(!rolesUtils.hasUpdateAuthority(stakeholder.getType(), stakeholder.getAlias())) { // EXCEPTION - Access denied throw new ForbiddenException("checkForExceptions category: You are not authorized to update stakeholder with id: "+stakeholderId); } Topic topic = topicDAO.findById(topicId); if(topic == null) { // EXCEPTION - Topic not found throw new EntityNotFoundException("checkForExceptions category: Topic with id: "+topicId+" not found"); } if(!stakeholder.getTopics().contains(topicId)) { // EXCEPTION - Topic not found in Stakeholder: stakeholder.getAlias(); throw new PathNotValidException("checkForExceptions category: Topic with id: "+topicId+" not found in Stakeholder: "+stakeholderId); } return topic; } public void deleteTree(Topic topic) { List categories = topic.getCategories(); for(String categoryId : categories) { Category category = categoryDAO.findById(categoryId); if (category == null) { // EXCEPTION - Category not found throw new EntityNotFoundException("Category delete tree: Category with id: "+categoryId+" not found (category exists in topic: "+topic.getId()+")"); } subCategoryController.deleteTree(category); categoryDAO.delete(categoryId); } } public void disConnectTree(Topic topic) { List categories = topic.getCategories(); for(String categoryId : categories) { Category category = categoryDAO.findById(categoryId); if (category == null) { // EXCEPTION - Category not found throw new EntityNotFoundException("Category disconnect tree: Category with id: "+categoryId+" not found (category exists in topic: "+topic.getId()+")"); } subCategoryController.disConnectTree(category); category.setDefaultId(null); categoryDAO.save(category); } } }