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.assertions.gui;
020:
021: import java.awt.BorderLayout;
022: import java.awt.Dimension;
023: import java.awt.event.ActionEvent;
024: import java.awt.event.ActionListener;
025:
026: import javax.swing.BorderFactory;
027: import javax.swing.Box;
028: import javax.swing.ButtonGroup;
029: import javax.swing.JButton;
030: import javax.swing.JCheckBox;
031: import javax.swing.JPanel;
032: import javax.swing.JRadioButton;
033: import javax.swing.JScrollPane;
034: import javax.swing.JTable;
035:
036: import org.apache.jmeter.assertions.ResponseAssertion;
037: import org.apache.jmeter.gui.util.PowerTableModel;
038: import org.apache.jmeter.gui.util.TextAreaCellRenderer;
039: import org.apache.jmeter.gui.util.TextAreaTableCellEditor;
040: import org.apache.jmeter.testelement.TestElement;
041: import org.apache.jmeter.testelement.property.PropertyIterator;
042: import org.apache.jmeter.util.JMeterUtils;
043:
044: /**
045: * GUI interface for a {@link ResponseAssertion}.
046: *
047: */
048: public class AssertionGui extends AbstractAssertionGui {
049: /** The name of the table column in the list of patterns. */
050: private static final String COL_NAME = JMeterUtils
051: .getResString("assertion_patterns_to_test"); //$NON-NLS-1$
052:
053: /** Radio button indicating that the text response should be tested. */
054: private JRadioButton responseStringButton;
055:
056: /** Radio button indicating that the URL should be tested. */
057: private JRadioButton urlButton;
058:
059: /** Radio button indicating that the responseMessage should be tested. */
060: private JRadioButton responseMessageButton;
061:
062: /** Radio button indicating that the responseCode should be tested. */
063: private JRadioButton responseCodeButton;
064:
065: /** Radio button indicating that the headers should be tested. */
066: private JRadioButton responseHeadersButton;
067:
068: /**
069: * Checkbox to indicate whether the response should be forced successful
070: * before testing. This is intended for use when checking the status code or
071: * status message.
072: */
073: private JCheckBox assumeSuccess;
074:
075: /**
076: * Radio button indicating to test if the field contains one of the
077: * patterns.
078: */
079: private JRadioButton containsBox;
080:
081: /**
082: * Radio button indicating to test if the field matches one of the patterns.
083: */
084: private JRadioButton matchesBox;
085:
086: /**
087: * Radio button indicating if the field equals the first pattern.
088: */
089: private JRadioButton equalsBox;
090:
091: /**
092: * Checkbox indicating to test that the field does NOT contain/match the
093: * patterns.
094: */
095: private JCheckBox notBox;
096:
097: /** A table of patterns to test against. */
098: private JTable stringTable;
099:
100: /** Button to add a new pattern. */
101: private JButton addPattern;
102:
103: /** Button to delete a pattern. */
104: private JButton deletePattern;
105:
106: /** Table model for the pattern table. */
107: private PowerTableModel tableModel;
108:
109: /**
110: * Create a new AssertionGui panel.
111: */
112: public AssertionGui() {
113: init();
114: }
115:
116: public String getLabelResource() {
117: return "assertion_title"; // $NON-NLS-1$
118: }
119:
120: /* Implements JMeterGUIComponent.createTestElement() */
121: public TestElement createTestElement() {
122: ResponseAssertion el = new ResponseAssertion();
123: modifyTestElement(el);
124: return el;
125: }
126:
127: /* Implements JMeterGUIComponent.modifyTestElement(TestElement) */
128: public void modifyTestElement(TestElement el) {
129: configureTestElement(el);
130: if (el instanceof ResponseAssertion) {
131: ResponseAssertion ra = (ResponseAssertion) el;
132:
133: ra.clearTestStrings();
134: String[] testStrings = tableModel.getData().getColumn(
135: COL_NAME);
136: for (int i = 0; i < testStrings.length; i++) {
137: ra.addTestString(testStrings[i]);
138: }
139:
140: if (responseStringButton.isSelected()) {
141: ra.setTestFieldResponseData();
142: } else if (responseCodeButton.isSelected()) {
143: ra.setTestFieldResponseCode();
144: } else if (responseMessageButton.isSelected()) {
145: ra.setTestFieldResponseMessage();
146: } else if (responseHeadersButton.isSelected()) {
147: ra.setTestFieldResponseHeaders();
148: } else { // Assume URL
149: ra.setTestFieldURL();
150: }
151:
152: ra.setAssumeSuccess(assumeSuccess.isSelected());
153:
154: if (containsBox.isSelected()) {
155: ra.setToContainsType();
156: } else if (equalsBox.isSelected()) {
157: ra.setToEqualsType();
158: } else {
159: ra.setToMatchType();
160: }
161:
162: if (notBox.isSelected()) {
163: ra.setToNotType();
164: } else {
165: ra.unsetNotType();
166: }
167: }
168: }
169:
170: /**
171: * Implements JMeterGUIComponent.clearGui
172: */
173: public void clearGui() {
174: super .clearGui();
175:
176: tableModel.clearData();
177:
178: responseStringButton.setSelected(true);
179: urlButton.setSelected(false);
180: responseCodeButton.setSelected(false);
181: responseMessageButton.setSelected(false);
182: responseHeadersButton.setSelected(false);
183: assumeSuccess.setSelected(false);
184:
185: containsBox.setSelected(true);
186: matchesBox.setSelected(false);
187: equalsBox.setSelected(false);
188: notBox.setSelected(false);
189: }
190:
191: /**
192: * A newly created component can be initialized with the contents of a Test
193: * Element object by calling this method. The component is responsible for
194: * querying the Test Element object for the relevant information to display
195: * in its GUI.
196: *
197: * @param el
198: * the TestElement to configure
199: */
200: public void configure(TestElement el) {
201: super .configure(el);
202: ResponseAssertion model = (ResponseAssertion) el;
203:
204: if (model.isContainsType()) {
205: containsBox.setSelected(true);
206: matchesBox.setSelected(false);
207: equalsBox.setSelected(false);
208: } else if (model.isEqualsType()) {
209: containsBox.setSelected(false);
210: matchesBox.setSelected(false);
211: equalsBox.setSelected(true);
212: } else {
213: containsBox.setSelected(false);
214: matchesBox.setSelected(true);
215: equalsBox.setSelected(false);
216: }
217:
218: if (model.isNotType()) {
219: notBox.setSelected(true);
220: } else {
221: notBox.setSelected(false);
222: }
223:
224: if (model.isTestFieldResponseData()) {
225: responseStringButton.setSelected(true);
226: } else if (model.isTestFieldResponseCode()) {
227: responseCodeButton.setSelected(true);
228: } else if (model.isTestFieldResponseMessage()) {
229: responseMessageButton.setSelected(true);
230: } else if (model.isTestFieldResponseHeaders()) {
231: responseHeadersButton.setSelected(true);
232: } else // Assume it is the URL
233: {
234: urlButton.setSelected(true);
235: }
236:
237: assumeSuccess.setSelected(model.getAssumeSuccess());
238:
239: tableModel.clearData();
240: PropertyIterator tests = model.getTestStrings().iterator();
241: while (tests.hasNext()) {
242: tableModel.addRow(new Object[] { tests.next()
243: .getStringValue() });
244: }
245:
246: if (model.getTestStrings().size() == 0) {
247: deletePattern.setEnabled(false);
248: } else {
249: deletePattern.setEnabled(true);
250: }
251:
252: tableModel.fireTableDataChanged();
253: }
254:
255: /**
256: * Initialize the GUI components and layout.
257: */
258: private void init() {
259: setLayout(new BorderLayout());
260: Box box = Box.createVerticalBox();
261: setBorder(makeBorder());
262:
263: box.add(makeTitlePanel());
264: box.add(createFieldPanel());
265: box.add(createTypePanel());
266: add(box, BorderLayout.NORTH);
267: add(createStringPanel(), BorderLayout.CENTER);
268: }
269:
270: /**
271: * Create a panel allowing the user to choose which response field should be
272: * tested.
273: *
274: * @return a new panel for selecting the response field
275: */
276: private JPanel createFieldPanel() {
277: JPanel panel = new JPanel();
278: panel.setBorder(BorderFactory.createTitledBorder(JMeterUtils
279: .getResString("assertion_resp_field"))); //$NON-NLS-1$
280:
281: responseStringButton = new JRadioButton(JMeterUtils
282: .getResString("assertion_text_resp")); //$NON-NLS-1$
283: urlButton = new JRadioButton(JMeterUtils
284: .getResString("assertion_url_samp")); //$NON-NLS-1$
285: responseCodeButton = new JRadioButton(JMeterUtils
286: .getResString("assertion_code_resp")); //$NON-NLS-1$
287: responseMessageButton = new JRadioButton(JMeterUtils
288: .getResString("assertion_message_resp")); //$NON-NLS-1$
289: responseHeadersButton = new JRadioButton(JMeterUtils
290: .getResString("assertion_headers")); //$NON-NLS-1$
291:
292: ButtonGroup group = new ButtonGroup();
293: group.add(responseStringButton);
294: group.add(urlButton);
295: group.add(responseCodeButton);
296: group.add(responseMessageButton);
297: group.add(responseHeadersButton);
298:
299: panel.add(responseStringButton);
300: panel.add(urlButton);
301: panel.add(responseCodeButton);
302: panel.add(responseMessageButton);
303: panel.add(responseHeadersButton);
304:
305: responseStringButton.setSelected(true);
306:
307: assumeSuccess = new JCheckBox(JMeterUtils
308: .getResString("assertion_assume_success")); //$NON-NLS-1$
309: panel.add(assumeSuccess);
310:
311: return panel;
312: }
313:
314: /**
315: * Create a panel allowing the user to choose what type of test should be
316: * performed.
317: *
318: * @return a new panel for selecting the type of assertion test
319: */
320: private JPanel createTypePanel() {
321: JPanel panel = new JPanel();
322: panel.setBorder(BorderFactory.createTitledBorder(JMeterUtils
323: .getResString("assertion_pattern_match_rules"))); //$NON-NLS-1$
324:
325: ButtonGroup group = new ButtonGroup();
326:
327: containsBox = new JRadioButton(JMeterUtils
328: .getResString("assertion_contains")); //$NON-NLS-1$
329: group.add(containsBox);
330: containsBox.setSelected(true);
331: panel.add(containsBox);
332:
333: matchesBox = new JRadioButton(JMeterUtils
334: .getResString("assertion_matches")); //$NON-NLS-1$
335: group.add(matchesBox);
336: panel.add(matchesBox);
337:
338: equalsBox = new JRadioButton(JMeterUtils
339: .getResString("assertion_equals")); //$NON-NLS-1$
340: group.add(equalsBox);
341: panel.add(equalsBox);
342:
343: notBox = new JCheckBox(JMeterUtils
344: .getResString("assertion_not")); //$NON-NLS-1$
345: panel.add(notBox);
346:
347: return panel;
348: }
349:
350: /**
351: * Create a panel allowing the user to supply a list of string patterns to
352: * test against.
353: *
354: * @return a new panel for adding string patterns
355: */
356: private JPanel createStringPanel() {
357: tableModel = new PowerTableModel(new String[] { COL_NAME },
358: new Class[] { String.class });
359: stringTable = new JTable(tableModel);
360:
361: TextAreaCellRenderer renderer = new TextAreaCellRenderer();
362: stringTable.setRowHeight(renderer.getPreferredHeight());
363: stringTable.setDefaultRenderer(String.class, renderer);
364: stringTable.setDefaultEditor(String.class,
365: new TextAreaTableCellEditor());
366: stringTable.setPreferredScrollableViewportSize(new Dimension(
367: 100, 70));
368:
369: JPanel panel = new JPanel();
370: panel.setLayout(new BorderLayout());
371: panel.setBorder(BorderFactory.createTitledBorder(JMeterUtils
372: .getResString("assertion_patterns_to_test"))); //$NON-NLS-1$
373:
374: panel.add(new JScrollPane(stringTable), BorderLayout.CENTER);
375: panel.add(createButtonPanel(), BorderLayout.SOUTH);
376:
377: return panel;
378: }
379:
380: /**
381: * Create a panel with buttons to add and delete string patterns.
382: *
383: * @return the new panel with add and delete buttons
384: */
385: private JPanel createButtonPanel() {
386: addPattern = new JButton(JMeterUtils.getResString("add")); //$NON-NLS-1$
387: addPattern.addActionListener(new AddPatternListener());
388:
389: deletePattern = new JButton(JMeterUtils.getResString("delete")); //$NON-NLS-1$
390: deletePattern.addActionListener(new ClearPatternsListener());
391: deletePattern.setEnabled(false);
392:
393: JPanel buttonPanel = new JPanel();
394: buttonPanel.add(addPattern);
395: buttonPanel.add(deletePattern);
396: return buttonPanel;
397: }
398:
399: /**
400: * An ActionListener for deleting a pattern.
401: *
402: */
403: private class ClearPatternsListener implements ActionListener {
404: public void actionPerformed(ActionEvent e) {
405: int index = stringTable.getSelectedRow();
406: if (index > -1) {
407: stringTable.getCellEditor(index,
408: stringTable.getSelectedColumn())
409: .cancelCellEditing();
410: tableModel.removeRow(index);
411: tableModel.fireTableDataChanged();
412: }
413: if (stringTable.getModel().getRowCount() == 0) {
414: deletePattern.setEnabled(false);
415: }
416: }
417: }
418:
419: /**
420: * An ActionListener for adding a pattern.
421: *
422: */
423: private class AddPatternListener implements ActionListener {
424: public void actionPerformed(ActionEvent e) {
425: tableModel.addNewRow();
426: deletePattern.setEnabled(true);
427: tableModel.fireTableDataChanged();
428: }
429: }
430: }
|