package eu.dnetlib.uoamonitorservice.service; import eu.dnetlib.uoaadmintoolslibrary.handlers.ForbiddenException; import eu.dnetlib.uoamonitorservice.dao.StakeholderDAO; import eu.dnetlib.uoamonitorservice.dto.StakeholderFull; import eu.dnetlib.uoamonitorservice.entities.Stakeholder; import eu.dnetlib.uoamonitorservice.generics.Common; import eu.dnetlib.uoamonitorservice.handlers.EntityNotFoundException; import eu.dnetlib.uoamonitorservice.primitives.Visibility; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import java.util.ArrayList; import java.util.Date; import java.util.HashSet; import java.util.List; import java.util.stream.Collectors; @Service public class StakeholderService { private final StakeholderDAO dao; private final CommonService commonService; private final TopicService topicService; @Autowired public StakeholderService(StakeholderDAO dao, CommonService commonService, TopicService topicService) { this.dao = dao; this.commonService = commonService; this.topicService = topicService; } public Stakeholder findByAlias(String alias) { return this.dao.findByAlias(alias).orElseThrow(() -> new EntityNotFoundException("Stakeholder with alias: " + alias + " not found")); } public List findByDefaultId(String id) { return this.dao.findByDefaultIdAndCopyTrue(id); } public Stakeholder findByPath(String stakeholderId) { if(stakeholderId.equals("-1")) { return null; } return dao.findById(stakeholderId).orElseThrow(() -> new EntityNotFoundException("Stakeholder with id: " + stakeholderId + " not found")); } public List getAllAliases() { return this.dao.findAll().stream().map(Stakeholder::getAlias).collect(Collectors.toList()); } public List getAll(String type) { if (type != null) { return this.dao.findByType(type); } return this.dao.findAll(); } public List getAllDefaultByRole(String type) { return (type == null ? this.dao.findByDefaultIdIsNull() : this.dao.findByDefaultIdAndType(null, type)).stream() .filter(stakeholder -> this.commonService.hasAccessAuthority(stakeholder.getType(), stakeholder.getAlias(), true)) .collect(Collectors.toList()); } public List getStakeholdersByTypeAndRole(String type, String defaultId, boolean manage) { List stakeholders; if (type != null && defaultId != null) { stakeholders = dao.findByDefaultIdAndType(defaultId, type); } else if (defaultId != null) { stakeholders = dao.findByDefaultIdAndCopyTrue(defaultId); } else if (type != null) { stakeholders = dao.findByDefaultIdIsNotNullAndType(type); } else { stakeholders = dao.findByDefaultIdIsNotNull(); } return stakeholders.stream().filter(stakeholder -> (!manage && (stakeholder.getVisibility() == Visibility.PUBLIC || stakeholder.getVisibility() == Visibility.RESTRICTED)) || this.commonService.hasAccessAuthority(stakeholder.getType(), stakeholder.getAlias(), false)) .collect(Collectors.toList()); } public StakeholderFull getFullStakeholder(Stakeholder stakeholder) { if (this.commonService.hasVisibilityAuthority(stakeholder.getType(), stakeholder.getAlias(), stakeholder)) { if(!stakeholder.isCopy() && stakeholder.getDefaultId() != null) { Stakeholder defaultStakeholder = this.findByPath(stakeholder.getDefaultId()); if(defaultStakeholder != null) { return new StakeholderFull(stakeholder, defaultStakeholder.getTopics().stream() .map(topicId -> topicService.getFullTopic(stakeholder.getType(), stakeholder.getAlias(), topicId)) .collect(Collectors.toList())); } } return new StakeholderFull(stakeholder, stakeholder.getTopics().stream() .map(topicId -> topicService.getFullTopic(stakeholder.getType(), stakeholder.getAlias(), topicId)) .collect(Collectors.toList())); } else { return null; } } public Stakeholder buildStakeholder(Stakeholder stakeholder, String copyId) { if(stakeholder.getDefaultId() == null) { stakeholder.setCopy(false); if(copyId == null) { stakeholder.setTopics(new ArrayList<>()); } else { Stakeholder copyFrom = this.findByPath(copyId); stakeholder.setTopics(copyFrom.getTopics().stream().map(this.topicService::copy).collect(Collectors.toList())); } } else { stakeholder.setTopics(new ArrayList<>()); if(stakeholder.isCopy()) { Stakeholder defaultStakeholder = this.findByPath(stakeholder.getDefaultId()); if(defaultStakeholder != null) { stakeholder.setTopics(defaultStakeholder.getTopics().stream().map(this.topicService::build).collect(Collectors.toList())); } } } return this.save(stakeholder); } public Stakeholder save(Stakeholder stakeholder) { if (stakeholder.getId() != null) { Stakeholder old = this.findByPath(stakeholder.getId()); stakeholder.setTopics(old.getTopics()); if (!stakeholder.isCopy() && stakeholder.getDefaultId() != null) { stakeholder.getTopics().forEach(topic -> { this.topicService.delete(stakeholder.getType(), topic, false); }); stakeholder.setTopics(new ArrayList<>()); } else { if(old.getTopics().isEmpty() && old.getDefaultId() != null) { Stakeholder defaultStakeholder = this.findByPath(stakeholder.getDefaultId()); if(defaultStakeholder != null) { stakeholder.setTopics(defaultStakeholder.getTopics().stream().map(this.topicService::build).collect(Collectors.toList())); } } stakeholder.getTopics().forEach(this.topicService::find); } } else { stakeholder.setCreationDate(new Date()); } stakeholder.setUpdateDate(new Date()); return this.dao.save(stakeholder); } public StakeholderFull reorderTopics(Stakeholder stakeholder, List topics) { if (this.commonService.hasEditAuthority(stakeholder.getType(), stakeholder.getAlias())) { topics.forEach(this.topicService::find); if (stakeholder.getTopics().size() == topics.size() && new HashSet<>(stakeholder.getTopics()).containsAll(topics)) { stakeholder.setTopics(topics); stakeholder.setUpdateDate(new Date()); this.reorderChildren(stakeholder, topics); return this.getFullStakeholder(this.dao.save(stakeholder)); } else { throw new EntityNotFoundException("Some topics dont exist in the stakeholder with id " + stakeholder.getId()); } } else { throw new ForbiddenException("You are not authorized to reorder topics in stakeholder with id: " + stakeholder.getId()); } } public void reorderChildren(Stakeholder defaultStakeholder, List defaultTopics) { this.dao.findByDefaultIdAndCopyTrue(defaultStakeholder.getId()).stream().map(this::getFullStakeholder).forEach(stakeholder -> { this.reorderTopics(new Stakeholder(stakeholder), this.commonService.reorder(defaultTopics, stakeholder.getTopics().stream().map(topic -> (Common) topic).collect(Collectors.toList()))); }); } public String delete(String id) { Stakeholder stakeholder = this.findByPath(id); if (this.commonService.hasDeleteAuthority(stakeholder.getType())) { this.dao.findByDefaultIdAndCopyTrue(stakeholder.getId()).forEach(child -> { this.delete(child.getId()); }); stakeholder.getTopics().forEach(topicId -> { this.topicService.delete(stakeholder.getType(), topicId, false); }); this.dao.delete(id); return stakeholder.getAlias(); } else { throw new ForbiddenException("Delete stakeholder: You are not authorized to delete stakeholder with id: " + id); } } public StakeholderFull changeVisibility(StakeholderFull stakeholder, Visibility visibility, Boolean propagate) { if (this.commonService.hasEditAuthority(stakeholder.getType(), stakeholder.getAlias())) { if (propagate) { stakeholder.setTopics(stakeholder.getTopics().stream(). map(topic -> this.topicService.changeVisibility(stakeholder.getType(), stakeholder.getAlias(), topic, visibility, true)) .collect(Collectors.toList())); } stakeholder.setVisibility(visibility); stakeholder.update(this.save(new Stakeholder(stakeholder))); return stakeholder; } else { throw new ForbiddenException("Change stakeholder visibility: You are not authorized to update stakeholder with id: " + stakeholder.getId()); } } public StakeholderFull changeVisibility(Stakeholder stakeholder, Visibility visibility, Boolean propagate) { StakeholderFull stakeholderFull = this.getFullStakeholder(stakeholder); return this.changeVisibility(stakeholderFull, visibility, propagate); } }