1
14package org.tp23.antinstaller.runtime.logic;
15
16import java.util.Arrays;
17import java.util.Comparator;
18import java.util.HashMap;
19import java.util.Map;
20
21import org.tp23.antinstaller.input.ResultContainer;
22import org.tp23.antinstaller.runtime.ConfigurationException;
23
24
29public class ExpressionBuilder {
30 private static final int GROUPING_START_OPERATOR = '(';
31
32 private static final int GROUPING_END_OPERATOR = ')';
33
34 private static final ValuesTest[] testValueConditions = {
35 new EndsWithTest(),
36 new EqualsTest(),
37 new GreaterThanOrEqualsTest(),
38 new LessThanOrEqualsTest(),
39 new NotEqualsTest(),
40 new StartsWithTest()
41 };
42
43 private static final LogicalTest[] testLogicalConditions = {
44 new LogicalAndTest(),
45 new LogicalOrTest()
46 };
47
48 private static final SingleExpressionTest SINGLE_EXPRESSION_TEST = new SingleExpressionTest();
49
50 private static Map tokenMap = new HashMap();
51
52 private static String[] valueTokens;
53
54 private static String[] logicalTokens;
55
56 static {
57 for (int i = 0; i < testValueConditions.length; i++) {
58 String[] tmpTokens = testValueConditions[i].getTestTokens();
59 for (int j = 0; j < tmpTokens.length; j++) {
60 tokenMap.put(tmpTokens[j], testValueConditions[i]);
61 }
62 }
63
64 valueTokens = new String[tokenMap.size()];
65 int index = 0;
66 for (int i = 0; i < testValueConditions.length; i++) {
67 String[] tmpTokens = testValueConditions[i].getTestTokens();
68 for (int j = 0; j < tmpTokens.length; j++) {
69 valueTokens[index++] = tmpTokens[j];
70 }
71 }
72
73 Comparator lengthComparator = new StringLengthComparator();
74
75 Arrays.sort(valueTokens, lengthComparator);
77
78 index = 0;
79 final int mapInitialSize = tokenMap.size();
80
81 for (int i = 0; i < testLogicalConditions.length; i++) {
82 String[] tmpTokens = testLogicalConditions[i].getTestTokens();
83 for (int j = 0; j < tmpTokens.length; j++) {
84 tokenMap.put(tmpTokens[j], testLogicalConditions[i]);
85 }
86 }
87
88 logicalTokens = new String[tokenMap.size() - mapInitialSize];
89 for (int i = 0; i < testLogicalConditions.length; i++) {
90 String[] tmpTokens = testLogicalConditions[i].getTestTokens();
91 for (int j = 0; j < tmpTokens.length; j++) {
92 logicalTokens[index++] = tmpTokens[j];
93 }
94 }
95
96 Arrays.sort(logicalTokens, lengthComparator);
97
98 }
99
00 public static Expression parseLogicalExpressions(ResultContainer container, String exprStr) throws ConfigurationException {
01 int startIndex = skipWhiteSpace(exprStr, 0);
02 int index = exprStr.indexOf(GROUPING_START_OPERATOR, startIndex);
03
04 if (index == -1) {
05 return getSimpleExpression(container, exprStr.substring(startIndex));
06 }
07
08 if (index != 0) {
09 throw new ConfigurationException("Illegal ifProperty value: If present, grouping operator " + GROUPING_START_OPERATOR
10 + " must be at start of property string");
11 }
12
13 ++startIndex;
15 int endIndex = exprStr.indexOf(GROUPING_END_OPERATOR, startIndex);
16
17 if (endIndex == -1) {
18 throw new ConfigurationException("Missing closing grouping bracket " + GROUPING_END_OPERATOR + " in expression " + exprStr);
19 }
20
21 int tstIndex = exprStr.indexOf(GROUPING_START_OPERATOR, startIndex);
23 if ((tstIndex != -1) && (tstIndex < endIndex)) {
24 throw new ConfigurationException("Nesting of logical operations is not supported: " + exprStr);
25 }
26
27 try {
28 Expression expr1 = parseLogicalExpressions(container, exprStr.substring(startIndex, endIndex));
29
30 LogicalTest test = null;
31
32 startIndex = endIndex + 1;
33
34 String logicalToken = getLogicalToken(exprStr, startIndex);
36
37 for (int i = 0; i < logicalTokens.length; i++) {
38
39 if (logicalTokens[i].compareTo(logicalToken) == 0) {
40 test = (LogicalTest) tokenMap.get(logicalTokens[i]);
41 index = exprStr.indexOf(logicalTokens[i], startIndex);
42 startIndex = index + logicalTokens[i].length();
43 break;
44 }
45 }
46
47 if (test == null) {
48 return new CompoundExpression(expr1, SINGLE_EXPRESSION_TEST, null);
49 } else {
50 startIndex = skipWhiteSpace(exprStr, startIndex);
51 String expr2Str = exprStr.substring(startIndex, exprStr.length());
52 return new CompoundExpression(expr1, test, parseLogicalExpressions(container, expr2Str));
53
54 }
55 } catch (Exception e) {
56 throw new ConfigurationException("Invalid ifProperty expression");
57 }
58 }
59
60 private static Expression getSimpleExpression(ResultContainer resultContainer, String exprStr) throws ConfigurationException {
61 try {
62 int index = -1;
63 int i;
64
65 for (i = 0; i < valueTokens.length; i++) {
66 index = exprStr.indexOf(valueTokens[i]);
67
68 if (index != -1) {
69 break;
70 }
71 }
72
73 return new SimpleExpression(resultContainer, exprStr.substring(0, index), (ValuesTest) tokenMap.get(valueTokens[i]), exprStr
74 .substring(index + valueTokens[i].length()));
75 } catch (Exception e) { throw new ConfigurationException("Invalid ifProperty expression");
77 }
78 }
79
80 private static int skipWhiteSpace(final String str, final int startIndex) {
81 final int strLen = str.length();
82 int index = startIndex;
83
84 while (index < strLen) {
85 if ((str.charAt(index) != ' ') && (str.charAt(index) != '\t')) {
86 break;
87 }
88
89 ++index;
90 }
91
92 return index;
93 }
94
95 private static String getLogicalToken(final String str, final int startIndex) {
96 final int strLen = str.length();
97 int tokenStart = skipWhiteSpace(str, startIndex);
98 int endIndex = tokenStart;
99
00 while (endIndex < strLen) {
01 int chr = str.charAt(endIndex);
02 if ((chr == ' ') || (chr == '\t') || (chr == GROUPING_START_OPERATOR)) {
03 break;
04 }
05
06 ++endIndex;
07 }
08
09 return str.substring(tokenStart, endIndex);
10 }
11}
12