package net.ion.craken.expression; import java.lang.reflect.InvocationTargetException; import java.util.List; import net.ion.craken.node.NodeCommonMap; import net.ion.craken.node.crud.Filters; import net.ion.framework.util.ArrayUtil; import net.ion.framework.util.ListUtil; import org.apache.commons.lang.reflect.MethodUtils; import org.apache.lucene.search.Filter; public final class BinaryExpression extends ValueObject implements Expression { public final Expression left; public final Expression right; public final Op operator; public BinaryExpression(Expression left, Op op, Expression right) { this.left = left; this.operator = op; this.right = right; } public Comparable value(NodeCommonMap node) { if (operator == Op.EQ && left instanceof QualifiedNameExpression && "exist".equals(((QualifiedNameExpression)left).lastName())) { return right.value(node) != null; } return operator.compute(left.value(node), right.value(node)) ; } public Filter filter(){ try { if (Op.AND == operator || Op.OR == operator){ Filter f1 = (Filter) MethodUtils.invokeMethod(left, "filter", new Object[0]) ; Filter f2 = (Filter) MethodUtils.invokeMethod(right, "filter", new Object[0]) ; if (operator == Op.AND) return Filters.and(f1, f2) ; if (operator == Op.OR) return Filters.or(f1, f2) ; } else if (Op.EQ == operator || Op.LT == operator || Op.LE == operator || Op.GT == operator || Op.GE == operator || Op.CONTAIN == operator){ if (Op.EQ == operator && left instanceof QualifiedNameExpression && right instanceof QualifiedNameExpression){ QualifiedNameExpression fld = findExistField() ; return Filters.exists(fld.lastName()) ; } QualifiedNameExpression qne = findQName() ; ConstantExpression con = findConstant(); return con.filter(operator, qne) ; } else if (Op.IN == operator){ QualifiedNameExpression qne = (QualifiedNameExpression) left ; TupleExpression te = (TupleExpression) right ; List<String> values = ListUtil.newList() ; for (Expression expr : te.expressions()){ values.add(((ConstantExpression)expr).constantValue().toString()) ; } return Filters.in(qne.lastName(), values.toArray(new String[0])) ; } else if (Op.NE == operator) { return Filters.ne(findQName().qname.last(), findConstant().constantValue().toString()) ; } } catch(ClassCastException e){ throw new UnsupportedOperationException(e) ; } catch (NoSuchMethodException e) { throw new UnsupportedOperationException(e) ; } catch (IllegalAccessException e) { throw new UnsupportedOperationException(e) ; } catch (InvocationTargetException e) { throw new UnsupportedOperationException(e) ; } throw new IllegalArgumentException() ; } private QualifiedNameExpression findExistField() { if ( "exist".equals( ((QualifiedNameExpression)left).lastName())) return (QualifiedNameExpression) right ; return (QualifiedNameExpression) left ; } private QualifiedNameExpression findQName(){ if (left instanceof QualifiedNameExpression) return (QualifiedNameExpression) left ; if (right instanceof QualifiedNameExpression) return (QualifiedNameExpression) right ; throw new IllegalArgumentException("illegal where expression : not found NameExpression") ; } private ConstantExpression findConstant(){ if (left instanceof ConstantExpression) return (ConstantExpression) left ; if (right instanceof ConstantExpression) return (ConstantExpression) right ; if (right instanceof QualifiedNameExpression && ArrayUtil.contains(new String[]{"true", "false"}, ((QualifiedNameExpression)right).lastName())){ String value = ((QualifiedNameExpression)right).lastName() ; return new BooleanExpression(Boolean.valueOf(value)) ; } if (left instanceof QualifiedNameExpression && ArrayUtil.contains(new String[]{"true", "false"}, ((QualifiedNameExpression)left).lastName())){ String value = ((QualifiedNameExpression)left).lastName() ; return new BooleanExpression(Boolean.valueOf(value)) ; } throw new IllegalArgumentException("illegal where expression : not found ConstantExpression") ; } }