diff --git a/pass-deposit-services/deposit-core/src/main/java/org/eclipse/pass/deposit/builder/DepositSubmissionMapper.java b/pass-deposit-services/deposit-core/src/main/java/org/eclipse/pass/deposit/builder/DepositSubmissionMapper.java index 549c7def6..5f7b84f1f 100644 --- a/pass-deposit-services/deposit-core/src/main/java/org/eclipse/pass/deposit/builder/DepositSubmissionMapper.java +++ b/pass-deposit-services/deposit-core/src/main/java/org/eclipse/pass/deposit/builder/DepositSubmissionMapper.java @@ -20,10 +20,10 @@ import java.net.URI; import java.time.LocalDate; -import java.time.LocalDateTime; import java.time.ZoneId; import java.time.ZonedDateTime; import java.time.format.DateTimeFormatter; +import java.time.format.DateTimeParseException; import java.util.ArrayList; import java.util.List; import java.util.Optional; @@ -73,8 +73,8 @@ public class DepositSubmissionMapper { private static final String AUTHORS_KEY = "authors"; private static final String AUTHOR_KEY = "author"; private static final String PUB_TYPE_KEY = "pubType"; - private static final String EMBARGO_END_DATE_PATTERN = "yyyy-MM-dd"; private static final String NLMTA_KEY = "journal-NLMTA-ID"; + private static final String DEFAULT_DATE_TIME_ZONE = "America/New_York"; /** * Creates a DepositSubmission by walking the tree of PassEntity objects, starting with the Submission entity, @@ -267,7 +267,7 @@ private void processCommonMetadata(DepositMetadata metadata, JsonObject submissi .ifPresent(pName -> metadata.getJournalMetadata().setPublisherName(pName)); getStringProperty(submissionData, PUBLICATION_DATE_KEY) - .ifPresent(pName -> metadata.getJournalMetadata().setPublicationDate(pName)); + .ifPresent(date -> metadata.getJournalMetadata().setPublicationDate(parseDate(date))); getArrayProperty(submissionData, ISSNS).ifPresent(issns -> { issns.forEach(issnObjAsStr -> { @@ -290,19 +290,29 @@ private void processCommonMetadata(DepositMetadata metadata, JsonObject submissi getStringProperty(submissionData, EMBARGO_END_DATE_KEY).ifPresent(endDate -> { try { - // TODO - Resolve inconsistent date/date-time formats in metadata and deposit data model - // TODO - Fix assumption of local timezone - DateTimeFormatter formatter = DateTimeFormatter.ofPattern(EMBARGO_END_DATE_PATTERN); - LocalDateTime localEndDate = LocalDate.parse(endDate, formatter).atStartOfDay(); - ZonedDateTime zonedEndDate = localEndDate.atZone(ZoneId.of("America/New_York")); - metadata.getArticleMetadata().setEmbargoLiftDate(zonedEndDate); - } catch (Exception e) { + metadata.getArticleMetadata().setEmbargoLiftDate(parseDate(endDate)); + } catch (DateTimeParseException e) { throw new DepositServiceRuntimeException( - String.format("Data file contained an invalid Date: '%s'.", endDate), e); + String.format("Data file contained an invalid Date: '%s'.", endDate), e); } }); } + // Parse an ISO 8601 date with or without a time zone + public ZonedDateTime parseDate(String date) { + try { + return ZonedDateTime.parse(date, DateTimeFormatter.ISO_DATE); + } catch (DateTimeParseException e) { + try { + return LocalDate.parse(date, DateTimeFormatter.ISO_LOCAL_DATE).atStartOfDay() + .atZone(ZoneId.of(DEFAULT_DATE_TIME_ZONE)); + } catch (DateTimeParseException e2) { + throw new DepositServiceRuntimeException( + String.format("Metadata contained an invalid Date: '%s'.", date), e2); + } + } + } + private void processCrossrefMetadata(DepositMetadata metadata, JsonObject submissionData) { getStringProperty(submissionData, DOI_KEY).ifPresent(doi -> { try { diff --git a/pass-deposit-services/deposit-core/src/main/java/org/eclipse/pass/deposit/provider/dspace/DSpaceMetadataMapper.java b/pass-deposit-services/deposit-core/src/main/java/org/eclipse/pass/deposit/provider/dspace/DSpaceMetadataMapper.java index eb9d3d713..c579aac60 100644 --- a/pass-deposit-services/deposit-core/src/main/java/org/eclipse/pass/deposit/provider/dspace/DSpaceMetadataMapper.java +++ b/pass-deposit-services/deposit-core/src/main/java/org/eclipse/pass/deposit/provider/dspace/DSpaceMetadataMapper.java @@ -79,10 +79,9 @@ public String patchWorkspaceItem(DepositSubmission submission) { metadata.add(add_array("traditionalpageone", "dc.identifier.citation", citation)); } - // TODO: Must format YYYY-MM-DD - // Required by DSpace - String publicationDate = journalMd.getPublicationDate(); - metadata.add(add_array("traditionalpageone", "dc.date.issued", publicationDate)); + // Required by DSpace as ISO 8601 local date + metadata.add(add_array("traditionalpageone", "dc.date.issued", journalMd.getPublicationDate(). + format(DateTimeFormatter.ISO_LOCAL_DATE))); // Add non-submitters as authors // TODO This is different from before @@ -171,8 +170,9 @@ private String createCitation(DepositSubmission submission) { // Attach a if not empty // publication date - after a single space, in parens, followed by "." - if (journalMd != null && journalMd.getPublicationDate() != null && !journalMd.getPublicationDate().isEmpty()) { - citationBldr.append(" (" + journalMd.getPublicationDate() + ")."); + if (journalMd != null && journalMd.getPublicationDate() != null) { + citationBldr.append(" (" + journalMd.getPublicationDate(). + format(DateTimeFormatter.ISO_LOCAL_DATE) + ")."); } // article title - after single space, in double quotes with "." inside if (articleMd != null && articleMd.getTitle() != null && !articleMd.getTitle().isEmpty()) { diff --git a/pass-deposit-services/deposit-core/src/main/java/org/eclipse/pass/deposit/provider/inveniordm/InvenioRdmMetadataMapper.java b/pass-deposit-services/deposit-core/src/main/java/org/eclipse/pass/deposit/provider/inveniordm/InvenioRdmMetadataMapper.java index f73235a56..1b4885016 100644 --- a/pass-deposit-services/deposit-core/src/main/java/org/eclipse/pass/deposit/provider/inveniordm/InvenioRdmMetadataMapper.java +++ b/pass-deposit-services/deposit-core/src/main/java/org/eclipse/pass/deposit/provider/inveniordm/InvenioRdmMetadataMapper.java @@ -15,6 +15,7 @@ */ package org.eclipse.pass.deposit.provider.inveniordm; +import java.time.format.DateTimeFormatter; import java.util.Objects; import net.minidev.json.JSONArray; @@ -49,8 +50,9 @@ public JSONObject toInvenioMetadata(DepositSubmission depositSubmission) { invenioMetadata.put("creators", creators); String title = depositSubmission.getSubmissionMeta().get("title").getAsString(); invenioMetadata.put("title", title); - String publicationDate = depositMetadata.getJournalMetadata().getPublicationDate(); - invenioMetadata.put("publication_date", publicationDate); + + invenioMetadata.put("publication_date", depositMetadata.getJournalMetadata(). + getPublicationDate().format(DateTimeFormatter.ISO_LOCAL_DATE)); JSONObject resourceType = new JSONObject(); resourceType.put("id", "publication-article"); invenioMetadata.put("resource_type", resourceType); diff --git a/pass-deposit-services/deposit-core/src/main/java/org/eclipse/pass/deposit/provider/j10p/DspaceMetadataDomWriter.java b/pass-deposit-services/deposit-core/src/main/java/org/eclipse/pass/deposit/provider/j10p/DspaceMetadataDomWriter.java index ee7a3853e..40309790a 100644 --- a/pass-deposit-services/deposit-core/src/main/java/org/eclipse/pass/deposit/provider/j10p/DspaceMetadataDomWriter.java +++ b/pass-deposit-services/deposit-core/src/main/java/org/eclipse/pass/deposit/provider/j10p/DspaceMetadataDomWriter.java @@ -469,8 +469,8 @@ Element createDublinCoreMetadataDCMES(DepositSubmission submission) { // Attach a if not empty // publication date - after a single space, in parens, followed by "." - if (journalMd != null && journalMd.getPublicationDate() != null && !journalMd.getPublicationDate().isEmpty()) { - citationBldr.append(" (" + journalMd.getPublicationDate() + ")."); + if (journalMd != null && journalMd.getPublicationDate() != null) { + citationBldr.append(" (" + journalMd.getPublicationDate().format(DateTimeFormatter.ISO_LOCAL_DATE) + ")."); } // article title - after single space, in double quotes with "." inside if (articleMd != null && articleMd.getTitle() != null && !articleMd.getTitle().isEmpty()) { diff --git a/pass-deposit-services/deposit-core/src/test/java/org/eclipse/pass/deposit/provider/j10p/DspaceMetadataDomWriterTest.java b/pass-deposit-services/deposit-core/src/test/java/org/eclipse/pass/deposit/provider/j10p/DspaceMetadataDomWriterTest.java index 7f4e6e3b5..9d8cacf54 100644 --- a/pass-deposit-services/deposit-core/src/test/java/org/eclipse/pass/deposit/provider/j10p/DspaceMetadataDomWriterTest.java +++ b/pass-deposit-services/deposit-core/src/test/java/org/eclipse/pass/deposit/provider/j10p/DspaceMetadataDomWriterTest.java @@ -104,8 +104,6 @@ import org.junit.jupiter.api.io.TempDir; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import org.springframework.core.io.ClassPathResource; -import org.springframework.core.io.Resource; import org.w3c.dom.Document; import org.w3c.dom.Element; import org.w3c.dom.NodeList; @@ -120,10 +118,6 @@ public class DspaceMetadataDomWriterTest { @TempDir private Path tempDir; - private List custodialContent = Arrays.asList( - new ClassPathResource(this.getClass().getPackage().getName().replace(".", "/") + "/manuscript.txt"), - new ClassPathResource(this.getClass().getPackage().getName().replace(".", "/") + "/figure.jpg")); - private final DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); private DspaceMetadataDomWriter underTest; @@ -229,7 +223,7 @@ public void writeSampleMets() throws Exception { when(journal.getJournalTitle()).thenReturn("American Journal of XYZ Research"); when(journal.getJournalId()).thenReturn("Am J of XYZ Res"); when(journal.getPublisherName()).thenReturn("Super Publisher"); - when(journal.getPublicationDate()).thenReturn("2018-09-12"); + when(journal.getPublicationDate()).thenReturn(ZonedDateTime.now()); underTest.addResource(r); underTest.addSubmission(submission); @@ -296,8 +290,6 @@ public void testAddResource() throws Exception { String type = "text/plain"; String checksumMd5Val = "abcdef12345"; String checksumMd5 = Checksum.OPTS.MD5.name(); - String checksumShaVal = "123456abcdef"; - String checksumSha = Checksum.OPTS.SHA256.name(); PackageStream.Checksum checksum = mock(PackageStream.Checksum.class); when(checksum.algorithm()).thenReturn(Checksum.OPTS.MD5); @@ -448,8 +440,7 @@ public void testCreateDublinCoreMetadata() throws Exception { DepositMetadata.Journal jMd = mock(DepositMetadata.Journal.class); String publisherName = "Big Publisher"; when(jMd.getPublisherName()).thenReturn(publisherName); - String publicationDate = "1/9/1919"; - when(jMd.getPublicationDate()).thenReturn(publicationDate); + when(jMd.getPublicationDate()).thenReturn(ZonedDateTime.now()); DepositMetadata md = mock(DepositMetadata.class); when(md.getArticleMetadata()).thenReturn(artMd); diff --git a/pass-deposit-services/deposit-core/src/test/java/org/eclipse/pass/deposit/provider/j10p/MetadataIT.java b/pass-deposit-services/deposit-core/src/test/java/org/eclipse/pass/deposit/provider/j10p/MetadataIT.java index 3d7432408..29ea14301 100644 --- a/pass-deposit-services/deposit-core/src/test/java/org/eclipse/pass/deposit/provider/j10p/MetadataIT.java +++ b/pass-deposit-services/deposit-core/src/test/java/org/eclipse/pass/deposit/provider/j10p/MetadataIT.java @@ -51,7 +51,7 @@ public class MetadataIT extends AbstractDepositSubmissionIT { " },\n {\n \"author\": \"Mary Beth Lacey\"\n }\n ],\n \"agreements\": {\n " + "\"JScholarship\": \"Text removed.\"\n },\n \"title\": \"My Test Article\",\n \"journal-title\": " + "\"Nature Communications\",\n \"issns\": [\n {\n \"issn\": \"2041-1723\",\n \"pubType\": " + - "\"Print\"\n }\n ],\n \"publisher\": \"Elsevier\",\n \"publicationDate\": \"Fall 2016\",\n " + + "\"Print\"\n }\n ],\n \"publisher\": \"Elsevier\",\n \"publicationDate\": \"2001-03-05\",\n " + "\"abstract\": \"Abstract text\",\n \"journal-NLMTA-ID\": \"Nat Commun\",\n \"agent_information\": " + "{\n \"name\": \"Chrome\",\n \"version\": \"69\"\n }\n}"; @@ -61,7 +61,7 @@ public class MetadataIT extends AbstractDepositSubmissionIT { "\"JScholarship\": \"Text removed.\"\n },\n \"title\": \"My Test Article\",\n \"journal-title\": " + "\"Nature Communications\",\n \"issns\": [\n {\n \"issn\": \"2041-1723\",\n " + "\"pubType\": \"Print\"\n }\n ],\n \"publisher\": \"Elsevier\",\n \"publicationDate\": " + - "\"Fall 2016\",\n \"abstract\": \"Abstract text\",\n \"journal-NLMTA-ID\": \"Nat Commun\",\n " + + "\"2020-05-06\",\n \"abstract\": \"Abstract text\",\n \"journal-NLMTA-ID\": \"Nat Commun\",\n " + "\"agent_information\": {\n \"name\": \"Chrome\",\n \"version\": \"69\"\n }\n}"; @Autowired private SubmissionTestUtil submissionTestUtil; @@ -96,7 +96,7 @@ public void commonContributorsAndFewAuthors() throws Exception { // In citation, list up to three authors. Take publication date from "common" if not in "crossref". assertNotNull(qdc.getElementsByTagNameNS(DCTERMS_NS, DCT_BIBLIOCITATION).item(0).getTextContent()); - assertEquals("Christine Cagney, Mary Beth Lacey. (Fall 2016). \"My Test Article.\" Nature Communications.", + assertEquals("Christine Cagney, Mary Beth Lacey. (2001-03-05). \"My Test Article.\" Nature Communications.", qdc.getElementsByTagNameNS(DCTERMS_NS, DCT_BIBLIOCITATION).item(0).getTextContent()); } @@ -116,7 +116,7 @@ public void crossrefAndManyAuthors() throws Exception { // Publication date in "crossref" has precedence over one in "common". assertNotNull(qdc.getElementsByTagNameNS(DCTERMS_NS, DCT_BIBLIOCITATION).item(0).getTextContent()); assertEquals( - "Christine Cagney, Mary Beth Lacey, David Michael Starsky, et al. (Fall 2016). \"My Test Article.\" " + + "Christine Cagney, Mary Beth Lacey, David Michael Starsky, et al. (2020-05-06). \"My Test Article.\" " + "Nature Communications.", qdc.getElementsByTagNameNS(DCTERMS_NS, DCT_BIBLIOCITATION).item(0).getTextContent()); } diff --git a/pass-deposit-services/deposit-model/src/main/java/org/eclipse/pass/deposit/model/DepositMetadata.java b/pass-deposit-services/deposit-model/src/main/java/org/eclipse/pass/deposit/model/DepositMetadata.java index f95ff630a..c0761b4e0 100644 --- a/pass-deposit-services/deposit-model/src/main/java/org/eclipse/pass/deposit/model/DepositMetadata.java +++ b/pass-deposit-services/deposit-model/src/main/java/org/eclipse/pass/deposit/model/DepositMetadata.java @@ -237,7 +237,7 @@ public static class Journal { /** * Date of publication */ - public String publicationDate; + public ZonedDateTime publicationDate; /** * ISSN mapped to journal publication type @@ -302,14 +302,14 @@ public void setPublisherName(String publisherName) { /** * @return {@link #publicationDate} */ - public String getPublicationDate() { + public ZonedDateTime getPublicationDate() { return publicationDate; } /** * @param publicationDate {@link #publicationDate} */ - public void setPublicationDate(String publicationDate) { + public void setPublicationDate(ZonedDateTime publicationDate) { this.publicationDate = publicationDate; }