package com.fasterxml.jackson.datatype.eclipsecollections.deser.pair;
import com.fasterxml.jackson.databind.BeanDescription;
import com.fasterxml.jackson.databind.DeserializationConfig;
import com.fasterxml.jackson.databind.DeserializationContext;
import com.fasterxml.jackson.databind.JavaType;
import com.fasterxml.jackson.databind.JsonMappingException;
import com.fasterxml.jackson.databind.PropertyMetadata;
import com.fasterxml.jackson.databind.PropertyName;
import com.fasterxml.jackson.databind.deser.CreatorProperty;
import com.fasterxml.jackson.databind.deser.SettableBeanProperty;
import com.fasterxml.jackson.databind.deser.ValueInstantiator;
import com.fasterxml.jackson.databind.deser.ValueInstantiators;
import com.fasterxml.jackson.databind.introspect.AnnotationCollector;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import java.util.function.BiFunction;
import org.eclipse.collections.api.tuple.Pair;
import org.eclipse.collections.api.tuple.Twin;
import org.eclipse.collections.api.tuple.primitive.BooleanBooleanPair;
import org.eclipse.collections.api.tuple.primitive.BooleanBytePair;
import org.eclipse.collections.api.tuple.primitive.BooleanCharPair;
import org.eclipse.collections.api.tuple.primitive.BooleanDoublePair;
import org.eclipse.collections.api.tuple.primitive.BooleanFloatPair;
import org.eclipse.collections.api.tuple.primitive.BooleanIntPair;
import org.eclipse.collections.api.tuple.primitive.BooleanLongPair;
import org.eclipse.collections.api.tuple.primitive.BooleanObjectPair;
import org.eclipse.collections.api.tuple.primitive.BooleanShortPair;
import org.eclipse.collections.api.tuple.primitive.ByteBooleanPair;
import org.eclipse.collections.api.tuple.primitive.ByteBytePair;
import org.eclipse.collections.api.tuple.primitive.ByteCharPair;
import org.eclipse.collections.api.tuple.primitive.ByteDoublePair;
import org.eclipse.collections.api.tuple.primitive.ByteFloatPair;
import org.eclipse.collections.api.tuple.primitive.ByteIntPair;
import org.eclipse.collections.api.tuple.primitive.ByteLongPair;
import org.eclipse.collections.api.tuple.primitive.ByteObjectPair;
import org.eclipse.collections.api.tuple.primitive.ByteShortPair;
import org.eclipse.collections.api.tuple.primitive.CharBooleanPair;
import org.eclipse.collections.api.tuple.primitive.CharBytePair;
import org.eclipse.collections.api.tuple.primitive.CharCharPair;
import org.eclipse.collections.api.tuple.primitive.CharDoublePair;
import org.eclipse.collections.api.tuple.primitive.CharFloatPair;
import org.eclipse.collections.api.tuple.primitive.CharIntPair;
import org.eclipse.collections.api.tuple.primitive.CharLongPair;
import org.eclipse.collections.api.tuple.primitive.CharObjectPair;
import org.eclipse.collections.api.tuple.primitive.CharShortPair;
import org.eclipse.collections.api.tuple.primitive.DoubleBooleanPair;
import org.eclipse.collections.api.tuple.primitive.DoubleBytePair;
import org.eclipse.collections.api.tuple.primitive.DoubleCharPair;
import org.eclipse.collections.api.tuple.primitive.DoubleDoublePair;
import org.eclipse.collections.api.tuple.primitive.DoubleFloatPair;
import org.eclipse.collections.api.tuple.primitive.DoubleIntPair;
import org.eclipse.collections.api.tuple.primitive.DoubleLongPair;
import org.eclipse.collections.api.tuple.primitive.DoubleObjectPair;
import org.eclipse.collections.api.tuple.primitive.DoubleShortPair;
import org.eclipse.collections.api.tuple.primitive.FloatBooleanPair;
import org.eclipse.collections.api.tuple.primitive.FloatBytePair;
import org.eclipse.collections.api.tuple.primitive.FloatCharPair;
import org.eclipse.collections.api.tuple.primitive.FloatDoublePair;
import org.eclipse.collections.api.tuple.primitive.FloatFloatPair;
import org.eclipse.collections.api.tuple.primitive.FloatIntPair;
import org.eclipse.collections.api.tuple.primitive.FloatLongPair;
import org.eclipse.collections.api.tuple.primitive.FloatObjectPair;
import org.eclipse.collections.api.tuple.primitive.FloatShortPair;
import org.eclipse.collections.api.tuple.primitive.IntBooleanPair;
import org.eclipse.collections.api.tuple.primitive.IntBytePair;
import org.eclipse.collections.api.tuple.primitive.IntCharPair;
import org.eclipse.collections.api.tuple.primitive.IntDoublePair;
import org.eclipse.collections.api.tuple.primitive.IntFloatPair;
import org.eclipse.collections.api.tuple.primitive.IntIntPair;
import org.eclipse.collections.api.tuple.primitive.IntLongPair;
import org.eclipse.collections.api.tuple.primitive.IntObjectPair;
import org.eclipse.collections.api.tuple.primitive.IntShortPair;
import org.eclipse.collections.api.tuple.primitive.LongBooleanPair;
import org.eclipse.collections.api.tuple.primitive.LongBytePair;
import org.eclipse.collections.api.tuple.primitive.LongCharPair;
import org.eclipse.collections.api.tuple.primitive.LongDoublePair;
import org.eclipse.collections.api.tuple.primitive.LongFloatPair;
import org.eclipse.collections.api.tuple.primitive.LongIntPair;
import org.eclipse.collections.api.tuple.primitive.LongLongPair;
import org.eclipse.collections.api.tuple.primitive.LongObjectPair;
import org.eclipse.collections.api.tuple.primitive.LongShortPair;
import org.eclipse.collections.api.tuple.primitive.ObjectBooleanPair;
import org.eclipse.collections.api.tuple.primitive.ObjectBytePair;
import org.eclipse.collections.api.tuple.primitive.ObjectCharPair;
import org.eclipse.collections.api.tuple.primitive.ObjectDoublePair;
import org.eclipse.collections.api.tuple.primitive.ObjectFloatPair;
import org.eclipse.collections.api.tuple.primitive.ObjectIntPair;
import org.eclipse.collections.api.tuple.primitive.ObjectLongPair;
import org.eclipse.collections.api.tuple.primitive.ObjectShortPair;
import org.eclipse.collections.api.tuple.primitive.ShortBooleanPair;
import org.eclipse.collections.api.tuple.primitive.ShortBytePair;
import org.eclipse.collections.api.tuple.primitive.ShortCharPair;
import org.eclipse.collections.api.tuple.primitive.ShortDoublePair;
import org.eclipse.collections.api.tuple.primitive.ShortFloatPair;
import org.eclipse.collections.api.tuple.primitive.ShortIntPair;
import org.eclipse.collections.api.tuple.primitive.ShortLongPair;
import org.eclipse.collections.api.tuple.primitive.ShortObjectPair;
import org.eclipse.collections.api.tuple.primitive.ShortShortPair;
import org.eclipse.collections.impl.tuple.Tuples;
import org.eclipse.collections.impl.tuple.primitive.PrimitiveTuples;
public final class PairInstantiators extends ValueInstantiators.Base {
private static final Map<Class<?>, ValueInstantiator> PURE_PRIMITIVE_INSTANTIATORS = new HashMap<>();
@Override
public ValueInstantiator findValueInstantiator(
DeserializationConfig config, BeanDescription beanDesc, ValueInstantiator defaultInstantiator
) {
Class<?> beanClass = beanDesc.getBeanClass();
ValueInstantiator purePrimitive = PURE_PRIMITIVE_INSTANTIATORS.get(beanClass);
if (purePrimitive != null) {
return purePrimitive;
}
JavaType beanType = beanDesc.getType();
if (beanClass == BooleanObjectPair.class) {
return primitiveObjectInstantiator(beanType, boolean.class,
(one, two) -> PrimitiveTuples.pair((boolean) one, two));
} else if (beanClass == ByteObjectPair.class) {
return primitiveObjectInstantiator(beanType, byte.class,
(one, two) -> PrimitiveTuples.pair((byte) one, two));
} else if (beanClass == ShortObjectPair.class) {
return primitiveObjectInstantiator(beanType, short.class,
(one, two) -> PrimitiveTuples.pair((short) one, two));
} else if (beanClass == CharObjectPair.class) {
return primitiveObjectInstantiator(beanType, char.class,
(one, two) -> PrimitiveTuples.pair((char) one, two));
} else if (beanClass == IntObjectPair.class) {
return primitiveObjectInstantiator(beanType, int.class,
(one, two) -> PrimitiveTuples.pair((int) one, two));
} else if (beanClass == FloatObjectPair.class) {
return primitiveObjectInstantiator(beanType, float.class,
(one, two) -> PrimitiveTuples.pair((float) one, two));
} else if (beanClass == LongObjectPair.class) {
return primitiveObjectInstantiator(beanType, long.class,
(one, two) -> PrimitiveTuples.pair((long) one, two));
} else if (beanClass == DoubleObjectPair.class) {
return primitiveObjectInstantiator(beanType, double.class,
(one, two) -> PrimitiveTuples.pair((double) one, two));
}
if (beanClass == ObjectBooleanPair.class) {
return objectPrimitiveInstantiator(beanType, boolean.class,
(one, two) -> PrimitiveTuples.pair(one, (boolean) two));
} else if (beanClass == ObjectBytePair.class) {
return objectPrimitiveInstantiator(beanType, byte.class,
(one, two) -> PrimitiveTuples.pair(one, (byte) two));
} else if (beanClass == ObjectShortPair.class) {
return objectPrimitiveInstantiator(beanType, short.class,
(one, two) -> PrimitiveTuples.pair(one, (short) two));
} else if (beanClass == ObjectCharPair.class) {
return objectPrimitiveInstantiator(beanType, char.class,
(one, two) -> PrimitiveTuples.pair(one, (char) two));
} else if (beanClass == ObjectIntPair.class) {
return objectPrimitiveInstantiator(beanType, int.class,
(one, two) -> PrimitiveTuples.pair(one, (int) two));
} else if (beanClass == ObjectFloatPair.class) {
return objectPrimitiveInstantiator(beanType, float.class,
(one, two) -> PrimitiveTuples.pair(one, (float) two));
} else if (beanClass == ObjectLongPair.class) {
return objectPrimitiveInstantiator(beanType, long.class,
(one, two) -> PrimitiveTuples.pair(one, (long) two));
} else if (beanClass == ObjectDoublePair.class) {
return objectPrimitiveInstantiator(beanType, double.class,
(one, two) -> PrimitiveTuples.pair(one, (double) two));
}
if (beanClass == Pair.class) {
return new ValueInstantiator.Base(beanType) {
@Override
public boolean canCreateFromObjectWith() {
return true;
}
@Override
public SettableBeanProperty[] getFromObjectArguments(DeserializationConfig config) {
JavaType oneType = beanType.containedType(0);
JavaType twoType = beanType.containedType(1);
return makeProperties(config, oneType, twoType);
}
@Override
public Object createFromObjectWith(DeserializationContext ctxt, Object[] args) throws IOException {
return Tuples.pair(args[0], args[1]);
}
};
}
if (beanClass == Twin.class) {
return new ValueInstantiator.Base(beanType) {
@Override
public boolean canCreateFromObjectWith() {
return true;
}
@Override
public SettableBeanProperty[] getFromObjectArguments(DeserializationConfig config) {
JavaType memberType = beanType.containedType(0);
return makeProperties(config, memberType, memberType);
}
@Override
public Object createFromObjectWith(DeserializationContext ctxt, Object[] args) throws IOException {
return Tuples.twin(args[0], args[1]);
}
};
}
return defaultInstantiator;
}
private static <P> ValueInstantiator primitiveObjectInstantiator(
JavaType inputType, Class<?> one,
BiFunction<Object, Object, P> factory
) {
return new ValueInstantiator.Base(inputType) {
@Override
public boolean canCreateFromObjectWith() {
return true;
}
@Override
public SettableBeanProperty[] getFromObjectArguments(DeserializationConfig config) {
JavaType oneType = config.constructType(one);
JavaType twoType = inputType.containedType(0);
return makeProperties(config, oneType, twoType);
}
@Override
public Object createFromObjectWith(DeserializationContext ctxt, Object[] args) throws IOException {
return factory.apply(args[0], args[1]);
}
};
}
private static <P> ValueInstantiator objectPrimitiveInstantiator(
JavaType inputType, Class<?> two,
BiFunction<Object, Object, P> factory
) {
return new ValueInstantiator.Base(inputType) {
@Override
public boolean canCreateFromObjectWith() {
return true;
}
@Override
public SettableBeanProperty[] getFromObjectArguments(DeserializationConfig config) {
JavaType oneType = inputType.containedType(0);
JavaType twoType = config.constructType(two);
return makeProperties(config, oneType, twoType);
}
@Override
public Object createFromObjectWith(DeserializationContext ctxt, Object[] args) throws IOException {
return factory.apply(args[0], args[1]);
}
};
}
private static <P> void purePrimitiveInstantiator(
Class<P> pairClass, Class<?> one, Class<?> two,
BiFunction<Object, Object, P> factory
) {
PURE_PRIMITIVE_INSTANTIATORS.put(pairClass, new ValueInstantiator.Base(pairClass) {
@Override
public boolean canCreateFromObjectWith() {
return true;
}
@Override
public SettableBeanProperty[] getFromObjectArguments(DeserializationConfig config) {
JavaType oneType = config.constructType(one);
JavaType twoType = config.constructType(two);
return makeProperties(config, oneType, twoType);
}
@Override
public Object createFromObjectWith(DeserializationContext ctxt, Object[] args) throws IOException {
return factory.apply(args[0], args[1]);
}
});
}
static SettableBeanProperty[] makeProperties(
DeserializationConfig config,
JavaType oneType,
JavaType twoType
) {
try {
return new SettableBeanProperty[]{
new CreatorProperty(
PropertyName.construct("one"),
oneType,
null,
config.findTypeDeserializer(oneType),
AnnotationCollector.emptyAnnotations(),
null, 0, null, PropertyMetadata.STD_REQUIRED
),
new CreatorProperty(
PropertyName.construct("two"),
twoType,
null,
config.findTypeDeserializer(twoType),
AnnotationCollector.emptyAnnotations(),
null, 1, null, PropertyMetadata.STD_REQUIRED
)
};
} catch (JsonMappingException e) {
throw new RuntimeException(e);
}
}
static {
purePrimitiveInstantiator(BooleanBooleanPair.class, boolean.class, boolean.class,
(one, two) -> PrimitiveTuples.pair((boolean) one, (boolean) two));
purePrimitiveInstantiator(BooleanBytePair.class, boolean.class, byte.class,
(one, two) -> PrimitiveTuples.pair((boolean) one, (byte) two));
purePrimitiveInstantiator(BooleanShortPair.class, boolean.class, short.class,
(one, two) -> PrimitiveTuples.pair((boolean) one, (short) two));
purePrimitiveInstantiator(BooleanCharPair.class, boolean.class, char.class,
(one, two) -> PrimitiveTuples.pair((boolean) one, (char) two));
purePrimitiveInstantiator(BooleanIntPair.class, boolean.class, int.class,
(one, two) -> PrimitiveTuples.pair((boolean) one, (int) two));
purePrimitiveInstantiator(BooleanFloatPair.class, boolean.class, float.class,
(one, two) -> PrimitiveTuples.pair((boolean) one, (float) two));
purePrimitiveInstantiator(BooleanLongPair.class, boolean.class, long.class,
(one, two) -> PrimitiveTuples.pair((boolean) one, (long) two));
purePrimitiveInstantiator(BooleanDoublePair.class, boolean.class, double.class,
(one, two) -> PrimitiveTuples.pair((boolean) one, (double) two));
purePrimitiveInstantiator(ByteBooleanPair.class, byte.class, boolean.class,
(one, two) -> PrimitiveTuples.pair((byte) one, (boolean) two));
purePrimitiveInstantiator(ByteBytePair.class, byte.class, byte.class,
(one, two) -> PrimitiveTuples.pair((byte) one, (byte) two));
purePrimitiveInstantiator(ByteShortPair.class, byte.class, short.class,
(one, two) -> PrimitiveTuples.pair((byte) one, (short) two));
purePrimitiveInstantiator(ByteCharPair.class, byte.class, char.class,
(one, two) -> PrimitiveTuples.pair((byte) one, (char) two));
purePrimitiveInstantiator(ByteIntPair.class, byte.class, int.class,
(one, two) -> PrimitiveTuples.pair((byte) one, (int) two));
purePrimitiveInstantiator(ByteFloatPair.class, byte.class, float.class,
(one, two) -> PrimitiveTuples.pair((byte) one, (float) two));
purePrimitiveInstantiator(ByteLongPair.class, byte.class, long.class,
(one, two) -> PrimitiveTuples.pair((byte) one, (long) two));
purePrimitiveInstantiator(ByteDoublePair.class, byte.class, double.class,
(one, two) -> PrimitiveTuples.pair((byte) one, (double) two));
purePrimitiveInstantiator(ShortBooleanPair.class, short.class, boolean.class,
(one, two) -> PrimitiveTuples.pair((short) one, (boolean) two));
purePrimitiveInstantiator(ShortBytePair.class, short.class, byte.class,
(one, two) -> PrimitiveTuples.pair((short) one, (byte) two));
purePrimitiveInstantiator(ShortShortPair.class, short.class, short.class,
(one, two) -> PrimitiveTuples.pair((short) one, (short) two));
purePrimitiveInstantiator(ShortCharPair.class, short.class, char.class,
(one, two) -> PrimitiveTuples.pair((short) one, (char) two));
purePrimitiveInstantiator(ShortIntPair.class, short.class, int.class,
(one, two) -> PrimitiveTuples.pair((short) one, (int) two));
purePrimitiveInstantiator(ShortFloatPair.class, short.class, float.class,
(one, two) -> PrimitiveTuples.pair((short) one, (float) two));
purePrimitiveInstantiator(ShortLongPair.class, short.class, long.class,
(one, two) -> PrimitiveTuples.pair((short) one, (long) two));
purePrimitiveInstantiator(ShortDoublePair.class, short.class, double.class,
(one, two) -> PrimitiveTuples.pair((short) one, (double) two));
purePrimitiveInstantiator(CharBooleanPair.class, char.class, boolean.class,
(one, two) -> PrimitiveTuples.pair((char) one, (boolean) two));
purePrimitiveInstantiator(CharBytePair.class, char.class, byte.class,
(one, two) -> PrimitiveTuples.pair((char) one, (byte) two));
purePrimitiveInstantiator(CharShortPair.class, char.class, short.class,
(one, two) -> PrimitiveTuples.pair((char) one, (short) two));
purePrimitiveInstantiator(CharCharPair.class, char.class, char.class,
(one, two) -> PrimitiveTuples.pair((char) one, (char) two));
purePrimitiveInstantiator(CharIntPair.class, char.class, int.class,
(one, two) -> PrimitiveTuples.pair((char) one, (int) two));
purePrimitiveInstantiator(CharFloatPair.class, char.class, float.class,
(one, two) -> PrimitiveTuples.pair((char) one, (float) two));
purePrimitiveInstantiator(CharLongPair.class, char.class, long.class,
(one, two) -> PrimitiveTuples.pair((char) one, (long) two));
purePrimitiveInstantiator(CharDoublePair.class, char.class, double.class,
(one, two) -> PrimitiveTuples.pair((char) one, (double) two));
purePrimitiveInstantiator(IntBooleanPair.class, int.class, boolean.class,
(one, two) -> PrimitiveTuples.pair((int) one, (boolean) two));
purePrimitiveInstantiator(IntBytePair.class, int.class, byte.class,
(one, two) -> PrimitiveTuples.pair((int) one, (byte) two));
purePrimitiveInstantiator(IntShortPair.class, int.class, short.class,
(one, two) -> PrimitiveTuples.pair((int) one, (short) two));
purePrimitiveInstantiator(IntCharPair.class, int.class, char.class,
(one, two) -> PrimitiveTuples.pair((int) one, (char) two));
purePrimitiveInstantiator(IntIntPair.class, int.class, int.class,
(one, two) -> PrimitiveTuples.pair((int) one, (int) two));
purePrimitiveInstantiator(IntFloatPair.class, int.class, float.class,
(one, two) -> PrimitiveTuples.pair((int) one, (float) two));
purePrimitiveInstantiator(IntLongPair.class, int.class, long.class,
(one, two) -> PrimitiveTuples.pair((int) one, (long) two));
purePrimitiveInstantiator(IntDoublePair.class, int.class, double.class,
(one, two) -> PrimitiveTuples.pair((int) one, (double) two));
purePrimitiveInstantiator(FloatBooleanPair.class, float.class, boolean.class,
(one, two) -> PrimitiveTuples.pair((float) one, (boolean) two));
purePrimitiveInstantiator(FloatBytePair.class, float.class, byte.class,
(one, two) -> PrimitiveTuples.pair((float) one, (byte) two));
purePrimitiveInstantiator(FloatShortPair.class, float.class, short.class,
(one, two) -> PrimitiveTuples.pair((float) one, (short) two));
purePrimitiveInstantiator(FloatCharPair.class, float.class, char.class,
(one, two) -> PrimitiveTuples.pair((float) one, (char) two));
purePrimitiveInstantiator(FloatIntPair.class, float.class, int.class,
(one, two) -> PrimitiveTuples.pair((float) one, (int) two));
purePrimitiveInstantiator(FloatFloatPair.class, float.class, float.class,
(one, two) -> PrimitiveTuples.pair((float) one, (float) two));
purePrimitiveInstantiator(FloatLongPair.class, float.class, long.class,
(one, two) -> PrimitiveTuples.pair((float) one, (long) two));
purePrimitiveInstantiator(FloatDoublePair.class, float.class, double.class,
(one, two) -> PrimitiveTuples.pair((float) one, (double) two));
purePrimitiveInstantiator(LongBooleanPair.class, long.class, boolean.class,
(one, two) -> PrimitiveTuples.pair((long) one, (boolean) two));
purePrimitiveInstantiator(LongBytePair.class, long.class, byte.class,
(one, two) -> PrimitiveTuples.pair((long) one, (byte) two));
purePrimitiveInstantiator(LongShortPair.class, long.class, short.class,
(one, two) -> PrimitiveTuples.pair((long) one, (short) two));
purePrimitiveInstantiator(LongCharPair.class, long.class, char.class,
(one, two) -> PrimitiveTuples.pair((long) one, (char) two));
purePrimitiveInstantiator(LongIntPair.class, long.class, int.class,
(one, two) -> PrimitiveTuples.pair((long) one, (int) two));
purePrimitiveInstantiator(LongFloatPair.class, long.class, float.class,
(one, two) -> PrimitiveTuples.pair((long) one, (float) two));
purePrimitiveInstantiator(LongLongPair.class, long.class, long.class,
(one, two) -> PrimitiveTuples.pair((long) one, (long) two));
purePrimitiveInstantiator(LongDoublePair.class, long.class, double.class,
(one, two) -> PrimitiveTuples.pair((long) one, (double) two));
purePrimitiveInstantiator(DoubleBooleanPair.class, double.class, boolean.class,
(one, two) -> PrimitiveTuples.pair((double) one, (boolean) two));
purePrimitiveInstantiator(DoubleBytePair.class, double.class, byte.class,
(one, two) -> PrimitiveTuples.pair((double) one, (byte) two));
purePrimitiveInstantiator(DoubleShortPair.class, double.class, short.class,
(one, two) -> PrimitiveTuples.pair((double) one, (short) two));
purePrimitiveInstantiator(DoubleCharPair.class, double.class, char.class,
(one, two) -> PrimitiveTuples.pair((double) one, (char) two));
purePrimitiveInstantiator(DoubleIntPair.class, double.class, int.class,
(one, two) -> PrimitiveTuples.pair((double) one, (int) two));
purePrimitiveInstantiator(DoubleFloatPair.class, double.class, float.class,
(one, two) -> PrimitiveTuples.pair((double) one, (float) two));
purePrimitiveInstantiator(DoubleLongPair.class, double.class, long.class,
(one, two) -> PrimitiveTuples.pair((double) one, (long) two));
purePrimitiveInstantiator(DoubleDoublePair.class, double.class, double.class,
(one, two) -> PrimitiveTuples.pair((double) one, (double) two));
}
}