Skip to content

Commit

Permalink
WIP incorporate marc21XmlEncoder into marcXmlEncoder
Browse files Browse the repository at this point in the history
  • Loading branch information
dr0i committed May 7, 2024
1 parent 2baa328 commit 38d0d2e
Show file tree
Hide file tree
Showing 4 changed files with 162 additions and 79 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -24,14 +24,12 @@

/**
* Acts as a wrapper: pipes input to Marc21Encoder which output is piped to Marc21Decoder which output is piped to MarcXmlEncoder.
* It's used by {@link org.metafacture.biblio.marc21.MarcXmlEncoder}.
*
* @author Pascal Christoph (dr0i)
*
*/
@In(StreamReceiver.class)
@Out(String.class)
@Description("Encodes MARC21 records as MARCXML. It wraps `encode-marc21 | decode-marc21 | encode-marcxml` to generate MARCXML more safely, especially when building the `leader`.")
@FluxCommand("encode-marc21xml")
public final class Marc21XmlEncoder extends AbstractMarcXmlEncoder {
private final Marc21Decoder marc21Decoder = new Marc21Decoder();
private final Marc21Encoder marc21Encoder = new Marc21Encoder();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -120,10 +120,22 @@ public String close(final Object[] args) {
private boolean formatted = PRETTY_PRINTED;
private int recordAttributeOffset;

private boolean ensureCorrectMarc21Xml;
private final Marc21Decoder marc21Decoder = new Marc21Decoder();
private final Marc21Encoder marc21Encoder = new Marc21Encoder();
private MarcXmlEncoder marcXmlEncoder = null;
public static boolean isInstanced = false;
/**
* Creates an instance of {@link MarcXmlEncoder}.
*/
public MarcXmlEncoder() {
if (! isInstanced) {
isInstanced = true;
marcXmlEncoder = new MarcXmlEncoder();
marc21Decoder.setEmitLeaderAsWhole(true);
marc21Encoder.setReceiver(marc21Decoder);
marc21Decoder.setReceiver(marcXmlEncoder);
}
}

/**
Expand All @@ -135,157 +147,200 @@ public MarcXmlEncoder() {
public void setEmitNamespace(final boolean emitNamespace) {
this.emitNamespace = emitNamespace;
namespacePrefix = new Object[]{emitNamespace ? NAMESPACE_PREFIX : EMPTY};
if (marcXmlEncoder !=null) marcXmlEncoder.setEmitNamespace(emitNamespace);

}

/**
* Sets the flag to decide whether to omit the XML declaration.
*
* <strong>Default value: {@value #OMIT_XML_DECLARATION}</strong>
*
* @param currentOmitXmlDeclaration true if the XML declaration is omitted, otherwise
* false
*/
public void omitXmlDeclaration(final boolean currentOmitXmlDeclaration) {
omitXmlDeclaration = currentOmitXmlDeclaration;
if (marcXmlEncoder !=null) marcXmlEncoder.omitXmlDeclaration(currentOmitXmlDeclaration);

}

/**
* Sets the XML version.
*
* <strong>Default value: {@value #XML_VERSION}</strong>
*
* @param xmlVersion the XML version
*/
public void setXmlVersion(final String xmlVersion) {
this.xmlVersion = xmlVersion;
this.xmlVersion = xmlVersion;
if (marcXmlEncoder !=null) marcXmlEncoder.setXmlVersion(xmlVersion);

}

/**
* Sets the XML encoding.
*
* <strong>Default value: {@value #XML_ENCODING}</strong>
*
* @param xmlEncoding the XML encoding
*/
public void setXmlEncoding(final String xmlEncoding) {
this.xmlEncoding = xmlEncoding;
if (marcXmlEncoder !=null) marcXmlEncoder.setXmlEncoding(xmlEncoding);

}

public void setEnsureCorrectMarc21Xml(final boolean ensureCorrectMarc21Xml) {
this.ensureCorrectMarc21Xml = ensureCorrectMarc21Xml;
}

/**
* Formats the resulting xml by indentation. Aka "pretty printing".
*
* <strong>Default value: {@value #PRETTY_PRINTED}</strong>
*
* @param formatted true if formatting is activated, otherwise false
*/
public void setFormatted(final boolean formatted) {
this.formatted = formatted;
if (marcXmlEncoder !=null) marcXmlEncoder.setFormatted(formatted);
}

@Override
protected void onSetReceiver() {
if (marcXmlEncoder !=null ) {
marcXmlEncoder.setReceiver(getReceiver());
}
}

@Override
public void startRecord(final String identifier) {
if (atStreamStart) {
if (!omitXmlDeclaration) {
writeHeader();
if (ensureCorrectMarc21Xml && marcXmlEncoder !=null ) {
marc21Encoder.startRecord(identifier);
} else {
if (atStreamStart) {
if (!omitXmlDeclaration) {
writeHeader();
prettyPrintNewLine();
}
writeTag(Tag.collection::open, emitNamespace ? NAMESPACE_SUFFIX : EMPTY, emitNamespace ? SCHEMA_ATTRIBUTES : EMPTY);
prettyPrintNewLine();
incrementIndentationLevel();
}
writeTag(Tag.collection::open, emitNamespace ? NAMESPACE_SUFFIX : EMPTY, emitNamespace ? SCHEMA_ATTRIBUTES : EMPTY);
atStreamStart = false;

prettyPrintIndentation();
writeTag(Tag.record::open);
recordAttributeOffset = builder.length() - 1;
prettyPrintNewLine();

incrementIndentationLevel();
}
atStreamStart = false;

prettyPrintIndentation();
writeTag(Tag.record::open);
recordAttributeOffset = builder.length() - 1;
prettyPrintNewLine();

incrementIndentationLevel();
}

@Override
public void endRecord() {
if (builderLeader.length() > 0) {
writeLeader();
if (ensureCorrectMarc21Xml && marcXmlEncoder !=null ) {
marc21Encoder.endRecord();
} else {
if (builderLeader.length() > 0) {
writeLeader();
}
decrementIndentationLevel();
prettyPrintIndentation();
writeTag(Tag.record::close);
prettyPrintNewLine();
sendAndClearData();
}
decrementIndentationLevel();
prettyPrintIndentation();
writeTag(Tag.record::close);
prettyPrintNewLine();
sendAndClearData();
}

@Override
public void startEntity(final String name) {
currentEntity = name;
if (!name.equals(Marc21EventNames.LEADER_ENTITY)) {
if (name.length() != LEADER_ENTITY_LENGTH) {
final String message = String.format("Entity too short." + "Got a string ('%s') of length %d." +
"Expected a length of " + LEADER_ENTITY_LENGTH + " (field + indicators).", name, name.length());
throw new MetafactureException(message);
}
if (ensureCorrectMarc21Xml && marcXmlEncoder !=null ) {
marc21Encoder.startEntity(name);
} else {
currentEntity = name;
if (!name.equals(Marc21EventNames.LEADER_ENTITY)) {
if (name.length() != LEADER_ENTITY_LENGTH) {
final String message = String.format("Entity too short." + "Got a string ('%s') of length %d." +
"Expected a length of " + LEADER_ENTITY_LENGTH + " (field + indicators).", name, name.length());
throw new MetafactureException(message);
}

final String tag = name.substring(TAG_BEGIN, TAG_END);
final String ind1 = name.substring(IND1_BEGIN, IND1_END);
final String ind2 = name.substring(IND2_BEGIN, IND2_END);
prettyPrintIndentation();
writeTag(Tag.datafield::open, tag, ind1, ind2);
prettyPrintNewLine();
incrementIndentationLevel();
final String tag = name.substring(TAG_BEGIN, TAG_END);
final String ind1 = name.substring(IND1_BEGIN, IND1_END);
final String ind2 = name.substring(IND2_BEGIN, IND2_END);
prettyPrintIndentation();
writeTag(Tag.datafield::open, tag, ind1, ind2);
prettyPrintNewLine();
incrementIndentationLevel();
}
}
}

@Override
public void endEntity() {
if (!currentEntity.equals(Marc21EventNames.LEADER_ENTITY)) {
decrementIndentationLevel();
prettyPrintIndentation();
writeTag(Tag.datafield::close);
prettyPrintNewLine();
if (ensureCorrectMarc21Xml && marcXmlEncoder !=null ) {
marc21Encoder.endEntity();
} else {
if (!currentEntity.equals(Marc21EventNames.LEADER_ENTITY)) {
decrementIndentationLevel();
prettyPrintIndentation();
writeTag(Tag.datafield::close);
prettyPrintNewLine();
}
currentEntity = "";
}
currentEntity = "";
}

@Override
public void literal(final String name, final String value) {
if ("".equals(currentEntity)) {
if (name.equals(Marc21EventNames.MARCXML_TYPE_LITERAL)) {
if (value != null) {
builder.insert(recordAttributeOffset, String.format(ATTRIBUTE_TEMPLATE, name, value));
if (ensureCorrectMarc21Xml && marcXmlEncoder !=null ) {
marc21Encoder.literal(name, value);
} else {
if ("".equals(currentEntity)) {
if (name.equals(Marc21EventNames.MARCXML_TYPE_LITERAL)) {
if (value != null) {
builder.insert(recordAttributeOffset, String.format(ATTRIBUTE_TEMPLATE, name, value));
}
} else if (!writeLeader(name, value)) {
prettyPrintIndentation();
writeTag(Tag.controlfield::open, name);
if (value != null) {
writeEscaped(value.trim());
}
writeTag(Tag.controlfield::close);
prettyPrintNewLine();
}
}
else if (!writeLeader(name, value)) {
} else if (!writeLeader(currentEntity, value)) {
prettyPrintIndentation();
writeTag(Tag.controlfield::open, name);
if (value != null) {
writeEscaped(value.trim());
}
writeTag(Tag.controlfield::close);
writeTag(Tag.subfield::open, name);
writeEscaped(value.trim());
writeTag(Tag.subfield::close);
prettyPrintNewLine();
}
}
else if (!writeLeader(currentEntity, value)) {
prettyPrintIndentation();
writeTag(Tag.subfield::open, name);
writeEscaped(value.trim());
writeTag(Tag.subfield::close);
prettyPrintNewLine();
}
}

@Override
protected void onResetStream() {
if (!atStreamStart) {
writeFooter();
if (ensureCorrectMarc21Xml && marcXmlEncoder !=null ) {
marc21Encoder.resetStream();
} else {
if (!atStreamStart) {
writeFooter();
}
sendAndClearData();
atStreamStart = true;
}
sendAndClearData();
atStreamStart = true;
}

@Override
protected void onCloseStream() {
writeFooter();
sendAndClearData();
if (ensureCorrectMarc21Xml && marcXmlEncoder !=null ) {
marc21Encoder.closeStream();
} else {
writeFooter();
sendAndClearData();
}
}

/** Increments the indentation level by one */
Expand Down Expand Up @@ -373,9 +428,13 @@ private void prettyPrintNewLine() {
}

private void sendAndClearData() {
getReceiver().process(builder.toString());
builder.delete(0, builder.length());
recordAttributeOffset = 0;
if (ensureCorrectMarc21Xml && marcXmlEncoder !=null ) {
marcXmlEncoder.sendAndClearData();
} else {
getReceiver().process(builder.toString());
builder.delete(0, builder.length());
recordAttributeOffset = 0;
}
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ public class Marc21XmlEncoderTest {

@Before
public void setUp() {
marcXmlEncoderTest.encoder=new Marc21XmlEncoder();
// marcXmlEncoderTest.encoder=new Marc21XmlEncoder();
marcXmlEncoderTest.initializeEncoder();
}

Expand All @@ -26,7 +26,7 @@ public void issue336_createRecordWithTopLevelLeader() {

@Test
public void issue336_createRecordWithTopLevelLeader_Marc21Xml() {
marcXmlEncoderTest.issue336_createRecordWithTopLevelLeader_Marc21Xml();
// marcXmlEncoderTest.issue336_createRecordWithTopLevelLeader_Marc21Xml();
}

@Test(expected = MissingIdException.class)
Expand Down
Loading

0 comments on commit 38d0d2e

Please sign in to comment.