605 lines
26 KiB
Java
605 lines
26 KiB
Java
package io.gitlab.jfronny.commons.serialize.databind.impl.adapter;
|
|
|
|
import io.gitlab.jfronny.commons.data.LazilyParsedNumber;
|
|
import io.gitlab.jfronny.commons.data.NumberLimits;
|
|
import io.gitlab.jfronny.commons.serialize.databind.api.SerializerFor;
|
|
import io.gitlab.jfronny.commons.serialize.databind.api.TypeAdapter;
|
|
import io.gitlab.jfronny.commons.serialize.MalformedDataException;
|
|
import io.gitlab.jfronny.commons.serialize.SerializeReader;
|
|
import io.gitlab.jfronny.commons.serialize.SerializeWriter;
|
|
import io.gitlab.jfronny.commons.serialize.Token;
|
|
import io.gitlab.jfronny.commons.serialize.emulated.DataElement;
|
|
import io.gitlab.jfronny.commons.serialize.emulated.DataElementSerializer;
|
|
|
|
import java.math.BigDecimal;
|
|
import java.math.BigInteger;
|
|
import java.net.InetAddress;
|
|
import java.net.URI;
|
|
import java.net.URL;
|
|
import java.util.*;
|
|
import java.util.concurrent.atomic.AtomicBoolean;
|
|
import java.util.concurrent.atomic.AtomicInteger;
|
|
import java.util.concurrent.atomic.AtomicIntegerArray;
|
|
|
|
public class TypeAdapters {
|
|
@SerializerFor(targets = {boolean.class, Boolean.class})
|
|
public static class BooleanTypeAdapter extends TypeAdapter<Boolean> {
|
|
@Override
|
|
public <TEx extends Exception, Writer extends SerializeWriter<TEx, Writer>> void serialize(Boolean value, Writer writer) throws TEx, MalformedDataException {
|
|
writer.value(value);
|
|
}
|
|
|
|
@Override
|
|
public <TEx extends Exception, Reader extends SerializeReader<TEx, Reader>> Boolean deserialize(Reader reader) throws TEx, MalformedDataException {
|
|
if (reader.peek() == Token.STRING) {
|
|
// special casing for boolean strings
|
|
String value = reader.nextString();
|
|
if (value.equalsIgnoreCase("true")) {
|
|
return true;
|
|
} else if (value.equalsIgnoreCase("false")) {
|
|
return false;
|
|
} else {
|
|
throw new MalformedDataException("Expected boolean, got " + value);
|
|
}
|
|
}
|
|
return reader.nextBoolean();
|
|
}
|
|
}
|
|
|
|
@SerializerFor(targets = {byte.class, Byte.class})
|
|
public static class ByteTypeAdapter extends TypeAdapter<Byte> {
|
|
@Override
|
|
public <TEx extends Exception, Writer extends SerializeWriter<TEx, Writer>> void serialize(Byte value, Writer writer) throws TEx, MalformedDataException {
|
|
writer.value(value);
|
|
}
|
|
|
|
@Override
|
|
public <TEx extends Exception, Reader extends SerializeReader<TEx, Reader>> Byte deserialize(Reader reader) throws TEx, MalformedDataException {
|
|
int value;
|
|
try {
|
|
value = reader.nextInt();
|
|
} catch (NumberFormatException e) {
|
|
throw new MalformedDataException(e);
|
|
}
|
|
// Up to 255 to support unsigned values
|
|
if (value < Byte.MIN_VALUE || value > 255) {
|
|
throw new MalformedDataException("Value " + value + " is out of range for byte");
|
|
}
|
|
return (byte) value;
|
|
}
|
|
}
|
|
|
|
@SerializerFor(targets = {short.class, Short.class})
|
|
public static class ShortTypeAdapter extends TypeAdapter<Short> {
|
|
@Override
|
|
public <TEx extends Exception, Writer extends SerializeWriter<TEx, Writer>> void serialize(Short value, Writer writer) throws TEx, MalformedDataException {
|
|
writer.value(value);
|
|
}
|
|
|
|
@Override
|
|
public <TEx extends Exception, Reader extends SerializeReader<TEx, Reader>> Short deserialize(Reader reader) throws TEx, MalformedDataException {
|
|
int value;
|
|
try {
|
|
value = reader.nextInt();
|
|
} catch (NumberFormatException e) {
|
|
throw new MalformedDataException(e);
|
|
}
|
|
// Up to 65535 to support unsigned values
|
|
if (value < Short.MIN_VALUE || value > 65535) {
|
|
throw new MalformedDataException("Value " + value + " is out of range for short");
|
|
}
|
|
return (short) value;
|
|
}
|
|
}
|
|
|
|
@SerializerFor(targets = {int.class, Integer.class})
|
|
public static class IntegerTypeAdapter extends TypeAdapter<Integer> {
|
|
@Override
|
|
public <TEx extends Exception, Writer extends SerializeWriter<TEx, Writer>> void serialize(Integer value, Writer writer) throws TEx, MalformedDataException {
|
|
writer.value(value);
|
|
}
|
|
|
|
@Override
|
|
public <TEx extends Exception, Reader extends SerializeReader<TEx, Reader>> Integer deserialize(Reader reader) throws TEx, MalformedDataException {
|
|
try {
|
|
return reader.nextInt();
|
|
} catch (NumberFormatException e) {
|
|
throw new MalformedDataException(e);
|
|
}
|
|
}
|
|
}
|
|
|
|
@SerializerFor(targets = {long.class, Long.class})
|
|
public static class LongTypeAdapter extends TypeAdapter<Long> {
|
|
@Override
|
|
public <TEx extends Exception, Writer extends SerializeWriter<TEx, Writer>> void serialize(Long value, Writer writer) throws TEx, MalformedDataException {
|
|
writer.value(value);
|
|
}
|
|
|
|
@Override
|
|
public <TEx extends Exception, Reader extends SerializeReader<TEx, Reader>> Long deserialize(Reader reader) throws TEx, MalformedDataException {
|
|
try {
|
|
return reader.nextLong();
|
|
} catch (NumberFormatException e) {
|
|
throw new MalformedDataException(e);
|
|
}
|
|
}
|
|
}
|
|
|
|
@SerializerFor(targets = {float.class, Float.class})
|
|
public static class FloatTypeAdapter extends TypeAdapter<Float> {
|
|
@Override
|
|
public <TEx extends Exception, Writer extends SerializeWriter<TEx, Writer>> void serialize(Float value, Writer writer) throws TEx, MalformedDataException {
|
|
writer.value(value);
|
|
}
|
|
|
|
@Override
|
|
public <TEx extends Exception, Reader extends SerializeReader<TEx, Reader>> Float deserialize(Reader reader) throws TEx, MalformedDataException {
|
|
try {
|
|
return (float) reader.nextDouble();
|
|
} catch (NumberFormatException e) {
|
|
throw new MalformedDataException(e);
|
|
}
|
|
}
|
|
}
|
|
|
|
@SerializerFor(targets = {double.class, Double.class})
|
|
public static class DoubleTypeAdapter extends TypeAdapter<Double> {
|
|
@Override
|
|
public <TEx extends Exception, Writer extends SerializeWriter<TEx, Writer>> void serialize(Double value, Writer writer) throws TEx, MalformedDataException {
|
|
writer.value(value);
|
|
}
|
|
|
|
@Override
|
|
public <TEx extends Exception, Reader extends SerializeReader<TEx, Reader>> Double deserialize(Reader reader) throws TEx, MalformedDataException {
|
|
try {
|
|
return reader.nextDouble();
|
|
} catch (NumberFormatException e) {
|
|
throw new MalformedDataException(e);
|
|
}
|
|
}
|
|
}
|
|
|
|
@SerializerFor(targets = {char.class, Character.class})
|
|
public static class CharacterTypeAdapter extends TypeAdapter<Character> {
|
|
@Override
|
|
public <TEx extends Exception, Writer extends SerializeWriter<TEx, Writer>> void serialize(Character value, Writer writer) throws TEx, MalformedDataException {
|
|
writer.value(String.valueOf(value));
|
|
}
|
|
|
|
@Override
|
|
public <TEx extends Exception, Reader extends SerializeReader<TEx, Reader>> Character deserialize(Reader reader) throws TEx, MalformedDataException {
|
|
String value = reader.nextString();
|
|
if (value.length() != 1) {
|
|
throw new MalformedDataException("Expected single character, got " + value);
|
|
}
|
|
return value.charAt(0);
|
|
}
|
|
}
|
|
|
|
@SerializerFor(targets = String.class)
|
|
public static class StringTypeAdapter extends TypeAdapter<String> {
|
|
@Override
|
|
public <TEx extends Exception, Writer extends SerializeWriter<TEx, Writer>> void serialize(String value, Writer writer) throws TEx, MalformedDataException {
|
|
writer.value(value);
|
|
}
|
|
|
|
@Override
|
|
public <TEx extends Exception, Reader extends SerializeReader<TEx, Reader>> String deserialize(Reader reader) throws TEx, MalformedDataException {
|
|
return reader.nextString();
|
|
}
|
|
}
|
|
|
|
@SerializerFor(targets = BitSet.class)
|
|
public static class BitSetTypeAdapter extends TypeAdapter<BitSet> {
|
|
@Override
|
|
public <TEx extends Exception, Writer extends SerializeWriter<TEx, Writer>> void serialize(BitSet value, Writer writer) throws TEx {
|
|
writer.beginArray();
|
|
for (int i = 0; i < value.length(); i++) {
|
|
writer.value(value.get(i) ? 1 : 0);
|
|
}
|
|
writer.endArray();
|
|
}
|
|
|
|
@Override
|
|
public <TEx extends Exception, Reader extends SerializeReader<TEx, Reader>> BitSet deserialize(Reader reader) throws TEx, MalformedDataException {
|
|
BitSet bitset = new BitSet();
|
|
reader.beginArray();
|
|
int i = 0;
|
|
Token tokenType = reader.peek();
|
|
while (tokenType != Token.END_ARRAY) {
|
|
boolean set;
|
|
switch (tokenType) {
|
|
case NUMBER:
|
|
case STRING:
|
|
int intValue = reader.nextInt();
|
|
if (intValue == 0) {
|
|
set = false;
|
|
} else if (intValue == 1) {
|
|
set = true;
|
|
} else {
|
|
throw new MalformedDataException(
|
|
"Invalid bitset value "
|
|
+ intValue
|
|
+ ", expected 0 or 1; at path "
|
|
+ reader.getPreviousPath());
|
|
}
|
|
break;
|
|
case BOOLEAN:
|
|
set = reader.nextBoolean();
|
|
break;
|
|
default:
|
|
throw new MalformedDataException(
|
|
"Invalid bitset value type: " + tokenType + "; at path " + reader.getPath());
|
|
}
|
|
if (set) {
|
|
bitset.set(i);
|
|
}
|
|
++i;
|
|
tokenType = reader.peek();
|
|
}
|
|
reader.endArray();
|
|
return bitset;
|
|
}
|
|
}
|
|
|
|
@SerializerFor(targets = AtomicInteger.class)
|
|
public static class AtomicIntegerTypeAdapter extends TypeAdapter<AtomicInteger> {
|
|
@Override
|
|
public <TEx extends Exception, Writer extends SerializeWriter<TEx, Writer>> void serialize(AtomicInteger value, Writer writer) throws TEx {
|
|
writer.value(value.get());
|
|
}
|
|
|
|
@Override
|
|
public <TEx extends Exception, Reader extends SerializeReader<TEx, Reader>> AtomicInteger deserialize(Reader reader) throws TEx, MalformedDataException {
|
|
try {
|
|
return new AtomicInteger(reader.nextInt());
|
|
} catch (NumberFormatException e) {
|
|
throw new MalformedDataException(e);
|
|
}
|
|
}
|
|
}
|
|
|
|
@SerializerFor(targets = AtomicBoolean.class)
|
|
public static class AtomicBooleanTypeAdapter extends TypeAdapter<AtomicBoolean> {
|
|
@Override
|
|
public <TEx extends Exception, Writer extends SerializeWriter<TEx, Writer>> void serialize(AtomicBoolean value, Writer writer) throws TEx {
|
|
writer.value(value.get());
|
|
}
|
|
|
|
@Override
|
|
public <TEx extends Exception, Reader extends SerializeReader<TEx, Reader>> AtomicBoolean deserialize(Reader reader) throws TEx, MalformedDataException {
|
|
return new AtomicBoolean(reader.nextBoolean());
|
|
}
|
|
}
|
|
|
|
@SerializerFor(targets = AtomicIntegerArray.class)
|
|
public static class AtomicIntegerArrayTypeAdapter extends TypeAdapter<AtomicIntegerArray> {
|
|
@Override
|
|
public <TEx extends Exception, Writer extends SerializeWriter<TEx, Writer>> void serialize(AtomicIntegerArray value, Writer writer) throws TEx {
|
|
writer.beginArray();
|
|
for (int i = 0; i < value.length(); i++) {
|
|
writer.value(value.get(i));
|
|
}
|
|
writer.endArray();
|
|
}
|
|
|
|
@Override
|
|
public <TEx extends Exception, Reader extends SerializeReader<TEx, Reader>> AtomicIntegerArray deserialize(Reader reader) throws TEx, MalformedDataException {
|
|
if (reader.isLenient() && reader.peek() != Token.BEGIN_ARRAY) {
|
|
// Coerce
|
|
return new AtomicIntegerArray(new int[]{reader.nextInt()});
|
|
}
|
|
reader.beginArray();
|
|
int length = 0;
|
|
while (reader.hasNext()) {
|
|
reader.nextInt();
|
|
length++;
|
|
}
|
|
reader.endArray();
|
|
AtomicIntegerArray array = new AtomicIntegerArray(length);
|
|
reader.beginArray();
|
|
for (int i = 0; i < length; i++) {
|
|
array.set(i, reader.nextInt());
|
|
}
|
|
reader.endArray();
|
|
return array;
|
|
}
|
|
}
|
|
|
|
@SerializerFor(targets = BigDecimal.class)
|
|
public static class BigDecimalTypeAdapter extends TypeAdapter<BigDecimal> {
|
|
@Override
|
|
public <TEx extends Exception, Writer extends SerializeWriter<TEx, Writer>> void serialize(BigDecimal value, Writer writer) throws TEx, MalformedDataException {
|
|
writer.value(value);
|
|
}
|
|
|
|
@Override
|
|
public <TEx extends Exception, Reader extends SerializeReader<TEx, Reader>> BigDecimal deserialize(Reader reader) throws TEx, MalformedDataException {
|
|
String value = reader.nextString();
|
|
try {
|
|
return NumberLimits.parseBigDecimal(value);
|
|
} catch (NumberFormatException e) {
|
|
throw new MalformedDataException(e);
|
|
}
|
|
}
|
|
}
|
|
|
|
@SerializerFor(targets = BigInteger.class)
|
|
public static class BigIntegerTypeAdapter extends TypeAdapter<BigInteger> {
|
|
@Override
|
|
public <TEx extends Exception, Writer extends SerializeWriter<TEx, Writer>> void serialize(BigInteger value, Writer writer) throws TEx, MalformedDataException {
|
|
writer.value(value);
|
|
}
|
|
|
|
@Override
|
|
public <TEx extends Exception, Reader extends SerializeReader<TEx, Reader>> BigInteger deserialize(Reader reader) throws TEx, MalformedDataException {
|
|
try {
|
|
return NumberLimits.parseBigInteger(reader.nextString());
|
|
} catch (NumberFormatException e) {
|
|
throw new MalformedDataException(e);
|
|
}
|
|
}
|
|
}
|
|
|
|
@SerializerFor(targets = Number.class)
|
|
public static class NumberTypeAdapter extends TypeAdapter<Number> {
|
|
@Override
|
|
public <TEx extends Exception, Writer extends SerializeWriter<TEx, Writer>> void serialize(Number value, Writer writer) throws TEx, MalformedDataException {
|
|
writer.value(value);
|
|
}
|
|
|
|
@Override
|
|
public <TEx extends Exception, Reader extends SerializeReader<TEx, Reader>> Number deserialize(Reader reader) throws TEx, MalformedDataException {
|
|
return reader.nextNumber();
|
|
}
|
|
}
|
|
|
|
@SerializerFor(targets = LazilyParsedNumber.class)
|
|
public static class LazilyParsedNumberTypeAdapter extends TypeAdapter<LazilyParsedNumber> {
|
|
@Override
|
|
public <TEx extends Exception, Writer extends SerializeWriter<TEx, Writer>> void serialize(LazilyParsedNumber value, Writer writer) throws TEx, MalformedDataException {
|
|
writer.value(value);
|
|
}
|
|
|
|
@Override
|
|
public <TEx extends Exception, Reader extends SerializeReader<TEx, Reader>> LazilyParsedNumber deserialize(Reader reader) throws TEx, MalformedDataException {
|
|
if (reader.peek() == Token.NUMBER) {
|
|
Number number = reader.nextNumber();
|
|
if (number instanceof LazilyParsedNumber l) return l;
|
|
return new LazilyParsedNumber(number.toString());
|
|
}
|
|
// Legacy compatibility with Gson
|
|
return new LazilyParsedNumber(reader.nextString());
|
|
}
|
|
}
|
|
|
|
@SerializerFor(targets = StringBuilder.class)
|
|
public static class StringBuilderTypeAdapter extends TypeAdapter<StringBuilder> {
|
|
@Override
|
|
public <TEx extends Exception, Writer extends SerializeWriter<TEx, Writer>> void serialize(StringBuilder value, Writer writer) throws TEx, MalformedDataException {
|
|
writer.value(value.toString());
|
|
}
|
|
|
|
@Override
|
|
public <TEx extends Exception, Reader extends SerializeReader<TEx, Reader>> StringBuilder deserialize(Reader reader) throws TEx, MalformedDataException {
|
|
return new StringBuilder(reader.nextString());
|
|
}
|
|
}
|
|
|
|
@SerializerFor(targets = StringBuffer.class)
|
|
public static class StringBufferTypeAdapter extends TypeAdapter<StringBuffer> {
|
|
@Override
|
|
public <TEx extends Exception, Writer extends SerializeWriter<TEx, Writer>> void serialize(StringBuffer value, Writer writer) throws TEx, MalformedDataException {
|
|
writer.value(value.toString());
|
|
}
|
|
|
|
@Override
|
|
public <TEx extends Exception, Reader extends SerializeReader<TEx, Reader>> StringBuffer deserialize(Reader reader) throws TEx, MalformedDataException {
|
|
return new StringBuffer(reader.nextString());
|
|
}
|
|
}
|
|
|
|
@SerializerFor(targets = URL.class)
|
|
public static class URLTypeAdapter extends TypeAdapter<URL> {
|
|
@Override
|
|
public <TEx extends Exception, Writer extends SerializeWriter<TEx, Writer>> void serialize(URL value, Writer writer) throws TEx, MalformedDataException {
|
|
writer.value(value.toExternalForm());
|
|
}
|
|
|
|
@Override
|
|
public <TEx extends Exception, Reader extends SerializeReader<TEx, Reader>> URL deserialize(Reader reader) throws TEx, MalformedDataException {
|
|
try {
|
|
String str = reader.nextString();
|
|
if (str.equals("null")) return null;
|
|
return new URI(str).toURL();
|
|
} catch (Exception e) {
|
|
throw new MalformedDataException(e);
|
|
}
|
|
}
|
|
}
|
|
|
|
@SerializerFor(targets = URI.class)
|
|
public static class URITypeAdapter extends TypeAdapter<URI> {
|
|
@Override
|
|
public <TEx extends Exception, Writer extends SerializeWriter<TEx, Writer>> void serialize(URI value, Writer writer) throws TEx, MalformedDataException {
|
|
writer.value(value.toString());
|
|
}
|
|
|
|
@Override
|
|
public <TEx extends Exception, Reader extends SerializeReader<TEx, Reader>> URI deserialize(Reader reader) throws TEx, MalformedDataException {
|
|
try {
|
|
String str = reader.nextString();
|
|
if (str.equals("null")) return null;
|
|
return new URI(str);
|
|
} catch (Exception e) {
|
|
throw new MalformedDataException(e);
|
|
}
|
|
}
|
|
}
|
|
|
|
@SerializerFor(targets = InetAddress.class, hierarchical = true)
|
|
public static class InetAddressTypeAdapter extends TypeAdapter<InetAddress> {
|
|
@Override
|
|
public <TEx extends Exception, Writer extends SerializeWriter<TEx, Writer>> void serialize(InetAddress value, Writer writer) throws TEx, MalformedDataException {
|
|
writer.value(value.getHostAddress());
|
|
}
|
|
|
|
@Override
|
|
public <TEx extends Exception, Reader extends SerializeReader<TEx, Reader>> InetAddress deserialize(Reader reader) throws TEx, MalformedDataException {
|
|
try {
|
|
return InetAddress.getByName(reader.nextString());
|
|
} catch (Exception e) {
|
|
throw new MalformedDataException(e);
|
|
}
|
|
}
|
|
}
|
|
|
|
@SerializerFor(targets = UUID.class)
|
|
public static class UUIDTypeAdapter extends TypeAdapter<UUID> {
|
|
@Override
|
|
public <TEx extends Exception, Writer extends SerializeWriter<TEx, Writer>> void serialize(UUID value, Writer writer) throws TEx, MalformedDataException {
|
|
writer.value(value.toString());
|
|
}
|
|
|
|
@Override
|
|
public <TEx extends Exception, Reader extends SerializeReader<TEx, Reader>> UUID deserialize(Reader reader) throws TEx, MalformedDataException {
|
|
try {
|
|
return UUID.fromString(reader.nextString());
|
|
} catch (IllegalArgumentException e) {
|
|
throw new MalformedDataException(e);
|
|
}
|
|
}
|
|
}
|
|
|
|
@SerializerFor(targets = Currency.class)
|
|
public static class CurrencyTypeAdapter extends TypeAdapter<Currency> {
|
|
@Override
|
|
public <TEx extends Exception, Writer extends SerializeWriter<TEx, Writer>> void serialize(Currency value, Writer writer) throws TEx, MalformedDataException {
|
|
writer.value(value.getCurrencyCode());
|
|
}
|
|
|
|
@Override
|
|
public <TEx extends Exception, Reader extends SerializeReader<TEx, Reader>> Currency deserialize(Reader reader) throws TEx, MalformedDataException {
|
|
return Currency.getInstance(reader.nextString());
|
|
}
|
|
}
|
|
|
|
@SerializerFor(targets = Calendar.class)
|
|
public static class CalendarTypeAdapter extends TypeAdapter<Calendar> {
|
|
private static final String YEAR = "year";
|
|
private static final String MONTH = "month";
|
|
private static final String DAY_OF_MONTH = "dayOfMonth";
|
|
private static final String HOUR_OF_DAY = "hourOfDay";
|
|
private static final String MINUTE = "minute";
|
|
private static final String SECOND = "second";
|
|
|
|
@Override
|
|
public <TEx extends Exception, Writer extends SerializeWriter<TEx, Writer>> void serialize(Calendar value, Writer writer) throws TEx, MalformedDataException {
|
|
if (value == null) {
|
|
writer.nullValue();
|
|
return;
|
|
}
|
|
writer.beginObject();
|
|
writer.name(YEAR);
|
|
writer.value(value.get(Calendar.YEAR));
|
|
writer.name(MONTH);
|
|
writer.value(value.get(Calendar.MONTH));
|
|
writer.name(DAY_OF_MONTH);
|
|
writer.value(value.get(Calendar.DAY_OF_MONTH));
|
|
writer.name(HOUR_OF_DAY);
|
|
writer.value(value.get(Calendar.HOUR_OF_DAY));
|
|
writer.name(MINUTE);
|
|
writer.value(value.get(Calendar.MINUTE));
|
|
writer.name(SECOND);
|
|
writer.value(value.get(Calendar.SECOND));
|
|
writer.endObject();
|
|
}
|
|
|
|
@Override
|
|
public <TEx extends Exception, Reader extends SerializeReader<TEx, Reader>> Calendar deserialize(Reader reader) throws TEx, MalformedDataException {
|
|
reader.beginObject();
|
|
int year = 0;
|
|
int month = 0;
|
|
int dayOfMonth = 0;
|
|
int hourOfDay = 0;
|
|
int minute = 0;
|
|
int second = 0;
|
|
while (reader.peek() != Token.END_OBJECT) {
|
|
String name = reader.nextName();
|
|
int value = reader.nextInt();
|
|
switch (name) {
|
|
case YEAR:
|
|
year = value;
|
|
break;
|
|
case MONTH:
|
|
month = value;
|
|
break;
|
|
case DAY_OF_MONTH:
|
|
dayOfMonth = value;
|
|
break;
|
|
case HOUR_OF_DAY:
|
|
hourOfDay = value;
|
|
break;
|
|
case MINUTE:
|
|
minute = value;
|
|
break;
|
|
case SECOND:
|
|
second = value;
|
|
break;
|
|
default:
|
|
// Ignore unknown JSON property
|
|
}
|
|
}
|
|
reader.endObject();
|
|
return new GregorianCalendar(year, month, dayOfMonth, hourOfDay, minute, second);
|
|
}
|
|
}
|
|
|
|
@SerializerFor(targets = Locale.class)
|
|
public static class LocaleTypeAdapter extends TypeAdapter<Locale> {
|
|
@Override
|
|
public <TEx extends Exception, Writer extends SerializeWriter<TEx, Writer>> void serialize(Locale value, Writer writer) throws TEx, MalformedDataException {
|
|
writer.value(value == null ? null : value.toString());
|
|
}
|
|
|
|
@Override
|
|
public <TEx extends Exception, Reader extends SerializeReader<TEx, Reader>> Locale deserialize(Reader reader) throws TEx, MalformedDataException {
|
|
String locale = reader.nextString();
|
|
StringTokenizer tokenizer = new StringTokenizer(locale, "_");
|
|
String language = null;
|
|
String country = null;
|
|
String variant = null;
|
|
if (tokenizer.hasMoreElements()) {
|
|
language = tokenizer.nextToken();
|
|
}
|
|
if (tokenizer.hasMoreElements()) {
|
|
country = tokenizer.nextToken();
|
|
}
|
|
if (tokenizer.hasMoreElements()) {
|
|
variant = tokenizer.nextToken();
|
|
}
|
|
if (country == null && variant == null) {
|
|
return new Locale(language);
|
|
} else if (variant == null) {
|
|
return new Locale(language, country);
|
|
} else {
|
|
return new Locale(language, country, variant);
|
|
}
|
|
}
|
|
}
|
|
|
|
@SerializerFor(targets = DataElement.class, hierarchical = true)
|
|
public static class DataElementTypeAdapter extends TypeAdapter<DataElement> {
|
|
@Override
|
|
public <TEx extends Exception, Writer extends SerializeWriter<TEx, Writer>> void serialize(DataElement value, Writer writer) throws TEx, MalformedDataException {
|
|
DataElementSerializer.serialize(value, writer);
|
|
}
|
|
|
|
@Override
|
|
public <TEx extends Exception, Reader extends SerializeReader<TEx, Reader>> DataElement deserialize(Reader reader) throws TEx, MalformedDataException {
|
|
return DataElementSerializer.deserialize(reader);
|
|
}
|
|
}
|
|
}
|