argos/dmp-backend/core/src/main/java/eu/eudat/service/prefillingsource/PrefillingSourceServiceImpl...

579 lines
36 KiB
Java

package eu.eudat.service.prefillingsource;
import eu.eudat.authorization.AuthorizationFlags;
import eu.eudat.authorization.Permission;
import eu.eudat.commons.JsonHandlingService;
import eu.eudat.commons.XmlHandlingService;
import eu.eudat.commons.enums.IsActive;
import eu.eudat.commons.types.descriptiontemplate.DefinitionEntity;
import eu.eudat.commons.types.descriptiontemplate.FieldEntity;
import eu.eudat.commons.types.descriptiontemplate.FieldSetEntity;
import eu.eudat.commons.types.descriptiontemplate.fielddata.ReferenceTypeDataEntity;
import eu.eudat.commons.types.descriptiontemplate.fielddata.SelectDataEntity;
import eu.eudat.commons.types.externalfetcher.*;
import eu.eudat.commons.types.prefillingsource.PrefillingSourceDefinitionEntity;
import eu.eudat.commons.types.prefillingsource.PrefillingSourceDefinitionFieldEntity;
import eu.eudat.commons.types.prefillingsource.PrefillingSourceDefinitionFixedValueFieldEntity;
import eu.eudat.convention.ConventionService;
import eu.eudat.data.DescriptionTemplateEntity;
import eu.eudat.data.PrefillingSourceEntity;
import eu.eudat.data.TenantEntityManager;
import eu.eudat.errorcode.ErrorThesaurusProperties;
import eu.eudat.model.*;
import eu.eudat.model.builder.DescriptionTemplateBuilder;
import eu.eudat.model.builder.PrefillingSourceBuilder;
import eu.eudat.model.deleter.PrefillingSourceDeleter;
import eu.eudat.model.descriptionproperties.*;
import eu.eudat.model.persist.PrefillingSearchRequest;
import eu.eudat.model.persist.DescriptionProfilingRequest;
import eu.eudat.model.persist.PrefillingSourcePersist;
import eu.eudat.model.persist.externalfetcher.*;
import eu.eudat.model.persist.prefillingsourcedefinition.PrefillingSourceDefinitionFieldPersist;
import eu.eudat.model.persist.prefillingsourcedefinition.PrefillingSourceDefinitionFixedValueFieldPersist;
import eu.eudat.model.persist.prefillingsourcedefinition.PrefillingSourceDefinitionPersist;
import eu.eudat.model.prefillingsourcedefinition.PrefillingSourceDefinition;
import eu.eudat.model.referencedefinition.Definition;
import eu.eudat.query.PrefillingSourceQuery;
import eu.eudat.query.lookup.ReferenceSearchLookup;
import eu.eudat.service.externalfetcher.ExternalFetcherService;
import eu.eudat.service.externalfetcher.criteria.ExternalReferenceCriteria;
import eu.eudat.service.externalfetcher.models.ExternalDataResult;
import eu.eudat.service.reference.ReferenceService;
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.xml.bind.JAXBException;
import org.apache.commons.lang3.StringEscapeUtils;
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 org.xml.sax.SAXException;
import javax.management.InvalidApplicationException;
import javax.xml.parsers.ParserConfigurationException;
import java.io.IOException;
import java.time.Instant;
import java.time.LocalDate;
import java.time.ZoneOffset;
import java.time.format.DateTimeFormatter;
import java.time.format.DateTimeParseException;
import java.time.temporal.ChronoUnit;
import java.util.*;
import java.util.stream.Collectors;
import java.util.stream.Stream;
@Service
public class PrefillingSourceServiceImpl implements PrefillingSourceService {
private static final LoggerService logger = new LoggerService(LoggerFactory.getLogger(PrefillingSourceServiceImpl.class));
private final TenantEntityManager entityManager;
private final AuthorizationService authorizationService;
private final DeleterFactory deleterFactory;
private final BuilderFactory builderFactory;
private final QueryFactory queryFactory;
private final ConventionService conventionService;
private final MessageSource messageSource;
private final XmlHandlingService xmlHandlingService;
private final ExternalFetcherService externalFetcherService;
private final ErrorThesaurusProperties errors;
private final JsonHandlingService jsonHandlingService;
private final ReferenceService referenceService;
private static final String Zenodo = "Zenodo";
public PrefillingSourceServiceImpl(
TenantEntityManager entityManager, AuthorizationService authorizationService, DeleterFactory deleterFactory, BuilderFactory builderFactory,
QueryFactory queryFactory, ConventionService conventionService, MessageSource messageSource,
XmlHandlingService xmlHandlingService, ExternalFetcherService externalFetcherService, ErrorThesaurusProperties errors, JsonHandlingService jsonHandlingService, ReferenceService referenceService) {
this.entityManager = entityManager;
this.authorizationService = authorizationService;
this.deleterFactory = deleterFactory;
this.builderFactory = builderFactory;
this.queryFactory = queryFactory;
this.conventionService = conventionService;
this.messageSource = messageSource;
this.xmlHandlingService = xmlHandlingService;
this.externalFetcherService = externalFetcherService;
this.errors = errors;
this.jsonHandlingService = jsonHandlingService;
this.referenceService = referenceService;
}
public PrefillingSource persist(PrefillingSourcePersist model, FieldSet fields) throws MyForbiddenException, MyValidationException, MyApplicationException, MyNotFoundException, InvalidApplicationException, JAXBException {
logger.debug(new MapLogEntry("persisting data").And("model", model).And("fields", fields));
this.authorizationService.authorizeForce(Permission.EditPrefillingSource);
Boolean isUpdate = this.conventionService.isValidGuid(model.getId());
PrefillingSourceEntity data;
if (isUpdate) {
data = this.entityManager.find(PrefillingSourceEntity.class, model.getId());
if (data == null)
throw new MyNotFoundException(messageSource.getMessage("General_ItemNotFound", new Object[]{model.getId(), PrefillingSource.class.getSimpleName()}, LocaleContextHolder.getLocale()));
if (!this.conventionService.hashValue(data.getUpdatedAt()).equals(model.getHash())) throw new MyValidationException(this.errors.getHashConflict().getCode(), this.errors.getHashConflict().getMessage());
} else {
data = new PrefillingSourceEntity();
data.setId(UUID.randomUUID());
data.setIsActive(IsActive.Active);
data.setCreatedAt(Instant.now());
}
data.setLabel(model.getLabel());
data.setDefinition(this.xmlHandlingService.toXml(this.buildDefinitionEntity(model.getDefinition())));
data.setUpdatedAt(Instant.now());
if (isUpdate) this.entityManager.merge(data);
else this.entityManager.persist(data);
this.entityManager.flush();
return this.builderFactory.builder(PrefillingSourceBuilder.class).authorize(AuthorizationFlags.OwnerOrDmpAssociatedOrPermission).build(BaseFieldSet.build(fields, PrefillingSource._id), data);
}
private @NotNull PrefillingSourceDefinitionEntity buildDefinitionEntity(PrefillingSourceDefinitionPersist persist) {
PrefillingSourceDefinitionEntity data = new PrefillingSourceDefinitionEntity();
if (persist == null)
return data;
if (!this.conventionService.isListNullOrEmpty(persist.getFields())) {
data.setFields(new ArrayList<>());
for (PrefillingSourceDefinitionFieldPersist fieldPersist : persist.getFields()) {
data.getFields().add(this.buildFieldEntity(fieldPersist));
}
}
if (!this.conventionService.isListNullOrEmpty(persist.getFixedValueFields())) {
data.setFixedValueFields(new ArrayList<>());
for (PrefillingSourceDefinitionFixedValueFieldPersist fieldPersist : persist.getFixedValueFields()) {
data.getFixedValueFields().add(this.buildFixedValueFieldEntity(fieldPersist));
}
}
if (persist.getSearchConfiguration() != null ) {
data.setSearchConfiguration(this.buildExternalFetcherApiConfigEntity(persist.getSearchConfiguration()));
}
if (persist.getGetConfiguration() != null && persist.getGetEnabled()) {
data.setGetConfiguration(this.buildExternalFetcherApiConfigEntity(persist.getGetConfiguration()));
}
return data;
}
private @NotNull PrefillingSourceDefinitionFieldEntity buildFieldEntity(PrefillingSourceDefinitionFieldPersist persist) {
PrefillingSourceDefinitionFieldEntity data = new PrefillingSourceDefinitionFieldEntity();
if (persist == null)
return data;
data.setCode(persist.getCode());
data.setSemanticTarget(persist.getSemanticTarget());
data.setSystemFieldTarget(persist.getSystemFieldTarget());
data.setTrimRegex(persist.getTrimRegex());
return data;
}
private @NotNull PrefillingSourceDefinitionFixedValueFieldEntity buildFixedValueFieldEntity(PrefillingSourceDefinitionFixedValueFieldPersist persist) {
PrefillingSourceDefinitionFixedValueFieldEntity data = new PrefillingSourceDefinitionFixedValueFieldEntity();
if (persist == null)
return data;
data.setSemanticTarget(persist.getSemanticTarget());
data.setSystemFieldTarget(persist.getSystemFieldTarget());
data.setFixedValue(persist.getFixedValue());
data.setTrimRegex(persist.getTrimRegex());
return data;
}
private @NotNull ExternalFetcherApiSourceConfigurationEntity buildExternalFetcherApiConfigEntity(ExternalFetcherApiSourceConfigurationPersist persist) {
ExternalFetcherApiSourceConfigurationEntity data = new ExternalFetcherApiSourceConfigurationEntity();
if (persist == null)
return data;
data.setUrl(persist.getUrl());
if (persist.getResults() != null ) {
data.setResults(this.buildResultsConfigEntity(persist.getResults()));
}
data.setKey(persist.getKey());
data.setLabel(persist.getLabel());
data.setOrdinal(persist.getOrdinal());
data.setType(persist.getType());
data.setReferenceTypeDependencyIds(persist.getReferenceTypeDependencyIds());
data.setPaginationPath(persist.getPaginationPath());
data.setContentType(persist.getContentType());
data.setFirstPage(persist.getFirstPage());
data.setHttpMethod(persist.getHttpMethod());
data.setRequestBody(persist.getRequestBody());
data.setFilterType(persist.getFilterType());
if (persist.getAuth() != null) {
data.setAuth(this.buildAuthConfigEntity(persist.getAuth()));
}
if (!this.conventionService.isListNullOrEmpty(persist.getQueries())){
data.setQueries(new ArrayList<>());
for (QueryConfigPersist queryConfigPersist: (persist.getQueries())){
data.getQueries().add(this.buildQueryConfigEntity(queryConfigPersist));
}
}
return data;
}
private @NotNull ResultsConfigurationEntity buildResultsConfigEntity(ResultsConfigurationPersist persist){
ResultsConfigurationEntity data = new ResultsConfigurationEntity();
if (persist == null) return data;
data.setResultsArrayPath(persist.getResultsArrayPath());
if (!this.conventionService.isListNullOrEmpty(persist.getFieldsMapping())){
data.setFieldsMapping(new ArrayList<>());
for (ResultFieldsMappingConfigurationPersist fieldsMappingPersist: persist.getFieldsMapping()) {
data.getFieldsMapping().add(this.buildResultFieldsMappingConfigEntity(fieldsMappingPersist));
}
}
return data;
}
private @NotNull ResultFieldsMappingConfigurationEntity buildResultFieldsMappingConfigEntity(ResultFieldsMappingConfigurationPersist persist){
ResultFieldsMappingConfigurationEntity data = new ResultFieldsMappingConfigurationEntity();
if (persist == null) return data;
data.setCode(persist.getCode());
data.setResponsePath(persist.getResponsePath());
return data;
}
private @NotNull AuthenticationConfigurationEntity buildAuthConfigEntity(AuthenticationConfigurationPersist persist){
AuthenticationConfigurationEntity data = new AuthenticationConfigurationEntity();
if (persist == null) return data;
data.setEnabled(persist.getEnabled());
data.setAuthUrl(persist.getAuthUrl());
data.setAuthMethod(persist.getAuthMethod());
data.setAuthRequestBody(persist.getAuthRequestBody());
data.setType(persist.getType());
data.setAuthTokenPath(persist.getAuthTokenPath());
return data;
}
private @NotNull QueryConfigEntity buildQueryConfigEntity(QueryConfigPersist persist){
QueryConfigEntity data = new QueryConfigEntity();
if (persist == null) return data;
data.setName(persist.getName());
data.setDefaultValue(persist.getDefaultValue());
if (!this.conventionService.isListNullOrEmpty(persist.getCases())){
data.setCases(new ArrayList<>());
for (QueryCaseConfigPersist queryCaseConfigPersist: persist.getCases()) {
data.getCases().add(this.buildQueryCaseConfigEntity(queryCaseConfigPersist));
}
}
return data;
}
private @NotNull QueryCaseConfigEntity buildQueryCaseConfigEntity(QueryCaseConfigPersist persist){
QueryCaseConfigEntity data = new QueryCaseConfigEntity();
if (persist == null) return data;
data.setReferenceTypeId(persist.getReferenceTypeId());
data.setReferenceTypeSourceKey(persist.getReferenceTypeSourceKey());
data.setSeparator(persist.getSeparator());
data.setValue(persist.getValue());
data.setLikePattern(persist.getLikePattern());
return data;
}
public void deleteAndSave(UUID id) throws MyForbiddenException, InvalidApplicationException {
logger.debug("deleting : {}", id);
this.authorizationService.authorizeForce(Permission.DeletePrefillingSource);
this.deleterFactory.deleter(PrefillingSourceDeleter.class).deleteAndSaveByIds(List.of(id));
}
public List<Prefilling> searchPrefillings(PrefillingSearchRequest model) {
PrefillingSourceEntity prefillingSourceEntity = this.queryFactory.query(PrefillingSourceQuery.class).ids(model.getPrefillingSourceId()).isActive(IsActive.Active).first();
if (prefillingSourceEntity == null)
throw new MyNotFoundException(messageSource.getMessage("General_ItemNotFound", new Object[]{model.getPrefillingSourceId(), PrefillingSource.class.getSimpleName()}, LocaleContextHolder.getLocale()));
PrefillingSourceDefinitionEntity prefillingSourceDefinition = this.xmlHandlingService.fromXmlSafe(PrefillingSourceDefinitionEntity.class, prefillingSourceEntity.getDefinition());
if (prefillingSourceDefinition == null)
throw new MyNotFoundException(messageSource.getMessage("General_ItemNotFound", new Object[]{model.getPrefillingSourceId(), PrefillingSourceDefinition.class.getSimpleName()}, LocaleContextHolder.getLocale()));
ExternalReferenceCriteria externalReferenceCriteria = new ExternalReferenceCriteria();
externalReferenceCriteria.setLike(model.getLike());
ExternalDataResult externalData = this.externalFetcherService.getExternalData(Stream.of(prefillingSourceDefinition.getSearchConfiguration()).collect(Collectors.toList()), externalReferenceCriteria, null);
if (externalData == null || this.conventionService.isListNullOrEmpty(externalData.getResults())) {
return null;
}
List<Prefilling> prefillings = new ArrayList<>();
for (Map<String, String> result : externalData.getResults()) {
Prefilling prefilling = new Prefilling();
prefilling.setId(result.getOrDefault(Prefilling._id, null));
prefilling.setLabel(result.getOrDefault(Prefilling._label, null));
prefilling.setKey(result.getOrDefault(Prefilling._key, null));
prefilling.setTag(result.getOrDefault(Prefilling._tag, null));
prefillings.add(prefilling);
}
prefillings = prefillings.stream().sorted(Comparator.comparing(Prefilling::getLabel, Comparator.nullsFirst(Comparator.naturalOrder()))).collect(Collectors.toList());
return prefillings;
}
public Description getPrefilledDescription(DescriptionProfilingRequest model, FieldSet fieldSet) throws JAXBException, ParserConfigurationException, IOException, InstantiationException, IllegalAccessException, SAXException, InvalidApplicationException {
PrefillingSourceEntity prefillingSourceEntity = this.queryFactory.query(PrefillingSourceQuery.class).ids(model.getPrefillingSourceId()).first();
if (prefillingSourceEntity == null) throw new MyNotFoundException(messageSource.getMessage("General_ItemNotFound", new Object[]{model.getPrefillingSourceId(), PrefillingSource.class.getSimpleName()}, LocaleContextHolder.getLocale()));
PrefillingSourceDefinitionEntity prefillingSourceDefinition = this.xmlHandlingService.fromXmlSafe(PrefillingSourceDefinitionEntity.class, prefillingSourceEntity.getDefinition());
if (prefillingSourceDefinition == null) throw new MyNotFoundException(messageSource.getMessage("General_ItemNotFound", new Object[]{model.getPrefillingSourceId(), PrefillingSourceDefinition.class.getSimpleName()}, LocaleContextHolder.getLocale()));
ExternalReferenceCriteria externalReferenceCriteria = new ExternalReferenceCriteria();
externalReferenceCriteria.setLike(model.getPrefillId());
ExternalDataResult externalData = this.externalFetcherService.getExternalData(Stream.of(prefillingSourceDefinition.getGetConfiguration()).collect(Collectors.toList()), externalReferenceCriteria, null);
if (externalData == null || this.conventionService.isListNullOrEmpty(externalData.getResults())) {
return null;
}
DescriptionTemplateEntity descriptionTemplateEntity = this.entityManager.find(DescriptionTemplateEntity.class, model.getDescriptionTemplateId());
if (descriptionTemplateEntity == null) throw new MyNotFoundException(messageSource.getMessage("General_ItemNotFound", new Object[]{model.getDescriptionTemplateId(), DescriptionTemplate.class.getSimpleName()}, LocaleContextHolder.getLocale()));
eu.eudat.commons.types.descriptiontemplate.DefinitionEntity descriptionTemplateDefinition = this.xmlHandlingService.fromXml(eu.eudat.commons.types.descriptiontemplate.DefinitionEntity.class, descriptionTemplateEntity.getDefinition());
Description description = new Description();
FieldSet descriptionTemplateFields = fieldSet.extractPrefixed(this.conventionService.asPrefix(Description._descriptionTemplate));
description.setDescriptionTemplate(this.builderFactory.builder(DescriptionTemplateBuilder.class).authorize(AuthorizationFlags.OwnerOrDmpAssociatedOrPermission).build(descriptionTemplateFields, descriptionTemplateEntity));
return mapPrefilledEntityToDescription(description, descriptionTemplateDefinition, prefillingSourceDefinition, prefillingSourceEntity.getLabel(), externalData.getResults().getFirst());//TODO
}
private Description mapPrefilledEntityToDescription(Description description, DefinitionEntity descriptionTemplateDefinition, PrefillingSourceDefinitionEntity prefillingSourceDefinition, String type, Map<String, String> externalData){
if (!this.conventionService.isListNullOrEmpty(prefillingSourceDefinition.getFields())) {
for (PrefillingSourceDefinitionFieldEntity field : prefillingSourceDefinition.getFields()) {
String sourceValue = externalData.get(field.getCode());
this.prefillSystemValueToDescription(description, field.getSystemFieldTarget(), sourceValue);
this.prefillSemanticValueToDescription(description, field.getSemanticTarget(), sourceValue, descriptionTemplateDefinition, type);
}
}
if (!this.conventionService.isListNullOrEmpty(prefillingSourceDefinition.getFixedValueFields())){
for (PrefillingSourceDefinitionFixedValueFieldEntity field: prefillingSourceDefinition.getFixedValueFields()) {
this.prefillSystemValueToDescription(description, field.getSystemFieldTarget(), field.getFixedValue());
this.prefillSemanticValueToDescription(description, field.getSemanticTarget(), field.getFixedValue(), descriptionTemplateDefinition, type);
}
}
if (!this.conventionService.isListNullOrEmpty(prefillingSourceDefinition.getFields())) {
for (PrefillingSourceDefinitionFieldEntity field : prefillingSourceDefinition.getFields()) {
String sourceValue = externalData.get(field.getCode());
this.ensureZenodoFields(description, field.getSemanticTarget(), sourceValue, descriptionTemplateDefinition, type);
}
}
if (!this.conventionService.isListNullOrEmpty(prefillingSourceDefinition.getFixedValueFields())) {
for (PrefillingSourceDefinitionFixedValueFieldEntity field : prefillingSourceDefinition.getFixedValueFields()) {
this.ensureZenodoFields(description, field.getSemanticTarget(), field.getFixedValue(), descriptionTemplateDefinition, type);
}
}
return description;
}
private void ensureZenodoFields(Description description, String semanticTarget, String value, DefinitionEntity definition, String type) {
if (!this.conventionService.isNullOrEmpty(type) && !this.conventionService.isNullOrEmpty(semanticTarget) && !this.conventionService.isNullOrEmpty(value) && type.equals(Zenodo)) {
if (semanticTarget.equals("rda.dataset.distribution.data_access")) {
if (value.equals("open")) {
List<FieldEntity> issuedFieldEntities = definition.getAllField().stream().filter(x -> x.getSchematics() != null && x.getSchematics().contains("rda.dataset.issued")).toList();
if (!this.conventionService.isListNullOrEmpty(issuedFieldEntities)) {
String issuedIdNode = issuedFieldEntities.getFirst().getId();
String issuedValue = this.conventionService.isNullOrEmpty(issuedIdNode) ? null : description.getProperties().getFieldSets().values().stream().map(PropertyDefinitionFieldSet::getItems).flatMap(List::stream)
.filter(x -> x.getFields() != null && x.getFields().containsKey(issuedIdNode)).map(x -> x.getFields().get(issuedIdNode).getTextValue()).findFirst().orElse(null);
if (!this.conventionService.isNullOrEmpty(issuedValue)) {
List<FieldSetEntity> licStartFieldSetsEntities = definition.getAllFieldSets().stream().filter(x -> x.getAllField() != null && x.getAllField().stream().anyMatch(y -> y.getSchematics() != null && y.getSchematics().contains("rda.dataset.distribution.license.start_date"))).toList();
for (FieldSetEntity licStartFieldSetEntity : licStartFieldSetsEntities) {
List<FieldEntity> licStartEntities = licStartFieldSetEntity.getAllField().stream().filter(x -> x.getSchematics() != null && x.getSchematics().contains("rda.dataset.distribution.license.start_date")).toList();
if (!this.conventionService.isListNullOrEmpty(licStartEntities)) {
this.ensureFieldSetEntity(description, licStartFieldSetEntity);
for (FieldEntity licStartDateNode : licStartEntities) {
description.getProperties().getFieldSets().get(licStartFieldSetEntity.getId()).getItems().getFirst().getFields().put(licStartDateNode.getId(), buildPropertyDefinitionFieldItemValue(licStartDateNode, semanticTarget, issuedValue, type));
}
}
}
}
}
}
}
}
}
private void ensureFieldSetEntity(Description description, FieldSetEntity fieldSetEntity){
if (description.getProperties() == null) description.setProperties(new PropertyDefinition());
if (description.getProperties().getFieldSets() == null) description.getProperties().setFieldSets(new HashMap<>());
if (!description.getProperties().getFieldSets().containsKey(fieldSetEntity.getId())) description.getProperties().getFieldSets().put(fieldSetEntity.getId(), new PropertyDefinitionFieldSet());
if (description.getProperties().getFieldSets().get(fieldSetEntity.getId()).getItems() == null) description.getProperties().getFieldSets().get(fieldSetEntity.getId()).setItems(new ArrayList<>());
if (this.conventionService.isListNullOrEmpty(description.getProperties().getFieldSets().get(fieldSetEntity.getId()).getItems())) description.getProperties().getFieldSets().get(fieldSetEntity.getId()).getItems().add(new PropertyDefinitionFieldSetItem());
if (description.getProperties().getFieldSets().get(fieldSetEntity.getId()).getItems().getFirst().getFields() == null) description.getProperties().getFieldSets().get(fieldSetEntity.getId()).getItems().getFirst().setFields(new HashMap<>());
if (description.getProperties().getFieldSets().get(fieldSetEntity.getId()).getItems().getFirst().getOrdinal() == null) description.getProperties().getFieldSets().get(fieldSetEntity.getId()).getItems().getFirst().setOrdinal(0);
}
private void prefillSemanticValueToDescription(Description description, String semanticTarget, String parsedValue, DefinitionEntity definition, String type) {
if (this.conventionService.isNullOrEmpty(semanticTarget) || this.conventionService.isNullOrEmpty(parsedValue)) return;
List<FieldSetEntity> fieldSetsEntities = definition.getAllFieldSets().stream().filter(x-> x.getAllField() != null && x.getAllField().stream().anyMatch(y-> !this.conventionService.isListNullOrEmpty(y.getSchematics()) && y.getSchematics().contains(semanticTarget))).toList();
for (FieldSetEntity fieldSetEntity: fieldSetsEntities) {
List<FieldEntity> fieldEntities = fieldSetEntity.getAllField().stream().filter(x-> !this.conventionService.isListNullOrEmpty(x.getSchematics()) && x.getSchematics().contains(semanticTarget)).toList();
if (!this.conventionService.isListNullOrEmpty(fieldEntities)) {
this.ensureFieldSetEntity(description, fieldSetEntity);
for (FieldEntity fieldEntity : fieldEntities){
description.getProperties().getFieldSets().get(fieldSetEntity.getId()).getItems().getFirst().getFields().put(fieldEntity.getId() , buildPropertyDefinitionFieldItemValue(fieldEntity, semanticTarget, parsedValue, type));
}
}
}
}
private void prefillSystemValueToDescription(Description description, String systemFieldTarget, String parsedValue) {
if (this.conventionService.isNullOrEmpty(systemFieldTarget) || this.conventionService.isNullOrEmpty(parsedValue)) return;
switch (systemFieldTarget) {
case Description._description -> description.setDescription(parsedValue);
case Description._label -> description.setLabel(parsedValue);
case Description._descriptionTags -> {
String[] valuesParsed = this.tryParseJsonAsObjectString(String[].class, parsedValue);
List<String> finalValue = valuesParsed == null ? List.of(parsedValue) : Arrays.stream(valuesParsed).toList();
for (String tagString : finalValue) {
if (description.getDescriptionTags() == null) description.setDescriptionTags(new ArrayList<>());
if (description.getDescriptionTags().stream().anyMatch(x -> x.getTag() != null && x.getTag().getLabel().equals(tagString))) continue;
DescriptionTag descriptionTag = new DescriptionTag();
Tag tag = new Tag();
tag.setLabel(tagString.trim());
descriptionTag.setTag(tag);
description.getDescriptionTags().add(descriptionTag);
}
}
}
}
private Field buildPropertyDefinitionFieldItemValue(FieldEntity fieldEntity, String semanticTarget, String value, String type) {
Field field = new Field();
if (fieldEntity == null || fieldEntity.getData() == null || fieldEntity.getData().getFieldType() == null || this.conventionService.isNullOrEmpty(value)) return field;
try{
switch (fieldEntity.getData().getFieldType()){
case FREE_TEXT, TEXT_AREA, RICH_TEXT_AREA, RADIO_BOX -> field.setTextValue(value.toLowerCase(Locale.ROOT));
case CHECK_BOX, BOOLEAN_DECISION -> field.setTextValue(value.trim().toLowerCase(Locale.ROOT));
case DATE_PICKER ->{
Instant instant = null;
try {
if (!this.conventionService.isNullOrEmpty(type) && type.equals(Zenodo) && semanticTarget.equals("rda.dataset.distribution.available_until") ) {
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("uuuu-MM-dd");
LocalDate date = LocalDate.parse(value, formatter);
date = date.plusYears(20);
instant = date.atStartOfDay().toInstant(ZoneOffset.UTC);
} else {
instant = Instant.parse(value);
}
} catch (DateTimeParseException ex) {
instant = LocalDate.parse(value).atStartOfDay().toInstant(ZoneOffset.UTC);
if (!this.conventionService.isNullOrEmpty(type) && type.equals(Zenodo) && semanticTarget.equals("rda.dataset.distribution.available_until") ) {
instant.plus(20, ChronoUnit.YEARS);
}
}
field.setDateValue(instant);
}
case DATASET_IDENTIFIER -> {
ExternalIdentifier externalIdentifier = new ExternalIdentifier();
externalIdentifier.setIdentifier(value);
if(!this.conventionService.isNullOrEmpty(type) && type.equals(Zenodo)) externalIdentifier.setType("doi");
field.setExternalIdentifier(externalIdentifier);
}
case SELECT -> {
String[] valuesParsed = this.tryParseJsonAsObjectString(String[].class, value);
List<String> finalValue = valuesParsed == null ? List.of(value) : Arrays.stream(valuesParsed).toList();
SelectDataEntity selectDataEntity = (SelectDataEntity) fieldEntity.getData();
if (selectDataEntity == null || selectDataEntity.getOptions() == null) throw new MyApplicationException("Can not cast fieldEntity data");
field.setTextListValue(new ArrayList<>());
for (SelectDataEntity.OptionEntity entity : selectDataEntity.getOptions()){
if (finalValue.contains(entity.getValue()) || finalValue.contains(entity.getLabel())){
field.getTextListValue().add(entity.getValue());
}
}
}
case TAGS -> {
String[] valuesParsed = this.tryParseJsonAsObjectString(String[].class, value);
field.setTextListValue(valuesParsed == null ? List.of(value) : Arrays.stream(valuesParsed).toList()); //TODO Tags, Currency is ids
}
case REFERENCE_TYPES -> {
String[] valuesParsed = this.tryParseJsonAsObjectString(String[].class, value);
List<String> finalValue = valuesParsed == null ? List.of(value) : Arrays.stream(valuesParsed).toList();
ReferenceTypeDataEntity selectDataEntity = (ReferenceTypeDataEntity) fieldEntity.getData();
if (selectDataEntity == null) throw new MyApplicationException("Can not cast fieldEntity data");
field.setReferences(new ArrayList<>());
for (String like : finalValue){
ReferenceSearchLookup externalReferenceCriteria = new ReferenceSearchLookup();
externalReferenceCriteria.setLike(like);
externalReferenceCriteria.setTypeId(selectDataEntity.getReferenceTypeId());
externalReferenceCriteria.setProject((BaseFieldSet) new BaseFieldSet()
.ensure(Reference._id)
.ensure(Reference._label)
.ensure(Reference._type)
.ensure(Reference._description)
.ensure(this.conventionService.asIndexer(Reference._description, Definition._fields, eu.eudat.model.referencedefinition.Field._code))
.ensure(this.conventionService.asIndexer(Reference._description, Definition._fields, eu.eudat.model.referencedefinition.Field._dataType))
.ensure(this.conventionService.asIndexer(Reference._description, Definition._fields, eu.eudat.model.referencedefinition.Field._value))
.ensure(Reference._reference)
.ensure(Reference._abbreviation)
.ensure(Reference._source)
.ensure(Reference._isActive)
.ensure(Reference._createdAt)
.ensure(Reference._updatedAt)
.ensure(Reference._hash)
);
List<Reference> references = this.referenceService.searchReferenceData(externalReferenceCriteria);
for (Reference reference : references){
if (reference.getReference().equals(like) || reference.getLabel().toUpperCase(Locale.ROOT).contains(like.toUpperCase(Locale.ROOT))) {
field.getReferences().add(reference);
}
}
}
}
case VALIDATION, UPLOAD, INTERNAL_ENTRIES_DMPS, INTERNAL_ENTRIES_DESCRIPTIONS -> throw new MyApplicationException("invalid type " + fieldEntity.getData().getFieldType());
default -> throw new MyApplicationException("invalid type " + fieldEntity.getData().getFieldType());
}
} catch (Exception e){
logger.error("Could not parse value " + value + " of field " + fieldEntity.getId() + " with type " + fieldEntity.getData().getFieldType(), e);
}
return field;
}
private <T> T tryParseJsonAsObjectString(Class<T> type, String value){
T item = this.jsonHandlingService.fromJsonSafe(type, value);
if (item == null) item = this.jsonHandlingService.fromJsonSafe(type, StringEscapeUtils.unescapeJava(value));
if (item == null) item = this.jsonHandlingService.fromJsonSafe(type, StringEscapeUtils.unescapeJson(value));
return item;
}
}