All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.joo.libra.sql.ExpressionNode Maven / Gradle / Ivy

There is a newer version: 2.1.2
Show newest version
package org.joo.libra.sql;

import java.math.BigDecimal;

import org.joo.libra.Predicate;
import org.joo.libra.PredicateContext;
import org.joo.libra.common.HasValue;
import org.joo.libra.logic.AndPredicate;
import org.joo.libra.logic.EqualsPredicate;
import org.joo.libra.logic.NotPredicate;
import org.joo.libra.logic.OrPredicate;
import org.joo.libra.numeric.GreaterEqualPredicate;
import org.joo.libra.numeric.GreaterThanPredicate;
import org.joo.libra.numeric.LessEqualPredicate;
import org.joo.libra.numeric.LessThanPredicate;
import org.joo.libra.sql.antlr.SqlLexer;
import org.joo.libra.text.ContainPredicate;
import org.joo.libra.text.IsEmptyPredicate;
import org.joo.libra.text.MatchPredicate;

public interface ExpressionNode {

	public Predicate buildPredicate();
}

abstract class InfixExpressionNode implements ExpressionNode {
	
	private ExpressionNode left;

	private ExpressionNode right;

	public ExpressionNode getLeft() {
		return left;
	}

	public void setLeft(ExpressionNode left) {
		this.left = left;
	}

	public ExpressionNode getRight() {
		return right;
	}

	public void setRight(ExpressionNode right) {
		this.right = right;
	}
}

class AndExpressionNode extends InfixExpressionNode {

	@Override
	public Predicate buildPredicate() {
		return new AndPredicate(getLeft().buildPredicate(), getRight().buildPredicate());
	}
}

class OrExpressionNode extends InfixExpressionNode {

	@Override
	public Predicate buildPredicate() {
		return new OrPredicate(getLeft().buildPredicate(), getRight().buildPredicate());
	}
}

class NotExpressionNode implements ExpressionNode {
	
	private ExpressionNode innerNode;

	public ExpressionNode getInnerNode() {
		return innerNode;
	}

	public void setInnerNode(ExpressionNode innerNode) {
		this.innerNode = innerNode;
	}
	
	@Override
	public Predicate buildPredicate() {
		return new NotPredicate(innerNode.buildPredicate());
	}
}

class ValueExpressionNode implements ExpressionNode, HasValue {
	
	private T value;

	@Override
	public T getValue(PredicateContext context) {
		return value;
	}

	public void setValue(T value) {
		this.value = value;
	}

	@Override
	public Predicate buildPredicate() {
		return null;
	}
}

class StringExpressionNode extends ValueExpressionNode {
	
}

class NumberExpressionNode extends ValueExpressionNode {
	
}

class BooleanExpressionNode extends ValueExpressionNode {
	
}

class ObjectExpressionNode extends ValueExpressionNode {
	
}

class EmptyExpressionNode implements ExpressionNode {
	
	private HasValue innerNode;
	
	private int op;

	@Override
	public Predicate buildPredicate() {
		if (op == SqlLexer.IS_NOT_EMPTY)
			return new NotPredicate(new IsEmptyPredicate(innerNode));
		return new IsEmptyPredicate(innerNode);
	}

	public HasValue getInnerNode() {
		return innerNode;
	}

	public void setInnerNode(HasValue innerNode) {
		this.innerNode = innerNode;
	}

	public int getOp() {
		return op;
	}

	public void setOp(int op) {
		this.op = op;
	}
}

class VariableExpressionNode implements ExpressionNode, HasValue {
	
	private String variableName;

	public String getVariableName() {
		return variableName;
	}

	public void setVariableName(String variableName) {
		this.variableName = variableName;
	}

	@Override
	public Object getValue(PredicateContext context) {
		if (context == null) return null;
		try {
			return ObjectUtils.getValue(context.getContext(), variableName);
		} catch (ReflectiveOperationException e) {
			throw new RuntimeException(e);
		}
	}

	@Override
	public Predicate buildPredicate() {
		return null;
	}
}


abstract class AbstractBinaryOpExpressionNode> implements ExpressionNode {

	private T left;
	
	private T right;
	
	private int op;

	public T getLeft() {
		return left;
	}

	public void setLeft(T left) {
		this.left = left;
	}

	public T getRight() {
		return right;
	}

	public void setRight(T right) {
		this.right = right;
	}

	public int getOp() {
		return op;
	}

	public void setOp(int op) {
		this.op = op;
	}
}

class MathExpressionNode extends AbstractBinaryOpExpressionNode> implements HasValue {

	@Override
	public Predicate buildPredicate() {
		return null;
	}

	@Override
	public Number getValue(PredicateContext context) {
		double left = getLeft().getValue(context).doubleValue();
		double right = getRight().getValue(context).doubleValue();
		switch(getOp()) {
		case SqlLexer.PLUS:
			return left + right;
		case SqlLexer.MINUS:
			return left - right;
		case SqlLexer.TIMES:
			return new BigDecimal(left).multiply(new BigDecimal(right));
		case SqlLexer.DIVIDE:
			return new BigDecimal(left).divide(new BigDecimal(right));
		}
		return null;
	}
}

class NumericCompareExpressionNode extends AbstractBinaryOpExpressionNode> {

	@Override
	public Predicate buildPredicate() {
		switch(getOp()) {
		case SqlLexer.GREATER_THAN:
			return new GreaterThanPredicate(getLeft(), getRight());
		case SqlLexer.GREATER_THAN_EQUALS:
			return new GreaterEqualPredicate(getLeft(), getRight());
		case SqlLexer.LESS_THAN:
			return new LessThanPredicate(getLeft(), getRight());
		case SqlLexer.LESS_THAN_EQUALS:
			return new LessEqualPredicate(getLeft(), getRight());
		}
		return null;
	}
	
}

class GenericCompareExpressionNode extends AbstractBinaryOpExpressionNode> {

	@Override
	public Predicate buildPredicate() {
		switch(getOp()) {
		case SqlLexer.EQUALS:
		case SqlLexer.IS_EQUALS:
		case SqlLexer.DBL_EQUALS:
			return new EqualsPredicate(getLeft(), getRight());
		case SqlLexer.NOT_EQUALS:
		case SqlLexer.IS_EQUALS_NOT:
			return new NotPredicate(new EqualsPredicate(getLeft(), getRight()));
		}
		return null;
	}
}

class LexicalCompareExpressionNode extends AbstractBinaryOpExpressionNode> {

	@Override
	public Predicate buildPredicate() {
		switch(getOp()) {
		case SqlLexer.MATCHES:
			return new MatchPredicate(getLeft(), getRight());
		}
		return null;
	}
}

class ContainsCompareExpressionNode extends AbstractBinaryOpExpressionNode> {

	@Override
	public Predicate buildPredicate() {
		return new ContainPredicate(getLeft(), getRight());
	}
}