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.control;
020:
021: import java.io.Serializable;
022:
023: import org.apache.jmeter.samplers.Sampler;
024: import org.apache.jmeter.testelement.property.StringProperty;
025: import org.apache.jorphan.logging.LoggingManager;
026: import org.apache.log.Logger;
027: import org.mozilla.javascript.Context;
028: import org.mozilla.javascript.Scriptable;
029:
030: /*******************************************************************************
031: *
032: * @author Cyrus Montakab created 2003/06/30
033: *
034: * This is a Conditional Controller; it will execute the set of statements
035: * (samplers/controllers, etc) while the 'condition' is true.
036: * In a programming world - this is equivalant of :
037: * if (condition) {
038: * statements ....
039: * }
040: * In JMeter you may have : Thread-Group (set to loop a number of times or indefinitely,
041: * ... Samplers ... (e.g. Counter )
042: * ... Other Controllers ....
043: * ... IfController ( condition set to something like - ${counter}<10)
044: * ... statements to perform if condition is true
045: * ...
046: * ... Other Controllers /Samplers }
047: *
048: ******************************************************************************/
049:
050: public class IfController extends GenericController implements
051: Serializable {
052:
053: private static final Logger logger = LoggingManager
054: .getLoggerForClass();
055:
056: private final static String CONDITION = "IfController.condition"; //$NON-NLS-1$
057:
058: private final static String EVALUATE_ALL = "IfController.evaluateAll"; //$NON-NLS-1$
059:
060: /**
061: * constructor
062: */
063: public IfController() {
064: super ();
065: }
066:
067: /**
068: * constructor
069: */
070: public IfController(String condition) {
071: super ();
072: this .setCondition(condition);
073: }
074:
075: /**
076: * Condition Accessor - this is gonna be like ${count}<10
077: */
078: public void setCondition(String condition) {
079: setProperty(new StringProperty(CONDITION, condition));
080: }
081:
082: /**
083: * Condition Accessor - this is gonna be like ${count}<10
084: */
085: public String getCondition() {
086: return getPropertyAsString(CONDITION);
087: }
088:
089: /**
090: * evaluate the condition clause log error if bad condition
091: */
092: static boolean evaluateCondition(String cond) {
093: logger.debug(" getCondition() : [" + cond + "]");
094:
095: String resultStr = "";
096: boolean result = false;
097:
098: // now evaluate the condition using JavaScript
099: Context cx = Context.enter();
100: try {
101: Scriptable scope = cx.initStandardObjects(null);
102: Object cxResultObject = cx.evaluateString(scope, cond
103: /** * conditionString ** */
104: , "<cmd>", 1, null);
105: resultStr = Context.toString(cxResultObject);
106:
107: if (resultStr.equals("false")) { //$NON-NLS-1$
108: result = false;
109: } else if (resultStr.equals("true")) { //$NON-NLS-1$
110: result = true;
111: } else {
112: throw new Exception(" BAD CONDITION :: " + cond
113: + " :: expected true or false");
114: }
115:
116: logger.debug(" >> evaluate Condition - [ " + cond
117: + "] results is [" + result + "]");
118: } catch (Exception e) {
119: logger.error(e.getMessage(), e);
120: } finally {
121: Context.exit();
122: }
123:
124: return result;
125: }
126:
127: /**
128: * This is overriding the parent method. IsDone indicates whether the
129: * termination condition is reached. I.e. if the condition evaluates to
130: * False - then isDone() returns TRUE
131: */
132: public boolean isDone() {
133: // boolean result = true;
134: // try {
135: // result = !evaluateCondition();
136: // } catch (Exception e) {
137: // logger.error(e.getMessage(), e);
138: // }
139: // setDone(true);
140: // return result;
141: // setDone(false);
142: return false;
143: }
144:
145: /**
146: * @see org.apache.jmeter.control.Controller#next()
147: */
148: public Sampler next() {
149: // We should only evalute the condition if it is the first
150: // time ( first "iteration" ) we are called.
151: // For subsequent calls, we are inside the IfControllerGroup,
152: // so then we just pass the control to the next item inside the if control
153: boolean result = true;
154: if (isEvaluateAll() || isFirst()) {
155: result = evaluateCondition(getCondition());
156: }
157:
158: if (result) {
159: return super .next();
160: }
161: try {
162: return nextIsNull();
163: } catch (NextIsNullException e1) {
164: return null;
165: }
166: }
167:
168: public boolean isEvaluateAll() {
169: return getPropertyAsBoolean(EVALUATE_ALL, false);
170: }
171:
172: public void setEvaluateAll(boolean b) {
173: setProperty(EVALUATE_ALL, b);
174: }
175: }
|