package com.fasterxml.jackson.dataformat.avro.deser;

import java.io.IOException;
import java.util.List;

import com.fasterxml.jackson.core.JsonToken;
import com.fasterxml.jackson.dataformat.avro.schema.AvroSchemaHelper;

Helper classes for reading non-structured values, and can thereby usually be accessed using simpler interface (although sometimes not: if so, instances are wrapped in ScalarDecoderWrappers).
/** * Helper classes for reading non-structured values, and can thereby usually * be accessed using simpler interface (although sometimes not: if so, * instances are wrapped in <code>ScalarDecoderWrapper</code>s). */
public abstract class ScalarDecoder { protected abstract JsonToken decodeValue(AvroParserImpl parser) throws IOException; protected abstract void skipValue(AvroParserImpl parser) throws IOException; public abstract AvroFieldReader asFieldReader(String name, boolean skipper); public abstract String getTypeId(); /* /********************************************************************** /* Decoder implementations /********************************************************************** */ protected final static class BooleanDecoder extends ScalarDecoder { @Override protected JsonToken decodeValue(AvroParserImpl parser) throws IOException { return parser.decodeBoolean(); } @Override protected void skipValue(AvroParserImpl parser) throws IOException { parser.skipBoolean(); } @Override public String getTypeId() { return AvroSchemaHelper.getTypeId(boolean.class); } @Override public AvroFieldReader asFieldReader(String name, boolean skipper) { return new FR(name, skipper, getTypeId()); } private final static class FR extends AvroFieldReader { public FR(String name, boolean skipper, String typeId) { super(name, skipper, typeId); } @Override public JsonToken readValue(AvroReadContext parent, AvroParserImpl parser) throws IOException { return parser.decodeBoolean(); } @Override public void skipValue(AvroParserImpl parser) throws IOException { parser.skipBoolean(); } } } protected final static class DoubleReader extends ScalarDecoder { @Override public JsonToken decodeValue(AvroParserImpl parser) throws IOException { return parser.decodeDouble(); } @Override protected void skipValue(AvroParserImpl parser) throws IOException { parser.skipDouble(); } @Override public String getTypeId() { return AvroSchemaHelper.getTypeId(double.class); } @Override public AvroFieldReader asFieldReader(String name, boolean skipper) { return new FR(name, skipper, getTypeId()); } private final static class FR extends AvroFieldReader { public FR(String name, boolean skipper, String typeId) { super(name, skipper, typeId); } @Override public JsonToken readValue(AvroReadContext parent, AvroParserImpl parser) throws IOException { return parser.decodeDouble(); } @Override public void skipValue(AvroParserImpl parser) throws IOException { parser.skipDouble(); } } } protected final static class FloatReader extends ScalarDecoder { @Override public JsonToken decodeValue(AvroParserImpl parser) throws IOException { return parser.decodeFloat(); } @Override protected void skipValue(AvroParserImpl parser) throws IOException { parser.skipFloat(); } @Override public String getTypeId() { return AvroSchemaHelper.getTypeId(float.class); } @Override public AvroFieldReader asFieldReader(String name, boolean skipper) { return new FR(name, skipper, getTypeId()); } private final static class FR extends AvroFieldReader { public FR(String name, boolean skipper, String typeId) { super(name, skipper, typeId); } @Override public JsonToken readValue(AvroReadContext parent, AvroParserImpl parser) throws IOException { return parser.decodeFloat(); } @Override public void skipValue(AvroParserImpl parser) throws IOException { parser.skipFloat(); } } } protected final static class IntReader extends ScalarDecoder { private final String _typeId; public IntReader(String typeId) { _typeId = typeId; } public IntReader() { this(AvroSchemaHelper.getTypeId(int.class)); } @Override public JsonToken decodeValue(AvroParserImpl parser) throws IOException { JsonToken token = parser.decodeIntToken(); // Character deserializer expects parser.getText() to return something. Make sure it's populated! if (Character.class.getName().equals(getTypeId())) { return parser.setString(Character.toString((char) parser.getIntValue())); } return token; } @Override protected void skipValue(AvroParserImpl parser) throws IOException { parser.skipInt(); } @Override public String getTypeId() { return _typeId; } @Override public AvroFieldReader asFieldReader(String name, boolean skipper) { return new FR(name, skipper, getTypeId()); } private final static class FR extends AvroFieldReader { public FR(String name, boolean skipper, String typeId) { super(name, skipper, typeId); } @Override public JsonToken readValue(AvroReadContext parent, AvroParserImpl parser) throws IOException { return parser.decodeIntToken(); } @Override public void skipValue(AvroParserImpl parser) throws IOException { parser.skipInt(); } } } protected final static class LongReader extends ScalarDecoder { @Override public JsonToken decodeValue(AvroParserImpl parser) throws IOException { return parser.decodeLongToken(); } @Override protected void skipValue(AvroParserImpl parser) throws IOException { parser.skipLong(); } @Override public String getTypeId() { return AvroSchemaHelper.getTypeId(long.class); } @Override public AvroFieldReader asFieldReader(String name, boolean skipper) { return new FR(name, skipper, getTypeId()); } private final static class FR extends AvroFieldReader { public FR(String name, boolean skipper, String typeId) { super(name, skipper, typeId); } @Override public JsonToken readValue(AvroReadContext parent, AvroParserImpl parser) throws IOException { return parser.decodeLongToken(); } @Override public void skipValue(AvroParserImpl parser) throws IOException { parser.skipLong(); } } } protected final static class NullReader extends ScalarDecoder { @Override public JsonToken decodeValue(AvroParserImpl parser) { return JsonToken.VALUE_NULL; } @Override protected void skipValue(AvroParserImpl parser) throws IOException { ; // value implied } @Override public String getTypeId() { return null; } @Override public AvroFieldReader asFieldReader(String name, boolean skipper) { return new FR(name, skipper); } private final static class FR extends AvroFieldReader { public FR(String name, boolean skipper) { super(name, skipper, null); } @Override public JsonToken readValue(AvroReadContext parent, AvroParserImpl parser) throws IOException { return JsonToken.VALUE_NULL; } @Override public void skipValue(AvroParserImpl parser) throws IOException { } } } protected final static class StringReader extends ScalarDecoder { private final String _typeId; public StringReader(String typeId) { _typeId = typeId; } public StringReader() { this(AvroSchemaHelper.getTypeId(String.class)); } @Override public JsonToken decodeValue(AvroParserImpl parser) throws IOException { return parser.decodeStringToken(); } @Override protected void skipValue(AvroParserImpl parser) throws IOException { parser.skipString(); } @Override public String getTypeId() { return _typeId; } @Override public AvroFieldReader asFieldReader(String name, boolean skipper) { return new FR(name, skipper, getTypeId()); } private final static class FR extends AvroFieldReader { public FR(String name, boolean skipper, String typeId) { super(name, skipper, typeId); } @Override public JsonToken readValue(AvroReadContext parent, AvroParserImpl parser) throws IOException { return parser.decodeStringToken(); } @Override public void skipValue(AvroParserImpl parser) throws IOException { parser.skipString(); } } } protected final static class BytesDecoder extends ScalarDecoder { @Override public JsonToken decodeValue(AvroParserImpl parser) throws IOException { return parser.decodeBytes(); } @Override protected void skipValue(AvroParserImpl parser) throws IOException { parser.skipBytes(); } @Override public String getTypeId() { return AvroSchemaHelper.getTypeId(byte[].class); } @Override public AvroFieldReader asFieldReader(String name, boolean skipper) { return new FR(name, skipper, getTypeId()); } private final static class FR extends AvroFieldReader { public FR(String name, boolean skipper, String typeId) { super(name, skipper, typeId); } @Override public JsonToken readValue(AvroReadContext parent, AvroParserImpl parser) throws IOException { return parser.decodeBytes(); } @Override public void skipValue(AvroParserImpl parser) throws IOException { parser.skipBytes(); } } } protected final static class ScalarUnionDecoder extends ScalarDecoder { public final ScalarDecoder[] _readers; public ScalarUnionDecoder(ScalarDecoder[] readers) { _readers = readers; } @Override protected JsonToken decodeValue(AvroParserImpl parser) throws IOException { return _checkIndex(parser.decodeIndex()).decodeValue(parser); } @Override protected void skipValue(AvroParserImpl parser) throws IOException { _checkIndex(parser.decodeIndex()).skipValue(parser); } private ScalarDecoder _checkIndex(int index) throws IOException { if (index < 0 || index >= _readers.length) { throw new IOException(String.format( "Invalid Union index (%s); union only has %d types", index, _readers.length)); } return _readers[index]; } @Override public String getTypeId() { return null; } @Override public AvroFieldReader asFieldReader(String name, boolean skipper) { return new FR(name, skipper, _readers); } private final static class FR extends AvroFieldReader { public final ScalarDecoder[] _readers; public FR(String name, boolean skipper, ScalarDecoder[] readers) { super(name, skipper, null); _readers = readers; } @Override public JsonToken readValue(AvroReadContext parent, AvroParserImpl parser) throws IOException { return _checkIndex(parser.decodeIndex()).decodeValue(parser); } @Override public void skipValue(AvroParserImpl parser) throws IOException { _checkIndex(parser.decodeIndex()).skipValue(parser); } private ScalarDecoder _checkIndex(int index) throws IOException { if (index < 0 || index >= _readers.length) { throw new IOException(String.format( "Invalid Union index (%s); union only has %d types", index, _readers.length)); } return _readers[index]; } } } protected final static class EnumDecoder extends ScalarDecoder { protected final String _name; protected final String[] _values; public EnumDecoder(String name, List<String> enumNames) { _name = name; _values = enumNames.toArray(new String[enumNames.size()]); } @Override public JsonToken decodeValue(AvroParserImpl parser) throws IOException { return parser.setString(_checkIndex(parser.decodeEnum())); } @Override protected void skipValue(AvroParserImpl parser) throws IOException { _checkIndex(parser.decodeEnum()); } private final String _checkIndex(int index) throws IOException { if (index < 0 || index >= _values.length) { throw new IOException(String.format( "Invalid Enum index (%s); enum '%s' only has %d types", index, _name, _values.length)); } return _values[index]; } @Override public String getTypeId() { return _name; } @Override public AvroFieldReader asFieldReader(String name, boolean skipper) { return new FR(name, skipper, this, _name); } private final static class FR extends AvroFieldReader { protected final String[] _values; public FR(String name, boolean skipper, EnumDecoder base, String typeId) { super(name, skipper, typeId); _values = base._values; } @Override public JsonToken readValue(AvroReadContext parent, AvroParserImpl parser) throws IOException { return parser.setString(_checkIndex(parser.decodeEnum())); } @Override public void skipValue(AvroParserImpl parser) throws IOException { _checkIndex(parser.decodeEnum()); } private final String _checkIndex(int index) throws IOException { if (index < 0 || index >= _values.length) { throw new IOException(String.format( "Invalid Enum index (%s); enum '%s' only has %d types", index, _name, _values.length)); } return _values[index]; } } } protected final static class FixedDecoder extends ScalarDecoder { private final int _size; private final String _typeId; public FixedDecoder(int fixedSize, String typeId) { _size = fixedSize; _typeId = typeId; } @Override public JsonToken decodeValue(AvroParserImpl parser) throws IOException { return parser.decodeFixed(_size); } @Override protected void skipValue(AvroParserImpl parser) throws IOException { parser.skipFixed(_size); } @Override public String getTypeId() { return _typeId; } @Override public AvroFieldReader asFieldReader(String name, boolean skipper) { return new FR(name, skipper, _size, _typeId); } private final static class FR extends AvroFieldReader { private final int _size; public FR(String name, boolean skipper, int size, String typeId) { super(name, skipper, typeId); _size = size; } @Override public JsonToken readValue(AvroReadContext parent, AvroParserImpl parser) throws IOException { return parser.decodeFixed(_size); } @Override public void skipValue(AvroParserImpl parser) throws IOException { parser.skipFixed(_size); } } } }