blob: f120248789c500e130e433ddfcf5ff8e64bce24e [file] [log] [blame]
package com.fasterxml.jackson.core.util;
import java.io.*;
import java.math.BigDecimal;
import java.math.BigInteger;
import java.util.Iterator;
import com.fasterxml.jackson.core.*;
import com.fasterxml.jackson.core.JsonParser.NumberType;
import com.fasterxml.jackson.core.type.ResolvedType;
import com.fasterxml.jackson.core.type.TypeReference;
import static org.junit.Assert.assertArrayEquals;
public class TestDelegates extends com.fasterxml.jackson.core.BaseTest
{
static class BogusSchema implements FormatSchema
{
@Override
public String getSchemaType() {
return "test";
}
}
static class POJO {
public int x = 3;
}
static class BogusCodec extends ObjectCodec
{
public Object pojoWritten;
public TreeNode treeWritten;
@Override
public Version version() {
return Version.unknownVersion();
}
@Override
public <T> T readValue(JsonParser p, Class<T> valueType) {
return null;
}
@Override
public <T> T readValue(JsonParser p, TypeReference<T> valueTypeRef) {
return null;
}
@Override
public <T> T readValue(JsonParser p, ResolvedType valueType) {
return null;
}
@Override
public <T> Iterator<T> readValues(JsonParser p, Class<T> valueType) {
return null;
}
@Override
public <T> Iterator<T> readValues(JsonParser p,
TypeReference<T> valueTypeRef) throws IOException {
return null;
}
@Override
public <T> Iterator<T> readValues(JsonParser p, ResolvedType valueType) {
return null;
}
@Override
public void writeValue(JsonGenerator gen, Object value) throws IOException {
gen.writeString("pojo");
pojoWritten = value;
}
@Override
public <T extends TreeNode> T readTree(JsonParser p) {
return null;
}
@Override
public void writeTree(JsonGenerator gen, TreeNode tree) throws IOException {
gen.writeString("tree");
treeWritten = tree;
}
@Override
public TreeNode createObjectNode() {
return null;
}
@Override
public TreeNode createArrayNode() {
return null;
}
@Override
public TreeNode missingNode() {
return null;
}
@Override
public TreeNode nullNode() {
return null;
}
@Override
public JsonParser treeAsTokens(TreeNode n) {
return null;
}
@Override
public <T> T treeToValue(TreeNode n, Class<T> valueType) {
return null;
}
}
static class BogusTree implements TreeNode {
@Override
public JsonToken asToken() {
return null;
}
@Override
public NumberType numberType() {
return null;
}
@Override
public int size() {
return 0;
}
@Override
public boolean isValueNode() {
return false;
}
@Override
public boolean isContainerNode() {
return false;
}
@Override
public boolean isMissingNode() {
return false;
}
@Override
public boolean isArray() {
return false;
}
@Override
public boolean isObject() {
return false;
}
@Override
public TreeNode get(String fieldName) {
return null;
}
@Override
public TreeNode get(int index) {
return null;
}
@Override
public TreeNode path(String fieldName) {
return null;
}
@Override
public TreeNode path(int index) {
return null;
}
@Override
public Iterator<String> fieldNames() {
return null;
}
@Override
public TreeNode at(JsonPointer ptr) {
return null;
}
@Override
public TreeNode at(String jsonPointerExpression) {
return null;
}
@Override
public JsonParser traverse() {
return null;
}
@Override
public JsonParser traverse(ObjectCodec codec) {
return null;
}
}
private final JsonFactory JSON_F = new JsonFactory();
/**
* Test default, non-overridden parser delegate.
*/
public void testParserDelegate() throws IOException
{
final String TOKEN ="foo";
JsonParser parser = JSON_F.createParser("[ 1, true, null, { \"a\": \"foo\" }, \"AQI=\" ]");
JsonParserDelegate del = new JsonParserDelegate(parser);
// Basic capabilities for parser:
assertFalse(del.canParseAsync());
assertFalse(del.canReadObjectId());
assertFalse(del.canReadTypeId());
assertFalse(del.requiresCustomCodec());
assertEquals(parser.version(), del.version());
// configuration
assertFalse(del.isEnabled(JsonParser.Feature.ALLOW_COMMENTS));
assertFalse(del.isEnabled(StreamReadFeature.IGNORE_UNDEFINED));
assertSame(parser, del.delegate());
assertNull(del.getSchema());
// initial state
assertNull(del.currentToken());
assertFalse(del.hasCurrentToken());
assertFalse(del.hasTextCharacters());
assertNull(del.getCurrentValue());
assertNull(del.getCurrentName());
assertToken(JsonToken.START_ARRAY, del.nextToken());
assertEquals(JsonTokenId.ID_START_ARRAY, del.currentTokenId());
assertTrue(del.hasToken(JsonToken.START_ARRAY));
assertFalse(del.hasToken(JsonToken.START_OBJECT));
assertTrue(del.hasTokenId(JsonTokenId.ID_START_ARRAY));
assertFalse(del.hasTokenId(JsonTokenId.ID_START_OBJECT));
assertTrue(del.isExpectedStartArrayToken());
assertFalse(del.isExpectedStartObjectToken());
assertEquals("[", del.getText());
assertNotNull(del.getParsingContext());
assertSame(parser.getParsingContext(), del.getParsingContext());
assertToken(JsonToken.VALUE_NUMBER_INT, del.nextToken());
assertEquals(1, del.getIntValue());
assertEquals(1, del.getValueAsInt());
assertEquals(1, del.getValueAsInt(3));
assertEquals(1L, del.getValueAsLong());
assertEquals(1L, del.getValueAsLong(3L));
assertEquals(1L, del.getLongValue());
assertEquals(1d, del.getValueAsDouble());
assertEquals(1d, del.getValueAsDouble(0.25));
assertEquals(1d, del.getDoubleValue());
assertTrue(del.getValueAsBoolean());
assertTrue(del.getValueAsBoolean(false));
assertEquals((byte)1, del.getByteValue());
assertEquals((short)1, del.getShortValue());
assertEquals(1f, del.getFloatValue());
assertFalse(del.isNaN());
assertEquals(NumberType.INT, del.getNumberType());
assertEquals(Integer.valueOf(1), del.getNumberValue());
assertNull(del.getEmbeddedObject());
assertToken(JsonToken.VALUE_TRUE, del.nextToken());
assertTrue(del.getBooleanValue());
assertEquals(parser.getCurrentLocation(), del.getCurrentLocation());
assertNull(del.getTypeId());
assertNull(del.getObjectId());
assertToken(JsonToken.VALUE_NULL, del.nextToken());
assertNull(del.getCurrentValue());
del.setCurrentValue(TOKEN);
assertToken(JsonToken.START_OBJECT, del.nextToken());
assertNull(del.getCurrentValue());
assertToken(JsonToken.FIELD_NAME, del.nextToken());
assertEquals("a", del.getCurrentName());
assertToken(JsonToken.VALUE_STRING, del.nextToken());
assertTrue(del.hasTextCharacters());
assertEquals("foo", del.getText());
assertToken(JsonToken.END_OBJECT, del.nextToken());
assertEquals(TOKEN, del.getCurrentValue());
assertToken(JsonToken.VALUE_STRING, del.nextToken());
assertArrayEquals(new byte[] { 1, 2 }, del.getBinaryValue());
assertToken(JsonToken.END_ARRAY, del.nextToken());
del.close();
assertTrue(del.isClosed());
assertTrue(parser.isClosed());
parser.close();
}
/**
* Test default, non-overridden generator delegate.
*/
@SuppressWarnings("deprecation")
public void testGeneratorDelegate() throws IOException
{
final String TOKEN ="foo";
StringWriter sw = new StringWriter();
JsonGenerator g0 = JSON_F.createGenerator(sw);
JsonGeneratorDelegate del = new JsonGeneratorDelegate(g0);
// Basic capabilities for parser:
assertTrue(del.canOmitFields());
assertFalse(del.canWriteBinaryNatively());
assertTrue(del.canWriteFormattedNumbers());
assertFalse(del.canWriteObjectId());
assertFalse(del.canWriteTypeId());
assertEquals(g0.version(), del.version());
// configuration
assertTrue(del.isEnabled(JsonGenerator.Feature.QUOTE_FIELD_NAMES));
assertFalse(del.isEnabled(StreamWriteFeature.IGNORE_UNKNOWN));
assertSame(g0, del.delegate());
assertSame(g0, del.getDelegate()); // deprecated as of 2.11
assertFalse(del.canUseSchema(new BogusSchema()));
// initial state
assertNull(del.getSchema());
assertNull(del.getPrettyPrinter());
del.writeStartArray();
assertEquals(1, del.getOutputBuffered());
del.writeNumber(13);
del.writeNumber(BigInteger.ONE);
del.writeNumber(new BigDecimal(0.5));
del.writeNumber("137");
del.writeNull();
del.writeBoolean(false);
del.writeString("foo");
// verify that we can actually set/get "current value" as expected, even with delegates
assertNull(del.getCurrentValue());
del.setCurrentValue(TOKEN);
del.writeStartObject(null, 0);
assertNull(del.getCurrentValue());
del.writeEndObject();
assertEquals(TOKEN, del.getCurrentValue());
del.writeStartArray(0);
del.writeEndArray();
del.writeEndArray();
del.flush();
del.close();
assertTrue(del.isClosed());
assertTrue(g0.isClosed());
assertEquals("[13,1,0.5,137,null,false,\"foo\",{},[]]", sw.toString());
g0.close();
}
public void testGeneratorDelegateArrays() throws IOException
{
StringWriter sw = new StringWriter();
JsonGenerator g0 = JSON_F.createGenerator(sw);
JsonGeneratorDelegate del = new JsonGeneratorDelegate(g0);
final Object MARKER = new Object();
del.writeStartArray(MARKER);
assertSame(MARKER, del.getCurrentValue());
del.writeArray(new int[] { 1, 2, 3 }, 0, 3);
del.writeArray(new long[] { 1, 123456, 2 }, 1, 1);
del.writeArray(new double[] { 0.25, 0.5, 0.75 }, 0, 2);
del.writeArray(new String[] { "Aa", "Bb", "Cc" }, 1, 2);
del.close();
assertEquals("[[1,2,3],[123456],[0.25,0.5],[\"Bb\",\"Cc\"]]", sw.toString());
g0.close();
}
public void testGeneratorDelegateComments() throws IOException
{
StringWriter sw = new StringWriter();
JsonGenerator g0 = JSON_F.createGenerator(sw);
JsonGeneratorDelegate del = new JsonGeneratorDelegate(g0);
final Object MARKER = new Object();
del.writeStartArray(MARKER, 5);
assertSame(MARKER, del.getCurrentValue());
del.writeNumber((short) 1);
del.writeNumber(12L);
del.writeNumber(0.25);
del.writeNumber(0.5f);
del.writeRawValue("/*foo*/");
del.writeRaw(" ");
del.close();
assertEquals("[1,12,0.25,0.5,/*foo*/ ]", sw.toString());
g0.close();
}
public void testDelegateCopyMethods() throws IOException
{
JsonParser p = JSON_F.createParser("[123,[true,false]]");
StringWriter sw = new StringWriter();
JsonGenerator g0 = JSON_F.createGenerator(sw);
JsonGeneratorDelegate del = new JsonGeneratorDelegate(g0);
assertToken(JsonToken.START_ARRAY, p.nextToken());
del.copyCurrentEvent(p);
assertToken(JsonToken.VALUE_NUMBER_INT, p.nextToken());
del.copyCurrentStructure(p);
assertToken(JsonToken.START_ARRAY, p.nextToken());
assertToken(JsonToken.VALUE_TRUE, p.nextToken());
assertToken(JsonToken.VALUE_FALSE, p.nextToken());
del.copyCurrentEvent(p);
g0.writeEndArray();
del.close();
g0.close();
p.close();
assertEquals("[123,false]", sw.toString());
}
public void testNotDelegateCopyMethods() throws IOException
{
JsonParser jp = JSON_F.createParser("[{\"a\":[1,2,{\"b\":3}],\"c\":\"d\"},{\"e\":false},null]");
StringWriter sw = new StringWriter();
JsonGenerator jg = new JsonGeneratorDelegate(JSON_F.createGenerator(sw), false) {
@Override
public void writeFieldName(String name) throws IOException {
super.writeFieldName(name+"-test");
super.writeBoolean(true);
super.writeFieldName(name);
}
};
jp.nextToken();
jg.copyCurrentStructure(jp);
jg.flush();
assertEquals("[{\"a-test\":true,\"a\":[1,2,{\"b-test\":true,\"b\":3}],\"c-test\":true,\"c\":\"d\"},{\"e-test\":true,\"e\":false},null]", sw.toString());
jp.close();
jg.close();
}
@SuppressWarnings("resource")
public void testGeneratorWithCodec() throws IOException
{
BogusCodec codec = new BogusCodec();
StringWriter sw = new StringWriter();
JsonGenerator g0 = JSON_F.createGenerator(sw);
g0.setCodec(codec);
JsonGeneratorDelegate del = new JsonGeneratorDelegate(g0, false);
del.writeStartArray();
POJO pojo = new POJO();
del.writeObject(pojo);
TreeNode tree = new BogusTree();
del.writeTree(tree);
del.writeEndArray();
del.close();
assertEquals("[\"pojo\",\"tree\"]", sw.toString());
assertSame(tree, codec.treeWritten);
assertSame(pojo, codec.pojoWritten);
}
}