Skip to content

Commit ca71bb6

Browse files
committed
Ensure marc:leader to be emitted first (#548)
1 parent e3cf044 commit ca71bb6

File tree

2 files changed

+40
-8
lines changed

2 files changed

+40
-8
lines changed

metafacture-biblio/src/main/java/org/metafacture/biblio/marc21/MarcXmlEncoder.java

Lines changed: 23 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -252,6 +252,7 @@ private static class Encoder extends DefaultStreamPipe<ObjectReceiver<String>> {
252252
private int indentationLevel;
253253
private boolean formatted = PRETTY_PRINTED;
254254
private int recordAttributeOffset;
255+
private int recordLeaderOffset;
255256

256257
private Encoder() {
257258
}
@@ -294,7 +295,7 @@ public void startRecord(final String identifier) {
294295
writeTag(Tag.record::open);
295296
recordAttributeOffset = builder.length() - 1;
296297
prettyPrintNewLine();
297-
298+
recordLeaderOffset = builder.length();
298299
incrementIndentationLevel();
299300
}
300301

@@ -353,7 +354,7 @@ else if (!appendLeader(name, value)) {
353354
if (value != null) {
354355
writeEscaped(value.trim());
355356
}
356-
writeTag(Tag.controlfield::close);
357+
writeTag(Tag.controlfield::close, false);
357358
prettyPrintNewLine();
358359
}
359360
}
@@ -408,9 +409,20 @@ private void writeFooter() {
408409
* @param str the unescaped sequence to be written
409410
*/
410411
private void writeRaw(final String str) {
412+
411413
builder.append(str);
412414
}
413415

416+
/**
417+
* Writes the unescaped sequence to the leader position.
418+
*
419+
* @param str the unescaped sequence to be written to the leader position
420+
*/
421+
private void writeRawLeader(final String str) {
422+
builder.insert(recordLeaderOffset, str);
423+
recordLeaderOffset = recordLeaderOffset + str.length();
424+
}
425+
414426
private boolean appendLeader(final String name, final String value) {
415427
if (name.equals(Marc21EventNames.LEADER_ENTITY)) {
416428
leaderBuilder.append(value);
@@ -432,11 +444,11 @@ private void writeEscaped(final String str) {
432444

433445
private void writeLeader() {
434446
final String leader = leaderBuilder.toString();
435-
if (!leader.isEmpty()) {
447+
if (leaderBuilder.length() > 0) {
436448
prettyPrintIndentation();
437-
writeTag(Tag.leader::open);
438-
writeRaw(leader);
439-
writeTag(Tag.leader::close);
449+
writeTagLeader(Tag.leader::open);
450+
writeRawLeader(leader);
451+
writeTagLeader(Tag.leader::close);
440452
prettyPrintNewLine();
441453
}
442454
}
@@ -447,6 +459,11 @@ private void writeTag(final Function<Object[], String> function, final Object...
447459
writeRaw(function.apply(allArgs));
448460
}
449461

462+
private void writeTagLeader(final Function<Object[], String> function) {
463+
writeRawLeader(function.apply(namespacePrefix));
464+
}
465+
466+
450467
private void prettyPrintIndentation() {
451468
if (formatted) {
452469
final String prefix = String.join("", Collections.nCopies(indentationLevel, INDENT));

metafacture-biblio/src/test/java/org/metafacture/biblio/marc21/MarcXmlEncoderTest.java

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
import org.junit.Test;
2626

2727
import static org.junit.Assert.assertEquals;
28+
import static org.junit.Assert.assertNotEquals;
2829
import static org.junit.Assert.assertTrue;
2930

3031
/**
@@ -249,12 +250,26 @@ private void issue336_createRecordWithTopLevelLeader(final MarcXmlEncoder encode
249250
encoder.endRecord();
250251
encoder.closeStream();
251252
String expected = XML_DECLARATION + XML_ROOT_OPEN
252-
+ "<marc:record><marc:controlfield tag=\"001\">8u3287432</marc:controlfield>" +
253-
"<marc:leader>" + expectedLeader + "</marc:leader></marc:record>" + XML_MARC_COLLECTION_END_TAG;
253+
+ "<marc:record><marc:leader>" + expectedLeader + "</marc:leader>" +
254+
"<marc:controlfield tag=\"001\">8u3287432</marc:controlfield></marc:record>" + XML_MARC_COLLECTION_END_TAG;
254255
String actual = resultCollector.toString();
255256
assertEquals(expected, actual);
256257
}
257258

259+
@Test
260+
public void issue548_failWhenLeaderIsNotFirst() {
261+
encoder.startRecord("1");
262+
encoder.literal("001", "8u3287432");
263+
encoder.literal(Marc21EventNames.LEADER_ENTITY, "00000naa a2200000uc 4500");
264+
encoder.endRecord();
265+
encoder.closeStream();
266+
String expected = XML_DECLARATION + XML_ROOT_OPEN
267+
+ "<marc:record><marc:controlfield tag=\"001\">8u3287432</marc:controlfield>" +
268+
"<marc:leader>00000naa a2200000uc 4500</marc:leader></marc:record>" + XML_MARC_COLLECTION_END_TAG;
269+
String actual = resultCollector.toString();
270+
assertNotEquals(expected, actual);
271+
}
272+
258273
@Test
259274
public void issue527_shouldEmitLeaderAlwaysAsWholeString() {
260275
createRecordWithLeader("1", "a", "o", "a", " ", "a", "z", "u", " ");

0 commit comments

Comments
 (0)