Merge branch 'multipleRepos' into Development

This commit is contained in:
Diamantis Tziotzios 2023-01-16 14:11:43 +02:00
commit 4dccaa93b8
74 changed files with 1669 additions and 823 deletions

View File

@ -12,4 +12,4 @@ RUN mvn package
FROM adoptopenjdk/openjdk11:alpine-jre
WORKDIR /app
COPY --from=MAVEN_BUILD /build/web/target/web-1.0-SNAPSHOT.jar /app/app.jar
ENTRYPOINT ["java", "-Djava.security.egd=file:/dev/./urandom", "-Dspring.profiles.active=${PROF}", "-Dspring.config.additional-location=/files/config/", "-jar","/app/app.jar"]
ENTRYPOINT ["java", "-Djava.security.egd=file:/dev/./urandom", "-Dspring.profiles.active=${PROF}", "-Dspring.config.additional-location=/files/config/", "-cp", "/app/app.jar", "-Dloader.path=/files/repo-jars", "org.springframework.boot.loader.PropertiesLauncher"]

View File

@ -87,7 +87,7 @@ public class DMPDaoImpl extends DatabaseAccess<DMP> implements DMPDao {
}
if (criteria.hasDoi()) {
query.where((builder, root) -> builder.not(builder.isNull(root.get("doi"))));
query.where((builder, root) -> builder.not(builder.isNull(root.join("dois").get("id"))));
}
query.where((builder, root) -> builder.notEqual(root.get("status"), DMP.DMPStatus.DELETED.getValue()));
return query;

View File

@ -80,7 +80,7 @@ public class DatasetDaoImpl extends DatabaseAccess<Dataset> implements DatasetDa
query.where((builder, root) -> root.get("profile").get("id").in(criteria.getDatasetTemplates()));
if (criteria.hasDoi()) {
query.where((builder, root) -> builder.not(builder.isNull(root.get("dmp").get("doi"))));
query.where((builder, root) -> builder.not(builder.isNull(root.join("dmp").join("dois").get("id"))));
}
query.where((builder, root) -> builder.notEqual(root.get("status"), Dataset.Status.DELETED.getValue()));
query.where((builder, root) -> builder.notEqual(root.get("status"), Dataset.Status.CANCELED.getValue()));

View File

@ -0,0 +1,10 @@
package eu.eudat.data.dao.entities;
import eu.eudat.data.dao.DatabaseAccessLayer;
import eu.eudat.data.entities.EntityDoi;
import java.util.UUID;
public interface EntityDoiDao extends DatabaseAccessLayer<EntityDoi, UUID> {
EntityDoi findFromDoi(String doi);
}

View File

@ -0,0 +1,56 @@
package eu.eudat.data.dao.entities;
import eu.eudat.data.dao.DatabaseAccess;
import eu.eudat.data.dao.databaselayer.service.DatabaseService;
import eu.eudat.data.entities.EntityDoi;
import eu.eudat.queryable.QueryableList;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import java.util.UUID;
import java.util.concurrent.CompletableFuture;
@Component("EntityDoiDao")
public class EntityDoiDaoImpl extends DatabaseAccess<EntityDoi> implements EntityDoiDao {
@Autowired
public EntityDoiDaoImpl(DatabaseService<EntityDoi> databaseService){
super(databaseService);
}
@Override
public EntityDoi createOrUpdate(EntityDoi item) {
return this.getDatabaseService().createOrUpdate(item, EntityDoi.class);
}
@Override
public CompletableFuture<EntityDoi> createOrUpdateAsync(EntityDoi item) {
return CompletableFuture.supplyAsync(() -> this.createOrUpdate(item));
}
@Override
public EntityDoi find(UUID id) {
return this.getDatabaseService().getQueryable(EntityDoi.class).where((builder, root) -> builder.equal(root.get("id"), id)).getSingle();
}
@Override
public EntityDoi findFromDoi(String doi) {
return this.getDatabaseService().getQueryable(EntityDoi.class).where((builder, root) -> builder.equal(root.get("doi"), doi)).getSingle();
}
@Override
public EntityDoi find(UUID id, String hint) {
return null;
}
@Override
public void delete(EntityDoi item) {
this.getDatabaseService().delete(item);
}
@Override
public QueryableList<EntityDoi> asQueryable() {
return this.getDatabaseService().getQueryable(EntityDoi.class);
}
}

View File

@ -3,7 +3,9 @@ package eu.eudat.data.dao.entities;
import eu.eudat.data.dao.DatabaseAccessLayer;
import eu.eudat.data.entities.FileUpload;
import java.util.List;
import java.util.UUID;
public interface FileUploadDao extends DatabaseAccessLayer<FileUpload, UUID> {
List<FileUpload> getFileUploads(UUID entityId);
}

View File

@ -7,6 +7,7 @@ import eu.eudat.queryable.QueryableList;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import java.util.List;
import java.util.UUID;
import java.util.concurrent.CompletableFuture;
@ -33,6 +34,11 @@ public class FileUploadDaoImpl extends DatabaseAccess<FileUpload> implements Fil
return getDatabaseService().getQueryable(FileUpload.class).where((builder, root) -> builder.equal(root.get("id"), id)).getSingle();
}
@Override
public List<FileUpload> getFileUploads(UUID entityId) {
return this.getDatabaseService().getQueryable(FileUpload.class).where((builder, root) -> builder.equal(root.get("entityId"), entityId)).toList();
}
@Override
public FileUpload find(UUID id, String hint) {
return null;

View File

@ -181,8 +181,8 @@ public class DMP implements DataEntity<DMP, UUID> {
@Convert(converter = DateToUTCConverter.class)
private Date publishedAt;
@Column(name = "\"DOI\"")
private String doi;
@OneToMany(mappedBy = "entityId", fetch = FetchType.LAZY)
private Set<EntityDoi> dois;
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "\"Project\"")
@ -339,12 +339,12 @@ public class DMP implements DataEntity<DMP, UUID> {
this.publishedAt = publishedAt;
}
public String getDoi() {
return doi;
}
public void setDoi(String doi) {
this.doi = doi;
}
public Set<EntityDoi> getDois() {
return dois;
}
public void setDois(Set<EntityDoi> dois) {
this.dois = dois;
}
public Project getProject() {
return project;
@ -380,7 +380,7 @@ public class DMP implements DataEntity<DMP, UUID> {
if (entity.getStatus().equals(DMPStatus.FINALISED.getValue())) this.setFinalizedAt(new Date());
if (entity.isPublic) this.setPublishedAt(new Date());
if (entity.getUsers() != null) this.users = entity.getUsers();
if (entity.getDoi() != null && entity.getDoi().trim().isEmpty()) this.doi = entity.doi;
this.dois = entity.getDois();
this.extraProperties = entity.getExtraProperties();
}

View File

@ -0,0 +1,121 @@
package eu.eudat.data.entities;
import eu.eudat.data.converters.DateToUTCConverter;
import eu.eudat.data.entities.helpers.EntityBinder;
import eu.eudat.queryable.queryableentity.DataEntity;
import org.hibernate.annotations.Type;
import javax.persistence.*;
import java.util.Arrays;
import java.util.Date;
import java.util.List;
import java.util.UUID;
import java.util.stream.Collectors;
@Entity
@Table(name = "\"EntityDoi\"")
public class EntityDoi implements DataEntity<EntityDoi, UUID> {
public enum EntityType {
DMP
}
@Id
@Column(name = "\"ID\"", updatable = false, nullable = false, columnDefinition = "BINARY(16)")
private UUID id;
@Enumerated(EnumType.STRING)
@Type(type = "eu.eudat.configurations.typedefinition.PostgreSQLEnumType")
@Column(name = "\"EntityType\"", nullable = false)
private EntityType entityType;
@Column(name = "\"RepositoryId\"", nullable = false)
private String repositoryId;
@Column(name = "\"Doi\"", nullable = false)
private String doi;
@Column(name = "\"CreatedAt\"", nullable = false)
@Convert(converter = DateToUTCConverter.class)
private Date createdAt;
@Column(name = "\"UpdatedAt\"", nullable = false)
@Convert(converter = DateToUTCConverter.class)
private Date updatedAt;
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "\"EntityId\"", nullable = false)
private DMP entityId;
public UUID getId() {
return id;
}
public void setId(UUID id) {
this.id = id;
}
public EntityType getEntityType() {
return entityType;
}
public void setEntityType(EntityType entityType) {
this.entityType = entityType;
}
public String getRepositoryId() {
return repositoryId;
}
public void setRepositoryId(String repositoryId) {
this.repositoryId = repositoryId;
}
public String getDoi() {
return doi;
}
public void setDoi(String doi) {
this.doi = doi;
}
public Date getCreatedAt() {
return createdAt;
}
public void setCreatedAt(Date createdAt) {
this.createdAt = createdAt;
}
public Date getUpdatedAt() {
return updatedAt;
}
public void setUpdatedAt(Date updatedAt) {
this.updatedAt = updatedAt;
}
public DMP getEntityId() {
return entityId;
}
public void setEntityId(DMP entityId) {
this.entityId = entityId;
}
@Override
public void update(EntityDoi doi) {
this.entityType = doi.getEntityType();
this.repositoryId = doi.getRepositoryId();
this.doi = doi.getDoi();
this.createdAt = doi.getCreatedAt();
this.updatedAt = doi.getUpdatedAt();
this.entityId = doi.getEntityId();
}
@Override
public UUID getKeys() {
return this.id;
}
@Override
public EntityDoi buildFromTuple(List<Tuple> tuple, List<String> fields, String base) {
String currentBase = base.isEmpty() ? "" : base + ".";
if (fields.contains(currentBase + "id")) this.id = EntityBinder.fromTuple(tuple, currentBase + "id");
if (fields.contains(currentBase + "entityId"))
this.entityId = tuple.stream().map(x -> new DMP().buildFromTuple(Arrays.asList(x), fields , base.isEmpty() ? "entityId" : base + "." + "entityId")).collect(Collectors.toList()).get(0);
return this;
}
}

View File

@ -57,7 +57,7 @@ public class Dmp implements ElasticEntity<Dmp> {
private Date modified;
private Date finalizedAt;
private Date publishedAt;
private String doi;
private List<Doi> dois;
public UUID getId() {
return id;
@ -203,12 +203,12 @@ public class Dmp implements ElasticEntity<Dmp> {
this.publishedAt = publishedAt;
}
public String getDoi() {
return doi;
public List<Doi> getDois() {
return dois;
}
public void setDoi(String doi) {
this.doi = doi;
public void setDois(List<Doi> dois) {
this.dois = dois;
}
@Override
@ -280,7 +280,17 @@ public class Dmp implements ElasticEntity<Dmp> {
builder.field(MapKey.MODIFIED.getName(), this.modified);
builder.field(MapKey.FINALIZEDAT.getName(), this.finalizedAt);
builder.field(MapKey.PUBLISHEDAT.getName(), this.publishedAt);
builder.field(MapKey.DOI.getName(), this.doi);
if (this.dois != null && !this.dois.isEmpty()) {
builder.startArray(MapKey.DOIS.getName());
this.dois.forEach(doi -> {
try {
doi.toElasticEntity(builder);
} catch (IOException e) {
logger.error(e.getMessage(), e);
}
});
builder.endArray();
}
builder.endObject();
return builder;
}
@ -329,8 +339,8 @@ public class Dmp implements ElasticEntity<Dmp> {
if (fields.get(MapKey.PUBLISHEDAT.getName()) != null) {
this.publishedAt = Date.from(Instant.parse(fields.get(MapKey.PUBLISHEDAT.getName()).toString()));
}
if (fields.get(MapKey.DOI.getName()) != null) {
this.doi = fields.get(MapKey.DOI.getName()).toString();
if (fields.get(MapKey.DOIS.getName()) != null) {
this.dois = ((List<HashMap<String, Object>>) fields.get(MapKey.DOIS.getName())).stream().map(map -> new Doi().fromElasticEntity(map)).collect(Collectors.toList());
}
}
return this;
@ -355,7 +365,7 @@ public class Dmp implements ElasticEntity<Dmp> {
MODIFIED ("modified"),
FINALIZEDAT ("finalizedAt"),
PUBLISHEDAT ("publishedAt"),
DOI ("doi");
DOIS ("dois");
private final String name;

View File

@ -0,0 +1,65 @@
package eu.eudat.elastic.entities;
import org.elasticsearch.common.xcontent.XContentBuilder;
import java.io.IOException;
import java.util.Map;
import java.util.UUID;
public class Doi implements ElasticEntity<Doi>{
private UUID id;
private String repositoryId;
private String doi;
private UUID dmp;
public UUID getId() {
return id;
}
public void setId(UUID id) {
this.id = id;
}
public String getRepositoryId() {
return repositoryId;
}
public void setRepositoryId(String repositoryId) {
this.repositoryId = repositoryId;
}
public String getDoi() {
return doi;
}
public void setDoi(String doi) {
this.doi = doi;
}
public UUID getDmp() {
return dmp;
}
public void setDmp(UUID dmp) {
this.dmp = dmp;
}
@Override
public XContentBuilder toElasticEntity(XContentBuilder builder) throws IOException {
builder.startObject();
builder.field("id", this.id.toString());
builder.field("repositoryId", this.repositoryId);
builder.field("doi", this.doi);
builder.field("dmp", this.dmp.toString());
builder.endObject();
return builder;
}
@Override
public Doi fromElasticEntity(Map<String, Object> fields) {
if (fields == null || fields.isEmpty()) {
return null;
}
this.id = UUID.fromString((String) fields.get("id"));
this.repositoryId = (String) fields.get("repositoryId");
this.doi = (String) fields.get("doi");
this.dmp = UUID.fromString((String) fields.get("dmp"));
return this;
}
}

View File

@ -26,13 +26,16 @@
<artifactId>queryable</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>eu.eudat</groupId>
<artifactId>elastic</artifactId>
<version>1.0.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>gr.cite.opendmp</groupId>
<artifactId>repositorydepositbase</artifactId>
<version>1.0.0</version>
</dependency>
<dependency>
@ -220,6 +223,39 @@
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<version>2.4</version>
<configuration>
<archive>
<manifest>
<addClasspath>true</addClasspath>
<mainClass>eu.eudat.EuDatApplication</mainClass>
<classpathPrefix>dependency-jars/</classpathPrefix>
</manifest>
</archive>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<version>2.5.1</version>
<executions>
<execution>
<id>copy-dependencies</id>
<phase>package</phase>
<goals>
<goal>copy-dependencies</goal>
</goals>
<configuration>
<outputDirectory>
${project.build.directory}/dependency-jars/
</outputDirectory>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>

View File

@ -8,7 +8,7 @@ import org.springframework.boot.builder.SpringApplicationBuilder;
import org.springframework.boot.web.servlet.support.SpringBootServletInitializer;
import org.springframework.scheduling.annotation.EnableAsync;
@SpringBootApplication
@SpringBootApplication(scanBasePackages = {"eu.eudat", "eu.eudat.depositinterface"})
@EnableAsync
public class EuDatApplication extends SpringBootServletInitializer {
private static final Logger logger = LoggerFactory.getLogger(EuDatApplication.class);

View File

@ -0,0 +1,67 @@
package eu.eudat.controllers;
import eu.eudat.logic.managers.DepositManager;
import eu.eudat.logic.security.claims.ClaimedAuthorities;
import eu.eudat.logic.services.ApiContext;
import eu.eudat.models.data.doi.DepositCode;
import eu.eudat.models.data.doi.DepositRequest;
import eu.eudat.models.data.doi.Doi;
import eu.eudat.models.data.doi.RepositoryConfig;
import eu.eudat.models.data.helpers.responses.ResponseItem;
import eu.eudat.models.data.security.Principal;
import eu.eudat.types.ApiMessageCode;
import eu.eudat.types.Authorities;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import java.util.List;
@RestController
@CrossOrigin
@RequestMapping(value = {"/api/deposit/"})
public class DepositController extends BaseController {
private static final Logger logger = LoggerFactory.getLogger(DepositController.class);
private DepositManager depositManager;
@Autowired
public DepositController(ApiContext apiContext, DepositManager depositManager){
super(apiContext);
this.depositManager = depositManager;
}
@RequestMapping(method = RequestMethod.GET, value = {"/repos"})
public @ResponseBody
ResponseEntity<ResponseItem<List<RepositoryConfig>>> getAvailableRepos(@ClaimedAuthorities(claims = {Authorities.ADMIN, Authorities.MANAGER, Authorities.USER, Authorities.ANONYMOUS}) Principal principal) {
List<RepositoryConfig> ids = this.depositManager.getAvailableRepos();
return ResponseEntity.status(HttpStatus.OK).body(new ResponseItem<List<RepositoryConfig>>().status(ApiMessageCode.NO_MESSAGE).payload(ids));
}
@RequestMapping(method = RequestMethod.POST, value = {"/getAccessToken"})
public @ResponseBody
ResponseEntity<ResponseItem<String>> getAccessToken(@RequestBody DepositCode depositCode, @ClaimedAuthorities(claims = {Authorities.ADMIN, Authorities.MANAGER, Authorities.USER, Authorities.ANONYMOUS}) Principal principal) throws Exception {
String accessToken = this.depositManager.authenticate(depositCode.getRepositoryId(), depositCode.getCode());
return ResponseEntity.status(HttpStatus.OK).body(new ResponseItem<String>().status(ApiMessageCode.NO_MESSAGE).payload(accessToken));
}
@RequestMapping(method = RequestMethod.POST, value = {"/createDoi"})
public @ResponseBody
ResponseEntity<ResponseItem<Doi>> createDoi(@RequestBody DepositRequest depositRequest, @ClaimedAuthorities(claims = {Authorities.ADMIN, Authorities.MANAGER, Authorities.USER, Authorities.ANONYMOUS}) Principal principal) {
try {
Doi doi = this.depositManager.deposit(depositRequest, principal);
if(doi != null){
return ResponseEntity.status(HttpStatus.OK).body(new ResponseItem<Doi>().status(ApiMessageCode.SUCCESS_MESSAGE).message("Successfully created DOI for Data Datamanagement Plan in question.").payload(doi));
}
else{
return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(new ResponseItem<Doi>().status(ApiMessageCode.ERROR_MESSAGE).message("Failed to create DOI for the Data Management Plan"));
}
} catch (Exception e) {
logger.error(e.getMessage(), e);
return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(new ResponseItem<Doi>().status(ApiMessageCode.ERROR_MESSAGE).message("Failed to create DOI for the Data Management Plan: " + e.getMessage()));
}
}
}

View File

@ -15,6 +15,8 @@ import eu.eudat.data.enumeration.notification.NotifyState;
import eu.eudat.data.query.items.table.dataset.DatasetTableRequest;
import eu.eudat.data.query.items.table.datasetprofile.DatasetProfileTableRequestItem;
import eu.eudat.data.query.items.table.dmp.DataManagementPlanTableRequest;
import eu.eudat.depositinterface.models.DMPDepositModel;
import eu.eudat.depositinterface.repository.RepositoryDeposit;
import eu.eudat.elastic.criteria.DmpCriteria;
import eu.eudat.elastic.entities.Collaborator;
import eu.eudat.elastic.entities.Dmp;
@ -29,6 +31,7 @@ import eu.eudat.logic.builders.entity.UserInfoBuilder;
import eu.eudat.logic.mapper.elastic.DmpMapper;
import eu.eudat.logic.mapper.elastic.criteria.DmpCriteriaMapper;
import eu.eudat.logic.proxy.config.configloaders.ConfigLoader;
import eu.eudat.logic.security.repositorydeposit.mapper.DMPToDepositMapper;
import eu.eudat.logic.services.ApiContext;
import eu.eudat.logic.services.forms.VisibilityRuleService;
import eu.eudat.logic.services.forms.VisibilityRuleServiceImpl;
@ -45,6 +48,8 @@ import eu.eudat.models.data.datasetprofile.DatasetProfileListingModel;
import eu.eudat.models.data.datasetwizard.DatasetWizardModel;
import eu.eudat.models.data.datasetwizard.DatasetsToBeFinalized;
import eu.eudat.models.data.dmp.*;
import eu.eudat.models.data.doi.DepositRequest;
import eu.eudat.models.data.doi.Doi;
import eu.eudat.models.data.dynamicfields.DynamicFieldWithValue;
import eu.eudat.models.data.entities.xmlmodels.dmpprofiledefinition.DataManagementPlanProfile;
import eu.eudat.models.data.entities.xmlmodels.dmpprofiledefinition.Field;
@ -57,11 +62,10 @@ import eu.eudat.models.data.project.ProjectDMPEditorModel;
import eu.eudat.models.data.security.Principal;
import eu.eudat.models.data.user.composite.PagedDatasetProfile;
import eu.eudat.models.data.userinfo.UserListingModel;
import eu.eudat.models.deposit.zenodo.ZenodoDeposit;
import eu.eudat.models.deposit.zenodo.mapper.DMPToZenodoMapper;
import eu.eudat.queryable.QueryableList;
import eu.eudat.types.Authorities;
import eu.eudat.types.MetricNames;
import org.apache.commons.io.IOUtils;
import org.apache.poi.xwpf.usermodel.XWPFDocument;
import org.apache.poi.xwpf.usermodel.XWPFParagraph;
import org.apache.poi.xwpf.usermodel.XWPFRun;
@ -70,11 +74,8 @@ import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.env.Environment;
import org.springframework.core.io.FileSystemResource;
import org.springframework.http.*;
import org.springframework.stereotype.Component;
import org.springframework.web.client.HttpClientErrorException;
import org.springframework.web.client.HttpServerErrorException;
import org.springframework.web.client.RestTemplate;
import org.springframework.web.multipart.MultipartFile;
import org.w3c.dom.Document;
@ -86,6 +87,7 @@ import javax.xml.bind.JAXBException;
import javax.xml.bind.Unmarshaller;
import java.io.*;
import java.math.BigInteger;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.time.Instant;
import java.time.temporal.ChronoUnit;
@ -93,6 +95,8 @@ import java.util.*;
import java.util.concurrent.CompletableFuture;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;
@Component
public class DataManagementPlanManager {
@ -114,9 +118,11 @@ public class DataManagementPlanManager {
private UserManager userManager;
private final MetricsManager metricsManager;
private final ConfigLoader configLoader;
private List<RepositoryDeposit> repositoriesDeposit;
@Autowired
public DataManagementPlanManager(ApiContext apiContext, DatasetManager datasetManager, Environment environment, RDAManager rdaManager, UserManager userManager, MetricsManager metricsManager, ConfigLoader configLoader) {
public DataManagementPlanManager(ApiContext apiContext, DatasetManager datasetManager, Environment environment, RDAManager rdaManager, UserManager userManager,
MetricsManager metricsManager, ConfigLoader configLoader, List<RepositoryDeposit> repositoriesDeposit) {
this.apiContext = apiContext;
this.datasetManager = datasetManager;
this.databaseRepository = apiContext.getOperationsContext().getDatabaseRepository();
@ -126,6 +132,7 @@ public class DataManagementPlanManager {
this.metricsManager = metricsManager;
this.configLoader = configLoader;
this.objectMapper = new ObjectMapper();
this.repositoriesDeposit = repositoriesDeposit;
}
/*
@ -749,7 +756,7 @@ public class DataManagementPlanManager {
metricsManager.decreaseValue(MetricNames.DMP, 1, MetricNames.DRAFT);
break;
case 1:
if (oldDmp.getDoi() != null) {
if (oldDmp.getDois() != null && !oldDmp.getDois().isEmpty()) {
metricsManager.decreaseValue(MetricNames.DMP, 1, MetricNames.DOIED);
}
if (oldDmp.isPublic()) {
@ -1057,9 +1064,9 @@ public class DataManagementPlanManager {
});
UserInfo user = apiContext.getOperationsContext().getDatabaseRepository().getUserInfoDao().find(principal.getId());
sendNotification(dmp, user, NotificationType.DMP_PUBLISH);
if (dmp.getDoi() != null && !dmp.getDoi().isEmpty()) {
this.createZenodoDoi(dmp.getId(), principal, true);
}
// if (dmp.getDois() != null && !dmp.getDois().isEmpty()) {
// this.createZenodoDoi(dmp.getId(), principal, true);
// }
}
@Transactional
@ -1151,6 +1158,10 @@ public class DataManagementPlanManager {
throw new Exception("User does not have the privilege to do this action.");
if (dmp.getStatus().equals(DMP.DMPStatus.ACTIVE.getValue()))
throw new Exception("DMP is already Active");
if (dmp.isPublic())
throw new Exception("DMP is publicly available");
if (!dmp.getDois().isEmpty())
throw new Exception("DMP is deposited");
dmp.setStatus(DMP.DMPStatus.ACTIVE.getValue());
apiContext.getOperationsContext().getDatabaseRepository().getDmpDao().createOrUpdate(dmp);
UUID dmpId = dmp.getId();
@ -2006,23 +2017,28 @@ public class DataManagementPlanManager {
* DOI Generation
* */
private String getPreviousDOI(UUID groupId, UUID selfId) {
private String getPreviousDOI(UUID groupId, UUID selfId, String repositoryId) {
DataManagementPlanCriteria criteria = new DataManagementPlanCriteria();
List<UUID> groupIds = new ArrayList<>();
groupIds.add(groupId);
criteria.setGroupIds(groupIds);
criteria.setAllVersions(true);
List<DMP> dmps = this.databaseRepository.getDmpDao().getWithCriteria(criteria).toList();
String doi = null;
dmps.sort((DMP d1, DMP d2) -> d2.getVersion() - d1.getVersion());
for (DMP dmp: dmps) {
if (!dmp.getId().equals(selfId)) {
if (dmp.getDoi() != null && !dmp.getDoi().isEmpty()) {
doi = dmp.getDoi();
if (dmp.getDois() != null && !dmp.getDois().isEmpty()) {
for (Iterator<EntityDoi> it = dmp.getDois().iterator(); it.hasNext(); ) {
EntityDoi entityDoi = it.next();
if(entityDoi.getRepositoryId().equals(repositoryId)){
return entityDoi.getDoi();
}
}
}
}
}
return doi;
return null;
}
private String getUnpublishedDOI(String DOI, String token, Integer version) {
@ -2064,6 +2080,22 @@ public class DataManagementPlanManager {
/*if (dmp.getDoi() != null)
throw new Exception("DMP already has a DOI");*/
FileEnvelope file = getWordDocument(id.toString(), principal, configLoader);
String name = file.getFilename().substring(0, file.getFilename().length() - 5);
File pdfFile = PDFUtils.convertToPDF(file, environment);
String fileName = name + ".pdf";
ResponseEntity<byte[]> jsonFile;
try {
jsonFile = getRDAJsonDocument(id.toString(), principal);
} catch (Exception e) {
throw e;
}
String previousDOI = this.getPreviousDOI(dmp.getGroupId(), dmp.getId(), "Zenodo");
File supportingFilesZip = this.createSupportingFilesZip(dmp);
DMPDepositModel dmpDepositModel = DMPToDepositMapper.fromDMP(dmp, pdfFile, fileName, jsonFile, supportingFilesZip, previousDOI);
String zenodoToken = "";
try {
if (this.userManager.isDOITokenValid(principal)) {
@ -2072,136 +2104,126 @@ public class DataManagementPlanManager {
} catch (NonValidTokenException e) {
zenodoToken = this.environment.getProperty("zenodo.access_token");
}
// First step, post call to Zenodo, to create the entry.
RestTemplate restTemplate = new RestTemplate();
HttpHeaders headers = new HttpHeaders();
headers.setAccept(Collections.singletonList(MediaType.APPLICATION_JSON));
headers.setContentType(MediaType.APPLICATION_JSON);
ZenodoDeposit deposit = DMPToZenodoMapper.fromDMP(dmp, environment, configLoader);
//if (Objects.requireNonNull(environment.getProperty("spring.profiles.active")).contains("devel")) {
String json = objectMapper.writerWithDefaultPrettyPrinter().writeValueAsString(deposit);
logger.info(json);
//}
HttpEntity<ZenodoDeposit> request = new HttpEntity<>(deposit, headers);
Map createResponse;
LinkedHashMap<String, String> links;
String previousDOI = this.getPreviousDOI(dmp.getGroupId(), dmp.getId());
String unpublishedUrl = null;
String publishUrl;
String finalDoi;
try {
if (previousDOI == null) {
String createUrl = this.environment.getProperty("zenodo.url") + "deposit/depositions" + "?access_token=" + zenodoToken;
createResponse = restTemplate.postForEntity(createUrl, request, Map.class).getBody();
links = (LinkedHashMap<String, String>) createResponse.get("links");
finalDoi = (String) createResponse.get("conceptdoi");
} else {
unpublishedUrl = this.getUnpublishedDOI(previousDOI, zenodoToken, dmp.getVersion());
if (unpublishedUrl == null) {
//It requires more than one step to create a new version
//First, get the deposit related to the concept DOI
String listUrl = this.environment.getProperty("zenodo.url") + "deposit/depositions" + "?q=conceptdoi:\"" + previousDOI + "\"&access_token=" + zenodoToken;
ResponseEntity<Map[]> listResponses = restTemplate.getForEntity(listUrl, Map[].class);
createResponse = listResponses.getBody()[0];
links = (LinkedHashMap<String, String>) createResponse.get("links");
//Second, make the new version (not in the links?)
String newVersionUrl = links.get("self") + "/actions/newversion" + "?access_token=" + zenodoToken;
createResponse = restTemplate.postForObject(newVersionUrl, null, Map.class);
links = (LinkedHashMap<String, String>) createResponse.get("links");
//Third, get the new deposit
String latestDraftUrl = links.get("latest_draft") + "?access_token=" + zenodoToken;
createResponse = restTemplate.getForObject(latestDraftUrl, Map.class);
links = (LinkedHashMap<String, String>) createResponse.get("links");
finalDoi = (String) createResponse.get("conceptdoi");
//At this point it might fail to perform the next requests so enclose them with try catch
try {
//Forth, update the new deposit's metadata
String updateUrl = links.get("self") + "?access_token=" + zenodoToken;
restTemplate.put(updateUrl, request);
//And finally remove pre-existing files from it
String fileListUrl = links.get("self") + "/files" + "?access_token=" + zenodoToken;
ResponseEntity<Map[]> fileListResponse = restTemplate.getForEntity(fileListUrl, Map[].class);
for (Map file : fileListResponse.getBody()) {
String fileDeleteUrl = links.get("self") + "/files/" + file.get("id") + "?access_token=" + zenodoToken;
restTemplate.delete(fileDeleteUrl);
}
} catch (Exception e) {
//In case the last two steps fail delete the latest Deposit it in order to create a new one (only one at a time is allowed)
restTemplate.delete(latestDraftUrl);
throw e;
}
}
else {
String listUrl = this.environment.getProperty("zenodo.url") + "deposit/depositions" + "?q=conceptdoi:\"" + previousDOI + "\"&access_token=" + zenodoToken;
ResponseEntity<Map[]> listResponses = restTemplate.getForEntity(listUrl, Map[].class);
createResponse = listResponses.getBody()[0];
links = (LinkedHashMap<String, String>) createResponse.get("links");
String finalDoi = null;
for(RepositoryDeposit repo: this.repositoriesDeposit) { //temp
if(repo.getConfiguration().getRepositoryId().equals("Zenodo")) {
finalDoi = repo.deposit(dmpDepositModel, zenodoToken);
if (finalDoi != null) {
EntityDoi doiEntity = new EntityDoi();
doiEntity.setId(UUID.randomUUID());
doiEntity.setEntityType(EntityDoi.EntityType.DMP);
doiEntity.setDoi(finalDoi);
doiEntity.setRepositoryId("Zenodo");
Date now = new Date();
doiEntity.setCreatedAt(now);
doiEntity.setUpdatedAt(now);
doiEntity.setEntityId(dmp);
apiContext.getOperationsContext().getDatabaseRepository().getEntityDoiDao().createOrUpdate(doiEntity);
dmp.getDois().add(doiEntity);
apiContext.getOperationsContext().getDatabaseRepository().getDmpDao().createOrUpdate(dmp);
}
}
if (!update) {
if (unpublishedUrl == null) {
// Second step, add the file to the entry.
FileEnvelope file = getWordDocument(id.toString(), principal, configLoader);
String name = file.getFilename().substring(0, file.getFilename().length() - 5);
File pdfFile = PDFUtils.convertToPDF(file, environment);
String fileName = name + ".pdf";
FileSystemResource fileSystemResource = new FileSystemResource(pdfFile);
HttpEntity<FileSystemResource> addFileMapRequest = new HttpEntity<>(fileSystemResource, null);
String addFileUrl = links.get("bucket") + "/" + fileName + "?access_token=" + zenodoToken;
restTemplate.put(addFileUrl, addFileMapRequest);
Files.deleteIfExists(file.getFile().toPath());
ResponseEntity<byte[]> jsonFile;
try {
jsonFile = getRDAJsonDocument(id.toString(), principal);
} catch (Exception e) {
throw e;
}
UUID jsonFileUUID = UUID.randomUUID();
File tempJsonFile = new File(this.environment.getProperty("temp.temp") + jsonFileUUID.toString() + ".json");
try (FileOutputStream jsonFos = new FileOutputStream(tempJsonFile)) {
jsonFos.write(jsonFile.getBody());
jsonFos.flush();
}
fileSystemResource = new FileSystemResource(tempJsonFile);
HttpHeaders jsonHeaders = new HttpHeaders();
jsonHeaders.add(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_OCTET_STREAM_VALUE);
addFileMapRequest = new HttpEntity<>(fileSystemResource, jsonHeaders);
String jsonFileName = jsonFile.getHeaders().get("Content-Disposition").get(0).substring(jsonFile.getHeaders().get("Content-Disposition").get(0).lastIndexOf('=') + 1);
addFileUrl = links.get("bucket") + "/" + jsonFileName + "?access_token=" + zenodoToken;
restTemplate.put(addFileUrl, addFileMapRequest);
Files.deleteIfExists(tempJsonFile.toPath());
// Third post call to Zenodo to publish the entry and return the DOI.
publishUrl = links.get("publish") + "?access_token=" + zenodoToken;
} else {
publishUrl = unpublishedUrl + "?access_token=" + zenodoToken;
}
// if (dmp.isPublic()) {
Map<String, Object> publishResponce = restTemplate.postForObject(publishUrl, "", Map.class);
finalDoi = (String) publishResponce.get("conceptdoi");
// }
} else {
Map<String, Object> editResponce = restTemplate.postForObject(links.get("edit") + "?access_token=" + zenodoToken, "", Map.class);
restTemplate.put(links.get("self") + "?access_token=" + zenodoToken, request);
Map<String, Object> publishResponce = restTemplate.postForObject(links.get("publish") + "?access_token=" + zenodoToken, "", Map.class);
finalDoi = (String) publishResponce.get("conceptdoi");
}
if (finalDoi != null) {
dmp.setDoi(finalDoi);
apiContext.getOperationsContext().getDatabaseRepository().getDmpDao().createOrUpdate(dmp);
}
return finalDoi;
} catch (HttpClientErrorException | HttpServerErrorException ex) {
//ObjectMapper ob = new ObjectMapper();
Map<String, String> parsedException = objectMapper.readValue(ex.getResponseBodyAsString(), HashMap.class);
throw new IOException(parsedException.get("message"), ex);
}
if(supportingFilesZip != null) {
Files.deleteIfExists(supportingFilesZip.toPath());
}
Files.deleteIfExists(pdfFile.toPath());
Files.deleteIfExists(file.getFile().toPath());
return finalDoi;
}
public Doi createDoi(DepositRequest depositRequest, Principal principal) throws Exception {
DMP dmp = this.apiContext.getOperationsContext().getDatabaseRepository().getDmpDao().find(UUID.fromString(depositRequest.getDmpId()));
if (!isUserOwnerOfDmp(dmp, principal))
throw new Exception("User is not authorized to invoke this action");
if (!dmp.getStatus().equals(DMP.DMPStatus.FINALISED.getValue()))
throw new Exception("DMP is not finalized");
/*if (dmp.getDoi() != null)
throw new Exception("DMP already has a DOI");*/
FileEnvelope file = getWordDocument(depositRequest.getDmpId(), principal, configLoader);
String name = file.getFilename().substring(0, file.getFilename().length() - 5).replaceAll("[^a-zA-Z0-9_+ ]", "").replace(" ", "_").replace(",", "_");
File pdfFile = PDFUtils.convertToPDF(file, environment);
String fileName = name + ".pdf";
ResponseEntity<byte[]> jsonFile;
try {
jsonFile = getRDAJsonDocument(depositRequest.getDmpId(), principal);
} catch (Exception e) {
throw e;
}
String previousDOI = this.getPreviousDOI(dmp.getGroupId(), dmp.getId(), depositRequest.getRepositoryId());
File supportingFilesZip = this.createSupportingFilesZip(dmp);
DMPDepositModel dmpDepositModel = DMPToDepositMapper.fromDMP(dmp, pdfFile, fileName, jsonFile, supportingFilesZip, previousDOI);
Optional<RepositoryDeposit> repo = this.repositoriesDeposit.stream().filter(x -> x.getConfiguration().getRepositoryId().equals(depositRequest.getRepositoryId())).findFirst();
String finalDoi = repo.map(r -> {
try {
return r.deposit(dmpDepositModel, depositRequest.getAccessToken());
} catch (Exception e) {
logger.error(e.getMessage(), e);
return null;
}
}).orElse(null);
Doi doiModel = null;
if (finalDoi != null) {
EntityDoi doiEntity = new EntityDoi();
doiEntity.setId(UUID.randomUUID());
doiEntity.setEntityType(EntityDoi.EntityType.DMP);
doiEntity.setDoi(finalDoi);
doiEntity.setRepositoryId(depositRequest.getRepositoryId());
Date now = new Date();
doiEntity.setCreatedAt(now);
doiEntity.setUpdatedAt(now);
doiEntity.setEntityId(dmp);
apiContext.getOperationsContext().getDatabaseRepository().getEntityDoiDao().createOrUpdate(doiEntity);
dmp.getDois().add(doiEntity);
apiContext.getOperationsContext().getDatabaseRepository().getDmpDao().createOrUpdate(dmp);
doiModel = new Doi().fromDataModel(doiEntity);
}
if(supportingFilesZip != null) {
Files.deleteIfExists(supportingFilesZip.toPath());
}
Files.deleteIfExists(pdfFile.toPath());
Files.deleteIfExists(file.getFile().toPath());
return doiModel;
}
private File createSupportingFilesZip(DMP dmp) throws IOException {
FileOutputStream fout = new FileOutputStream(this.environment.getProperty("temp.temp") + "supportingFiles.zip");
ZipOutputStream zout = new ZipOutputStream(fout);
boolean hasFileUploaded = false;
Set<Dataset> datasets = dmp.getDataset();
for (Dataset dataset : datasets) {
List<FileUpload> files = this.apiContext.getOperationsContext().getDatabaseRepository().getFileUploadDao().getFileUploads(dataset.getId());
for (FileUpload f : files) {
if(!f.getIsDeleted()){
File exportFile = new File(this.environment.getProperty("file.storage") + f.getId());
String filename = f.getName().replace(" ", "_").replace(",", "_");
byte[] content = Files.readAllBytes(exportFile.toPath());
ZipEntry ze = new ZipEntry(filename);
zout.putNextEntry(ze);
zout.write(content, 0, content.length);
zout.closeEntry();
hasFileUploaded = true;
}
}
}
zout.close();
if(!hasFileUploaded){
Files.deleteIfExists(new File(this.environment.getProperty("temp.temp") + "supportingFiles.zip").toPath());
}
return hasFileUploaded ? new File(this.environment.getProperty("temp.temp") + "supportingFiles.zip") : null;
}
/*

View File

@ -0,0 +1,60 @@
package eu.eudat.logic.managers;
import eu.eudat.data.entities.DMP;
import eu.eudat.depositinterface.models.DMPDepositModel;
import eu.eudat.depositinterface.repository.RepositoryDeposit;
import eu.eudat.depositinterface.repository.RepositoryDepositConfiguration;
import eu.eudat.exceptions.security.NonValidTokenException;
import eu.eudat.logic.security.repositorydeposit.mapper.DMPToDepositMapper;
import eu.eudat.logic.utilities.documents.helpers.FileEnvelope;
import eu.eudat.logic.utilities.documents.pdf.PDFUtils;
import eu.eudat.models.data.doi.DepositRequest;
import eu.eudat.models.data.doi.Doi;
import eu.eudat.models.data.doi.RepositoryConfig;
import eu.eudat.models.data.security.Principal;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Component;
import java.io.File;
import java.nio.file.Files;
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
@Component
public class DepositManager {
private static final Logger logger = LoggerFactory.getLogger(DepositManager.class);
private List<RepositoryDeposit> repositories;
private DataManagementPlanManager dataManagementPlanManager;
@Autowired
public DepositManager(List<RepositoryDeposit> repositories, DataManagementPlanManager dataManagementPlanManager){
this.repositories = repositories;
this.dataManagementPlanManager = dataManagementPlanManager;
}
public List<RepositoryConfig> getAvailableRepos() {
List<RepositoryConfig> reposConfigModel = new ArrayList<>();
for (RepositoryDeposit r: this.repositories) {
RepositoryConfig repoModel = new RepositoryConfig();
RepositoryDepositConfiguration repoConf = r.getConfiguration();
if(repoConf != null) {
reposConfigModel.add(repoModel.toModel(repoConf));
}
}
return reposConfigModel;
}
public String authenticate(String id, String code) {
Optional<RepositoryDeposit> repo = repositories.stream().filter(x -> x.getConfiguration().getRepositoryId().equals(id)).findFirst();
return repo.map(repositoryDeposit -> repositoryDeposit.authenticate(code)).orElse(null);
}
public Doi deposit(DepositRequest depositRequest, Principal principal) throws Exception {
return this.dataManagementPlanManager.createDoi(depositRequest, principal);
}
}

View File

@ -1,27 +0,0 @@
package eu.eudat.logic.proxy.config;
import com.fasterxml.jackson.annotation.JsonProperty;
public class DOIFunder {
@JsonProperty("Funder")
private String funder;
@JsonProperty("DOI")
private String DOI;
public String getFunder() {
return funder;
}
public void setFunder(String funder) {
this.funder = funder;
}
public String getDOI() {
return DOI;
}
public void setDOI(String DOI) {
this.DOI = DOI;
}
}

View File

@ -1,6 +1,5 @@
package eu.eudat.logic.proxy.config.configloaders;
import eu.eudat.logic.proxy.config.DOIFunder;
import eu.eudat.logic.proxy.config.ExternalUrls;
import eu.eudat.logic.security.customproviders.ConfigurableProvider.entities.ConfigurableProviders;
import org.apache.poi.xwpf.usermodel.XWPFDocument;
@ -15,5 +14,4 @@ public interface ConfigLoader {
XWPFDocument getDatasetDocument();
ConfigurableProviders getConfigurableProviders();
Map<String, String> getKeyToSourceMap();
List<DOIFunder> getDOIFunders();
}

View File

@ -2,7 +2,6 @@ package eu.eudat.logic.proxy.config.configloaders;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.ObjectMapper;
import eu.eudat.logic.proxy.config.DOIFunder;
import eu.eudat.logic.proxy.config.ExternalUrls;
import eu.eudat.logic.security.customproviders.ConfigurableProvider.entities.ConfigurableProviders;
import org.apache.poi.xwpf.usermodel.XWPFDocument;
@ -41,7 +40,6 @@ public class DefaultConfigLoader implements ConfigLoader {
private XWPFDocument datasetDocument;
private ConfigurableProviders configurableProviders;
private Map<String, String> keyToSourceMap;
private List<DOIFunder> doiFunders = new ArrayList<>();
@Autowired
private Environment environment;
@ -207,18 +205,6 @@ public class DefaultConfigLoader implements ConfigLoader {
return keyToSourceMap;
}
@Override
public List<DOIFunder> getDOIFunders() {
if (doiFunders == null || doiFunders.isEmpty()) {
try {
List<Map<String, Object>> tempdoiFunders = mapper.readValue(getStreamFromPath(environment.getProperty("configuration.doi_funder")), List.class);
doiFunders = tempdoiFunders.stream().map(map -> mapper.convertValue(map, DOIFunder.class) ).collect(Collectors.toList());
} catch (IOException e) {
logger.error(e.getLocalizedMessage(), e);
}
}
return doiFunders;
}
private Document getXmlDocumentFromFilePath(String filePath) {
InputStream is = null;

View File

@ -0,0 +1,74 @@
package eu.eudat.logic.security.repositorydeposit.mapper;
import eu.eudat.data.entities.*;
import eu.eudat.depositinterface.models.*;
import org.springframework.http.ResponseEntity;
import java.io.File;
import java.util.stream.Collectors;
public class DMPToDepositMapper {
public static DMPDepositModel fromDMP(DMP entity, File pdfFile, String fileName, ResponseEntity<byte[]> jsonFile, File supportingFilesZip, String previousDOI) {
DMPDepositModel deposit = new DMPDepositModel();
deposit.setId(entity.getId());
deposit.setVersion(entity.getVersion());
deposit.setLabel(entity.getLabel());
deposit.setDescription(entity.getDescription());
deposit.setPublic(entity.isPublic());
deposit.setUsers(entity.getUsers().stream().map(DMPToDepositMapper::fromUserDMP).collect(Collectors.toSet()));
deposit.setOrganisations(entity.getOrganisations().stream().map(DMPToDepositMapper::fromOrganisation).collect(Collectors.toSet()));
deposit.setResearchers(entity.getResearchers().stream().map(DMPToDepositMapper::fromResearcher).collect(Collectors.toSet()));
deposit.setGrant(fromGrant(entity.getGrant()));
deposit.setPdfFile(pdfFile);
deposit.setPdfFileName(fileName);
deposit.setRdaJson(jsonFile);
deposit.setSupportingFilesZip(supportingFilesZip);
deposit.setPreviousDOI(previousDOI);
deposit.setExtraProperties(entity.getExtraProperties());
return deposit;
}
private static UserDMPDepositModel fromUserDMP(UserDMP entity){
UserDMPDepositModel deposit = new UserDMPDepositModel();
deposit.setUser(fromUserInfo(entity.getUser()));
deposit.setRole(entity.getRole());
return deposit;
}
private static UserInfoDepositModel fromUserInfo(UserInfo entity){
UserInfoDepositModel deposit = new UserInfoDepositModel();
deposit.setName(entity.getName());
deposit.setEmail(entity.getEmail());
return deposit;
}
private static OrganisationDepositModel fromOrganisation(Organisation entity){
OrganisationDepositModel deposit = new OrganisationDepositModel();
deposit.setLabel(entity.getLabel());
return deposit;
}
private static ResearcherDepositModel fromResearcher(Researcher entity){
ResearcherDepositModel deposit = new ResearcherDepositModel();
deposit.setLabel(entity.getLabel());
deposit.setReference(entity.getReference());
return deposit;
}
private static GrantDepositModel fromGrant(Grant entity){
GrantDepositModel deposit = new GrantDepositModel();
deposit.setId(entity.getId());
deposit.setReference(entity.getReference());
deposit.setFunder(fromFunder(entity.getFunder()));
return deposit;
}
private static FunderDepositModel fromFunder(Funder entity){
FunderDepositModel deposit = new FunderDepositModel();
deposit.setLabel(entity.getLabel());
return deposit;
}
}

View File

@ -60,5 +60,7 @@ public interface DatabaseRepository {
FileUploadDao getFileUploadDao();
EntityDoiDao getEntityDoiDao();
<T> void detachEntity(T entity);
}

View File

@ -39,6 +39,7 @@ public class DatabaseRepositoryImpl implements DatabaseRepository {
private LockDao lockDao;
private NotificationDao notificationDao;
private FileUploadDao fileUploadDao;
private EntityDoiDao entityDoiDao;
private EntityManager entityManager;
@ -317,6 +318,15 @@ public class DatabaseRepositoryImpl implements DatabaseRepository {
this.fileUploadDao = fileUploadDao;
}
@Override
public EntityDoiDao getEntityDoiDao() {
return entityDoiDao;
}
@Autowired
public void setEntityDoiDao(EntityDoiDao entityDoiDao) {
this.entityDoiDao = entityDoiDao;
}
public <T> void detachEntity(T entity) {
this.entityManager.detach(entity);

View File

@ -1036,9 +1036,8 @@ public class WordBuilder {
r.setText(text, 0);
}
if(text.contains("{ARGOS.DMP.DOI}")){
String doi = dmpEntity.getDoi();
if(doi != null)
text = text.replace("{ARGOS.DMP.DOI}", doi);
if(dmpEntity.getDois() != null && !dmpEntity.getDois().isEmpty())
text = text.replace("{ARGOS.DMP.DOI}", dmpEntity.getDois().iterator().next().getDoi());
else
text = text.replace("{ARGOS.DMP.DOI}", "-");
r.setText(text, 0);

View File

@ -4,6 +4,7 @@ import eu.eudat.data.entities.*;
import eu.eudat.logic.utilities.builders.XmlBuilder;
import eu.eudat.models.DataModel;
import eu.eudat.models.data.datasetwizard.DatasetWizardModel;
import eu.eudat.models.data.doi.Doi;
import eu.eudat.models.data.dynamicfields.DynamicFieldWithValue;
import eu.eudat.models.data.entities.xmlmodels.dmpprofiledefinition.DataManagementPlanProfile;
import eu.eudat.models.data.funder.Funder;
@ -40,7 +41,7 @@ public class DataManagementPlan implements DataModel<DMP, DataManagementPlan> {
private List<DynamicFieldWithValue> dynamicFields;
private Map<String, Object> properties;
private List<UserInfoListingModel> users;
private String doi;
private List<Doi> dois;
private Project project;
private Funder funder;
private Boolean isPublic;
@ -194,11 +195,11 @@ public class DataManagementPlan implements DataModel<DMP, DataManagementPlan> {
this.users = users;
}
public String getDoi() {
return doi;
public List<Doi> getDois() {
return dois;
}
public void setDoi(String doi) {
this.doi = doi;
public void setDois(List<Doi> dois) {
this.dois = dois;
}
public Project getProject() {
@ -280,7 +281,7 @@ public class DataManagementPlan implements DataModel<DMP, DataManagementPlan> {
this.status = entity.getStatus();
this.associatedUsers = entity.getUsers() != null ? entity.getUsers().stream().map(item -> new UserListingModel().fromDataModel(item.getUser())).collect(Collectors.toList()) : new ArrayList<>();
this.users = entity.getUsers() != null ? entity.getUsers().stream().map(item -> new UserInfoListingModel().fromDataModel(item)).collect(Collectors.toList()) : new ArrayList<>();
this.doi = entity.getDoi();
this.dois = entity.getDois() != null ? entity.getDois().stream().map(item -> new Doi().fromDataModel(item)).collect(Collectors.toList()): new ArrayList<>();
if (entity.getProject() != null) {
this.project = new Project();
@ -376,7 +377,7 @@ public class DataManagementPlan implements DataModel<DMP, DataManagementPlan> {
this.status = entity.getStatus();
this.associatedUsers = entity.getUsers() != null ? entity.getUsers().stream().map(item -> new UserListingModel().fromDataModel(item.getUser())).collect(Collectors.toList()) : new ArrayList<>();
this.users = entity.getUsers() != null ? entity.getUsers().stream().map(item -> new UserInfoListingModel().fromDataModel(item)).collect(Collectors.toList()) : new ArrayList<>();
this.doi = entity.getDoi();
this.dois = entity.getDois() != null ? entity.getDois().stream().map(item -> new Doi().fromDataModel(item)).collect(Collectors.toList()): new ArrayList<>();
this.grant.fromDataModel(entity.getGrant());
if (entity.getProject() != null) {

View File

@ -0,0 +1,21 @@
package eu.eudat.models.data.doi;
public class DepositCode {
private String repositoryId;
private String code;
public String getRepositoryId() {
return repositoryId;
}
public void setRepositoryId(String repositoryId) {
this.repositoryId = repositoryId;
}
public String getCode() {
return code;
}
public void setCode(String code) {
this.code = code;
}
}

View File

@ -0,0 +1,29 @@
package eu.eudat.models.data.doi;
public class DepositRequest {
private String repositoryId;
private String dmpId;
private String accessToken;
public String getRepositoryId() {
return repositoryId;
}
public void setRepositoryId(String repositoryId) {
this.repositoryId = repositoryId;
}
public String getDmpId() {
return dmpId;
}
public void setDmpId(String dmpId) {
this.dmpId = dmpId;
}
public String getAccessToken() {
return accessToken;
}
public void setAccessToken(String accessToken) {
this.accessToken = accessToken;
}
}

View File

@ -0,0 +1,85 @@
package eu.eudat.models.data.doi;
import eu.eudat.data.entities.EntityDoi;
import eu.eudat.models.DataModel;
import eu.eudat.models.data.dmp.DataManagementPlan;
import java.util.Date;
import java.util.UUID;
public class Doi implements DataModel<EntityDoi, Doi> {
private UUID id;
private String repositoryId;
private String doi;
private Date createdAt;
private Date updatedAt;
private DataManagementPlan dmp;
public UUID getId() {
return id;
}
public void setId(UUID id) {
this.id = id;
}
public String getRepositoryId() {
return repositoryId;
}
public void setRepositoryId(String repositoryId) {
this.repositoryId = repositoryId;
}
public String getDoi() {
return doi;
}
public void setDoi(String doi) {
this.doi = doi;
}
public Date getCreatedAt() {
return createdAt;
}
public void setCreatedAt(Date createdAt) {
this.createdAt = createdAt;
}
public Date getUpdatedAt() {
return updatedAt;
}
public void setUpdatedAt(Date updatedAt) {
this.updatedAt = updatedAt;
}
public DataManagementPlan getDmp() {
return dmp;
}
public void setDmp(DataManagementPlan dmp) {
this.dmp = dmp;
}
@Override
public Doi fromDataModel(EntityDoi entity) {
this.id = entity.getId();
this.repositoryId = entity.getRepositoryId();
this.doi = entity.getDoi();
this.createdAt = entity.getCreatedAt();
this.updatedAt = entity.getUpdatedAt();
return this;
}
@Override
public EntityDoi toDataModel() throws Exception {
EntityDoi entityDoi = new EntityDoi();
entityDoi.setId(this.id);
entityDoi.setRepositoryId(this.repositoryId);
entityDoi.setDoi(this.doi);
entityDoi.setCreatedAt(this.createdAt);
entityDoi.setUpdatedAt(this.updatedAt);
return entityDoi;
}
@Override
public String getHint() {
return null;
}
}

View File

@ -0,0 +1,65 @@
package eu.eudat.models.data.doi;
import eu.eudat.depositinterface.repository.RepositoryDepositConfiguration;
public class RepositoryConfig {
private int depositType;
private String repositoryId;
private String repositoryAuthorizationUrl;
private String repositoryRecordUrl;
private String repositoryClientId;
private String redirectUri;
public int getDepositType() {
return depositType;
}
public void setDepositType(int depositType) {
this.depositType = depositType;
}
public String getRepositoryId() {
return repositoryId;
}
public void setRepositoryId(String repositoryId) {
this.repositoryId = repositoryId;
}
public String getRepositoryAuthorizationUrl() {
return repositoryAuthorizationUrl;
}
public void setRepositoryAuthorizationUrl(String repositoryAuthorizationUrl) {
this.repositoryAuthorizationUrl = repositoryAuthorizationUrl;
}
public String getRepositoryRecordUrl() {
return repositoryRecordUrl;
}
public void setRepositoryRecordUrl(String repositoryRecordUrl) {
this.repositoryRecordUrl = repositoryRecordUrl;
}
public String getRepositoryClientId() {
return repositoryClientId;
}
public void setRepositoryClientId(String repositoryClientId) {
this.repositoryClientId = repositoryClientId;
}
public String getRedirectUri() {
return redirectUri;
}
public void setRedirectUri(String redirectUri) {
this.redirectUri = redirectUri;
}
public RepositoryConfig toModel(RepositoryDepositConfiguration r){
this.setDepositType(r.getDepositType());
this.setRepositoryId(r.getRepositoryId());
this.setRepositoryAuthorizationUrl(r.getRepositoryAuthorizationUrl());
this.setRepositoryRecordUrl(r.getRepositoryRecordUrl());
this.setRepositoryClientId(r.getRepositoryClientId());
this.setRedirectUri(r.getRedirectUri());
return this;
}
}

View File

@ -8,6 +8,7 @@ import eu.eudat.models.data.dataset.DatasetOverviewModel;
import eu.eudat.models.data.dmp.AssociatedProfile;
import eu.eudat.models.data.dmp.Organisation;
import eu.eudat.models.data.dmp.Researcher;
import eu.eudat.models.data.doi.Doi;
import eu.eudat.models.data.grant.GrantOverviewModel;
import java.util.Date;
@ -35,7 +36,7 @@ public class DataManagementPlanOverviewModel implements DataModel<DMP, DataManag
private String description;
private boolean isPublic;
private Date publishedAt;
private String doi;
private List<Doi> dois;
public String getId() {
@ -164,11 +165,11 @@ public class DataManagementPlanOverviewModel implements DataModel<DMP, DataManag
this.publishedAt = publishedAt;
}
public String getDoi() {
return doi;
public List<Doi> getDois() {
return dois;
}
public void setDoi(String doi) {
this.doi = doi;
public void setDois(List<Doi> dois) {
this.dois = dois;
}
@Override
@ -180,6 +181,9 @@ public class DataManagementPlanOverviewModel implements DataModel<DMP, DataManag
if (entity.getResearchers() != null) {
this.researchers = entity.getResearchers().stream().map(item -> new Researcher().fromDataModel(item)).collect(Collectors.toList());
}
if(entity.getDois() != null){
this.dois = entity.getDois().stream().map(item -> new Doi().fromDataModel(item)).collect(Collectors.toList());
}
return this;
}
@ -208,7 +212,7 @@ public class DataManagementPlanOverviewModel implements DataModel<DMP, DataManag
}
this.isPublic = entity.isPublic();
this.publishedAt = entity.getPublishedAt();
this.doi = entity.getDoi();
this.dois = entity.getDois().stream().map(item -> new Doi().fromDataModel(item)).collect(Collectors.toList());
return this;
}

View File

@ -1,9 +1,6 @@
package eu.eudat.models.data.rda;
import eu.eudat.data.entities.DMP;
import eu.eudat.data.entities.Dataset;
import eu.eudat.data.entities.UserDMP;
import eu.eudat.data.entities.UserInfo;
import eu.eudat.data.entities.*;
import eu.eudat.logic.managers.DatasetManager;
import eu.eudat.models.data.security.Principal;
@ -146,8 +143,17 @@ public class DmpRDAExportModel {
dmpRda.dataset.add(new DatasetRDAExportModel().fromDataModel(dataset, datasetManager, principal));
}
dmpRda.description = entity.getDescription().replace("\n", " ");
if (entity.getDoi() != null) {
dmpRda.dmp_id = new IdRDAExportModel(entity.getDoi(), "zenodo");
if (entity.getDois() != null && !entity.getDois().isEmpty()) {
boolean zenodoDoi = false;
for(EntityDoi doi: entity.getDois()){
if(doi.getRepositoryId().equals("Zenodo")){
dmpRda.dmp_id = new IdRDAExportModel(doi.getDoi(), "zenodo");
zenodoDoi = true;
}
}
if(!zenodoDoi){
dmpRda.dmp_id = new IdRDAExportModel(entity.getId().toString(), "other");
}
}
else {
dmpRda.dmp_id = new IdRDAExportModel(entity.getId().toString(), "other");

View File

@ -1,18 +0,0 @@
package eu.eudat.models.deposit.zenodo;
import com.fasterxml.jackson.annotation.JsonValue;
public enum ZenodoAccessRight {
RESTRICTED("restricted"), EMBARGOED("embargoed"), OPEN("open");
private final String value;
ZenodoAccessRight(String value) {
this.value = value;
}
@JsonValue
public String getValue() {
return value;
}
}

View File

@ -1,19 +0,0 @@
package eu.eudat.models.deposit.zenodo;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.fasterxml.jackson.annotation.JsonInclude;
@JsonIgnoreProperties(ignoreUnknown = true)
@JsonInclude(JsonInclude.Include.NON_NULL)
public class ZenodoComunity {
private String identifier;
public String getIdentifier() {
return identifier;
}
public void setIdentifier(String identifier) {
this.identifier = identifier;
}
}

View File

@ -1,45 +0,0 @@
package eu.eudat.models.deposit.zenodo;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.fasterxml.jackson.annotation.JsonInclude;
@JsonIgnoreProperties(ignoreUnknown = true)
@JsonInclude(JsonInclude.Include.NON_NULL)
public class ZenodoContributor {
private String name;
private String type;
private String affiliation;
private String orcid;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
public String getAffiliation() {
return affiliation;
}
public void setAffiliation(String affiliation) {
this.affiliation = affiliation;
}
public String getOrcid() {
return orcid;
}
public void setOrcid(String orcid) {
this.orcid = orcid;
}
}

View File

@ -1,19 +0,0 @@
package eu.eudat.models.deposit.zenodo;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.fasterxml.jackson.annotation.JsonInclude;
@JsonIgnoreProperties(ignoreUnknown = true)
@JsonInclude(JsonInclude.Include.NON_NULL)
public class ZenodoDeposit {
private ZenodoDepositMetadata metadata;
public ZenodoDepositMetadata getMetadata() {
return metadata;
}
public void setMetadata(ZenodoDepositMetadata metadata) {
this.metadata = metadata;
}
}

View File

@ -1,159 +0,0 @@
package eu.eudat.models.deposit.zenodo;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.JsonProperty;
import java.time.Instant;
import java.util.List;
@JsonIgnoreProperties(ignoreUnknown = true)
@JsonInclude(JsonInclude.Include.NON_NULL)
public class ZenodoDepositMetadata {
private String title;
@JsonProperty("upload_type")
private String uploadType;
@JsonProperty("publication_type")
private String publicationType;
private String description;
private String version;
private List<ZenodoComunity> communities;
@JsonProperty("access_right")
private ZenodoAccessRight accessRight;
@JsonProperty("access_conditions")
private String accessConditions;
@JsonProperty("embargo_date")
private String embargoDate;
private String license;
@JsonProperty("related_identifiers")
private List<ZenodoRelator> relatedIdentifiers;
private List<ZenodoContributor> contributors;
private List<ZenodoGrant> grants;
private List<ZenodoContributor> creators;
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public String getUploadType() {
return uploadType;
}
public void setUploadType(String uploadType) {
this.uploadType = uploadType;
}
public String getPublicationType() {
return publicationType;
}
public void setPublicationType(String publicationType) {
this.publicationType = publicationType;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
public String getVersion() {
return version;
}
public void setVersion(String version) {
this.version = version;
}
public List<ZenodoComunity> getCommunities() {
return communities;
}
public void setCommunities(List<ZenodoComunity> communities) {
this.communities = communities;
}
public ZenodoAccessRight getAccessRight() {
return accessRight;
}
public void setAccessRight(ZenodoAccessRight accessRight) {
this.accessRight = accessRight;
}
public String getAccessConditions() {
return accessConditions;
}
public void setAccessConditions(String accessConditions) {
this.accessConditions = accessConditions;
}
public String getEmbargoDate() {
return embargoDate;
}
public void setEmbargoDate(String embargoDate) {
this.embargoDate = embargoDate;
}
public String getLicense() {
return license;
}
public void setLicense(String license) {
this.license = license;
}
public List<ZenodoRelator> getRelatedIdentifiers() {
return relatedIdentifiers;
}
public void setRelatedIdentifiers(List<ZenodoRelator> relatedIdentifiers) {
this.relatedIdentifiers = relatedIdentifiers;
}
public List<ZenodoContributor> getContributors() {
return contributors;
}
public void setContributors(List<ZenodoContributor> contributors) {
this.contributors = contributors;
}
public List<ZenodoGrant> getGrants() {
return grants;
}
public void setGrants(List<ZenodoGrant> grants) {
this.grants = grants;
}
public List<ZenodoContributor> getCreators() {
return creators;
}
public void setCreators(List<ZenodoContributor> creators) {
this.creators = creators;
}
}

View File

@ -1,18 +0,0 @@
package eu.eudat.models.deposit.zenodo;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.fasterxml.jackson.annotation.JsonInclude;
@JsonIgnoreProperties(ignoreUnknown = true)
@JsonInclude(JsonInclude.Include.NON_NULL)
public class ZenodoGrant {
private String id;
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
}

View File

@ -1,28 +0,0 @@
package eu.eudat.models.deposit.zenodo;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.fasterxml.jackson.annotation.JsonInclude;
@JsonIgnoreProperties(ignoreUnknown = true)
@JsonInclude(JsonInclude.Include.NON_NULL)
public class ZenodoRelator {
private String identifier;
private String relation;
public String getIdentifier() {
return identifier;
}
public void setIdentifier(String identifier) {
this.identifier = identifier;
}
public String getRelation() {
return relation;
}
public void setRelation(String relation) {
this.relation = relation;
}
}

View File

@ -1,115 +0,0 @@
package eu.eudat.models.deposit.zenodo.mapper;
import eu.eudat.data.entities.DMP;
import eu.eudat.data.entities.Organisation;
import eu.eudat.data.entities.UserDMP;
import eu.eudat.logic.proxy.config.DOIFunder;
import eu.eudat.logic.proxy.config.configloaders.ConfigLoader;
import eu.eudat.models.deposit.zenodo.*;
import org.springframework.core.env.Environment;
import java.time.Instant;
import java.util.*;
import java.util.stream.Collectors;
public class DMPToZenodoMapper {
public static ZenodoDeposit fromDMP(DMP dmp, Environment environment, ConfigLoader configLoader) {
Map<String, Object> extraProperties = dmp.getExtraProperties() != null ? new org.json.JSONObject(dmp.getExtraProperties()).toMap() : new HashMap<>();
ZenodoDeposit deposit = new ZenodoDeposit();
deposit.setMetadata(new ZenodoDepositMetadata());
deposit.getMetadata().setTitle(dmp.getLabel());
deposit.getMetadata().setUploadType("publication");
deposit.getMetadata().setPublicationType("datamanagementplan");
deposit.getMetadata().setDescription((dmp.getDescription() != null && !dmp.getDescription().isEmpty() ? dmp.getDescription() : "<p></p>"));
deposit.getMetadata().setVersion(dmp.getVersion().toString());
ZenodoComunity community = new ZenodoComunity();
community.setIdentifier(environment.getProperty("zenodo.community"));
deposit.getMetadata().setCommunities(Collections.singletonList(community));
if (extraProperties.get("visible") == null) {
deposit.getMetadata().setAccessRight(ZenodoAccessRight.RESTRICTED);
deposit.getMetadata().setAccessConditions("");
} else {
if (((Boolean) extraProperties.get("visible"))) {
Instant publicationDate = Instant.parse(extraProperties.get("publicDate").toString());
if (publicationDate.isBefore(Instant.now())) {
deposit.getMetadata().setAccessRight(ZenodoAccessRight.OPEN);
} else {
deposit.getMetadata().setAccessRight(ZenodoAccessRight.EMBARGOED);
deposit.getMetadata().setEmbargoDate(publicationDate.toString());
}
if (extraProperties.get("license") != null) {
deposit.getMetadata().setLicense(((Map<?, ?>) extraProperties.get("license")).get("pid").toString());
}
} else {
deposit.getMetadata().setAccessRight(ZenodoAccessRight.RESTRICTED);
deposit.getMetadata().setAccessConditions("");
}
}
if (dmp.isPublic()) {
ZenodoRelator relator = new ZenodoRelator();
relator.setIdentifier((environment.getProperty("dmp.domain") + "/external/zenodo/" + dmp.getId().toString()));
relator.setRelation("isIdenticalTo");
deposit.getMetadata().setRelatedIdentifiers(Collections.singletonList(relator));
}
deposit.getMetadata().setContributors(new LinkedList<>());
List<ZenodoContributor> contributors = dmp.getUsers().stream().map(userDMP -> {
ZenodoContributor contributor = new ZenodoContributor();
contributor.setName(userDMP.getUser().getName());
contributor.setType("ProjectMember");
if (dmp.getOrganisations() != null && !dmp.getOrganisations().isEmpty()) {
contributor.setAffiliation(dmp.getOrganisations()
.stream().map(Organisation::getLabel).collect(Collectors.joining(", ")));
} else {
contributor.setAffiliation(environment.getProperty("zenodo.affiliation"));
}
return contributor;
}).collect(Collectors.toList());
List<ZenodoContributor> researchers = dmp.getResearchers().stream().map(researcher -> {
ZenodoContributor contributor = new ZenodoContributor();
contributor.setName(researcher.getLabel());
contributor.setType("Researcher");
String referenceHead = researcher.getReference().split(":")[0];
String referenceTail = researcher.getReference().replace(referenceHead + ":", "");
contributor.setAffiliation(referenceHead);
if (referenceHead.equalsIgnoreCase("ORCID")) {
contributor.setOrcid(referenceTail);
}
return contributor;
}).collect(Collectors.toList());
deposit.getMetadata().getContributors().addAll(contributors);
deposit.getMetadata().getContributors().addAll(researchers);
if (dmp.getGrant().getReference() == null) {
dmp.getGrant().setReference("dmp:" + dmp.getGrant().getId());
}
String grantReferenceHead = dmp.getGrant().getReference().split(":")[0];
if (grantReferenceHead.equals("openaire")) {
String grantReferenceTail = dmp.getGrant().getReference().split(":")[3];
DOIFunder doiFunder = configLoader.getDOIFunders().stream()
.filter(doiFunder1 -> dmp.getGrant().getFunder().getLabel().contains(doiFunder1.getFunder()) || doiFunder1.getFunder().contains(dmp.getGrant().getFunder().getLabel()))
.findFirst().orElse(null);
if (doiFunder != null) {
String finalId = doiFunder.getDOI() + "::" + grantReferenceTail;
ZenodoGrant grant = new ZenodoGrant();
grant.setId(finalId);
deposit.getMetadata().setGrants(Collections.singletonList(grant));
}
}
ZenodoContributor creator = new ZenodoContributor();
creator.setName(dmp.getUsers().stream().filter(userDMP -> userDMP.getRole().equals(UserDMP.UserDMPRoles.OWNER.getValue())).findFirst().get().getUser().getName());
if (dmp.getOrganisations() != null && !dmp.getOrganisations().isEmpty()) {
creator.setAffiliation(dmp.getOrganisations()
.stream().map(Organisation::getLabel).collect(Collectors.joining(", ")));
} else {
creator.setAffiliation(environment.getProperty("zenodo.affiliation"));
}
deposit.getMetadata().setCreators(Collections.singletonList(creator));
return deposit;
}
}

View File

@ -47,8 +47,12 @@ public class DmpRDAMapper {
}
}
Dmp rda = new Dmp();
if (dmp.getDoi() != null && !dmp.getDoi().isEmpty()) {
rda.setDmpId(DmpIdRDAMapper.toRDA(dmp.getDoi()));
if (dmp.getDois() != null && !dmp.getDois().isEmpty()) {
for(EntityDoi doi: dmp.getDois()){
if(doi.getRepositoryId().equals("Zenodo")){
rda.setDmpId(DmpIdRDAMapper.toRDA(doi.getDoi()));
}
}
} else {
rda.setDmpId(DmpIdRDAMapper.toRDA(dmp.getId()));
}
@ -105,7 +109,10 @@ public class DmpRDAMapper {
DMP entity = new DMP();
entity.setLabel(rda.getTitle());
if (rda.getDmpId().getType() == DmpId.Type.DOI) {
entity.setDoi(rda.getDmpId().getIdentifier());
EntityDoi doi = apiContext.getOperationsContext().getDatabaseRepository().getEntityDoiDao().findFromDoi(rda.getDmpId().getIdentifier());
Set<EntityDoi> dois = new HashSet<>();
dois.add(doi);
entity.setDois(dois);
}
if (((List<String>) rda.getAdditionalProperties().get("templates")) != null && !((List<String>) rda.getAdditionalProperties().get("templates")).isEmpty()) {
entity.setAssociatedDmps(((List<String>) rda.getAdditionalProperties().get("templates")).stream().map(this::getProfile).filter(Objects::nonNull).collect(Collectors.toSet()));

View File

@ -0,0 +1,61 @@
package eu.eudat.publicapi.models.doi;
import eu.eudat.data.entities.EntityDoi;
import eu.eudat.logic.utilities.helpers.LabelGenerator;
import eu.eudat.models.DataModel;
import java.util.UUID;
public class DoiPublicModel implements DataModel<EntityDoi, DoiPublicModel>, LabelGenerator {
private UUID id;
private String repositoryId;
private String doi;
public UUID getId() {
return id;
}
public void setId(UUID id) {
this.id = id;
}
public String getRepositoryId() {
return repositoryId;
}
public void setRepositoryId(String repositoryId) {
this.repositoryId = repositoryId;
}
public String getDoi() {
return doi;
}
public void setDoi(String doi) {
this.doi = doi;
}
@Override
public DoiPublicModel fromDataModel(EntityDoi entity) {
this.id = entity.getId();
this.repositoryId = entity.getRepositoryId();
this.doi = entity.getDoi();
return this;
}
@Override
public EntityDoi toDataModel() throws Exception {
EntityDoi entity = new EntityDoi();
entity.setId(this.getId());
entity.setRepositoryId(this.getRepositoryId());
entity.setDoi(this.getDoi());
return entity;
}
@Override
public String generateLabel() {
return this.getDoi();
}
@Override
public String getHint() {
return null;
}
}

View File

@ -7,6 +7,7 @@ import eu.eudat.logic.utilities.builders.XmlBuilder;
import eu.eudat.models.DataModel;
import eu.eudat.models.data.user.composite.PagedDatasetProfile;
import eu.eudat.publicapi.models.associatedprofile.AssociatedProfilePublicModel;
import eu.eudat.publicapi.models.doi.DoiPublicModel;
import eu.eudat.publicapi.models.grant.GrantPublicOverviewModel;
import eu.eudat.publicapi.models.organisation.OrganizationPublicModel;
import eu.eudat.publicapi.models.researcher.ResearcherPublicModel;
@ -35,7 +36,7 @@ public class DataManagementPlanPublicModel implements DataModel<DMP, DataManagem
private List<UserInfoPublicModel> users;
private String description;
private Date publishedAt;
private String doi;
private List<DoiPublicModel> dois;
public String getId() {
@ -150,11 +151,11 @@ public class DataManagementPlanPublicModel implements DataModel<DMP, DataManagem
this.publishedAt = publishedAt;
}
public String getDoi() {
return doi;
public List<DoiPublicModel> getDois() {
return dois;
}
public void setDoi(String doi) {
this.doi = doi;
public void setDois(List<DoiPublicModel> dois) {
this.dois = dois;
}
@Override
@ -198,7 +199,7 @@ public class DataManagementPlanPublicModel implements DataModel<DMP, DataManagem
}
}
this.publishedAt = entity.getPublishedAt();
this.doi = entity.getDoi();
this.dois = entity.getDois().stream().map(item -> new DoiPublicModel().fromDataModel(item)).collect(Collectors.toList());
return this;
}

View File

@ -926,6 +926,27 @@ CREATE TABLE public."FileUpload"
ALTER TABLE public."FileUpload" OWNER TO :POSTGRES_USER;
--
-- Name: EntityDoi; Type: TABLE; Schema: public; Owner: :POSTGRES_USER
--
CREATE TYPE DoiEntityType AS ENUM ('DMP');
CREATE TABLE public."EntityDoi"
(
"ID" uuid NOT NULL,
"EntityType" DoiEntityType NOT NULL,
"RepositoryId" character varying(150) NOT NULL,
"Doi" character varying(50) NOt NULL,
"CreatedAt" timestamp(6) with time zone DEFAULT now() NOT NULL,
"UpdatedAt" timestamp(6) with time zone DEFAULT now() NOT NULL,
"EntityId" uuid NOT NULL,
CONSTRAINT "Doi_pkey" PRIMARY KEY ("ID"),
CONSTRAINT fk_doi_entityId FOREIGN KEY ("EntityId") REFERENCES public."DMP"("ID")
);
ALTER TABLE public."EntityDoi" OWNER TO :POSTGRES_USER;
--
-- Name: Content Content_pkey; Type: CONSTRAINT; Schema: public; Owner: :POSTGRES_USER
--

View File

@ -0,0 +1,26 @@
DO $$DECLARE
this_version CONSTANT varchar := '00.00.010';
BEGIN
PERFORM * FROM "DBVersion" WHERE version = this_version;
IF FOUND THEN RETURN; END IF;
CREATE TYPE DoiEntityType AS ENUM ('DMP');
CREATE TABLE public."EntityDoi"
(
"ID" uuid NOT NULL,
"EntityType" DoiEntityType NOT NULL,
"RepositoryId" character varying(150) NOT NULL,
"Doi" character varying(50) NOt NULL,
"CreatedAt" timestamp(6) with time zone DEFAULT now() NOT NULL,
"UpdatedAt" timestamp(6) with time zone DEFAULT now() NOT NULL,
"EntityId" uuid NOT NULL,
CONSTRAINT "Doi_pkey" PRIMARY KEY ("ID"),
CONSTRAINT fk_doi_entityId FOREIGN KEY ("EntityId") REFERENCES public."DMP"("ID")
);
/*ALTER TABLE public."EntityDoi" OWNER TO :POSTGRES_USER;*/
INSERT INTO public."DBVersion" VALUES ('DMPDB', '00.00.010', '2022-10-27 10:50:00.000000+02', now(), 'Add Doi Table for depositions');
END$$;

View File

@ -0,0 +1,14 @@
DO $$DECLARE
this_version CONSTANT varchar := '00.00.011';
BEGIN
PERFORM * FROM "DBVersion" WHERE version = this_version;
IF FOUND THEN RETURN; END IF;
INSERT INTO public."EntityDoi" ("ID", "EntityType", "RepositoryId", "Doi", "CreatedAt", "UpdatedAt", "EntityId")
SELECT uuid_generate_v4(), 'DMP', 'Zenodo', public."DMP"."DOI", now(), now(), public."DMP"."ID"
FROM public."DMP"
WHERE public."DMP"."DOI" IS NOT NULL;
INSERT INTO public."DBVersion" VALUES ('DMPDB', '00.00.011', '2022-10-27 10:50:00.000000+02', now(), 'Migrate DMP.DOI to EntityDoi table');
END$$;

View File

@ -0,0 +1,11 @@
DO $$DECLARE
this_version CONSTANT varchar := '00.00.012';
BEGIN
PERFORM * FROM "DBVersion" WHERE version = this_version;
IF FOUND THEN RETURN; END IF;
ALTER TABLE public."DMP" DROP COLUMN "DOI";
INSERT INTO public."DBVersion" VALUES ('DMPDB', '00.00.012', '2022-10-27 10:50:00.000000+02', now(), 'Delete doi column from dmp table');
END$$;

View File

@ -0,0 +1,5 @@
export enum DepositConfigurationStatus {
System = 0,
User = 1,
BothSystemAndUser = 2
}

View File

@ -46,6 +46,7 @@ import { CollectionUtils } from './services/utilities/collection-utils.service';
import { TypeUtils } from './services/utilities/type-utils.service';
import { SpecialAuthGuard } from './special-auth-guard.service';
import {PrefillingService} from "@app/core/services/prefilling.service";
import { DepositRepositoriesService } from './services/deposit-repositories/deposit-repositories.service';
//
//
// This is shared module that provides all the services. Its imported only once on the AppModule.
@ -89,6 +90,7 @@ export class CoreServiceModule {
FunderService,
GrantFileUploadService,
DmpService,
DepositRepositoriesService,
DmpProfileService,
ExternalSourcesService,
ExternalSourcesConfigurationService,

View File

@ -0,0 +1,10 @@
import { DepositConfigurationStatus } from "@app/core/common/enum/deposit-configuration-status";
export class DepositConfigurationModel {
depositType: DepositConfigurationStatus;
repositoryId: string;
repositoryAuthorizationUrl: string;
repositoryRecordUrl: string;
repositoryClientId: string;
redirectUri: string;
}

View File

@ -0,0 +1,10 @@
export class DepositRequest {
repositoryId: string;
dmpId: string;
accessToken: string;
}
export class DepositCode {
repositoryId: string;
code: string;
}

View File

@ -4,6 +4,7 @@ import { DmpAssociatedProfileModel } from "../dmp-profile/dmp-associated-profile
import { ResearcherModel } from "../researcher/researcher";
import { GrantOverviewModel } from "../grant/grant-overview";
import { DatasetOverviewModel } from "../dataset/dataset-overview";
import { DoiModel } from "../doi/doi";
export interface DmpOverviewModel {
id: string;
@ -26,4 +27,5 @@ export interface DmpOverviewModel {
finalizedAt: Date;
publishedAt: Date;
doi: string;
dois: DoiModel[];
}

View File

@ -0,0 +1,7 @@
export interface DoiModel {
id: string;
repositoryId: string;
doi: string;
createdAt: Date;
updatedAt: Date;
}

View File

@ -66,11 +66,6 @@ export class ConfigurationService extends BaseComponent {
return this._allowOrganizationCreator;
}
private _doiLink: string;
get doiLink(): string {
return this._doiLink;
}
private _useSplash: string;
get useSplash(): string {
return this._useSplash;
@ -137,7 +132,6 @@ export class ConfigurationService extends BaseComponent {
this._lockInterval = config.lockInterval;
this._guideAssets = config.guideAssets;
this._allowOrganizationCreator = config.allowOrganizationCreator;
this._doiLink = config.doiLink;
this._useSplash = config.useSplash;
this._orcidPath = config.orcidPath;
if (config.matomo) {

View File

@ -0,0 +1,38 @@
import { HttpClient, HttpHeaders } from '@angular/common/http';
import { Injectable } from '@angular/core';
import { DepositConfigurationModel } from '@app/core/model/deposit/deposit-configuration';
import { DepositCode, DepositRequest } from '@app/core/model/deposit/deposit-request';
import { DoiModel } from '@app/core/model/doi/doi';
import { Observable } from 'rxjs';
import { ConfigurationService } from '../configuration/configuration.service';
import { BaseHttpService } from '../http/base-http.service';
@Injectable()
export class DepositRepositoriesService {
private actionUrl: string;
private headers = new HttpHeaders();
constructor(private http: BaseHttpService, private httpClient: HttpClient, private configurationService: ConfigurationService) {
this.actionUrl = configurationService.server + 'deposit/';
}
getAvailableRepos(): Observable<DepositConfigurationModel[]> {
return this.http.get<DepositConfigurationModel[]>(this.actionUrl + 'repos', { headers: this.headers });
}
getAccessToken(repositoryId: string, code: string): Observable<string> {
const depositCode = new DepositCode();
depositCode.repositoryId = repositoryId;
depositCode.code = code;
return this.http.post<string>(this.actionUrl + 'getAccessToken', depositCode, { headers: this.headers });
}
createDoi(repositoryId: string, dmpId: string, accessToken: string | null): Observable<DoiModel> {
const depositRequest = new DepositRequest();
depositRequest.repositoryId = repositoryId;
depositRequest.dmpId = dmpId;
depositRequest.accessToken = accessToken;
return this.http.post<DoiModel>(this.actionUrl + 'createDoi', depositRequest, { headers: this.headers });
}
}

View File

@ -50,6 +50,7 @@ import { FormProgressIndicationComponent } from '../misc/dataset-description-for
import { FormProgressIndicationModule } from '../misc/dataset-description-form/components/form-progress-indication/form-progress-indication.module';
import { DatasetPreviewDialogComponent } from './dataset-preview/dataset-preview-dialog.component';
import {RichTextEditorModule} from "@app/library/rich-text-editor/rich-text-editor.module";
import { DmpDepositDialogComponent } from './editor/dmp-deposit-dialog/dmp-deposit-dialog.component';
@NgModule({
imports: [
@ -103,7 +104,8 @@ import {RichTextEditorModule} from "@app/library/rich-text-editor/rich-text-edit
FundingInfoComponent,
DatasetInfoComponent,
LicenseInfoComponent,
DatasetPreviewDialogComponent
DatasetPreviewDialogComponent,
DmpDepositDialogComponent
],
entryComponents: [
DmpInvitationDialogComponent,
@ -119,7 +121,8 @@ import {RichTextEditorModule} from "@app/library/rich-text-editor/rich-text-edit
StartNewDmpDialogComponent,
StartNewDatasetDialogComponent,
DatasetEditorDetailsComponent,
DatasetPreviewDialogComponent
DatasetPreviewDialogComponent,
DmpDepositDialogComponent
]
})
export class DmpModule { }

View File

@ -0,0 +1,21 @@
<div class="row d-flex flex-row">
<div mat-dialog-title class="col-auto">{{ data.message }}</div>
<div class="col-auto close-btn ml-auto" (click)="close()">
<mat-icon>close</mat-icon>
</div>
</div>
<div *ngIf="inputRepos.length > 0">
<mat-action-list>
<button mat-list-item *ngFor="let repo of inputRepos" (click)="deposit(repo)"> {{ repo.repositoryId }} </button>
</mat-action-list>
</div>
<div *ngIf="inputRepos.length === 0" class="emptyList">{{'DMP-OVERVIEW.DEPOSIT.NO-REPOSITORIES' | translate}}</div>
<div mat-dialog-actions class="d-flex justify-content-end mb-1">
<div class="col-auto">
<button mat-raised-button cdkFocusInitial (click)="close()" class="cancel-btn">{{ data.cancelButton }}</button>
</div>
<!-- <div class="col-auto">
<button mat-raised-button class="submit-btn" (click)="onSubmit()">{{ data.confirmButton }}</button>
</div> -->
</div>

View File

@ -0,0 +1,138 @@
import { Component, Inject, OnInit } from '@angular/core';
import { MatDialog, MatDialogRef, MAT_DIALOG_DATA } from '@angular/material/dialog';
import { DepositConfigurationStatus } from '@app/core/common/enum/deposit-configuration-status';
import { DepositConfigurationModel } from '@app/core/model/deposit/deposit-configuration';
import { DmpOverviewModel } from '@app/core/model/dmp/dmp-overview';
import { DoiModel } from '@app/core/model/doi/doi';
import { DepositRepositoriesService } from '@app/core/services/deposit-repositories/deposit-repositories.service';
import { SnackBarNotificationLevel, UiNotificationService } from '@app/core/services/notification/ui-notification-service';
import { Oauth2DialogService } from '@app/ui/misc/oauth2-dialog/service/oauth2-dialog.service';
import { BaseComponent } from '@common/base/base.component';
import { MultipleChoiceDialogComponent } from '@common/modules/multiple-choice-dialog/multiple-choice-dialog.component';
import { TranslateService } from '@ngx-translate/core';
import { takeUntil } from 'rxjs/operators';
@Component({
selector: 'app-dmp-deposit-dialog',
templateUrl: './dmp-deposit-dialog.component.html',
styleUrls: ['./dmp-deposit-dialog.component.scss']
})
export class DmpDepositDialogComponent extends BaseComponent implements OnInit {
inputRepos: DepositConfigurationModel[];
outputRepos: DoiModel[];
dmp: DmpOverviewModel;
private oauthLock: boolean;
constructor(
private depositRepositoriesService: DepositRepositoriesService,
public dialogRef: MatDialogRef<DmpDepositDialogComponent>,
private dialog: MatDialog,
private language: TranslateService,
private translate: TranslateService,
private uiNotificationService: UiNotificationService,
private oauth2DialogService: Oauth2DialogService,
@Inject(MAT_DIALOG_DATA) public data: any
) {
super();
this.inputRepos = data['depositRepos'][0];
this.dmp = data['depositRepos'][1];
for(var i = 0; i < this.dmp.dois.length; i++){
this.inputRepos = this.inputRepos.filter(r => this.hasDoi(r, this.dmp.dois, i));
}
this.outputRepos = [];
}
hasDoi(repo, dois, i){
return repo.repositoryId !== dois[i].repositoryId;
}
ngOnInit(): void {
}
onSubmit() {
this.dialogRef.close(this.outputRepos);
}
close() {
this.dialogRef.close(this.outputRepos);
}
deposit(repo: DepositConfigurationModel) {
if(repo.depositType == DepositConfigurationStatus.BothSystemAndUser){
const dialogRef = this.dialog.open(MultipleChoiceDialogComponent, {
maxWidth: '600px',
restoreFocus: false,
data: {
message: this.language.instant('DMP-OVERVIEW.DEPOSIT.ACCOUNT-LOGIN'),
titles: [this.language.instant('DMP-OVERVIEW.DEPOSIT.LOGIN', { 'repository': repo.repositoryId }), this.language.instant('DMP-OVERVIEW.MULTIPLE-DIALOG.USE-DEFAULT')]
}
});
dialogRef.afterClosed().pipe(takeUntil(this._destroyed)).subscribe(result => {
switch (result) {
case 0:
this.showOauth2Dialog(repo.repositoryAuthorizationUrl + '?client_id=' + repo.repositoryClientId
+ '&response_type=code&scope=deposit:write+deposit:actions+user:email&state=astate&redirect_uri='
+ repo.redirectUri, repo, this.dmp);
break;
case 1:
this.depositRepositoriesService.createDoi(repo.repositoryId, this.dmp.id, null)
.pipe(takeUntil(this._destroyed))
.subscribe(doi =>{
this.onDOICallbackSuccess();
this.outputRepos.push(doi);
this.close();
}, error => this.onDOICallbackError(error));
break;
}
});
}
else if(repo.depositType == DepositConfigurationStatus.System){
this.depositRepositoriesService.createDoi(repo.repositoryId, this.dmp.id, null)
.pipe(takeUntil(this._destroyed))
.subscribe(doi =>{
this.onDOICallbackSuccess();
this.outputRepos.push(doi);
this.close();
}, error => this.onDOICallbackError(error));
}
}
onDOICallbackSuccess(): void {
this.uiNotificationService.snackBarNotification(this.language.instant('DMP-EDITOR.SNACK-BAR.SUCCESSFUL-DOI'), SnackBarNotificationLevel.Success);
}
onDOICallbackError(error) {
this.uiNotificationService.snackBarNotification(error.error.message ? error.error.message : this.language.instant('DMP-EDITOR.SNACK-BAR.UNSUCCESSFUL-DOI'), SnackBarNotificationLevel.Error);
}
showOauth2Dialog(url: string, repo: DepositConfigurationModel, dmp: DmpOverviewModel) {
this.oauth2DialogService.login(url)
.pipe(takeUntil(this._destroyed))
.subscribe(result => {
if (result !== undefined) {
if (result.oauthCode !== undefined && result.oauthCode !== null && !this.oauthLock) {
this.depositRepositoriesService.getAccessToken(repo.repositoryId, result.oauthCode)
.pipe(takeUntil(this._destroyed))
.subscribe(token => {
this.depositRepositoriesService.createDoi(repo.repositoryId, dmp.id, token)
.pipe(takeUntil(this._destroyed))
.subscribe(doi =>{
this.onDOICallbackSuccess();
this.outputRepos.push(doi);
this.close();
}, error => this.onDOICallbackError(error));
});
this.oauthLock = true;
}
}
else{
this.oauthLock = false;
}
});
}
}

View File

@ -980,7 +980,8 @@ export class DmpEditorComponent extends CheckDeactivateBaseComponent implements
dmpDescription: this.formGroup.get('description').value,
datasets: this.formGroup.get('datasets').value.map(x => {
return { label: x.label, id: x.id, status: x.status };
})
}),
accessRights: false
}
const dialogRef = this.dialog.open(DmpFinalizeDialogComponent, {

View File

@ -64,8 +64,11 @@
<div class="row pt-2 pb-2 pl-4 pr-4">
{{ 'DMP-FINALISE-DIALOG.IMPACT' | translate }}
</div>
<div class="row pl-4 pr-4">
{{ 'DMP-FINALISE-DIALOG.AFTER-FINALIZATION' | translate }}
<div *ngIf="inputModel.accessRights" class="row pl-4 pr-4">
{{ 'DMP-FINALISE-DIALOG.AFTER-FINALIZATION-PUBLISH' | translate }}
</div>
<div *ngIf="!inputModel.accessRights" class="row pl-4 pr-4">
{{ 'DMP-FINALISE-DIALOG.AFTER-FINALIZATION-RESTRICT-ACCESS' | translate }}
</div>
</div>

View File

@ -95,6 +95,7 @@ export interface DmpFinalizeDialogInput {
dmpLabel: string;
dmpDescription: string;
datasets: DmpFinalizeDialogDataset[];
accessRights: boolean;
}
export interface DmpFinalizeDialogDataset {

View File

@ -114,21 +114,41 @@
<div *ngIf="!hasDoi(dmp)" class="row d-flex flex-column ml-0 mr-0 mb-3">
<p class="doi-label">{{'DMP-EDITOR.TITLE.SUBTITLE' | translate}}</p>
<div class="doi-panel">
<p *ngIf="!hasDoi(dmp)" class="mb-0 ml-3">
<textarea #doi class="doi-txt">{{ dmp.doi }}</textarea>
</p>
<div class="d-flex justify-content-end">
<button (click)="copyDoi(doi)" mat-mini-fab class="mr-2 d-flex justify-content-center align-items-center" matTooltip="{{'DMP-LISTING.ACTIONS.COPY' | translate}}" matTooltipPosition="above">
<mat-select #select class="mb-0 ml-3" placeholder="{{ dmp.dois[0].doi }}">
<mat-option *ngFor="let doi of dmp.dois" (click)="selectDoi(select, doi)">
{{doi.repositoryId}}
</mat-option>
</mat-select>
<div class="d-flex justify-content-end ml-3">
<button (click)="copyDoi(dmp.dois[0].doi)" mat-mini-fab class="mr-2 d-flex justify-content-center align-items-center" matTooltip="{{'DMP-LISTING.ACTIONS.COPY' | translate}}" matTooltipPosition="above">
<mat-icon class="mat-mini-fab-icon">content_copy</mat-icon>
</button>
<button mat-mini-fab class="mr-2 d-flex justify-content-center align-items-center" matTooltip="{{'GRANT-EDITOR.ACTIONS.VISIT-WEBSITE' | translate}}" matTooltipPosition="above">
<a [href]="createDoiLink(dmp.doi)" class="doi-link" target="_blank">
<a [href]="createDoiLink(dmp.dois[0])" class="doi-link" target="_blank">
<mat-icon class="mat-mini-fab-icon">launch</mat-icon>
</a>
</button>
</div>
</div>
</div>
<!-- <div *ngIf="!hasDoi(dmp)" class="row d-flex flex-column ml-0 mr-0 mb-3">
<p class="doi-label">{{'DMP-EDITOR.TITLE.SUBTITLE' | translate}}</p>
<div class="doi-panel">
<p *ngIf="!hasDoi(dmp)" class="mb-0 ml-3">
<textarea #doi class="doi-txt">{{ dmp.dois[0].doi }}</textarea>
</p>
<div class="d-flex justify-content-end">
<button (click)="copyDoi(doi)" mat-mini-fab class="mr-2 d-flex justify-content-center align-items-center" matTooltip="{{'DMP-LISTING.ACTIONS.COPY' | translate}}" matTooltipPosition="above">
<mat-icon class="mat-mini-fab-icon">content_copy</mat-icon>
</button>
<button mat-mini-fab class="mr-2 d-flex justify-content-center align-items-center" matTooltip="{{'GRANT-EDITOR.ACTIONS.VISIT-WEBSITE' | translate}}" matTooltipPosition="above">
<a [href]="createDoiLink(dmp.dois[0].doi)" class="doi-link" target="_blank">
<mat-icon class="mat-mini-fab-icon">launch</mat-icon>
</a>
</button>
</div>
</div>
</div> -->
<div class="frame mb-3 pt-4 pl-3 pr-5 pb-1">
<div *ngIf="isDraftDmp(dmp) && isUserOwner && !lockStatus">
<div class="row ml-0 mr-0 pl-4 d-flex align-items-center" (click)="finalize(dmp)">
@ -141,7 +161,7 @@
<hr class="hr-line">
</div>
</div>
<div *ngIf="hasDoi(dmp) && isFinalizedDmp(dmp) && !this.isPublicView && isUserOwner" (click)="getDoi(dmp)" class="row ml-0 mr-0 pl-4 pb-3 d-flex align-items-center">
<div *ngIf="(hasDoi(dmp) || moreDeposit()) && isFinalizedDmp(dmp) && !this.isPublicView && isUserOwner" (click)="deposit()" class="row ml-0 mr-0 pl-4 pb-3 d-flex align-items-center">
<button mat-mini-fab class="frame-btn">
<mat-icon class="mat-mini-fab-icon">archive</mat-icon>
</button>
@ -167,12 +187,12 @@
<p class="mb-0 pl-2 frame-txt">{{ 'DMP-LISTING.ACTIONS.START-NEW-VERSION' | translate }}
</p>
</div>
<div *ngIf="!dmp.isPublic && showPublishButton(dmp) && isUserOwner" class="row ml-0 mr-0 pl-4 pb-3 d-flex align-items-center" (click)="publish(dmp.id)">
<!-- <div *ngIf="!dmp.isPublic && showPublishButton(dmp) && isUserOwner" class="row ml-0 mr-0 pl-4 pb-3 d-flex align-items-center" (click)="publish(dmp.id)">
<button mat-mini-fab class="frame-btn">
<mat-icon class="mat-mini-fab-icon">public</mat-icon>
</button>
<p class="mb-0 pl-2 frame-txt">{{ 'DMP-LISTING.ACTIONS.MAKE-PUBLIC' | translate }}</p>
</div>
</div> -->
<mat-menu #exportMenu="matMenu" xPosition="before">
<button mat-menu-item (click)="downloadPDF(dmp.id)">
<i class="fa fa-file-pdf-o pr-2"></i>

View File

@ -18,16 +18,15 @@ import { BreadcrumbItem } from '@app/ui/misc/breadcrumb/definition/breadcrumb-it
import { BaseComponent } from '@common/base/base.component';
import { TranslateService } from '@ngx-translate/core';
import * as FileSaver from 'file-saver';
import { Observable, of as observableOf, interval } from 'rxjs';
import { Observable, of as observableOf } from 'rxjs';
import { takeUntil, map } from 'rxjs/operators';
import { Role } from "@app/core/common/enum/role";
import { DmpInvitationDialogComponent } from '../invitation/dmp-invitation-dialog.component';
import { MultipleChoiceDialogComponent } from '@common/modules/multiple-choice-dialog/multiple-choice-dialog.component';
import { ConfigurationService } from '@app/core/services/configuration/configuration.service';
import { Oauth2DialogService } from '@app/ui/misc/oauth2-dialog/service/oauth2-dialog.service';
import { UserService } from '@app/core/services/user/user.service';
import { Location } from '@angular/common';
import { FormGroup, FormArray, FormControl } from '@angular/forms';
import { FormGroup } from '@angular/forms';
import { LockService } from '@app/core/services/lock/lock.service';
import { VersionListingModel } from '@app/core/model/version/version-listing.model';
import { CloneDialogComponent } from '../clone/clone-dialog/clone-dialog.component';
@ -41,6 +40,12 @@ import { StartNewDmpDialogComponent } from '../start-new-dmp-dialogue/start-new-
import { HttpClient } from '@angular/common/http';
import { MatomoService } from '@app/core/services/matomo/matomo-service';
import { PopupNotificationDialogComponent } from '@app/library/notification/popup/popup-notification.component';
import { DepositRepositoriesService } from '@app/core/services/deposit-repositories/deposit-repositories.service';
import { DmpDepositDialogComponent } from '../editor/dmp-deposit-dialog/dmp-deposit-dialog.component';
import { DepositConfigurationModel } from '@app/core/model/deposit/deposit-configuration';
import { DoiModel } from '@app/core/model/doi/doi';
import { MatSelect } from '@angular/material/select';
import { isNullOrUndefined } from '@app/utilities/enhancers/utils';
@Component({
selector: 'app-dmp-overview',
@ -63,28 +68,27 @@ export class DmpOverviewComponent extends BaseComponent implements OnInit {
textMessage: any;
versions: VersionListingModel[];
version: VersionListingModel;
private oauthLock: boolean;
@ViewChild('doi')
doi: ElementRef;
depositRepos: DepositConfigurationModel[] = [];
formGroup: FormGroup;
constructor(
private route: ActivatedRoute,
private router: Router,
private dmpService: DmpService,
private depositRepositoriesService: DepositRepositoriesService,
private translate: TranslateService,
private authentication: AuthService,
private dialog: MatDialog,
private language: TranslateService,
private uiNotificationService: UiNotificationService,
private configurationService: ConfigurationService,
private oauth2DialogService: Oauth2DialogService,
private userService: UserService,
private location: Location,
private lockService: LockService,
private httpClient: HttpClient,
private matomoService: MatomoService
) {
super();
@ -145,6 +149,13 @@ export class DmpOverviewComponent extends BaseComponent implements OnInit {
});
}
});
this.depositRepositoriesService.getAvailableRepos()
.pipe(takeUntil(this._destroyed))
.subscribe(
repos => {
this.depositRepos = repos;
},
error => this.depositRepos = []);
}
onFetchingDeletedCallbackError(redirectRoot: string) {
@ -444,26 +455,7 @@ export class DmpOverviewComponent extends BaseComponent implements OnInit {
}
hasDoi(dmp: DmpOverviewModel) {
return dmp.doi == null ? true : false;
}
getAccessUrl(): string {
const redirectUri = this.configurationService.app + 'oauth2';
const url = this.configurationService.loginProviders.zenodoConfiguration.oauthUrl
+ '?client_id=' + this.configurationService.loginProviders.zenodoConfiguration.clientId
+ '&response_type=code&scope=deposit:write+deposit:actions+user:email&state=astate&redirect_uri='
+ redirectUri;
return url;
}
getDoi(dmp: DmpOverviewModel) {
this.userService.hasDOIToken().subscribe(response => {
this.hasDOIToken = true;
this.showConfirmationDOIDialog(dmp);
}, error => {
this.hasDOIToken = false;
this.showErrorConfirmationDOIDialog(error.error.message, dmp);
});
return (this.dmp.dois == null || this.dmp.dois.length == 0) ? true : false;
}
getAllVersions(dmp: DmpOverviewModel) {
@ -474,82 +466,6 @@ export class DmpOverviewComponent extends BaseComponent implements OnInit {
});
}
showConfirmationDOIDialog(dmp: DmpOverviewModel) {
const dialogRef = this.dialog.open(ConfirmationDialogComponent, {
maxWidth: '600px',
restoreFocus: false,
data: {
message: this.language.instant('GENERAL.CONFIRMATION-DIALOG.ZENODO-DOI', { 'username': this.hasDOIToken ? this.authentication.current().zenodoEmail : 'default' }),
confirmButton: this.language.instant('GENERAL.CONFIRMATION-DIALOG.ACTIONS.CONFIRM'),
cancelButton: this.language.instant('GENERAL.CONFIRMATION-DIALOG.ACTIONS.CANCEL'),
}
});
dialogRef.afterClosed().pipe(takeUntil(this._destroyed)).subscribe(result => {
if (result) {
this.dmpService.getDoi(dmp.id)
.pipe(takeUntil(this._destroyed))
.subscribe(
complete => {
this.onDOICallbackSuccess();
this.dmp.doi = complete;
},
error => this.onDeleteCallbackError(error)
);
}
});
}
showErrorConfirmationDOIDialog(message: string, dmp: DmpOverviewModel) {
const dialogRef = this.dialog.open(MultipleChoiceDialogComponent, {
maxWidth: '600px',
restoreFocus: false,
data: {
message: message ? this.language.instant(message) : this.language.instant('GENERAL.ERRORS.HTTP-REQUEST-ERROR'),
titles: [this.language.instant('DMP-OVERVIEW.MULTIPLE-DIALOG.ZENODO-LOGIN'), this.language.instant('DMP-OVERVIEW.MULTIPLE-DIALOG.USE-DEFAULT')]
}
});
dialogRef.afterClosed().pipe(takeUntil(this._destroyed)).subscribe(result => {
switch (result) {
case 0:
// this.authentication.logout();
// this.router.navigate(['/login/external/zenodo']);
this.showOauth2Dialog(this.getAccessUrl(), dmp);
break;
case 1:
this.showConfirmationDOIDialog(dmp);
break;
}
});
}
showOauth2Dialog(url: string, dmp: DmpOverviewModel) {
this.oauth2DialogService.login(url)
.pipe(takeUntil(this._destroyed))
.subscribe(result => {
if (result !== undefined) {
if (result.oauthCode !== undefined && result.oauthCode !== null && !this.oauthLock) {
this.userService.registerDOIToken(result.oauthCode, this.configurationService.app + 'oauth2')
.pipe(takeUntil(this._destroyed))
.subscribe(() => {
this.hasDOIToken = true;
this.showConfirmationDOIDialog(dmp);
});
this.oauthLock = true;
}
} else {
this.oauthLock = false;
}
});
}
onDOICallbackSuccess(): void {
this.uiNotificationService.snackBarNotification(this.language.instant('DMP-EDITOR.SNACK-BAR.SUCCESSFUL-DOI'), SnackBarNotificationLevel.Success);
}
onDOICallbackError(error) {
this.uiNotificationService.snackBarNotification(error.error.message ? error.error.message : this.language.instant('DMP-EDITOR.SNACK-BAR.UNSUCCESSFUL-DOI'), SnackBarNotificationLevel.Error);
}
showPublishButton(dmp: DmpOverviewModel) {
return this.isFinalizedDmp(dmp) && !dmp.isPublic && this.hasPublishButton;
}
@ -578,45 +494,94 @@ export class DmpOverviewComponent extends BaseComponent implements OnInit {
});
}
finalize(dmp: DmpOverviewModel) {
const dialogInputModel: DmpFinalizeDialogInput = {
dmpLabel: this.dmp.label,
dmpDescription: this.dmp.description,
datasets: this.dmp.datasets.map(x => {
return { label: x.label, id: x.id, status: x.status }
})
}
const dialogRef = this.dialog.open(DmpFinalizeDialogComponent, {
maxWidth: '500px',
deposit(){
const dialogRef = this.dialog.open(DmpDepositDialogComponent, {
maxWidth: '600px',
disableClose: true,
restoreFocus: false,
autoFocus: false,
data: {
dialogInputModel: dialogInputModel,
message: this.language.instant('GENERAL.CONFIRMATION-DIALOG.FINALIZE-ITEM'),
confirmButton: this.language.instant('DMP-FINALISE-DIALOG.SUBMIT'),
cancelButton: this.language.instant('GENERAL.CONFIRMATION-DIALOG.ACTIONS.CANCEL'),
depositRepos: [this.depositRepos, this.dmp],
message: this.language.instant('DMP-OVERVIEW.DEPOSIT.SELECT-REPOSITORIES'),
confirmButton: this.language.instant('DMP-OVERVIEW.DEPOSIT.AUTHORIZE'),
cancelButton: this.language.instant('DMP-OVERVIEW.DEPOSIT.CANCEL'),
}
});
dialogRef.afterClosed().pipe(takeUntil(this._destroyed)).subscribe((result: DmpFinalizeDialogOutput) => {
if (result && !result.cancelled) {
var datasetsToBeFinalized: DatasetsToBeFinalized = {
uuids: result.datasetsToBeFinalized
};
this.dmpService.finalize(datasetsToBeFinalized, this.dmp.id)
.pipe(takeUntil(this._destroyed))
.subscribe(
complete => {
this.dmp.status = DmpStatus.Finalized;
this.onUpdateCallbackSuccess();
},
error => this.onUpdateCallbackError(error)
);
dialogRef.afterClosed().pipe(takeUntil(this._destroyed)).subscribe((result: DoiModel[]) => {
if (result.length > 0) {
this.dmp.dois.push(...result);
this.hasDOIToken = true;
}
});
}
moreDeposit(){
return (this.dmp.dois.length < this.depositRepos.length) ? true : false;
}
finalize(dmp: DmpOverviewModel) {
const extraProperties = new ExtraPropertiesFormModel();
this.dmpService.getSingle(this.dmp.id).pipe(map(data => data as DmpModel))
.pipe(takeUntil(this._destroyed))
.subscribe(data => {
if (!isNullOrUndefined(data.extraProperties)) {
extraProperties.fromModel(data.extraProperties);
}
const dialogInputModel: DmpFinalizeDialogInput = {
dmpLabel: this.dmp.label,
dmpDescription: this.dmp.description,
datasets: this.dmp.datasets.map(x => {
return { label: x.label, id: x.id, status: x.status }
}),
accessRights: extraProperties.visible
}
const dialogRef = this.dialog.open(DmpFinalizeDialogComponent, {
maxWidth: '500px',
restoreFocus: false,
autoFocus: false,
data: {
dialogInputModel: dialogInputModel,
message: this.language.instant('GENERAL.CONFIRMATION-DIALOG.FINALIZE-ITEM'),
confirmButton: this.language.instant('DMP-FINALISE-DIALOG.SUBMIT'),
cancelButton: this.language.instant('GENERAL.CONFIRMATION-DIALOG.ACTIONS.CANCEL'),
}
});
dialogRef.afterClosed().pipe(takeUntil(this._destroyed)).subscribe((result: DmpFinalizeDialogOutput) => {
if (result && !result.cancelled) {
var datasetsToBeFinalized: DatasetsToBeFinalized = {
uuids: result.datasetsToBeFinalized
};
this.dmpService.finalize(datasetsToBeFinalized, this.dmp.id)
.pipe(takeUntil(this._destroyed))
.subscribe(
complete => {
if(extraProperties.visible){
//this.publish(this.dmp.id);
this.dmpService.publish(this.dmp.id)
.pipe(takeUntil(this._destroyed))
.subscribe(() => {
//this.hasPublishButton = false;
this.dmp.status = DmpStatus.Finalized;
this.onUpdateCallbackSuccess();
});
}
else{
this.dmp.status = DmpStatus.Finalized;
this.onUpdateCallbackSuccess();
}
},
error => this.onUpdateCallbackError(error)
);
}
});
});
}
// newVersion(id: String, label: String) {
// let url = this.router.createUrlTree(['/plans/new_version/', id, { dmpLabel: label }])
// window.open(url.toString(), '_blank')
@ -677,10 +642,28 @@ export class DmpOverviewComponent extends BaseComponent implements OnInit {
this.router.navigate(['/datasets', 'new', this.dmp.id]);
}
createDoiLink(doi: string): string {
const doiarr = doi.split('.');
const id = doiarr[doiarr.length - 1];
return this.configurationService.doiLink + id;
selectDoi(s: MatSelect, doiModel: DoiModel){
s.placeholder = doiModel.doi;
const foundIdx = this.dmp.dois.findIndex(el => el == doiModel);
this.dmp.dois.splice(foundIdx, 1);
this.dmp.dois.unshift(doiModel);
}
createDoiLink(doiModel: DoiModel): string {
const recordUrl = this.depositRepos.find(r => r.repositoryId == doiModel.repositoryId).repositoryRecordUrl;
if(typeof recordUrl !== "undefined"){
if(doiModel.repositoryId == "Zenodo"){
const doiarr = doiModel.doi.split('.');
const id = doiarr[doiarr.length - 1];
return this.depositRepos.find(r => r.repositoryId == doiModel.repositoryId).repositoryRecordUrl + id;
}
else{
return this.depositRepos.find(r => r.repositoryId == doiModel.repositoryId).repositoryRecordUrl + doiModel.doi;
}
}
else{
return "";
}
}
reverse() {
@ -750,10 +733,15 @@ export class DmpOverviewComponent extends BaseComponent implements OnInit {
}
copyDoi(doi) {
let domElement = doi.nativeElement as HTMLInputElement;
domElement.select();
const el = document.createElement('textarea');
el.value = doi;
el.setAttribute('readonly', '');
el.style.position = 'absolute';
el.style.left = '-9999px';
document.body.appendChild(el);
el.select();
document.execCommand('copy');
domElement.setSelectionRange(0, 0);
document.body.removeChild(el);
this.uiNotificationService.snackBarNotification(this.language.instant('GENERAL.SNACK-BAR.SUCCESSFUL-COPY-TO-CLIPBOARD'), SnackBarNotificationLevel.Success);
}
@ -838,5 +826,99 @@ export class DmpOverviewComponent extends BaseComponent implements OnInit {
// });
// }
// getAccessUrl(): string {
// const redirectUri = this.configurationService.app + 'oauth2';
// const url = this.configurationService.loginProviders.zenodoConfiguration.oauthUrl
// + '?client_id=' + this.configurationService.loginProviders.zenodoConfiguration.clientId
// + '&response_type=code&scope=deposit:write+deposit:actions+user:email&state=astate&redirect_uri='
// + redirectUri;
// return url;
// }
// getDoi(dmp: DmpOverviewModel) {
// this.userService.hasDOIToken().subscribe(response => {
// this.hasDOIToken = true;
// this.showConfirmationDOIDialog(dmp);
// }, error => {
// this.hasDOIToken = false;
// this.showErrorConfirmationDOIDialog(error.error.message, dmp);
// });
// }
// showConfirmationDOIDialog(dmp: DmpOverviewModel) {
// const dialogRef = this.dialog.open(ConfirmationDialogComponent, {
// maxWidth: '600px',
// restoreFocus: false,
// data: {
// message: this.language.instant('GENERAL.CONFIRMATION-DIALOG.ZENODO-DOI', { 'username': this.hasDOIToken ? this.authentication.current().zenodoEmail : 'default' }),
// confirmButton: this.language.instant('GENERAL.CONFIRMATION-DIALOG.ACTIONS.CONFIRM'),
// cancelButton: this.language.instant('GENERAL.CONFIRMATION-DIALOG.ACTIONS.CANCEL'),
// }
// });
// dialogRef.afterClosed().pipe(takeUntil(this._destroyed)).subscribe(result => {
// if (result) {
// this.dmpService.getDoi(dmp.id)
// .pipe(takeUntil(this._destroyed))
// .subscribe(
// complete => {
// this.onDOICallbackSuccess();
// this.dmp.doi = complete;
// },
// error => this.onDeleteCallbackError(error)
// );
// }
// });
// }
// showErrorConfirmationDOIDialog(message: string, dmp: DmpOverviewModel) {
// const dialogRef = this.dialog.open(MultipleChoiceDialogComponent, {
// maxWidth: '600px',
// restoreFocus: false,
// data: {
// message: message ? this.language.instant(message) : this.language.instant('GENERAL.ERRORS.HTTP-REQUEST-ERROR'),
// titles: [this.language.instant('DMP-OVERVIEW.MULTIPLE-DIALOG.ZENODO-LOGIN'), this.language.instant('DMP-OVERVIEW.MULTIPLE-DIALOG.USE-DEFAULT')]
// }
// });
// dialogRef.afterClosed().pipe(takeUntil(this._destroyed)).subscribe(result => {
// switch (result) {
// case 0:
// // this.authentication.logout();
// // this.router.navigate(['/login/external/zenodo']);
// this.showOauth2Dialog(this.getAccessUrl(), dmp);
// break;
// case 1:
// this.showConfirmationDOIDialog(dmp);
// break;
// }
// });
// }
// showOauth2Dialog(url: string, dmp: DmpOverviewModel) {
// this.oauth2DialogService.login(url)
// .pipe(takeUntil(this._destroyed))
// .subscribe(result => {
// if (result !== undefined) {
// if (result.oauthCode !== undefined && result.oauthCode !== null && !this.oauthLock) {
// this.userService.registerDOIToken(result.oauthCode, this.configurationService.app + 'oauth2')
// .pipe(takeUntil(this._destroyed))
// .subscribe(() => {
// this.hasDOIToken = true;
// this.showConfirmationDOIDialog(dmp);
// });
// this.oauthLock = true;
// }
// } else {
// this.oauthLock = false;
// }
// });
// }
// onDOICallbackSuccess(): void {
// this.uiNotificationService.snackBarNotification(this.language.instant('DMP-EDITOR.SNACK-BAR.SUCCESSFUL-DOI'), SnackBarNotificationLevel.Success);
// }
// onDOICallbackError(error) {
// this.uiNotificationService.snackBarNotification(error.error.message ? error.error.message : this.language.instant('DMP-EDITOR.SNACK-BAR.UNSUCCESSFUL-DOI'), SnackBarNotificationLevel.Error);
// }
}

View File

@ -104,7 +104,8 @@ export class QuickWizardEditorComponent extends CheckDeactivateBaseComponent imp
dmpDescription: this.formGroup.get('dmp').get('description').value,
datasets: (this.formGroup.get('datasets').get('datasetsList') as FormArray).controls.map(x => {
return { label: x.get('datasetLabel').value, status: DatasetStatus.Finalized };
})
}),
accessRights: false
}
const dialogRef = this.dialog.open(DmpFinalizeDialogComponent, {

View File

@ -57,7 +57,6 @@
"lockInterval": 60000,
"guideAssets": "assets/images/guide",
"allowOrganizationCreator": true,
"doiLink": "https://sandbox.zenodo.org/record/",
"useSplash": false,
"orcidPath": "https://orcid.org/",
"maxFileSizeInMB": 10

View File

@ -805,6 +805,14 @@
"ZENODO-LOGIN": "Login with Zenodo",
"USE-DEFAULT": "Use Default Token"
},
"DEPOSIT": {
"ACCOUNT-LOGIN": "Which account would you like to use?",
"LOGIN": "Login with {{repository}}",
"NO-REPOSITORIES": "No publishing repositories",
"SELECT-REPOSITORIES": "Select repositories to deposit",
"AUTHORIZE": "Proceed to authorization",
"CANCEL": "Cancel"
},
"LOCKED-DIALOG":{
"TITLE": "DMP is locked",
"MESSAGE":"Somebody else is modifying the DMP at this moment. If you would like to modify or view it, please come back later."

View File

@ -805,6 +805,14 @@
"ZENODO-LOGIN": "Login with Zenodo",
"USE-DEFAULT": "Use Default Token"
},
"DEPOSIT": {
"ACCOUNT-LOGIN": "Which account would you like to use?",
"LOGIN": "Login with {{repository}}",
"NO-REPOSITORIES": "No publishing repositories",
"SELECT-REPOSITORIES": "Select repositories to deposit",
"AUTHORIZE": "Proceed to authorization",
"CANCEL": "Cancel"
},
"LOCKED-DIALOG":{
"TITLE": "DMP is locked",
"MESSAGE":"Somebody else is modifying the DMP at this moment. If you would like to modify or view it, please come back later."
@ -1786,7 +1794,8 @@
"AT-LEAST-ONE-DATASET-FINALISED": "You need to have at least one Dataset Finalized"
},
"IMPACT": "This action will finalize your DMP, and you won't be able to edit it again.",
"AFTER-FINALIZATION": "After finalizing your DMP you can Publish it, and it'll be publicly available to the ARGOS tool.",
"AFTER-FINALIZATION-PUBLISH": "After finalizing your DMP, it'll be published and be publicly available to the ARGOS tool.",
"AFTER-FINALIZATION-RESTRICT-ACCESS": "Your DMP can be published and be publicly available to the ARGOS tool after finalization when its access rights are opened. Current access rights: restricted",
"INVALID": "Invalid"
},
"DRAFTS": {

View File

@ -805,6 +805,14 @@
"ZENODO-LOGIN": "Identificarse con Zenodo",
"USE-DEFAULT": "Usar el token por defecto"
},
"DEPOSIT": {
"ACCOUNT-LOGIN": "Which account would you like to use?",
"LOGIN": "Login with {{repository}}",
"NO-REPOSITORIES": "No publishing repositories",
"SELECT-REPOSITORIES": "Select repositories to deposit",
"AUTHORIZE": "Proceed to authorization",
"CANCEL": "Cancel"
},
"LOCKED-DIALOG":{
"TITLE": "PGD bloqeuado",
"MESSAGE":"Alguien más está modificando el PGD. Si quiere modificarlo o visualizarlo, por favor, inténtelo más tarde."

View File

@ -805,6 +805,14 @@
"ZENODO-LOGIN": "Σύνδεση με Zenodo",
"USE-DEFAULT": "Χρήση Προκαθορισμένου Token"
},
"DEPOSIT": {
"ACCOUNT-LOGIN": "Which account would you like to use?",
"LOGIN": "Login with {{repository}}",
"NO-REPOSITORIES": "No publishing repositories",
"SELECT-REPOSITORIES": "Select repositories to deposit",
"AUTHORIZE": "Proceed to authorization",
"CANCEL": "Cancel"
},
"LOCKED-DIALOG":{
"TITLE": "DMP is locked",
"MESSAGE":"Somebody else is modifying the DMP at this moment. If you would like to modify or view it, please come back later."

View File

@ -805,6 +805,14 @@
"ZENODO-LOGIN": "Prijavite se pomoću Zenodo korisničkog računa",
"USE-DEFAULT": "Koristite zadanu opciju"
},
"DEPOSIT": {
"ACCOUNT-LOGIN": "Which account would you like to use?",
"LOGIN": "Login with {{repository}}",
"NO-REPOSITORIES": "No publishing repositories",
"SELECT-REPOSITORIES": "Select repositories to deposit",
"AUTHORIZE": "Proceed to authorization",
"CANCEL": "Cancel"
},
"LOCKED-DIALOG": {
"TITLE": "PUP je zaključan",
"MESSAGE": "U ovom trenutku netko drugi uređuje informacije o skupu podataka. Ako želite pregledati zapis ili napraviti izmjenu, pričekajte i pokušajte ponovo kasnije."

View File

@ -805,6 +805,14 @@
"ZENODO-LOGIN": "Zaloguj się za pomocą Zenodo",
"USE-DEFAULT": "Użyj domyślnego tokena"
},
"DEPOSIT": {
"ACCOUNT-LOGIN": "Which account would you like to use?",
"LOGIN": "Login with {{repository}}",
"NO-REPOSITORIES": "No publishing repositories",
"SELECT-REPOSITORIES": "Select repositories to deposit",
"AUTHORIZE": "Proceed to authorization",
"CANCEL": "Cancel"
},
"LOCKED-DIALOG": {
"TITLE": "DMP jest zablokowany",
"MESSAGE": "W tej chwili ktoś inny modyfikuje ten zbiór danych. Możesz przeglądać ten zbiór danych, ale nie możesz wprowadzać żadnych zmian. Jeśli chcesz go zmodyfikować, wróć później."

View File

@ -810,6 +810,14 @@
"ZENODO-LOGIN": "Entre com o Zenodo",
"USE-DEFAULT": "Use o Token"
},
"DEPOSIT": {
"ACCOUNT-LOGIN": "Which account would you like to use?",
"LOGIN": "Login with {{repository}}",
"NO-REPOSITORIES": "No publishing repositories",
"SELECT-REPOSITORIES": "Select repositories to deposit",
"AUTHORIZE": "Proceed to authorization",
"CANCEL": "Cancel"
},
"LOCKED-DIALOG":{
"TITLE": "DMP is locked",
"MESSAGE":"Somebody else is modifying the DMP at this moment. If you would like to modify or view it, please come back later."

View File

@ -805,6 +805,14 @@
"ZENODO-LOGIN": "Prihlásiť sa do Zenodo",
"USE-DEFAULT": "Použite predvolený token"
},
"DEPOSIT": {
"ACCOUNT-LOGIN": "Which account would you like to use?",
"LOGIN": "Login with {{repository}}",
"NO-REPOSITORIES": "No publishing repositories",
"SELECT-REPOSITORIES": "Select repositories to deposit",
"AUTHORIZE": "Proceed to authorization",
"CANCEL": "Cancel"
},
"LOCKED-DIALOG":{
"TITLE": "DMP is locked",
"MESSAGE":"Somebody else is modifying the DMP at this moment. If you would like to modify or view it, please come back later."

View File

@ -805,6 +805,14 @@
"ZENODO-LOGIN": "Prijavite se pomoću Zenodo naloga",
"USE-DEFAULT": "Koristite podrazumevani znak"
},
"DEPOSIT": {
"ACCOUNT-LOGIN": "Which account would you like to use?",
"LOGIN": "Login with {{repository}}",
"NO-REPOSITORIES": "No publishing repositories",
"SELECT-REPOSITORIES": "Select repositories to deposit",
"AUTHORIZE": "Proceed to authorization",
"CANCEL": "Cancel"
},
"LOCKED-DIALOG":{
"TITLE": "DMP is locked",
"MESSAGE":"Somebody else is modifying the DMP at this moment. If you would like to modify or view it, please come back later."

View File

@ -805,6 +805,14 @@
"ZENODO-LOGIN": "Zenodo ile oturum aç",
"USE-DEFAULT": "Mevcut Jetonu Kullan"
},
"DEPOSIT": {
"ACCOUNT-LOGIN": "Which account would you like to use?",
"LOGIN": "Login with {{repository}}",
"NO-REPOSITORIES": "No publishing repositories",
"SELECT-REPOSITORIES": "Select repositories to deposit",
"AUTHORIZE": "Proceed to authorization",
"CANCEL": "Cancel"
},
"LOCKED-DIALOG":{
"TITLE": "DMP is locked",
"MESSAGE":"Somebody else is modifying the DMP at this moment. If you would like to modify or view it, please come back later."