diff --git a/.travis.yml b/.travis.yml deleted file mode 100644 index b2244db..0000000 --- a/.travis.yml +++ /dev/null @@ -1,4 +0,0 @@ -language: java -jdk: - - openjdk11 - diff --git a/gradle.properties b/gradle.properties index 2815476..a51ec74 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,9 +1,9 @@ group = org.xbib name = marc -version = 2.4.0 +version = 2.5.0 gradle.wrapper.version = 6.6.1 -xbib-content.version = 2.3.1 +xbib-content.version = 2.6.4 xbib-bibliographic-character-sets.version = 2.0.0 xalan.version = 2.7.2 xmlunit-matchers.version = 2.6.3 diff --git a/gradle/test/junit5.gradle b/gradle/test/junit5.gradle index 53a2338..49d2b29 100644 --- a/gradle/test/junit5.gradle +++ b/gradle/test/junit5.gradle @@ -1,5 +1,5 @@ -def junitVersion = project.hasProperty('junit.version')?project.property('junit.version'):'5.6.2' +def junitVersion = project.hasProperty('junit.version')?project.property('junit.version'):'5.7.0' def hamcrestVersion = project.hasProperty('hamcrest.version')?project.property('hamcrest.version'):'2.2' dependencies { @@ -11,7 +11,7 @@ dependencies { test { useJUnitPlatform() - failFast = true + failFast = false testLogging { events 'STARTED', 'PASSED', 'FAILED', 'SKIPPED' } diff --git a/settings.gradle b/settings.gradle deleted file mode 100644 index 89f4110..0000000 --- a/settings.gradle +++ /dev/null @@ -1 +0,0 @@ -rootProject.name = name diff --git a/src/main/java/org/xbib/marc/Marc.java b/src/main/java/org/xbib/marc/Marc.java index e14d0a3..a802a60 100644 --- a/src/main/java/org/xbib/marc/Marc.java +++ b/src/main/java/org/xbib/marc/Marc.java @@ -126,18 +126,18 @@ public final class Marc { /** * Run XML stream parser over an XML input stream, with an XML event consumer. + * @param xmlInputFactory the XML input factory * @param consumer the XML event consumer * @throws XMLStreamException if parsing fails */ - public void parseEvents(MarcXchangeEventConsumer consumer) throws XMLStreamException { + public void parseEvents(XMLInputFactory xmlInputFactory, MarcXchangeEventConsumer consumer) throws XMLStreamException { Objects.requireNonNull(consumer); if (builder.getMarcListeners() != null) { for (Map.Entry entry : builder.getMarcListeners().entrySet()) { consumer.setMarcListener(entry.getKey(), entry.getValue()); } } - XMLInputFactory inputFactory = XMLInputFactory.newInstance(); - XMLEventReader xmlEventReader = inputFactory.createXMLEventReader(builder.getInputStream()); + XMLEventReader xmlEventReader = xmlInputFactory.createXMLEventReader(builder.getInputStream()); while (xmlEventReader.hasNext()) { consumer.add(xmlEventReader.nextEvent()); } @@ -240,16 +240,6 @@ public final class Marc { new InputSource(builder.getInputStream())).document(); } - /** - * Transform W3C document of the record in the ISO 2709 input stream by an XSL stylesheet. - * @param stylesheetUrl the URL of the stylesheet - * @param result the result of the transformation - * @throws IOException if transformation fails - */ - public void transform(URL stylesheetUrl, Result result) throws IOException { - transform(TransformerFactory.newInstance(), stylesheetUrl, result); - } - /** * Transform W3C document of the record in the ISO 2709 input stream by an XSL stylesheet. * @@ -440,6 +430,8 @@ public final class Marc { protected final Builder builder; + protected SAXParser saxParser; + private MarcXmlReader(Builder builder) { this.builder = builder; } @@ -504,6 +496,11 @@ public final class Marc { return builder.getContentHandler(); } + public MarcXmlReader setSaxParser(SAXParser saxParser) { + this.saxParser = saxParser; + return this; + } + /** * Parse MARC XML via SAX. * @@ -524,21 +521,23 @@ public final class Marc { builder.setContentHandler(handler); } try { - SAXParserFactory factory = SAXParserFactory.newInstance(); - factory.setNamespaceAware(true); - SAXParser sax = factory.newSAXParser(); + if (saxParser == null) { + SAXParserFactory factory = SAXParserFactory.newInstance(); + factory.setNamespaceAware(true); + saxParser = factory.newSAXParser(); + } if (builder.getFeatures() != null) { for (Map.Entry entry : builder.getFeatures().entrySet()) { - sax.getXMLReader().setFeature(entry.getKey(), entry.getValue()); + saxParser.getXMLReader().setFeature(entry.getKey(), entry.getValue()); } } if (builder.getProperties() != null) { for (Map.Entry entry : builder.getProperties().entrySet()) { - sax.getXMLReader().setProperty(entry.getKey(), entry.getValue()); + saxParser.getXMLReader().setProperty(entry.getKey(), entry.getValue()); } } - sax.getXMLReader().setContentHandler(builder.getContentHandler()); - sax.getXMLReader().parse(inputSource); + saxParser.getXMLReader().setContentHandler(builder.getContentHandler()); + saxParser.getXMLReader().parse(inputSource); } catch (SAXException | ParserConfigurationException e) { throw new IOException(e); } finally { @@ -628,9 +627,9 @@ public final class Marc { private InverseMarcContentHandler defaultContentHandler; - private Map features = new HashMap<>(); + private final Map features = new HashMap<>(); - private Map properties = new HashMap<>(); + private final Map properties = new HashMap<>(); private Map listeners = new HashMap<>(); diff --git a/src/main/java/org/xbib/marc/MarcField.java b/src/main/java/org/xbib/marc/MarcField.java index a15969d..544f686 100644 --- a/src/main/java/org/xbib/marc/MarcField.java +++ b/src/main/java/org/xbib/marc/MarcField.java @@ -362,9 +362,9 @@ public class MarcField implements Comparable { private String value; - private LinkedList subfields; + private final LinkedList subfields; - private LinkedList subfieldIds; + private final LinkedList subfieldIds; private Boolean isControl; @@ -516,7 +516,10 @@ public class MarcField implements Comparable { * @return this builder */ public Builder subfieldValue(String value) { - subfields.add(new Subfield(subfields.removeLast().getId(), value)); + if (!subfields.isEmpty()) { + String id = subfields.removeLast().getId(); + subfields.add(new Subfield(id, value)); + } return this; } @@ -590,7 +593,8 @@ public class MarcField implements Comparable { this.position = field.getPosition(); this.length = field.getLength(); this.value = field.getValue(); - this.subfields = new LinkedList<>(field.getSubfields()); + this.subfields.clear(); + this.subfields.addAll(field.getSubfields()); for (Subfield subfield : subfields) { subfieldIds.add(subfield.getId()); } diff --git a/src/main/java/org/xbib/marc/tools/MarcTool.java b/src/main/java/org/xbib/marc/tools/MarcTool.java index a17f821..7bd69f0 100644 --- a/src/main/java/org/xbib/marc/tools/MarcTool.java +++ b/src/main/java/org/xbib/marc/tools/MarcTool.java @@ -29,6 +29,7 @@ import java.util.Objects; import java.util.logging.Level; import java.util.logging.Logger; +import javax.xml.transform.TransformerFactory; import javax.xml.transform.stream.StreamResult; /** @@ -110,8 +111,9 @@ public class MarcTool { .setMarcListener(writer); if (schema != null && stylesheet != null && result != null) { System.setProperty("http.agent", "Java Agent"); - builder.setSchema(schema).build().transform(new URL(stylesheet), - new StreamResult(Files.newBufferedWriter(Paths.get(result)))); + builder.setSchema(schema).build().transform(TransformerFactory.newInstance(), + new URL(stylesheet), + new StreamResult(Files.newBufferedWriter(Paths.get(result)))); } else { builder.build().writeCollection(65536); } diff --git a/src/main/java/org/xbib/marc/transformer/field/MarcFieldTransformers.java b/src/main/java/org/xbib/marc/transformer/field/MarcFieldTransformers.java index 3d33275..cbf7766 100644 --- a/src/main/java/org/xbib/marc/transformer/field/MarcFieldTransformers.java +++ b/src/main/java/org/xbib/marc/transformer/field/MarcFieldTransformers.java @@ -31,6 +31,7 @@ public class MarcFieldTransformers extends LinkedList { LinkedList list = new LinkedList<>(); // lastBuilt allows us to access the last MarcField built across different MarcFieldTransformer MarcField lastBuilt = null; + // critial area - marc fields must not change here - so we can not reuse transformes by multiple threads for (MarcField marcField : marcFields) { boolean found = false; String key; diff --git a/src/test/java/org/xbib/marc/MarcToModsTest.java b/src/test/java/org/xbib/marc/MarcToModsTest.java index 34c3bfb..a7c3e87 100644 --- a/src/test/java/org/xbib/marc/MarcToModsTest.java +++ b/src/test/java/org/xbib/marc/MarcToModsTest.java @@ -180,13 +180,14 @@ public class MarcToModsTest { StringWriter sw = new StringWriter(); Result result = new StreamResult(sw); System.setProperty("http.agent", "Java Agent"); - marc.transform(new URL("http://www.loc.gov/standards/mods/v3/MARC21slim2MODS3.xsl"), result); + marc.transform(TransformerFactory.newInstance(), + new URL("http://www.loc.gov/standards/mods/v3/MARC21slim2MODS3.xsl"), result); assertThat(sw.toString(), CompareMatcher.isIdenticalTo(getClass().getResource("summerland-mods-loc-goc.xml").openStream())); } - private class ClasspathResourceURIResolver implements URIResolver { + private static class ClasspathResourceURIResolver implements URIResolver { @Override public Source resolve(String href, String base) throws TransformerException { return new StreamSource(getClass().getResourceAsStream(href)); diff --git a/src/test/java/org/xbib/marc/tools/ToolTest.java b/src/test/java/org/xbib/marc/tools/ToolTest.java index 4c687e2..f17d897 100644 --- a/src/test/java/org/xbib/marc/tools/ToolTest.java +++ b/src/test/java/org/xbib/marc/tools/ToolTest.java @@ -1,8 +1,9 @@ package org.xbib.marc.tools; +import org.junit.jupiter.api.Disabled; import org.junit.jupiter.api.Test; -import org.junit.jupiter.params.ParameterizedTest; +@Disabled("system exit ends testing?") public class ToolTest { @Test diff --git a/src/test/java/org/xbib/marc/xml/MarcEventConsumerTest.java b/src/test/java/org/xbib/marc/xml/MarcEventConsumerTest.java index ed3d987..80103d7 100644 --- a/src/test/java/org/xbib/marc/xml/MarcEventConsumerTest.java +++ b/src/test/java/org/xbib/marc/xml/MarcEventConsumerTest.java @@ -8,6 +8,7 @@ import org.xmlunit.matchers.CompareMatcher; import java.io.InputStream; import java.io.StringWriter; import java.nio.charset.StandardCharsets; +import javax.xml.stream.XMLInputFactory; /** * @@ -44,7 +45,7 @@ public class MarcEventConsumerTest { .setFormat("AlephXML") .setType("Bibliographic") .build() - .parseEvents(consumer); + .parseEvents(XMLInputFactory.newFactory(), consumer); writer.endCollection(); writer.endDocument(); sw.close();