/*
* ToroDB
* Copyright © 2014 8Kdata Technology (www.8kdata.com)
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.torodb.backend.derby.converters.array;
import com.google.common.collect.Maps;
import com.torodb.backend.converters.array.ArrayConverter;
import com.torodb.backend.converters.array.BinaryToArrayConverter;
import com.torodb.backend.converters.array.BooleanToArrayConverter;
import com.torodb.backend.converters.array.DateToArrayConverter;
import com.torodb.backend.converters.array.DoubleToArrayConverter;
import com.torodb.backend.converters.array.InstantToArrayConverter;
import com.torodb.backend.converters.array.IntegerToArrayConverter;
import com.torodb.backend.converters.array.LongToArrayConverter;
import com.torodb.backend.converters.array.MongoObjectIdToArrayConverter;
import com.torodb.backend.converters.array.MongoTimestampToArrayConverter;
import com.torodb.backend.converters.array.NullToArrayConverter;
import com.torodb.backend.converters.array.StringToArrayConverter;
import com.torodb.backend.converters.array.TimeToArrayConverter;
import com.torodb.backend.converters.array.ValueToArrayConverterProvider;
import com.torodb.core.exceptions.SystemException;
import com.torodb.kvdocument.types.ArrayType;
import com.torodb.kvdocument.types.BinaryType;
import com.torodb.kvdocument.types.BooleanType;
import com.torodb.kvdocument.types.DateType;
import com.torodb.kvdocument.types.DoubleType;
import com.torodb.kvdocument.types.InstantType;
import com.torodb.kvdocument.types.IntegerType;
import com.torodb.kvdocument.types.KvType;
import com.torodb.kvdocument.types.LongType;
import com.torodb.kvdocument.types.MongoObjectIdType;
import com.torodb.kvdocument.types.MongoTimestampType;
import com.torodb.kvdocument.types.NullType;
import com.torodb.kvdocument.types.StringType;
import com.torodb.kvdocument.types.TimeType;
import com.torodb.kvdocument.values.KvArray;
import com.torodb.kvdocument.values.KvBinary;
import com.torodb.kvdocument.values.KvBoolean;
import com.torodb.kvdocument.values.KvDate;
import com.torodb.kvdocument.values.KvInstant;
import com.torodb.kvdocument.values.KvInteger;
import com.torodb.kvdocument.values.KvLong;
import com.torodb.kvdocument.values.KvMongoObjectId;
import com.torodb.kvdocument.values.KvNull;
import com.torodb.kvdocument.values.KvString;
import com.torodb.kvdocument.values.KvTime;
import java.util.Map;
import javax.annotation.Nonnull;
import javax.json.JsonArray;
import javax.json.JsonNumber;
import javax.json.JsonObject;
import javax.json.JsonString;
import javax.json.JsonValue;
public class DerbyValueToArrayConverterProvider implements ValueToArrayConverterProvider {
private static final long serialVersionUID = 1L;
private final Map<Class<? extends KvType>, ArrayConverter<?, ?>> converters;
private final ArrayConverter<JsonArray, KvArray> arrayConverter;
private final ArrayConverter<JsonValue, KvBoolean> booleanConverter;
private final ArrayConverter<JsonString, KvDate> dateConverter;
private final ArrayConverter<JsonString, KvInstant> dateTimeConverter;
private final DoubleToArrayConverter doubleConverter;
private final ArrayConverter<JsonNumber, KvInteger> integerConverter;
private final ArrayConverter<JsonNumber, KvLong> longConverter;
private final ArrayConverter<JsonValue, KvNull> nullConverter;
private final ArrayConverter<JsonString, KvString> stringConverter;
private final ArrayConverter<JsonString, KvTime> timeConverter;
private final ArrayConverter<JsonString, KvMongoObjectId> mongoObjectIdConverter;
private final MongoTimestampToArrayConverter mongoTimestampConverter;
private final ArrayConverter<JsonString, KvBinary> binaryConverter;
private DerbyValueToArrayConverterProvider() {
arrayConverter = new ArrayToArrayConverter(this);
booleanConverter = new BooleanToArrayConverter();
dateConverter = new DateToArrayConverter();
dateTimeConverter = new InstantToArrayConverter();
doubleConverter = new DoubleToArrayConverter();
integerConverter = new IntegerToArrayConverter();
longConverter = new LongToArrayConverter();
nullConverter = new NullToArrayConverter();
stringConverter = new StringToArrayConverter();
timeConverter = new TimeToArrayConverter();
mongoObjectIdConverter = new MongoObjectIdToArrayConverter();
mongoTimestampConverter = new MongoTimestampToArrayConverter();
binaryConverter = new BinaryToArrayConverter();
converters = Maps.newHashMap();
converters.put(ArrayType.class, arrayConverter);
converters.put(BooleanType.class, booleanConverter);
converters.put(DateType.class, dateConverter);
converters.put(InstantType.class, dateTimeConverter);
converters.put(DoubleType.class, doubleConverter);
converters.put(IntegerType.class, integerConverter);
converters.put(LongType.class, longConverter);
converters.put(NullType.class, nullConverter);
converters.put(StringType.class, stringConverter);
converters.put(TimeType.class, timeConverter);
converters.put(MongoObjectIdType.class, mongoObjectIdConverter);
converters.put(MongoTimestampType.class, mongoTimestampConverter);
converters.put(BinaryType.class, binaryConverter);
}
public static DerbyValueToArrayConverterProvider getInstance() {
return ToArrayConverterHolder.INSTANCE;
}
@Override
public ArrayConverter<?, ?> getConverter(KvType valueType) {
ArrayConverter<?, ?> converter = converters.get(valueType.getClass());
if (converter == null) {
throw new AssertionError("There is no converter that converts "
+ "elements of type " + valueType);
}
return converter;
}
@Override
@Nonnull
public ArrayConverter<?, ?> fromJsonValue(JsonValue jsonValue) {
switch (jsonValue.getValueType()) {
case ARRAY:
assert jsonValue instanceof JsonArray;
return arrayConverter;
case TRUE:
case FALSE:
return booleanConverter;
case NULL:
return nullConverter;
case NUMBER:
assert jsonValue instanceof JsonNumber;
JsonNumber number = (JsonNumber) jsonValue;
if (number.isIntegral()) {
try {
long l = number.longValueExact();
if (l < Integer.MIN_VALUE || l > Integer.MAX_VALUE) {
return longConverter;
}
return integerConverter;
} catch (ArithmeticException ex) {
throw new SystemException(
"Unexpected integral value. " + number + " is "
+ "bigger than long values"
);
}
}
return doubleConverter;
case STRING:
assert jsonValue instanceof JsonString;
return stringConverter;
case OBJECT: {
JsonObject asObject = ((JsonObject) jsonValue);
if (mongoTimestampConverter.isValid(asObject)) {
return mongoTimestampConverter;
}
throw new IllegalArgumentException("Te recived JsonObject " + jsonValue
+ " was not recognized as a valid KVValue codification");
}
default:
throw new IllegalArgumentException("Instances of '"
+ jsonValue.getClass() + "' like '" + jsonValue
+ "' are not supported");
}
}
public ArrayConverter<JsonArray, KvArray> getArrayConverter() {
return arrayConverter;
}
public ArrayConverter<JsonValue, KvBoolean> getBooleanConverter() {
return booleanConverter;
}
public ArrayConverter<JsonString, KvDate> getDateConverter() {
return dateConverter;
}
public ArrayConverter<JsonString, KvInstant> getInstantConverter() {
return dateTimeConverter;
}
public DoubleToArrayConverter getDoubleConverter() {
return doubleConverter;
}
public ArrayConverter<JsonNumber, KvInteger> getIntegerConverter() {
return integerConverter;
}
public ArrayConverter<JsonNumber, KvLong> getLongConverter() {
return longConverter;
}
public ArrayConverter<JsonValue, KvNull> getNullConverter() {
return nullConverter;
}
public ArrayConverter<JsonString, KvString> getStringConverter() {
return stringConverter;
}
public ArrayConverter<JsonString, KvTime> getTimeConverter() {
return timeConverter;
}
public ArrayConverter<JsonString, KvMongoObjectId> getMongoObjectIdConverter() {
return mongoObjectIdConverter;
}
public MongoTimestampToArrayConverter getMongoTimestampConverter() {
return mongoTimestampConverter;
}
public ArrayConverter<JsonString, KvBinary> getBinaryConverter() {
return binaryConverter;
}
private static class ToArrayConverterHolder {
private static final DerbyValueToArrayConverterProvider INSTANCE =
new DerbyValueToArrayConverterProvider();
}
//@edu.umd.cs.findbugs.annotations.SuppressFBWarnings(value = "UPM_UNCALLED_PRIVATE_METHOD")
private Object readResolve() {
return DerbyValueToArrayConverterProvider.getInstance();
}
}