package es.udc.cartolab.gvsig.navtable.format;
import java.sql.Time;
import java.sql.Timestamp;
import java.sql.Types;
import java.text.DateFormat;
import java.text.NumberFormat;
import java.text.ParseException;
import com.hardcode.gdbms.engine.values.Value;
import com.hardcode.gdbms.engine.values.ValueFactory;
/**
* ValueFactory to create values from its type, taking into account the format
* of the value as stated in NavTableFormats.
*/
public class ValueFactoryNT extends ValueFactory {
public static Value createValueByType(String text, int type)
throws ParseException {
Value value;
if (text == null) {
return ValueFactory.createNullValue();
}
switch (type) {
case Types.BIGINT:
value = ValueFactory.createValue(Long.parseLong(text));
break;
case Types.BIT:
case Types.BOOLEAN:
value = ValueFactory.createValue(Boolean.valueOf(text)
.booleanValue());
break;
case Types.CHAR:
case Types.VARCHAR:
case Types.LONGVARCHAR:
value = ValueFactory.createValue(text);
break;
case Types.DATE:
try {
value = DateFormatNT.convertStringToValue(text);
} catch (IllegalArgumentException e) {
throw new ParseException(e.getMessage(), 0);
}
break;
case Types.DECIMAL:
case Types.NUMERIC:
case Types.FLOAT:
case Types.DOUBLE:
NumberFormat doubleFormat = DoubleFormatNT.getDisplayingFormat();
value = ValueFactory.createValue(doubleFormat.parse(text)
.doubleValue());
break;
case Types.INTEGER:
NumberFormat integerFormat = IntegerFormatNT.getDisplayingFormat();
value = ValueFactory.createValue(integerFormat.parse(text)
.intValue());
break;
case Types.REAL:
value = ValueFactory.createValue(Float.parseFloat(text));
break;
case Types.SMALLINT:
value = ValueFactory.createValue(Short.parseShort(text));
break;
case Types.TINYINT:
value = ValueFactory.createValue(Byte.parseByte(text));
break;
case Types.BINARY:
case Types.VARBINARY:
case Types.LONGVARBINARY:
if ((text.length() / 2) != (text.length() / 2.0)) {
throw new ParseException(
"binary fields must have even number of characters.", 0);
}
byte[] array = new byte[text.length() / 2];
for (int i = 0; i < (text.length() / 2); i++) {
String byte_ = text.substring(2 * i, (2 * i) + 2);
array[i] = (byte) Integer.parseInt(byte_, 16);
}
value = ValueFactory.createValue(array);
break;
case Types.TIMESTAMP:
value = ValueFactory.createValue(Timestamp.valueOf(text));
break;
case Types.TIME:
DateFormat tf = DateFormat.getTimeInstance();
value = ValueFactory
.createValue(new Time(tf.parse(text).getTime()));
break;
case Types.OTHER:
// We check if the text can be parsed as a number after stripping
// starting and trailing zeroes
doubleFormat = DoubleFormatNT.getDisplayingFormat();
String aux = removeStartingTrailingZeros(text);
try {
Double doubleValue = doubleFormat.parse(aux).doubleValue();
// If the parsed number has the same length as the string, we
// can confirm it can be represented as a number
if ((doubleValue.toString().length() == aux.length())
&& (doubleValue >= 0.0)) {
// If double value and int value are the same, then we
// return an int
if (doubleValue.intValue() == doubleValue.doubleValue()) {
return ValueFactory.createValue(doubleValue.intValue());
}
return ValueFactory.createValue(doubleValue);
}
} catch (ParseException e) {
} catch (Exception e) {
e.printStackTrace();
}
default:
// By default, we return the original string
value = ValueFactory.createValue(text);
}
return value;
}
private static String removeStartingTrailingZeros(String number) {
char decimalSeparator = DoubleFormatNT.getDisplayingFormat()
.format(1.1).charAt(1);
String aux;
if (!number.contains(decimalSeparator + "")) {
aux = number.replaceAll("^[0]*", "");
} else {
aux = number.replaceAll("^[0]*", "").replaceAll("[0]*$", "")
.replaceAll("\\" + decimalSeparator + "$", "");
if (!aux.contains("" + decimalSeparator)) {
aux += decimalSeparator + "0";
}
if (aux.startsWith("" + decimalSeparator)) {
aux = "0" + aux;
}
}
return aux;
}
}