diff --git a/metafacture-biblio/src/main/java/org/metafacture/biblio/iso2709/Iso2709Constants.java b/metafacture-biblio/src/main/java/org/metafacture/biblio/iso2709/Iso2709Constants.java index ebe9475c8..02a7ec3f7 100644 --- a/metafacture-biblio/src/main/java/org/metafacture/biblio/iso2709/Iso2709Constants.java +++ b/metafacture-biblio/src/main/java/org/metafacture/biblio/iso2709/Iso2709Constants.java @@ -23,9 +23,13 @@ * @author Christoph Böhme * */ -final class Iso2709Constants { +public final class Iso2709Constants { - static final int RECORD_LABEL_LENGTH = 24; + public static final int IMPL_CODES_START = 6; + public static final int IMPL_CODES_LENGTH = 4; + public static final int RECORD_LABEL_LENGTH = 24; + public static final int RECORD_STATUS_POS = 5; + public static final int SYSTEM_CHARS_START = 17; static final int MIN_RECORD_LENGTH = RECORD_LABEL_LENGTH + 2; static final int MAX_RECORD_LENGTH = 99_999; @@ -38,18 +42,11 @@ final class Iso2709Constants { static final int RECORD_LENGTH_START = 0; static final int RECORD_LENGTH_LENGTH = 5; - static final int RECORD_STATUS_POS = 5; - - static final int IMPL_CODES_START = 6; - static final int IMPL_CODES_LENGTH = 4; - static final int INDICATOR_LENGTH_POS = 10; static final int IDENTIFIER_LENGTH_POS = 11; static final int BASE_ADDRESS_START = 12; static final int BASE_ADDRESS_LENGTH = 5; - - static final int SYSTEM_CHARS_START = 17; static final int SYSTEM_CHARS_LENGTH = 3; static final int FIELD_LENGTH_LENGTH_POS = 20; diff --git a/metafacture-biblio/src/main/java/org/metafacture/biblio/marc21/Marc21Encoder.java b/metafacture-biblio/src/main/java/org/metafacture/biblio/marc21/Marc21Encoder.java index 876f85203..3cd536fe7 100644 --- a/metafacture-biblio/src/main/java/org/metafacture/biblio/marc21/Marc21Encoder.java +++ b/metafacture-biblio/src/main/java/org/metafacture/biblio/marc21/Marc21Encoder.java @@ -16,6 +16,7 @@ package org.metafacture.biblio.marc21; +import org.metafacture.biblio.iso2709.Iso2709Constants; import org.metafacture.biblio.iso2709.RecordBuilder; import org.metafacture.biblio.iso2709.RecordFormat; import org.metafacture.framework.FluxCommand; @@ -180,7 +181,12 @@ public void literal(final String name, final String value) { builder.appendSubfield(name.toCharArray(), value); break; case IN_LEADER_ENTITY: - processLiteralInLeader(name, value); + if (name == Marc21EventNames.LEADER_ENTITY) { + processLeaderAsOneLiteral(value); + } + else { + processLeaderAsSubfields(name, value); + } break; case IN_RECORD: processTopLevelLiteral(name, value); @@ -190,12 +196,30 @@ public void literal(final String name, final String value) { } } - private void processLiteralInLeader(final String name, final String value) { + private void processLeaderAsOneLiteral(final String value) { + if (value.length() != Iso2709Constants.RECORD_LABEL_LENGTH) { + throw new FormatException( + "leader literal must contain " + Iso2709Constants.RECORD_LABEL_LENGTH + " characters: " + value); + } + processLeaderAsSubfields(Marc21EventNames.RECORD_STATUS_LITERAL, value.charAt(Iso2709Constants.RECORD_STATUS_POS)); + processLeaderAsSubfields(Marc21EventNames.RECORD_TYPE_LITERAL, value.charAt(Iso2709Constants.IMPL_CODES_START)); + processLeaderAsSubfields(Marc21EventNames.BIBLIOGRAPHIC_LEVEL_LITERAL, value.charAt(Iso2709Constants.IMPL_CODES_START + 1)); + processLeaderAsSubfields(Marc21EventNames.TYPE_OF_CONTROL_LITERAL, value.charAt(Iso2709Constants.IMPL_CODES_START + 2)); + processLeaderAsSubfields(Marc21EventNames.CHARACTER_CODING_LITERAL, value.charAt(Iso2709Constants.RECORD_STATUS_POS + Iso2709Constants.IMPL_CODES_LENGTH)); + processLeaderAsSubfields(Marc21EventNames.ENCODING_LEVEL_LITERAL, value.charAt(Iso2709Constants.SYSTEM_CHARS_START)); + processLeaderAsSubfields(Marc21EventNames.CATALOGING_FORM_LITERAL, value.charAt(Iso2709Constants.SYSTEM_CHARS_START + 1)); + processLeaderAsSubfields(Marc21EventNames.MULTIPART_LEVEL_LITERAL, value.charAt(Iso2709Constants.SYSTEM_CHARS_START + 2)); + } + + private void processLeaderAsSubfields(final String name, final String value) { if (value.length() != 1) { throw new FormatException( "literal must only contain a single character:" + name); } - final char code = value.charAt(0); + processLeaderAsSubfields(name, value.charAt(0)); + } + + private void processLeaderAsSubfields(final String name, final char code) { switch (name) { case Marc21EventNames.RECORD_STATUS_LITERAL: requireValidCode(code, Marc21Constants.RECORD_STATUS_CODES); @@ -251,7 +275,12 @@ private void processTopLevelLiteral(final String name, final String value) { // these literals here. return; } - builder.appendReferenceField(name.toCharArray(), value); + if (Marc21EventNames.LEADER_ENTITY.equals(name)) { + processLeaderAsOneLiteral(value); + } + else { + builder.appendReferenceField(name.toCharArray(), value); + } } @Override diff --git a/metafacture-biblio/src/test/java/org/metafacture/biblio/marc21/Marc21EncoderTest.java b/metafacture-biblio/src/test/java/org/metafacture/biblio/marc21/Marc21EncoderTest.java index 41e8d2b6c..e8e70325d 100644 --- a/metafacture-biblio/src/test/java/org/metafacture/biblio/marc21/Marc21EncoderTest.java +++ b/metafacture-biblio/src/test/java/org/metafacture/biblio/marc21/Marc21EncoderTest.java @@ -114,4 +114,37 @@ public void issue278ShouldNotFailWhenProcessingLeaderEntity() { verify(receiver).process(any(String.class)); } + @Test + public void issue454ShouldNotFailWhenProcessingEntityLeaderAsOneString() { + marc21Encoder.startRecord(""); + marc21Encoder.startEntity(LEADER_ENTITY); + marc21Encoder.literal(LEADER_ENTITY, "02602pam a2200529 c 4500"); + marc21Encoder.endEntity(); + marc21Encoder.endRecord(); + + verify(receiver).process(matches("00026pam a2200025 c 4500\u001e\u001d")); + } + + @Test + public void issue454ShouldNotFailWhenProcessingLeaderAsOneString() { + marc21Encoder.startRecord(""); + marc21Encoder.literal(LEADER_ENTITY, "02602pam a2200529 c 4500"); + marc21Encoder.endRecord(); + + verify(receiver).process(matches("00026pam a2200025 c 4500\u001e\u001d")); + } + + @Test + public void issue524ShouldComputeValidLeader() { + marc21Encoder.startRecord(""); + marc21Encoder.literal(LEADER_ENTITY, "00000pam a7777777 c 4444"); + marc21Encoder.startEntity("021a "); + marc21Encoder.literal("v", "Fritz"); + marc21Encoder.literal("n", "Bauer"); + marc21Encoder.endEntity(); + marc21Encoder.endRecord(); + + verify(receiver).process(matches("00055pam a2200037 c 4500021001700000\u001e.*\u001d")); + } + }