Merge branch 'dmp-refactoring' of https://code-repo.d4science.org/MaDgiK-CITE/argos into dmp-refactoring

This commit is contained in:
Sofia Papacharalampous 2024-05-22 12:39:35 +03:00
commit 9e18aea655
14 changed files with 559 additions and 23 deletions

View File

@ -56,7 +56,7 @@
<dependency>
<groupId>org.opencdmp</groupId>
<artifactId>common-models</artifactId>
<version>0.0.14</version>
<version>0.0.15</version>
</dependency>
<dependency>
<groupId>gr.cite</groupId>

View File

@ -6,6 +6,7 @@ import gr.cite.tools.exception.MyNotFoundException;
import gr.cite.tools.exception.MyValidationException;
import gr.cite.tools.fieldset.FieldSet;
import jakarta.xml.bind.JAXBException;
import org.opencdmp.commonmodels.models.description.DescriptionModel;
import org.opencdmp.commons.types.description.importexport.DescriptionImportExport;
import org.opencdmp.data.DmpDescriptionTemplateEntity;
import org.opencdmp.data.StorageFileEntity;
@ -54,4 +55,6 @@ public interface DescriptionService {
Description importXml(DescriptionImportExport descriptionXml, UUID dmpId, List<DmpDescriptionTemplateEntity> dmpDescriptionTemplates, FieldSet fields) throws MyForbiddenException, MyNotFoundException, JAXBException, ParserConfigurationException, TransformerException, InvalidApplicationException, IOException, InstantiationException, IllegalAccessException, SAXException;
Description importJson(DescriptionModel model, UUID dmpId, List<DmpDescriptionTemplateEntity> dmpDescriptionTemplates, FieldSet fields) throws MyForbiddenException, MyNotFoundException, InvalidApplicationException, IOException ;
}

View File

@ -18,6 +18,10 @@ import org.opencdmp.authorization.AffiliatedResource;
import org.opencdmp.authorization.AuthorizationFlags;
import org.opencdmp.authorization.Permission;
import org.opencdmp.authorization.authorizationcontentresolver.AuthorizationContentResolver;
import org.opencdmp.commonmodels.models.description.*;
import org.opencdmp.commonmodels.models.descriptiotemplate.DescriptionTemplateModel;
import org.opencdmp.commonmodels.models.descriptiotemplate.fielddata.ReferenceTypeDataModel;
import org.opencdmp.commonmodels.models.reference.ReferenceModel;
import org.opencdmp.commons.JsonHandlingService;
import org.opencdmp.commons.XmlHandlingService;
import org.opencdmp.commons.enums.*;
@ -1267,7 +1271,7 @@ public class DescriptionServiceImpl implements DescriptionService {
//endregion
//region Import
//region Import xml
public Description importXml(DescriptionImportExport descriptionXml, UUID dmpId, List<DmpDescriptionTemplateEntity> dmpDescriptionTemplates, FieldSet fields) throws MyForbiddenException, MyNotFoundException, JAXBException, ParserConfigurationException, TransformerException, InvalidApplicationException, IOException, InstantiationException, IllegalAccessException, SAXException{
@ -1427,4 +1431,170 @@ public class DescriptionServiceImpl implements DescriptionService {
//endregion
//region Import RDA Json
public Description importJson(DescriptionModel model, UUID dmpId, List<DmpDescriptionTemplateEntity> dmpDescriptionTemplates, FieldSet fields) throws MyForbiddenException, MyNotFoundException, InvalidApplicationException, IOException {
if (model == null) throw new MyNotFoundException("Description common model not found");
logger.debug(new MapLogEntry("import description").And("dmpId", dmpId).And("fields", fields));
DescriptionPersist persist = new DescriptionPersist();
persist.setLabel(model.getLabel());
persist.setDescription(model.getDescription());
persist.setStatus(DescriptionStatus.Draft);
persist.setDmpId(dmpId);
if (model.getDescriptionTemplate() != null) {
persist.setDescriptionTemplateId(model.getDescriptionTemplate().getId());
if (!this.conventionService.isListNullOrEmpty(dmpDescriptionTemplates) && model.getSectionId() != null && model.getDescriptionTemplate().getGroupId() != null){
DmpDescriptionTemplateEntity dmpDescriptionTemplate = dmpDescriptionTemplates.stream().filter(x -> x.getDmpId().equals(dmpId) &&
x.getDescriptionTemplateGroupId().equals(model.getDescriptionTemplate().getGroupId()) &&
x.getSectionId().equals(model.getSectionId())).findFirst().orElse(null);
if (dmpDescriptionTemplate != null) persist.setDmpDescriptionTemplateId(dmpDescriptionTemplate.getId());
}
}
persist.setTags(model.getTags());
persist.setProperties(this.commonPropertyDefinitionToPersist(model));
this.validatorFactory.validator(DescriptionPersist.DescriptionPersistValidator.class).validateForce(persist);
return this.persist(persist, fields);
}
private PropertyDefinitionPersist commonPropertyDefinitionToPersist(DescriptionModel model) {
if (model == null)
return null;
PropertyDefinitionPersist persist = new PropertyDefinitionPersist();
Map<String, PropertyDefinitionFieldSetPersist> fieldSetsMap = new HashMap<>();
if (model.getDescriptionTemplate() != null && model.getDescriptionTemplate().getDefinition() != null && !this.conventionService.isListNullOrEmpty(model.getDescriptionTemplate().getDefinition().getPages())) {
if (model.getProperties() != null && model.getProperties().getFieldSets() != null && !model.getProperties().getFieldSets().isEmpty()){
for (String fieldSetId: model.getProperties().getFieldSets().keySet()){
fieldSetsMap.put(fieldSetId, this.commonPropertyDefinitionFieldSetToPersist(model.getProperties().getFieldSets().get(fieldSetId), model.getDescriptionTemplate()));
}
}
}
persist.setFieldSets(fieldSetsMap);
return persist;
}
private PropertyDefinitionFieldSetPersist commonPropertyDefinitionFieldSetToPersist(PropertyDefinitionFieldSetModel model, DescriptionTemplateModel descriptionTemplate) {
if (model == null)
return null;
PropertyDefinitionFieldSetPersist persist = new PropertyDefinitionFieldSetPersist();
if (!this.conventionService.isListNullOrEmpty(model.getItems())){
List<PropertyDefinitionFieldSetItemPersist> items = new ArrayList<>();
for (PropertyDefinitionFieldSetItemModel fieldSetItem: model.getItems()) {
items.add(this.commonPropertyDefinitionFieldSetItemToPersist(fieldSetItem, descriptionTemplate));
}
persist.setItems(items);
return persist;
}
return null;
}
private PropertyDefinitionFieldSetItemPersist commonPropertyDefinitionFieldSetItemToPersist(PropertyDefinitionFieldSetItemModel model, DescriptionTemplateModel descriptionTemplate) {
if (model == null)
return null;
PropertyDefinitionFieldSetItemPersist persist = new PropertyDefinitionFieldSetItemPersist();
persist.setComment(model.getComment());
persist.setOrdinal(model.getOrdinal());
Map<String, FieldPersist> fields = new HashMap<>();
if (model.getFields() != null && !model.getFields().isEmpty()){
for (String fieldId: model.getFields().keySet()) {
fields.put(fieldId, this.commonFieldToPersist(model.getFields().get(fieldId), descriptionTemplate));
}
}
persist.setFields(fields);
return persist;
}
private FieldPersist commonFieldToPersist(FieldModel model, DescriptionTemplateModel descriptionTemplate) {
if (model == null || descriptionTemplate == null)
return null;
org.opencdmp.commonmodels.models.descriptiotemplate.FieldModel descriptionTemplateField = descriptionTemplate.getDefinition().getFieldById(model.getId()).stream().findFirst().orElse(null);
if (descriptionTemplateField == null){
return null;
}
FieldPersist persist = new FieldPersist();
if (descriptionTemplateField.getData().getFieldType().equals(FieldType.REFERENCE_TYPES)){
ReferenceTypeDataModel referenceTypeDataModel = (ReferenceTypeDataModel) descriptionTemplateField.getData();
if (referenceTypeDataModel != null){
if (!this.conventionService.isListNullOrEmpty(model.getReferences()))
if (referenceTypeDataModel.getMultipleSelect()){
List<ReferencePersist> referencePersists = new ArrayList<>();
for (ReferenceModel referenceModel: model.getReferences()) {
referencePersists.add(this.commonReferenceToPersist(referenceModel));
}
persist.setReferences(referencePersists);
}else {
persist.setReference(this.commonReferenceToPersist(model.getReferences().stream().findFirst().orElse(null)));
}
}
} else {
persist.setBooleanValue(model.getBooleanValue());
persist.setDateValue(model.getDateValue());
persist.setTextValue(model.getTextValue());
persist.setTextListValue(model.getTextListValue());
if (model.getExternalIdentifier() != null){
persist.setExternalIdentifier(this.commonExternalIdentifierToPersist(model.getExternalIdentifier()));
}
}
return persist;
}
private ReferencePersist commonReferenceToPersist(ReferenceModel model) {
if (model == null)
return null;
ReferencePersist persist = new ReferencePersist();
persist.setId(model.getId());
persist.setLabel(model.getLabel());
persist.setDescription(model.getDescription());
persist.setReference(model.getReference());
persist.setAbbreviation(model.getAbbreviation());
persist.setSource(model.getSource());
switch (model.getSourceType()){
case Internal -> persist.setSourceType(ReferenceSourceType.Internal);
case External -> persist.setSourceType(ReferenceSourceType.External);
default -> throw new MyApplicationException("Unrecognized Type " + model.getSourceType().getValue());
}
return persist;
}
private ExternalIdentifierPersist commonExternalIdentifierToPersist(ExternalIdentifierModel model) {
if (model == null)
return null;
ExternalIdentifierPersist persist = new ExternalIdentifierPersist();
persist.setType(model.getType());
persist.setIdentifier(model.getIdentifier());
return persist;
}
//endregion
}

View File

@ -12,6 +12,7 @@ import gr.cite.tools.exception.MyValidationException;
import gr.cite.tools.fieldset.FieldSet;
import jakarta.xml.bind.JAXBException;
import org.springframework.http.ResponseEntity;
import org.springframework.web.multipart.MultipartFile;
import org.xml.sax.SAXException;
import javax.crypto.BadPaddingException;
@ -58,4 +59,5 @@ public interface DmpService {
Dmp importXml(byte[] bytes, String label, FieldSet fields) throws MyForbiddenException, MyNotFoundException, JAXBException, ParserConfigurationException, TransformerException, InvalidApplicationException, IOException, InstantiationException, IllegalAccessException, SAXException;
Dmp importJson(MultipartFile file, String label, String repositoryId, String format, FieldSet fields) throws MyForbiddenException, MyNotFoundException, JAXBException, InvalidApplicationException, IOException, InvalidAlgorithmParameterException, NoSuchPaddingException, IllegalBlockSizeException, NoSuchAlgorithmException, BadPaddingException, InvalidKeyException;
}

View File

@ -21,6 +21,18 @@ import org.jetbrains.annotations.NotNull;
import org.opencdmp.authorization.AuthorizationFlags;
import org.opencdmp.authorization.Permission;
import org.opencdmp.authorization.authorizationcontentresolver.AuthorizationContentResolver;
import org.opencdmp.commonmodels.models.DmpUserModel;
import org.opencdmp.commonmodels.models.UserModel;
import org.opencdmp.commonmodels.models.description.DescriptionModel;
import org.opencdmp.commonmodels.models.dmp.DmpBlueprintValueModel;
import org.opencdmp.commonmodels.models.dmp.DmpContactModel;
import org.opencdmp.commonmodels.models.dmp.DmpModel;
import org.opencdmp.commonmodels.models.dmpblueprint.FieldModel;
import org.opencdmp.commonmodels.models.dmpblueprint.ReferenceTypeFieldModel;
import org.opencdmp.commonmodels.models.dmpblueprint.SectionModel;
import org.opencdmp.commonmodels.models.dmpdescriptiontemplate.DmpDescriptionTemplateModel;
import org.opencdmp.commonmodels.models.dmpreference.DmpReferenceModel;
import org.opencdmp.commonmodels.models.reference.ReferenceModel;
import org.opencdmp.commons.JsonHandlingService;
import org.opencdmp.commons.XmlHandlingService;
import org.opencdmp.commons.enums.*;
@ -87,6 +99,7 @@ import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;
import org.xml.sax.SAXException;
import javax.crypto.BadPaddingException;
@ -1626,12 +1639,12 @@ public class DmpServiceImpl implements DmpService {
//endregion
//region Import
//region Import Xml
public Dmp importXml(byte[] bytes, String label, FieldSet fields) throws MyForbiddenException, MyNotFoundException, JAXBException, ParserConfigurationException, TransformerException, InvalidApplicationException, IOException, InstantiationException, IllegalAccessException, SAXException {
logger.debug(new MapLogEntry("import data").And("bytes", bytes).And("label", label).And("fields", fields));
// this.authorizationService.authorizeForce(Permission.ImportDmpBlueprint);
this.authorizationService.authorizeForce(Permission.NewDmp);
DmpPersist persist = new DmpPersist();
@ -1828,4 +1841,224 @@ public class DmpServiceImpl implements DmpService {
//endregion
//region Import RDA JSON
public Dmp importJson(MultipartFile file, String label, String repositoryId, String format, FieldSet fields) throws MyForbiddenException, MyNotFoundException, JAXBException, InvalidApplicationException, IOException, InvalidAlgorithmParameterException, NoSuchPaddingException, IllegalBlockSizeException, NoSuchAlgorithmException, BadPaddingException, InvalidKeyException {
DmpModel model = this.fileTransformerService.importDmp(file, repositoryId, format);
if (model == null) throw new MyNotFoundException("Plan Import Error");
logger.debug(new MapLogEntry("import data").And("bytes", file.getBytes()).And("label", label).And("fields", fields));
DmpPersist persist = new DmpPersist();
persist.setLabel(label);
persist.setStatus(DmpStatus.Draft);
persist.setDescription(model.getDescription());
switch (model.getAccessType()) {
case Public -> persist.setAccessType(DmpAccessType.Public);
case Restricted -> persist.setAccessType(DmpAccessType.Restricted);
default -> throw new MyApplicationException("Unrecognized Type " + model.getAccessType().getValue());
}
persist.setLanguage(model.getLanguage());
persist.setProperties(this.commonDmpPropertiesToPersist(model));
if (!this.conventionService.isListNullOrEmpty(model.getUsers())) {
List<UserEntity> users = this.queryFactory.query(UserQuery.class).disableTracking().ids(model.getUsers().stream().map(x -> x.getUser()).collect(Collectors.toList()).stream().map(UserModel::getId).filter(Objects::nonNull).distinct().toList()).isActive(IsActive.Active).collect();
List<UUID> userIds = users == null ? new ArrayList<>() : users.stream().map(x -> x.getId()).collect(Collectors.toList());
List<DmpUserPersist> dmpUsers = new ArrayList<>();
for (DmpUserModel user : model.getUsers()) {
dmpUsers.add(this.commonDmpUserToPersist(user, userIds));
}
persist.setUsers(dmpUsers);
}
if (model.getDmpBlueprint() != null) persist.setBlueprint(model.getDmpBlueprint().getId());
if (!this.conventionService.isListNullOrEmpty(model.getDescriptionTemplates())) {
List<DmpDescriptionTemplatePersist> descriptionTemplates = new ArrayList<>();
for (DmpDescriptionTemplateModel descriptionTemplate : model.getDescriptionTemplates()) {
descriptionTemplates.add(this.commonDmpDescriptionTemplateToPersist(descriptionTemplate));
}
persist.setDescriptionTemplates(descriptionTemplates);
}
this.validatorFactory.validator(DmpPersist.DmpPersistValidator.class).validateForce(persist);
Dmp dmp = this.persist(persist, fields);
if (!this.conventionService.isListNullOrEmpty(model.getDescriptions())) {
if (dmp == null || dmp.getId() == null) throw new MyApplicationException("Error creating dmp");
List<DmpDescriptionTemplateEntity> dmpDescriptionTemplates = this.queryFactory.query(DmpDescriptionTemplateQuery.class).disableTracking()
.isActive(IsActive.Active)
.dmpIds(dmp.getId())
.collect();
for (DescriptionModel description: model.getDescriptions()){
this.descriptionService.importJson(description, dmp.getId(), dmpDescriptionTemplates, fields != null ? fields.extractPrefixed(this.conventionService.asPrefix(Dmp._description)) : null);
}
}
return dmp;
}
private DmpPropertiesPersist commonDmpPropertiesToPersist(DmpModel model) {
if (model == null)
return null;
DmpPropertiesPersist persist = new DmpPropertiesPersist();
List<DmpContactPersist> contacts = new ArrayList<>();
if (model.getProperties() != null && !this.conventionService.isListNullOrEmpty(model.getProperties().getContacts())) {
List<UserEntity> users = this.queryFactory.query(UserQuery.class).disableTracking().ids(model.getProperties().getContacts().stream().map(x -> x.getUser()).collect(Collectors.toList()).stream().map(UserModel::getId).filter(Objects::nonNull).distinct().toList()).isActive(IsActive.Active).collect();
List<UUID> usersIds = users == null ? new ArrayList<>() : users.stream().map(x -> x.getId()).collect(Collectors.toList());
for (DmpContactModel contact : model.getProperties().getContacts()) {
contacts.add(this.commonDmpContactToPersist(contact, usersIds));
}
}
Map<UUID, DmpBlueprintValuePersist> dmpBlueprintValues = new HashMap<>();
if (model.getDmpBlueprint() != null && model.getDmpBlueprint().getDefinition() != null && !this.conventionService.isListNullOrEmpty(model.getDmpBlueprint().getDefinition().getSections())) {
List<SectionModel> sections = model.getDmpBlueprint().getDefinition().getSections();
if (!this.conventionService.isListNullOrEmpty(sections)){
for (SectionModel section : model.getDmpBlueprint().getDefinition().getSections()) {
if (!this.conventionService.isListNullOrEmpty(section.getFields()) && !this.conventionService.isListNullOrEmpty(model.getReferences())){
for (FieldModel field : section.getFields()) {
// reference
if (field.getCategory().equals(DmpBlueprintFieldCategory.ReferenceType)){
ReferenceTypeFieldModel referenceField = (ReferenceTypeFieldModel) field;
List<DmpReferenceModel> dmpReferencesByField = model.getReferences().stream().filter(x -> x.getData() != null && x.getData().getBlueprintFieldId().equals(referenceField.getId())).collect(Collectors.toList());
if (!this.conventionService.isListNullOrEmpty(dmpReferencesByField)){
dmpBlueprintValues.put(referenceField.getId(), this.commonDmpReferenceFieldToDmpBlueprintValuePersist(referenceField, dmpReferencesByField));
}
} else {
// custom fields
if (model.getProperties() != null && this.conventionService.isListNullOrEmpty(model.getProperties().getDmpBlueprintValues())){
DmpBlueprintValueModel dmpBlueprintValueModel = model.getProperties().getDmpBlueprintValues().stream().filter(x -> x.getFieldId().equals(field.getId())).findFirst().orElse(null);
if (dmpBlueprintValueModel != null) dmpBlueprintValues.put(dmpBlueprintValueModel.getFieldId(), this.commonDmpBlueprintValueToPersist(dmpBlueprintValueModel));
}
}
}
}
}
}
}
persist.setContacts(contacts);
persist.setDmpBlueprintValues(dmpBlueprintValues);
return persist;
}
private DmpBlueprintValuePersist commonDmpReferenceFieldToDmpBlueprintValuePersist(ReferenceTypeFieldModel model, List<DmpReferenceModel> dmpReferences) {
if (model == null || this.conventionService.isListNullOrEmpty(dmpReferences))
return null;
DmpBlueprintValuePersist persist = new DmpBlueprintValuePersist();
persist.setFieldId(model.getId());
if (model.getMultipleSelect()){
List<ReferencePersist> references = new ArrayList<>();
for (DmpReferenceModel dmpReference : dmpReferences) {
references.add(this.commonDmpReferenceToReferencePersist(dmpReference.getReference()));
}
persist.setReferences(references);
} else {
persist.setReference(this.commonDmpReferenceToReferencePersist(dmpReferences.get(0).getReference()));
}
return persist;
}
private ReferencePersist commonDmpReferenceToReferencePersist(ReferenceModel model) {
if (model == null)
return null;
ReferencePersist persist = new ReferencePersist();
persist.setId(model.getId());
persist.setLabel(model.getLabel());
persist.setDescription(model.getDescription());
persist.setReference(model.getReference());
persist.setAbbreviation(model.getAbbreviation());
persist.setSource(model.getSource());
switch (model.getSourceType()){
case Internal -> persist.setSourceType(ReferenceSourceType.Internal);
case External -> persist.setSourceType(ReferenceSourceType.External);
default -> throw new MyApplicationException("Unrecognized Type " + model.getSourceType().getValue());
}
return persist;
}
private DmpBlueprintValuePersist commonDmpBlueprintValueToPersist(DmpBlueprintValueModel model) {
if (model == null)
return null;
DmpBlueprintValuePersist persist = new DmpBlueprintValuePersist();
persist.setFieldId(model.getFieldId());
persist.setFieldValue(model.getValue());
return persist;
}
private DmpDescriptionTemplatePersist commonDmpDescriptionTemplateToPersist(DmpDescriptionTemplateModel model) {
if (model == null)
return null;
DmpDescriptionTemplatePersist persist = new DmpDescriptionTemplatePersist();
persist.setDescriptionTemplateGroupId(model.getDescriptionTemplateGroupId());
persist.setSectionId(model.getSectionId());
return persist;
}
private DmpUserPersist commonDmpUserToPersist(DmpUserModel model, List<UUID> userIds) {
if (model == null)
return null;
if (model.getUser() != null && model.getUser().getId() != null && !userIds.isEmpty() && userIds.contains(model.getUser().getId())) {
DmpUserPersist persist = new DmpUserPersist();
persist.setUser(model.getUser().getId());
switch (model.getRole()){
case Owner -> persist.setRole(DmpUserRole.Owner);
case User -> persist.setRole(DmpUserRole.User);
case DescriptionContributor -> persist.setRole(DmpUserRole.DescriptionContributor);
case Reviewer -> persist.setRole(DmpUserRole.Reviewer);
default -> throw new MyApplicationException("Unrecognized Type " + model.getRole().getValue());
}
persist.setSectionId(model.getSectionId());
return persist;
}
return null;
}
private DmpContactPersist commonDmpContactToPersist(DmpContactModel model, List<UUID> userIds) {
if (model == null)
return null;
DmpContactPersist persist = new DmpContactPersist();
if (model.getUser() != null && model.getUser().getId() != null && !userIds.isEmpty() && userIds.contains(model.getUser().getId())){
persist.setUserId(model.getUser().getId());
} else {
persist.setEmail(model.getEmail());
persist.setFirstName(model.getEmail());
persist.setLastName(model.getLastName());
}
return persist;
}
}

View File

@ -1,11 +1,15 @@
package org.opencdmp.service.filetransformer;
import jakarta.xml.bind.JAXBException;
import org.opencdmp.commonmodels.models.dmp.DmpModel;
import org.opencdmp.model.file.RepositoryFileFormat;
import org.springframework.web.multipart.MultipartFile;
import javax.crypto.BadPaddingException;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;
import javax.management.InvalidApplicationException;
import java.io.IOException;
import java.security.InvalidAlgorithmParameterException;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
@ -18,4 +22,7 @@ public interface FileTransformerService {
org.opencdmp.model.file.FileEnvelope exportDmp(UUID dmpId, String repositoryId, String format) throws InvalidAlgorithmParameterException, NoSuchPaddingException, IllegalBlockSizeException, InvalidApplicationException, NoSuchAlgorithmException, BadPaddingException, InvalidKeyException;
org.opencdmp.model.file.FileEnvelope exportDescription(UUID descriptionId, String repositoryId, String format) throws InvalidAlgorithmParameterException, NoSuchPaddingException, IllegalBlockSizeException, InvalidApplicationException, NoSuchAlgorithmException, BadPaddingException, InvalidKeyException;
DmpModel importDmp(MultipartFile file, String repositoryId, String format) throws InvalidAlgorithmParameterException, NoSuchPaddingException, IllegalBlockSizeException, InvalidApplicationException, NoSuchAlgorithmException, BadPaddingException, InvalidKeyException, IOException, JAXBException;
}

View File

@ -10,27 +10,30 @@ import gr.cite.tools.exception.MyNotFoundException;
import gr.cite.tools.fieldset.BaseFieldSet;
import gr.cite.tools.logging.LoggerService;
import gr.cite.tools.logging.MapLogEntry;
import jakarta.xml.bind.JAXBException;
import org.apache.commons.io.FilenameUtils;
import org.opencdmp.authorization.AuthorizationFlags;
import org.opencdmp.authorization.Permission;
import org.opencdmp.commonmodels.models.FileEnvelopeModel;
import org.opencdmp.commonmodels.models.description.DescriptionModel;
import org.opencdmp.commonmodels.models.dmp.DmpModel;
import org.opencdmp.commons.JsonHandlingService;
import org.opencdmp.commons.enums.IsActive;
import org.opencdmp.commons.enums.StorageType;
import org.opencdmp.commons.enums.TenantConfigurationType;
import org.opencdmp.commons.enums.*;
import org.opencdmp.commons.scope.tenant.TenantScope;
import org.opencdmp.commons.scope.user.UserScope;
import org.opencdmp.commons.types.filetransformer.FileTransformerSourceEntity;
import org.opencdmp.commons.types.tenantconfiguration.FileTransformerTenantConfigurationEntity;
import org.opencdmp.convention.ConventionService;
import org.opencdmp.data.TenantConfigurationEntity;
import org.opencdmp.event.TenantConfigurationTouchedEvent;
import org.opencdmp.filetransformerbase.interfaces.FileTransformerConfiguration;
import org.opencdmp.model.StorageFile;
import org.opencdmp.model.builder.commonmodels.description.DescriptionCommonModelBuilder;
import org.opencdmp.model.builder.commonmodels.dmp.DmpCommonModelBuilder;
import org.opencdmp.model.description.Description;
import org.opencdmp.model.dmp.Dmp;
import org.opencdmp.model.file.RepositoryFileFormat;
import org.opencdmp.model.persist.*;
import org.opencdmp.model.tenantconfiguration.TenantConfiguration;
import org.opencdmp.query.DescriptionQuery;
import org.opencdmp.query.DmpQuery;
@ -44,6 +47,7 @@ import org.springframework.context.MessageSource;
import org.springframework.context.event.EventListener;
import org.springframework.context.i18n.LocaleContextHolder;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.reactive.function.client.ExchangeFilterFunction;
import org.springframework.web.reactive.function.client.WebClient;
import reactor.core.publisher.Mono;
@ -52,6 +56,8 @@ import javax.crypto.BadPaddingException;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;
import javax.management.InvalidApplicationException;
import java.io.IOException;
import java.net.URLConnection;
import java.security.InvalidAlgorithmParameterException;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
@ -75,10 +81,11 @@ public class FileTransformerServiceImpl implements FileTransformerService {
private final TenantProperties tenantProperties;
private final JsonHandlingService jsonHandlingService;
private final FileTransformerSourcesCacheService fileTransformerSourcesCacheService;
private final UserScope userScope;
@Autowired
public FileTransformerServiceImpl(FileTransformerProperties fileTransformerProperties, TokenExchangeCacheService tokenExchangeCacheService, FileTransformerConfigurationCacheService fileTransformerConfigurationCacheService, AuthorizationService authorizationService,
QueryFactory queryFactory, BuilderFactory builderFactory, StorageFileService storageFileService, MessageSource messageSource, ConventionService conventionService, TenantScope tenantScope, EncryptionService encryptionService, TenantProperties tenantProperties, JsonHandlingService jsonHandlingService, FileTransformerSourcesCacheService fileTransformerSourcesCacheService) {
QueryFactory queryFactory, BuilderFactory builderFactory, StorageFileService storageFileService, MessageSource messageSource, ConventionService conventionService, TenantScope tenantScope, EncryptionService encryptionService, TenantProperties tenantProperties, JsonHandlingService jsonHandlingService, FileTransformerSourcesCacheService fileTransformerSourcesCacheService, UserScope userScope) {
this.fileTransformerProperties = fileTransformerProperties;
this.tokenExchangeCacheService = tokenExchangeCacheService;
this.fileTransformerConfigurationCacheService = fileTransformerConfigurationCacheService;
@ -93,7 +100,8 @@ public class FileTransformerServiceImpl implements FileTransformerService {
this.tenantProperties = tenantProperties;
this.jsonHandlingService = jsonHandlingService;
this.fileTransformerSourcesCacheService = fileTransformerSourcesCacheService;
this.clients = new HashMap<>();
this.userScope = userScope;
this.clients = new HashMap<>();
}
private FileTransformerRepository getRepository(String repoId) throws InvalidApplicationException, InvalidAlgorithmParameterException, NoSuchPaddingException, IllegalBlockSizeException, NoSuchAlgorithmException, BadPaddingException, InvalidKeyException {
@ -283,4 +291,39 @@ public class FileTransformerServiceImpl implements FileTransformerService {
});
}
@Override
public DmpModel importDmp(MultipartFile file, String repositoryId, String format) throws InvalidAlgorithmParameterException, NoSuchPaddingException, IllegalBlockSizeException, InvalidApplicationException, NoSuchAlgorithmException, BadPaddingException, InvalidKeyException, IOException, JAXBException {
this.authorizationService.authorize(Permission.NewDmp);
if (file == null) return null;
//GK: First get the right client
FileTransformerRepository repository = this.getRepository(repositoryId);
if (repository == null) throw new MyNotFoundException(this.messageSource.getMessage("General_ItemNotFound", new Object[]{format, FileTransformerRepository.class.getSimpleName()}, LocaleContextHolder.getLocale()));
String name = FilenameUtils.removeExtension(file.getOriginalFilename());
String extension = FilenameUtils.getExtension(file.getOriginalFilename());
String mimeType = URLConnection.guessContentTypeFromName(file.getOriginalFilename());
FileEnvelopeModel fileEnvelope = new FileEnvelopeModel();
fileEnvelope.setFile(file.getBytes());
fileEnvelope.setMimeType(mimeType);
fileEnvelope.setFilename(name + (extension.startsWith(".") ? "" : ".") + extension);
if (repository.getConfiguration() != null && repository.getConfiguration().isUseSharedStorage()){
StorageFilePersist storageFilePersist = new StorageFilePersist();
storageFilePersist.setName(name);
storageFilePersist.setExtension(extension);
storageFilePersist.setMimeType(mimeType);
storageFilePersist.setOwnerId(this.userScope.getUserIdSafe());
storageFilePersist.setStorageType(StorageType.Transformer);
StorageFile storageFile = this.storageFileService.persistBytes(storageFilePersist, file.getBytes(), new BaseFieldSet(StorageFile._id, StorageFile._fileRef, StorageFile._mimeType, StorageFile._extension, StorageFile._name));
fileEnvelope.setFileRef(storageFile.getFileRef());
}
return repository.importDmp(fileEnvelope);
}
}

View File

@ -26,7 +26,6 @@ import org.opencdmp.model.builder.dmp.DmpBuilder;
import org.opencdmp.model.censorship.PublicDmpCensor;
import org.opencdmp.model.censorship.dmp.DmpCensor;
import org.opencdmp.model.dmp.Dmp;
import org.opencdmp.model.dmpblueprint.DmpBlueprint;
import org.opencdmp.model.persist.*;
import org.opencdmp.model.result.QueryResult;
import org.opencdmp.query.DmpQuery;
@ -364,4 +363,20 @@ public class DmpController {
return model;
}
@PostMapping("json/import")
@Transactional
public Dmp importJson(@RequestParam("file") MultipartFile file, @RequestParam("label") String label, @RequestParam("repositoryId") String repositoryId, @RequestParam("format") String format, FieldSet fields) throws InvalidAlgorithmParameterException, JAXBException, NoSuchPaddingException, IllegalBlockSizeException, InvalidApplicationException, IOException, NoSuchAlgorithmException, BadPaddingException, InvalidKeyException {
logger.debug(new MapLogEntry("import json" + Dmp.class.getSimpleName()).And("transformerId", repositoryId).And("file", file).And("label", label));
Dmp model = this.dmpService.importJson(file, label, repositoryId, format, fields);
this.auditService.track(AuditableAction.Dmp_Import, Map.ofEntries(
new AbstractMap.SimpleEntry<String, Object>("transformerId", repositoryId),
new AbstractMap.SimpleEntry<String, Object>("file", file),
new AbstractMap.SimpleEntry<String, Object>("fields", fields)
));
return model;
}
}

View File

@ -2,7 +2,7 @@ web:
security:
enabled: true
authorized-endpoints: [ api ]
allowed-endpoints: [ api/public, api/dmp/public, api/description/public, /api/supportive-material/public, api/language/public, api/contact-support/public, api/dashboard/public, prometheus, health, metrics ]
allowed-endpoints: [ api/public, api/dmp/public, api/description/public, /api/supportive-material/public, api/language/public, api/contact-support/public, api/dashboard/public, prometheus, health, metrics, swagger-ui, v3/api-docs ]
idp:
api-key:
enabled: false

View File

@ -1,5 +1,7 @@
springdoc:
packagesToScan: org.opencdmp.publicapi.controllers
packagesToScan: org.opencdmp.controllers.publicapi
pathsToScan: "/api/public/(dmps|datasets)/?.*"
swagger-ui:
enabled: true
useRootPath: true
docExpansion: none

View File

@ -207,6 +207,28 @@ export class DmpService {
catchError((error: any) => throwError(error)));;
}
uploadJson(file: File, label: string, repositoryId: string, format: string, reqFields: string[] = []): Observable<Dmp> {
const url = `${this.apiBase}/json/import`;
const params = new BaseHttpParams();
params.interceptorContext = {
excludedInterceptors: [InterceptorType.JSONContentType]
};
const formData = new FormData();
formData.append('file', file);
formData.append('label', label);
formData.append('repositoryId', repositoryId);
formData.append('format', format);
if (reqFields.length > 0){
for (var i = 0; i < reqFields.length; i++) {
formData.append('field[]', reqFields[i]);
}
}
return this.http.post<Dmp>(url, formData, { params: params }).pipe(catchError((error: any) => throwError(error)));
}
//
// Autocomplete Commons
//

View File

@ -66,15 +66,28 @@ export class StartNewDmpDialogComponent extends BaseComponent {
});
dialogRef.afterClosed().pipe(takeUntil(this._destroyed)).subscribe(result => {
if (result && result.success) {
this.dmpService.uploadXml(result.fileList[0], result.dmpTitle)
.pipe(takeUntil(this._destroyed))
.subscribe(
(complete) => {
this.onCallbackImportComplete();
this.dialog.closeAll();
},
(error) => this.onCallbackImportFail(error.error)
);
const file = result.fileList[0] as File;
if (file?.type.includes('/xml')){
this.dmpService.uploadXml(result.fileList[0], result.dmpTitle)
.pipe(takeUntil(this._destroyed))
.subscribe(
(complete) => {
this.onCallbackImportComplete();
this.dialog.closeAll();
},
(error) => this.onCallbackImportFail(error.error)
);
} else if (file?.type.includes('/json')){
this.dmpService.uploadJson(result.fileList[0], result.dmpTitle, 'rda-file-transformer', 'json')
.pipe(takeUntil(this._destroyed))
.subscribe(
(complete) => {
this.onCallbackImportComplete();
this.dialog.closeAll();
},
(error) => this.onCallbackImportFail(error.error)
);
}
}
});
}

View File

@ -133,5 +133,6 @@ These are the semantics suggestions.
- `zenodo.related_identifiers.isRequiredBy`
- `zenodo.related_identifiers.isObsoletedBy`
- `zenodo.related_identifiers.obsoletes`
- `zenodo.publication_date`
</TabItem>
</Tabs>

View File

@ -3,4 +3,29 @@ sidebar_position: 1
description: A brief guide on the API documentation tool this platform uses
---
import Tabs from '@theme/Tabs';
import TabItem from '@theme/TabItem';
import Admonition from '@theme/Admonition';
# Swagger
The swagger UI is available at the `/swagger-ui/index.html` url. It contains documentation for the following API endpoints.
<Tabs>
<TabItem value="public" label="Public API">
- **/api/public/dmps/\*\***
- **/api/public/descriptions/\*\***
</TabItem>
<TabItem value="internal" label="Internal API">
- **/api/dmp/\*\***
- **/api/description/\*\***
<Admonition type="info">
<p>These endpoints require authentication.</p>
</Admonition>
</TabItem>
</Tabs>