788 lines
43 KiB
Java
788 lines
43 KiB
Java
package eu.old.eudat.migration;
|
|
|
|
import com.fasterxml.jackson.annotation.JsonValue;
|
|
import eu.old.eudat.models.data.components.commons.DefaultValue;
|
|
import org.opencdmp.commons.XmlHandlingService;
|
|
import org.opencdmp.commons.enums.*;
|
|
import org.opencdmp.commons.types.descriptiontemplate.*;
|
|
import org.opencdmp.commons.types.descriptiontemplate.fielddata.*;
|
|
import org.opencdmp.commons.types.externalfetcher.*;
|
|
import org.opencdmp.commons.types.referencetype.*;
|
|
import org.opencdmp.convention.ConventionService;
|
|
import org.opencdmp.data.DescriptionTemplateEntity;
|
|
import org.opencdmp.data.ReferenceEntity;
|
|
import org.opencdmp.data.ReferenceTypeEntity;
|
|
import org.opencdmp.data.converters.enums.DatabaseEnum;
|
|
import org.opencdmp.model.DescriptionTemplate;
|
|
import org.opencdmp.query.DescriptionTemplateQuery;
|
|
import org.opencdmp.query.ReferenceTypeQuery;
|
|
import eu.old.eudat.logic.services.helpers.HelpersService;
|
|
import eu.old.eudat.logic.utilities.builders.XmlBuilder;
|
|
import eu.old.eudat.models.data.components.commons.Multiplicity;
|
|
import eu.old.eudat.models.data.components.commons.Rule;
|
|
import eu.old.eudat.models.data.components.commons.datafield.*;
|
|
import eu.old.eudat.models.data.entities.xmlmodels.datasetprofiledefinition.*;
|
|
import gr.cite.tools.data.query.Ordering;
|
|
import gr.cite.tools.data.query.Paging;
|
|
import gr.cite.tools.data.query.QueryFactory;
|
|
import gr.cite.tools.exception.MyApplicationException;
|
|
import gr.cite.tools.logging.LoggerService;
|
|
import jakarta.persistence.EntityManager;
|
|
import jakarta.ws.rs.NotSupportedException;
|
|
import jakarta.xml.bind.JAXBException;
|
|
import org.apache.commons.lang3.StringUtils;
|
|
import org.elasticsearch.common.inject.Guice;
|
|
import org.jetbrains.annotations.NotNull;
|
|
import org.slf4j.LoggerFactory;
|
|
import org.springframework.http.MediaType;
|
|
import org.springframework.stereotype.Service;
|
|
import org.w3c.dom.Document;
|
|
import org.xml.sax.SAXException;
|
|
|
|
import javax.management.InvalidApplicationException;
|
|
import javax.xml.parsers.ParserConfigurationException;
|
|
import javax.xml.transform.TransformerException;
|
|
import java.io.IOException;
|
|
import java.net.URI;
|
|
import java.net.URISyntaxException;
|
|
import java.time.Instant;
|
|
import java.time.LocalDate;
|
|
import java.time.ZoneOffset;
|
|
import java.time.format.DateTimeParseException;
|
|
import java.util.*;
|
|
import java.util.stream.Collectors;
|
|
|
|
@Service
|
|
public class DescriptionTemplateXmlMigrationService {
|
|
|
|
private static final LoggerService logger = new LoggerService(LoggerFactory.getLogger(DescriptionTemplateXmlMigrationService.class));
|
|
private final EntityManager entityManager;
|
|
private final ConventionService conventionService;
|
|
private final XmlHandlingService xmlHandlingService;
|
|
private final QueryFactory queryFactory;
|
|
private final MigrationTools migrationTools;
|
|
|
|
private static final int PageSize = 500;
|
|
private static final boolean TestMode = false;
|
|
|
|
public DescriptionTemplateXmlMigrationService(EntityManager entityManager, ConventionService conventionService, XmlHandlingService xmlHandlingService, QueryFactory queryFactory, MigrationTools migrationTools) {
|
|
this.entityManager = entityManager;
|
|
this.conventionService = conventionService;
|
|
this.xmlHandlingService = xmlHandlingService;
|
|
this.queryFactory = queryFactory;
|
|
this.migrationTools = migrationTools;
|
|
}
|
|
|
|
public void migrate() throws IOException, NoSuchFieldException, IllegalAccessException, JAXBException, ParserConfigurationException, InstantiationException, SAXException, InvalidApplicationException, TransformerException, URISyntaxException {
|
|
long total = this.queryFactory.query(DescriptionTemplateQuery.class).count();
|
|
logger.debug("Migrate DescriptionTemplate Total : " + total);
|
|
int page = 0;
|
|
|
|
Map<String, ReferenceTypeEntity> referenceTypeEntityMap = new HashMap<>();
|
|
Map<UUID, ReferenceTypeEntity> knownReferenceEntities = this.queryFactory.query(ReferenceTypeQuery.class).ids(ReferenceTypeIds.KnownReferenceTypeIds).collect().stream().collect(Collectors.toMap(ReferenceTypeEntity::getId, x-> x));
|
|
List<DescriptionTemplateEntity> items;
|
|
do {
|
|
DescriptionTemplateQuery query = this.queryFactory.query(DescriptionTemplateQuery.class);
|
|
query.setOrder(new Ordering().addDescending(DescriptionTemplate._createdAt));
|
|
query.setPage(new Paging(page * PageSize, PageSize));
|
|
items = query.collect();
|
|
if (items != null && !items.isEmpty()) {
|
|
|
|
logger.debug("Migrate DescriptionTemplate " + page * PageSize + " of " + total);
|
|
|
|
for (DescriptionTemplateEntity item : items) {
|
|
if (this.conventionService.isNullOrEmpty(item.getDefinition())) continue;
|
|
Document document = XmlBuilder.fromXml(item.getDefinition());
|
|
if (document == null){
|
|
logger.error("Migrate DescriptionTemplate " + item.getId() + " failed read xml");
|
|
throw new MyApplicationException("Migrate DescriptionTemplate " + item.getId() + " failed read xml");
|
|
}
|
|
ViewStyleModel viewStyleModel = null;
|
|
try {
|
|
viewStyleModel = new ViewStyleModel().fromXml(document.getDocumentElement());
|
|
} catch (Exception ex){
|
|
logger.error("Migrate DescriptionTemplate " + item.getId() + " failed read xml");
|
|
throw new MyApplicationException("Migrate DescriptionTemplate " + item.getId() + " failed read xml");
|
|
}
|
|
item.setDefinition(this.xmlHandlingService.toXml(this.buildDefinitionEntity(viewStyleModel, referenceTypeEntityMap, knownReferenceEntities)));
|
|
this.entityManager.merge(item);
|
|
}
|
|
|
|
this.entityManager.flush();
|
|
page++;
|
|
}
|
|
} while (items != null && !items.isEmpty() && !TestMode);
|
|
|
|
logger.debug("Migrate DescriptionTemplate ReferenceTypes : " + referenceTypeEntityMap.size());
|
|
for (ReferenceTypeEntity item : referenceTypeEntityMap.values()){
|
|
this.entityManager.persist(item);
|
|
}
|
|
this.entityManager.flush();
|
|
}
|
|
|
|
private @NotNull DefinitionEntity buildDefinitionEntity(ViewStyleModel persist, Map<String, ReferenceTypeEntity> referenceTypeEntityMap, Map<UUID, ReferenceTypeEntity> knownReferenceEntities) throws URISyntaxException {
|
|
DefinitionEntity data = new DefinitionEntity();
|
|
if (persist == null)
|
|
return data;
|
|
if (!this.conventionService.isListNullOrEmpty(persist.getPages())) {
|
|
Map<String, List<Section>> sectionPerPage = mapSectionsToPage(persist);
|
|
data.setPages(new ArrayList<>());
|
|
for (Page pagePersist : persist.getPages()) {
|
|
data.getPages().add(this.buildPageEntity(pagePersist, sectionPerPage.get(pagePersist.getId()), referenceTypeEntityMap, knownReferenceEntities));
|
|
}
|
|
}
|
|
|
|
return data;
|
|
}
|
|
|
|
private @NotNull SectionEntity buildSectionEntity(Section persist, Map<String, ReferenceTypeEntity> referenceTypeEntityMap, Map<UUID, ReferenceTypeEntity> knownReferenceEntities) throws URISyntaxException {
|
|
SectionEntity data = new SectionEntity();
|
|
if (persist == null)
|
|
return data;
|
|
|
|
data.setId(persist.getId());
|
|
data.setDescription(persist.getDescription());
|
|
data.setExtendedDescription(persist.getExtendedDescription());
|
|
data.setNumbering(persist.getNumbering());
|
|
data.setOrdinal(persist.getOrdinal());
|
|
data.setDefaultVisibility(persist.isDefaultVisibility());
|
|
data.setTitle(persist.getTitle());
|
|
|
|
if (!this.conventionService.isListNullOrEmpty(persist.getSections())) {
|
|
data.setSections(new ArrayList<>());
|
|
for (Section sectionPersist : persist.getSections()) {
|
|
data.getSections().add(this.buildSectionEntity(sectionPersist, referenceTypeEntityMap, knownReferenceEntities));
|
|
}
|
|
}
|
|
|
|
if (!this.conventionService.isListNullOrEmpty(persist.getFieldSets())) {
|
|
data.setFieldSets(new ArrayList<>());
|
|
for (FieldSet fieldSetPersist : persist.getFieldSets()) {
|
|
data.getFieldSets().add(this.buildFieldSetEntity(fieldSetPersist, referenceTypeEntityMap, knownReferenceEntities));
|
|
}
|
|
}
|
|
|
|
return data;
|
|
}
|
|
|
|
private @NotNull FieldSetEntity buildFieldSetEntity(FieldSet persist, Map<String, ReferenceTypeEntity> referenceTypeEntityMap, Map<UUID, ReferenceTypeEntity> knownReferenceEntities) throws URISyntaxException {
|
|
FieldSetEntity data = new FieldSetEntity();
|
|
if (persist == null)
|
|
return data;
|
|
|
|
data.setId(persist.getId());
|
|
data.setOrdinal(persist.getOrdinal());
|
|
data.setNumbering(persist.getNumbering());
|
|
data.setTitle(persist.getTitle());
|
|
data.setDescription(persist.getDescription());
|
|
data.setExtendedDescription(persist.getExtendedDescription());
|
|
data.setAdditionalInformation(persist.getAdditionalInformation());
|
|
data.setHasCommentField(persist.getHasCommentField());
|
|
data.setHasMultiplicity(persist.getMultiplicity() != null && (persist.getMultiplicity().getMin() != 0 || persist.getMultiplicity().getMax() != 0));
|
|
|
|
if (persist.getMultiplicity() != null && data.getHasMultiplicity()) data.setMultiplicity(this.buildMultiplicityEntity(persist.getMultiplicity()));
|
|
|
|
if (!this.conventionService.isListNullOrEmpty(persist.getFields())) {
|
|
data.setFields(new ArrayList<>());
|
|
for (Field fieldPersist : persist.getFields()) {
|
|
data.getFields().add(this.buildFieldEntity(fieldPersist, referenceTypeEntityMap, knownReferenceEntities));
|
|
}
|
|
}
|
|
return data;
|
|
}
|
|
|
|
private @NotNull FieldEntity buildFieldEntity(Field persist, Map<String, ReferenceTypeEntity> referenceTypeEntityMap, Map<UUID, ReferenceTypeEntity> knownReferenceEntities) throws URISyntaxException {
|
|
FieldEntity data = new FieldEntity();
|
|
if (persist == null)
|
|
return data;
|
|
|
|
data.setId(persist.getId());
|
|
data.setOrdinal(persist.getOrdinal());
|
|
data.setSchematics(persist.getSchematics());
|
|
data.setNumbering(persist.getNumbering());
|
|
if (persist.getValidations() != null) data.setValidations(persist.getValidations().stream().map(x-> {
|
|
switch (x){
|
|
case NONE -> {
|
|
return FieldValidationType.None;
|
|
}
|
|
case REQUIRED -> {
|
|
return FieldValidationType.Required;
|
|
}
|
|
case URL -> {
|
|
return FieldValidationType.Url;
|
|
}
|
|
default -> throw new MyApplicationException("Invalid type " + x);
|
|
}
|
|
|
|
}).toList());
|
|
data.setIncludeInExport(persist.getExport());
|
|
if (persist.getData() != null) {
|
|
data.setData(this.buildFieldDataEntity(persist.getData(), persist.getViewStyle().getRenderStyle(), referenceTypeEntityMap, knownReferenceEntities));
|
|
if (persist.getViewStyle().getRenderStyle().equals("externalDatasets")){
|
|
FieldDataExternalDatasetType type = null;
|
|
try {
|
|
type = FieldDataExternalDatasetType.of(((ExternalDatasetsData)persist.getData()).getType());
|
|
} catch (Exception e) { type = FieldDataExternalDatasetType.Other; }
|
|
if (type == null) type = FieldDataExternalDatasetType.Other;
|
|
if (data.getSchematics() == null) data.setSchematics(new ArrayList<>());
|
|
switch (type){
|
|
case Other -> data.getSchematics().add("referencetype.externaldataset.type.other");
|
|
case ProducedDataset -> data.getSchematics().add("referencetype.externaldataset.type.produced");
|
|
case ReusedDataset -> data.getSchematics().add("referencetype.externaldataset.type.reused");
|
|
default -> throw new MyApplicationException("Invalid type " + type);
|
|
}
|
|
}
|
|
}
|
|
|
|
if (persist.getDefaultValue() != null) data.setDefaultValue(this.buildDefaultValueEntity(persist.getDefaultValue(), data.getData().getFieldType()));
|
|
if (persist.getVisible() != null && !this.conventionService.isListNullOrEmpty(persist.getVisible().getRules())) {
|
|
data.setVisibilityRules(new ArrayList<>());
|
|
for (Rule fieldPersist : persist.getVisible().getRules()) {
|
|
data.getVisibilityRules().add(this.buildRuleEntity(fieldPersist, data.getData().getFieldType()));
|
|
}
|
|
}
|
|
return data;
|
|
}
|
|
|
|
private BaseFieldDataEntity buildFieldDataEntity(FieldData<?> persist, String renderStyle, Map<String, ReferenceTypeEntity> referenceTypeEntityMap, Map<UUID, ReferenceTypeEntity> knownReferenceEntities) throws URISyntaxException {
|
|
if (renderStyle.equals("checkBox")){
|
|
return this.buildLabelDataEntity(persist.getLabel(), FieldType.CHECK_BOX);
|
|
}
|
|
if (renderStyle.equals("validation")){
|
|
return this.buildLabelDataEntity(persist.getLabel(), FieldType.VALIDATION);
|
|
}
|
|
if (renderStyle.equals("textarea")){
|
|
return this.buildLabelDataEntity(persist.getLabel(), FieldType.TEXT_AREA);
|
|
}
|
|
if (renderStyle.equals("tags")){
|
|
return this.buildLabelDataEntity(persist.getLabel(), FieldType.TAGS);
|
|
}
|
|
if (renderStyle.equals("richTextarea")){
|
|
return this.buildLabelDataEntity(persist.getLabel(), FieldType.RICH_TEXT_AREA);
|
|
}
|
|
if (renderStyle.equals("freetext")){
|
|
return this.buildLabelDataEntity(persist.getLabel(), FieldType.FREE_TEXT);
|
|
}
|
|
if (renderStyle.equals("datePicker")){
|
|
return this.buildLabelDataEntity(persist.getLabel(), FieldType.DATE_PICKER);
|
|
}
|
|
if (renderStyle.equals("datasetIdentifier")){
|
|
return this.buildLabelDataEntity(persist.getLabel(), FieldType.DATASET_IDENTIFIER);
|
|
}
|
|
if (renderStyle.equals("currency")){
|
|
return this.buildReferenceTypeDataEntity(persist.getLabel(), false, ReferenceTypeIds.Currency);
|
|
}
|
|
if (renderStyle.equals("taxonomies")){
|
|
return this.buildReferenceTypeDataEntity(persist.getLabel(), ((TaxonomiesData)persist).getMultiAutoComplete(), ReferenceTypeIds.Taxonomy);
|
|
}
|
|
if (renderStyle.equals("services")){
|
|
return this.buildReferenceTypeDataEntity(persist.getLabel(), ((ServicesData)persist).getMultiAutoComplete(),ReferenceTypeIds.Services);
|
|
}
|
|
if (renderStyle.equals("researchers")){
|
|
return this.buildReferenceTypeDataEntity(persist.getLabel(), ((ResearcherData)persist).getMultiAutoComplete(),ReferenceTypeIds.Researcher);
|
|
}
|
|
if (renderStyle.equals("registries")){
|
|
return this.buildReferenceTypeDataEntity(persist.getLabel(), ((RegistriesData)persist).getMultiAutoComplete(),ReferenceTypeIds.Registries);
|
|
}
|
|
if (renderStyle.equals("pubRepositories")){
|
|
return this.buildReferenceTypeDataEntity(persist.getLabel(), ((DataRepositoriesData)persist).getMultiAutoComplete(),ReferenceTypeIds.PubRepositories);
|
|
}
|
|
if (renderStyle.equals("publications")){
|
|
return this.buildReferenceTypeDataEntity(persist.getLabel(), ((PublicationsData)persist).getMultiAutoComplete(), ReferenceTypeIds.Publication);
|
|
}
|
|
if (renderStyle.equals("organizations")){
|
|
return this.buildReferenceTypeDataEntity(persist.getLabel(), ((OrganizationsData)persist).getMultiAutoComplete(), ReferenceTypeIds.Organizations);
|
|
}
|
|
if (renderStyle.equals("licenses")){
|
|
return this.buildReferenceTypeDataEntity(persist.getLabel(), ((LicensesData)persist).getMultiAutoComplete(), ReferenceTypeIds.License);
|
|
}
|
|
if (renderStyle.equals("journalRepositories")){
|
|
return this.buildReferenceTypeDataEntity(persist.getLabel(), ((DataRepositoriesData)persist).getMultiAutoComplete(), ReferenceTypeIds.Journal);
|
|
}
|
|
if (renderStyle.equals("dataRepositories")){
|
|
return this.buildReferenceTypeDataEntity(persist.getLabel(), ((DataRepositoriesData)persist).getMultiAutoComplete(), ReferenceTypeIds.DataRepositories);
|
|
}
|
|
if (renderStyle.equals("booleanDecision")){
|
|
return this.buildLabelDataEntity(persist.getLabel(), FieldType.BOOLEAN_DECISION);
|
|
}
|
|
if (renderStyle.equals("internalDmpEntities")){
|
|
switch (((InternalDmpEntitiesData<?>)persist).getType()){
|
|
case "dmps":
|
|
return this.buildLabelAndMultiplicityDataEntity(persist.getLabel(), ((DMPsAutoCompleteData)persist).getMultiAutoComplete(),FieldType.INTERNAL_ENTRIES_DMPS);
|
|
case "datasets":
|
|
return this.buildLabelAndMultiplicityDataEntity(persist.getLabel(), ((DatasetsAutoCompleteData)persist).getMultiAutoComplete(),FieldType.INTERNAL_ENTRIES_DESCRIPTIONS);
|
|
case "researchers":
|
|
return this.buildReferenceTypeDataEntity(persist.getLabel(), ((ResearchersAutoCompleteData)persist).getMultiAutoComplete(), ReferenceTypeIds.Researcher);
|
|
}
|
|
}
|
|
|
|
if (renderStyle.equals("externalDatasets")){
|
|
return this.buildReferenceTypeDataEntity(persist.getLabel(), ((ExternalDatasetsData)persist).getMultiAutoComplete(), ReferenceTypeIds.Datasets);
|
|
}
|
|
|
|
|
|
|
|
if (renderStyle.equals("upload")){
|
|
UploadDataEntity data = new UploadDataEntity();
|
|
data.setLabel(persist.getLabel());
|
|
data.setMaxFileSizeInMB(((UploadData)persist).getMaxFileSizeInMB());
|
|
data.setTypes(new ArrayList<>());
|
|
if (((UploadData)persist).getTypes() != null){
|
|
for (UploadData.Option option : ((UploadData)persist).getTypes()){
|
|
UploadDataEntity.UploadDataOptionEntity optionEntity =new UploadDataEntity.UploadDataOptionEntity();
|
|
optionEntity.setValue(option.getValue());
|
|
optionEntity.setLabel(option.getLabel());
|
|
data.getTypes().add(optionEntity);
|
|
}
|
|
}
|
|
data.setFieldType(FieldType.UPLOAD);
|
|
return data;
|
|
}
|
|
|
|
if (renderStyle.equals("radiobox")){
|
|
RadioBoxDataEntity data = new RadioBoxDataEntity();
|
|
data.setLabel(persist.getLabel());
|
|
data.setOptions(new ArrayList<>());
|
|
if (((RadioBoxData)persist).getOptions() != null){
|
|
for (RadioBoxData.Option option : ((RadioBoxData)persist).getOptions()){
|
|
RadioBoxDataEntity.RadioBoxDataOptionEntity optionEntity = new RadioBoxDataEntity.RadioBoxDataOptionEntity();
|
|
optionEntity.setValue(option.getValue());
|
|
optionEntity.setLabel(option.getLabel());
|
|
data.getOptions().add(optionEntity);
|
|
}
|
|
}
|
|
data.setFieldType(FieldType.RADIO_BOX);
|
|
return data;
|
|
}
|
|
|
|
if (renderStyle.equals("combobox")){
|
|
switch (((ComboBoxData<?>)persist).getType()){
|
|
case "wordlist":{
|
|
SelectDataEntity data = new SelectDataEntity();
|
|
data.setLabel(persist.getLabel());
|
|
data.setOptions(new ArrayList<>());
|
|
data.setMultipleSelect(((WordListData)persist).getMultiList());
|
|
if (((WordListData)persist).getOptions() != null){
|
|
for (ComboBoxData.Option option : ((WordListData)persist).getOptions()){
|
|
SelectDataEntity.OptionEntity optionEntity = new SelectDataEntity.OptionEntity();
|
|
optionEntity.setValue(option.getValue());
|
|
optionEntity.setLabel(option.getLabel());
|
|
data.getOptions().add(optionEntity);
|
|
}
|
|
}
|
|
data.setFieldType(FieldType.SELECT);
|
|
return data;
|
|
}
|
|
case "autocomplete":{
|
|
ReferenceTypeEntity referenceType = this.resolveReferenceTypeEntityAutoCompleteData(((AutoCompleteData)persist), referenceTypeEntityMap, knownReferenceEntities);
|
|
return this.buildReferenceTypeDataEntity(persist.getLabel(), ((AutoCompleteData)persist).getMultiAutoComplete(), referenceType.getId());
|
|
}
|
|
}
|
|
}
|
|
throw new MyApplicationException("Can transform field data" + renderStyle);
|
|
}
|
|
|
|
private BaseFieldDataEntity buildLabelDataEntity(String label, FieldType fieldType) {
|
|
LabelDataEntity data = new LabelDataEntity();
|
|
data.setLabel(label);
|
|
data.setFieldType(fieldType);
|
|
return data;
|
|
}
|
|
|
|
private BaseFieldDataEntity buildLabelAndMultiplicityDataEntity(String label, Boolean multiAutoComplete, FieldType fieldType) {
|
|
LabelAndMultiplicityDataEntity data = new LabelAndMultiplicityDataEntity();
|
|
data.setLabel(label);
|
|
data.setFieldType(fieldType);
|
|
data.setMultipleSelect(multiAutoComplete);
|
|
return data;
|
|
}
|
|
|
|
private BaseFieldDataEntity buildReferenceTypeDataEntity(String label, Boolean multiAutoComplete, UUID referenceTypeId) {
|
|
ReferenceTypeDataEntity data = new ReferenceTypeDataEntity();
|
|
data.setLabel(label);
|
|
data.setFieldType(FieldType.REFERENCE_TYPES);
|
|
data.setMultipleSelect(multiAutoComplete);
|
|
data.setReferenceTypeId(referenceTypeId);
|
|
return data;
|
|
}
|
|
|
|
private @NotNull DefaultValueEntity buildDefaultValueEntity(DefaultValue persist, FieldType fieldType) {
|
|
DefaultValueEntity data = new DefaultValueEntity();
|
|
if (persist == null)
|
|
return data;
|
|
String textValue = persist.getValue();
|
|
if (textValue == null || textValue.isEmpty()) return data;
|
|
|
|
switch (fieldType){
|
|
case FREE_TEXT, TEXT_AREA, RICH_TEXT_AREA, RADIO_BOX -> data.setTextValue(textValue.trim());
|
|
case CHECK_BOX, BOOLEAN_DECISION -> {
|
|
if (!this.conventionService.isNullOrEmpty(textValue)) {
|
|
data.setBooleanValue("true".equals(textValue.trim().toLowerCase(Locale.ROOT)));
|
|
}
|
|
}
|
|
case DATE_PICKER -> {
|
|
Instant instant = null;
|
|
if(!this.conventionService.isNullOrEmpty(textValue)) {
|
|
try {
|
|
instant = Instant.parse(textValue);
|
|
} catch (DateTimeParseException ex) {
|
|
instant = LocalDate.parse(textValue).atStartOfDay().toInstant(ZoneOffset.UTC);
|
|
}
|
|
}
|
|
data.setDateValue(instant);
|
|
}
|
|
case SELECT -> {
|
|
if(!this.conventionService.isNullOrEmpty(textValue)) {
|
|
String[] valuesParsed = migrationTools.tryParseJsonAsObjectString(String[].class, textValue);
|
|
data.setTextListValue(valuesParsed == null ? List.of(textValue) : Arrays.stream(valuesParsed).toList());
|
|
}
|
|
}
|
|
case DATASET_IDENTIFIER, VALIDATION -> {
|
|
throw new NotSupportedException("Upload validator not supported");
|
|
}
|
|
case UPLOAD -> throw new NotSupportedException("Upload validator not supported");
|
|
case TAGS -> throw new NotSupportedException("Tags validator not supported");
|
|
|
|
case INTERNAL_ENTRIES_DMPS -> throw new NotSupportedException("INTERNAL_ENTRIES_DMPS validator not supported");
|
|
case INTERNAL_ENTRIES_DESCRIPTIONS -> throw new NotSupportedException("INTERNAL_ENTRIES_DESCRIPTIONS validator not supported");
|
|
case REFERENCE_TYPES -> throw new NotSupportedException("REFERENCE_TYPES validator not supported");
|
|
default -> throw new MyApplicationException("unrecognized type " + fieldType);
|
|
}
|
|
return data;
|
|
}
|
|
|
|
|
|
private @NotNull RuleEntity buildRuleEntity(Rule persist, FieldType fieldType) {
|
|
RuleEntity data = new RuleEntity();
|
|
if (persist == null)
|
|
return data;
|
|
String textValue = persist.getValue();
|
|
if (textValue == null || textValue.isEmpty()) return data;
|
|
|
|
data.setTarget(persist.getTarget());
|
|
switch (fieldType){
|
|
case FREE_TEXT, TEXT_AREA, RICH_TEXT_AREA, RADIO_BOX -> data.setTextValue(textValue.trim());
|
|
case CHECK_BOX, BOOLEAN_DECISION -> {
|
|
if (!this.conventionService.isNullOrEmpty(textValue)) {
|
|
data.setBooleanValue("true".equals(textValue.trim().toLowerCase(Locale.ROOT)));
|
|
}
|
|
}
|
|
case DATE_PICKER -> {
|
|
Instant instant = null;
|
|
if(!this.conventionService.isNullOrEmpty(textValue)) {
|
|
try {
|
|
instant = Instant.parse(textValue);
|
|
} catch (DateTimeParseException ex) {
|
|
instant = LocalDate.parse(textValue).atStartOfDay().toInstant(ZoneOffset.UTC);
|
|
}
|
|
}
|
|
data.setDateValue(instant);
|
|
}
|
|
case SELECT -> {
|
|
if(!this.conventionService.isNullOrEmpty(textValue)) {
|
|
String[] valuesParsed = migrationTools.tryParseJsonAsObjectString(String[].class, textValue);
|
|
data.setTextListValue(valuesParsed == null ? List.of(textValue) : Arrays.stream(valuesParsed).toList());
|
|
}
|
|
}
|
|
case DATASET_IDENTIFIER, VALIDATION -> {
|
|
if(!this.conventionService.isNullOrEmpty(textValue)) {
|
|
org.opencdmp.commons.types.descriptiontemplate.ExternalIdentifierEntity externalIdentifierEntity = migrationTools.tryParseJsonAsObjectString(org.opencdmp.commons.types.descriptiontemplate.ExternalIdentifierEntity.class, textValue);
|
|
if (externalIdentifierEntity == null) throw new MyApplicationException("Could not parse dataset External Identifier : " + textValue);
|
|
data.setExternalIdentifier(externalIdentifierEntity);
|
|
}
|
|
}
|
|
case UPLOAD -> throw new NotSupportedException("Upload validator not supported");
|
|
case TAGS -> throw new NotSupportedException("Tags validator not supported");
|
|
|
|
case INTERNAL_ENTRIES_DMPS -> throw new NotSupportedException("INTERNAL_ENTRIES_DMPS validator not supported");
|
|
case INTERNAL_ENTRIES_DESCRIPTIONS -> throw new NotSupportedException("INTERNAL_ENTRIES_DESCRIPTIONS validator not supported");
|
|
case REFERENCE_TYPES -> throw new NotSupportedException("REFERENCE_TYPES validator not supported");
|
|
default -> throw new MyApplicationException("unrecognized type " + fieldType);
|
|
}
|
|
return data;
|
|
}
|
|
private @NotNull MultiplicityEntity buildMultiplicityEntity(Multiplicity persist) {
|
|
MultiplicityEntity data = new MultiplicityEntity();
|
|
if (persist == null)
|
|
return data;
|
|
|
|
data.setMax(persist.getMax());
|
|
data.setMin(persist.getMin());
|
|
data.setPlaceholder(persist.getPlaceholder());
|
|
data.setTableView(persist.getTableView());
|
|
return data;
|
|
}
|
|
|
|
|
|
|
|
private @NotNull PageEntity buildPageEntity(Page persist, List<Section> sections, Map<String, ReferenceTypeEntity> referenceTypeEntityMap, Map<UUID, ReferenceTypeEntity> knownReferenceEntities) throws URISyntaxException {
|
|
PageEntity data = new PageEntity();
|
|
if (persist == null)
|
|
return data;
|
|
|
|
data.setId(persist.getId());
|
|
data.setOrdinal(persist.getOrdinal());
|
|
data.setTitle(persist.getTitle());
|
|
|
|
if (!this.conventionService.isListNullOrEmpty(sections)) {
|
|
data.setSections(new ArrayList<>());
|
|
for (Section sectionPersist : sections) {
|
|
data.getSections().add(this.buildSectionEntity(sectionPersist, referenceTypeEntityMap, knownReferenceEntities));
|
|
}
|
|
}
|
|
return data;
|
|
}
|
|
|
|
|
|
private Map<String, List<Section>> mapSectionsToPage(ViewStyleModel persist){
|
|
List<String> mappedSectionsIds = new ArrayList<>();
|
|
Map<String, List<Section>> sectionPerPage = new HashMap<>();
|
|
if (persist == null || persist.getPages() == null || persist.getSections() == null) return sectionPerPage;
|
|
|
|
for (Page page :persist.getPages()){
|
|
sectionPerPage.put(page.getId(), new ArrayList<>());
|
|
for (Section section : persist.getSections()){
|
|
if (this.isInPage(section, page)){
|
|
if (mappedSectionsIds.contains(section.getId())) throw new MyApplicationException("Multiple page section found for page " + page.getId() + " section " + section.getId());
|
|
mappedSectionsIds.add(section.getId());
|
|
sectionPerPage.get(page.getId()).add(section);
|
|
}
|
|
}
|
|
}
|
|
|
|
for (Section section : persist.getSections()){
|
|
if (!mappedSectionsIds.contains(section.getId())) throw new MyApplicationException("Orphan section found " + section.getId());
|
|
}
|
|
|
|
return sectionPerPage;
|
|
}
|
|
|
|
private boolean isInPage(Section section, Page page){
|
|
try {
|
|
return UUID.fromString(section.getPage()).equals(UUID.fromString(page.getId()));
|
|
} catch (Exception e){
|
|
return section.getPage().toLowerCase(Locale.ROOT).equals(page.getId().toLowerCase(Locale.ROOT));
|
|
}
|
|
}
|
|
|
|
public ReferenceTypeEntity resolveReferenceTypeEntityAutoCompleteData(AutoCompleteData persist, Map<String, ReferenceTypeEntity> referenceTypeEntityMap, Map<UUID, ReferenceTypeEntity> knownReferenceEntities) throws URISyntaxException {
|
|
ReferenceTypeDefinitionEntity definitionEntity = this.buildReferenceTypeDefinitionEntity(persist);
|
|
String hash = this.referenceTypeCalculatedHash(definitionEntity);
|
|
ReferenceTypeEntity data = this.getReferenceTypeEntityByUrl(definitionEntity, knownReferenceEntities);
|
|
if (data == null){
|
|
data = referenceTypeEntityMap.getOrDefault(hash, null);
|
|
}
|
|
if (data == null) {
|
|
data = new ReferenceTypeEntity();
|
|
data.setId(UUID.randomUUID());
|
|
data.setIsActive(IsActive.Active);
|
|
data.setCreatedAt(Instant.now());
|
|
data.setName(persist.getLabel().substring(0, Math.min(persist.getLabel().length(), 199)));
|
|
data.setCode(persist.getLabel().substring(0, Math.min(persist.getLabel().length(), 99)));
|
|
data.setDefinition(this.xmlHandlingService.toXmlSafe(definitionEntity));
|
|
data.setUpdatedAt(Instant.now());
|
|
referenceTypeEntityMap.put(hash, data);
|
|
}
|
|
return data;
|
|
}
|
|
|
|
private ReferenceTypeEntity getReferenceTypeEntityByUrl(ReferenceTypeDefinitionEntity definitionEntity, Map<UUID, ReferenceTypeEntity> knownReferenceEntities){
|
|
if (definitionEntity == null || this.conventionService.isListNullOrEmpty(definitionEntity.getSources()) || definitionEntity.getSources().size() != 1) return null;
|
|
ExternalFetcherApiSourceConfigurationEntity externalFetcherApiSourceConfigurationEntity = (ExternalFetcherApiSourceConfigurationEntity)definitionEntity.getSources().getFirst();
|
|
if (externalFetcherApiSourceConfigurationEntity == null || this.conventionService.isNullOrEmpty(externalFetcherApiSourceConfigurationEntity.getUrl())) return null;
|
|
|
|
String url = StringUtils.stripEnd(externalFetcherApiSourceConfigurationEntity.getUrl().trim().toLowerCase(Locale.ROOT).replace(" ", ""), "/");
|
|
if (url.equals("https://eestore.paas2.uninett.no/api/license".trim().toLowerCase(Locale.ROOT).replace(" ", ""))) return knownReferenceEntities.get(ReferenceTypeIds.License);
|
|
else if (url.equals("https://zenodo.org/api/licenses".trim().toLowerCase(Locale.ROOT).replace(" ", ""))) return knownReferenceEntities.get(ReferenceTypeIds.License);
|
|
else if (url.equals("https://zenodo.org/api/licenses?q={like}".trim().toLowerCase(Locale.ROOT).replace(" ", ""))) return knownReferenceEntities.get(ReferenceTypeIds.License);
|
|
else if (url.equals("http://api.openaire.eu/search/publications".trim().toLowerCase(Locale.ROOT).replace(" ", ""))) return knownReferenceEntities.get(ReferenceTypeIds.Publication);
|
|
else if (url.equals("http://api.openaire.eu/search/publications?format=json&title={like}".trim().toLowerCase(Locale.ROOT).replace(" ", ""))) return knownReferenceEntities.get(ReferenceTypeIds.Publication);
|
|
else if (url.equals("https://services.openaire.eu/openaire/ds/searchdetails/{page}/{pageSize}?requestSortBy=id&order=ASCENDING".trim().toLowerCase(Locale.ROOT).replace(" ", ""))) return knownReferenceEntities.get(ReferenceTypeIds.Publication);
|
|
else if (url.equals("https://eestore.paas2.uninett.no/api/datarepo".trim().toLowerCase(Locale.ROOT).replace(" ", ""))) return knownReferenceEntities.get(ReferenceTypeIds.DataRepositories);
|
|
else if (url.equals("https://services.openaire.eu/search/v2/api/datasources?q={like}&fq=datasourcetypeuiname exact \"Data Repository\"&format=json".trim().toLowerCase(Locale.ROOT).replace(" ", ""))) return knownReferenceEntities.get(ReferenceTypeIds.DataRepositories);
|
|
else if (url.equals("https://services.openaire.eu/search/v2/api/datasources?q={like}&fq=datasourcetypeuiname".trim().toLowerCase(Locale.ROOT).replace(" ", ""))) return knownReferenceEntities.get(ReferenceTypeIds.DataRepositories);
|
|
else if (url.equals("https://services.openaire.eu/search/v2/api/resources?query=oaftype exact datasource and {like} and ( datasourcetypeuiid = \"pubsrepository::journal\" or datasourcetypeuiid = \"aggregator::pubsrepository::journals\")&page=0&size=60&format=json".trim().toLowerCase(Locale.ROOT).replace(" ", ""))) return knownReferenceEntities.get(ReferenceTypeIds.Journal);
|
|
else if (url.equals("https://eestore.paas2.uninett.no/api/metadataschema".trim().toLowerCase(Locale.ROOT).replace(" ", ""))) return knownReferenceEntities.get(ReferenceTypeIds.Registries);
|
|
else if (url.equals("https://eestore.paas2.uninett.no/api/taxonomy".trim().toLowerCase(Locale.ROOT).replace(" ", ""))) return knownReferenceEntities.get(ReferenceTypeIds.Taxonomy);
|
|
|
|
return null;
|
|
}
|
|
|
|
public String referenceTypeCalculatedHash(ReferenceTypeDefinitionEntity definitionEntity) {
|
|
List<String> sourceKeys = new ArrayList<>();
|
|
if (definitionEntity.getSources() != null){
|
|
for (ExternalFetcherApiSourceConfigurationEntity source : definitionEntity.getSources().stream().map(x-> (ExternalFetcherApiSourceConfigurationEntity)x).toList()){
|
|
StringBuilder sourceStringBuilder = new StringBuilder();
|
|
sourceStringBuilder.append(StringUtils.stripEnd(source.getUrl().trim().toLowerCase(Locale.ROOT), "/"));
|
|
sourceStringBuilder.append(source.getHttpMethod().getValue().toString().trim().toLowerCase(Locale.ROOT));
|
|
// sourceStringBuilder.append(source.getKey());
|
|
// if (source.getResults() != null){
|
|
// sourceStringBuilder.append(source.getResults().getResultsArrayPath());
|
|
// if (source.getResults().getFieldsMapping() != null) {
|
|
// sourceStringBuilder.append(source.getResults().getFieldsMapping().stream().filter(x-> x.getCode().equals(ReferenceEntity.KnownFields.ReferenceId)).map(ResultFieldsMappingConfigurationEntity::getResponsePath).findFirst().orElse(""));
|
|
// sourceStringBuilder.append(source.getResults().getFieldsMapping().stream().filter(x-> x.getCode().equals(ReferenceEntity.KnownFields.Label)).map(ResultFieldsMappingConfigurationEntity::getResponsePath).findFirst().orElse(""));
|
|
// }
|
|
// }
|
|
sourceKeys.add(sourceStringBuilder.toString().toLowerCase(Locale.ROOT));
|
|
}
|
|
}
|
|
return sourceKeys.stream().sorted().collect(Collectors.joining(""));
|
|
}
|
|
|
|
private @NotNull ReferenceTypeDefinitionEntity buildReferenceTypeDefinitionEntity(AutoCompleteData persist) throws URISyntaxException {
|
|
ReferenceTypeDefinitionEntity data = new ReferenceTypeDefinitionEntity();
|
|
if (persist == null) return data;
|
|
data.setFields(new ArrayList<>());
|
|
|
|
if (!this.conventionService.isListNullOrEmpty(persist.getAutoCompleteSingleDataList())){
|
|
data.setSources(new ArrayList<>());
|
|
int ordinal = 0;
|
|
for (AutoCompleteData.AutoCompleteSingleData sourceBaseConfigPersist: persist.getAutoCompleteSingleDataList()) {
|
|
data.getSources().add(this.buildSourceBaseConfigEntity(sourceBaseConfigPersist, ordinal));
|
|
ordinal++;
|
|
}
|
|
}
|
|
|
|
return data;
|
|
}
|
|
|
|
private @NotNull ExternalFetcherApiSourceConfigurationEntity buildSourceBaseConfigEntity(AutoCompleteData.AutoCompleteSingleData persist, int ordinal) throws URISyntaxException {
|
|
if (persist == null) return new ExternalFetcherApiSourceConfigurationEntity();
|
|
|
|
ExternalFetcherApiSourceConfigurationEntity apiEntity = new ExternalFetcherApiSourceConfigurationEntity();
|
|
|
|
URI uri;
|
|
if (persist.getUrl().contains("?")) {
|
|
uri = new URI(persist.getUrl().substring(0, persist.getUrl().trim().lastIndexOf("?")));
|
|
} else {
|
|
uri = new URI(persist.getUrl().trim());
|
|
}
|
|
String source = persist.getAutoCompleteOptions().getSource();
|
|
source = source != null && !source.isEmpty() ? source : uri.getHost();
|
|
|
|
String parsedUrl = persist.getUrl().trim();
|
|
parsedUrl = parsedUrl.replace("%20", " ");
|
|
parsedUrl = parsedUrl.replace("%22", "\"");
|
|
while (parsedUrl.contains("&")) {
|
|
parsedUrl = parsedUrl.replace("&", "&");
|
|
}
|
|
|
|
apiEntity.setUrl(parsedUrl);
|
|
apiEntity.setResults(this.buildResultsConfigEntity(persist));
|
|
|
|
apiEntity.setPaginationPath(null);
|
|
apiEntity.setContentType(MediaType.APPLICATION_JSON_VALUE);
|
|
apiEntity.setFirstPage("1");
|
|
apiEntity.setHttpMethod(this.toReferenceTypeExternalApiHTTPMethodType(persist.getMethod()));
|
|
apiEntity.setRequestBody(null);
|
|
apiEntity.setFilterType(null);
|
|
if (persist.getHasAuth() && persist.getAuth() != null) {
|
|
apiEntity.setAuth(this.buildAuthConfigEntity(persist.getAuth()));
|
|
}
|
|
apiEntity.setQueries(new ArrayList<>());
|
|
apiEntity.getQueries().add(this.buildQueryConfigEntity(parsedUrl));
|
|
|
|
apiEntity.setType(ExternalFetcherSourceType.API);
|
|
apiEntity.setKey(source);
|
|
apiEntity.setLabel(source);
|
|
apiEntity.setOrdinal(ordinal);
|
|
apiEntity.setReferenceTypeDependencyIds(null);
|
|
|
|
return apiEntity;
|
|
}
|
|
|
|
private @NotNull ResultsConfigurationEntity buildResultsConfigEntity(AutoCompleteData.AutoCompleteSingleData persist){
|
|
ResultsConfigurationEntity data = new ResultsConfigurationEntity();
|
|
|
|
|
|
data.setResultsArrayPath(persist.getOptionsRoot());
|
|
if (persist.getAutoCompleteOptions() == null && this.conventionService.isNullOrEmpty(persist.getAutoCompleteOptions().getLabel())) {
|
|
data.setFieldsMapping(new ArrayList<>());
|
|
ResultFieldsMappingConfigurationEntity labelField = new ResultFieldsMappingConfigurationEntity();
|
|
labelField.setCode(ReferenceEntity.KnownFields.Label);
|
|
labelField.setResponsePath(persist.getAutoCompleteOptions().getLabel());
|
|
data.getFieldsMapping().add(labelField);
|
|
}
|
|
if (persist.getAutoCompleteOptions() == null && this.conventionService.isNullOrEmpty(persist.getAutoCompleteOptions().getValue())) {
|
|
ResultFieldsMappingConfigurationEntity idField = new ResultFieldsMappingConfigurationEntity();
|
|
idField.setCode(ReferenceEntity.KnownFields.ReferenceId);
|
|
idField.setResponsePath(persist.getAutoCompleteOptions().getValue());
|
|
data.getFieldsMapping().add(idField);
|
|
}
|
|
return data;
|
|
}
|
|
|
|
private @NotNull QueryConfigEntity buildQueryConfigEntity(String path){
|
|
QueryConfigEntity data = new QueryConfigEntity();
|
|
|
|
data.setName("like");
|
|
if ((path.toLowerCase(Locale.ROOT).trim().contains("openaire") || path.toLowerCase(Locale.ROOT).trim().contains("orcid")
|
|
|| path.toLowerCase(Locale.ROOT).trim().contains("ror") || path.toLowerCase(Locale.ROOT).trim().contains("fairsharing"))) {
|
|
data.setDefaultValue("*");
|
|
} else {
|
|
data.setDefaultValue("");
|
|
}
|
|
data.setCases(new ArrayList<>());
|
|
QueryCaseConfigEntity caseConfig = new QueryCaseConfigEntity();
|
|
caseConfig.setReferenceTypeId(null);
|
|
caseConfig.setReferenceTypeSourceKey(null);
|
|
caseConfig.setSeparator(null);
|
|
caseConfig.setValue("{like}");
|
|
caseConfig.setLikePattern(null);
|
|
data.getCases().add(caseConfig);
|
|
|
|
return data;
|
|
}
|
|
|
|
private @NotNull AuthenticationConfigurationEntity buildAuthConfigEntity(AutoCompleteData.AuthAutoCompleteData persist){
|
|
AuthenticationConfigurationEntity data = new AuthenticationConfigurationEntity();
|
|
if (persist == null) return data;
|
|
|
|
data.setEnabled(true);
|
|
data.setAuthUrl(persist.getUrl());
|
|
data.setAuthMethod(this.toReferenceTypeExternalApiHTTPMethodType(persist.getMethod()));
|
|
data.setAuthRequestBody(persist.getBody());
|
|
data.setType(persist.getType());
|
|
data.setAuthTokenPath(persist.getPath());
|
|
|
|
return data;
|
|
}
|
|
|
|
private ExternalFetcherApiHTTPMethodType toReferenceTypeExternalApiHTTPMethodType(String method){
|
|
|
|
if (this.conventionService.isNullOrEmpty(method)) {
|
|
logger.error("Migrate DescriptionTemplate autocomplete method not set use default GET");
|
|
return ExternalFetcherApiHTTPMethodType.GET;
|
|
} else if (method.toLowerCase(Locale.ROOT).trim().equals("get")) {
|
|
return ExternalFetcherApiHTTPMethodType.GET;
|
|
} else if (method.toLowerCase(Locale.ROOT).trim().equals("post")) {
|
|
return ExternalFetcherApiHTTPMethodType.POST;
|
|
} else {
|
|
logger.error("Migrate DescriptionTemplate autocomplete method is invalid " + method);
|
|
throw new MyApplicationException("Migrate DescriptionTemplate autocomplete method is invalid " + method);
|
|
}
|
|
}
|
|
|
|
public enum FieldDataExternalDatasetType implements DatabaseEnum<String> {
|
|
ReusedDataset("reused_dataset"),
|
|
ProducedDataset("produced_dataset"),
|
|
Other("other");
|
|
private final String value;
|
|
|
|
FieldDataExternalDatasetType(String value) {
|
|
this.value = value;
|
|
}
|
|
|
|
@JsonValue
|
|
public String getValue() {
|
|
return value;
|
|
}
|
|
|
|
private static final Map<String, FieldDataExternalDatasetType> map = EnumUtils.getEnumValueMap(FieldDataExternalDatasetType.class);
|
|
|
|
public static FieldDataExternalDatasetType of(String i) {
|
|
return map.get(i);
|
|
}
|
|
}
|
|
}
|