source: other-projects/trunk/realistic-books/packages/AntInstaller/src/org/tp23/antinstaller/runtime/logic/ExpressionBuilder.java@ 19253

Last change on this file since 19253 was 19253, checked in by davidb, 15 years ago

Establishing a source code repository for Veronica's Realistic Book's software

File size: 6.3 KB
Line 
1/*
2 * Licensed under the Apache License, Version 2.0 (the "License");
3 * you may not use this file except in compliance with the License.
4 * You may obtain a copy of the License at
5 *
6 * http://www.apache.org/licenses/LICENSE-2.0
7 *
8 * Unless required by applicable law or agreed to in writing, software
9 * distributed under the License is distributed on an "AS IS" BASIS,
10 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11 * See the License for the specific language governing permissions and
12 * limitations under the License.
13 */
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/**
25 * @author mwilson
26 * @version $Id: ExpressionBuilder.java,v 1.2 2006/12/21 00:03:18 teknopaul Exp $
27 * @since 0.7.4 patch 2
28 */
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 //Have to sort so that longest test operator is checked for first
76 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
100 public static Expression parseLogicalExpressions(ResultContainer container, String exprStr) throws ConfigurationException {
101 int startIndex = skipWhiteSpace(exprStr, 0);
102 int index = exprStr.indexOf(GROUPING_START_OPERATOR, startIndex);
103
104 if (index == -1) {
105 return getSimpleExpression(container, exprStr.substring(startIndex));
106 }
107
108 if (index != 0) {
109 throw new ConfigurationException("Illegal ifProperty value: If present, grouping operator " + GROUPING_START_OPERATOR
110 + " must be at start of property string");
111 }
112
113 ++startIndex; //Skip over grouping operator
114
115 int endIndex = exprStr.indexOf(GROUPING_END_OPERATOR, startIndex);
116
117 if (endIndex == -1) {
118 throw new ConfigurationException("Missing closing grouping bracket " + GROUPING_END_OPERATOR + " in expression " + exprStr);
119 }
120
121 //Check that this isn't an attempt tu use nested logical tests - not supported
122 int tstIndex = exprStr.indexOf(GROUPING_START_OPERATOR, startIndex);
123 if ((tstIndex != -1) && (tstIndex < endIndex)) {
124 throw new ConfigurationException("Nesting of logical operations is not supported: " + exprStr);
125 }
126
127 try {
128 Expression expr1 = parseLogicalExpressions(container, exprStr.substring(startIndex, endIndex));
129
130 LogicalTest test = null;
131
132 startIndex = endIndex + 1;
133
134 //Look for logical operator token
135 String logicalToken = getLogicalToken(exprStr, startIndex);
136
137 for (int i = 0; i < logicalTokens.length; i++) {
138
139 if (logicalTokens[i].compareTo(logicalToken) == 0) {
140 test = (LogicalTest) tokenMap.get(logicalTokens[i]);
141 index = exprStr.indexOf(logicalTokens[i], startIndex);
142 startIndex = index + logicalTokens[i].length();
143 break;
144 }
145 }
146
147 if (test == null) {
148 return new CompoundExpression(expr1, SINGLE_EXPRESSION_TEST, null);
149 } else {
150 startIndex = skipWhiteSpace(exprStr, startIndex);
151 String expr2Str = exprStr.substring(startIndex, exprStr.length());
152 return new CompoundExpression(expr1, test, parseLogicalExpressions(container, expr2Str));
153
154 }
155 } catch (Exception e) {
156 throw new ConfigurationException("Invalid ifProperty expression");
157 }
158 }
159
160 private static Expression getSimpleExpression(ResultContainer resultContainer, String exprStr) throws ConfigurationException {
161 try {
162 int index = -1;
163 int i;
164
165 for (i = 0; i < valueTokens.length; i++) {
166 index = exprStr.indexOf(valueTokens[i]);
167
168 if (index != -1) {
169 break;
170 }
171 }
172
173 return new SimpleExpression(resultContainer, exprStr.substring(0, index), (ValuesTest) tokenMap.get(valueTokens[i]), exprStr
174 .substring(index + valueTokens[i].length()));
175 } catch (Exception e) { // can be StringIndexOutOfBoundsException - PH
176 throw new ConfigurationException("Invalid ifProperty expression");
177 }
178 }
179
180 private static int skipWhiteSpace(final String str, final int startIndex) {
181 final int strLen = str.length();
182 int index = startIndex;
183
184 while (index < strLen) {
185 if ((str.charAt(index) != ' ') && (str.charAt(index) != '\t')) {
186 break;
187 }
188
189 ++index;
190 }
191
192 return index;
193 }
194
195 private static String getLogicalToken(final String str, final int startIndex) {
196 final int strLen = str.length();
197 int tokenStart = skipWhiteSpace(str, startIndex);
198 int endIndex = tokenStart;
199
200 while (endIndex < strLen) {
201 int chr = str.charAt(endIndex);
202 if ((chr == ' ') || (chr == '\t') || (chr == GROUPING_START_OPERATOR)) {
203 break;
204 }
205
206 ++endIndex;
207 }
208
209 return str.substring(tokenStart, endIndex);
210 }
211}
Note: See TracBrowser for help on using the repository browser.