001: /*
002: * soapUI, copyright (C) 2004-2007 eviware.com
003: *
004: * soapUI is free software; you can redistribute it and/or modify it under the
005: * terms of version 2.1 of the GNU Lesser General Public License as published by
006: * the Free Software Foundation.
007: *
008: * soapUI is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without
009: * even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
010: * See the GNU Lesser General Public License for more details at gnu.org.
011: */
012:
013: package com.eviware.soapui.impl.wsdl.loadtest.log;
014:
015: import java.util.ArrayList;
016: import java.util.Collections;
017: import java.util.HashMap;
018: import java.util.List;
019: import java.util.Map;
020: import java.util.Stack;
021:
022: import javax.swing.AbstractListModel;
023:
024: import com.eviware.soapui.SoapUI;
025: import com.eviware.soapui.impl.wsdl.loadtest.WsdlLoadTest;
026: import com.eviware.soapui.model.support.TestSuiteListenerAdapter;
027: import com.eviware.soapui.model.testsuite.TestStep;
028:
029: /**
030: * Log for LoadTest events
031: *
032: * @author Ole.Matzura
033: */
034:
035: public class LoadTestLog extends AbstractListModel implements Runnable {
036: private List<LoadTestLogEntry> entries = Collections
037: .synchronizedList(new ArrayList<LoadTestLogEntry>());
038: private final WsdlLoadTest loadTest;
039: private int totalErrorCount;
040: private Map<String, Integer> errorCounts = new HashMap<String, Integer>();
041: private Stack<LoadTestLogEntry> entriesStack = new Stack<LoadTestLogEntry>();
042: private Thread modelThread;
043: private InternalTestSuiteListener testSuiteListener = new InternalTestSuiteListener();
044:
045: public LoadTestLog(WsdlLoadTest loadTest) {
046: this .loadTest = loadTest;
047: loadTest.getTestCase().getTestSuite().addTestSuiteListener(
048: testSuiteListener);
049: }
050:
051: public void release() {
052: loadTest.getTestCase().getTestSuite().removeTestSuiteListener(
053: testSuiteListener);
054: }
055:
056: public int getSize() {
057: return entries.size();
058: }
059:
060: public Object getElementAt(int index) {
061: return entries.get(index);
062: }
063:
064: public synchronized void addEntry(LoadTestLogEntry entry) {
065: entriesStack.push(entry);
066:
067: if (modelThread == null) {
068: modelThread = new Thread(this , loadTest.getName()
069: + " LoadTestLog Updater");
070: modelThread.start();
071: }
072: }
073:
074: public void run() {
075: // always run at least once
076: while (true) {
077: try {
078: while (!entriesStack.isEmpty()) {
079: int cnt = 0;
080: while (cnt < 10 && !entriesStack.isEmpty()) {
081: LoadTestLogEntry entry = entriesStack.pop();
082: if (entry != null) {
083: entries.add(entry);
084: if (entry.isError()) {
085: totalErrorCount++;
086: TestStep targetStep = entry
087: .getTargetStep();
088: String stepName = targetStep == null ? "- Total -"
089: : targetStep.getName();
090:
091: Integer errorCount = errorCounts
092: .get(stepName);
093: if (errorCount == null)
094: errorCount = 1;
095: else
096: errorCount = errorCount + 1;
097:
098: errorCounts.put(stepName, errorCount);
099: }
100:
101: cnt++;
102: }
103: }
104:
105: if (cnt > 0)
106: fireIntervalAdded(this , entries.size() - cnt,
107: entries.size() - 1);
108: }
109:
110: // break if load test is not running
111: if (!loadTest.isRunning())
112: break;
113:
114: Thread.sleep(200);
115: } catch (Exception e) {
116: SoapUI.logError(e);
117: }
118: }
119:
120: modelThread = null;
121: }
122:
123: public void clear() {
124: entriesStack.clear();
125:
126: if (!entries.isEmpty()) {
127: int size = entries.size();
128: entries.clear();
129: fireIntervalRemoved(this , 0, size - 1);
130: totalErrorCount = 0;
131: errorCounts.clear();
132: }
133: }
134:
135: public void clearErrors() {
136: int sz = entries.size();
137:
138: for (int c = 0; c < entries.size(); c++) {
139: if (entries.get(c).isError()) {
140: entries.remove(c);
141: c--;
142: }
143: }
144:
145: totalErrorCount = 0;
146: errorCounts.clear();
147:
148: if (sz > entries.size()) {
149: fireIntervalRemoved(this , entries.size(), sz);
150: fireContentsChanged(this , 0, entries.size());
151: }
152: }
153:
154: public void clearEntries(TestStep testStep) {
155: int sz = entries.size();
156:
157: String testStepName = testStep.getName();
158: for (int c = 0; c < entries.size(); c++) {
159: if (entries.get(c).getTargetStep() != null
160: && testStepName.equals(entries.get(c)
161: .getTargetStep().getName())) {
162: entries.remove(c);
163: c--;
164: }
165: }
166:
167: if (errorCounts.containsKey(testStepName)) {
168: totalErrorCount -= errorCounts.get(testStepName).intValue();
169: errorCounts.remove(testStepName);
170: }
171:
172: if (sz > entries.size()) {
173: fireIntervalRemoved(this , entries.size(), sz);
174: fireContentsChanged(this , 0, entries.size());
175: }
176: }
177:
178: public WsdlLoadTest getLoadTest() {
179: return loadTest;
180: }
181:
182: public int getErrorCount(String stepName) {
183: if (stepName == null)
184: return totalErrorCount;
185:
186: Integer counts = errorCounts.get(stepName);
187: return counts == null ? 0 : counts;
188: }
189:
190: private final class InternalTestSuiteListener extends
191: TestSuiteListenerAdapter {
192: public void testStepRemoved(TestStep testStep, int index) {
193: if (testStep.getTestCase() == loadTest.getTestCase()) {
194: clearEntries(testStep);
195: }
196: }
197: }
198: }
|