package eu.dnetlib.uoamonitorservice.service; import eu.dnetlib.uoaadmintoolslibrary.handlers.ForbiddenException; import eu.dnetlib.uoamonitorservice.dao.CategoryDAO; import eu.dnetlib.uoamonitorservice.dao.StakeholderDAO; import eu.dnetlib.uoamonitorservice.dao.SubCategoryDAO; import eu.dnetlib.uoamonitorservice.dao.TopicDAO; import eu.dnetlib.uoamonitorservice.dto.SubCategoryFull; import eu.dnetlib.uoamonitorservice.entities.Category; import eu.dnetlib.uoamonitorservice.entities.Stakeholder; import eu.dnetlib.uoamonitorservice.entities.SubCategory; import eu.dnetlib.uoamonitorservice.handlers.EntityNotFoundException; import eu.dnetlib.uoamonitorservice.handlers.PathNotValidException; import eu.dnetlib.uoamonitorservice.primitives.Visibility; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import java.util.HashSet; import java.util.List; import java.util.stream.Collectors; @Service public class SubCategoryService { private final StakeholderDAO stakeholderDAO; private final TopicDAO topicDAO; private final CategoryDAO categoryDAO; private final SubCategoryDAO dao; private final CommonService commonService; private final SectionService sectionService; @Autowired public SubCategoryService(StakeholderDAO stakeholderDAO, TopicDAO topicDAO, CategoryDAO categoryDAO, SubCategoryDAO dao,CommonService commonService, SectionService sectionService) { this.stakeholderDAO = stakeholderDAO; this.topicDAO = topicDAO; this.categoryDAO = categoryDAO; this.dao = dao; this.commonService = commonService; this.sectionService = sectionService; } public SubCategory find(String id) { return dao.findById(id).orElseThrow(() -> new EntityNotFoundException("SubCategory with id: " + id + " not found")); } public SubCategory findByPath(Category category, String subcategoryId) { if (!category.getSubCategories().contains(subcategoryId)) { throw new PathNotValidException("SubCategory with id: " + subcategoryId + " not found in Category: " + category.getId()); } return this.dao.findById(subcategoryId).orElseThrow(() -> new EntityNotFoundException("SubCategory with id: " + subcategoryId + " not found")); } public SubCategoryFull getFullSubCategory(String type, String alias, SubCategory subCategory) { if(commonService.hasVisibilityAuthority(type, alias, subCategory)) { return new SubCategoryFull(subCategory, subCategory.getNumbers().stream() .map(sectionId -> this.sectionService.getFullSection(type, alias, sectionId)) .collect(Collectors.toList()), subCategory.getCharts().stream() .map(sectionId -> this.sectionService.getFullSection(type, alias, sectionId)) .collect(Collectors.toList())); } else { return null; } } public SubCategoryFull getFullSubCategory(String type, String alias, String subCategoryId) { SubCategory subCategory = this.find(subCategoryId); return this.getFullSubCategory(type, alias, subCategory); } public SubCategoryFull buildSubcategory(SubCategoryFull subCategoryFull) { subCategoryFull.setNumbers(subCategoryFull.getNumbers().stream().map(this.sectionService::buildSection).collect(Collectors.toList())); subCategoryFull.setCharts(subCategoryFull.getCharts().stream().map(this.sectionService::buildSection).collect(Collectors.toList())); subCategoryFull.update(this.save(new SubCategory(subCategoryFull))); return subCategoryFull; } public SubCategory save(SubCategory subCategory) { if(subCategory.getId() != null) { SubCategory old = this.find(subCategory.getId()); subCategory.setNumbers(old.getNumbers()); subCategory.setCharts(old.getCharts()); } subCategory.getNumbers().forEach(this.sectionService::find); subCategory.getCharts().forEach(this.sectionService::find); return this.dao.save(subCategory); } public SubCategoryFull save(Stakeholder stakeholder, Category category, SubCategory subCategory) { if (subCategory.getId() != null) { if (this.commonService.hasEditAuthority(stakeholder.getType(), stakeholder.getAlias())) { SubCategory old = this.find(subCategory.getId()); subCategory.setNumbers(old.getNumbers()); subCategory.setCharts(old.getCharts()); this.updateChildren(subCategory); subCategory = this.save(subCategory); } else { throw new ForbiddenException("You are not authorized to update stakeholder with id: " + stakeholder.getId()); } } else { if (this.commonService.hasCreateAuthority(stakeholder.getType())) { subCategory = this.save(subCategory); this.createChildren(category, subCategory); this.addSubCategory(category, subCategory.getId()); } else { throw new ForbiddenException("You are not authorized to create a subCategory in stakeholder with id: " + stakeholder.getId()); } } return this.getFullSubCategory(stakeholder.getType(), stakeholder.getAlias(), subCategory); } public void createChildren(Category defaultCategory, SubCategory subCategory) { this.categoryDAO.findByDefaultId(defaultCategory.getId()).forEach(category -> { this.topicDAO.findByCategoriesContaining(category.getId()).forEach(topic -> { this.stakeholderDAO.findByTopicsContaining(topic.getId()).forEach(stakeholder -> { this.save(stakeholder, category, subCategory.copy()); }); }); }); } public void updateChildren(SubCategory subCategory) { this.dao.findByDefaultId(subCategory.getId()).forEach(child -> { this.save(subCategory.override(child, this.find(subCategory.getId()))); }); } public SubCategoryFull reorderNumbers(Stakeholder stakeholder, SubCategory subCategory, List numbers) { if(this.commonService.hasEditAuthority(stakeholder.getType(), stakeholder.getAlias())) { numbers.forEach(this.sectionService::find); if (subCategory.getNumbers().size() == numbers.size() && new HashSet<>(subCategory.getNumbers()).containsAll(numbers)) { subCategory.setNumbers(numbers); return this.getFullSubCategory(stakeholder.getType(), stakeholder.getAlias(), this.dao.save(subCategory)); } else { throw new EntityNotFoundException("Some sections dont exist in the subCategory with id " + subCategory.getId()); } } else { throw new ForbiddenException("You are not authorized to reorder sections in subCategory with id: " + subCategory.getId()); } } public SubCategoryFull reorderCharts(Stakeholder stakeholder, SubCategory subCategory, List charts) { if(this.commonService.hasEditAuthority(stakeholder.getType(), stakeholder.getAlias())) { charts.forEach(this.sectionService::find); if (subCategory.getCharts().size() == charts.size() && new HashSet<>(subCategory.getCharts()).containsAll(charts)) { subCategory.setCharts(charts); return this.getFullSubCategory(stakeholder.getType(), stakeholder.getAlias(), this.dao.save(subCategory)); } else { throw new EntityNotFoundException("Some sections dont exist in the subCategory with id " + subCategory.getId()); } } else { throw new ForbiddenException("You are not authorized to reorder sections in subCategory with id: " + subCategory.getId()); } } public void delete(String type, SubCategory subCategory, boolean remove) { if(this.commonService.hasDeleteAuthority(type)) { this.dao.findByDefaultId(subCategory.getId()).forEach(child -> { this.delete(type, child.getId(), remove); }); subCategory.getNumbers().forEach(sectionId -> { this.sectionService.delete(type, sectionId, false); }); subCategory.getCharts().forEach(sectionId -> { this.sectionService.delete(type, sectionId, false); }); if (remove) { this.removeSubCategory(subCategory.getId()); } this.dao.delete(subCategory); } else { throw new ForbiddenException("Delete subCategory: You are not authorized to delete subCategory with id: " + subCategory.getId()); } } public void delete(String type, String id, boolean remove) { SubCategory subCategory = this.find(id); this.delete(type, subCategory, remove); } public void addSubCategory(Category category, String id) { category.addSubCategory(id); this.categoryDAO.save(category); } public void removeSubCategory(String id) { this.categoryDAO.findBySubCategoriesContaining(id).forEach(category -> { category.removeSubCategory(id); this.categoryDAO.save(category); }); } public SubCategoryFull changeVisibility(String type, String alias, SubCategoryFull subCategory, Visibility visibility, Boolean propagate) { if(this.commonService.hasEditAuthority(type, alias)) { subCategory.setVisibility(visibility); if(propagate) { subCategory.setNumbers(subCategory.getNumbers().stream() .map(section -> this.sectionService.changeVisibility(type, alias, section, visibility)) .collect(Collectors.toList())); subCategory.setCharts(subCategory.getCharts().stream() .map(section -> this.sectionService.changeVisibility(type, alias, section, visibility)) .collect(Collectors.toList())); } subCategory.update(this.save(new SubCategory(subCategory))); return subCategory; } else { throw new ForbiddenException("Change subCategory visibility: You are not authorized to update subCategory with id: " + subCategory.getId()); } } public SubCategoryFull changeVisibility(String type, String alias, SubCategory subCategory, Visibility visibility, Boolean propagate) { SubCategoryFull subCategoryFull = this.getFullSubCategory(type, alias, subCategory); return this.changeVisibility(type, alias, subCategoryFull, visibility, propagate); } }