Please wait. This can take some minutes ...
Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance.
Project price only 1 $
You can buy this project and download/modify it how often you want.
com.googlecode.paradox.rowset.ValuesConverter Maven / Gradle / Ivy
/*
* Copyright (c) 2009 Leonardo Alves da Costa
*
* This program is free software: you can redistribute it and/or modify it under the terms of the GNU 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 General Public
* License for more details. You should have received a copy of the GNU General Public License along with this
* program. If not, see .
*/
package com.googlecode.paradox.rowset;
import com.googlecode.paradox.ConnectionInfo;
import com.googlecode.paradox.exceptions.DataError;
import com.googlecode.paradox.exceptions.ParadoxDataException;
import com.googlecode.paradox.exceptions.ParadoxSyntaxErrorException;
import com.googlecode.paradox.exceptions.SyntaxError;
import com.googlecode.paradox.results.ParadoxType;
import java.io.DataInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.math.BigDecimal;
import java.nio.ByteBuffer;
import java.nio.charset.*;
import java.sql.*;
import java.util.Calendar;
import java.util.HashMap;
import java.util.Map;
import java.util.Optional;
import java.util.function.BiFunction;
/**
* Custom values conversion utility class.
*
* @since 1.6.0
*/
public final class ValuesConverter {
/**
* Default class mapping.
*/
private static final Map, BiFunction> CLASS_MAPPING = new HashMap<>();
/**
* Default type mapping.
*/
private static final Map> TYPE_MAPPING = new HashMap<>();
static {
CLASS_MAPPING.put(BigDecimal.class, ValuesConverter::getBigDecimal);
CLASS_MAPPING.put(Boolean.class, ValuesConverter::getBoolean);
CLASS_MAPPING.put(Byte.class, ValuesConverter::getByte);
CLASS_MAPPING.put(byte[].class, ValuesConverter::getByteArray);
CLASS_MAPPING.put(Date.class, ValuesConverter::getDate);
CLASS_MAPPING.put(Double.class, ValuesConverter::getDouble);
CLASS_MAPPING.put(Float.class, ValuesConverter::getFloat);
CLASS_MAPPING.put(Integer.class, ValuesConverter::getInteger);
CLASS_MAPPING.put(Long.class, ValuesConverter::getLong);
CLASS_MAPPING.put(Short.class, ValuesConverter::getShort);
CLASS_MAPPING.put(String.class, ValuesConverter::getString);
CLASS_MAPPING.put(Time.class, ValuesConverter::getTime);
CLASS_MAPPING.put(Timestamp.class, ValuesConverter::getTimestamp);
TYPE_MAPPING.put(Types.BOOLEAN, ValuesConverter::getBoolean);
TYPE_MAPPING.put(Types.BINARY, ValuesConverter::getByteArray);
TYPE_MAPPING.put(Types.BLOB, ValuesConverter::getByteArray);
TYPE_MAPPING.put(Types.DATE, ValuesConverter::getDate);
TYPE_MAPPING.put(Types.DOUBLE, ValuesConverter::getDouble);
TYPE_MAPPING.put(Types.NUMERIC, ValuesConverter::getDouble);
TYPE_MAPPING.put(Types.FLOAT, ValuesConverter::getFloat);
TYPE_MAPPING.put(Types.INTEGER, ValuesConverter::getInteger);
TYPE_MAPPING.put(Types.CLOB, ValuesConverter::getString);
TYPE_MAPPING.put(Types.NCLOB, ValuesConverter::getString);
TYPE_MAPPING.put(Types.VARCHAR, ValuesConverter::getString);
TYPE_MAPPING.put(Types.NVARCHAR, ValuesConverter::getString);
TYPE_MAPPING.put(Types.TIME, ValuesConverter::getTime);
TYPE_MAPPING.put(Types.TIMESTAMP, ValuesConverter::getTimestamp);
TYPE_MAPPING.put(Types.TIMESTAMP_WITH_TIMEZONE, ValuesConverter::getTimestamp);
}
/**
* Utility class, not for use.
*/
private ValuesConverter() {
super();
}
/**
* Converts the value to one defined in type.
*
* @param value the value to convert.
* @param type the destination type.
* @param connectionInfo the connection info.
* @param the result class.
* @return the converted value.
* @throws SQLException in case of failures.
*/
@SuppressWarnings("unchecked")
public static T convert(final Object value, Class type, final ConnectionInfo connectionInfo) throws SQLException {
try {
return (T) CLASS_MAPPING.get(type).apply(value, connectionInfo);
} catch (final IllegalArgumentException e) {
throw new ParadoxDataException(DataError.INVALID_CONVERSION, e, value);
}
}
/**
* Converts the value to one defined in type.
*
* @param value the value to convert.
* @param sqlType the destination type.
* @param connectionInfo the connection info.
* @return the converted value.
* @throws SQLException in case of failures.
*/
public static Object convert(final Object value, int sqlType, final ConnectionInfo connectionInfo)
throws SQLException {
try {
return TYPE_MAPPING.get(sqlType).apply(value, connectionInfo);
} catch (final IllegalArgumentException e) {
throw new ParadoxDataException(DataError.INVALID_CONVERSION, e, value);
}
}
/**
* Converts the value to one defined in type.
*
* @param value the value to convert.
* @param type the destination type.
* @param connectionInfo the connection info.
* @return the converted value.
* @throws SQLException in case of failures.
*/
public static Object convert(final Object value, ParadoxType type, final ConnectionInfo connectionInfo) throws SQLException {
try {
return CLASS_MAPPING.get(type.getJavaClass()).apply(value, connectionInfo);
} catch (final IllegalArgumentException e) {
throw new ParadoxDataException(DataError.INVALID_CONVERSION, e, value);
}
}
/**
* Converts the value to boolean.
*
* @param value the value to convert.
* @param connectionInfo the connection info.
* @return the converted boolean value.
*/
public static Boolean getBoolean(final Object value, final ConnectionInfo connectionInfo) {
Boolean ret = null;
if (value instanceof Boolean) {
ret = (Boolean) value;
} else if (value instanceof Number) {
if (((Number) value).intValue() == 0) {
ret = Boolean.FALSE;
} else {
ret = Boolean.TRUE;
}
} else if (value != null) {
final Integer i = getInteger(value, connectionInfo);
if (i != null) {
// Try to convert with integers.
if (i == 0) {
ret = Boolean.FALSE;
} else {
ret = Boolean.TRUE;
}
} else {
ret = Boolean.valueOf(value.toString());
}
}
return ret;
}
/**
* Converts the value to byte.
*
* @param value the value to convert.
* @param connectionInfo the connection info.
* @return the converted byte value.
*/
public static Byte getByte(final Object value, final ConnectionInfo connectionInfo) {
Byte ret = null;
if (value instanceof Byte) {
ret = (Byte) value;
} else if (value instanceof Number) {
ret = ((Number) value).byteValue();
} else if (value instanceof Boolean) {
if (((boolean) value)) {
ret = 1;
} else {
ret = 0;
}
} else if (value != null) {
try {
ret = Byte.valueOf(value.toString());
} catch (final NumberFormatException e) {
connectionInfo.addWarning(e);
}
}
return ret;
}
/**
* Converts the value to short.
*
* @param value the value to convert.
* @param connectionInfo the connection info.
* @return the converted short value.
*/
public static Short getShort(final Object value, final ConnectionInfo connectionInfo) {
Short ret = null;
if (value instanceof Short) {
ret = (Short) value;
} else if (value instanceof Number) {
ret = ((Number) value).shortValue();
} else if (value instanceof Boolean) {
if (((boolean) value)) {
ret = 1;
} else {
ret = 0;
}
} else if (value != null) {
try {
ret = Short.valueOf(value.toString());
} catch (final NumberFormatException e) {
connectionInfo.addWarning(e);
}
}
return ret;
}
/**
* Convert to a valid positive integer.
*
* @param value the value to convert.
* @param connectionInfo the connection information.
* @return a positive integer value.
* @throws ParadoxSyntaxErrorException if the value is not a valid integer value.
*/
public static int getPositiveInteger(final Object value, final ConnectionInfo connectionInfo)
throws ParadoxSyntaxErrorException {
final Integer size = getInteger(value, connectionInfo);
if (size == null || size < 0) {
throw new ParadoxSyntaxErrorException(SyntaxError.INVALID_PARAMETER_VALUE, value);
}
return size;
}
/**
* Get the value as integer.
*
* @param value the value to convert.
* @param connectionInfo the connection info.
* @return the integer value.
*/
public static Integer getInteger(final Object value, final ConnectionInfo connectionInfo) {
Integer ret = null;
if (value instanceof Integer) {
ret = (Integer) value;
} else if (value instanceof Number) {
ret = ((Number) value).intValue();
} else if (value instanceof Boolean) {
if (((boolean) value)) {
ret = 1;
} else {
ret = 0;
}
} else if (value != null) {
try {
ret = Integer.valueOf(value.toString());
} catch (final NumberFormatException e) {
connectionInfo.addWarning(e);
try {
// Try to convert with BigDecimal.
ret = new BigDecimal(value.toString()).intValue();
} catch (final NumberFormatException e1) {
connectionInfo.addWarning(e1);
}
}
}
return ret;
}
/**
* Get the value as long.
*
* @param value the value to convert.
* @param connectionInfo the connection info.
* @return the long value.
*/
public static Long getLong(final Object value, final ConnectionInfo connectionInfo) {
Long ret = null;
if (value instanceof Long) {
ret = (Long) value;
} else if (value instanceof Number) {
ret = ((Number) value).longValue();
} else if (value instanceof Boolean) {
if (((boolean) value)) {
ret = 1L;
} else {
ret = 0L;
}
} else if (value != null) {
try {
ret = Long.valueOf(value.toString());
} catch (final NumberFormatException e) {
connectionInfo.addWarning(e);
try {
// Try to convert with BigDecimal.
ret = new BigDecimal(value.toString()).longValue();
} catch (final NumberFormatException e1) {
connectionInfo.addWarning(e1);
}
}
}
return ret;
}
/**
* Get the value as {@link BigDecimal}.
*
* @param value the value to convert.
* @param connectionInfo the connection info.
* @return the {@link BigDecimal} value.
*/
public static BigDecimal getBigDecimal(final Object value, final ConnectionInfo connectionInfo) {
BigDecimal ret = null;
if (value instanceof BigDecimal) {
return (BigDecimal) value;
} else if (value instanceof Number) {
ret = BigDecimal.valueOf(((Number) value).doubleValue());
} else if (value instanceof Boolean) {
if (((boolean) value)) {
ret = BigDecimal.ONE;
} else {
ret = BigDecimal.ZERO;
}
} else if (value != null) {
try {
ret = new BigDecimal(value.toString());
} catch (final NumberFormatException e) {
connectionInfo.addWarning(e);
}
}
return ret;
}
/**
* Get the value as float.
*
* @param value the value to convert.
* @param connectionInfo the connection info.
* @return the float value.
*/
public static Float getFloat(final Object value, final ConnectionInfo connectionInfo) {
Float ret = null;
if (value instanceof Float) {
ret = (Float) value;
} else if (value instanceof Number) {
ret = ((Number) value).floatValue();
} else if (value instanceof Boolean) {
if (((boolean) value)) {
ret = 1.0F;
} else {
ret = 0.0F;
}
} else if (value != null) {
try {
ret = Float.valueOf(value.toString());
} catch (final NumberFormatException e) {
connectionInfo.addWarning(e);
}
}
return ret;
}
/**
* Get the value as double.
*
* @param value the value to convert.
* @param connectionInfo the connection info.
* @return the double value.
*/
public static Double getDouble(final Object value, final ConnectionInfo connectionInfo) {
Double ret = null;
if (value instanceof Double) {
ret = (Double) value;
} else if (value instanceof Number) {
ret = ((Number) value).doubleValue();
} else if (value instanceof Boolean) {
if (((boolean) value)) {
ret = 1.0;
} else {
ret = 0.0;
}
} else if (value != null) {
try {
ret = Double.valueOf(value.toString());
} catch (final NumberFormatException e) {
connectionInfo.addWarning(e);
}
}
return ret;
}
/**
* Gets only the time part from the date.
*
* @param date the date to use.
* @return the time part of the date.
*/
public static Time removeDate(java.util.Date date) {
if (date == null) {
return null;
}
Calendar c = Calendar.getInstance();
c.setTime(date);
c.set(Calendar.YEAR, 1970);
c.set(Calendar.MONTH, Calendar.JANUARY);
c.set(Calendar.DAY_OF_MONTH, 1);
return new Time(c.getTimeInMillis());
}
/**
* Get the value as {@link Time}.
*
* @param value the value to convert.
* @param connectionInfo the connection info.
* @return the {@link Time} value.
*/
public static Time getTime(final Object value, final ConnectionInfo connectionInfo) {
Time ret = null;
if (value instanceof Time) {
ret = (Time) value;
} else if (value instanceof java.util.Date) {
ret = removeDate((java.util.Date) value);
} else if (value != null) {
try {
ret = Time.valueOf(value.toString().trim());
} catch (final IllegalArgumentException e) {
connectionInfo.addWarning(e);
try {
// Trying with Date instead.
final Date date = Date.valueOf(value.toString());
ret = removeDate(date);
} catch (final IllegalArgumentException e1) {
connectionInfo.addWarning(e1);
try {
// Trying with Timestamp instead.
final Timestamp timestamp = Timestamp.valueOf(value.toString());
ret = removeDate(timestamp);
} catch (final IllegalArgumentException e2) {
connectionInfo.addWarning(e2);
}
}
}
}
return ret;
}
/**
* Get the value as {@link Timestamp}.
*
* @param value the value to convert.
* @param connectionInfo the connection info.
* @return the {@link Timestamp} value.
*/
public static Timestamp getTimestamp(final Object value, final ConnectionInfo connectionInfo) {
Timestamp ret = null;
if (value instanceof Timestamp) {
ret = (Timestamp) value;
} else if (value instanceof java.util.Date) {
ret = new Timestamp(((java.util.Date) value).getTime());
} else if (value != null) {
try {
ret = Timestamp.valueOf(value.toString().trim());
} catch (final IllegalArgumentException e) {
connectionInfo.addWarning(e);
try {
// Trying with Date instead.
final Date date = Date.valueOf(value.toString());
ret = new Timestamp(date.getTime());
} catch (final IllegalArgumentException e1) {
connectionInfo.addWarning(e1);
try {
// Trying with Time instead.
final Time time = Time.valueOf(value.toString());
ret = new Timestamp(time.getTime());
} catch (final IllegalArgumentException e2) {
connectionInfo.addWarning(e2);
}
}
}
}
return ret;
}
/**
* Gets the date without time.
*
* @param date the date to use.
* @return the date without the time.
*/
public static Date removeTime(java.util.Date date) {
if (date == null) {
return null;
}
Calendar c = Calendar.getInstance();
c.setTime(date);
c.set(Calendar.HOUR_OF_DAY, 0);
c.set(Calendar.MINUTE, 0);
c.set(Calendar.SECOND, 0);
c.set(Calendar.MILLISECOND, 0);
return new Date(c.getTimeInMillis());
}
/**
* Get the value as {@link Date}.
*
* @param value the value to convert.
* @param connectionInfo the connection info.
* @return the {@link Date} value.
*/
public static Date getDate(final Object value, final ConnectionInfo connectionInfo) {
Date ret = null;
if (value instanceof Date) {
ret = (Date) value;
} else if (value instanceof java.util.Date) {
ret = removeTime((java.util.Date) value);
} else if (value != null) {
try {
ret = Date.valueOf(value.toString().trim());
} catch (final IllegalArgumentException e) {
connectionInfo.addWarning(e);
try {
// Trying with timestamp instead.
final Timestamp timestamp = Timestamp.valueOf(value.toString());
ret = removeTime(timestamp);
} catch (final IllegalArgumentException e1) {
connectionInfo.addWarning(e1);
}
}
}
return ret;
}
/**
* Get the value as byte[].
*
* @param value the value to convert.
* @param connectionInfo the connection info.
* @return the byte[] value.
*/
public static byte[] getByteArray(final Object value, final ConnectionInfo connectionInfo) {
byte[] ret = null;
if (value instanceof byte[]) {
ret = (byte[]) value;
} else if (value != null) {
ret = value.toString().getBytes(StandardCharsets.UTF_8);
}
return ret;
}
/**
* Get the value as String.
*
* @param value the value to convert.
* @param connectionInfo the connection info.
* @return the String value.
*/
public static String getString(final Object value, final ConnectionInfo connectionInfo) {
String ret = null;
if (value instanceof String) {
ret = (String) value;
} else if (value instanceof byte[]) {
ret = new String((byte[]) value, StandardCharsets.UTF_8);
} else if (value != null) {
ret = value.toString();
}
return ret;
}
/**
* Get the byte[] from an {@link InputStream}.
*
* @param inputStream the stream to load from.
* @param length the length to load.
* @return the byte[] loaded from stream.
* @throws ParadoxDataException in case of failures.
*/
public static byte[] getBytes(final InputStream inputStream, final int length) throws ParadoxDataException {
byte[] ret = null;
if (inputStream != null) {
try (final DataInputStream dis = new DataInputStream(inputStream)) {
ret = new byte[length];
dis.readFully(ret);
} catch (final IOException e) {
throw new ParadoxDataException(DataError.INVALID_CONVERSION, e, inputStream);
}
}
return ret;
}
/**
* Convert a byte array to String using a charset specified.
*
* @param bytes the byte array to convert.
* @param charset the charset to use.
* @return the converted String.
* @throws ParadoxDataException in case of converter errors.
*/
public static String convert(final byte[] bytes, final Charset charset) throws ParadoxDataException {
final CharsetDecoder decoder = Optional.ofNullable(charset).orElse(StandardCharsets.US_ASCII).newDecoder();
decoder.onMalformedInput(CodingErrorAction.IGNORE);
decoder.onUnmappableCharacter(CodingErrorAction.IGNORE);
final ByteBuffer input = ByteBuffer.wrap(bytes);
try {
return decoder.decode(input).toString();
} catch (CharacterCodingException e) {
throw new ParadoxDataException(DataError.ERROR_LOADING_DATA, e);
}
}
}