diff --git a/doc/release-notes/12662-smaller-datacite-xml.md b/doc/release-notes/12662-smaller-datacite-xml.md new file mode 100644 index 00000000000..16f26c689fd --- /dev/null +++ b/doc/release-notes/12662-smaller-datacite-xml.md @@ -0,0 +1,4 @@ +Introduces a new JVM-option `dataverse.datacite.xml.datafile-info` that allows you to configure the number of `size` and `format` elements included in the +DataCite XML metadata. Valid options are `expanded` (default, the current behavior of including one `size` and one `format` element per datafile), `brief` +(one `size` element with the sum of all datafile sizes and one `format` element per unique datafile format), and `none` (no `size` or `format` elements included +in the DataCite XML metadata). See #12662 for details. diff --git a/doc/sphinx-guides/source/installation/config.rst b/doc/sphinx-guides/source/installation/config.rst index 360a96e8eb5..bc650a38b7f 100644 --- a/doc/sphinx-guides/source/installation/config.rst +++ b/doc/sphinx-guides/source/installation/config.rst @@ -848,6 +848,25 @@ Here are the configuration options for PermaLinks: You must restart Payara after making changes to these settings. +.. _datacite-settings: + +DataCite Settings +----------------- + +.. _dataverse.datacite.xml.datafile-info: + +dataverse.datacite.xml.datafile-info ++++++++++++++++++++++++++++++++++++++ + +``dataverse.datacite.xml.datafile-info`` controls how DataCite XML for datasets represents +datafile sizes and formats. The default value, ``expanded``, preserves the current behavior and emits +one ``size`` and one ``format`` element per datafile. Set the value to ``brief`` to emit a single +``size`` element with the sum of all known datafile sizes and one ``format`` element per distinct +datafile format. Set the value to ``none`` to omit datafile ``size`` and ``format`` elements entirely. +This setting applies to both the DataCite metadata export and to DataCite XML sent by the PID provider, +such as when publishing a new dataset version or explicitly updating PID-provider metadata for a +published dataset. + .. _auth-modes: Auth Modes: Local vs. Remote vs. Both diff --git a/src/main/java/edu/harvard/iq/dataverse/pidproviders/PidProviderFactoryBean.java b/src/main/java/edu/harvard/iq/dataverse/pidproviders/PidProviderFactoryBean.java index 267cbab3edd..ceac8e5b14c 100644 --- a/src/main/java/edu/harvard/iq/dataverse/pidproviders/PidProviderFactoryBean.java +++ b/src/main/java/edu/harvard/iq/dataverse/pidproviders/PidProviderFactoryBean.java @@ -174,10 +174,11 @@ private void loadProviders() { // Defaults for testing where no account is set up String dcUsername = JvmSettings.LEGACY_DATACITE_USERNAME.lookup(); String dcPassword = JvmSettings.LEGACY_DATACITE_PASSWORD.lookup(); + String datafileInfoMode = JvmSettings.DATACITE_XML_DATAFILE_INFO.lookupOptional().orElse("expanded"); if (mdsUrl != null && restUrl != null && dcUsername != null && dcPassword != null) { legacy = new DataCiteDOIProvider("legacy", "legacy", authority, shoulder, identifierGenerationStyle, dataFilePidFormat, "", "", mdsUrl, restUrl, dcUsername, - dcPassword); + dcPassword, datafileInfoMode); } break; case "FAKE": diff --git a/src/main/java/edu/harvard/iq/dataverse/pidproviders/doi/XmlMetadataTemplate.java b/src/main/java/edu/harvard/iq/dataverse/pidproviders/doi/XmlMetadataTemplate.java index 954ddc46f36..cb220213d04 100644 --- a/src/main/java/edu/harvard/iq/dataverse/pidproviders/doi/XmlMetadataTemplate.java +++ b/src/main/java/edu/harvard/iq/dataverse/pidproviders/doi/XmlMetadataTemplate.java @@ -16,6 +16,7 @@ import java.util.Date; import java.util.HashMap; import java.util.HashSet; +import java.util.LinkedHashSet; import java.util.List; import java.util.Map; import java.util.Optional; @@ -58,13 +59,43 @@ public class XmlMetadataTemplate { public static final String XML_XSI = "http://www.w3.org/2001/XMLSchema-instance"; public static final String XML_SCHEMA_VERSION = "4.7"; + public enum DatafileInfoMode { + EXPANDED("expanded"), + BRIEF("brief"), + NONE("none"); + + private final String value; + + DatafileInfoMode(String value) { + this.value = value; + } + + public static DatafileInfoMode from(String value) { + if (value != null) { + for (DatafileInfoMode mode : values()) { + if (mode.value.equalsIgnoreCase(value.trim())) { + return mode; + } + } + logger.warning("Unknown DataCite datafile info mode '" + value + "', using expanded"); + } + return EXPANDED; + } + } + private DoiMetadata doiMetadata; + private DatafileInfoMode datafileInfoMode = DatafileInfoMode.EXPANDED; public XmlMetadataTemplate() { } public XmlMetadataTemplate(DoiMetadata doiMetadata) { + this(doiMetadata, DatafileInfoMode.EXPANDED); + } + + public XmlMetadataTemplate(DoiMetadata doiMetadata, DatafileInfoMode datafileInfoMode) { this.doiMetadata = doiMetadata; + this.datafileInfoMode = datafileInfoMode; } public String generateXML(DvObject dvObject) { @@ -1192,19 +1223,35 @@ private static String getCanonicalPublicationType(String pubIdType) { private void writeSize(XMLStreamWriter xmlw, DvObject dvObject) throws XMLStreamException { // sizes -> size boolean sizesWritten = false; - List dataFiles = new ArrayList(); - - if (dvObject instanceof Dataset dataset) { - dataFiles = dataset.getFiles(); - } else if (dvObject instanceof DataFile df) { - dataFiles.add(df); + if (datafileInfoMode == DatafileInfoMode.NONE) { + return; + } + List dataFiles = getDataFiles(dvObject); + if (datafileInfoMode == DatafileInfoMode.BRIEF) { + long totalSize = 0L; + boolean hasKnownSize = false; + if (dataFiles != null && !dataFiles.isEmpty()) { + for (DataFile dataFile : dataFiles) { + long size = dataFile.getFilesize(); + if (size != -1) { + totalSize += size; + hasKnownSize = true; + } + } + } + if (hasKnownSize) { + xmlw.writeStartElement("sizes"); + XmlWriterUtil.writeFullElement(xmlw, "size", Long.toString(totalSize)); + xmlw.writeEndElement(); + } + return; } if (dataFiles != null && !dataFiles.isEmpty()) { for (DataFile dataFile : dataFiles) { - Long size = dataFile.getFilesize(); + long size = dataFile.getFilesize(); if (size != -1) { sizesWritten = XmlWriterUtil.writeOpenTagIfNeeded(xmlw, "sizes", sizesWritten); - XmlWriterUtil.writeFullElement(xmlw, "size", size.toString()); + XmlWriterUtil.writeFullElement(xmlw, "size", Long.toString(size)); } } } @@ -1217,12 +1264,28 @@ private void writeSize(XMLStreamWriter xmlw, DvObject dvObject) throws XMLStream private void writeFormats(XMLStreamWriter xmlw, DvObject dvObject) throws XMLStreamException { boolean formatsWritten = false; - List dataFiles = new ArrayList(); - - if (dvObject instanceof Dataset dataset) { - dataFiles = dataset.getFiles(); - } else if (dvObject instanceof DataFile df) { - dataFiles.add(df); + if (datafileInfoMode == DatafileInfoMode.NONE) { + return; + } + List dataFiles = getDataFiles(dvObject); + if (datafileInfoMode == DatafileInfoMode.BRIEF) { + Set uniqueFormats = new LinkedHashSet<>(); + if (dataFiles != null && !dataFiles.isEmpty()) { + for (DataFile dataFile : dataFiles) { + String format = dataFile.getContentType(); + if (StringUtils.isNotBlank(format)) { + uniqueFormats.add(format); + } + } + } + if (!uniqueFormats.isEmpty()) { + xmlw.writeStartElement("formats"); + for (String format : uniqueFormats) { + XmlWriterUtil.writeFullElement(xmlw, "format", format); + } + xmlw.writeEndElement(); + } + return; } if (dataFiles != null && !dataFiles.isEmpty()) { for (DataFile dataFile : dataFiles) { @@ -1245,6 +1308,16 @@ private void writeFormats(XMLStreamWriter xmlw, DvObject dvObject) throws XMLStr } + private List getDataFiles(DvObject dvObject) { + List dataFiles = new ArrayList<>(); + if (dvObject instanceof Dataset dataset) { + return dataset.getFiles() != null ? dataset.getFiles() : dataFiles; + } else if (dvObject instanceof DataFile df) { + dataFiles.add(df); + } + return dataFiles; + } + private void writeVersion(XMLStreamWriter xmlw, DvObject dvObject) throws XMLStreamException { Dataset d = null; if (dvObject instanceof Dataset) { diff --git a/src/main/java/edu/harvard/iq/dataverse/pidproviders/doi/datacite/DOIDataCiteRegisterService.java b/src/main/java/edu/harvard/iq/dataverse/pidproviders/doi/datacite/DOIDataCiteRegisterService.java index e106b4fca4f..0fb0d2bb2a3 100644 --- a/src/main/java/edu/harvard/iq/dataverse/pidproviders/doi/datacite/DOIDataCiteRegisterService.java +++ b/src/main/java/edu/harvard/iq/dataverse/pidproviders/doi/datacite/DOIDataCiteRegisterService.java @@ -23,6 +23,8 @@ import edu.harvard.iq.dataverse.pidproviders.AbstractPidProvider; import edu.harvard.iq.dataverse.pidproviders.doi.DoiMetadata; import edu.harvard.iq.dataverse.pidproviders.doi.XmlMetadataTemplate; +import edu.harvard.iq.dataverse.pidproviders.doi.XmlMetadataTemplate.DatafileInfoMode; +import edu.harvard.iq.dataverse.settings.JvmSettings; import org.xmlunit.builder.DiffBuilder; import org.xmlunit.builder.Input; @@ -58,8 +60,13 @@ public DOIDataCiteRegisterService(String url, String restApiUrl, String username * https://support.datacite.org/docs/mds-api-guide#doi-states */ public String reserveIdentifier(String identifier, Map metadata, DvObject dvObject) throws IOException { + return reserveIdentifier(identifier, metadata, dvObject, getConfiguredDatafileInfoMode()); + } + + public String reserveIdentifier(String identifier, Map metadata, DvObject dvObject, + DatafileInfoMode datafileInfoMode) throws IOException { String retString = ""; - String xmlMetadata = getMetadataFromDvObject(identifier, metadata, dvObject); + String xmlMetadata = getMetadataFromDvObject(identifier, metadata, dvObject, datafileInfoMode); retString = client.postMetadata(xmlMetadata); @@ -67,8 +74,13 @@ public String reserveIdentifier(String identifier, Map metadata, } public String registerIdentifier(String identifier, Map metadata, DvObject dvObject) throws IOException { + return registerIdentifier(identifier, metadata, dvObject, getConfiguredDatafileInfoMode()); + } + + public String registerIdentifier(String identifier, Map metadata, DvObject dvObject, + DatafileInfoMode datafileInfoMode) throws IOException { String retString = ""; - String xmlMetadata = getMetadataFromDvObject(identifier, metadata, dvObject); + String xmlMetadata = getMetadataFromDvObject(identifier, metadata, dvObject, datafileInfoMode); String target = metadata.get("_target"); retString = client.postMetadata(xmlMetadata); @@ -79,10 +91,15 @@ public String registerIdentifier(String identifier, Map metadata public String reRegisterIdentifier(String identifier, Map metadata, DvObject dvObject) throws IOException { + return reRegisterIdentifier(identifier, metadata, dvObject, getConfiguredDatafileInfoMode()); + } + + public String reRegisterIdentifier(String identifier, Map metadata, DvObject dvObject, + DatafileInfoMode datafileInfoMode) throws IOException { String retString = ""; // "bare identifier" is the canonical pid with the "doi:" prefix stripped String bareIdentifier = identifier.substring(identifier.indexOf(":") + 1); - String xmlMetadata = getMetadataFromDvObject(identifier, metadata, dvObject); + String xmlMetadata = getMetadataFromDvObject(identifier, metadata, dvObject, datafileInfoMode); String target = metadata.get("_target"); String currentMetadata = null; boolean hasDifferences = false; @@ -131,8 +148,20 @@ public String deactivateIdentifier(String identifier, Map metada return retString; } - - public static String getMetadataFromDvObject(String identifier, Map metadata, DvObject dvObject) { + + /** + * Backward-compatibility fallback for callers that still use no-arg overloads. + */ + private static DatafileInfoMode getConfiguredDatafileInfoMode() { + return DatafileInfoMode.from(JvmSettings.DATACITE_XML_DATAFILE_INFO.lookupOptional().orElse("expanded")); + } + + public static String getMetadataFromDvObject(String identifier, Map metadata, DvObject dvObject) { + return getMetadataFromDvObject(identifier, metadata, dvObject, getConfiguredDatafileInfoMode()); + } + + public static String getMetadataFromDvObject(String identifier, Map metadata, DvObject dvObject, + DatafileInfoMode datafileInfoMode) { Dataset dataset = null; @@ -182,7 +211,7 @@ public static String getMetadataFromDvObject(String identifier, Map metadata, DvObject dvObject) throws IOException { + return modifyIdentifier(identifier, metadata, dvObject, getConfiguredDatafileInfoMode()); + } + + public String modifyIdentifier(String identifier, Map metadata, DvObject dvObject, + DatafileInfoMode datafileInfoMode) throws IOException { - String xmlMetadata = getMetadataFromDvObject(identifier, metadata, dvObject); + String xmlMetadata = getMetadataFromDvObject(identifier, metadata, dvObject, datafileInfoMode); logger.fine("XML to send to DataCite: " + xmlMetadata); diff --git a/src/main/java/edu/harvard/iq/dataverse/pidproviders/doi/datacite/DataCiteDOIProvider.java b/src/main/java/edu/harvard/iq/dataverse/pidproviders/doi/datacite/DataCiteDOIProvider.java index 1fc08b42ad4..46c483ae3f5 100644 --- a/src/main/java/edu/harvard/iq/dataverse/pidproviders/doi/datacite/DataCiteDOIProvider.java +++ b/src/main/java/edu/harvard/iq/dataverse/pidproviders/doi/datacite/DataCiteDOIProvider.java @@ -15,6 +15,7 @@ import edu.harvard.iq.dataverse.FileMetadata; import edu.harvard.iq.dataverse.GlobalId; import edu.harvard.iq.dataverse.pidproviders.doi.AbstractDOIProvider; +import edu.harvard.iq.dataverse.pidproviders.doi.XmlMetadataTemplate; import edu.harvard.iq.dataverse.settings.FeatureFlags; import edu.harvard.iq.dataverse.util.json.JsonUtil; import jakarta.json.JsonObject; @@ -47,18 +48,20 @@ public class DataCiteDOIProvider extends AbstractDOIProvider { private String apiUrl; private String username; private String password; + private XmlMetadataTemplate.DatafileInfoMode datafileInfoMode; private DOIDataCiteRegisterService doiDataCiteRegisterService; public DataCiteDOIProvider(String id, String label, String providerAuthority, String providerShoulder, String identifierGenerationStyle, String datafilePidFormat, String managedList, String excludedList, - String mdsUrl, String apiUrl, String username, String password) { + String mdsUrl, String apiUrl, String username, String password, String datafileInfoMode) { super(id, label, providerAuthority, providerShoulder, identifierGenerationStyle, datafilePidFormat, managedList, excludedList); this.mdsUrl = mdsUrl; this.apiUrl = apiUrl; this.username = username; this.password = password; + this.datafileInfoMode = XmlMetadataTemplate.DatafileInfoMode.from(datafileInfoMode); doiDataCiteRegisterService = new DOIDataCiteRegisterService(mdsUrl, apiUrl, username, password); } @@ -95,7 +98,7 @@ public String createIdentifier(DvObject dvObject) throws Exception { Map metadata = getMetadataForCreateIndicator(dvObject); metadata.put("_status", DRAFT); try { - String retString = doiDataCiteRegisterService.reserveIdentifier(identifier, metadata, dvObject); + String retString = doiDataCiteRegisterService.reserveIdentifier(identifier, metadata, dvObject, datafileInfoMode); logger.log(Level.FINE, "create DOI identifier retString : " + retString); return retString; } catch (Exception e) { @@ -132,7 +135,7 @@ public String modifyIdentifierTargetURL(DvObject dvObject) throws Exception { try { Map metadata = getIdentifierMetadata(dvObject); metadata.put("_target", getTargetUrl(dvObject)); - doiDataCiteRegisterService.modifyIdentifier(identifier, metadata, dvObject); + doiDataCiteRegisterService.modifyIdentifier(identifier, metadata, dvObject, datafileInfoMode); } catch (Exception e) { logger.log(Level.WARNING, "modifyMetadata failed", e); throw e; @@ -219,9 +222,9 @@ public boolean publicizeIdentifier(DvObject dvObject) { metadata.put("_target", getTargetUrl(dvObject)); try { if (FeatureFlags.ONLY_UPDATE_DATACITE_WHEN_NEEDED.enabled()) { - doiDataCiteRegisterService.reRegisterIdentifier(identifier, metadata, dvObject); + doiDataCiteRegisterService.reRegisterIdentifier(identifier, metadata, dvObject, datafileInfoMode); } else { - doiDataCiteRegisterService.registerIdentifier(identifier, metadata, dvObject); + doiDataCiteRegisterService.registerIdentifier(identifier, metadata, dvObject, datafileInfoMode); } return true; } catch (Exception e) { diff --git a/src/main/java/edu/harvard/iq/dataverse/pidproviders/doi/datacite/DataCiteProviderFactory.java b/src/main/java/edu/harvard/iq/dataverse/pidproviders/doi/datacite/DataCiteProviderFactory.java index 99d13b2647c..057d67c627b 100644 --- a/src/main/java/edu/harvard/iq/dataverse/pidproviders/doi/datacite/DataCiteProviderFactory.java +++ b/src/main/java/edu/harvard/iq/dataverse/pidproviders/doi/datacite/DataCiteProviderFactory.java @@ -31,9 +31,10 @@ public PidProvider createPidProvider(String providerId) { String apiUrl = JvmSettings.DATACITE_REST_API_URL.lookupOptional(providerId).orElse("https://api.test.datacite.org"); String username = JvmSettings.DATACITE_USERNAME.lookup(providerId); String password = JvmSettings.DATACITE_PASSWORD.lookup(providerId); + String datafileInfoMode = JvmSettings.DATACITE_XML_DATAFILE_INFO.lookupOptional().orElse("expanded"); return new DataCiteDOIProvider(providerId, providerLabel, providerAuthority, providerShoulder, identifierGenerationStyle, - datafilePidFormat, managedList, excludedList, mdsUrl, apiUrl, username, password); + datafilePidFormat, managedList, excludedList, mdsUrl, apiUrl, username, password, datafileInfoMode); } public String getType() { diff --git a/src/main/java/edu/harvard/iq/dataverse/settings/JvmSettings.java b/src/main/java/edu/harvard/iq/dataverse/settings/JvmSettings.java index 8ed18b4c63f..8c59a152024 100644 --- a/src/main/java/edu/harvard/iq/dataverse/settings/JvmSettings.java +++ b/src/main/java/edu/harvard/iq/dataverse/settings/JvmSettings.java @@ -117,6 +117,10 @@ public enum JvmSettings { MDB_SYSTEM_METADATA_KEYS(SCOPE_METADATA, "block-system-metadata-keys"), MDB_SYSTEM_KEY_FOR(MDB_SYSTEM_METADATA_KEYS), + // DATACITE SETTINGS (applies to both DataCite PID provider and DataCite metadata export) + SCOPE_DATACITE(PREFIX, "datacite"), + DATACITE_XML_DATAFILE_INFO(SCOPE_DATACITE, "xml.datafile-info"), + // PERSISTENT IDENTIFIER SETTINGS SCOPE_PID(PREFIX, "pid"), PID_PROVIDERS(SCOPE_PID, "providers"), diff --git a/src/test/java/edu/harvard/iq/dataverse/pidproviders/PidUtilTest.java b/src/test/java/edu/harvard/iq/dataverse/pidproviders/PidUtilTest.java index d73ca414b7a..19b2fa4f000 100644 --- a/src/test/java/edu/harvard/iq/dataverse/pidproviders/PidUtilTest.java +++ b/src/test/java/edu/harvard/iq/dataverse/pidproviders/PidUtilTest.java @@ -498,7 +498,7 @@ public void testLegacyConfig() throws IOException { if (mdsUrl != null && restUrl != null && dcUsername != null && dcPassword != null) { legacy = new DataCiteDOIProvider("legacy", "legacy", authority, shoulder, identifierGenerationStyle, dataFilePidFormat, "", "", mdsUrl, restUrl, dcUsername, - dcPassword); + dcPassword, "expanded"); } break; case "FAKE": diff --git a/src/test/java/edu/harvard/iq/dataverse/pidproviders/doi/datacite/DataCiteProviderTest.java b/src/test/java/edu/harvard/iq/dataverse/pidproviders/doi/datacite/DataCiteProviderTest.java index 572fc722272..79fad589d2d 100644 --- a/src/test/java/edu/harvard/iq/dataverse/pidproviders/doi/datacite/DataCiteProviderTest.java +++ b/src/test/java/edu/harvard/iq/dataverse/pidproviders/doi/datacite/DataCiteProviderTest.java @@ -83,7 +83,7 @@ public void testDoiLifecycle() throws IOException { String shoulder = System.getenv("DataCiteShoulder"); DataCiteDOIProvider provider = new DataCiteDOIProvider("test", "test", authority, shoulder, "randomString", SystemConfig.DataFilePIDFormat.DEPENDENT.toString(), "", "", "https://mds.test.datacite.org", - "https://api.test.datacite.org", username, password); + "https://api.test.datacite.org", username, password, "expanded"); provider.setPidProviderServiceBean(pidService); diff --git a/src/test/java/edu/harvard/iq/dataverse/pidproviders/doi/datacite/XmlMetadataTemplateTest.java b/src/test/java/edu/harvard/iq/dataverse/pidproviders/doi/datacite/XmlMetadataTemplateTest.java index 19da198399a..49c4c171384 100644 --- a/src/test/java/edu/harvard/iq/dataverse/pidproviders/doi/datacite/XmlMetadataTemplateTest.java +++ b/src/test/java/edu/harvard/iq/dataverse/pidproviders/doi/datacite/XmlMetadataTemplateTest.java @@ -2,6 +2,7 @@ import edu.harvard.iq.dataverse.ControlledVocabularyValue; import edu.harvard.iq.dataverse.DataCitation; +import edu.harvard.iq.dataverse.DataFile; import edu.harvard.iq.dataverse.Dataset; import edu.harvard.iq.dataverse.DatasetAuthor; import edu.harvard.iq.dataverse.DatasetField; @@ -22,6 +23,7 @@ import edu.harvard.iq.dataverse.pidproviders.PidProviderFactoryBean; import edu.harvard.iq.dataverse.pidproviders.doi.DoiMetadata; import edu.harvard.iq.dataverse.pidproviders.doi.XmlMetadataTemplate; +import edu.harvard.iq.dataverse.pidproviders.doi.XmlMetadataTemplate.DatafileInfoMode; import edu.harvard.iq.dataverse.settings.JvmSettings; import edu.harvard.iq.dataverse.settings.SettingsServiceBean; import edu.harvard.iq.dataverse.util.json.CompoundVocabularyException; @@ -420,6 +422,84 @@ public void testDataCiteXMLCreationAllFieldsMultipleGeoLocations() throws IOExce } + @Test + public void testDataCiteXMLDatafileInfoModes() throws Exception { + Dataset dataset = createDatasetWithFiles( + createDataFile(100L, "text/plain"), + createDataFile(200L, "application/pdf"), + createDataFile(300L, "text/plain"), + createDataFile(-1L, null)); + DoiMetadata doiMetadata = createMinimalDoiMetadata(); + + String expandedXml = new XmlMetadataTemplate(doiMetadata, DatafileInfoMode.EXPANDED).generateXML(dataset); + assertEquals(List.of("100", "200", "300"), XmlPath.from(expandedXml).getList("resource.sizes.size")); + assertEquals(List.of("text/plain", "application/pdf", "text/plain"), + XmlPath.from(expandedXml).getList("resource.formats.format")); + + String briefXml = new XmlMetadataTemplate(doiMetadata, DatafileInfoMode.BRIEF).generateXML(dataset); + assertDataCiteXmlIsSchemaValid(briefXml); + assertEquals(List.of("600"), XmlPath.from(briefXml).getList("resource.sizes.size")); + assertEquals(List.of("text/plain", "application/pdf"), + XmlPath.from(briefXml).getList("resource.formats.format")); + + String noneXml = new XmlMetadataTemplate(doiMetadata, DatafileInfoMode.NONE).generateXML(dataset); + assertFalse(noneXml.contains("")); + assertFalse(noneXml.contains("")); + + String defaultXml = new XmlMetadataTemplate(doiMetadata).generateXML(dataset); + assertEquals(XmlPath.from(expandedXml).getList("resource.sizes.size"), + XmlPath.from(defaultXml).getList("resource.sizes.size")); + assertEquals(XmlPath.from(expandedXml).getList("resource.formats.format"), + XmlPath.from(defaultXml).getList("resource.formats.format")); + } + + private void assertDataCiteXmlIsSchemaValid(String xml) throws Exception { + StreamSource source = new StreamSource(new StringReader(xml)); + source.setSystemId("DataCite XML for test dataset"); + assertTrue(XmlValidator.validateXmlSchema(source, + new URL("https://schema.datacite.org/meta/kernel-4/metadata.xsd"))); + } + + private DoiMetadata createMinimalDoiMetadata() { + DoiMetadata doiMetadata = new DoiMetadata(); + doiMetadata.setTitle("A Title"); + doiMetadata.setPublisher("Dataverse"); + doiMetadata.setAuthors(new ArrayList<>()); + return doiMetadata; + } + + private Dataset createDatasetWithFiles(DataFile... dataFiles) { + Dataset dataset = new Dataset(); + dataset.setGlobalId(new GlobalId("doi", "10.5072", "FK2/FILES", null, null, null)); + dataset.setFiles(List.of(dataFiles)); + + DatasetVersion datasetVersion = new DatasetVersion(); + datasetVersion.setVersionState(VersionState.DRAFT); + datasetVersion.setDataset(dataset); + datasetVersion.setTermsOfUseAndAccess(new TermsOfUseAndAccess()); + + DatasetFieldType titleFieldType = new DatasetFieldType(DatasetFieldConstant.title, + DatasetFieldType.FieldType.TEXT, false); + DatasetField titleField = new DatasetField(); + titleField.setDatasetVersion(datasetVersion); + titleField.setDatasetFieldType(titleFieldType); + titleField.setSingleValue("First Title"); + datasetVersion.setDatasetFields(List.of(titleField)); + + dataset.setVersions(new ArrayList<>(List.of(datasetVersion))); + DatasetType datasetType = new DatasetType(); + datasetType.setName(DatasetType.DATASET_TYPE_DATASET); + dataset.setDatasetType(datasetType); + return dataset; + } + + private DataFile createDataFile(long filesize, String contentType) { + DataFile dataFile = new DataFile(); + dataFile.setFilesize(filesize); + dataFile.setContentType(contentType); + return dataFile; + } + @Test public void testDataCiteXMLCreationInvalidDates() throws IOException { Dataverse collection = new Dataverse(); diff --git a/src/test/java/edu/harvard/iq/dataverse/settings/JvmSettingsTest.java b/src/test/java/edu/harvard/iq/dataverse/settings/JvmSettingsTest.java index f4494b7116e..0d0b586e851 100644 --- a/src/test/java/edu/harvard/iq/dataverse/settings/JvmSettingsTest.java +++ b/src/test/java/edu/harvard/iq/dataverse/settings/JvmSettingsTest.java @@ -21,6 +21,12 @@ void lookupSetting() { void lookupPidProviderSetting() { assertEquals("test", JvmSettings.DATACITE_USERNAME.lookup("datacite")); } + + @Test + @SystemProperty(key = "dataverse.datacite.xml.datafile-info", value = "brief") + void lookupDataciteDatafileInfoSetting() { + assertEquals("brief", JvmSettings.DATACITE_XML_DATAFILE_INFO.lookup()); + } @Test @SystemProperty(key = "dataverse.ingest.rserve.port", value = "1234")