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 3cd536fe..fb8ad50b 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 @@ -81,6 +81,7 @@ public final class Marc21Encoder extends private State state = State.IN_STREAM; private boolean generateIdField; + private boolean validateLeader = true; /** * Initializes the encoder with MARC 21 constants and charset. @@ -108,6 +109,18 @@ public void setGenerateIdField(final boolean generateIdField) { this.generateIdField = generateIdField; } + /** + * Controls whether the leader should be validated. + *
+ * The default value of {@code validateLeader} is true. + *
+ *
+ * @param validateLeader if false the leader is not validated
+ */
+ public void setValidateLeader(final boolean validateLeader) {
+ this.validateLeader = validateLeader;
+ }
+
/**
* Gets the flag to decide whether the ID field is generated.
*
@@ -259,12 +272,14 @@ private void processLeaderAsSubfields(final String name, final char code) {
}
private void requireValidCode(final char code, final char[] validCodes) {
- for (final char validCode: validCodes) {
- if (validCode == code) {
- return;
+ if (validateLeader) {
+ for (final char validCode : validCodes) {
+ if (validCode == code) {
+ return;
+ }
}
+ throw new FormatException("invalid code '" + code + "'; allowed codes are: " + Arrays.toString(validCodes));
}
- throw new FormatException("invalid code '" + code + "'; allowed codes are: " + Arrays.toString(validCodes));
}
private void processTopLevelLiteral(final String name, final String value) {
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 3113a324..19bc9888 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
@@ -95,6 +95,11 @@ public String close(final Object[] args) {
private static final int LEADER_ENTITY_LENGTH = 5;
+ private static final int LEADER_CONCAT_ENTITIES_LENGTH = 8;
+ private static final int LEADER_CONCAT_ENTITIES_POS_04 = 4;
+ private static final int LEADER_CONCAT_ENTITIES_POS_05 = 5;
+ private static final int LEADER_CONCAT_ENTITIES_POS_07 = 7;
+
private static final int IND1_BEGIN = 3;
private static final int IND1_END = 4;
private static final int IND2_BEGIN = 4;
@@ -445,7 +450,12 @@ private void writeLeader() {
}
writeTagLeader(Tag.leader::open);
- writeRawLeader(leader);
+ if (leader.length() == LEADER_CONCAT_ENTITIES_LENGTH) {
+ writeRawLeader("0000" + leader.substring(0, LEADER_CONCAT_ENTITIES_POS_04) + "2200000" + leader.substring(LEADER_CONCAT_ENTITIES_POS_05, LEADER_CONCAT_ENTITIES_POS_07) + "4500"); // creates a valid leader without counted elements
+ }
+ else {
+ writeRawLeader(leader);
+ }
writeTagLeader(Tag.leader::close);
if (formatted) {
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 e8e70325..f81d864c 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
@@ -38,6 +38,8 @@
*/
public final class Marc21EncoderTest {
+ private static final String BAD_LEADER = "00600ny a22002053n 4500";
+
private Marc21Encoder marc21Encoder;
@Mock
@@ -147,4 +149,21 @@ public void issue524ShouldComputeValidLeader() {
verify(receiver).process(matches("00055pam a2200037 c 4500021001700000\u001e.*\u001d"));
}
+ @Test(expected = FormatException.class)
+ public void issue567ShouldFailValidateLeaderAsDefault() {
+ marc21Encoder.startRecord("");
+ marc21Encoder.literal(LEADER_ENTITY, BAD_LEADER);
+ marc21Encoder.endRecord();
+ }
+
+ @Test
+ public void issue567ShouldNotValidateLeader() {
+ marc21Encoder.setValidateLeader(false);
+ marc21Encoder.startRecord("");
+ marc21Encoder.literal(LEADER_ENTITY, BAD_LEADER );
+ marc21Encoder.endRecord();
+
+ verify(receiver).process(matches("00026ny a22000253n 4500\u001e\u001d"));
+ }
+
}
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 2e1c8df2..5d62ff24 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
@@ -301,13 +301,13 @@ public void issue548_failWhenLeaderIsNotFirst() {
}
@Test
- public void issue527_shouldEmitLeaderAlwaysAsWholeString() {
+ public void issue527_shouldEmitLeaderAlwaysAsWholeStringWithAddedDefaultLeaderValuesIfLeaderLengthIs8() {
createRecordWithLeader("1", "a", "o", "a", " ", "a", "z", "u", " ");
createRecordWithLeader("2", "d", "u", "m", " ", "m", "y", "#", " ");
encoder.closeStream();
String expected = XML_DECLARATION + XML_ROOT_OPEN
- + "