001: /*
002: * Copyright 2005-2007 The Kuali Foundation.
003: *
004: *
005: * Licensed under the Educational Community License, Version 1.0 (the "License");
006: * you may not use this file except in compliance with the License.
007: * You may obtain a copy of the License at
008: *
009: * http://www.opensource.org/licenses/ecl1.php
010: *
011: * Unless required by applicable law or agreed to in writing, software
012: * distributed under the License is distributed on an "AS IS" BASIS,
013: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014: * See the License for the specific language governing permissions and
015: * limitations under the License.
016: */
017: package edu.iu.uis.eden.test.web.framework.actions;
018:
019: import java.util.ArrayList;
020: import java.util.Iterator;
021: import java.util.List;
022: import java.util.regex.Matcher;
023: import java.util.regex.Pattern;
024:
025: import org.w3c.dom.Node;
026:
027: import edu.iu.uis.eden.test.web.framework.Filter;
028: import edu.iu.uis.eden.test.web.framework.Property;
029: import edu.iu.uis.eden.test.web.framework.PropertyScheme;
030: import edu.iu.uis.eden.test.web.framework.Script;
031: import edu.iu.uis.eden.test.web.framework.Util;
032:
033: /**
034: * ScriptAction that sets or unsets a variable.
035: * <pre>
036: * <variable name="..." [ match="..." ] [ replace="..." replacement="..." ] [ filters="..." ] value="..." />
037: * <variable name="..." [ match="..." ] [ replace="..." replacement="..." ] [ filters="..." ] />...<variable>
038: * </pre>
039: * All attributes are resolved via {@link edu.iu.uis.eden.test.web.framework.Util#getResolvableAttribute(Node, String, PropertyScheme)},
040: * defaulting to literal scheme.<br/>
041: * Explanation of attributes:
042: * <dl>
043: * <dt>match</dt>
044: * <dd>Re-assigns the value of the variable to the groups found in a supplied regular expression. E.g. variable value: "coursenumber: 1234"; match attribute: ".*coursenumber: +([0-9]+).*"; the result would be a List of all course numbers in the variable value.</dd>
045: * <dt>replace, replacement</dt>
046: * <dd>These allow regular expression search/replace. 'replace' is the regular expression to match, and 'replacement' is the replacement text. Implemented as: stringValue.replaceAll(replaceRegex, replacementString);</dd>
047: * <dt>filters</dt>
048: * <dd>Allows applying a sequence of preconfigured filters to the value. The list of filter names is comma-delimited. E.g. filters="DUPLICATE_SPACES, DUPLICATE_NEWLINES"</dd>
049: * </dl>
050: * @author Aaron Hamid (arh14 at cornell dot edu)
051: */
052: public class VariableAction extends BaseScriptAction {
053: private static final String[] NAMES = { "variable" };
054:
055: public String[] getNames() {
056: return NAMES;
057: }
058:
059: public void process(Script script, Node node) {
060: String vname = Util.getAttribute(node, "name");
061: if (vname == null) {
062: String message = "'name' attribute must be specified for 'variable' element";
063: log.error(message);
064: throw new RuntimeException(message);
065: }
066:
067: Property valueProp = Util.getResolvableAttribute(node, "value",
068: PropertyScheme.LITERAL_SCHEME);
069: Object value = null;
070: if (valueProp != null) {
071: value = script.getState().retrieveProperty(valueProp);
072: } else {
073: value = Util.getContent(node);
074: }
075: if (value == null) {
076: log.warn("No value specified for variable '" + vname + "'");
077: }
078:
079: Property matchProp = Util.getResolvableAttribute(node, "match",
080: PropertyScheme.LITERAL_SCHEME);
081: if (matchProp != null) {
082: Object matchValue = script.getState().retrieveProperty(
083: matchProp);
084: if (matchValue == null) {
085: String message = "Could not load match property: "
086: + matchProp;
087: log.error(message);
088: throw new RuntimeException(message);
089: }
090: if (!(matchValue instanceof String)) {
091: String message = "match property is not a String: "
092: + matchValue;
093: log.error(message);
094: throw new RuntimeException(message);
095: }
096: String stringValue = Util.getAsString(value, "Value");
097:
098: log.info("Assigning result of match \"" + matchValue
099: + "\" groups on value to variable '" + vname + "'");
100: Matcher matcher = Pattern.compile((String) matchValue)
101: .matcher(stringValue);
102: List groupList = new ArrayList();
103: // iterate over all matches and add all groups
104: /* TODO - look into Matcher.find()... could be problem
105: * EX: Pattern [-+]?[0-9]*\.?[0-9]+
106: * Value to Match = 123456.a34
107: * Matcher.matches() = false
108: * Matcher.find() = true
109: * Matcher.group(0) = 123456.
110: * next find() = 34
111: */
112: while (matcher.find()) {
113: for (int i = 0; i < matcher.groupCount(); i++) {
114: groupList.add(matcher.group(i));
115: }
116: }
117: script.getState().setVariable(vname, groupList);
118: }
119:
120: Property replaceProp = Util.getResolvableAttribute(node,
121: "replace", PropertyScheme.LITERAL_SCHEME);
122: if (replaceProp != null) {
123: Object replaceValue = script.getState().retrieveProperty(
124: replaceProp);
125: if (!(replaceValue instanceof String)) {
126: String message = "replace property is not a String";
127: log.error(message);
128: throw new RuntimeException(message);
129: }
130: String replaceRegex = (String) replaceValue;
131:
132: Property replacementProp = Util.getResolvableAttribute(
133: node, "replacement", PropertyScheme.LITERAL_SCHEME);
134: if (replacementProp == null) {
135: String message = "'replacement' attribute must also be specified when 'replace' attribute is specified on 'variable' element";
136: log.error(message);
137: throw new RuntimeException(message);
138: }
139: Object replacementValue = script.getState()
140: .retrieveProperty(replaceProp);
141: if (!(replacementValue instanceof String)) {
142: String message = "replacement property is not a String";
143: log.error(message);
144: throw new RuntimeException(message);
145: }
146: String replacementString = (String) replacementValue;
147: String stringValue = Util.getAsString(value, "Value");
148: log.info("Assigning result of replaceAll(\"" + replaceRegex
149: + "\",\"" + replacementString
150: + "\") on value to variable '" + vname + "'");
151: value = stringValue.replaceAll(replaceRegex,
152: replacementString);
153: }
154:
155: Property filtersProp = Util.getResolvableAttribute(node,
156: "filters", PropertyScheme.LITERAL_SCHEME);
157: if (filtersProp != null) {
158: Object filtersValue = script.getState().retrieveProperty(
159: filtersProp);
160: if (filtersValue == null) {
161: String message = "Could not load filters property: "
162: + filtersProp;
163: log.error(message);
164: throw new RuntimeException(message);
165: }
166: String filtersString = Util.getAsString(filtersValue,
167: "filters value");
168: Filter f = (Filter) script.getState().getFilters().get(
169: filtersString);
170: List filterNameList = new ArrayList();
171: if (f != null) {
172: filterNameList.add(filtersString);
173: } else {
174: String[] filterNames = filtersString.trim().split(
175: "\\s*,+\\s*");
176: for (int i = 0; i < filterNames.length; i++) {
177: filterNameList.add(filterNames[i]);
178: }
179: }
180:
181: String result = Util.getAsString(value, "Value");
182: Iterator it = filterNameList.iterator();
183: while (it.hasNext()) {
184: f = (Filter) script.getState().getFilters().get(
185: (String) it.next());
186: if (f != null) {
187: result = f.filter(result);
188: }
189: }
190:
191: if (result.equals(value)) {
192: log.warn("Filter did not modify value");
193: }
194:
195: value = result;
196: }
197:
198: log.info("Setting variable '" + vname + "' to "
199: + (value == null ? "null" : "'" + value + "'"));
200: script.getState().setVariable(vname, value);
201: }
202: }
|