package eu.eudat.depositinterface.dataverserepository.interfaces; import com.fasterxml.jackson.databind.ObjectMapper; import com.researchspace.dataverse.api.v1.DataverseAPI; import com.researchspace.dataverse.api.v1.DataverseConfig; import com.researchspace.dataverse.entities.*; import com.researchspace.dataverse.entities.facade.DatasetAuthor; import com.researchspace.dataverse.entities.facade.DatasetContact; import com.researchspace.dataverse.entities.facade.DatasetDescription; import com.researchspace.dataverse.entities.facade.DatasetFacade; import com.researchspace.dataverse.http.DataverseAPIImpl; import eu.eudat.depositinterface.dataverserepository.config.ConfigLoader; import eu.eudat.depositinterface.models.DMPDepositModel; import eu.eudat.depositinterface.repository.RepositoryDeposit; import eu.eudat.depositinterface.repository.RepositoryDepositConfiguration; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.core.env.Environment; import org.springframework.http.*; import org.springframework.stereotype.Component; import org.springframework.util.LinkedMultiValueMap; import org.springframework.util.MultiValueMap; import org.springframework.web.client.RestTemplate; import java.io.File; import java.io.FileOutputStream; import java.io.IOException; import java.io.OutputStream; import java.net.MalformedURLException; import java.net.URL; import java.nio.file.Files; import java.util.*; import java.util.stream.Collectors; import static com.researchspace.dataverse.entities.Version.MAJOR; import static com.researchspace.dataverse.entities.Version.MINOR; @Component public class DataverseDeposit implements RepositoryDeposit { private static final Logger logger = LoggerFactory.getLogger(DataverseDeposit.class); private static final ObjectMapper objectMapper = new ObjectMapper(); private static final String API_TOKEN = ""; private static final String SYSTEM_PARENT_DATAVERSE_ALIAS = ""; private static final String SERVER = ""; private static final String SYSTEM_EMAIL = ""; private DataverseAPI api; private boolean isApiSet; private ConfigLoader configLoader; private Environment environment; @Autowired public DataverseDeposit(ConfigLoader configLoader, Environment environment){ this.configLoader = configLoader; this.environment = environment; this.isApiSet = false; } private void setDataverseApi() throws MalformedURLException { if(!this.isApiSet) { this.api = new DataverseAPIImpl(); DataverseConfig config = new DataverseConfig(new URL(SERVER), API_TOKEN, SYSTEM_PARENT_DATAVERSE_ALIAS); api.configure(config); this.isApiSet = true; } } @Override public String deposit(DMPDepositModel dmpDepositModel, String repositoryAccessToken) throws Exception { if(!this.isApiSet) this.setDataverseApi(); String doi; DatasetFacade dataset = DatasetFacade.builder() .title(dmpDepositModel.getLabel()) .authors(dmpDepositModel.getUsers().stream().map(x -> DatasetAuthor.builder().authorName(x.getUser().getName()).build()).collect(Collectors.toList())) .contacts(dmpDepositModel.getUsers().stream().map(x -> DatasetContact.builder().datasetContactEmail(x.getUser().getEmail()).build()).collect(Collectors.toList())) .subject("Other") .description(DatasetDescription.builder().description(dmpDepositModel.getDescription()).build()) .languages(new ArrayList<>()) .depositor("") .build(); if(dmpDepositModel.getPreviousDOI() == null || dmpDepositModel.getPreviousDOI().isEmpty()){ Identifier id = this.api.getDataverseOperations().createDataset(dataset, SYSTEM_PARENT_DATAVERSE_ALIAS); doi = this.api.getDatasetOperations().getDataset(id).getDoiId().orElse(null); this.uploadFiles(dmpDepositModel, doi); this.api.getDatasetOperations().publishDataset(id, MAJOR); } else{ Map datasetJson = this.getDatasetIdentifier(dmpDepositModel.getPreviousDOI()); Identifier id = new Identifier(); id.setId(((Integer) datasetJson.get("id")).longValue()); this.uploadFiles(dmpDepositModel, dmpDepositModel.getPreviousDOI()); this.api.getDatasetOperations().updateDataset(dataset, id); DataverseResponse publishedDataset = this.api.getDatasetOperations().publishDataset(id, MAJOR); doi = publishedDataset.getData().getAuthority() + "/" + publishedDataset.getData().getIdentifier(); } return doi; } private void uploadFiles(DMPDepositModel dmpDepositModel, String doi) throws IOException { this.uploadFile(dmpDepositModel.getPdfFileName(), dmpDepositModel.getPdfFile(), doi); String contentDisposition = dmpDepositModel.getRdaJson().getHeaders().get("Content-Disposition").get(0); String jsonFileName = contentDisposition.substring(contentDisposition.lastIndexOf('=') + 1); File rdaJson = new File(this.environment.getProperty("storage.temp") + jsonFileName); OutputStream output = new FileOutputStream(rdaJson); try { output.write(Objects.requireNonNull(dmpDepositModel.getRdaJson().getBody())); output.flush(); output.close(); } catch (IOException e) { logger.error(e.getMessage(), e); } this.uploadFile(jsonFileName, rdaJson, doi); Files.deleteIfExists(rdaJson.toPath()); } private Map getDatasetIdentifier(String previousDOI) { HttpHeaders headers = new HttpHeaders(); headers.set("X-Dataverse-key", API_TOKEN); String serverUrl = SERVER + "/api/datasets/:persistentId?persistentId=doi:" + previousDOI; RestTemplate restTemplate = new RestTemplate(); return (Map) restTemplate.exchange(serverUrl, HttpMethod.GET, new HttpEntity<>(headers), Map.class).getBody().get("data"); } private void uploadFile(String filename, File file, String doi) throws IOException { HttpHeaders headers = new HttpHeaders(); headers.setContentType(MediaType.MULTIPART_FORM_DATA); headers.set("X-Dataverse-key", API_TOKEN); MultiValueMap fileMap = new LinkedMultiValueMap<>(); ContentDisposition contentDisposition = ContentDisposition .builder("form-data") .name("file") .filename(filename) .build(); fileMap.add(HttpHeaders.CONTENT_DISPOSITION, contentDisposition.toString()); HttpEntity fileEntity = new HttpEntity<>(Files.readAllBytes(file.toPath()), fileMap); MultiValueMap body = new LinkedMultiValueMap<>(); body.add("file", fileEntity); body.add("jsonData", "{\"restrict\":\"false\", \"tabIngest\":\"false\"}"); HttpEntity> requestEntity = new HttpEntity<>(body, headers); String serverUrl = SERVER + "/api/datasets/:persistentId/add?persistentId=doi:" + doi; RestTemplate restTemplate = new RestTemplate(); ResponseEntity resp = restTemplate.postForEntity(serverUrl, requestEntity, Object.class); } @Override public RepositoryDepositConfiguration getConfiguration() { eu.eudat.depositinterface.dataverserepository.config.DataverseConfig dataverseConfig = this.configLoader.getDataverseConfig(); return dataverseConfig.toRepoConfig(); } @Override public String authenticate(String code) { return null; } }