From 5776707039c2a44e209c3a594004b68f329fd15c Mon Sep 17 00:00:00 2001 From: Jens Wille Date: Wed, 19 Jun 2024 15:10:37 +0200 Subject: [PATCH] Emit top-level MARC record leader as single element. (#527) See also #336. Co-authored-by: Pascal Christoph --- .../biblio/marc21/MarcXmlEncoder.java | 28 ++++++--- .../biblio/marc21/MarcXmlEncoderTest.java | 61 +++++++++++++++---- 2 files changed, 68 insertions(+), 21 deletions(-) diff --git a/metafacture-biblio/src/main/java/org/metafacture/biblio/marc21/MarcXmlEncoder.java b/metafacture-biblio/src/main/java/org/metafacture/biblio/marc21/MarcXmlEncoder.java index 7b4440a4d..928859360 100644 --- a/metafacture-biblio/src/main/java/org/metafacture/biblio/marc21/MarcXmlEncoder.java +++ b/metafacture-biblio/src/main/java/org/metafacture/biblio/marc21/MarcXmlEncoder.java @@ -105,6 +105,7 @@ public String close(final Object[] args) { private static final int TAG_END = 3; private final StringBuilder builder = new StringBuilder(); + private final StringBuilder leaderBuilder = new StringBuilder(); private boolean atStreamStart = true; @@ -206,6 +207,7 @@ public void startRecord(final String identifier) { @Override public void endRecord() { + writeLeader(); decrementIndentationLevel(); prettyPrintIndentation(); writeTag(Tag.record::close); @@ -252,7 +254,7 @@ public void literal(final String name, final String value) { builder.insert(recordAttributeOffset, String.format(ATTRIBUTE_TEMPLATE, name, value)); } } - else if (!writeLeader(name, value)) { + else if (!appendLeader(name, value)) { prettyPrintIndentation(); writeTag(Tag.controlfield::open, name); if (value != null) { @@ -262,7 +264,7 @@ else if (!writeLeader(name, value)) { prettyPrintNewLine(); } } - else if (!writeLeader(currentEntity, value)) { + else if (!appendLeader(currentEntity, value)) { prettyPrintIndentation(); writeTag(Tag.subfield::open, name); writeEscaped(value.trim()); @@ -316,6 +318,16 @@ private void writeRaw(final String str) { builder.append(str); } + private boolean appendLeader(final String name, final String value) { + if (name.equals(Marc21EventNames.LEADER_ENTITY)) { + leaderBuilder.append(value); + return true; + } + else { + return false; + } + } + /** * Writes an escaped sequence. * @@ -325,18 +337,14 @@ private void writeEscaped(final String str) { builder.append(XmlUtil.escape(str, false)); } - private boolean writeLeader(final String name, final String value) { - if (name.equals(Marc21EventNames.LEADER_ENTITY)) { + private void writeLeader() { + final String leader = leaderBuilder.toString(); + if (!leader.isEmpty()) { prettyPrintIndentation(); writeTag(Tag.leader::open); - writeRaw(value); + writeRaw(leader); writeTag(Tag.leader::close); prettyPrintNewLine(); - - return true; - } - else { - return false; } } diff --git a/metafacture-biblio/src/test/java/org/metafacture/biblio/marc21/MarcXmlEncoderTest.java b/metafacture-biblio/src/test/java/org/metafacture/biblio/marc21/MarcXmlEncoderTest.java index bc6fb0d49..00f497b05 100644 --- a/metafacture-biblio/src/test/java/org/metafacture/biblio/marc21/MarcXmlEncoderTest.java +++ b/metafacture-biblio/src/test/java/org/metafacture/biblio/marc21/MarcXmlEncoderTest.java @@ -16,14 +16,14 @@ package org.metafacture.biblio.marc21; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertTrue; +import org.metafacture.framework.MetafactureException; +import org.metafacture.framework.helpers.DefaultObjectReceiver; -import org.junit.After; import org.junit.Before; import org.junit.Test; -import org.metafacture.framework.MetafactureException; -import org.metafacture.framework.helpers.DefaultObjectReceiver; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; /** * Tests for class {@link MarcXmlEncoder}. @@ -63,11 +63,7 @@ public void process(final String obj) { resultCollector = new StringBuilder(); } - @After - public void tearDown() { - } - - private void addOneRecord(MarcXmlEncoder encoder) { + private void addOneRecord(final MarcXmlEncoder encoder) { encoder.startRecord(RECORD_ID); encoder.literal("001", RECORD_ID); encoder.startEntity("010 "); @@ -201,7 +197,7 @@ public void createAnRecordWithLeader() { } @Test - public void issue336_createRecordWithTopLevelLeader() { + public void issue336_createRecordWithTopLevelLeader_dummy() { encoder.startRecord("1"); encoder.literal(Marc21EventNames.LEADER_ENTITY, "dummy"); encoder.endRecord(); @@ -212,6 +208,49 @@ public void issue336_createRecordWithTopLevelLeader() { assertEquals(expected, actual); } + @Test + public void issue336_createRecordWithTopLevelLeader_defaultMarc21Xml() { + issue336_createRecordWithTopLevelLeader(encoder, "00000naa a2200000uc 4500"); + } + + private void issue336_createRecordWithTopLevelLeader(final MarcXmlEncoder encoder, final String expectedLeader) { + encoder.startRecord("1"); + encoder.literal("001", "8u3287432"); + encoder.literal(Marc21EventNames.LEADER_ENTITY, "00000naa a2200000uc 4500"); + encoder.endRecord(); + encoder.closeStream(); + String expected = XML_DECLARATION + XML_ROOT_OPEN + + "8u3287432" + + "" + expectedLeader + "" + XML_MARC_COLLECTION_END_TAG; + String actual = resultCollector.toString(); + assertEquals(expected, actual); + } + + @Test + public void issue527_shouldEmitLeaderAlwaysAsWholeString() { + issue527_shouldEmitLeaderAlwaysAsWholeString(encoder); + } + + private void issue527_shouldEmitLeaderAlwaysAsWholeString(final MarcXmlEncoder encoder) { + encoder.startRecord("1"); + encoder.startEntity(Marc21EventNames.LEADER_ENTITY); + encoder.literal(Marc21EventNames.RECORD_STATUS_LITERAL, "a"); + encoder.literal(Marc21EventNames.RECORD_TYPE_LITERAL, "o"); + encoder.literal(Marc21EventNames.BIBLIOGRAPHIC_LEVEL_LITERAL, "a"); + encoder.literal(Marc21EventNames.TYPE_OF_CONTROL_LITERAL, " "); + encoder.literal(Marc21EventNames.CHARACTER_CODING_LITERAL, "a"); + encoder.literal(Marc21EventNames.ENCODING_LEVEL_LITERAL, "z"); + encoder.literal(Marc21EventNames.CATALOGING_FORM_LITERAL, "u"); + encoder.literal(Marc21EventNames.MULTIPART_LEVEL_LITERAL, " "); + encoder.endEntity(); + encoder.endRecord(); + encoder.closeStream(); + String expected = XML_DECLARATION + XML_ROOT_OPEN + + "aoa azu " + XML_MARC_COLLECTION_END_TAG; + String actual = resultCollector.toString(); + assertEquals(expected, actual); + } + @Test public void sendDataAndClearWhenRecordStartedAndStreamResets() { encoder.startRecord("1");