ExpressionBooleanColumn.java
package org.microspace.table.query.sql;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.microspace.table.Entry;
import org.microspace.table.column.Accessor;
import org.microspace.table.column.ColumnReferences;
import org.microspace.table.column.GetSetPair;
import org.microspace.table.column.IndexedMap;
import org.microspace.table.query.SqlFormat;
import org.microspace.util.PojoUtil;
/**
*
* @author Gaspar Sinai - {@literal gaspar.sinai@microspace.org}
* @version 2017-09-29
* @param <T> The type of the Table.
*/
public class ExpressionBooleanColumn<T> implements Expression<T> {
private static final long serialVersionUID = 1L;
final Class<T> tableClass;
final Class<?> columnClass;
final String columnNameL;
final OperatorType operator;
final String columnNameR;
final String columnEscL;
final String columnEscR;
boolean needsBracket = false;
public void setNeedsBracket (boolean needsBracket) {
this.needsBracket = needsBracket;
}
public ExpressionBooleanColumn(Class<T> tableClass,
OperatorType operator, String columnNameL, String columnEscL,
String columnNameR, String columnEscR) {
this.tableClass = tableClass;
this.columnEscL = columnEscL;
this.columnEscR = columnEscR;
Accessor<T> accessor = PojoUtil.getUnannotateAccessor(tableClass);
GetSetPair<T> gettterL = accessor.getGetSetPair(columnNameL);
if (gettterL == null) {
throw new IllegalArgumentException("Unkown Column: " + columnNameL);
}
this.columnClass = PojoUtil.getColumnClass(tableClass, columnNameL);
gettterL = accessor.getGetSetPair(columnNameR);
if (gettterL == null) {
throw new IllegalArgumentException("Unkown Column: " + columnNameR);
}
Class<?> columnClassR = PojoUtil.getColumnClass(tableClass, columnNameR);
if (!columnClassR.equals(columnClass)) {
throw new IllegalArgumentException("Column Type Mismatch: " + columnNameL + " " + columnNameR);
}
this.operator = operator;
this.columnNameL = columnNameL;
this.columnNameR = columnNameR;
if (columnClass == null) {
throw new IllegalArgumentException("Unkown Column");
}
}
public IndexedMap<Object, Entry<T>> apply(Accessor<T> accessor,
IndexedMap<Object, Entry<T>> entries,
ColumnReferences<T>[] indexedColumns, InnerSelectContext<?> innerSelectContext) {
IndexedMap<Object, Entry<T>> retMap = new IndexedMap<Object, Entry<T>>(
accessor.getPrimaryKeyGetSetPair().getIndexType());
GetSetPair<T> getSetPairL = accessor.getGetSetPair(columnNameL);
GetSetPair<T> getSetPairR = accessor.getGetSetPair(columnNameR);
int columnNumberL = getSetPairL.getIndex();
int columnNumberR = getSetPairR.getIndex();
switch (operator) {
case EQ:
for (Entry<T> entry : entries.values()) {
Object fieldL = entry.getField(columnNumberL);
Object fieldR = entry.getField(columnNumberR);
if (fieldL == null && fieldR == null) {
retMap.put(entry.getPrimaryKey(), entry);
continue;
}
if (fieldL == null) continue;
if (fieldR == null) continue;
if (ExpressionBoolean.equals(fieldL, fieldR)) {
retMap.put(entry.getPrimaryKey(), entry);
}
}
break;
case NOT_EQ:
for (Entry<T> entry : entries.values()) {
Object fieldL = entry.getField(columnNumberL);
Object fieldR = entry.getField(columnNumberR);
if (fieldL == null && fieldR == null) {
continue;
}
if (fieldL == null) {
retMap.put(entry.getPrimaryKey(), entry);
continue;
}
if (fieldR == null) {
retMap.put(entry.getPrimaryKey(), entry);
continue;
}
if (!ExpressionBoolean.equals(fieldL, fieldR)) {
retMap.put(entry.getPrimaryKey(), entry);
}
}
break;
case GTH:
for (Entry<T> entry : entries.values()) {
Object fieldL = entry.getField(columnNumberL);
Object fieldR = entry.getField(columnNumberR);
if (fieldL == null && fieldR == null) {
continue;
}
if (fieldL == null) {
continue;
}
if (fieldR == null) {
retMap.put(entry.getPrimaryKey(), entry);
continue;
}
if (ExpressionBoolean.compare(fieldL, fieldR) > 0) {
retMap.put(entry.getPrimaryKey(), entry);
}
}
break;
case GET:
for (Entry<T> entry : entries.values()) {
Object fieldL = entry.getField(columnNumberL);
Object fieldR = entry.getField(columnNumberR);
if (fieldL == null && fieldR == null) {
retMap.put(entry.getPrimaryKey(), entry);
continue;
}
if (fieldL == null) {
continue;
}
if (fieldR == null) {
retMap.put(entry.getPrimaryKey(), entry);
continue;
}
if (ExpressionBoolean.compare(fieldL, fieldR) >= 0) {
retMap.put(entry.getPrimaryKey(), entry);
}
}
break;
case LET:
for (Entry<T> entry : entries.values()) {
Object fieldL = entry.getField(columnNumberL);
Object fieldR = entry.getField(columnNumberR);
if (fieldL == null && fieldR == null) {
retMap.put(entry.getPrimaryKey(), entry);
continue;
}
if (fieldL == null) {
retMap.put(entry.getPrimaryKey(), entry);
continue;
}
if (fieldR == null) {
continue;
}
if (ExpressionBoolean.compare(fieldL, fieldR) <= 0) {
retMap.put(entry.getPrimaryKey(), entry);
}
}
break;
case LTH:
for (Entry<T> entry : entries.values()) {
Object fieldL = entry.getField(columnNumberL);
Object fieldR = entry.getField(columnNumberR);
if (fieldL == null && fieldR == null) {
retMap.put(entry.getPrimaryKey(), entry);
continue;
}
if (fieldL == null) {
retMap.put(entry.getPrimaryKey(), entry);
continue;
}
if (fieldR == null) {
continue;
}
if (ExpressionBoolean.compare(fieldL, fieldR) < 0) {
retMap.put(entry.getPrimaryKey(), entry);
}
}
break;
case IS_NULL:
case IS_NOT_NULL:
break;
case LIKE:
case NOT_LIKE:
for (Entry<T> entry : entries.values()) {
Object fieldL = entry.getField(columnNumberL);
Object fieldR = entry.getField(columnNumberR);
if (fieldL == null && fieldR == null) {
if ((operator == OperatorType.LIKE)) {
retMap.put(entry.getPrimaryKey(), entry);
}
continue;
}
if (fieldL == null) {
continue;
}
if (fieldR == null) {
continue;
}
String expr = fieldR.toString();
expr = expr.toUpperCase();
expr = expr.replace(".", "\\.");
// TODO Add more.
expr = expr.replace("?", ".");
expr = expr.replace("%", ".*");
Pattern pattern = Pattern.compile(expr);
String str = fieldL.toString().toUpperCase();
Matcher m = pattern.matcher(str);
if (m.matches() == (operator == OperatorType.LIKE)) {
retMap.put(entry.getPrimaryKey(), entry);
}
}
break;
default:
break;
}
return retMap;
}
@Override
public boolean match(T object, Accessor<T> accessor) {
GetSetPair<T> getSetPairL = accessor.getGetSetPair(columnNameL);
Object fieldL = getSetPairL.get(object);
GetSetPair<T> getSetPairR = accessor.getGetSetPair(columnNameR);
Object fieldR = getSetPairR.get(object);
if (fieldL == null && fieldR == null) {
return true;
}
if (fieldL == null) return false;
if (fieldR == null) return false;
return ExpressionBoolean.equals(fieldL, fieldR);
}
@Override
public String formatSqlQuery (SqlFormat format) {
String escL = columnEscL;
String escR = columnEscR;
if (format == SqlFormat.GIGASPACES) {
escL = "`";
escR = "`";
}
String ret = escL + columnNameL + escL + " "
+ operator.constructSqlString(format) + " "
+ escR + columnNameR + escR;
if (format == SqlFormat.GIGASPACES || format == SqlFormat.GIGASPACES_LITERAL) {
throw new IllegalArgumentException ("Expression not supported by GigaSpaces: " + ret);
}
return ret;
}
}