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.protocol.java.control.gui;
020:
021: import java.awt.BorderLayout;
022: import java.awt.event.ActionEvent;
023: import java.awt.event.ActionListener;
024: import java.io.IOException;
025: import java.lang.reflect.Method;
026: import java.util.List;
027:
028: import javax.swing.JCheckBox;
029: import javax.swing.JComboBox;
030: import javax.swing.JLabel;
031: import javax.swing.JOptionPane;
032: import javax.swing.JPanel;
033: import javax.swing.event.ChangeEvent;
034: import javax.swing.event.ChangeListener;
035:
036: import junit.framework.TestCase;
037:
038: import org.apache.jmeter.gui.util.VerticalPanel;
039: import org.apache.jmeter.protocol.java.sampler.JUnitSampler;
040: import org.apache.jmeter.samplers.gui.AbstractSamplerGui;
041: import org.apache.jmeter.testelement.TestElement;
042: import org.apache.jmeter.util.JMeterUtils;
043: import org.apache.jorphan.gui.JLabeledTextField;
044: import org.apache.jorphan.logging.LoggingManager;
045: import org.apache.jorphan.reflect.ClassFinder;
046: import org.apache.jorphan.util.JOrphanUtils;
047: import org.apache.log.Logger;
048:
049: /**
050: * The <code>JUnitTestSamplerGui</code> class provides the user interface
051: * for the {@link JUnitSampler}.
052: *
053: */
054: public class JUnitTestSamplerGui extends AbstractSamplerGui implements
055: ChangeListener, ActionListener {
056: private static final Logger log = LoggingManager
057: .getLoggerForClass();
058:
059: /** The name of the classnameCombo JComboBox */
060: private static final String CLASSNAMECOMBO = "classnamecombo"; //$NON-NLS-1$
061: private static final String METHODCOMBO = "methodcombo"; //$NON-NLS-1$
062: private static final String PREFIX = "test"; //$NON-NLS-1$
063:
064: // Names of JUnit methods
065: private static final String ONETIMESETUP = "oneTimeSetUp"; //$NON-NLS-1$
066: private static final String ONETIMETEARDOWN = "oneTimeTearDown"; //$NON-NLS-1$
067: private static final String SUITE = "suite"; //$NON-NLS-1$
068:
069: private static final String[] SPATHS = new String[] { JMeterUtils
070: .getJMeterHome()
071: + "/lib/junit/", //$NON-NLS-1$
072: };
073:
074: private JLabeledTextField constructorLabel = new JLabeledTextField(
075: JMeterUtils.getResString("junit_constructor_string")); //$NON-NLS-1$
076:
077: private JLabel methodLabel = new JLabel(JMeterUtils
078: .getResString("junit_test_method")); //$NON-NLS-1$
079:
080: private JLabeledTextField successMsg = new JLabeledTextField(
081: JMeterUtils.getResString("junit_success_msg")); //$NON-NLS-1$
082:
083: private JLabeledTextField failureMsg = new JLabeledTextField(
084: JMeterUtils.getResString("junit_failure_msg")); //$NON-NLS-1$
085:
086: private JLabeledTextField errorMsg = new JLabeledTextField(
087: JMeterUtils.getResString("junit_error_msg")); //$NON-NLS-1$
088:
089: private JLabeledTextField successCode = new JLabeledTextField(
090: JMeterUtils.getResString("junit_success_code")); //$NON-NLS-1$
091:
092: private JLabeledTextField failureCode = new JLabeledTextField(
093: JMeterUtils.getResString("junit_failure_code")); //$NON-NLS-1$
094:
095: private JLabeledTextField errorCode = new JLabeledTextField(
096: JMeterUtils.getResString("junit_error_code")); //$NON-NLS-1$
097:
098: private JLabeledTextField filterpkg = new JLabeledTextField(
099: JMeterUtils.getResString("junit_pkg_filter")); //$NON-NLS-1$
100:
101: private JCheckBox doSetup = new JCheckBox(JMeterUtils
102: .getResString("junit_do_setup_teardown")); //$NON-NLS-1$
103: private JCheckBox appendError = new JCheckBox(JMeterUtils
104: .getResString("junit_append_error")); //$NON-NLS-1$
105: private JCheckBox appendExc = new JCheckBox(JMeterUtils
106: .getResString("junit_append_exception")); //$NON-NLS-1$
107:
108: /** A combo box allowing the user to choose a test class. */
109: private JComboBox classnameCombo;
110: private JComboBox methodName;
111: private transient TestCase TESTCLASS = null;
112: private List METHODLIST = null;
113:
114: private transient ClassFilter FILTER = new ClassFilter();
115: private List CLASSLIST = null;
116:
117: /**
118: * Constructor for JUnitTestSamplerGui
119: */
120: public JUnitTestSamplerGui() {
121: super ();
122: init();
123: }
124:
125: public String getLabelResource() {
126: return "junit_request"; //$NON-NLS-1$
127: }
128:
129: /**
130: * Initialize the GUI components and layout.
131: */
132: private void init() {
133: setLayout(new BorderLayout(0, 5));
134: setBorder(makeBorder());
135:
136: add(makeTitlePanel(), BorderLayout.NORTH);
137:
138: add(createClassPanel(), BorderLayout.CENTER);
139: }
140:
141: private JPanel createClassPanel() {
142: METHODLIST = new java.util.ArrayList();
143:
144: try {
145: // Find all the classes which extend junit.framework.TestCase
146: CLASSLIST = ClassFinder.findClassesThatExtend(SPATHS,
147: new Class[] { TestCase.class });
148: } catch (IOException e) {
149: log.error("Exception getting interfaces.", e);
150: }
151:
152: JLabel label = new JLabel(JMeterUtils
153: .getResString("protocol_java_classname")); //$NON-NLS-1$
154:
155: classnameCombo = new JComboBox(CLASSLIST.toArray());
156: classnameCombo.addActionListener(this );
157: classnameCombo.setName(CLASSNAMECOMBO);
158: classnameCombo.setEditable(false);
159: label.setLabelFor(classnameCombo);
160:
161: if (FILTER != null && FILTER.size() > 0) {
162: methodName = new JComboBox(FILTER.filterArray(METHODLIST));
163: } else {
164: methodName = new JComboBox(METHODLIST.toArray());
165: }
166: methodName.addActionListener(this );
167: methodName.setName(METHODCOMBO);
168: methodLabel.setLabelFor(methodName);
169:
170: VerticalPanel panel = new VerticalPanel();
171: panel.add(filterpkg);
172: panel.add(label);
173: filterpkg.addChangeListener(this );
174:
175: if (classnameCombo != null) {
176: panel.add(classnameCombo);
177: }
178: constructorLabel.setText("");
179: panel.add(constructorLabel);
180: panel.add(methodLabel);
181: if (methodName != null) {
182: panel.add(methodName);
183: }
184: panel.add(successMsg);
185: panel.add(successCode);
186: panel.add(failureMsg);
187: panel.add(failureCode);
188: panel.add(errorMsg);
189: panel.add(errorCode);
190: panel.add(doSetup);
191: panel.add(appendError);
192: panel.add(appendExc);
193: return panel;
194: }
195:
196: private void initGui() { // TODO - unfinished?
197: appendError.setSelected(false);
198: appendExc.setSelected(false);
199: doSetup.setSelected(false);
200: filterpkg.setText(""); //$NON-NLS-1$
201: constructorLabel.setText(""); //$NON-NLS-1$
202: successCode.setText(JMeterUtils
203: .getResString("junit_success_default_code")); //$NON-NLS-1$
204: successMsg.setText(JMeterUtils
205: .getResString("junit_success_default_msg")); //$NON-NLS-1$
206: failureCode.setText(JMeterUtils
207: .getResString("junit_failure_default_code")); //$NON-NLS-1$
208: failureMsg.setText(JMeterUtils
209: .getResString("junit_failure_default_msg")); //$NON-NLS-1$
210: errorMsg.setText(JMeterUtils
211: .getResString("junit_error_default_msg")); //$NON-NLS-1$
212: errorCode.setText(JMeterUtils
213: .getResString("junit_error_default_code")); //$NON-NLS-1$
214: }
215:
216: public void clearGui() {
217: super .clearGui();
218: initGui();
219: }
220:
221: /* Implements JMeterGuiComponent.createTestElement() */
222: public TestElement createTestElement() {
223: JUnitSampler sampler = new JUnitSampler();
224: modifyTestElement(sampler);
225: return sampler;
226: }
227:
228: /* Implements JMeterGuiComponent.modifyTestElement(TestElement) */
229: public void modifyTestElement(TestElement el) {
230: JUnitSampler sampler = (JUnitSampler) el;
231: configureTestElement(sampler);
232: if (classnameCombo.getSelectedItem() != null
233: && classnameCombo.getSelectedItem() instanceof String) {
234: sampler.setClassname((String) classnameCombo
235: .getSelectedItem());
236: }
237: sampler.setConstructorString(constructorLabel.getText());
238: if (methodName.getSelectedItem() != null) {
239: Object mobj = methodName.getSelectedItem();
240: sampler.setMethod((String) mobj);
241: }
242: sampler.setFilterString(filterpkg.getText());
243: sampler.setSuccess(successMsg.getText());
244: sampler.setSuccessCode(successCode.getText());
245: sampler.setFailure(failureMsg.getText());
246: sampler.setFailureCode(failureCode.getText());
247: sampler.setDoNotSetUpTearDown(doSetup.isSelected());
248: sampler.setAppendError(appendError.isSelected());
249: sampler.setAppendException(appendExc.isSelected());
250: }
251:
252: /* Overrides AbstractJMeterGuiComponent.configure(TestElement) */
253: public void configure(TestElement el) {
254: super .configure(el);
255: JUnitSampler sampler = (JUnitSampler) el;
256: classnameCombo.setSelectedItem(sampler.getClassname());
257: instantiateClass();
258: methodName.setSelectedItem(sampler.getMethod());
259: filterpkg.setText(sampler.getFilterString());
260: constructorLabel.setText(sampler.getConstructorString());
261: if (sampler.getSuccessCode().length() > 0) {
262: successCode.setText(sampler.getSuccessCode());
263: } else {
264: successCode.setText(JMeterUtils
265: .getResString("junit_success_default_code")); //$NON-NLS-1$
266: }
267: if (sampler.getSuccess().length() > 0) {
268: successMsg.setText(sampler.getSuccess());
269: } else {
270: successMsg.setText(JMeterUtils
271: .getResString("junit_success_default_msg")); //$NON-NLS-1$
272: }
273: if (sampler.getFailureCode().length() > 0) {
274: failureCode.setText(sampler.getFailureCode());
275: } else {
276: failureCode.setText(JMeterUtils
277: .getResString("junit_failure_default_code")); //$NON-NLS-1$
278: }
279: if (sampler.getFailure().length() > 0) {
280: failureMsg.setText(sampler.getFailure());
281: } else {
282: failureMsg.setText(JMeterUtils
283: .getResString("junit_failure_default_msg")); //$NON-NLS-1$
284: }
285: if (sampler.getError().length() > 0) {
286: errorMsg.setText(sampler.getError());
287: } else {
288: errorMsg.setText(JMeterUtils
289: .getResString("junit_error_default_msg")); //$NON-NLS-1$
290: }
291: if (sampler.getErrorCode().length() > 0) {
292: errorCode.setText(sampler.getErrorCode());
293: } else {
294: errorCode.setText(JMeterUtils
295: .getResString("junit_error_default_code")); //$NON-NLS-1$
296: }
297: doSetup.setSelected(sampler.getDoNotSetUpTearDown());
298: appendError.setSelected(sampler.getAppendError());
299: appendExc.setSelected(sampler.getAppendException());
300: }
301:
302: public void instantiateClass() {
303: String className = ((String) classnameCombo.getSelectedItem());
304: if (className != null) {
305: TESTCLASS = (TestCase) JUnitSampler.getClassInstance(
306: className, constructorLabel.getText());
307: if (TESTCLASS == null) {
308: clearMethodCombo();
309: }
310: configureMethodCombo();
311: }
312: }
313:
314: public void showErrorDialog() {
315: JOptionPane.showConfirmDialog(this ,
316: JMeterUtils.getResString("junit_constructor_error"), //$NON-NLS-1$
317: "Warning", JOptionPane.OK_CANCEL_OPTION,
318: JOptionPane.ERROR_MESSAGE);
319: }
320:
321: public void configureMethodCombo() {
322: if (TESTCLASS != null) {
323: clearMethodCombo();
324: String[] names = getMethodNames(getMethods(TESTCLASS,
325: METHODLIST));
326: for (int idx = 0; idx < names.length; idx++) {
327: methodName.addItem(names[idx]);
328: METHODLIST.add(names[idx]);
329: }
330: methodName.repaint();
331: }
332: }
333:
334: public void clearMethodCombo() {
335: methodName.removeAllItems();
336: METHODLIST.clear();
337: }
338:
339: public Method[] getMethods(Object obj, List list) {
340: Method[] meths = obj.getClass().getMethods();
341: for (int idx = 0; idx < meths.length; idx++) {
342: if (meths[idx].getName().startsWith(PREFIX)
343: || meths[idx].getName().equals(ONETIMESETUP)
344: || meths[idx].getName().equals(ONETIMETEARDOWN)
345: || meths[idx].getName().equals(SUITE)) {
346: list.add(meths[idx]);
347: }
348: }
349: if (list.size() > 0) {
350: Method[] rmeth = new Method[list.size()];
351: return (Method[]) list.toArray(rmeth);
352: }
353: return new Method[0];
354: }
355:
356: public String[] getMethodNames(Method[] meths) {
357: String[] names = new String[meths.length];
358: for (int idx = 0; idx < meths.length; idx++) {
359: names[idx] = meths[idx].getName();
360: }
361: return names;
362: }
363:
364: public Class[] filterClasses(Class[] clz) {
365: if (clz != null && clz.length > 0) {
366: Class[] nclz = null;
367: return nclz;
368: }
369: return clz;
370: }
371:
372: /**
373: * Handle action events for this component. This method currently handles
374: * events for the classname combo box.
375: *
376: * @param evt the ActionEvent to be handled
377: */
378: public void actionPerformed(ActionEvent evt) {
379: if (evt.getSource() == classnameCombo) {
380: instantiateClass();
381: }
382: }
383:
384: /**
385: * the current implementation checks to see if the source
386: * of the event is the filterpkg field.
387: */
388: public void stateChanged(ChangeEvent event) {
389: if (event.getSource() == filterpkg) {
390: FILTER.setPackges(JOrphanUtils.split(filterpkg.getText(),
391: ",")); //$NON-NLS-1$
392: classnameCombo.removeAllItems();
393: // change the classname drop down
394: Object[] clist = FILTER.filterArray(CLASSLIST);
395: for (int idx = 0; idx < clist.length; idx++) {
396: classnameCombo.addItem(clist[idx]);
397: }
398: }
399: }
400: }
|