Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix #99 do not close stream when autoclose is disabled in yaml generator/parser #112

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -451,7 +451,21 @@ public void close() throws IOException
_emitter.emit(new DocumentEndEvent(null, null, false));
_emitter.emit(new StreamEndEvent(null, null));
super.close();
_writer.close();

/* 25-Nov-2008, tatus: As per [JACKSON-16] we are not to call close()
* on the underlying Reader, unless we "own" it, or auto-closing
* feature is enabled.
* One downside: when using UTF8Writer, underlying buffer(s)
* may not be properly recycled if we don't close the writer.
*/
if (_writer != null) {
if (_ioContext.isResourceManaged() || isEnabled(JsonGenerator.Feature.AUTO_CLOSE_TARGET)) {
_writer.close();
} else if (isEnabled(JsonGenerator.Feature.FLUSH_PASSED_TO_STREAM)) {
// If we can't close it, we should at least flush
_writer.flush();
}
}
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -216,7 +216,16 @@ public Version version() {

@Override
protected void _closeInput() throws IOException {
_reader.close();
/* 25-Nov-2008, tatus: As per [JACKSON-16] we are not to call close()
* on the underlying Reader, unless we "own" it, or auto-closing
* feature is enabled.
* One downside is that when using our optimized
* Reader (granted, we only do that for UTF-32...) this
* means that buffer recycling won't work correctly.
*/
if (_ioContext.isResourceManaged() || isEnabled(JsonParser.Feature.AUTO_CLOSE_SOURCE)) {
_reader.close();
}
}

/*
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
package com.fasterxml.jackson.dataformat.yaml.deser;

import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.StringReader;

import org.junit.Assert;

import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.dataformat.yaml.ModuleTestBase;

public class ParserAutoCloseTest extends ModuleTestBase {

public void testParseReaderWithAutoClose() throws IOException {
ObjectMapper yamlMapper = newObjectMapper();

CloseTrackerReader reader = new CloseTrackerReader("foo:bar");
yamlMapper.readTree(reader);

Assert.assertEquals(true, reader.isClosed());
}

public void testParseStreamWithAutoClose() throws IOException {
ObjectMapper yamlMapper = newObjectMapper();

CloseTrackerOutputStream stream = new CloseTrackerOutputStream("foo:bar");
yamlMapper.readTree(stream);

Assert.assertEquals(true, stream.isClosed());
}

public void testParseReaderWithoutAutoClose() throws IOException {
ObjectMapper yamlMapper = newObjectMapper()
.disable(JsonParser.Feature.AUTO_CLOSE_SOURCE);

CloseTrackerReader reader = new CloseTrackerReader("foo:bar");
yamlMapper.readTree(reader);

Assert.assertEquals(false, reader.isClosed());
}


public void testParseStreamWithoutAutoClose() throws IOException {
ObjectMapper yamlMapper = newObjectMapper()
.disable(JsonParser.Feature.AUTO_CLOSE_SOURCE);

CloseTrackerOutputStream stream = new CloseTrackerOutputStream("foo:bar");
yamlMapper.readTree(stream);

Assert.assertEquals(false, stream.isClosed());
}

public static class CloseTrackerReader extends StringReader {
private boolean closed;

public CloseTrackerReader(String s) {
super(s);
}

@Override
public void close() {
closed = true;
super.close();
}

public boolean isClosed() {
return closed;
}
}


public static class CloseTrackerOutputStream extends ByteArrayInputStream {
private boolean closed;

public CloseTrackerOutputStream(String s) {
super(s.getBytes());
}

@Override
public void close() throws IOException {
closed = true;
super.close();
}

public boolean isClosed() {
return closed;
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
package com.fasterxml.jackson.dataformat.yaml.ser;

import java.io.IOException;
import java.io.OutputStream;
import java.io.StringWriter;

import org.junit.Assert;

import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.dataformat.yaml.ModuleTestBase;
import com.fasterxml.jackson.dataformat.yaml.YAMLFactory;

public class GeneratorAutoCloseTest extends ModuleTestBase {

private Pojo pojo = new Pojo("bar");

public void testGenerateWriterWithoAutoCloseTarget() throws IOException {
CloseTrackerWriter writer = new CloseTrackerWriter();
ObjectMapper yamlMapper = newObjectMapper();
yamlMapper.writeValue(writer, pojo);
Assert.assertEquals(true, writer.isClosed());
}

public void testGenerateOutputStreamWithAutoCloseTarget() throws IOException {
CloseTrackerOutputStream stream = new CloseTrackerOutputStream();
ObjectMapper yamlMapper = newObjectMapper();
yamlMapper.writeValue(stream, pojo);
Assert.assertEquals(true, stream.isClosed());
}

public void testGenerateWriterWithoutAutoCloseTarget() throws IOException {
CloseTrackerWriter writer = new CloseTrackerWriter();
ObjectMapper yamlMapper = newObjectMapper()
.disable(JsonGenerator.Feature.AUTO_CLOSE_TARGET);
yamlMapper.writeValue(writer, pojo);
Assert.assertEquals(false, writer.isClosed());
}

public void testGenerateOutputStreamWithoutAutoCloseTarget() throws IOException {
CloseTrackerOutputStream stream = new CloseTrackerOutputStream();
ObjectMapper yamlMapper = newObjectMapper()
.disable(JsonGenerator.Feature.AUTO_CLOSE_TARGET);
yamlMapper.writeValue(stream, pojo);
Assert.assertEquals(false, stream.isClosed());
}

public void testGenerateOutputStreamWithoutAutoCloseTargetOnFactory() throws IOException {
CloseTrackerOutputStream stream = new CloseTrackerOutputStream();
ObjectMapper yamlMapper = new ObjectMapper(
new YAMLFactory()
.disable(JsonGenerator.Feature.AUTO_CLOSE_TARGET)
);
yamlMapper.writeValue(stream, pojo);
Assert.assertEquals(false, stream.isClosed());
}


static class CloseTrackerOutputStream extends OutputStream {
private boolean closed;

@Override
public void write(int b) throws IOException {

}

@Override
public void close() throws IOException {
closed = true;
super.close();
}

public boolean isClosed() {
return closed;
}
}

static class CloseTrackerWriter extends StringWriter {
private boolean closed;


@Override
public void close() throws IOException {
closed = true;
super.close();
}

public boolean isClosed() {
return closed;
}
}

static class Pojo {

public final String foo;

Pojo(final String foo) {
this.foo = foo;
}
}
}