dnet-applications/apps/dnet-exporter-api/src/main/java/eu/dnetlib/openaire/community/db/CommunityService.java

354 lines
15 KiB
Java

package eu.dnetlib.openaire.community.db;
import java.util.Arrays;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.function.BiConsumer;
import java.util.function.Function;
import java.util.stream.Collectors;
import javax.transaction.Transactional;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.stereotype.Service;
import eu.dnetlib.openaire.community.db.model.DbCommunity;
import eu.dnetlib.openaire.community.db.model.DbDatasource;
import eu.dnetlib.openaire.community.db.model.DbDatasourcePK;
import eu.dnetlib.openaire.community.db.model.DbOrganization;
import eu.dnetlib.openaire.community.db.model.DbProject;
import eu.dnetlib.openaire.community.db.model.DbProjectPK;
import eu.dnetlib.openaire.community.db.model.DbSubCommunity;
import eu.dnetlib.openaire.community.db.model.DbSupportOrg;
import eu.dnetlib.openaire.community.db.repository.DbCommunityRepository;
import eu.dnetlib.openaire.community.db.repository.DbDatasourceRepository;
import eu.dnetlib.openaire.community.db.repository.DbOrganizationRepository;
import eu.dnetlib.openaire.community.db.repository.DbProjectRepository;
import eu.dnetlib.openaire.community.db.repository.DbSubCommunityRepository;
import eu.dnetlib.openaire.community.db.repository.DbSupportOrgRepository;
import eu.dnetlib.openaire.community.db.utils.CommunityMappingUtils;
import eu.dnetlib.openaire.exporter.exceptions.CommunityException;
import eu.dnetlib.openaire.exporter.exceptions.ResourceNotFoundException;
import eu.dnetlib.openaire.exporter.model.community.CommunityContentprovider;
import eu.dnetlib.openaire.exporter.model.community.CommunityDetails;
import eu.dnetlib.openaire.exporter.model.community.CommunityOrganization;
import eu.dnetlib.openaire.exporter.model.community.CommunityProject;
import eu.dnetlib.openaire.exporter.model.community.CommunitySummary;
import eu.dnetlib.openaire.exporter.model.community.CommunityWritableProperties;
import eu.dnetlib.openaire.exporter.model.community.SubCommunity;
import eu.dnetlib.openaire.exporter.model.community.selectioncriteria.SelectionCriteria;
@Service
@ConditionalOnProperty(value = "openaire.exporter.enable.community", havingValue = "true")
public class CommunityService {
// TODO
// 1) Import tramite profili:
// 1.1) Completare CommunityImporterController
// 2) Subcommunities: visualizzazione tramite le context api
// 3) Importare le orgs dal wf di provision, ad esempio:
// https://services.openaire.eu/is/mvc/ui/isManager.do#/profile/4801c33c-66ca-4ab6-af64-aa812194ec61_V29ya2Zsb3dEU1Jlc291cmNlcy9Xb3JrZmxvd0RTUmVzb3VyY2VUeXBl
// 4) Verificare Tickets: #8835, #8854, #6483, #3259, #3494
@Autowired
private DbCommunityRepository dbCommunityRepository;
@Autowired
private DbProjectRepository dbProjectRepository;
@Autowired
private DbDatasourceRepository dbDatasourceRepository;
@Autowired
private DbOrganizationRepository dbOrganizationRepository;
@Autowired
private DbSupportOrgRepository dbSupportOrgRepository;
@Autowired
private DbSubCommunityRepository dbSubCommunityRepository;
public List<CommunitySummary> listCommunities() throws CommunityException {
return dbCommunityRepository.findAll()
.stream()
.map(CommunityMappingUtils::toCommunitySummary)
.collect(Collectors.toList());
}
public CommunityDetails saveCommunity(final CommunityDetails details) throws CommunityException {
dbCommunityRepository.save(CommunityMappingUtils.toCommunity(details));
return getCommunity(details.getId());
}
public CommunityDetails getCommunity(final String id) throws CommunityException, ResourceNotFoundException {
final DbCommunity c = dbCommunityRepository.findById(id).orElseThrow(() -> new ResourceNotFoundException("Community not found: " + id));
return CommunityMappingUtils.CommunityDetails(c);
}
@Transactional
public void setCommunity(final String id, final CommunityWritableProperties details) throws CommunityException, ResourceNotFoundException {
final DbCommunity c = dbCommunityRepository.findById(id).orElseThrow(() -> new ResourceNotFoundException("Community not found: " + id));
CommunityMappingUtils.populateCommunity(c, details);
dbCommunityRepository.save(c);
}
public Page<CommunityProject> getCommunityProjects(final String id, final int page, final int size) throws CommunityException, ResourceNotFoundException {
return dbProjectRepository.findByCommunity(id, PageRequest.of(page, size)).map(CommunityMappingUtils::toCommunityProject);
}
public CommunityProject addCommunityProject(final String id, final CommunityProject project) throws CommunityException, ResourceNotFoundException {
final DbProject p = CommunityMappingUtils.toDbProject(id, project);
dbProjectRepository.save(p);
return project;
}
public List<CommunityProject> addCommunityProjectList(final String id, final List<CommunityProject> projectList)
throws CommunityException, ResourceNotFoundException {
final List<DbProject> list = projectList.stream()
.map(p -> CommunityMappingUtils.toDbProject(id, p))
.collect(Collectors.toList());
dbProjectRepository.saveAll(list);
return projectList;
}
public void removeCommunityProject(final String id, final String projectId) throws CommunityException, ResourceNotFoundException {
dbProjectRepository.deleteById(new DbProjectPK(id, projectId));
}
public void removeCommunityProjectList(final String id, final List<String> projectIdList) throws CommunityException, ResourceNotFoundException {
final List<DbProjectPK> list = projectIdList.stream()
.map(projectId -> new DbProjectPK(id, projectId))
.collect(Collectors.toList());
dbProjectRepository.deleteAllById(list);
}
public List<CommunityContentprovider> getCommunityContentproviders(final String id) throws CommunityException, ResourceNotFoundException {
return dbDatasourceRepository.findByCommunity(id)
.stream()
.map(CommunityMappingUtils::toCommunityContentprovider)
.collect(Collectors.toList());
}
public CommunityContentprovider addCommunityContentprovider(final String id, final CommunityContentprovider cp)
throws CommunityException, ResourceNotFoundException {
final DbDatasource ds = CommunityMappingUtils.toDbDatasource(id, cp);
dbDatasourceRepository.save(ds);
return cp;
}
public List<CommunityContentprovider> addCommunityContentProvidersList(final String id, final List<CommunityContentprovider> contentprovidersList)
throws CommunityException, ResourceNotFoundException {
final List<DbDatasource> list = contentprovidersList.stream()
.map(cp -> CommunityMappingUtils.toDbDatasource(id, cp))
.collect(Collectors.toList());
dbDatasourceRepository.saveAll(list);
return contentprovidersList;
}
public void removeCommunityContentProvider(final String id, final String contentproviderId) throws CommunityException, ResourceNotFoundException {
dbDatasourceRepository.deleteById(new DbDatasourcePK(id, contentproviderId));
}
public void removeCommunityContentProviderList(final String id, final List<String> contentProviderIdList)
throws CommunityException, ResourceNotFoundException {
final List<DbDatasourcePK> list = contentProviderIdList.stream()
.map(dsId -> new DbDatasourcePK(id, dsId))
.collect(Collectors.toList());
dbDatasourceRepository.deleteAllById(list);
}
public void removeCommunityOrganization(final String id, final String organizationId) throws CommunityException, ResourceNotFoundException {
dbDatasourceRepository.deleteById(new DbDatasourcePK(id, organizationId));
}
public List<CommunityOrganization> getCommunityOrganizations(final String id) throws CommunityException, ResourceNotFoundException {
return dbSupportOrgRepository.findByCommunity(id)
.stream()
.map(CommunityMappingUtils::toCommunityOrganization)
.collect(Collectors.toList());
}
public CommunityOrganization addCommunityOrganization(final String id, final CommunityOrganization organization)
throws CommunityException, ResourceNotFoundException {
final DbSupportOrg o = CommunityMappingUtils.toDbSupportOrg(id, organization);
dbSupportOrgRepository.save(o);
return organization;
}
public List<CommunityOrganization> addCommunityOrganizationList(final String id, final List<CommunityOrganization> orgList)
throws CommunityException, ResourceNotFoundException {
final List<DbSupportOrg> list = orgList.stream()
.map(o -> CommunityMappingUtils.toDbSupportOrg(id, o))
.collect(Collectors.toList());
dbSupportOrgRepository.saveAll(list);
return orgList;
}
public void removeSubCommunity(final String id, final String subCommunityId) throws CommunityException, ResourceNotFoundException {
dbSubCommunityRepository.deleteById(subCommunityId);
}
public List<SubCommunity> getSubCommunities(final String id) throws CommunityException, ResourceNotFoundException {
return dbSubCommunityRepository.findByCommunity(id)
.stream()
.map(CommunityMappingUtils::toSubCommunity)
.collect(Collectors.toList());
}
public SubCommunity addSubCommunity(final SubCommunity sub) {
final DbSubCommunity sc = CommunityMappingUtils.toDbSubCommunity(sub);
dbSubCommunityRepository.save(sc);
return sub;
}
public List<SubCommunity> addSubCommunityList(final List<SubCommunity> subs) {
final List<DbSubCommunity> list = subs.stream()
.map(CommunityMappingUtils::toDbSubCommunity)
.collect(Collectors.toList());
dbSubCommunityRepository.saveAll(list);
return subs;
}
public CommunityDetails addCommunitySubjects(final String id, final String... subjects) throws CommunityException, ResourceNotFoundException {
return modifyElementToArrayField(id, c -> c.getSubjects(), (c, subs) -> c.setSubjects(subs), false, subjects);
}
public CommunityDetails removeCommunitySubjects(final String id, final String... subjects) throws CommunityException, ResourceNotFoundException {
return modifyElementToArrayField(id, c -> c.getSubjects(), (c, subs) -> c.setSubjects(subs), true, subjects);
}
public CommunityDetails addCommunityFOS(final String id, final String... foss) throws CommunityException, ResourceNotFoundException {
return modifyElementToArrayField(id, c -> c.getFos(), (c, fos) -> c.setFos(fos), false, foss);
}
public CommunityDetails removeCommunityFOS(final String id, final String... foss) throws CommunityException, ResourceNotFoundException {
return modifyElementToArrayField(id, c -> c.getFos(), (c, fos) -> c.setFos(fos), true, foss);
}
public CommunityDetails addCommunitySDG(final String id, final String... sdgs) throws CommunityException, ResourceNotFoundException {
return modifyElementToArrayField(id, c -> c.getSdg(), (c, sdg) -> c.setSdg(sdg), false, sdgs);
}
public CommunityDetails removeCommunitySDG(final String id, final String... sdgs) throws CommunityException, ResourceNotFoundException {
return modifyElementToArrayField(id, c -> c.getSdg(), (c, sdg) -> c.setSdg(sdg), true, sdgs);
}
public CommunityDetails addCommunityAdvancedConstraint(final String id, final SelectionCriteria advancedCosntraint)
throws CommunityException, ResourceNotFoundException {
final DbCommunity dbEntry = dbCommunityRepository.findById(id).orElseThrow(() -> new ResourceNotFoundException("Community not found: " + id));
dbEntry.setAdvancedConstraints(advancedCosntraint);
dbCommunityRepository.save(dbEntry);
return getCommunity(id);
}
public CommunityDetails removeCommunityAdvancedConstraint(final String id) throws ResourceNotFoundException, CommunityException {
final DbCommunity dbEntry = dbCommunityRepository.findById(id).orElseThrow(() -> new ResourceNotFoundException("Community not found: " + id));
dbEntry.setAdvancedConstraints(null);
dbCommunityRepository.save(dbEntry);
return getCommunity(id);
}
public CommunityDetails removeCommunityZenodoCommunity(final String id, final String zenodoCommunity, final boolean isMain)
throws CommunityException, ResourceNotFoundException {
if (isMain) {
return updateElementToSimpleField(id, (c, val) -> c.setMainZenodoCommunity(val), null);
} else {
return modifyElementToArrayField(id, c -> c.getOtherZenodoCommunities(), (c, arr) -> c.setOtherZenodoCommunities(arr), true, zenodoCommunity);
}
}
public CommunityDetails addCommunityZenodoCommunity(final String id, final String zenodoCommunity, final boolean isMain)
throws CommunityException, ResourceNotFoundException {
if (isMain) {
return updateElementToSimpleField(id, (c, val) -> c.setMainZenodoCommunity(val), zenodoCommunity);
} else {
return modifyElementToArrayField(id, c -> c.getOtherZenodoCommunities(), (c, arr) -> c.setOtherZenodoCommunities(arr), false, zenodoCommunity);
}
}
@Transactional
private CommunityDetails updateElementToSimpleField(final String id,
final BiConsumer<DbCommunity, String> setter,
final String value) throws ResourceNotFoundException, CommunityException {
final DbCommunity dbEntry = dbCommunityRepository.findById(id).orElseThrow(() -> new ResourceNotFoundException("Community not found: " + id));
setter.accept(dbEntry, value);
dbCommunityRepository.save(dbEntry);
return getCommunity(id);
}
@Transactional
private CommunityDetails modifyElementToArrayField(final String id,
final Function<DbCommunity, String[]> getter,
final BiConsumer<DbCommunity, String[]> setter,
final boolean remove,
final String... values) throws ResourceNotFoundException, CommunityException {
final DbCommunity dbEntry = dbCommunityRepository.findById(id).orElseThrow(() -> new ResourceNotFoundException("Community not found: " + id));
final Set<String> tmpList = new LinkedHashSet<>();
final String[] oldValues = getter.apply(dbEntry);
if (oldValues != null) {
for (final String s : oldValues) {
tmpList.add(s);
}
}
if (remove) {
tmpList.removeAll(Arrays.asList(values));
} else {
tmpList.addAll(Arrays.asList(values));
}
setter.accept(dbEntry, tmpList.toArray(new String[tmpList.size()]));
dbCommunityRepository.save(dbEntry);
return getCommunity(id);
}
public List<String> getOpenAIRECommunities(final String zenodoId) {
return dbCommunityRepository.findByZenodoId(zenodoId);
}
public Map<String, Set<String>> getPropagationOrganizationCommunityMap() {
return dbOrganizationRepository.findAll()
.stream()
.collect(Collectors.groupingBy(DbOrganization::getOrgId, Collectors.mapping(DbOrganization::getCommunity, Collectors.toSet())));
}
public Set<String> getPropagationOrganizationsForCommunity(final String communityId) {
return dbOrganizationRepository.findByCommunity(communityId)
.stream()
.map(DbOrganization::getOrgId)
.collect(Collectors.toSet());
}
@Transactional
public Set<String> addPropagationOrganizationForCommunity(final String communityId, final String organizationId) {
final DbOrganization o = new DbOrganization(communityId, organizationId);
dbOrganizationRepository.save(o);
return getPropagationOrganizationsForCommunity(communityId);
}
@Transactional
public Set<String> removePropagationOrganizationForCommunity(final String communityId, final String organizationId) {
final DbOrganization o = new DbOrganization(communityId, organizationId);
dbOrganizationRepository.delete(o);
return getPropagationOrganizationsForCommunity(communityId);
}
}