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: import java.util.ArrayList;
023: import java.util.Iterator;
024: import java.util.LinkedList;
025: import java.util.List;
026:
027: import org.apache.jmeter.engine.event.LoopIterationEvent;
028: import org.apache.jmeter.engine.event.LoopIterationListener;
029: import org.apache.jmeter.samplers.Sampler;
030: import org.apache.jmeter.testelement.AbstractTestElement;
031: import org.apache.jmeter.testelement.TestElement;
032: import org.apache.jorphan.logging.LoggingManager;
033: import org.apache.log.Logger;
034:
035: /**
036: * @author Michael Stover
037: * @author Thad Smith
038: * @version $Revision: 493779 $
039: */
040: public class GenericController extends AbstractTestElement implements
041: Controller, Serializable {
042: private static final Logger log = LoggingManager
043: .getLoggerForClass();
044:
045: protected transient LinkedList iterationListeners = new LinkedList();
046:
047: protected transient List subControllersAndSamplers = new ArrayList();
048:
049: protected transient int current;
050:
051: private transient int iterCount;
052:
053: private transient boolean done, first;
054:
055: /**
056: * Creates a Generic Controller
057: */
058: public GenericController() {
059: }
060:
061: public void initialize() {
062: resetCurrent();
063: resetIterCount();
064: done = false;
065: first = true;
066: TestElement elem;
067: for (int i = 0; i < subControllersAndSamplers.size(); i++) {
068: elem = (TestElement) subControllersAndSamplers.get(i);
069: if (elem instanceof Controller) {
070: ((Controller) elem).initialize();
071: }
072: }
073: }
074:
075: protected void reInitialize() {
076: resetCurrent();
077: incrementIterCount();
078: setFirst(true);
079: recoverRunningVersion();
080: }
081:
082: /**
083: * @see org.apache.jmeter.control.Controller#next()
084: */
085: public Sampler next() {
086: fireIterEvents();
087: log.debug("Calling next on: " + this .getClass().getName());
088: if (isDone())
089: return null;
090: Sampler returnValue = null;
091: TestElement currentElement = null;
092: try {
093: currentElement = getCurrentElement();
094: setCurrentElement(currentElement);
095: if (currentElement == null) {
096: // incrementCurrent();
097: returnValue = nextIsNull();
098: } else {
099: if (currentElement instanceof Sampler) {
100: returnValue = nextIsASampler((Sampler) currentElement);
101: } else {
102: returnValue = nextIsAController((Controller) currentElement);
103: }
104: }
105: } catch (NextIsNullException e) {
106: returnValue = null;
107: }
108: return returnValue;
109: }
110:
111: /**
112: * @see org.apache.jmeter.control.Controller#isDone()
113: */
114: public boolean isDone() {
115: return done;
116: }
117:
118: protected void setDone(boolean done) {
119: this .done = done;
120: }
121:
122: protected boolean isFirst() {
123: return first;
124: }
125:
126: public void setFirst(boolean b) {
127: first = b;
128: }
129:
130: protected Sampler nextIsAController(Controller controller)
131: throws NextIsNullException {
132: Sampler returnValue;
133: Sampler sampler = controller.next();
134: if (sampler == null) {
135: currentReturnedNull(controller);
136: returnValue = next();
137: } else {
138: returnValue = sampler;
139: }
140: return returnValue;
141: }
142:
143: protected Sampler nextIsASampler(Sampler element)
144: throws NextIsNullException {
145: incrementCurrent();
146: return element;
147: }
148:
149: protected Sampler nextIsNull() throws NextIsNullException {
150: reInitialize();
151: return null;
152: }
153:
154: protected void currentReturnedNull(Controller c) {
155: if (c.isDone()) {
156: removeCurrentElement();
157: } else {
158: incrementCurrent();
159: }
160: }
161:
162: /**
163: * Gets the SubControllers attribute of the GenericController object
164: *
165: * @return the SubControllers value
166: */
167: protected List getSubControllers() {
168: return subControllersAndSamplers;
169: }
170:
171: private void addElement(TestElement child) {
172: subControllersAndSamplers.add(child);
173: }
174:
175: protected void setCurrentElement(TestElement currentElement)
176: throws NextIsNullException {
177: }
178:
179: protected TestElement getCurrentElement()
180: throws NextIsNullException {
181: if (current < subControllersAndSamplers.size()) {
182: return (TestElement) subControllersAndSamplers.get(current);
183: } else {
184: if (subControllersAndSamplers.size() == 0) {
185: setDone(true);
186: throw new NextIsNullException();
187: }
188: return null;
189: }
190: }
191:
192: protected void removeCurrentElement() {
193: subControllersAndSamplers.remove(current);
194: }
195:
196: protected void incrementCurrent() {
197: current++;
198: }
199:
200: protected void resetCurrent() {
201: current = 0;
202: }
203:
204: public void addTestElement(TestElement child) {
205: if (child instanceof Controller || child instanceof Sampler) {
206: addElement(child);
207: }
208: }
209:
210: public void addIterationListener(LoopIterationListener lis) {
211: /*
212: * A little hack - add each listener to the start of the list - this
213: * ensures that the thread running the show is the first listener and
214: * can modify certain values before other listeners are called.
215: */
216: iterationListeners.addFirst(lis);
217: }
218:
219: protected void fireIterEvents() {
220: if (isFirst()) {
221: fireIterationStart();
222: first = false;
223: }
224: }
225:
226: protected void fireIterationStart() {
227: Iterator iter = iterationListeners.iterator();
228: LoopIterationEvent event = new LoopIterationEvent(this ,
229: getIterCount());
230: while (iter.hasNext()) {
231: LoopIterationListener item = (LoopIterationListener) iter
232: .next();
233: item.iterationStart(event);
234: }
235: }
236:
237: protected int getIterCount() {
238: return iterCount;
239: }
240:
241: protected void incrementIterCount() {
242: iterCount++;
243: }
244:
245: protected void resetIterCount() {
246: iterCount = 0;
247: }
248: }
|