package eu.dnetlib.uoamonitorservice.service; import eu.dnetlib.uoaadmintoolslibrary.handlers.ForbiddenException; import eu.dnetlib.uoamonitorservice.dao.*; import eu.dnetlib.uoamonitorservice.entities.Indicator; import eu.dnetlib.uoamonitorservice.entities.Section; 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.Date; import java.util.List; @Service public class IndicatorService { private final StakeholderDAO stakeholderDAO; private final TopicDAO topicDAO; private final CategoryDAO categoryDAO; private final SubCategoryDAO subCategoryDAO; private final SectionDAO sectionDAO; private final IndicatorDAO dao; private final CommonService commonService; @Autowired public IndicatorService(StakeholderDAO stakeholderDAO, TopicDAO topicDAO, CategoryDAO categoryDAO,SubCategoryDAO subCategoryDAO, SectionDAO sectionDAO, IndicatorDAO dao, CommonService commonService) { this.stakeholderDAO = stakeholderDAO; this.topicDAO = topicDAO; this.categoryDAO = categoryDAO; this.subCategoryDAO = subCategoryDAO; this.sectionDAO = sectionDAO; this.dao = dao; this.commonService = commonService; } public Indicator find(String id) { return dao.findById(id).orElseThrow(() -> new EntityNotFoundException("Indicator with id: " + id + " not found")); } public Indicator findByPath(Section section, String indicatorId) { if (!section.getIndicators().contains(indicatorId)) { throw new PathNotValidException("Indicator with id: " + indicatorId + " not found in Section: " + section.getId()); } return this.dao.findById(indicatorId).orElseThrow(() -> new EntityNotFoundException("Indicator with id: " + indicatorId + " not found")); } public Indicator getIndicator(String type, String alias, String id) { Indicator indicator = this.find(id); if(this.commonService.hasVisibilityAuthority(type, alias, indicator)) { return indicator; } else { return null; } } public String build(String id) { return this.save(this.find(id).copy()).getId(); } public String copy(String id) { Indicator copy = new Indicator(this.find(id)); copy.setId(null); return this.save(copy).getId(); } public Indicator save(Indicator indicator) { if(indicator.getId() == null) { indicator.setCreationDate(new Date()); } indicator.setUpdateDate(new Date()); return this.dao.save(indicator); } public Indicator save(Stakeholder stakeholder, Section section, Indicator indicator) { if(indicator.getId() != null) { if (this.commonService.hasEditAuthority(stakeholder.getType(), stakeholder.getAlias())) { this.updateChildren(indicator); indicator = this.save(indicator); } else { throw new ForbiddenException("You are not authorized to update stakeholder with id: " + stakeholder.getId()); } } else { if (this.commonService.hasCreateAuthority(stakeholder.getType())) { indicator = this.save(indicator); this.createChildren(section, indicator); this.addIndicator(section, indicator.getId()); } else { throw new ForbiddenException("You are not authorized to create an indicator in stakeholder with id: " + stakeholder.getId()); } } return indicator; } public void createChildren(Section defaultSection, Indicator indicator) { this.sectionDAO.findByDefaultId(defaultSection.getId()).forEach(section -> { List subCategories = this.subCategoryDAO.findByNumbersContaining(section.getId()); subCategories.addAll(this.subCategoryDAO.findByChartsContaining(section.getId())); subCategories.forEach(subCategory -> { this.categoryDAO.findBySubCategoriesContaining(subCategory.getId()).forEach(category -> { this.topicDAO.findByCategoriesContaining(category.getId()).forEach(topic -> { this.stakeholderDAO.findByTopicsContaining(topic.getId()).forEach(stakeholder -> { this.save(stakeholder, section, indicator.copy()); }); }); }); }); }); } public void updateChildren(Indicator indicator) { this.dao.findByDefaultId(indicator.getId()).forEach(child -> { this.save(indicator.override(child, this.find(indicator.getId()))); }); } public void delete(String type, Indicator indicator, boolean remove) { if(this.commonService.hasDeleteAuthority(type)) { this.dao.findByDefaultId(indicator.getId()).forEach(child -> { this.delete(type, child.getId(), remove); }); if(remove) { this.removeIndicator(indicator.getId()); } this.dao.delete(indicator); } else { throw new ForbiddenException("Delete indicator: You are not authorized to delete indicator with id: " + indicator.getId()); } } public void delete(String type, String id, boolean remove) { Indicator indicator = this.find(id); this.delete(type, indicator, remove); } public void addIndicator(Section section, String id) { section.addIndicator(id); section.setUpdateDate(new Date()); this.sectionDAO.save(section); } public void removeIndicator(String id) { this.sectionDAO.findByIndicatorsContaining(id).forEach(section -> { section.removeIndicator(id); section.setUpdateDate(new Date()); this.sectionDAO.save(section); }); } public Indicator changeVisibility(String type, String alias, Indicator indicator, Visibility visibility) { if(this.commonService.hasEditAuthority(type, alias)) { indicator.setVisibility(visibility); return this.save(indicator); } else { throw new ForbiddenException("Change section visibility: You are not authorized to update section with id: " + indicator.getId()); } } }