diff --git a/pass-deposit-services/deposit-core/src/main/java/org/eclipse/pass/deposit/provider/nihms/NihmsAssembler.java b/pass-deposit-services/deposit-core/src/main/java/org/eclipse/pass/deposit/provider/nihms/NihmsAssembler.java index 602de4e9..d999c0e1 100644 --- a/pass-deposit-services/deposit-core/src/main/java/org/eclipse/pass/deposit/provider/nihms/NihmsAssembler.java +++ b/pass-deposit-services/deposit-core/src/main/java/org/eclipse/pass/deposit/provider/nihms/NihmsAssembler.java @@ -18,12 +18,10 @@ import static org.eclipse.pass.deposit.assembler.AssemblerSupport.buildMetadata; -import java.net.URI; import java.time.ZonedDateTime; import java.time.format.DateTimeFormatter; import java.util.List; import java.util.Map; -import java.util.UUID; import org.eclipse.pass.deposit.assembler.AbstractAssembler; import org.eclipse.pass.deposit.assembler.ArchivingPackageStream; @@ -45,7 +43,7 @@ public class NihmsAssembler extends AbstractAssembler { * Package specification URI identifying the NIHMS native packaging spec, as specified by their 07/2017 * bulk publishing pdf. */ - public static final String SPEC_NIHMS_NATIVE_2017_07 = "nihms-native-2017-07"; + public static final String SPEC_NIHMS_NATIVE_2022_05 = "nihms-native-2022-05"; /** * Mime type of zip files. @@ -81,20 +79,11 @@ protected PackageStream createPackageStream(DepositSubmission submission, } static void namePackage(DepositSubmission submission, MetadataBuilder mb) { - String submissionUuid = null; - - try { - URI submissionUri = URI.create(submission.getId()); - submissionUuid = submissionUri.getPath().substring(submissionUri.getPath().lastIndexOf("/") + 1); - } catch (Exception e) { - submissionUuid = UUID.randomUUID().toString(); - } - String packageFileName = String.format(PACKAGE_FILE_NAME, - SPEC_NIHMS_NATIVE_2017_07, + SPEC_NIHMS_NATIVE_2022_05, ZonedDateTime.now() .format(DateTimeFormatter.ofPattern("uuuu-MM-dd_HH-MM-ss")), - submissionUuid); + submission.getId()); StringBuilder ext = new StringBuilder(packageFileName); PackageStream.Metadata md = mb.build(); diff --git a/pass-deposit-services/deposit-core/src/main/java/org/eclipse/pass/deposit/provider/nihms/NihmsMetadataSerializer.java b/pass-deposit-services/deposit-core/src/main/java/org/eclipse/pass/deposit/provider/nihms/NihmsMetadataSerializer.java index 391e63ed..67700fd6 100644 --- a/pass-deposit-services/deposit-core/src/main/java/org/eclipse/pass/deposit/provider/nihms/NihmsMetadataSerializer.java +++ b/pass-deposit-services/deposit-core/src/main/java/org/eclipse/pass/deposit/provider/nihms/NihmsMetadataSerializer.java @@ -17,30 +17,34 @@ package org.eclipse.pass.deposit.provider.nihms; import java.io.ByteArrayOutputStream; +import java.time.LocalDate; +import java.time.Period; import java.util.Arrays; import java.util.List; +import javax.xml.parsers.DocumentBuilderFactory; +import javax.xml.parsers.ParserConfigurationException; +import javax.xml.transform.OutputKeys; +import javax.xml.transform.Transformer; +import javax.xml.transform.TransformerException; +import javax.xml.transform.TransformerFactory; +import javax.xml.transform.dom.DOMSource; +import javax.xml.transform.stream.StreamResult; -import com.thoughtworks.xstream.XStream; -import com.thoughtworks.xstream.converters.Converter; -import com.thoughtworks.xstream.converters.MarshallingContext; -import com.thoughtworks.xstream.converters.UnmarshallingContext; -import com.thoughtworks.xstream.io.HierarchicalStreamReader; -import com.thoughtworks.xstream.io.HierarchicalStreamWriter; -import com.thoughtworks.xstream.io.xml.DomDriver; -import com.thoughtworks.xstream.io.xml.XmlFriendlyNameCoder; import org.eclipse.pass.deposit.assembler.SizedStream; import org.eclipse.pass.deposit.model.DepositMetadata; import org.eclipse.pass.deposit.model.JournalPublicationType; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import org.w3c.dom.Document; +import org.w3c.dom.Element; /** - * XML serialization of our NihmsMetadata to conform with the bulk submission dtd + * XML serialization of our NihmsMetadata to conform with the bulk submission + * dtd * * @author Jim Martino (jrm@jhu.edu) */ public class NihmsMetadataSerializer implements StreamingSerializer { - private static final Logger LOG = LoggerFactory.getLogger(NihmsMetadataSerializer.class); private DepositMetadata metadata; @@ -49,169 +53,164 @@ public NihmsMetadataSerializer(DepositMetadata metadata) { this.metadata = metadata; } + @Override public SizedStream serialize() { - XStream xstream = new XStream(new DomDriver("UTF-8", new XmlFriendlyNameCoder("_-", "_"))); - ByteArrayOutputStream os = new ByteArrayOutputStream(); - xstream.registerConverter(new MetadataConverter()); - xstream.alias("nihms-submit", DepositMetadata.class); - xstream.toXML(metadata, os); + try { + Document doc = DocumentBuilderFactory.newDefaultInstance().newDocumentBuilder().newDocument(); + + write_metadata(doc); + + Transformer transformer = TransformerFactory.newInstance().newTransformer(); + transformer.setOutputProperty(OutputKeys.ENCODING, "UTF-8"); + transformer.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, "yes"); + transformer.setOutputProperty(OutputKeys.INDENT, "yes"); + + ByteArrayOutputStream os = new ByteArrayOutputStream(); + transformer.transform(new DOMSource(doc), new StreamResult(os)); - return NihmsAssemblerUtil.asSizedStream(os); + return NihmsAssemblerUtil.asSizedStream(os); + } catch (ParserConfigurationException | TransformerException e) { + throw new RuntimeException("Failed to serialize nihms metadata", e); + } } - private class MetadataConverter implements Converter { - @SuppressWarnings("rawtypes") - public boolean canConvert(Class clazz) { - return DepositMetadata.class == clazz; + private void add_text_element(Document doc, Element parent, String name, String text, String attr, + String attr_value) { + if (text != null) { + Element el = doc.createElement(name); + parent.appendChild(el); + el.setTextContent(text); + + if (attr != null && attr_value != null) { + el.setAttribute(attr, attr_value); + } } + } - public void marshal(Object value, HierarchicalStreamWriter writer, - MarshallingContext context) { - DepositMetadata metadata = (DepositMetadata) value; - - //process manuscript element (except, strangely, for title, which we do after journal) - DepositMetadata.Manuscript manuscript = metadata.getManuscriptMetadata(); - DepositMetadata.Article article = metadata.getArticleMetadata(); - if (manuscript != null) { - writer.startNode("manuscript"); - if (manuscript.getNihmsId() != null) { - writer.addAttribute("id", manuscript.getNihmsId()); - } + private void add_text_element(Document doc, Element parent, String name, String text) { + add_text_element(doc, parent, name, text, null, null); + } - //primitive types - writer.addAttribute("publisher_pdf", booleanConvert(manuscript.isPublisherPdf())); - writer.addAttribute("show_publisher_pdf", booleanConvert(manuscript.isShowPublisherPdf())); - if (metadata.getArticleMetadata() != null && metadata.getArticleMetadata() - .getEmbargoLiftDate() != null) { - // todo: resolve the calculation of the embargo offset - } + private void write_metadata(Document doc) { + DepositMetadata.Manuscript manuscript = metadata.getManuscriptMetadata(); + DepositMetadata.Article article = metadata.getArticleMetadata(); + DepositMetadata.Journal journal = metadata.getJournalMetadata(); - if (manuscript.getManuscriptUrl() != null) { - writer.addAttribute("href", manuscript.getManuscriptUrl().toString()); - } - if (article != null && article.getDoi() != null) { - // DOI may not include UTI's scheme or host, only path - String path = article.getDoi().getPath(); - if (path.startsWith("/")) { - path = path.substring(1); - } - writer.addAttribute("doi", path); + Element root = doc.createElement("manuscript-submit"); + doc.appendChild(root); + + if (manuscript.getNihmsId() != null) { + root.setAttribute("manuscript-id", manuscript.getNihmsId()); + } + + if (article != null && metadata.getArticleMetadata().getEmbargoLiftDate() != null) { + LocalDate lift = article.getEmbargoLiftDate().toLocalDate(); + LocalDate now = LocalDate.now(); + + if (lift.isAfter(now)) { + long months = Period.between(LocalDate.now(), lift).toTotalMonths(); + + // The max embargo time is 12 months + if (months > 12) { + months = 12; } - writer.endNode(); //end manuscript + root.setAttribute("embargo-months", "" + months); } + } - //process journal - DepositMetadata.Journal journal = metadata.getJournalMetadata(); - if (journal != null) { - writer.startNode("journal-meta"); - if (journal.getJournalId() != null) { - writer.startNode("journal-id"); - if (journal.getJournalType() != null) { - writer.addAttribute("journal-id-type", journal.getJournalType()); - } - writer.setValue(journal.getJournalId()); - writer.endNode(); + if (article != null && article.getDoi() != null) { + // DOI may not include UTI's scheme or host, only path + String path = article.getDoi().getPath(); + if (path.startsWith("/")) { + path = path.substring(1); + } + + root.setAttribute("doi", path); + } + + // There is an optional agency attribute. + // Should only be used for non-NIH funders when grant information is also given + + if (journal != null) { + Element journal_meta = doc.createElement("journal-meta"); + root.appendChild(journal_meta); + + add_text_element(doc, journal_meta, "nlm-ta", journal.getJournalId()); + + // If the IssnPubType is incomplete (either the pubType or issn is null or + // empty), we should omit it from the metadata, per NIH's requirements. + // See https://github.com/OA-PASS/metadata-schemas/pull/28 and + // https://github.com/OA-PASS/jhu-package-providers/issues/16 + journal.getIssnPubTypes().values().forEach(issnPubType -> { + if (issnPubType.pubType == null || issnPubType.issn == null || issnPubType.issn.trim().isEmpty()) { + LOG.debug("Discarding incomplete ISSN: {}", issnPubType); + return; } - journal.getIssnPubTypes().values().forEach(issnPubType -> { - // if the IssnPubType is incomplete (either the pubType or issn is null or empty), we should - // omit it from the metadata, per NIH's requirements - // See https://github.com/OA-PASS/metadata-schemas/pull/28 and - // https://github.com/OA-PASS/jhu-package-providers/issues/16 - if (issnPubType.pubType == null || issnPubType.issn == null || issnPubType.issn.trim().isEmpty()) { - LOG.debug("Discarding incomplete ISSN: {}", issnPubType); - return; - } - writer.startNode("issn"); - // The JournalPublicationType OPUB should be translated to JournalPublicationType EPUB to stay - // valid with respect to the NIHMS metadata schema - if (issnPubType.pubType == JournalPublicationType.OPUB) { - writer.addAttribute("pub-type", JournalPublicationType.EPUB.name().toLowerCase()); - } else { - writer.addAttribute("pub-type", issnPubType.pubType.name().toLowerCase()); - } - writer.setValue(issnPubType.issn); - writer.endNode(); - }); - - if (journal.getJournalTitle() != null) { - writer.startNode("journal-title"); - writer.setValue(journal.getJournalTitle()); - writer.endNode(); + if (issnPubType.pubType == JournalPublicationType.PPUB) { + add_text_element(doc, journal_meta, "issn", issnPubType.issn, "issn-type", "print"); + } else if (issnPubType.pubType == JournalPublicationType.EPUB + || issnPubType.pubType == JournalPublicationType.OPUB) { + add_text_element(doc, journal_meta, "issn", issnPubType.issn, "issn-type", "electronic"); } - writer.endNode(); //end journal-meta - } + }); - //now process full manuscript title - if (manuscript != null && manuscript.getTitle() != null) { - writer.startNode("title"); - writer.setValue(manuscript.getTitle()); - writer.endNode(); - } + add_text_element(doc, journal_meta, "journal-title", journal.getJournalTitle()); + } - //process contacts - List persons = metadata.getPersons(); - if (persons != null && persons.size() > 0) { - writer.startNode("contacts"); - for (DepositMetadata.Person person : persons) { - // There should be exactly one corresponding PI per deposit. - if (person.getType() == DepositMetadata.PERSON_TYPE.submitter) { - writer.startNode("person"); - if (person.getFirstName() != null) { - writer.addAttribute("fname", person.getFirstName()); - } else { - if (person.getFullName() != null) { - writer.addAttribute("fname", person.getFullName().split("\\s")[0]); - } - } - if (person.getMiddleName() != null) { - writer.addAttribute("mname", person.getMiddleName()); + if (manuscript != null && manuscript.title != null) { + add_text_element(doc, root, "manuscript-title", manuscript.title); + } + + // Could add a citation element if we had all the information + + List persons = metadata.getPersons(); + + if (persons != null && persons.size() > 0) { + Element contacts = doc.createElement("contacts"); + root.appendChild(contacts); + + for (DepositMetadata.Person person : persons) { + // There should be exactly one corresponding PI per deposit. + if (person.getType() == DepositMetadata.PERSON_TYPE.submitter) { + Element p = doc.createElement("person"); + contacts.appendChild(p); + + if (person.getFirstName() != null) { + p.setAttribute("fname", person.getFirstName()); + } else { + if (person.getFullName() != null) { + p.setAttribute("fname", person.getFullName().split("\\s")[0]); } - if (person.getLastName() != null) { - writer.addAttribute("lname", person.getLastName()); - } else { - if (person.getFullName() != null) { - String[] split = person.getFullName().split("\\s"); - if (split.length > 2) { - // middle name is present - writer.addAttribute("lname", - String.join(" ", Arrays.copyOfRange(split, 2, split.length))); - } else { - writer.addAttribute("lname", split[1]); - } + } + if (person.getMiddleName() != null) { + p.setAttribute("mname", person.getMiddleName()); + } + if (person.getLastName() != null) { + p.setAttribute("lname", person.getLastName()); + } else { + if (person.getFullName() != null) { + String[] split = person.getFullName().split("\\s"); + if (split.length > 2) { + // middle name is present + p.setAttribute("lname", + String.join(" ", Arrays.copyOfRange(split, 2, split.length))); + } else { + p.setAttribute("lname", split[1]); } } - if (person.getEmail() != null) { - writer.addAttribute("email", person.getEmail()); - } - //primitive types - writer.addAttribute("corrpi", booleanConvert(true)); - writer.addAttribute("pi", booleanConvert(true)); - // Searching for another Person who matches this one and who is an AUTHOR - // would be difficult due to name variations, so do not output that attribute. - writer.endNode(); // end person - break; // Make sure we only write one person to the metadata } + if (person.getEmail() != null) { + p.setAttribute("email", person.getEmail()); + } + + p.setAttribute("person-type", "author"); } - writer.endNode(); //end contacts } } - public Object unmarshal(HierarchicalStreamReader reader, - UnmarshallingContext context) { - return null; - } - } - - /** - * Method to convert boolean into yes or no - * - * @param b the boolean to convert - * @return yes if true, no if false - */ - String booleanConvert(boolean b) { - return (b ? "yes" : "no"); + // Could add grant information here if it was useful. + // Can only be used for a set list of funders } - } diff --git a/pass-deposit-services/deposit-core/src/test/java/org/eclipse/pass/deposit/provider/nihms/NihmsAssemblerIT.java b/pass-deposit-services/deposit-core/src/test/java/org/eclipse/pass/deposit/provider/nihms/NihmsAssemblerIT.java index 280fe482..6b96194e 100644 --- a/pass-deposit-services/deposit-core/src/test/java/org/eclipse/pass/deposit/provider/nihms/NihmsAssemblerIT.java +++ b/pass-deposit-services/deposit-core/src/test/java/org/eclipse/pass/deposit/provider/nihms/NihmsAssemblerIT.java @@ -16,7 +16,7 @@ package org.eclipse.pass.deposit.provider.nihms; import static org.eclipse.pass.deposit.provider.nihms.NihmsAssembler.APPLICATION_GZIP; -import static org.eclipse.pass.deposit.provider.nihms.NihmsAssembler.SPEC_NIHMS_NATIVE_2017_07; +import static org.eclipse.pass.deposit.provider.nihms.NihmsAssembler.SPEC_NIHMS_NATIVE_2022_05; import static org.eclipse.pass.deposit.util.DepositTestUtil.asList; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertFalse; @@ -78,7 +78,7 @@ public void setUp() throws Exception { protected Map getOptions() { return new HashMap<>() { { - put(Spec.KEY, SPEC_NIHMS_NATIVE_2017_07); + put(Spec.KEY, SPEC_NIHMS_NATIVE_2022_05); put(Archive.KEY, Archive.OPTS.TAR); put(Compression.KEY, Compression.OPTS.GZIP); } @@ -101,7 +101,7 @@ protected void verifyStreamMetadata(PackageStream.Metadata metadata) { assertEquals(Compression.OPTS.GZIP, metadata.compression()); assertEquals(Archive.OPTS.TAR, metadata.archive()); assertTrue(metadata.archived()); - assertEquals(SPEC_NIHMS_NATIVE_2017_07, metadata.spec()); + assertEquals(SPEC_NIHMS_NATIVE_2022_05, metadata.spec()); assertEquals(APPLICATION_GZIP, metadata.mimeType()); } @@ -205,10 +205,10 @@ public void testPackageMetadata() throws Exception { // root element is Element root = metaDom.getDocumentElement(); - assertEquals("nihms-submit", root.getTagName()); + assertEquals("manuscript-submit", root.getTagName()); - // required element is present with the manuscript title as the value - Element title = asList(root.getElementsByTagName("title")).get(0); + // required <manuscript-title> element is present with the manuscript title as the value + Element title = asList(root.getElementsByTagName("manuscript-title")).get(0); assertEquals(submission.getMetadata().getManuscriptMetadata().getTitle(), title.getTextContent()); // Insure that only one <person> element is present in the submission metadata @@ -242,8 +242,7 @@ public void testPackageMetadata() throws Exception { }); // Assert that the DOI is present in the metadata - Element ms = asList(root.getElementsByTagName("manuscript")).get(0); - assertEquals(submission.getMetadata().getArticleMetadata().getDoi().toString(), ms.getAttribute("doi")); + assertEquals(submission.getMetadata().getArticleMetadata().getDoi().toString(), root.getAttribute("doi")); // Assert that the ISSNs are present in the metadata as the <issn> element List<Element> issns = asList(root.getElementsByTagName("issn")); @@ -255,10 +254,10 @@ public void testPackageMetadata() throws Exception { issns.forEach(issn -> assertTrue(issnPubTypes.containsKey(issn.getTextContent()))); issns.forEach(issn -> { DepositMetadata.IssnPubType pubType = issnPubTypes.get(issn.getTextContent()); - if (pubType.pubType == JournalPublicationType.OPUB) { - assertEquals(issn.getAttribute("pub-type"), JournalPublicationType.EPUB.name().toLowerCase()); + if (pubType.pubType == JournalPublicationType.OPUB || pubType.pubType == JournalPublicationType.EPUB) { + assertEquals(issn.getAttribute("issn-type"), "electronic"); } else { - assertEquals(issn.getAttribute("pub-type"), pubType.pubType.name().toLowerCase()); + assertEquals(issn.getAttribute("issn-type"), "print"); } }); diff --git a/pass-deposit-services/deposit-core/src/test/java/org/eclipse/pass/deposit/provider/nihms/NihmsAssemblerTest.java b/pass-deposit-services/deposit-core/src/test/java/org/eclipse/pass/deposit/provider/nihms/NihmsAssemblerTest.java index 7686d3b9..12572bd5 100644 --- a/pass-deposit-services/deposit-core/src/test/java/org/eclipse/pass/deposit/provider/nihms/NihmsAssemblerTest.java +++ b/pass-deposit-services/deposit-core/src/test/java/org/eclipse/pass/deposit/provider/nihms/NihmsAssemblerTest.java @@ -55,7 +55,7 @@ public void setUp() throws Exception { mdBuilder = mock(MetadataBuilder.class); String expectedSubmissionUuid = UUID.randomUUID().toString(); - when(submission.getId()).thenReturn("http://example.org/" + expectedSubmissionUuid); + when(submission.getId()).thenReturn(expectedSubmissionUuid); when(mdBuilder.build()).thenReturn(metadata); diff --git a/pass-deposit-services/deposit-core/src/test/java/org/eclipse/pass/deposit/provider/nihms/NihmsMetadataSerializerTest.java b/pass-deposit-services/deposit-core/src/test/java/org/eclipse/pass/deposit/provider/nihms/NihmsMetadataSerializerTest.java index 73bada13..772d1860 100644 --- a/pass-deposit-services/deposit-core/src/test/java/org/eclipse/pass/deposit/provider/nihms/NihmsMetadataSerializerTest.java +++ b/pass-deposit-services/deposit-core/src/test/java/org/eclipse/pass/deposit/provider/nihms/NihmsMetadataSerializerTest.java @@ -31,6 +31,7 @@ import java.net.URI; import java.net.URL; import java.nio.file.Path; +import java.time.ZonedDateTime; import java.util.ArrayList; import java.util.HashMap; import java.util.List; @@ -42,6 +43,7 @@ import javax.xml.parsers.ParserConfigurationException; import javax.xml.transform.stream.StreamSource; +import com.github.jknack.handlebars.internal.Files; import org.apache.commons.io.IOUtils; import org.eclipse.pass.deposit.assembler.SizedStream; import org.eclipse.pass.deposit.model.DepositMetadata; @@ -101,6 +103,7 @@ public void setup() throws Exception { // populate article metadata article.setDoi(URI.create("10.1234/smh0000001")); + article.setEmbargoLiftDate(ZonedDateTime.now().plusYears(100)); //populate persons DepositMetadata.Person person1 = new DepositMetadata.Person(); @@ -113,8 +116,8 @@ public void setup() throws Exception { // Enter the first person twice, as both an author and a PI DepositMetadata.Person person1a = new DepositMetadata.Person(person1); - person1.setType(DepositMetadata.PERSON_TYPE.pi); - personList.add(person1); + person1a.setType(DepositMetadata.PERSON_TYPE.pi); + personList.add(person1a); DepositMetadata.Person person2 = new DepositMetadata.Person(); person2.setType(DepositMetadata.PERSON_TYPE.submitter); @@ -160,7 +163,7 @@ public void testSerializedMetadataValidity() throws Exception { OutputStream os = new FileOutputStream(targetFile); os.write("<?xml version=\"1.0\" encoding=\"utf-8\"?>\n".getBytes()); - os.write("<!DOCTYPE nihms-submit SYSTEM \"bulksubmission.dtd\">\n".getBytes()); + os.write("<!DOCTYPE manuscript-submit SYSTEM \"bulksubmission.dtd\">\n".getBytes()); os.write(buffer); os.close(); @@ -170,6 +173,15 @@ public void testSerializedMetadataValidity() throws Exception { v.setSchemaSource(dtd); StreamSource s = new StreamSource(targetFile); ValidationResult r = v.validateInstance(s); + + if (!r.isValid()) { + System.err.println(Files.read(targetFile, UTF_8)); + + r.getProblems().forEach(p -> { + System.err.println(p); + }); + } + assertTrue(r.isValid()); } @@ -186,7 +198,7 @@ public void testSerializedMetadataDoi() throws Exception { metadata.getArticleMetadata().setDoi(URI.create(path)); sizedStream = underTest.serialize(); is = sizedStream.getInputStream(); - node = builder.parse(is).getDocumentElement().getFirstChild().getNextSibling(); + node = builder.parse(is).getDocumentElement(); doi = node.getAttributes().getNamedItem("doi").getTextContent(); is.close(); assertTrue(doi.contentEquals(path)); @@ -194,7 +206,7 @@ public void testSerializedMetadataDoi() throws Exception { metadata.getArticleMetadata().setDoi(URI.create("http://dx.doi.org/" + path)); sizedStream = underTest.serialize(); is = sizedStream.getInputStream(); - node = builder.parse(is).getDocumentElement().getFirstChild().getNextSibling(); + node = builder.parse(is).getDocumentElement(); doi = node.getAttributes().getNamedItem("doi").getTextContent(); is.close(); assertTrue(doi.contentEquals(path)); @@ -208,9 +220,7 @@ public void completeIssnPubtype() throws IOException, ParserConfigurationExcepti DepositMetadata metadata = new DepositMetadata(); DepositMetadata.Journal journalMd = new DepositMetadata.Journal(); String expectedIssn = "foo"; - String expectedPubType = JournalPublicationType.EPUB.name() - .toLowerCase(); // remember OPUB is mapped to EPUB when - // serializing + String expectedPubType = "electronic"; DepositMetadata.IssnPubType issn = new DepositMetadata.IssnPubType(expectedIssn, JournalPublicationType.OPUB); journalMd.setIssnPubTypes(new HashMap<>() { @@ -236,7 +246,7 @@ public void completeIssnPubtype() throws IOException, ParserConfigurationExcepti new RuntimeException( "Missing expected <issn> element for " + expectedIssn + " and " + expectedPubType)); - assertEquals(expectedPubType, actualIssn.getAttributes().getNamedItem("pub-type").getNodeValue()); + assertEquals(expectedPubType, actualIssn.getAttributes().getNamedItem("issn-type").getNodeValue()); } /** diff --git a/pass-deposit-services/deposit-core/src/test/java/org/eclipse/pass/deposit/provider/nihms/NihmsThreadedAssemblyIT.java b/pass-deposit-services/deposit-core/src/test/java/org/eclipse/pass/deposit/provider/nihms/NihmsThreadedAssemblyIT.java index 4475065c..9ee2bbb5 100644 --- a/pass-deposit-services/deposit-core/src/test/java/org/eclipse/pass/deposit/provider/nihms/NihmsThreadedAssemblyIT.java +++ b/pass-deposit-services/deposit-core/src/test/java/org/eclipse/pass/deposit/provider/nihms/NihmsThreadedAssemblyIT.java @@ -16,7 +16,7 @@ package org.eclipse.pass.deposit.provider.nihms; import static java.util.Collections.singletonList; -import static org.eclipse.pass.deposit.provider.nihms.NihmsAssembler.SPEC_NIHMS_NATIVE_2017_07; +import static org.eclipse.pass.deposit.provider.nihms.NihmsAssembler.SPEC_NIHMS_NATIVE_2022_05; import java.util.HashMap; import java.util.Map; @@ -41,7 +41,7 @@ protected AbstractAssembler assemblerUnderTest() { protected Map<String, Object> packageOptions() { return new HashMap<>() { { - put(PackageOptions.Spec.KEY, SPEC_NIHMS_NATIVE_2017_07); + put(PackageOptions.Spec.KEY, SPEC_NIHMS_NATIVE_2022_05); put(PackageOptions.Archive.KEY, PackageOptions.Archive.OPTS.TAR); put(PackageOptions.Compression.KEY, PackageOptions.Compression.OPTS.GZIP); put(PackageOptions.Checksum.KEY, singletonList(PackageOptions.Checksum.OPTS.SHA256)); diff --git a/pass-deposit-services/deposit-core/src/test/resources/org/eclipse/pass/deposit/provider/nihms/bulksubmission.dtd b/pass-deposit-services/deposit-core/src/test/resources/org/eclipse/pass/deposit/provider/nihms/bulksubmission.dtd index 6e43c785..2c344e4b 100644 --- a/pass-deposit-services/deposit-core/src/test/resources/org/eclipse/pass/deposit/provider/nihms/bulksubmission.dtd +++ b/pass-deposit-services/deposit-core/src/test/resources/org/eclipse/pass/deposit/provider/nihms/bulksubmission.dtd @@ -1,127 +1,124 @@ -<!ELEMENT nihms-submit (manuscript?, journal-meta, (article-meta | permissions)?, title, contacts, disclaimer?, custom-meta-group?) > - <!ATTLIST nihms-submit - xmlns:xlink CDATA #FIXED 'http://www.w3.org/1999/xlink' - agency CDATA #IMPLIED > +<!ELEMENT manuscript-submit (journal-meta, manuscript-title, citation?, contacts, grants?, permissions?, disclaimer?, custom-meta-group?) > +<!ATTLIST manuscript-submit + agency CDATA #IMPLIED + manuscript-id CDATA #IMPLIED + embargo-months (0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12) #IMPLIED + pmid CDATA #IMPLIED + pmcid CDATA #IMPLIED + doi CDATA #IMPLIED + xmlns:xlink CDATA #FIXED 'http://www.w3.org/1999/xlink' +> +<!-- ================================================================ --> +<!-- JOURNAL METADATA information about the journal --> +<!-- ================================================================ --> +<!ELEMENT journal-meta ( (nlm-ta | issn), issn*, journal-title?) > - <!ELEMENT manuscript EMPTY> - <!ATTLIST manuscript - id CDATA #IMPLIED - publisher_pdf (yes|no) #IMPLIED - show_publisher_pdf (yes|no) #IMPLIED - embargo CDATA #IMPLIED - pmid CDATA #IMPLIED - pmcid CDATA #IMPLIED - href CDATA #IMPLIED - doi CDATA #IMPLIED +<!ELEMENT nlm-ta (#PCDATA) > <!-- Holds the NLM Title Abbreviation for the journal --> - > - <!-- embargo = count of months, 0 to 12 --> +<!ELEMENT issn (#PCDATA) > +<!ATTLIST issn + issn-type (print | electronic | linking) #REQUIRED > + +<!ELEMENT journal-title (#PCDATA) > - <!ELEMENT journal-meta ( (journal-id | issn), issn*, journal-title?) > - <!ELEMENT journal-id (#PCDATA) > - <!ATTLIST journal-id - journal-id-type (nlm-ta) #REQUIRED > - <!ELEMENT journal-title (#PCDATA) > - <!ELEMENT issn (#PCDATA) > - <!ATTLIST issn - pub-type (ppub|epub) #REQUIRED > +<!-- ================================================================ --> +<!-- CITATION information about the article --> +<!-- ================================================================ --> +<!ELEMENT manuscript-title (#PCDATA | sub| sup | b | i)* > - <!ELEMENT title (#PCDATA) > +<!ELEMENT citation (pub-date+, volume, issue, (fpage | elocation-id), lpage?, URL*) > - <!ELEMENT contacts (person+)> +<!ELEMENT pub-date ( ((day?, month?) | season?), year) > +<!ATTLIST pub-date + pub-date-type (issue | article) #REQUIRED > - <!ELEMENT person (grant*)> - <!ATTLIST person - fname CDATA #REQUIRED - mname CDATA #IMPLIED - lname CDATA #REQUIRED - email CDATA #IMPLIED - auth CDATA #IMPLIED - pi (yes|no) #IMPLIED - corrpi (yes|no) #IMPLIED - author (yes|no) #IMPLIED - agency CDATA #IMPLIED - center CDATA #IMPLIED - > +<!ELEMENT day (#PCDATA) > - <!ELEMENT grant EMPTY > - <!ATTLIST grant - id CDATA #IMPLIED - authority (nih|wt|hhmi|era|nasa) #REQUIRED - project CDATA #IMPLIED - > +<!ELEMENT month (#PCDATA) > - <!ELEMENT article-meta (article-id*, subj-group*, pub-date+, volume, issue, (fpage | elocation-id), lpage?, copyright-statement?, license?, self-uri*) > +<!ELEMENT season (#PCDATA) > - <!ELEMENT permissions (copyright-statement?, license?) > +<!ELEMENT year (#PCDATA) > - <!ELEMENT volume (#PCDATA) > +<!ELEMENT volume (#PCDATA) > - <!ELEMENT issue (#PCDATA) > +<!ELEMENT issue (#PCDATA) > - <!ELEMENT fpage (#PCDATA) > +<!ELEMENT fpage (#PCDATA) > - <!ELEMENT elocation-id (#PCDATA) > +<!ELEMENT elocation-id (#PCDATA) > - <!ELEMENT lpage (#PCDATA) > +<!ELEMENT lpage (#PCDATA) > - <!ELEMENT copyright-statement (#PCDATA) > +<!ELEMENT URL (#PCDATA) > +<!ATTLIST URL + url-type (citation | full-text) #REQUIRED> + + +<!-- ================================================================ --> +<!-- PERMISSIONS information about the ownership and use rights --> +<!-- ================================================================ --> +<!ELEMENT permissions (copyright-statement?) > - <!ELEMENT article-id (#PCDATA) > - <!ATTLIST article-id - pub-id-type (doi|pmid|pmcid|publisher-id) #REQUIRED > +<!ELEMENT copyright-statement (#PCDATA | sub| sup | b | i)* > - <!ELEMENT pub-date ( ((day?, month?) | season?), year) > - <!ATTLIST pub-date - pub-type (ppub|epub|epub-ppub|epreprint|collection) #REQUIRED > - <!-- use ppub for print publication, epub for electronic or online publication date --> +<!-- ================================================================ --> +<!-- CONTACT information about the people (at least one is required) --> +<!-- ================================================================ --> +<!ELEMENT contacts (person+)> - <!ELEMENT day (#PCDATA) > +<!ELEMENT person EMPTY> +<!ATTLIST person + fname CDATA #REQUIRED + mname CDATA #IMPLIED + lname CDATA #REQUIRED + email CDATA #REQUIRED + person-type (author | reviewer) #REQUIRED +> +<!ELEMENT grants (grant+)> - <!ELEMENT month (#PCDATA) > +<!ELEMENT grant (PI?) > +<!ATTLIST grant + id CDATA #IMPLIED + funder ( nih | ahrq | aspr | cdc | epa | fda | hhmi | nasa | nist | va ) #REQUIRED + center CDATA #IMPLIED +> - <!ELEMENT season (#PCDATA) > +<!ELEMENT PI EMPTY > +<!ATTLIST PI + fname CDATA #REQUIRED + lname CDATA #REQUIRED + email CDATA #IMPLIED + > + +<!ELEMENT custom-meta-group (custom-meta+)> + +<!ELEMENT custom-meta (#PCDATA | sub| sup | b | i)* > +<!ATTLIST custom-meta + name CDATA #REQUIRED> - <!ELEMENT year (#PCDATA) > - <!ELEMENT license (p) > - <!ATTLIST license - license-type CDATA #IMPLIED - xlink:href CDATA #IMPLIED - > +<!ELEMENT disclaimer (#PCDATA | sub| sup | b | i)* > - <!ELEMENT self-uri EMPTY> - <!ATTLIST self-uri - xlink:href CDATA #REQUIRED - xmlns:xlink CDATA #IMPLIED - content-type CDATA #IMPLIED - > +<!-- ================================================================ --> +<!-- FORMATTING --> +<!-- ================================================================ --> +<!ELEMENT sub (#PCDATA | sub| sup | b | i)* > <!-- subscript --> - <!ELEMENT custom-meta-group (custom-meta+)> +<!ELEMENT sup (#PCDATA | sub| sup | b | i)* > <!-- superscript --> - <!ELEMENT custom-meta (#PCDATA) > - <!ATTLIST custom-meta - name CDATA #REQUIRED> +<!ELEMENT b (#PCDATA | sub| sup | b | i)* > <!-- boldface --> - <!ELEMENT p (#PCDATA|uri)* > +<!ELEMENT i (#PCDATA | sub| sup | b | i)* > <!-- italic --> - <!ELEMENT uri (#PCDATA)> - <!ATTLIST uri - xlink:href CDATA #IMPLIED - href CDATA #IMPLIED - > - <!-- use subj-group and subject for TOC headings --> - <!ELEMENT subj-group (subject, subj-group?) > - <!ELEMENT subject (#PCDATA) > - <!ELEMENT disclaimer (#PCDATA) > diff --git a/pass-deposit-services/deposit-model/src/main/resources/nihms-bulksub-specs.dtd b/pass-deposit-services/deposit-model/src/main/resources/nihms-bulksub-specs.dtd index 6e43c785..2c344e4b 100644 --- a/pass-deposit-services/deposit-model/src/main/resources/nihms-bulksub-specs.dtd +++ b/pass-deposit-services/deposit-model/src/main/resources/nihms-bulksub-specs.dtd @@ -1,127 +1,124 @@ -<!ELEMENT nihms-submit (manuscript?, journal-meta, (article-meta | permissions)?, title, contacts, disclaimer?, custom-meta-group?) > - <!ATTLIST nihms-submit - xmlns:xlink CDATA #FIXED 'http://www.w3.org/1999/xlink' - agency CDATA #IMPLIED > +<!ELEMENT manuscript-submit (journal-meta, manuscript-title, citation?, contacts, grants?, permissions?, disclaimer?, custom-meta-group?) > +<!ATTLIST manuscript-submit + agency CDATA #IMPLIED + manuscript-id CDATA #IMPLIED + embargo-months (0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12) #IMPLIED + pmid CDATA #IMPLIED + pmcid CDATA #IMPLIED + doi CDATA #IMPLIED + xmlns:xlink CDATA #FIXED 'http://www.w3.org/1999/xlink' +> +<!-- ================================================================ --> +<!-- JOURNAL METADATA information about the journal --> +<!-- ================================================================ --> +<!ELEMENT journal-meta ( (nlm-ta | issn), issn*, journal-title?) > - <!ELEMENT manuscript EMPTY> - <!ATTLIST manuscript - id CDATA #IMPLIED - publisher_pdf (yes|no) #IMPLIED - show_publisher_pdf (yes|no) #IMPLIED - embargo CDATA #IMPLIED - pmid CDATA #IMPLIED - pmcid CDATA #IMPLIED - href CDATA #IMPLIED - doi CDATA #IMPLIED +<!ELEMENT nlm-ta (#PCDATA) > <!-- Holds the NLM Title Abbreviation for the journal --> - > - <!-- embargo = count of months, 0 to 12 --> +<!ELEMENT issn (#PCDATA) > +<!ATTLIST issn + issn-type (print | electronic | linking) #REQUIRED > + +<!ELEMENT journal-title (#PCDATA) > - <!ELEMENT journal-meta ( (journal-id | issn), issn*, journal-title?) > - <!ELEMENT journal-id (#PCDATA) > - <!ATTLIST journal-id - journal-id-type (nlm-ta) #REQUIRED > - <!ELEMENT journal-title (#PCDATA) > - <!ELEMENT issn (#PCDATA) > - <!ATTLIST issn - pub-type (ppub|epub) #REQUIRED > +<!-- ================================================================ --> +<!-- CITATION information about the article --> +<!-- ================================================================ --> +<!ELEMENT manuscript-title (#PCDATA | sub| sup | b | i)* > - <!ELEMENT title (#PCDATA) > +<!ELEMENT citation (pub-date+, volume, issue, (fpage | elocation-id), lpage?, URL*) > - <!ELEMENT contacts (person+)> +<!ELEMENT pub-date ( ((day?, month?) | season?), year) > +<!ATTLIST pub-date + pub-date-type (issue | article) #REQUIRED > - <!ELEMENT person (grant*)> - <!ATTLIST person - fname CDATA #REQUIRED - mname CDATA #IMPLIED - lname CDATA #REQUIRED - email CDATA #IMPLIED - auth CDATA #IMPLIED - pi (yes|no) #IMPLIED - corrpi (yes|no) #IMPLIED - author (yes|no) #IMPLIED - agency CDATA #IMPLIED - center CDATA #IMPLIED - > +<!ELEMENT day (#PCDATA) > - <!ELEMENT grant EMPTY > - <!ATTLIST grant - id CDATA #IMPLIED - authority (nih|wt|hhmi|era|nasa) #REQUIRED - project CDATA #IMPLIED - > +<!ELEMENT month (#PCDATA) > - <!ELEMENT article-meta (article-id*, subj-group*, pub-date+, volume, issue, (fpage | elocation-id), lpage?, copyright-statement?, license?, self-uri*) > +<!ELEMENT season (#PCDATA) > - <!ELEMENT permissions (copyright-statement?, license?) > +<!ELEMENT year (#PCDATA) > - <!ELEMENT volume (#PCDATA) > +<!ELEMENT volume (#PCDATA) > - <!ELEMENT issue (#PCDATA) > +<!ELEMENT issue (#PCDATA) > - <!ELEMENT fpage (#PCDATA) > +<!ELEMENT fpage (#PCDATA) > - <!ELEMENT elocation-id (#PCDATA) > +<!ELEMENT elocation-id (#PCDATA) > - <!ELEMENT lpage (#PCDATA) > +<!ELEMENT lpage (#PCDATA) > - <!ELEMENT copyright-statement (#PCDATA) > +<!ELEMENT URL (#PCDATA) > +<!ATTLIST URL + url-type (citation | full-text) #REQUIRED> + + +<!-- ================================================================ --> +<!-- PERMISSIONS information about the ownership and use rights --> +<!-- ================================================================ --> +<!ELEMENT permissions (copyright-statement?) > - <!ELEMENT article-id (#PCDATA) > - <!ATTLIST article-id - pub-id-type (doi|pmid|pmcid|publisher-id) #REQUIRED > +<!ELEMENT copyright-statement (#PCDATA | sub| sup | b | i)* > - <!ELEMENT pub-date ( ((day?, month?) | season?), year) > - <!ATTLIST pub-date - pub-type (ppub|epub|epub-ppub|epreprint|collection) #REQUIRED > - <!-- use ppub for print publication, epub for electronic or online publication date --> +<!-- ================================================================ --> +<!-- CONTACT information about the people (at least one is required) --> +<!-- ================================================================ --> +<!ELEMENT contacts (person+)> - <!ELEMENT day (#PCDATA) > +<!ELEMENT person EMPTY> +<!ATTLIST person + fname CDATA #REQUIRED + mname CDATA #IMPLIED + lname CDATA #REQUIRED + email CDATA #REQUIRED + person-type (author | reviewer) #REQUIRED +> +<!ELEMENT grants (grant+)> - <!ELEMENT month (#PCDATA) > +<!ELEMENT grant (PI?) > +<!ATTLIST grant + id CDATA #IMPLIED + funder ( nih | ahrq | aspr | cdc | epa | fda | hhmi | nasa | nist | va ) #REQUIRED + center CDATA #IMPLIED +> - <!ELEMENT season (#PCDATA) > +<!ELEMENT PI EMPTY > +<!ATTLIST PI + fname CDATA #REQUIRED + lname CDATA #REQUIRED + email CDATA #IMPLIED + > + +<!ELEMENT custom-meta-group (custom-meta+)> + +<!ELEMENT custom-meta (#PCDATA | sub| sup | b | i)* > +<!ATTLIST custom-meta + name CDATA #REQUIRED> - <!ELEMENT year (#PCDATA) > - <!ELEMENT license (p) > - <!ATTLIST license - license-type CDATA #IMPLIED - xlink:href CDATA #IMPLIED - > +<!ELEMENT disclaimer (#PCDATA | sub| sup | b | i)* > - <!ELEMENT self-uri EMPTY> - <!ATTLIST self-uri - xlink:href CDATA #REQUIRED - xmlns:xlink CDATA #IMPLIED - content-type CDATA #IMPLIED - > +<!-- ================================================================ --> +<!-- FORMATTING --> +<!-- ================================================================ --> +<!ELEMENT sub (#PCDATA | sub| sup | b | i)* > <!-- subscript --> - <!ELEMENT custom-meta-group (custom-meta+)> +<!ELEMENT sup (#PCDATA | sub| sup | b | i)* > <!-- superscript --> - <!ELEMENT custom-meta (#PCDATA) > - <!ATTLIST custom-meta - name CDATA #REQUIRED> +<!ELEMENT b (#PCDATA | sub| sup | b | i)* > <!-- boldface --> - <!ELEMENT p (#PCDATA|uri)* > +<!ELEMENT i (#PCDATA | sub| sup | b | i)* > <!-- italic --> - <!ELEMENT uri (#PCDATA)> - <!ATTLIST uri - xlink:href CDATA #IMPLIED - href CDATA #IMPLIED - > - <!-- use subj-group and subject for TOC headings --> - <!ELEMENT subj-group (subject, subj-group?) > - <!ELEMENT subject (#PCDATA) > - <!ELEMENT disclaimer (#PCDATA) >