258 lines
13 KiB
Java
258 lines
13 KiB
Java
package eu.eudat.service.reference;
|
|
|
|
import com.fasterxml.jackson.core.JsonProcessingException;
|
|
import eu.eudat.authorization.AuthorizationFlags;
|
|
import eu.eudat.authorization.Permission;
|
|
import eu.eudat.commons.XmlHandlingService;
|
|
import eu.eudat.commons.enums.IsActive;
|
|
import eu.eudat.commons.enums.ReferenceFieldDataType;
|
|
import eu.eudat.commons.enums.ReferenceSourceType;
|
|
import eu.eudat.commons.types.reference.DefinitionEntity;
|
|
import eu.eudat.commons.types.reference.FieldEntity;
|
|
import eu.eudat.commons.types.referencetype.*;
|
|
import eu.eudat.convention.ConventionService;
|
|
import eu.eudat.data.ReferenceEntity;
|
|
import eu.eudat.data.ReferenceTypeEntity;
|
|
import eu.eudat.model.Reference;
|
|
import eu.eudat.model.ReferenceType;
|
|
import eu.eudat.model.builder.ReferenceBuilder;
|
|
import eu.eudat.model.deleter.ReferenceDeleter;
|
|
import eu.eudat.model.persist.ReferencePersist;
|
|
import eu.eudat.model.persist.referencedefinition.DefinitionPersist;
|
|
import eu.eudat.model.persist.referencedefinition.FieldPersist;
|
|
import eu.eudat.query.ReferenceQuery;
|
|
import eu.eudat.query.lookup.ReferenceSearchLookup;
|
|
import eu.eudat.service.externalfetcher.ExternalFetcherService;
|
|
import eu.eudat.service.externalfetcher.config.entities.SourceBaseConfiguration;
|
|
import eu.eudat.service.externalfetcher.criteria.ExternalReferenceCriteria;
|
|
import eu.eudat.service.externalfetcher.models.ExternalDataResult;
|
|
import gr.cite.commons.web.authz.service.AuthorizationService;
|
|
import gr.cite.tools.data.builder.BuilderFactory;
|
|
import gr.cite.tools.data.deleter.DeleterFactory;
|
|
import gr.cite.tools.data.query.QueryFactory;
|
|
import gr.cite.tools.exception.MyApplicationException;
|
|
import gr.cite.tools.exception.MyForbiddenException;
|
|
import gr.cite.tools.exception.MyNotFoundException;
|
|
import gr.cite.tools.exception.MyValidationException;
|
|
import gr.cite.tools.fieldset.BaseFieldSet;
|
|
import gr.cite.tools.fieldset.FieldSet;
|
|
import gr.cite.tools.logging.LoggerService;
|
|
import gr.cite.tools.logging.MapLogEntry;
|
|
import jakarta.persistence.EntityManager;
|
|
import jakarta.xml.bind.JAXBException;
|
|
import org.jetbrains.annotations.NotNull;
|
|
import org.slf4j.LoggerFactory;
|
|
import org.springframework.context.MessageSource;
|
|
import org.springframework.context.i18n.LocaleContextHolder;
|
|
import org.springframework.stereotype.Service;
|
|
|
|
import javax.management.InvalidApplicationException;
|
|
import javax.xml.parsers.ParserConfigurationException;
|
|
import javax.xml.transform.TransformerException;
|
|
import java.time.Instant;
|
|
import java.util.*;
|
|
import java.util.stream.Collectors;
|
|
|
|
@Service
|
|
public class ReferenceServiceImpl implements ReferenceService {
|
|
|
|
private static final LoggerService logger = new LoggerService(LoggerFactory.getLogger(ReferenceServiceImpl.class));
|
|
private final EntityManager entityManager;
|
|
private final AuthorizationService authorizationService;
|
|
private final DeleterFactory deleterFactory;
|
|
private final BuilderFactory builderFactory;
|
|
private final ConventionService conventionService;
|
|
private final MessageSource messageSource;
|
|
private final QueryFactory queryFactory;
|
|
private final XmlHandlingService xmlHandlingService;
|
|
|
|
public final ExternalFetcherService externalFetcherService;
|
|
public ReferenceServiceImpl(
|
|
EntityManager entityManager,
|
|
AuthorizationService authorizationService,
|
|
DeleterFactory deleterFactory,
|
|
BuilderFactory builderFactory,
|
|
ConventionService conventionService,
|
|
MessageSource messageSource,
|
|
QueryFactory queryFactory,
|
|
XmlHandlingService xmlHandlingService, ExternalFetcherService externalFetcherService) {
|
|
this.entityManager = entityManager;
|
|
this.authorizationService = authorizationService;
|
|
this.deleterFactory = deleterFactory;
|
|
this.builderFactory = builderFactory;
|
|
this.conventionService = conventionService;
|
|
this.messageSource = messageSource;
|
|
this.queryFactory = queryFactory;
|
|
this.xmlHandlingService = xmlHandlingService;
|
|
this.externalFetcherService = externalFetcherService;
|
|
}
|
|
|
|
@Override
|
|
public Reference persist(ReferencePersist model, FieldSet fields) throws MyForbiddenException, MyValidationException, MyApplicationException, MyNotFoundException, InvalidApplicationException, JAXBException, JsonProcessingException, TransformerException, ParserConfigurationException {
|
|
logger.debug(new MapLogEntry("persisting data").And("model", model).And("fields", fields));
|
|
|
|
this.authorizationService.authorizeForce(Permission.EditDmpBlueprint);
|
|
|
|
Boolean isUpdate = this.conventionService.isValidGuid(model.getId());
|
|
|
|
ReferenceEntity data;
|
|
if (isUpdate) {
|
|
data = this.entityManager.find(ReferenceEntity.class, model.getId());
|
|
if (data == null)
|
|
throw new MyNotFoundException(messageSource.getMessage("General_ItemNotFound", new Object[]{model.getId(), Reference.class.getSimpleName()}, LocaleContextHolder.getLocale()));
|
|
} else {
|
|
data = new ReferenceEntity();
|
|
data.setId(UUID.randomUUID());
|
|
data.setIsActive(IsActive.Active);
|
|
data.setCreatedAt(Instant.now());
|
|
}
|
|
|
|
data.setLabel(model.getLabel());
|
|
data.setTypeId(model.getTypeId());
|
|
data.setDescription(model.getDescription());
|
|
data.setDefinition(this.xmlHandlingService.toXmlSafe(this.buildDefinitionEntity(model.getDefinition())));
|
|
data.setUpdatedAt(Instant.now());
|
|
data.setReference(model.getReference());
|
|
data.setAbbreviation(model.getAbbreviation());
|
|
data.setSource(model.getSource());
|
|
data.setSourceType(model.getSourceType());
|
|
|
|
if (isUpdate) this.entityManager.merge(data);
|
|
else this.entityManager.persist(data);
|
|
|
|
this.entityManager.flush();
|
|
|
|
return this.builderFactory.builder(ReferenceBuilder.class).authorize(AuthorizationFlags.OwnerOrDmpAssociatedOrPermission).build(BaseFieldSet.build(fields, Reference._id), data);
|
|
}
|
|
|
|
private @NotNull DefinitionEntity buildDefinitionEntity(DefinitionPersist persist){
|
|
DefinitionEntity data = new DefinitionEntity();
|
|
if (persist == null) return data;
|
|
if (!this.conventionService.isListNullOrEmpty(persist.getFields())){
|
|
data.setFields(new ArrayList<>());
|
|
for (FieldPersist fieldPersist: persist.getFields()) {
|
|
data.getFields().add(this.buildFieldEntity(fieldPersist));
|
|
}
|
|
}
|
|
|
|
return data;
|
|
}
|
|
|
|
private @NotNull FieldEntity buildFieldEntity(FieldPersist persist){
|
|
FieldEntity data = new FieldEntity();
|
|
if (persist == null) return data;
|
|
|
|
data.setCode(persist.getCode());
|
|
data.setDataType(persist.getDataType());
|
|
data.setValue(persist.getValue());
|
|
|
|
return data;
|
|
}
|
|
|
|
@Override
|
|
public void deleteAndSave(UUID id) throws MyForbiddenException, InvalidApplicationException {
|
|
logger.debug("deleting : {}", id);
|
|
|
|
this.authorizationService.authorizeForce(Permission.DeleteReference);
|
|
|
|
this.deleterFactory.deleter(ReferenceDeleter.class).deleteAndSaveByIds(List.of(id));
|
|
}
|
|
|
|
@Override
|
|
public List<Reference> searchReferenceData(ReferenceSearchLookup lookup) throws MyNotFoundException {
|
|
int initialOffset = 0;
|
|
if (lookup.getPage() != null && !lookup.getPage().isEmpty()){
|
|
initialOffset = lookup.getPage().getOffset();
|
|
lookup.getPage().setOffset(0);
|
|
}
|
|
|
|
ReferenceTypeEntity data = this.entityManager.find(ReferenceTypeEntity.class, lookup.getTypeId());
|
|
if (data == null) throw new MyNotFoundException(messageSource.getMessage("General_ItemNotFound", new Object[]{lookup.getTypeId(), ReferenceType.class.getSimpleName()}, LocaleContextHolder.getLocale()));
|
|
|
|
String like;
|
|
if (lookup.getLike() != null){
|
|
like = lookup.getLike().replaceAll("%", "");
|
|
} else {
|
|
like = null;
|
|
}
|
|
ExternalReferenceCriteria externalReferenceCriteria = new ExternalReferenceCriteria(like, lookup.getDependencyReferences());
|
|
|
|
ExternalDataResult remoteRepos = this.getReferenceData(data, externalReferenceCriteria, lookup.getKey());
|
|
|
|
List<Reference> externalModels = new ArrayList<>();
|
|
if (remoteRepos != null && !this.conventionService.isListNullOrEmpty(remoteRepos.getResults())){
|
|
List<ReferenceEntity> referenceEntities = new ArrayList<>();
|
|
for (Map<String, String> result : remoteRepos.getResults()){
|
|
if (result == null || result.isEmpty()) continue;;
|
|
ReferenceEntity referenceEntity = buildReferenceEntityFromExternalData(result, data);
|
|
referenceEntities.add(referenceEntity);
|
|
}
|
|
externalModels = this.builderFactory.builder(ReferenceBuilder.class).authorize(AuthorizationFlags.OwnerOrDmpAssociatedOrPermission).build(lookup.getProject(), referenceEntities);
|
|
}
|
|
|
|
List<Reference> models = this.fetchReferenceFromDb(lookup);
|
|
|
|
for (Reference externalReference : externalModels){
|
|
if (models.stream().noneMatch(x-> x.getReference() != null && x.getSource() != null && x.getReference().equals(externalReference.getReference()) && x.getSource().equals(externalReference.getSource()))) models.add(externalReference);
|
|
}
|
|
|
|
if (!this.conventionService.isNullOrEmpty(like)) { models = models.stream().filter(x -> x.getLabel().toLowerCase(Locale.ROOT).toLowerCase().contains(like.toLowerCase(Locale.ROOT))).collect(Collectors.toList()); }
|
|
models = models.stream().sorted(Comparator.comparing(Reference::getLabel, Comparator.nullsFirst(Comparator.naturalOrder()))).collect(Collectors.toList());
|
|
|
|
if (lookup.getPage() != null && !lookup.getPage().isEmpty()){
|
|
models = models.stream().skip(initialOffset).limit(lookup.getPage().getSize()).toList();
|
|
}
|
|
|
|
return models;
|
|
}
|
|
|
|
@NotNull
|
|
private ReferenceEntity buildReferenceEntityFromExternalData(Map<String, String> result, ReferenceTypeEntity data) {
|
|
ReferenceEntity referenceEntity = new ReferenceEntity();
|
|
referenceEntity.setTypeId(data.getId());
|
|
referenceEntity.setIsActive(IsActive.Active);
|
|
referenceEntity.setReference(result.getOrDefault(ReferenceEntity.KnownFields.ReferenceId, null));
|
|
referenceEntity.setSource(result.getOrDefault(ReferenceEntity.KnownFields.Key, null));
|
|
referenceEntity.setAbbreviation(result.getOrDefault(ReferenceEntity.KnownFields.Abbreviation, null));
|
|
referenceEntity.setDescription(result.getOrDefault(ReferenceEntity.KnownFields.Description, null));
|
|
referenceEntity.setLabel(result.getOrDefault(ReferenceEntity.KnownFields.Label, null));
|
|
referenceEntity.setSourceType(ReferenceSourceType.External);
|
|
DefinitionEntity definitionEntity = new DefinitionEntity();
|
|
definitionEntity.setFields(new ArrayList<>());
|
|
for (Map.Entry<String, String> resultValue : result.entrySet()){
|
|
if (resultValue.getKey().equals(ReferenceEntity.KnownFields.ReferenceId)
|
|
|| resultValue.getKey().equals(ReferenceEntity.KnownFields.Abbreviation)
|
|
|| resultValue.getKey().equals(ReferenceEntity.KnownFields.Description)
|
|
|| resultValue.getKey().equals(ReferenceEntity.KnownFields.Label)
|
|
|| resultValue.getKey().equals(ReferenceEntity.KnownFields.SourceLabel)) continue;
|
|
FieldEntity fieldEntity = new FieldEntity();
|
|
fieldEntity.setCode(resultValue.getKey());
|
|
fieldEntity.setValue(resultValue.getValue());
|
|
fieldEntity.setDataType(ReferenceFieldDataType.Text);
|
|
definitionEntity.getFields().add(fieldEntity);
|
|
}
|
|
if (!definitionEntity.getFields().isEmpty()) referenceEntity.setDefinition(this.xmlHandlingService.toXmlSafe(definitionEntity));
|
|
return referenceEntity;
|
|
}
|
|
|
|
private List<Reference> fetchReferenceFromDb(ReferenceSearchLookup lookup){
|
|
ReferenceQuery query = lookup.enrich(this.queryFactory).authorize(AuthorizationFlags.OwnerOrDmpAssociatedOrPermission).sourceTypes(ReferenceSourceType.Internal).typeIds(lookup.getTypeId());
|
|
|
|
List<ReferenceEntity> data = query.collectAs(lookup.getProject());
|
|
return this.builderFactory.builder(ReferenceBuilder.class).authorize(AuthorizationFlags.OwnerOrDmpAssociatedOrPermission).build(lookup.getProject(), data);
|
|
}
|
|
|
|
private ExternalDataResult getReferenceData(ReferenceTypeEntity referenceType, ExternalReferenceCriteria externalReferenceCriteria, String key) {
|
|
ReferenceTypeDefinitionEntity referenceTypeDefinition = this.xmlHandlingService.fromXmlSafe(ReferenceTypeDefinitionEntity.class, referenceType.getDefinition());
|
|
if (referenceTypeDefinition == null || this.conventionService.isListNullOrEmpty(referenceTypeDefinition.getSources())) return new ExternalDataResult();
|
|
|
|
ExternalDataResult results = this.externalFetcherService.getExternalData(referenceTypeDefinition.getSources().stream().map(x -> (SourceBaseConfiguration)x).collect(Collectors.toList()), externalReferenceCriteria, key);
|
|
for (Map<String, String> result: results.getResults()) {
|
|
result.put("referenceType", referenceType.getName());
|
|
}
|
|
return results;
|
|
}
|
|
|
|
|
|
}
|