From 57d79894609664141f8e52c1367e1cb9d350ea6d Mon Sep 17 00:00:00 2001 From: Torsten Krause Date: Sun, 18 Oct 2026 15:51:44 +0200 Subject: [PATCH 1/2] MIR-1697 add support for Crossref abstracts --- ...srefJatsAbstract2ModsAbstractResolver.java | 272 ++++++++++++++++++ .../resources/config/mir/mycore.properties | 3 + .../xslt/mir/functions/mircrossrefutils.xsl | 16 ++ .../crossref-jats-abstract2html.xsl | 78 +++++ .../mir/import/enrichment/crossref2mods.xsl | 6 + ...JatsAbstract2ModsAbstractResolverTest.java | 92 ++++++ .../example.json | 20 ++ 7 files changed, 487 insertions(+) create mode 100644 mir-module/src/main/java/org/mycore/mir/importer/MIRCrossrefJatsAbstract2ModsAbstractResolver.java create mode 100644 mir-module/src/main/resources/xslt/mir/functions/mircrossrefutils.xsl create mode 100644 mir-module/src/main/resources/xslt/mir/import/enrichment/crossref-jats-abstract2html.xsl create mode 100644 mir-module/src/test/java/org/mycore/mir/importer/MIRCrossrefJatsAbstract2ModsAbstractResolverTest.java create mode 100644 mir-module/src/test/resources/MIRCrossrefJatsAbstract2ModsAbstractResolverTest/example.json diff --git a/mir-module/src/main/java/org/mycore/mir/importer/MIRCrossrefJatsAbstract2ModsAbstractResolver.java b/mir-module/src/main/java/org/mycore/mir/importer/MIRCrossrefJatsAbstract2ModsAbstractResolver.java new file mode 100644 index 0000000000..ca419a0616 --- /dev/null +++ b/mir-module/src/main/java/org/mycore/mir/importer/MIRCrossrefJatsAbstract2ModsAbstractResolver.java @@ -0,0 +1,272 @@ +/* + * This file is part of *** M y C o R e *** + * See https://www.mycore.de/ for details. + * + * MyCoRe is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * MyCoRe is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with MyCoRe. If not, see . + */ + +package org.mycore.mir.importer; + +import java.io.StringWriter; +import java.net.URLDecoder; +import java.nio.charset.StandardCharsets; +import java.util.Base64; +import java.util.UUID; + +import javax.xml.parsers.DocumentBuilder; +import javax.xml.parsers.DocumentBuilderFactory; +import javax.xml.transform.OutputKeys; +import javax.xml.transform.Source; +import javax.xml.transform.Transformer; +import javax.xml.transform.TransformerException; +import javax.xml.transform.TransformerFactory; +import javax.xml.transform.URIResolver; +import javax.xml.transform.dom.DOMSource; +import javax.xml.transform.stream.StreamResult; + +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; +import org.mycore.common.MCRConstants; +import org.mycore.common.MCRException; +import org.mycore.common.config.MCRConfigurationException; +import org.mycore.common.content.MCRContent; +import org.mycore.common.content.MCRStringContent; +import org.mycore.common.content.transformer.MCRContentTransformer; +import org.mycore.common.content.transformer.MCRContentTransformerFactory; +import org.mycore.mir.editor.MIREditorUtils; +import org.w3c.dom.Document; +import org.w3c.dom.Element; +import org.w3c.dom.Node; +import org.w3c.dom.NodeList; + +/** + * The Crossref JSON API, as used by the default configuration of the metadata enricher in MIR, + * provides abstracts as JATS XML string embedded in its JSON response, like: + *

+ * {
+ *   "status": "ok",
+ *   "message-type": "work",
+ *   "message-version": "1.0.0",
+ *   "message": {
+ *     ...
+ *     "abstract": "<jats:title>Abstract</jats:title>\n<jats:p><jats:bold>Lorem ipsum</jats:bold> dolor sit <jats:italic>amet</jats:italic>, 23<jats:sup>42</jats:sup>.</jats:p>"
+ *   }
+ * }
+ * 
+ * This JSON is turned into XML by xslTransform:json2xml and interpreted by + * xslTransform:crossref2mods using xslt/mir/import/enrichment/crossref2mods.xsl + * which sends the JATS XML string as an URL encoded string to this URI resolver. + *

+ * This URI resolver processes the JATS XML into MIR specific MODS XML. To do this, it + *

    + *
  1. reverts the URL encoding; + *
  2. wraps the JATS XML into a jats:abstract-Element (including the namespace binding); + *
  3. transforms the JATS document into HTML using the content transformer crossref-jats-abstract2html; + *
  4. places the HTML into an abstract-element with a random altRepGroup-attribute value; + *
  5. Base64-encodes the string representation of that abstract-element; + *
  6. creates a data URL using that Base64 encoded data; + *
  7. creates a mods:abstract-element with + *
      + *
    • contentType-attribute with value text/xml, + *
    • altRepGroup-attribute with same value as above and, + *
    • altFormat-attribute with data URL as its value + *
    + * and a mods:abstract-element with + *
      + *
    • no contentType-attribute, + *
    • altRepGroup-attribute with same value as above and, + *
    • a plain text version of the HTML created with {@link MIREditorUtils#getPlainTextString(String)} as text; + *
    + *
  8. places both mods:abstract-elements inside a mods:mods-element and + *
  9. returns that mods:mods-element. + *
+ */ +public class MIRCrossrefJatsAbstract2ModsAbstractResolver implements URIResolver { + + private static final Logger LOGGER = LogManager.getLogger(); + + public static final String JATS_ABSTRACT_OPENING_TAG = ""; + + public static final String JATS_ABSTRACT_CLOSING_TAG = ""; + + public static final String MODS_NAMESPACE = MCRConstants.MODS_NAMESPACE.getURI(); + + @Override + public Source resolve(String href, String base) throws TransformerException { + + DocumentBuilder documentBuilder = getDocumentBuilder(); + + try { + + String encodedJatsString = href.substring("crossref-jats-abstract2mods-abstract:".length()); + String jatsString = URLDecoder.decode(encodedJatsString, StandardCharsets.UTF_8); + String jatsDocumentString = JATS_ABSTRACT_OPENING_TAG + jatsString + JATS_ABSTRACT_CLOSING_TAG; + + if (LOGGER.isDebugEnabled()) { + LOGGER.debug("JATS document: {}", jatsDocumentString); + } + + MCRContent jatsDocumentContent = new MCRStringContent(jatsDocumentString); + Document htmlDocument = transform(jatsDocumentContent, "crossref-jats-abstract2html"); + + if (LOGGER.isDebugEnabled()) { + LOGGER.debug("HTML document: {}", toString(htmlDocument)); + } + + NodeList htmlNodes = htmlDocument.getDocumentElement().getChildNodes(); + String htmlString = toHtmlString(htmlNodes); + + if (LOGGER.isDebugEnabled()) { + LOGGER.debug("HTML: {}", htmlString); + } + + String altRepGroup = getRandomRepGroup(); + + Document innerAbstractDocument = documentBuilder.newDocument(); + Element innerAbstractElement = innerAbstractDocument.createElement("abstract"); + innerAbstractDocument.appendChild(innerAbstractElement); + innerAbstractElement.setAttribute("altRepGroup", altRepGroup); + innerAbstractElement.setTextContent(htmlString); + String innerAbstractXml = toXmlString(innerAbstractDocument); + + if (LOGGER.isDebugEnabled()) { + LOGGER.debug("inner abstract document: {}", innerAbstractXml); + } + + Base64.Encoder encoder = Base64.getEncoder(); + String innerAbstractXmlBase64 = encoder.encodeToString(innerAbstractXml.getBytes(StandardCharsets.UTF_8)); + String innerAbstractDataUrl = "data:text/xml;charset=UTF-8;base64," + innerAbstractXmlBase64; + + if (LOGGER.isDebugEnabled()) { + LOGGER.debug("inner abstract data URL: {}", innerAbstractDataUrl); + } + + Document outerModsDocument = documentBuilder.newDocument(); + Element outerModsElement = outerModsDocument.createElementNS(MODS_NAMESPACE, "mods"); + outerModsDocument.appendChild(outerModsElement); + Element outerHtmlAbstractElement = outerModsDocument.createElementNS(MODS_NAMESPACE, "abstract"); + outerModsElement.appendChild(outerHtmlAbstractElement); + outerHtmlAbstractElement.setAttribute("altRepGroup", altRepGroup); + outerHtmlAbstractElement.setAttribute("contentType", "text/xml"); + outerHtmlAbstractElement.setAttribute("altFormat", innerAbstractDataUrl); + Element outerTextAbstractElement = outerModsDocument.createElementNS(MODS_NAMESPACE, "abstract"); + outerModsElement.appendChild(outerTextAbstractElement); + outerTextAbstractElement.setAttribute("altRepGroup", altRepGroup); + outerTextAbstractElement.setTextContent(MIREditorUtils.getPlainTextString(htmlString)); + + if (LOGGER.isDebugEnabled()) { + LOGGER.debug("outer MODS document: {}", toString(outerModsDocument)); + } + + return new DOMSource(outerModsDocument); + + } catch (Exception e) { + + LOGGER.info("Failed to parse JATS XML fragment", e); + + Document outerModsDocument = documentBuilder.newDocument(); + Element outerModsElement = outerModsDocument.createElementNS(MODS_NAMESPACE, "mods"); + outerModsDocument.appendChild(outerModsElement); + + if (LOGGER.isDebugEnabled()) { + LOGGER.debug("outer MODS document: {}", toString(outerModsDocument)); + } + + return new DOMSource(outerModsDocument); + + } + + } + + private static String toHtmlString(NodeList nodeList) throws Exception { + + StringBuilder builder = new StringBuilder(); + + TransformerFactory transformerFactory = TransformerFactory.newInstance(); + Transformer transformer = transformerFactory.newTransformer(); + transformer.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, "yes"); + transformer.setOutputProperty(OutputKeys.METHOD, "xml"); + + for (int i = 0; i < nodeList.getLength(); i++) { + Node node = nodeList.item(i); + StringWriter writer = new StringWriter(); + transformer.transform(new DOMSource(node), new StreamResult(writer)); + builder.append(writer); + } + + String xmlString = builder.toString(); + + // fix wrongful double escaping provided by some publishers + xmlString = xmlString.replace("&lt;", "<"); + xmlString = xmlString.replace("&gt;", ">"); + xmlString = xmlString.replace("&amp;", "&"); + + return xmlString; + + } + + private static String toXmlString(Document document) throws Exception { + + StringBuilder builder = new StringBuilder(); + + TransformerFactory transformerFactory = TransformerFactory.newInstance(); + Transformer transformer = transformerFactory.newTransformer(); + transformer.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, "no"); + transformer.setOutputProperty(OutputKeys.METHOD, "xml"); + + StringWriter writer = new StringWriter(); + transformer.transform(new DOMSource(document), new StreamResult(writer)); + builder.append(writer); + + return builder.toString(); + + } + + public static Document transform(MCRContent content, String transformerId) throws Exception { + MCRContentTransformer transformer = MCRContentTransformerFactory.getTransformer(transformerId); + if (transformer == null) { + throw new MCRConfigurationException("Content transformer " + transformerId + " is not configured, set " + + "MCR.ContentTransformer." + transformerId + ".Stylesheet or .Class"); + } + MCRContent result = transformer.transform(content); + return getDocumentBuilder().parse(result.getInputSource()); + } + + private static DocumentBuilder getDocumentBuilder() { + try { + DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance(); + documentBuilderFactory.setNamespaceAware(true); + return documentBuilderFactory.newDocumentBuilder(); + } catch (Exception e) { + throw new MCRException("Failed to create document builder", e); + } + } + + private static String getRandomRepGroup() { + return UUID.randomUUID().toString().substring(16); + } + + private static String toString(Document document) { + try { + Transformer transformer = TransformerFactory.newInstance().newTransformer(); + StreamResult result = new StreamResult(new StringWriter()); + DOMSource source = new DOMSource(document); + transformer.transform(source, result); + return result.getWriter().toString(); + } catch (Exception e) { + throw new MCRException("Failed to create string representation of XML document", e); + } + } + +} diff --git a/mir-module/src/main/resources/config/mir/mycore.properties b/mir-module/src/main/resources/config/mir/mycore.properties index 24a1dbfa24..a449b6bd65 100644 --- a/mir-module/src/main/resources/config/mir/mycore.properties +++ b/mir-module/src/main/resources/config/mir/mycore.properties @@ -713,6 +713,9 @@ MCR.MODS.EnrichmentResolver.DataSource.PubMed.pubmed.URI=xslTransform:pubmed2mod # CrossRef MCR.MODS.EnrichmentResolver.DataSource.CrossRef.IdentifierTypes=doi MCR.MODS.EnrichmentResolver.DataSource.CrossRef.doi.URI=xslTransform:crossref2mods:notnull:xslTransform:json2xml:https://api.crossref.org/works/{0} +MCR.URIResolver.xslIncludes.functions=%MCR.URIResolver.xslIncludes.functions%,mir/functions/mircrossrefutils.xsl +MCR.URIResolver.ModuleResolver.crossref-jats-abstract2mods-abstract.Class=org.mycore.mir.importer.MIRCrossrefJatsAbstract2ModsAbstractResolver +MCR.ContentTransformer.crossref-jats-abstract2html.Stylesheet=xslt/mir/import/enrichment/crossref-jats-abstract2html.xsl # DataCite MCR.MODS.EnrichmentResolver.DataSource.DataCite.IdentifierTypes=doi diff --git a/mir-module/src/main/resources/xslt/mir/functions/mircrossrefutils.xsl b/mir-module/src/main/resources/xslt/mir/functions/mircrossrefutils.xsl new file mode 100644 index 0000000000..e9a0edbc39 --- /dev/null +++ b/mir-module/src/main/resources/xslt/mir/functions/mircrossrefutils.xsl @@ -0,0 +1,16 @@ + + + + + + + + + + diff --git a/mir-module/src/main/resources/xslt/mir/import/enrichment/crossref-jats-abstract2html.xsl b/mir-module/src/main/resources/xslt/mir/import/enrichment/crossref-jats-abstract2html.xsl new file mode 100644 index 0000000000..50c08c8441 --- /dev/null +++ b/mir-module/src/main/resources/xslt/mir/import/enrichment/crossref-jats-abstract2html.xsl @@ -0,0 +1,78 @@ + + + + + + + + + + + + + + + +

+ + + +

+
+ + +

+ +

+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
  • + +
  • +
    + + + + + +
    diff --git a/mir-module/src/main/resources/xslt/mir/import/enrichment/crossref2mods.xsl b/mir-module/src/main/resources/xslt/mir/import/enrichment/crossref2mods.xsl index f6c7efc1ef..734f127e0b 100644 --- a/mir-module/src/main/resources/xslt/mir/import/enrichment/crossref2mods.xsl +++ b/mir-module/src/main/resources/xslt/mir/import/enrichment/crossref2mods.xsl @@ -4,6 +4,7 @@ @@ -25,6 +26,7 @@ + @@ -166,4 +168,8 @@ + + + + diff --git a/mir-module/src/test/java/org/mycore/mir/importer/MIRCrossrefJatsAbstract2ModsAbstractResolverTest.java b/mir-module/src/test/java/org/mycore/mir/importer/MIRCrossrefJatsAbstract2ModsAbstractResolverTest.java new file mode 100644 index 0000000000..1e42957877 --- /dev/null +++ b/mir-module/src/test/java/org/mycore/mir/importer/MIRCrossrefJatsAbstract2ModsAbstractResolverTest.java @@ -0,0 +1,92 @@ +package org.mycore.mir.importer; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertTrue; + +import java.io.IOException; +import java.io.StringReader; +import java.nio.charset.StandardCharsets; +import java.util.Base64; +import java.util.List; + +import org.jdom2.Document; +import org.jdom2.Element; +import org.jdom2.JDOMException; +import org.jdom2.filter.Filters; +import org.jdom2.input.SAXBuilder; +import org.jdom2.output.Format; +import org.jdom2.output.XMLOutputter; +import org.jdom2.xpath.XPathFactory; +import org.junit.jupiter.api.Test; +import org.mycore.common.MCRConstants; +import org.mycore.common.config.MCRConfiguration2; +import org.mycore.common.xsl.uriresolver.MCRURIResolver; +import org.mycore.test.MyCoReTest; + +@MyCoReTest +public class MIRCrossrefJatsAbstract2ModsAbstractResolverTest { + + public static final String ALT_FORMAT_PREFIX = "data:text/xml;charset=UTF-8;base64,"; + + @Test + public void testAbstractMapping() throws IOException, JDOMException { + + String uri = MCRConfiguration2.getStringOrThrow("MCR.MODS.EnrichmentResolver.DataSource.CrossRef.doi.URI"); + + String className = MIRCrossrefJatsAbstract2ModsAbstractResolverTest.class.getSimpleName(); + uri = uri.replace("https://api.crossref.org/works/{0}", "resource:" + className + "/example.json"); + + Element element = MCRURIResolver.obtainInstance().resolve(uri); + + System.out.println("MODS:"); + new XMLOutputter(Format.getPrettyFormat()).output(element, System.out); + System.out.println(); + + List plainTextAbstractElements = evaluate(element, ".//mods:abstract[not(@contentType)]"); + assertEquals(1, plainTextAbstractElements.size()); + + Element plainTextAbstractElement = plainTextAbstractElements.getFirst(); + + String plainText = plainTextAbstractElement.getText(); + assertEquals("Lorem ipsum dolor sit amet, 2342.", plainText); + + List htmlAbstractElements = evaluate(element, ".//mods:abstract[@contentType='text/xml']"); + assertEquals(1, htmlAbstractElements.size()); + + Element htmlAbstractElement = htmlAbstractElements.getFirst(); + assertEquals(plainTextAbstractElement.getAttributeValue("altRepGroup"), + htmlAbstractElement.getAttributeValue("altRepGroup")); + + String altFormat = htmlAbstractElement.getAttributeValue("altFormat"); + assertTrue(altFormat.startsWith(ALT_FORMAT_PREFIX)); + String altFormatData = altFormat.substring(ALT_FORMAT_PREFIX.length()); + String altFormatXml = new String(Base64.getDecoder().decode(altFormatData), StandardCharsets.UTF_8); + + Document altFormatDocument = new SAXBuilder().build(new StringReader(altFormatXml)); + Element altFormatElement = altFormatDocument.getRootElement(); + + System.out.println("Abstract:"); + new XMLOutputter(Format.getPrettyFormat()).output(altFormatElement, System.out); + System.out.println(); + + assertEquals(htmlAbstractElement.getAttributeValue("altRepGroup"), + altFormatElement.getAttributeValue("altRepGroup")); + + Document altFormatHtmlDocument = new SAXBuilder().build(new StringReader(altFormatElement.getText())); + Element altFormatHtmlElement = altFormatHtmlDocument.getRootElement(); + + String html = new XMLOutputter(Format.getCompactFormat()).outputString(altFormatHtmlElement); + + System.out.println("HTML:"); + System.out.println(html); + + assertEquals("

    Lorem ipsumdolor sitamet, 2342.

    ", html); + + } + + private static List evaluate(Element element, String xpath) { + return XPathFactory.instance() + .compile(xpath, Filters.element(), null, MCRConstants.getStandardNamespaces()) + .evaluate(element); + } +} diff --git a/mir-module/src/test/resources/MIRCrossrefJatsAbstract2ModsAbstractResolverTest/example.json b/mir-module/src/test/resources/MIRCrossrefJatsAbstract2ModsAbstractResolverTest/example.json new file mode 100644 index 0000000000..cc99610781 --- /dev/null +++ b/mir-module/src/test/resources/MIRCrossrefJatsAbstract2ModsAbstractResolverTest/example.json @@ -0,0 +1,20 @@ +{ + "status": "ok", + "message-type": "work", + "message-version": "1.0.0", + "message": { + "indexed": { + "date-parts": [ + [ + 2026, + 10, + 18 + ] + ], + "date-time": "2026-01-01T00:00:00Z", + "timestamp": 1767222000, + "version": "4.4.0" + }, + "abstract": "Abstract\nLorem ipsum dolor sit amet, 2342." + } +} From 753a14140a536ae64f92eba0a75c81910433c7a7 Mon Sep 17 00:00:00 2001 From: Torsten Krause Date: Thu, 29 Oct 2026 14:52:21 +0100 Subject: [PATCH 2/2] MIR-1697 add opt-in-property for new feature, disabled by default --- .../resources/config/mir/mycore.properties | 4 +++ .../xslt/mir/functions/mircrossrefutils.xsl | 9 +++-- ...JatsAbstract2ModsAbstractResolverTest.java | 36 +++++++++++++++++-- 3 files changed, 45 insertions(+), 4 deletions(-) diff --git a/mir-module/src/main/resources/config/mir/mycore.properties b/mir-module/src/main/resources/config/mir/mycore.properties index a449b6bd65..88e5aa2ee1 100644 --- a/mir-module/src/main/resources/config/mir/mycore.properties +++ b/mir-module/src/main/resources/config/mir/mycore.properties @@ -713,6 +713,10 @@ MCR.MODS.EnrichmentResolver.DataSource.PubMed.pubmed.URI=xslTransform:pubmed2mod # CrossRef MCR.MODS.EnrichmentResolver.DataSource.CrossRef.IdentifierTypes=doi MCR.MODS.EnrichmentResolver.DataSource.CrossRef.doi.URI=xslTransform:crossref2mods:notnull:xslTransform:json2xml:https://api.crossref.org/works/{0} + +# usage of abstracts provided by Crossref +# disabled by default due to potential copyright issues, see https://www.crossref.org/documentation/retrieve-metadata/#73020 +MCR.MODS.EnrichmentResolver.DataSource.CrossRef.UseAbstracts=false MCR.URIResolver.xslIncludes.functions=%MCR.URIResolver.xslIncludes.functions%,mir/functions/mircrossrefutils.xsl MCR.URIResolver.ModuleResolver.crossref-jats-abstract2mods-abstract.Class=org.mycore.mir.importer.MIRCrossrefJatsAbstract2ModsAbstractResolver MCR.ContentTransformer.crossref-jats-abstract2html.Stylesheet=xslt/mir/import/enrichment/crossref-jats-abstract2html.xsl diff --git a/mir-module/src/main/resources/xslt/mir/functions/mircrossrefutils.xsl b/mir-module/src/main/resources/xslt/mir/functions/mircrossrefutils.xsl index e9a0edbc39..1d0b272058 100644 --- a/mir-module/src/main/resources/xslt/mir/functions/mircrossrefutils.xsl +++ b/mir-module/src/main/resources/xslt/mir/functions/mircrossrefutils.xsl @@ -1,16 +1,21 @@ + + - - + + + + diff --git a/mir-module/src/test/java/org/mycore/mir/importer/MIRCrossrefJatsAbstract2ModsAbstractResolverTest.java b/mir-module/src/test/java/org/mycore/mir/importer/MIRCrossrefJatsAbstract2ModsAbstractResolverTest.java index 1e42957877..0732bc8b56 100644 --- a/mir-module/src/test/java/org/mycore/mir/importer/MIRCrossrefJatsAbstract2ModsAbstractResolverTest.java +++ b/mir-module/src/test/java/org/mycore/mir/importer/MIRCrossrefJatsAbstract2ModsAbstractResolverTest.java @@ -19,6 +19,8 @@ import org.jdom2.xpath.XPathFactory; import org.junit.jupiter.api.Test; import org.mycore.common.MCRConstants; +import org.mycore.common.MCRTestConfiguration; +import org.mycore.common.MCRTestProperty; import org.mycore.common.config.MCRConfiguration2; import org.mycore.common.xsl.uriresolver.MCRURIResolver; import org.mycore.test.MyCoReTest; @@ -26,12 +28,19 @@ @MyCoReTest public class MIRCrossrefJatsAbstract2ModsAbstractResolverTest { + public static final String DATASOURCE_URI = "MCR.MODS.EnrichmentResolver.DataSource.CrossRef.doi.URI"; + + public static final String USE_ABSTRACTS = "MCR.MODS.EnrichmentResolver.DataSource.CrossRef.UseAbstracts"; + public static final String ALT_FORMAT_PREFIX = "data:text/xml;charset=UTF-8;base64,"; @Test - public void testAbstractMapping() throws IOException, JDOMException { + @MCRTestConfiguration(properties = { + @MCRTestProperty(key = USE_ABSTRACTS, string = "true") + }) + public void testEnabledAbstractMapping() throws IOException, JDOMException { - String uri = MCRConfiguration2.getStringOrThrow("MCR.MODS.EnrichmentResolver.DataSource.CrossRef.doi.URI"); + String uri = MCRConfiguration2.getStringOrThrow(DATASOURCE_URI); String className = MIRCrossrefJatsAbstract2ModsAbstractResolverTest.class.getSimpleName(); uri = uri.replace("https://api.crossref.org/works/{0}", "resource:" + className + "/example.json"); @@ -84,9 +93,32 @@ public void testAbstractMapping() throws IOException, JDOMException { } + @Test + @MCRTestConfiguration(properties = { + @MCRTestProperty(key = USE_ABSTRACTS, string = "false") + }) + public void testDisabledAbstractMapping() throws IOException { + + String uri = MCRConfiguration2.getStringOrThrow(DATASOURCE_URI); + + String className = MIRCrossrefJatsAbstract2ModsAbstractResolverTest.class.getSimpleName(); + uri = uri.replace("https://api.crossref.org/works/{0}", "resource:" + className + "/example.json"); + + Element element = MCRURIResolver.obtainInstance().resolve(uri); + + System.out.println("MODS:"); + new XMLOutputter(Format.getPrettyFormat()).output(element, System.out); + System.out.println(); + + List plainTextAbstractElements = evaluate(element, ".//mods:abstract[not(@contentType)]"); + assertEquals(0, plainTextAbstractElements.size()); + + } + private static List evaluate(Element element, String xpath) { return XPathFactory.instance() .compile(xpath, Filters.element(), null, MCRConstants.getStandardNamespaces()) .evaluate(element); } + }