Skip to content

Commit 3a839ce

Browse files
committed
Fix #163
1 parent 65a0693 commit 3a839ce

File tree

5 files changed

+61
-30
lines changed

5 files changed

+61
-30
lines changed

release-notes/CREDITS-2.x

+4
Original file line numberDiff line numberDiff line change
@@ -84,3 +84,7 @@ Vincent Boulaye (vboulaye@github)
8484
* Implemented #15: Add a `CsvParser.Feature.SKIP_EMPTY_LINES` to allow
8585
skipping empty rows
8686
(2.10.1)
87+
88+
Piyush Kumar (piyushkumar13@github)
89+
* Reported #163: (yaml) `SequenceWriter` does not create multiple docs in a single yaml file
90+
(2.10.2)

release-notes/VERSION-2.x

+2
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,8 @@ Modules:
1010

1111
2.10.2 (not yet released)
1212

13+
#163: (yaml) `SequenceWriter` does not create multiple docs in a single yaml file
14+
(reported by Piyush K)
1315
#166: (csv) Incorrect `JsonParseException` Message for missing separator char
1416
(reported by gimiz@github)
1517

yaml/src/main/java/com/fasterxml/jackson/dataformat/yaml/YAMLGenerator.java

+48-17
Original file line numberDiff line numberDiff line change
@@ -216,6 +216,8 @@ private Feature(boolean defaultState) {
216216

217217
protected DumperOptions _outputOptions;
218218

219+
protected final org.yaml.snakeyaml.DumperOptions.Version _docVersion;
220+
219221
// for field names, leave out quotes
220222
private final static DumperOptions.ScalarStyle STYLE_UNQUOTED_NAME = DumperOptions.ScalarStyle.PLAIN;
221223

@@ -252,6 +254,8 @@ private Feature(boolean defaultState) {
252254
*/
253255
protected String _typeId;
254256

257+
protected int _rootValueCount;
258+
255259
/*
256260
/**********************************************************
257261
/* Life-cycle
@@ -267,19 +271,14 @@ public YAMLGenerator(IOContext ctxt, int jsonFeatures, int yamlFeatures,
267271
_ioContext = ctxt;
268272
_formatFeatures = yamlFeatures;
269273
_writer = out;
274+
_docVersion = version;
270275

271276
_outputOptions = buildDumperOptions(jsonFeatures, yamlFeatures, version);
272277

273278
_emitter = new Emitter(_writer, _outputOptions);
274279
// should we start output now, or try to defer?
275-
_emitter.emit(new StreamStartEvent(null, null));
276-
Map<String,String> noTags = Collections.emptyMap();
277-
278-
boolean startMarker = Feature.WRITE_DOC_START_MARKER.enabledIn(yamlFeatures);
279-
280-
_emitter.emit(new DocumentStartEvent(null, null, startMarker,
281-
version, // for 1.10 was: ((version == null) ? null : version.getArray()),
282-
noTags));
280+
_emit(new StreamStartEvent(null, null));
281+
_emitStartDocument();
283282
}
284283

285284
protected DumperOptions buildDumperOptions(int jsonFeatures, int yamlFeatures,
@@ -479,8 +478,11 @@ public final void flush() throws IOException
479478
public void close() throws IOException
480479
{
481480
if (!isClosed()) {
482-
_emitter.emit(new DocumentEndEvent(null, null, false));
483-
_emitter.emit(new StreamEndEvent(null, null));
481+
// 11-Dec-2019, tatu: Should perhaps check if content is to be auto-closed...
482+
// but need END_DOCUMENT regardless
483+
484+
_emitEndDocument();
485+
_emit(new StreamEndEvent(null, null));
484486
super.close();
485487

486488
/* 25-Nov-2008, tatus: As per [JACKSON-16] we are not to call close()
@@ -518,7 +520,7 @@ public final void writeStartArray() throws IOException
518520
if (anchor != null) {
519521
_objectId = null;
520522
}
521-
_emitter.emit(new SequenceStartEvent(anchor, yamlTag,
523+
_emit(new SequenceStartEvent(anchor, yamlTag,
522524
implicit, null, null, style));
523525
}
524526

@@ -531,7 +533,7 @@ public final void writeEndArray() throws IOException
531533
// just to make sure we don't "leak" type ids
532534
_typeId = null;
533535
_writeContext = _writeContext.getParent();
534-
_emitter.emit(new SequenceEndEvent(null, null));
536+
_emit(new SequenceEndEvent(null, null));
535537
}
536538

537539
@Override
@@ -546,7 +548,7 @@ public final void writeStartObject() throws IOException
546548
if (anchor != null) {
547549
_objectId = null;
548550
}
549-
_emitter.emit(new MappingStartEvent(anchor, yamlTag,
551+
_emit(new MappingStartEvent(anchor, yamlTag,
550552
implicit, null, null, style));
551553
}
552554

@@ -559,7 +561,7 @@ public final void writeEndObject() throws IOException
559561
// just to make sure we don't "leak" type ids
560562
_typeId = null;
561563
_writeContext = _writeContext.getParent();
562-
_emitter.emit(new MappingEndEvent(null, null));
564+
_emit(new MappingEndEvent(null, null));
563565
}
564566

565567
/*
@@ -815,7 +817,7 @@ public void writeObjectRef(Object id)
815817
{
816818
_verifyValueWrite("write Object reference");
817819
AliasEvent evt = new AliasEvent(String.valueOf(id), null, null);
818-
_emitter.emit(evt);
820+
_emit(evt);
819821
}
820822

821823
@Override
@@ -840,6 +842,15 @@ protected final void _verifyValueWrite(String typeMsg)
840842
if (status == JsonWriteContext.STATUS_EXPECT_NAME) {
841843
_reportError("Can not "+typeMsg+", expecting field name");
842844
}
845+
if (_writeContext.inRoot()) {
846+
// Start-doc emitted when creating generator, but otherwise need it; similarly,
847+
// need matching end-document to close earlier open one
848+
if (_writeContext.getCurrentIndex() > 0) {
849+
_emitEndDocument();
850+
_emitStartDocument();
851+
}
852+
}
853+
843854
}
844855

845856
@Override
@@ -861,7 +872,7 @@ protected void _releaseBuffers() {
861872

862873
protected void _writeScalar(String value, String type, DumperOptions.ScalarStyle style) throws IOException
863874
{
864-
_emitter.emit(_scalarEvent(value, style));
875+
_emit(_scalarEvent(value, style));
865876
}
866877

867878
private void _writeScalarBinary(Base64Variant b64variant,
@@ -874,7 +885,7 @@ private void _writeScalarBinary(Base64Variant b64variant,
874885
}
875886
final String lf = _lf();
876887
String encoded = _base64encode(b64variant, data, lf);
877-
_emitter.emit(new ScalarEvent(null, TAG_BINARY, EXPLICIT_TAGS, encoded,
888+
_emit(new ScalarEvent(null, TAG_BINARY, EXPLICIT_TAGS, encoded,
878889
null, null, STYLE_BASE64));
879890
}
880891

@@ -976,4 +987,24 @@ private boolean _valueNeedsQuoting(String name) {
976987
protected String _lf() {
977988
return _outputOptions.getLineBreak().getString();
978989
}
990+
991+
// @since 2.10.2
992+
protected void _emitStartDocument() throws IOException
993+
{
994+
Map<String,String> noTags = Collections.emptyMap();
995+
boolean startMarker = Feature.WRITE_DOC_START_MARKER.enabledIn(_formatFeatures);
996+
_emit(new DocumentStartEvent(null, null, startMarker,
997+
_docVersion, // for 1.10 was: ((version == null) ? null : version.getArray()),
998+
noTags));
999+
}
1000+
1001+
// @since 2.10.2
1002+
protected void _emitEndDocument() throws IOException {
1003+
_emit(new DocumentEndEvent(null, null, false));
1004+
}
1005+
1006+
// @since 2.10.2
1007+
protected final void _emit(Event e) throws IOException {
1008+
_emitter.emit(e);
1009+
}
9791010
}
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,11 @@
1-
package com.fasterxml.jackson.dataformat.yaml.failing;
1+
package com.fasterxml.jackson.dataformat.yaml;
22

33
import java.io.StringWriter;
4+
import java.util.Arrays;
45
import java.util.Collections;
56

67
import com.fasterxml.jackson.databind.*;
78

8-
import com.fasterxml.jackson.dataformat.yaml.ModuleTestBase;
9-
109
// for [dataformats-text#163]
1110
public class MultipleDocumentsWriteTest extends ModuleTestBase
1211
{
@@ -26,25 +25,21 @@ public void testWriteMultipleDocsBeans() throws Exception
2625
}
2726
w.close();
2827

29-
String yaml = w.toString();
30-
31-
// !!! TODO: actual expected multi-doc contents:
32-
assertEquals("foo", yaml);
28+
String yaml = w.toString().trim();
29+
assertEquals("---\nvalue: 42\n---\nvalue: 28", yaml);
3330
}
3431

3532
public void testWriteMultipleDocsLists() throws Exception
3633
{
3734
ObjectMapper mapper = newObjectMapper();
3835
StringWriter w = new StringWriter();
3936
try (SequenceWriter seqW = mapper.writer().writeValues(w)) {
40-
seqW.write(Collections.singleton(42));
37+
seqW.write(Arrays.asList(28,12));
4138
seqW.write(Collections.singleton(28));
4239
}
4340
w.close();
4441

45-
String yaml = w.toString();
46-
47-
// !!! TODO: actual expected multi-doc contents:
48-
assertEquals("foo", yaml);
42+
String yaml = w.toString().trim();
43+
assertEquals("---\n- 28\n- 12\n---\n- 28", yaml);
4944
}
5045
}

yaml/src/test/java/com/fasterxml/jackson/dataformat/yaml/deser/DatabindReadTest.java

-1
Original file line numberDiff line numberDiff line change
@@ -116,7 +116,6 @@ public void testUUIDs() throws Exception
116116
{
117117
UUID uuid = new UUID(0, 0);
118118
String yaml = MAPPER.writeValueAsString(uuid);
119-
120119
UUID result = MAPPER.readValue(yaml, UUID.class);
121120

122121
assertEquals(uuid, result);

0 commit comments

Comments
 (0)