Skip to content

Commit 4a06170

Browse files
committed
Fixes to sequence writing; changed naming to be more consistent with 'readValues()' (hence, 'writeValues()'),
added first tests
1 parent 884751e commit 4a06170

File tree

5 files changed

+301
-50
lines changed

5 files changed

+301
-50
lines changed

src/main/java/com/fasterxml/jackson/databind/ObjectWriter.java

Lines changed: 124 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -628,39 +628,154 @@ public ObjectWriter withoutAttribute(Object key) {
628628
/**********************************************************
629629
*/
630630

631-
public SequenceWriter createSequenceWriter(File out) throws IOException {
631+
/**
632+
* Method for creating a {@link SequenceWriter} to write a sequence of root
633+
* values using configuration of this {@link ObjectWriter}.
634+
* Sequence is not surrounded by JSON array; some backend types may not
635+
* support writing of such sequences as root level.
636+
* Resulting writer needs to be {@link SequenceWriter#close()}d after all
637+
* values have been written to ensure closing of underlying generator and
638+
* output stream.
639+
*
640+
* @param out Target file to write value sequence to.
641+
*
642+
* @since 2.5
643+
*/
644+
public SequenceWriter writeValues(File out) throws IOException {
632645
return _newSequenceWriter(false,
633646
_generatorFactory.createGenerator(out, JsonEncoding.UTF8), true);
634647
}
635648

636-
public SequenceWriter createSequenceWriter(JsonGenerator gen) throws IOException {
649+
/**
650+
* Method for creating a {@link SequenceWriter} to write a sequence of root
651+
* values using configuration of this {@link ObjectWriter}.
652+
* Sequence is not surrounded by JSON array; some backend types may not
653+
* support writing of such sequences as root level.
654+
* Resulting writer needs to be {@link SequenceWriter#close()}d after all
655+
* values have been written to ensure that all content gets flushed by
656+
* the generator. However, since a {@link JsonGenerator} is explicitly passed,
657+
* it will NOT be closed when {@link SequenceWriter#close()} is called.
658+
*
659+
* @param gen Low-level generator caller has already constructed that will
660+
* be used for actual writing of token stream.
661+
*
662+
* @since 2.5
663+
*/
664+
public SequenceWriter writeValues(JsonGenerator gen) throws IOException {
637665
return _newSequenceWriter(false, _configureGenerator(gen), false);
638666
}
639667

640-
public SequenceWriter createSequenceWriter(Writer out) throws IOException {
668+
/**
669+
* Method for creating a {@link SequenceWriter} to write a sequence of root
670+
* values using configuration of this {@link ObjectWriter}.
671+
* Sequence is not surrounded by JSON array; some backend types may not
672+
* support writing of such sequences as root level.
673+
* Resulting writer needs to be {@link SequenceWriter#close()}d after all
674+
* values have been written to ensure closing of underlying generator and
675+
* output stream.
676+
*
677+
* @param out Target writer to use for writing the token stream
678+
*
679+
* @since 2.5
680+
*/
681+
public SequenceWriter writeValues(Writer out) throws IOException {
641682
return _newSequenceWriter(false,
642683
_generatorFactory.createGenerator(out), true);
643684
}
644685

645-
public SequenceWriter createSequenceWriter(OutputStream out) throws IOException {
686+
/**
687+
* Method for creating a {@link SequenceWriter} to write a sequence of root
688+
* values using configuration of this {@link ObjectWriter}.
689+
* Sequence is not surrounded by JSON array; some backend types may not
690+
* support writing of such sequences as root level.
691+
* Resulting writer needs to be {@link SequenceWriter#close()}d after all
692+
* values have been written to ensure closing of underlying generator and
693+
* output stream.
694+
*
695+
* @param out Physical output stream to use for writing the token stream
696+
*
697+
* @since 2.5
698+
*/
699+
public SequenceWriter writeValues(OutputStream out) throws IOException {
646700
return _newSequenceWriter(false,
647701
_generatorFactory.createGenerator(out, JsonEncoding.UTF8), true);
648702
}
649-
650-
public SequenceWriter createArrayWriter(File out) throws IOException {
703+
704+
/**
705+
* Method for creating a {@link SequenceWriter} to write an array of
706+
* root-level values, using configuration of this {@link ObjectWriter}.
707+
* Resulting writer needs to be {@link SequenceWriter#close()}d after all
708+
* values have been written to ensure closing of underlying generator and
709+
* output stream.
710+
*<p>
711+
* Note that the type to use with {@link ObjectWriter#forType(Class)} needs to
712+
* be type of individual values (elements) to write and NOT matching array
713+
* or {@link java.util.Collection} type.
714+
*
715+
* @param out File to write token stream to
716+
*
717+
* @since 2.5
718+
*/
719+
public SequenceWriter writeValuesAsArray(File out) throws IOException {
651720
return _newSequenceWriter(true,
652721
_generatorFactory.createGenerator(out, JsonEncoding.UTF8), true);
653722
}
654723

655-
public SequenceWriter createArrayWriter(JsonGenerator gen) throws IOException {
724+
/**
725+
* Method for creating a {@link SequenceWriter} to write an array of
726+
* root-level values, using configuration of this {@link ObjectWriter}.
727+
* Resulting writer needs to be {@link SequenceWriter#close()}d after all
728+
* values have been written to ensure that all content gets flushed by
729+
* the generator. However, since a {@link JsonGenerator} is explicitly passed,
730+
* it will NOT be closed when {@link SequenceWriter#close()} is called.
731+
*<p>
732+
* Note that the type to use with {@link ObjectWriter#forType(Class)} needs to
733+
* be type of individual values (elements) to write and NOT matching array
734+
* or {@link java.util.Collection} type.
735+
*
736+
* @param gen Underlying generator to use for writing the token stream
737+
*
738+
* @since 2.5
739+
*/
740+
public SequenceWriter writeValuesAsArray(JsonGenerator gen) throws IOException {
656741
return _newSequenceWriter(true, gen, false);
657742
}
658743

659-
public SequenceWriter createArrayWriter(Writer out) throws IOException {
744+
/**
745+
* Method for creating a {@link SequenceWriter} to write an array of
746+
* root-level values, using configuration of this {@link ObjectWriter}.
747+
* Resulting writer needs to be {@link SequenceWriter#close()}d after all
748+
* values have been written to ensure closing of underlying generator and
749+
* output stream.
750+
*<p>
751+
* Note that the type to use with {@link ObjectWriter#forType(Class)} needs to
752+
* be type of individual values (elements) to write and NOT matching array
753+
* or {@link java.util.Collection} type.
754+
*
755+
* @param out Writer to use for writing the token stream
756+
*
757+
* @since 2.5
758+
*/
759+
public SequenceWriter writeValuesAsArray(Writer out) throws IOException {
660760
return _newSequenceWriter(true, _generatorFactory.createGenerator(out), true);
661761
}
662762

663-
public SequenceWriter createArrayWriter(OutputStream out) throws IOException {
763+
/**
764+
* Method for creating a {@link SequenceWriter} to write an array of
765+
* root-level values, using configuration of this {@link ObjectWriter}.
766+
* Resulting writer needs to be {@link SequenceWriter#close()}d after all
767+
* values have been written to ensure closing of underlying generator and
768+
* output stream.
769+
*<p>
770+
* Note that the type to use with {@link ObjectWriter#forType(Class)} needs to
771+
* be type of individual values (elements) to write and NOT matching array
772+
* or {@link java.util.Collection} type.
773+
*
774+
* @param out Physical output stream to use for writing the token stream
775+
*
776+
* @since 2.5
777+
*/
778+
public SequenceWriter writeValuesAsArray(OutputStream out) throws IOException {
664779
return _newSequenceWriter(true,
665780
_generatorFactory.createGenerator(out, JsonEncoding.UTF8), true);
666781
}

src/main/java/com/fasterxml/jackson/databind/SequenceWriter.java

Lines changed: 44 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
import java.io.Closeable;
44
import java.io.IOException;
5+
import java.util.Collection;
56

67
import com.fasterxml.jackson.core.*;
78
import com.fasterxml.jackson.databind.ser.DefaultSerializerProvider;
@@ -26,7 +27,7 @@
2627
* @since 2.5
2728
*/
2829
public class SequenceWriter
29-
implements Versioned, java.io.Closeable
30+
implements Versioned, java.io.Closeable, java.io.Flushable
3031
{
3132
/*
3233
/**********************************************************
@@ -124,16 +125,15 @@ public Version version() {
124125
* to write. If root type was specified for {@link ObjectWriter},
125126
* value must be of compatible type (same or subtype).
126127
*/
127-
public void writeValue(Object value) throws IOException
128+
public SequenceWriter write(Object value) throws IOException
128129
{
129130
if (value == null) {
130131
_provider.serializeValue(_generator, null);
131-
return;
132+
return this;
132133
}
133134

134135
if (_cfgCloseCloseable && (value instanceof Closeable)) {
135-
_writeCloseableValue(value);
136-
return;
136+
return _writeCloseableValue(value);
137137
}
138138
JsonSerializer<Object> ser = _rootSerializer;
139139
if (ser == null) {
@@ -147,6 +147,7 @@ public void writeValue(Object value) throws IOException
147147
if (_cfgFlush) {
148148
_generator.flush();
149149
}
150+
return this;
150151
}
151152

152153
/**
@@ -158,16 +159,15 @@ public void writeValue(Object value) throws IOException
158159
* If root type was specified for {@link ObjectWriter},
159160
* value must be of compatible type (same or subtype).
160161
*/
161-
public void writeValue(Object value, JavaType type) throws IOException
162+
public SequenceWriter write(Object value, JavaType type) throws IOException
162163
{
163164
if (value == null) {
164165
_provider.serializeValue(_generator, null);
165-
return;
166+
return this;
166167
}
167168

168169
if (_cfgCloseCloseable && (value instanceof Closeable)) {
169-
_writeCloseableValue(value, type);
170-
return;
170+
return _writeCloseableValue(value, type);
171171
}
172172
/* 15-Dec-2014, tatu: I wonder if this could be come problematic. It shouldn't
173173
* really, since trying to use differently paramterized types in a sequence
@@ -182,8 +182,32 @@ public void writeValue(Object value, JavaType type) throws IOException
182182
if (_cfgFlush) {
183183
_generator.flush();
184184
}
185+
return this;
185186
}
186-
187+
188+
public SequenceWriter writeAll(Object[] value) throws IOException
189+
{
190+
for (int i = 0, len = value.length; i < len; ++i) {
191+
write(value[i]);
192+
}
193+
return this;
194+
}
195+
196+
public <C extends Collection<?>> SequenceWriter writeAll(C container) throws IOException
197+
{
198+
for (Object value : container) {
199+
write(value);
200+
}
201+
return this;
202+
}
203+
204+
@Override
205+
public void flush() throws IOException {
206+
if (!_closed) {
207+
_generator.flush();
208+
}
209+
}
210+
187211
@Override
188212
public void close() throws IOException
189213
{
@@ -193,6 +217,9 @@ public void close() throws IOException
193217
_openArray = false;
194218
_generator.writeEndArray();
195219
}
220+
if (_closeGenerator) {
221+
_generator.close();
222+
}
196223
}
197224
}
198225

@@ -202,7 +229,7 @@ public void close() throws IOException
202229
/**********************************************************
203230
*/
204231

205-
protected void _writeCloseableValue(Object value) throws IOException
232+
protected SequenceWriter _writeCloseableValue(Object value) throws IOException
206233
{
207234
Closeable toClose = (Closeable) value;
208235
try {
@@ -229,14 +256,15 @@ protected void _writeCloseableValue(Object value) throws IOException
229256
} catch (IOException ioe) { }
230257
}
231258
}
259+
return this;
232260
}
233261

234-
protected void _writeCloseableValue(Object value, JavaType type) throws IOException
262+
protected SequenceWriter _writeCloseableValue(Object value, JavaType type) throws IOException
235263
{
236264
Closeable toClose = (Closeable) value;
237265
try {
238266
// 15-Dec-2014, tatu: As per above, could be problem that we do not pass generic type
239-
JsonSerializer<Object >ser = _dynamicSerializers.serializerFor(type.getRawClass());
267+
JsonSerializer<Object> ser = _dynamicSerializers.serializerFor(type.getRawClass());
240268
if (ser == null) {
241269
ser = _findAndAddDynamic(type);
242270
}
@@ -254,20 +282,21 @@ protected void _writeCloseableValue(Object value, JavaType type) throws IOExcept
254282
} catch (IOException ioe) { }
255283
}
256284
}
285+
return this;
257286
}
258287

259288
protected final JsonSerializer<Object> _findAndAddDynamic(Class<?> type) throws JsonMappingException
260289
{
261290
PropertySerializerMap.SerializerAndMapResult result
262-
= _dynamicSerializers.findAndAddPrimarySerializer(type, _provider, null);
291+
= _dynamicSerializers.findAndAddRootValueSerializer(type, _provider);
263292
_dynamicSerializers = result.map;
264293
return result.serializer;
265294
}
266295

267296
protected final JsonSerializer<Object> _findAndAddDynamic(JavaType type) throws JsonMappingException
268297
{
269298
PropertySerializerMap.SerializerAndMapResult result
270-
= _dynamicSerializers.findAndAddPrimarySerializer(type, _provider, null);
299+
= _dynamicSerializers.findAndAddRootValueSerializer(type, _provider);
271300
_dynamicSerializers = result.map;
272301
return result.serializer;
273302
}

0 commit comments

Comments
 (0)