/**
* Copyright 2004-2016 Riccardo Solmi. All rights reserved.
* This file is part of the Whole Platform.
*
* The Whole Platform is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* The Whole Platform 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 Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with the Whole Platform. If not, see <http://www.gnu.org/licenses/>.
*/
package org.whole.lang.sql.parsers;
import java.lang.reflect.Array;
import java.math.BigDecimal;
import java.sql.Date;
import java.sql.Time;
import java.sql.Timestamp;
import java.util.HashMap;
import java.util.Map;
import org.whole.lang.exceptions.WholeIllegalArgumentException;
import org.whole.lang.model.EnumValue;
import org.whole.lang.parsers.DefaultDataTypePresentationParser;
import org.whole.lang.reflect.EntityDescriptor;
import org.whole.lang.sql.model.BinaryOperatorEnum;
import org.whole.lang.sql.model.BooleanOperatorEnum;
import org.whole.lang.sql.model.IsTypeEnum;
import org.whole.lang.sql.reflect.SQLEntityDescriptorEnum;
import org.whole.lang.util.WholeMessages;
/**
* @author Riccardo Solmi
*/
public class SQLDataTypeParser extends DefaultDataTypePresentationParser {
private static class SingletonHolder {
private static final SQLDataTypeParser instance = new SQLDataTypeParser();
}
public static SQLDataTypeParser instance() {
return SingletonHolder.instance;
}
protected SQLDataTypeParser() {
}
public String parseString(EntityDescriptor<?> ed, String value) {
if (ed.getOrdinal() == SQLEntityDescriptorEnum.StringValue_ord)
return value.replace("''", "'");
else
return super.parseString(ed, value);
}
public String unparseString(EntityDescriptor<?> ed, String value) {
if (ed.getOrdinal() == SQLEntityDescriptorEnum.StringValue_ord)
return value.replace("'", "''");
else
return super.unparseString(ed, value);
}
public Object parseObject(EntityDescriptor<?> ed, String value) {
switch (ed.getOrdinal()) {
case SQLEntityDescriptorEnum.DecimalValue_ord:
return new BigDecimal(value);
case SQLEntityDescriptorEnum.ArrayValue_ord:
String[] values = value.split(",");
Object[] array = new Object[values.length];
for (int i=0; i<values.length; i++)
array[i] = Integer.parseInt(values[i].trim());
return array;
case SQLEntityDescriptorEnum.BinaryValue_ord:
int length = value.length()/2;
byte[] bytes = new byte[length];
for (int i=0; i<length; i++)
bytes[i] = (byte)
((Character.digit(value.charAt(i*2), 16) << 4) +
Character.digit(value.charAt(i*2+1), 16));
return bytes;
case SQLEntityDescriptorEnum.DateValue_ord:
return Date.valueOf(value);
case SQLEntityDescriptorEnum.TimeValue_ord:
return Time.valueOf(value);
case SQLEntityDescriptorEnum.TimestampValue_ord:
return Timestamp.valueOf(value);
}
throw new WholeIllegalArgumentException(WholeMessages.no_data_type);
}
public String unparseObject(EntityDescriptor<?> ed, Object value) {
switch (ed.getOrdinal()) {
case SQLEntityDescriptorEnum.ArrayValue_ord:
assert value.getClass().isArray();
StringBuilder sb = new StringBuilder();
int length = Array.getLength(value);
for (int i=0; i<length; i++) {
if (i>0)
sb.append(", ");
sb.append(Array.get(value, i));
}
return sb.toString();
case SQLEntityDescriptorEnum.BinaryValue_ord:
assert value.getClass().isArray();
StringBuilder sb2 = new StringBuilder();
int length2 = Array.getLength(value);
for (int i=0; i<length2; i++) {
int byteVal = (Byte) Array.get(value, i);
sb2.append(Character.forDigit((byteVal & 255) >>> 4, 16));
sb2.append(Character.forDigit(byteVal & 15, 16));
}
return sb2.toString();
}
return value != null ? value.toString() : " ";
}
public EnumValue parseEnumValue(EntityDescriptor<?> ed, String value) {
EnumValue enumValue = null;
switch (ed.getOrdinal()) {
case SQLEntityDescriptorEnum.BinaryOperator_ord:
enumValue = parseBinaryOperator(value);
break;
case SQLEntityDescriptorEnum.BooleanOperator_ord:
enumValue = parseBooleanOperator(value);
break;
case SQLEntityDescriptorEnum.IsType_ord:
enumValue = parseIsType(value);
break;
}
if (enumValue != null)
return enumValue;
else
return super.parseEnumValue(ed, value);
}
public String unparseEnumValue(EntityDescriptor<?> ed, EnumValue value) {
switch (ed.getOrdinal()) {
case SQLEntityDescriptorEnum.BinaryOperator_ord:
return unparseBinaryOperator(value);
case SQLEntityDescriptorEnum.BooleanOperator_ord:
return unparseBooleanOperator(value);
case SQLEntityDescriptorEnum.IsType_ord:
return unparseIsType(value);
default:
return super.unparseEnumValue(ed, value);
}
}
public static final String unparseIsType(EnumValue value) {
switch (value.getOrdinal()) {
case IsTypeEnum.NULL_ord:
return "NULL";
case IsTypeEnum.NOT_NULL_ord:
return "NOT NULL";
case IsTypeEnum.TRUE_ord:
return "TRUE";
case IsTypeEnum.NOT_TRUE_ord:
return "NOT TRUE";
case IsTypeEnum.FALSE_ord:
return "FALSE";
case IsTypeEnum.NOT_FALSE_ord:
return "NOT FALSE";
case IsTypeEnum.UNKNOWN_ord:
return "UNKNOWN";
case IsTypeEnum.NOT_UNKNOWN_ord:
return "NOT UNKNOWN";
default:
throw new IllegalArgumentException();
}
}
public static final String unparseBinaryOperator(EnumValue value) {
switch (value.getOrdinal()) {
case BinaryOperatorEnum.concat_ord:
return "+";
case BinaryOperatorEnum.div_ord:
return "/";
case BinaryOperatorEnum.mul_ord:
return "*";
case BinaryOperatorEnum.sub_ord:
return "-";
case BinaryOperatorEnum.sum_ord:
return "+";
default:
throw new IllegalArgumentException();
}
}
public static final String unparseBooleanOperator(EnumValue value) {
switch (value.getOrdinal()) {
case BooleanOperatorEnum.and_ord:
return "and";
case BooleanOperatorEnum.eq_ord:
return "=";
case BooleanOperatorEnum.ge_ord:
return ">=";
case BooleanOperatorEnum.gt_ord:
return ">";
case BooleanOperatorEnum.le_ord:
return "<=";
case BooleanOperatorEnum.lt_ord:
return "<";
case BooleanOperatorEnum.ne_ord:
return "<>";
case BooleanOperatorEnum.or_ord:
return "or";
case BooleanOperatorEnum.like_ord:
return "LIKE";
default:
throw new IllegalArgumentException();
}
}
private static volatile Map<String, IsTypeEnum.Value> isTypeMap;
public static final IsTypeEnum.Value parseIsType(String value) {
if (isTypeMap == null) {
synchronized (SQLDataTypeParser.class) {
if (isTypeMap == null) {
isTypeMap = new HashMap<String, IsTypeEnum.Value>();
isTypeMap.put("NULL", IsTypeEnum.NULL);
isTypeMap.put("NOT NULL", IsTypeEnum.NOT_NULL);
isTypeMap.put("FALSE", IsTypeEnum.FALSE);
isTypeMap.put("NOT FALSE", IsTypeEnum.NOT_FALSE);
isTypeMap.put("TRUE", IsTypeEnum.TRUE);
isTypeMap.put("NOT TRUE", IsTypeEnum.NOT_TRUE);
isTypeMap.put("UNKNOWN", IsTypeEnum.UNKNOWN);
isTypeMap.put("NOT UNKNOWN", IsTypeEnum.NOT_UNKNOWN);
assert IsTypeEnum.instance.size() == isTypeMap.size();
}
}
}
return isTypeMap.get(value.toUpperCase());
}
private static volatile Map<String, BinaryOperatorEnum.Value> binaryOperatorMap;
public static final BinaryOperatorEnum.Value parseBinaryOperator(String value) {
if (binaryOperatorMap == null) {
synchronized (SQLDataTypeParser.class) {
if (binaryOperatorMap == null) {
binaryOperatorMap = new HashMap<String, BinaryOperatorEnum.Value>();
binaryOperatorMap.put("+", BinaryOperatorEnum.concat);
binaryOperatorMap.put("/", BinaryOperatorEnum.div);
binaryOperatorMap.put("*", BinaryOperatorEnum.mul);
binaryOperatorMap.put("-", BinaryOperatorEnum.sub);
binaryOperatorMap.put("+", BinaryOperatorEnum.sum);
assert BinaryOperatorEnum.instance.size() == binaryOperatorMap.size();
}
}
}
return binaryOperatorMap.get(value);
}
private static volatile Map<String, BooleanOperatorEnum.Value> booleanOperatorMap;
public static final BooleanOperatorEnum.Value parseBooleanOperator(String value) {
if (booleanOperatorMap == null) {
synchronized (SQLDataTypeParser.class) {
if (booleanOperatorMap == null) {
booleanOperatorMap = new HashMap<String, BooleanOperatorEnum.Value>();
booleanOperatorMap.put("and", BooleanOperatorEnum.and);
booleanOperatorMap.put("=", BooleanOperatorEnum.eq);
booleanOperatorMap.put(">=", BooleanOperatorEnum.ge);
booleanOperatorMap.put(">", BooleanOperatorEnum.gt);
booleanOperatorMap.put("<=", BooleanOperatorEnum.le);
booleanOperatorMap.put("<", BooleanOperatorEnum.lt);
booleanOperatorMap.put("<>", BooleanOperatorEnum.ne);
booleanOperatorMap.put("or", BooleanOperatorEnum.or);
booleanOperatorMap.put("LIKE", BooleanOperatorEnum.like);
assert BooleanOperatorEnum.instance.size() == booleanOperatorMap.size();
}
}
}
return booleanOperatorMap.get(value);
}
}