@@ -49,9 +49,6 @@ public final class MarcXmlEncoder extends DefaultStreamPipe<ObjectReceiver<Strin
49
49
public static final boolean OMIT_XML_DECLARATION = false ;
50
50
public static final boolean ENSURE_CORRECT_MARC21_XML = false ;
51
51
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
-
55
52
private enum Tag {
56
53
57
54
collection (" xmlns%s=\" " + NAMESPACE + "\" %s" ),
@@ -106,7 +103,6 @@ public String close(final Object[] args) {
106
103
private static final int TAG_END = 3 ;
107
104
108
105
private final Encoder encoder = new Encoder ();
109
- private final Marc21Decoder decoder = new Marc21Decoder ();
110
106
private final Marc21Encoder wrapper = new Marc21Encoder ();
111
107
112
108
private DefaultStreamPipe <ObjectReceiver <String >> pipe ;
@@ -115,6 +111,7 @@ public String close(final Object[] args) {
115
111
* Creates an instance of {@link MarcXmlEncoder}.
116
112
*/
117
113
public MarcXmlEncoder () {
114
+ final Marc21Decoder decoder = new Marc21Decoder ();
118
115
decoder .setEmitLeaderAsWhole (true );
119
116
120
117
wrapper
@@ -136,7 +133,6 @@ public void setEmitNamespace(final boolean emitNamespace) {
136
133
137
134
/**
138
135
* Sets the flag to decide whether to omit the XML declaration.
139
- *
140
136
* <strong>Default value: {@value #OMIT_XML_DECLARATION}</strong>
141
137
*
142
138
* @param currentOmitXmlDeclaration true if the XML declaration is omitted, otherwise
@@ -148,7 +144,6 @@ public void omitXmlDeclaration(final boolean currentOmitXmlDeclaration) {
148
144
149
145
/**
150
146
* Sets the XML version.
151
- *
152
147
* <strong>Default value: {@value #XML_VERSION}</strong>
153
148
*
154
149
* @param xmlVersion the XML version
@@ -159,7 +154,6 @@ public void setXmlVersion(final String xmlVersion) {
159
154
160
155
/**
161
156
* Sets the XML encoding.
162
- *
163
157
* <strong>Default value: {@value #XML_ENCODING}</strong>
164
158
*
165
159
* @param xmlEncoding the XML encoding
@@ -173,7 +167,6 @@ public void setXmlEncoding(final String xmlEncoding) {
173
167
* If true, the input data is validated to ensure correct MARC21. Also the leader may be generated.
174
168
* 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}.
175
169
* This validation and treatment of the leader is more safe but comes with a performance impact.
176
- *
177
170
* <strong>Default value: {@value #ENSURE_CORRECT_MARC21_XML}</strong>
178
171
*
179
172
* @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) {
184
177
185
178
/**
186
179
* Formats the resulting xml by indentation. Aka "pretty printing".
187
- *
188
180
* <strong>Default value: {@value #PRETTY_PRINTED}</strong>
189
181
*
190
182
* @param formatted true if formatting is activated, otherwise false
@@ -247,11 +239,12 @@ private static class Encoder extends DefaultStreamPipe<ObjectReceiver<String>> {
247
239
private String currentEntity = "" ;
248
240
249
241
private boolean emitNamespace = true ;
250
- private Object [] namespacePrefix = new Object []{emitNamespace ? NAMESPACE_PREFIX : EMPTY };
242
+ private Object [] namespacePrefix = new Object []{NAMESPACE_PREFIX };
251
243
252
244
private int indentationLevel ;
253
245
private boolean formatted = PRETTY_PRINTED ;
254
246
private int recordAttributeOffset ;
247
+ private int recordLeaderOffset ;
255
248
256
249
private Encoder () {
257
250
}
@@ -294,7 +287,7 @@ public void startRecord(final String identifier) {
294
287
writeTag (Tag .record ::open );
295
288
recordAttributeOffset = builder .length () - 1 ;
296
289
prettyPrintNewLine ();
297
-
290
+ recordLeaderOffset = builder . length ();
298
291
incrementIndentationLevel ();
299
292
}
300
293
@@ -353,7 +346,7 @@ else if (!appendLeader(name, value)) {
353
346
if (value != null ) {
354
347
writeEscaped (value .trim ());
355
348
}
356
- writeTag (Tag .controlfield ::close );
349
+ writeTag (Tag .controlfield ::close , false );
357
350
prettyPrintNewLine ();
358
351
}
359
352
}
@@ -408,9 +401,20 @@ private void writeFooter() {
408
401
* @param str the unescaped sequence to be written
409
402
*/
410
403
private void writeRaw (final String str ) {
404
+
411
405
builder .append (str );
412
406
}
413
407
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
+
414
418
private boolean appendLeader (final String name , final String value ) {
415
419
if (name .equals (Marc21EventNames .LEADER_ENTITY )) {
416
420
leaderBuilder .append (value );
@@ -432,11 +436,11 @@ private void writeEscaped(final String str) {
432
436
433
437
private void writeLeader () {
434
438
final String leader = leaderBuilder .toString ();
435
- if (! leader . isEmpty () ) {
439
+ if (leaderBuilder . length () > 0 ) {
436
440
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 );
440
444
prettyPrintNewLine ();
441
445
}
442
446
}
@@ -447,6 +451,10 @@ private void writeTag(final Function<Object[], String> function, final Object...
447
451
writeRaw (function .apply (allArgs ));
448
452
}
449
453
454
+ private void writeTagLeader (final Function <Object [], String > function ) {
455
+ writeRawLeader (function .apply (namespacePrefix ));
456
+ }
457
+
450
458
private void prettyPrintIndentation () {
451
459
if (formatted ) {
452
460
final String prefix = String .join ("" , Collections .nCopies (indentationLevel , INDENT ));
0 commit comments