CloneHelper.java
/*-
* #%L
* JSQLParser library
* %%
* Copyright (C) 2004 - 2019 JSQLParser
* %%
* Dual licensed under GNU LGPL 2.1 or Apache License 2.0
* #L%
*/
package net.sf.jsqlparser.util.cnfexpression;
import net.sf.jsqlparser.expression.Expression;
import net.sf.jsqlparser.expression.NotExpression;
import net.sf.jsqlparser.expression.operators.conditional.AndExpression;
import net.sf.jsqlparser.expression.operators.conditional.OrExpression;
import net.sf.jsqlparser.expression.operators.relational.ParenthesedExpressionList;
import java.util.ArrayList;
import java.util.List;
/**
* This class is mainly used for handling the cloning of an expression tree. Note this is the
* shallow copy of the tree. That means I do not modify or copy the expression other than these
* expressions: AND, OR, NOT, (), MULTI-AND, MULTI-OR. Since the CNF conversion only change the
* condition part of the tree.
*
* @author messfish
*/
class CloneHelper {
public static Expression modify(Expression express) {
if (express instanceof NotExpression) {
return new NotExpression(modify(((NotExpression) express).getExpression()));
}
if (express instanceof ParenthesedExpressionList) {
ParenthesedExpressionList<?> parenthesis = (ParenthesedExpressionList<?>) express;
if (parenthesis.size() == 1) {
return modify(parenthesis.get(0));
}
}
if (express instanceof AndExpression) {
AndExpression and = (AndExpression) express;
List<Expression> list = new ArrayList<>();
list.add(modify(and.getLeftExpression()));
list.add(modify(and.getRightExpression()));
MultiAndExpression result = new MultiAndExpression(list);
// if (and.isNot()) {
// return new NotExpression(result);
// }
return result;
}
if (express instanceof OrExpression) {
OrExpression or = (OrExpression) express;
List<Expression> list = new ArrayList<>();
list.add(modify(or.getLeftExpression()));
list.add(modify(or.getRightExpression()));
MultiOrExpression result = new MultiOrExpression(list);
// if (or.isNot()) {
// return new NotExpression(result);
// }
return result;
}
// if (express instanceof BinaryExpression) {
// BinaryExpression binary = (BinaryExpression) express;
// if (binary.isNot()) {
// binary.removeNot();
// return new NotExpression(modify(binary));
// }
// }
return express;
}
/**
* This method is used to copy the expression which happens at step four. I only copy the
* conditional expressions since the CNF only changes the conditional part.
*
* @param express the expression that will be copied.
* @return the copied expression.
*/
public static Expression shallowCopy(Expression express) {
if (express instanceof MultipleExpression) {
MultipleExpression multi = (MultipleExpression) express;
List<Expression> list = new ArrayList<>();
for (int i = 0; i < multi.size(); i++) {
list.add(shallowCopy(multi.getChild(i)));
}
if (express instanceof MultiAndExpression) {
return new MultiAndExpression(list);
}
/*
* since there only two possibilities of the multiple expression, so after the if
* condition, it is certain this is a multi-or.
*/
return new MultiOrExpression(list);
}
return express;
}
/**
* This helper method is used to change the multiple expression into the binary form,
* respectively and return the root of the expression tree.
*
* @param isMultiOr variable tells whether the expression is or.
* @param exp the expression that needs to be converted.
* @return the root of the expression tree.
*/
public static Expression changeBack(Boolean isMultiOr, Expression exp) {
if (!(exp instanceof MultipleExpression)) {
return exp;
}
List<Expression> result = ((MultipleExpression) exp).getList();
while (result.size() > 1) {
List<Expression> compressed = new ArrayList<>();
for (int i = 0; i < result.size(); i = i + 2) {
Expression left = result.get(i);
Expression right = i + 1 < result.size() ? result.get(i + 1) : null;
if (isMultiOr) {
compressed.add(right != null ? new OrExpression(left, right) : left);
} else {
compressed.add(right != null ? new AndExpression(left, right) : left);
}
}
result = compressed;
}
if (isMultiOr) {
return new ParenthesedExpressionList<>(result.get(0));
} else {
return result.get(0);
}
// MultipleExpression changed = (MultipleExpression) exp;
// Expression result = changed.getChild(0);
// for (int i = 1; i < changed.size(); i++) {
// Expression left = result;
// Expression right = changed.getChild(i);
// if (isMultiOr) {
// result = new OrExpression(left, right);
// } else {
// result = new AndExpression(left, right);
// }
// }
// if (isMultiOr) {
// return new Parenthesis(result);
// }
// return result;
}
}