uoa-monitor-service/src/main/java/eu/dnetlib/uoamonitorservice/service/CategoryService.java

192 lines
8.6 KiB
Java

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.TopicDAO;
import eu.dnetlib.uoamonitorservice.dto.CategoryFull;
import eu.dnetlib.uoamonitorservice.dto.TopicFull;
import eu.dnetlib.uoamonitorservice.entities.Category;
import eu.dnetlib.uoamonitorservice.entities.Stakeholder;
import eu.dnetlib.uoamonitorservice.entities.Topic;
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 CategoryService {
private final StakeholderDAO stakeholderDAO;
private final TopicDAO topicDAO;
private final CategoryDAO dao;
private final SubCategoryService subCategoryService;
private final CommonService commonService;
@Autowired
public CategoryService(StakeholderDAO stakeholderDAO, TopicDAO topicDAO, CategoryDAO dao, SubCategoryService subCategoryService, CommonService commonService) {
this.stakeholderDAO = stakeholderDAO;
this.topicDAO = topicDAO;
this.dao = dao;
this.subCategoryService = subCategoryService;
this.commonService = commonService;
}
public Category find(String id) {
return dao.findById(id).orElseThrow(() -> new EntityNotFoundException("Category with id: " + id + " not found"));
}
public Category findByPath(Topic topic, String categoryId) {
if (!topic.getCategories().contains(categoryId)) {
throw new PathNotValidException("Category with id: " + categoryId + " not found in Topic: " + topic.getId());
}
return this.dao.findById(categoryId).orElseThrow(() -> new EntityNotFoundException("Category with id: " + categoryId + " not found"));
}
public CategoryFull getFullCategory(String type, String alias, Category category) {
if (commonService.hasVisibilityAuthority(type, alias, category)) {
return new CategoryFull(category, category.getSubCategories().stream()
.map(subCategoryId -> this.subCategoryService.getFullSubCategory(type, alias, subCategoryId))
.collect(Collectors.toList()));
} else {
return null;
}
}
public CategoryFull getFullCategory(String type, String alias, String categoryId) {
Category category = this.find(categoryId);
return this.getFullCategory(type, alias, category);
}
public CategoryFull buildCategory(CategoryFull categoryFull) {
categoryFull.setSubCategories(categoryFull.getSubCategories().stream().map(this.subCategoryService::buildSubcategory).collect(Collectors.toList()));
categoryFull.update(this.save(new Category(categoryFull)));
return categoryFull;
}
public Category save(Category category) {
if(category.getId() != null) {
category.setSubCategories(this.find(category.getId()).getSubCategories());
}
category.getSubCategories().forEach(this.subCategoryService::find);
return this.dao.save(category);
}
public CategoryFull save(Stakeholder stakeholder, Topic topic, Category category) {
return this.save(stakeholder, topic, category, true);
}
public CategoryFull save(Stakeholder stakeholder, Topic topic, Category category, boolean createOverview) {
if (category.getId() != null) {
if (this.commonService.hasEditAuthority(stakeholder.getType(), stakeholder.getAlias())) {
category.setSubCategories(this.find(topic.getId()).getSubCategories());
this.updateChildren(category);
category = this.save(category);
} else {
throw new ForbiddenException("You are not authorized to update stakeholder with id: " + stakeholder.getId());
}
} else {
if (this.commonService.hasCreateAuthority(stakeholder.getType())) {
category = this.save(category);
this.createChildren(topic, category);
if(createOverview) {
this.subCategoryService.save(stakeholder, category, category.createOverview());
}
this.addCategory(topic, category.getId());
} else {
throw new ForbiddenException("You are not authorized to create a category in stakeholder with id: " + stakeholder.getId());
}
}
return this.getFullCategory(stakeholder.getType(), stakeholder.getAlias(), category);
}
public void createChildren(Topic defaultTopic, Category category) {
this.topicDAO.findByDefaultId(defaultTopic.getId()).forEach(topic -> {
this.stakeholderDAO.findByTopicsContaining(topic.getId()).forEach(stakeholder -> {
this.save(stakeholder, topic, category.copy(), false);
});
});
}
public void updateChildren(Category category) {
this.dao.findByDefaultId(category.getId()).forEach(child -> {
this.save(category.override(child, this.find(category.getId())));
});
}
public CategoryFull reorderSubCategories(Stakeholder stakeholder, Category category, List<String> subcategories) {
if(this.commonService.hasEditAuthority(stakeholder.getType(), stakeholder.getAlias())) {
subcategories.forEach(this.subCategoryService::find);
if (category.getSubCategories().size() == subcategories.size() && new HashSet<>(category.getSubCategories()).containsAll(subcategories)) {
category.setSubCategories(subcategories);
return this.getFullCategory(stakeholder.getType(), stakeholder.getAlias(), this.dao.save(category));
} else {
throw new EntityNotFoundException("Some subCategories dont exist in the category with id " + category.getId());
}
} else {
throw new ForbiddenException("You are not authorized to reorder subCategories in category with id: " + category.getId());
}
}
public void delete(String type, Category category, boolean remove) {
if (this.commonService.hasDeleteAuthority(type)) {
this.dao.findByDefaultId(category.getId()).forEach(child -> {
this.delete(type, child.getId(), remove);
});
category.getSubCategories().forEach(subcategoryId -> {
this.subCategoryService.delete(type, subcategoryId, false);
});
if (remove) {
this.removeCategory(category.getId());
}
this.dao.delete(category);
} else {
throw new ForbiddenException("Delete category: You are not authorized to delete category with id: " + category.getId());
}
}
public void delete(String type, String id, boolean remove) {
Category category = this.find(id);
this.delete(type, category, remove);
}
public void addCategory(Topic topic, String id) {
topic.addCategory(id);
this.topicDAO.save(topic);
}
public void removeCategory(String id) {
this.topicDAO.findByCategoriesContaining(id).forEach(topic -> {
topic.removeCategory(id);
this.topicDAO.save(topic);
});
}
public CategoryFull changeVisibility(String type, String alias, CategoryFull category, Visibility visibility, Boolean propagate) {
if (this.commonService.hasEditAuthority(type, alias)) {
category.setVisibility(visibility);
if (propagate) {
category.setSubCategories(category.getSubCategories().stream()
.map(subCategory -> this.subCategoryService.changeVisibility(type, alias, subCategory, visibility, true))
.collect(Collectors.toList()));
}
category.update(this.save(new Category(category)));
return category;
} else {
throw new ForbiddenException("Change category visibility: You are not authorized to update category with id: " + category.getId());
}
}
public CategoryFull changeVisibility(String type, String alias, Category category, Visibility visibility, Boolean propagate) {
CategoryFull categoryFull = this.getFullCategory(type, alias, category);
return this.changeVisibility(type, alias, categoryFull, visibility, propagate);
}
}