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

stream.expressions.version2.ConditionFactory Maven / Gradle / Ivy

The newest version!
/*
 *  streams library
 *
 *  Copyright (C) 2011-2014 by Christian Bockermann, Hendrik Blom
 * 
 *  streams is a library, API and runtime environment for processing high
 *  volume data streams. It is composed of three submodules "stream-api",
 *  "stream-core" and "stream-runtime".
 *
 *  The streams library (and its submodules) is free software: you can 
 *  redistribute it and/or modify it under the terms of the 
 *  GNU Affero General Public License as published by the Free Software 
 *  Foundation, either version 3 of the License, or (at your option) any 
 *  later version.
 *
 *  The stream.ai library (and its submodules) 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 Affero General Public License for more details.
 *
 *  You should have received a copy of the GNU Affero General Public License
 *  along with this program.  If not, see http://www.gnu.org/licenses/.
 */
package stream.expressions.version2;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @author Hendrik Blom
 * 
 */
public class ConditionFactory {
	static Logger log = LoggerFactory.getLogger(ConditionFactory.class);

	private Map> dExps;
	private Map> sExps;

	private Map> setExps;
	private Map subCond;

	public ConditionFactory() {
		subCond = new HashMap();
		dExps = new HashMap>();
		sExps = new HashMap>();
		setExps = new HashMap>();
	}

	public Condition create(String ex) {

		// Handle empty Condition
		if (ex == null || ex.isEmpty()) {
			log.debug("Created new Empty Condition");
			return new EmptyCondition("EMPTY");
		}

		// Check brackets
		// checkBrackets(ex, "{", "}");

		// Replace and Create Expressions
		// ex = replaceAndCreateSetExpressions(ex);
		ex = replaceAndCreateExpressions(ex);
		// Remove all whitespaces
		ex = ex.replace(" ", "");

		ex = replaceAndCreateStringExpressions(ex);

		// Debug Logging
		printDoubleExpressions();
		printStringExpressions();
		printSetExpressions();
		log.debug("Expression: {}", ex);

		// Replace subConditions (e.g. (...)) by a Map.key
		ex = readSubConditions(ex);
		print("SubConditions", subCond);
		log.trace("Expression: {}", ex);

		// Create ConditionTree
		ConditionTree t = new ConditionTree(subCond);
		t.init();
		t.setRoot(ex);
		t.eval();
		log.trace("ConditionTree:\n {}", t);

		// Create the condition from the given tree

		Condition result = createCondition(t);
		reset();
		return result;
	}

	private Condition createCondition(ConditionTree t) {
		if (t == null)
			throw new IllegalArgumentException("Bad ConditionTree \n" + t);

		// t is LEAF
		if (t.isLeaf()) {
			if (t.getRoot().contains("null"))
				return createNullCondition(t.getRoot());
			if (t.getRoot().contains("true") || t.getRoot().contains("TRUE")
					|| t.getRoot().contains("false")
					|| t.getRoot().contains("FALSE")) {
				return createBooleanCondition(t.getRoot());
			}

			// Hier ist die Magic
			if (t.getRoot().contains(":p10sete_"))
				return createSetCondition(t.getRoot());
			if (t.getRoot().contains(":p10se"))
				return createStringCondition(t.getRoot());
			return createDoubleCondition(t.getRoot());
		}

		// t is no LEAF
		if (t.getOp().equals("AND"))
			return new AndCondition(createCondition(t.left),
					createCondition(t.right));
		if (t.getOp().equals("OR"))
			return new OrCondition(createCondition(t.left),
					createCondition(t.right));

		throw new IllegalArgumentException("Bad ConditionTree \n" + t);
	}

	private Condition createSetCondition(String c) {
		// Double
		if (c.contains(">")) {
			String[] exps = c.split(">");
			if (exps.length != 2)
				throw new IllegalArgumentException("Bad ConditionString" + c);
		}

		return null;
	}

	/**
	 * Create equals-true-condition out of a given string expression.
	 *
	 * @param expr expression value as string
	 * @return condition
	 */
	private Condition extractEqualsTrueExpression(String expr) {
		Expression de = dExps.get(expr);
		if (de != null) {
			return new EqualsTrueCondition(new BooleanExpression(de.getExpression()));
		}
		return null;
	}

	/**
	 * Create equals-false-condition out of a given string expression.
	 *
	 * @param expr expression value as string
	 * @return condition
	 */
	private Condition extractEqualsFalseExpression(String expr) {
		Expression de = dExps.get(expr);
		if (de != null) {
			return new EqualsFalseCondition(new BooleanExpression(de.getExpression()));
		}
		return null;
	}

	/**
	 * Check if given expression contains upper or lower case of given value (true or false)
	 *
	 * @param expr  expression value
	 * @param value boolean value, true or false
	 * @return true or false
	 */
	private boolean containsBool (String expr, String value) {
		return expr.contains(value.toUpperCase()) || expr.contains(value.toLowerCase());
	}

	private Condition createBooleanCondition(String c) {
		// ==
		if (c.contains("==")) {
			String[] exps = c.split("==");
			if (exps.length != 2)
				throw new IllegalArgumentException("Bad ConditionString" + c);

			if (containsBool(exps[0], "TRUE")) {
				return extractEqualsTrueExpression(exps[1]);
			}
			if (containsBool(exps[1], "TRUE")) {
				return extractEqualsTrueExpression(exps[0]);
			}
			if (containsBool(exps[0], "FALSE")) {
				return extractEqualsFalseExpression(exps[1]);
			}
			if (containsBool(exps[1], "FALSE")) {
				return extractEqualsFalseExpression(exps[0]);
			}
		}
		// !=
		if (c.contains("!=")) {
			String[] exps = c.split("!=");
			if (exps.length != 2)
				throw new IllegalArgumentException("Bad ConditionString" + c);

			if (containsBool(exps[0], "TRUE")) {
				return extractEqualsFalseExpression(exps[0]);
			}
			if (containsBool(exps[1], "TRUE")) {
				return extractEqualsFalseExpression(exps[0]);
			}
			if (containsBool(exps[0], "FALSE")) {
				return extractEqualsTrueExpression(exps[1]);
			}
			if (containsBool(exps[1], "FALSE")) {
				return extractEqualsTrueExpression(exps[0]);
			}
		}
		if("FALSE".equals(c.trim()) || "false".equals(c.trim()))
			return new FalseCondition(c);
		if("TRUE".equals(c.trim()) || "true".equals(c.trim()))
			return new TrueCondition(c);
		throw new IllegalArgumentException("Bad ConditionString" + c);
	}

	private Condition createNullCondition(String c) {
		if (c == null || c.isEmpty())
			throw new IllegalArgumentException("Bad ConditionString" + c);

		// Operator ==
		if (c.contains("==")) {
			String[] exps = c.split("==");
			if (exps.length != 2)
				throw new IllegalArgumentException("Bad ConditionString" + c);
			if (exps[0].contains("null")) {
				Expression ex = buildSerializableExpression(exps[1]);
				if (ex == null)
					return new EmptyCondition(c);
				return new EqualsNullCondition(c, ex);
			}
			Expression ex = buildSerializableExpression(exps[0]);
			if (ex == null)
				return new EmptyCondition(c);
			return new EqualsNullCondition(c, ex);
		}

		// Operator !=
		if (c.contains("!=")) {
			String[] exps = c.split("!=");
			if (exps.length != 2)
				throw new IllegalArgumentException("Bad ConditionString" + c);
			if (exps[0].contains("null")) {
				Expression ex = buildSerializableExpression(exps[1]);
				if (ex == null)
					return new EmptyCondition(c);
				return new NotEqualsNullCondition(c, ex);
			}
			Expression ex = buildSerializableExpression(exps[0]);
			if (ex == null)
				return new EmptyCondition(c);
			return new NotEqualsNullCondition(c, ex);
		}
		throw new IllegalArgumentException("Bad ConditionString" + c);
	}

	private OperatorCondition createStringCondition(String c) {
		if (c == null || c.isEmpty())
			throw new IllegalArgumentException("Empty or NULL Expression" + c);

		// S Expressions
		if (c.contains("==")) {
			String[] exps = c.split("==");
			if (exps.length != 2)
				throw new IllegalArgumentException("Bad ConditionString" + c);
			Expression left = createOrBuildStringExpression(exps[0]);
			Expression right = createOrBuildStringExpression(exps[1]);
			return new EqualsStringCondition(left, right);
		}

		if (c.contains("!=")) {
			String[] exps = c.split("!=");
			if (exps.length != 2)
				throw new IllegalArgumentException("Bad ConditionString" + c);
			Expression left = createOrBuildStringExpression(exps[0]);
			Expression right = createOrBuildStringExpression(exps[1]);
			return new NotEqualsStringCondition(left, right);
		}
		if (c.contains("@rx")) {
			String[] exps = c.split("@rx");
			if (exps.length != 2)
				throw new IllegalArgumentException("Bad ConditionString" + c);
			Expression left = createOrBuildStringExpression(exps[0]);
			Expression right = createOrBuildStringExpression(exps[1]);
			return new EqualsRXCondition(left, right);
		}
		if (c.contains("@nrx")) {
			String[] exps = c.split("@nrx");
			if (exps.length != 2)
				throw new IllegalArgumentException("Bad ConditionString" + c);
			Expression left = createOrBuildStringExpression(exps[0]);
			Expression right = createOrBuildStringExpression(exps[1]);
			return new NotEqualsRXCondition(left, right);
		}
		throw new IllegalArgumentException(
				"Unknown Operator in the given Expression" + c);
	}

	private OperatorCondition createDoubleCondition(String c) {
		if (c == null || c.isEmpty())
			throw new IllegalArgumentException("Bad ConditionString" + c);

		// Double Expressions
		if (c.contains("==")) {
			String[] exps = c.split("==");
			if (exps.length != 2)
				throw new IllegalArgumentException("Bad ConditionString" + c);
			Expression left = createOrBuildDoubleExpression(exps[0]);
			Expression right = createOrBuildDoubleExpression(exps[1]);
			return new EqualsDoubleCondition(left, right);
		}
		if (c.contains("!=")) {
			String[] exps = c.split("!=");
			if (exps.length != 2)
				throw new IllegalArgumentException("Bad ConditionString" + c);
			Expression left = createOrBuildDoubleExpression(exps[0]);
			Expression right = createOrBuildDoubleExpression(exps[1]);
			return new NotEqualsDoubleCondition(left, right);
		}
		if (c.contains("<=")) {
			String[] exps = c.split("<=");
			if (exps.length != 2)
				throw new IllegalArgumentException("Bad ConditionString" + c);
			Expression left = createOrBuildDoubleExpression(exps[0]);
			Expression right = createOrBuildDoubleExpression(exps[1]);
			return new LEDoubleCondition(left, right);
		}
		if (c.contains(">=")) {
			String[] exps = c.split(">=");
			if (exps.length != 2)
				throw new IllegalArgumentException("Bad ConditionString" + c);
			Expression left = createOrBuildDoubleExpression(exps[0]);
			Expression right = createOrBuildDoubleExpression(exps[1]);
			return new GEDoubleCondition(left, right);
		}
		if (c.contains(">")) {
			String[] exps = c.split(">");
			if (exps.length != 2)
				throw new IllegalArgumentException("Bad ConditionString" + c);
			Expression left = createOrBuildDoubleExpression(exps[0]);
			Expression right = createOrBuildDoubleExpression(exps[1]);
			return new GDoubleCondition(left, right);
		}
		if (c.contains("<")) {
			String[] exps = c.split("<");
			if (exps.length != 2)
				throw new IllegalArgumentException("Bad ConditionString" + c);
			Expression left = createOrBuildDoubleExpression(exps[0]);
			Expression right = createOrBuildDoubleExpression(exps[1]);
			return new LDoubleCondition(left, right);
		}
		return null;

	}

	private Expression buildSerializableExpression(String key) {
		Expression ed = dExps.get(key);
		if (ed != null)
			return ed.toSerializableExpression();
		Expression es = sExps.get(key);
		if (es != null)
			return es.toSerializableExpression();
		return null;
	}

	private Expression createOrBuildDoubleExpression(String key) {
		Expression e = dExps.get(key);
		if (e == null)
			e = new DoubleExpression(key);
		return e;
	}

	private Expression createOrBuildStringExpression(String key) {
		Expression e = sExps.get(key);
		if (e == null) {
			Expression d = dExps.get(key);
			if (d != null)
				key = d.getExpression();
			e = new StringExpression(key);
		}
		return e;
	}

	@SuppressWarnings("unused")
	private void checkBrackets(String ex, String bracketOpen,
			String bracketClose) {
		// Test brackets
		boolean run = true;
		String testB = ex;
		while (run) {
			int s1 = testB.indexOf(bracketOpen);
			int s2 = testB.indexOf(bracketOpen, s1 + 1);
			int e1 = testB.indexOf(bracketClose);

			if (s1 < 0 && e1 < 0)
				run = false;
			else {

				// Bracket {{}
				if (s2 > 0 && s2 < e1) {
					String ss = "";
					if (s2 > 0)
						ss = testB.substring(0, s2);
					String se = "";
					if (s2 < testB.length())
						se = testB.substring(s2 + 1);
					throw new IllegalArgumentException("1:Bad " + bracketOpen
							+ "..." + bracketClose + ":" + ss + "__"
							+ bracketOpen + "__" + se);
				}
				// only one } left or }{}
				if (s1 < 0 && e1 >= 0 || (e1 < s1 && s1 > 0 && e1 >= 0)) {
					String ss = "";
					if (e1 > 0)
						ss = testB.substring(0, e1 - 1);
					String se = "";
					if (e1 < testB.length())
						se = testB.substring(e1 + 1);
					throw new IllegalArgumentException("1:Bad " + bracketOpen
							+ "..." + bracketClose + ":" + ss + "__"
							+ bracketClose + "__" + se);
				}
				// only one { left
				if (s1 >= 0 && e1 < 0) {
					String ss = "";
					if (s1 > 0)
						ss = testB.substring(0, s1 - 1);
					String se = "";
					if (s1 < testB.length())
						se = testB.substring(s1 + 1);
					throw new IllegalArgumentException("1:Bad " + bracketOpen
							+ "..." + bracketClose + ":" + ss + "__"
							+ bracketOpen + "__" + se);
				}

				testB = testB.substring(e1 + 1);
			}

		}

	}

	@SuppressWarnings("unused")
	private String replaceAndCreateSetExpressions(String ex) {
		boolean run = true;
		int i = 0;
		while (run) {
			// Find start of Expression
			int s = ex.indexOf(".{");
			if (s > 0) {
				// Split String
				String[] sub = new String[2];
				sub[0] = ex.substring(0, s);
				sub[1] = ex.substring(s, ex.length() - 1);

				// find last %{
				int ts = sub[0].lastIndexOf("%{");
				// find second index of }
				int te = sub[0].indexOf("}");
				te = sub[0].indexOf("}", te);
				String sube = ex.substring(ts, s + te - 1);
				String key = ":p10sete_" + i;
				SetExpression exp = new SetExpression(sube);
				setExps.put(key, exp);
				ex = ex.replace(sube, key);
			} else
				run = false;
		}
		return ex;
	}

	private String replaceAndCreateExpressions(String ex) {
		// PRIO 10
		boolean run = true;
		int i = 0;
		while (run) {
			int s = ex.indexOf("%{");
			if (s >= 0) {
				String se;
				String key;
				int e = ex.indexOf("}");
				if (s - 1 >= 0 && ex.charAt(s - 1) == '\'') {
					if (e + 1 < ex.length() && ex.charAt(e + 1) == '\'') {
						se = ex.substring(s - 1, e + 2);
						key = ";p10se_" + i;
						StringExpression exp = new StringExpression(se);

						sExps.put(key, exp);
					} else
						throw new IllegalArgumentException("Bad String ''");
				} else {
					se = ex.substring(s, e + 1);
					key = ":p10e_" + i;
					DoubleExpression exp = new DoubleExpression(se);
					dExps.put(key, exp);
				}

				ex = ex.replace(se, key);
				i++;
			} else
				run = false;

		}
		return ex;

	}

	private String replaceAndCreateStringExpressions(String ex) {
		// PRIO 10
		List ms = find(ex, "'");
		if (ms.size() % 2 != 0)
			throw new IllegalArgumentException("Bad %{...}");
		boolean run = true;
		int i = 0;
		while (run) {
			int s = ex.indexOf("'");
			if (s >= 0) {
				String subString = ex.substring(s);
				int e = subString.indexOf("'", 1);
				log.debug(subString);
				String se = subString.substring(0, e + 1);
				String key = ":p10se_" + i;
				StringExpression exp = new StringExpression(se);

				sExps.put(key, exp);
				ex = ex.replace(se, key);
				i++;

			} else
				run = false;
		}
		return ex;

	}

	private String readSubConditions(String ex) {
		// PRIO 9

		boolean run = true;
		int c = 0;
		boolean start = false;
		while (run) {
			// Bis start gefunden
			if (!start) {
				ex = brackets(ex, c);
				c++;
				// If all Brackets are removed
				if (!ex.contains("("))
					run = false;
			}
		}
		return ex;

	}

	private String brackets(String ex, int count)
			throws IllegalArgumentException {

		// TODO Aufwerten der Fehlermeldung
		List ms = find(ex, "(");
		List me = find(ex, ")");
		if (ms.size() != me.size())
			throw new IllegalArgumentException("Bad (...) ");

		// No Brackets
		if (ms.size() == 0)
			return ex;
		// One pair of Brackets
		if (ms.size() == 1 || (me.get(0) < ms.get(1) && ms.get(0) < me.get(0))) {
			String subexp = ex.substring(ms.get(0), me.get(0) + 1);
			String key = ":subc_" + count;
			subCond.put(key, subexp.substring(1, subexp.length() - 1));
			return ex.replace(subexp, key);
		}

		// Multiple Brackets
		boolean run = true;
		int i = 1;
		while (run) {
			if (i == ms.size()) {
				i--;
				run = false;
			} else if (ms.get(i) > me.get(0)) {
				i--;
				run = false;
			} else
				i++;
		}

		String subexp = ex.substring(ms.get(i), me.get(0) + 1);
		String key = ":subc_" + count;
		subCond.put(key, subexp.substring(1, subexp.length() - 1));
		return ex.replace(subexp, key);
	}

	public List find(String condition, String f)
			throws IllegalArgumentException {
		List results = new ArrayList();
		boolean run = true;
		int start = 0;
		while (run) {
			int p = condition.indexOf(f, start);
			if (p < 0)
				run = false;
			else {
				start = p + 1;
				results.add(p);
				if (start >= condition.length())
					run = false;
			}

		}
		return results;

	}

	private void printDoubleExpressions() {
		if (dExps.size() == 0)
			log.trace("No DoubleExpressions created.");
		else {
			StringBuilder b = new StringBuilder();
			b.append("DoubleExpression created:\n");
			for (Map.Entry> e : dExps.entrySet()) {
				b.append(e.getKey() + " = " + e.getValue() + "\n");
			}
			log.trace(b.toString());
		}
	}

	private void printStringExpressions() {
		if (sExps.size() == 0)
			log.trace("No StringExpressions created.");
		else {
			StringBuilder b = new StringBuilder();
			b.append("StringExpressions created:\n");
			for (Map.Entry> e : sExps.entrySet()) {
				b.append(e.getKey() + " = " + e.getValue() + "\n");
			}
			log.trace(b.toString());
		}
	}

	private void printSetExpressions() {
		if (setExps.size() == 0)
			log.trace("No SetExpressions created.");
		else {
			StringBuilder b = new StringBuilder();
			b.append("SetExpressions created:\n");
			for (Map.Entry> e : setExps.entrySet()) {
				b.append(e.getKey() + " = " + e.getValue() + "\n");
			}
			log.trace(b.toString());
		}
	}

	private void print(String name, Map m) {
		if (m.isEmpty())
			log.trace("{} is empty", name);
		else {
			StringBuilder b = new StringBuilder();
			b.append("{} contains:\n");
			for (Map.Entry e : m.entrySet()) {
				b.append(e.getKey() + " = " + e.getValue() + "\n");
			}
			log.trace(b.toString());
		}
	}

	private final class ConditionTree {

		private String root;
		private String op = null;
		private ConditionTree left;
		private ConditionTree right;
		private boolean eval = false;
		private boolean leaf = true;
		private Map subCond;

		public ConditionTree(Map l9) {
			this.subCond = l9;
		}

		public String getRoot() {
			return root;
		}

		public void setRoot(String root) {
			this.root = root;
		}

		public String getOp() {
			return op;
		}

		public boolean isLeaf() {
			return leaf;
		}

		public void init() {
			left = new ConditionTree(this.subCond);
			right = new ConditionTree(this.subCond);
		}

		@Override
		public String toString() {
			if (eval = false || (eval && leaf))
				return root;

			StringBuilder s = new StringBuilder();
			s.append(op + "\n");
			s.append("left=" + left.toString() + "[" + left.leaf + "]\n");
			s.append("right=" + right.toString() + "[" + right.leaf + "]\n");
			return s.toString();
		}

		private void evalRecursive(String[] split){
			left.root = split[0];
			right.root = split[1];
			leaf = false;
			left.init();
			right.init();
			left.eval();
			right.eval();
			eval = true;
		}

		public void eval() {
			String[] split = root.split("or|OR", 2);
			if (split.length == 2) {
				evalRecursive(split);
				op = "OR";
				return;
			}
			// split = root.split("||", 2);

			split = root.split("and|AND", 2);
			if (split.length == 2) {
				evalRecursive(split);
				op = "AND";
				return;
			}
			// split = root.split("&&", 2);

			if (root.contains(":subc_")) {
				root = subCond.get(root);
				eval();
			}
			eval = true;
		}

	}

	private void reset() {
		subCond = new HashMap<>();
		dExps = new HashMap<>();
		sExps = new HashMap<>();
	}
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy