@@ -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