@@ -49,9 +49,6 @@ public final class MarcXmlEncoder extends DefaultStreamPipe<ObjectReceiver<Strin
4949 public static final boolean OMIT_XML_DECLARATION = false ;
5050 public static final boolean ENSURE_CORRECT_MARC21_XML = false ;
5151
52- private static final String ROOT_OPEN = "<marc:collection xmlns:marc=\" http://www.loc.gov/MARC21/slim\" xmlns:xsi=\" http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation=\" http://www.loc.gov/MARC21/slim http://www.loc.gov/standards/marcxml/schema/MARC21slim.xsd\" >" ;
53- private static final String ROOT_CLOSE = "</marc:collection>" ;
54-
5552 private enum Tag {
5653
5754 collection (" xmlns%s=\" " + NAMESPACE + "\" %s" ),
@@ -106,7 +103,6 @@ public String close(final Object[] args) {
106103 private static final int TAG_END = 3 ;
107104
108105 private final Encoder encoder = new Encoder ();
109- private final Marc21Decoder decoder = new Marc21Decoder ();
110106 private final Marc21Encoder wrapper = new Marc21Encoder ();
111107
112108 private DefaultStreamPipe <ObjectReceiver <String >> pipe ;
@@ -115,6 +111,7 @@ public String close(final Object[] args) {
115111 * Creates an instance of {@link MarcXmlEncoder}.
116112 */
117113 public MarcXmlEncoder () {
114+ final Marc21Decoder decoder = new Marc21Decoder ();
118115 decoder .setEmitLeaderAsWhole (true );
119116
120117 wrapper
@@ -136,7 +133,6 @@ public void setEmitNamespace(final boolean emitNamespace) {
136133
137134 /**
138135 * Sets the flag to decide whether to omit the XML declaration.
139- *
140136 * <strong>Default value: {@value #OMIT_XML_DECLARATION}</strong>
141137 *
142138 * @param currentOmitXmlDeclaration true if the XML declaration is omitted, otherwise
@@ -148,7 +144,6 @@ public void omitXmlDeclaration(final boolean currentOmitXmlDeclaration) {
148144
149145 /**
150146 * Sets the XML version.
151- *
152147 * <strong>Default value: {@value #XML_VERSION}</strong>
153148 *
154149 * @param xmlVersion the XML version
@@ -159,7 +154,6 @@ public void setXmlVersion(final String xmlVersion) {
159154
160155 /**
161156 * Sets the XML encoding.
162- *
163157 * <strong>Default value: {@value #XML_ENCODING}</strong>
164158 *
165159 * @param xmlEncoding the XML encoding
@@ -173,7 +167,6 @@ public void setXmlEncoding(final String xmlEncoding) {
173167 * If true, the input data is validated to ensure correct MARC21. Also the leader may be generated.
174168 * It acts as a wrapper: the input is piped to {@link org.metafacture.biblio.marc21.Marc21Encoder}, whose output is piped to {@link org.metafacture.biblio.marc21.Marc21Decoder}, whose output is piped to {@link org.metafacture.biblio.marc21.MarcXmlEncoder}.
175169 * This validation and treatment of the leader is more safe but comes with a performance impact.
176- *
177170 * <strong>Default value: {@value #ENSURE_CORRECT_MARC21_XML}</strong>
178171 *
179172 * @param ensureCorrectMarc21Xml if true the input data is validated to ensure correct MARC21. Also the leader may be generated.
@@ -184,7 +177,6 @@ public void setEnsureCorrectMarc21Xml(final boolean ensureCorrectMarc21Xml) {
184177
185178 /**
186179 * Formats the resulting xml by indentation. Aka "pretty printing".
187- *
188180 * <strong>Default value: {@value #PRETTY_PRINTED}</strong>
189181 *
190182 * @param formatted true if formatting is activated, otherwise false
@@ -247,11 +239,12 @@ private static class Encoder extends DefaultStreamPipe<ObjectReceiver<String>> {
247239 private String currentEntity = "" ;
248240
249241 private boolean emitNamespace = true ;
250- private Object [] namespacePrefix = new Object []{emitNamespace ? NAMESPACE_PREFIX : EMPTY };
242+ private Object [] namespacePrefix = new Object []{NAMESPACE_PREFIX };
251243
252244 private int indentationLevel ;
253245 private boolean formatted = PRETTY_PRINTED ;
254246 private int recordAttributeOffset ;
247+ private int recordLeaderOffset ;
255248
256249 private Encoder () {
257250 }
@@ -294,7 +287,7 @@ public void startRecord(final String identifier) {
294287 writeTag (Tag .record ::open );
295288 recordAttributeOffset = builder .length () - 1 ;
296289 prettyPrintNewLine ();
297-
290+ recordLeaderOffset = builder . length ();
298291 incrementIndentationLevel ();
299292 }
300293
@@ -353,7 +346,7 @@ else if (!appendLeader(name, value)) {
353346 if (value != null ) {
354347 writeEscaped (value .trim ());
355348 }
356- writeTag (Tag .controlfield ::close );
349+ writeTag (Tag .controlfield ::close , false );
357350 prettyPrintNewLine ();
358351 }
359352 }
@@ -408,9 +401,20 @@ private void writeFooter() {
408401 * @param str the unescaped sequence to be written
409402 */
410403 private void writeRaw (final String str ) {
404+
411405 builder .append (str );
412406 }
413407
408+ /**
409+ * Writes the unescaped sequence to the leader position.
410+ *
411+ * @param str the unescaped sequence to be written to the leader position
412+ */
413+ private void writeRawLeader (final String str ) {
414+ builder .insert (recordLeaderOffset , str );
415+ recordLeaderOffset = recordLeaderOffset + str .length ();
416+ }
417+
414418 private boolean appendLeader (final String name , final String value ) {
415419 if (name .equals (Marc21EventNames .LEADER_ENTITY )) {
416420 leaderBuilder .append (value );
@@ -432,11 +436,11 @@ private void writeEscaped(final String str) {
432436
433437 private void writeLeader () {
434438 final String leader = leaderBuilder .toString ();
435- if (! leader . isEmpty () ) {
439+ if (leaderBuilder . length () > 0 ) {
436440 prettyPrintIndentation ();
437- writeTag (Tag .leader ::open );
438- writeRaw (leader );
439- writeTag (Tag .leader ::close );
441+ writeTagLeader (Tag .leader ::open );
442+ writeRawLeader (leader );
443+ writeTagLeader (Tag .leader ::close );
440444 prettyPrintNewLine ();
441445 }
442446 }
@@ -447,6 +451,10 @@ private void writeTag(final Function<Object[], String> function, final Object...
447451 writeRaw (function .apply (allArgs ));
448452 }
449453
454+ private void writeTagLeader (final Function <Object [], String > function ) {
455+ writeRawLeader (function .apply (namespacePrefix ));
456+ }
457+
450458 private void prettyPrintIndentation () {
451459 if (formatted ) {
452460 final String prefix = String .join ("" , Collections .nCopies (indentationLevel , INDENT ));
0 commit comments