001: /*
002: * Licensed to the Apache Software Foundation (ASF) under one or more
003: * contributor license agreements. See the NOTICE file distributed with
004: * this work for additional information regarding copyright ownership.
005: * The ASF licenses this file to You under the Apache License, Version 2.0
006: * (the "License"); you may not use this file except in compliance with
007: * the License. You may obtain a copy of the License at
008: *
009: * http://www.apache.org/licenses/LICENSE-2.0
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: */
018:
019: package org.apache.jmeter.engine.util;
020:
021: import java.util.Collection;
022: import java.util.HashMap;
023: import java.util.Iterator;
024: import java.util.LinkedList;
025: import java.util.List;
026: import java.util.Map;
027:
028: import org.apache.jmeter.functions.Function;
029: import org.apache.jmeter.functions.InvalidVariableException;
030: import org.apache.jmeter.samplers.SampleResult;
031: import org.apache.jmeter.samplers.Sampler;
032: import org.apache.jmeter.threads.JMeterContext;
033: import org.apache.jmeter.threads.JMeterContextService;
034: import org.apache.jmeter.util.JMeterUtils;
035: import org.apache.jorphan.logging.LoggingManager;
036: import org.apache.jorphan.reflect.ClassFinder;
037: import org.apache.log.Logger;
038:
039: /**
040: * CompoundFunction.
041: *
042: * @author mstover
043: */
044: public class CompoundVariable implements Function {
045: private static final Logger log = LoggingManager
046: .getLoggerForClass();
047:
048: private String rawParameters;
049:
050: private static FunctionParser functionParser = new FunctionParser();
051:
052: private static Map functions = new HashMap();
053:
054: private boolean hasFunction, isDynamic;
055:
056: private String permanentResults = ""; // $NON-NLS-1$
057:
058: private LinkedList compiledComponents = new LinkedList();
059:
060: static {
061: try {
062: List classes = ClassFinder.findClassesThatExtend(
063: JMeterUtils.getSearchPaths(),
064: new Class[] { Function.class }, true);
065: Iterator iter = classes.iterator();
066: while (iter.hasNext()) {
067: Function tempFunc = (Function) Class.forName(
068: (String) iter.next()).newInstance();
069: String referenceKey = tempFunc.getReferenceKey();
070: functions.put(referenceKey, tempFunc.getClass());
071: // Add alias for original StringFromFile name (had only one underscore)
072: if (referenceKey.equals("__StringFromFile")) {//$NON-NLS-1$
073: functions.put(
074: "_StringFromFile", tempFunc.getClass());//$NON-NLS-1$
075: }
076: }
077: } catch (Exception err) {
078: log.error("", err);
079: }
080: }
081:
082: public CompoundVariable() {
083: super ();
084: isDynamic = true;
085: hasFunction = false;
086: }
087:
088: public CompoundVariable(String parameters) {
089: this ();
090: try {
091: setParameters(parameters);
092: } catch (InvalidVariableException e) {
093: }
094: }
095:
096: public String execute() {
097: if (isDynamic) {
098: JMeterContext context = JMeterContextService.getContext();
099: SampleResult previousResult = context.getPreviousResult();
100: Sampler currentSampler = context.getCurrentSampler();
101: return execute(previousResult, currentSampler);
102: }
103: return permanentResults; // $NON-NLS-1$
104: }
105:
106: /**
107: * Allows the retrieval of the original String prior to it being compiled.
108: *
109: * @return String
110: */
111: public String getRawParameters() {
112: return rawParameters;
113: }
114:
115: /*
116: * (non-Javadoc)
117: *
118: * @see Function#execute(SampleResult, Sampler)
119: */
120: public String execute(SampleResult previousResult,
121: Sampler currentSampler) {
122: if (compiledComponents == null
123: || compiledComponents.size() == 0) {
124: return ""; // $NON-NLS-1$
125: }
126: boolean testDynamic = false;
127: StringBuffer results = new StringBuffer();
128: Iterator iter = compiledComponents.iterator();
129: while (iter.hasNext()) {
130: Object item = iter.next();
131: if (item instanceof Function) {
132: testDynamic = true;
133: try {
134: results.append(((Function) item).execute(
135: previousResult, currentSampler));
136: } catch (InvalidVariableException e) {
137: }
138: } else if (item instanceof SimpleVariable) {
139: testDynamic = true;
140: results.append(((SimpleVariable) item).toString());
141: } else {
142: results.append(item);
143: }
144: }
145: if (!testDynamic) {
146: isDynamic = false;
147: permanentResults = results.toString();
148: }
149: return results.toString();
150: }
151:
152: public CompoundVariable getFunction() {
153: CompoundVariable func = new CompoundVariable();
154: func.compiledComponents = (LinkedList) compiledComponents
155: .clone();
156: func.rawParameters = rawParameters;
157: return func;
158: }
159:
160: public List getArgumentDesc() {
161: return new LinkedList();
162: }
163:
164: public void clear() {
165: hasFunction = false;
166: compiledComponents.clear();
167: }
168:
169: public void setParameters(String parameters)
170: throws InvalidVariableException {
171: this .rawParameters = parameters;
172: if (parameters == null || parameters.length() == 0) {
173: return;
174: }
175:
176: compiledComponents = functionParser.compileString(parameters);
177: if (compiledComponents.size() > 1
178: || !(compiledComponents.get(0) instanceof String)) {
179: hasFunction = true;
180: }
181: }
182:
183: /*
184: * (non-Javadoc)
185: *
186: * @see org.apache.jmeter.functions.Function#setParameters(Collection)
187: */
188: public void setParameters(Collection parameters)
189: throws InvalidVariableException {
190: }
191:
192: static Object getNamedFunction(String functionName)
193: throws InvalidVariableException {
194: if (functions.containsKey(functionName)) {
195: try {
196: return ((Class) functions.get(functionName))
197: .newInstance();
198: } catch (Exception e) {
199: log.error("", e); // $NON-NLS-1$
200: throw new InvalidVariableException();
201: }
202: }
203: return new SimpleVariable(functionName);
204: }
205:
206: public boolean hasFunction() {
207: return hasFunction;
208: }
209:
210: /**
211: * @see Function#getReferenceKey()
212: */
213: public String getReferenceKey() {
214: return ""; // $NON-NLS-1$
215: }
216: }
|