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.panels.teststeps;
014:
015: import java.awt.BorderLayout;
016: import java.awt.Color;
017: import java.awt.Dimension;
018: import java.awt.event.ActionEvent;
019:
020: import javax.swing.AbstractAction;
021: import javax.swing.Action;
022: import javax.swing.BorderFactory;
023: import javax.swing.DefaultListModel;
024: import javax.swing.Icon;
025: import javax.swing.JButton;
026: import javax.swing.JComboBox;
027: import javax.swing.JComponent;
028: import javax.swing.JLabel;
029: import javax.swing.JList;
030: import javax.swing.JPanel;
031: import javax.swing.JScrollPane;
032: import javax.swing.JSplitPane;
033: import javax.swing.JTextArea;
034: import javax.swing.ListSelectionModel;
035: import javax.swing.event.ListSelectionEvent;
036: import javax.swing.event.ListSelectionListener;
037: import javax.swing.text.Document;
038:
039: import com.eviware.soapui.SoapUI;
040: import com.eviware.soapui.impl.wsdl.actions.support.ShowOnlineHelpAction;
041: import com.eviware.soapui.impl.wsdl.panels.support.TestRunComponentEnabler;
042: import com.eviware.soapui.impl.wsdl.panels.teststeps.support.GotoTestStepsComboBoxModel;
043: import com.eviware.soapui.impl.wsdl.submit.transports.http.WsdlResponse;
044: import com.eviware.soapui.impl.wsdl.support.HelpUrls;
045: import com.eviware.soapui.impl.wsdl.teststeps.WsdlGotoTestStep;
046: import com.eviware.soapui.impl.wsdl.teststeps.WsdlTestRequestStep;
047: import com.eviware.soapui.impl.wsdl.teststeps.WsdlGotoTestStep.GotoCondition;
048: import com.eviware.soapui.model.ModelItem;
049: import com.eviware.soapui.support.DocumentListenerAdapter;
050: import com.eviware.soapui.support.UISupport;
051: import com.eviware.soapui.support.components.JUndoableTextArea;
052: import com.eviware.soapui.support.xml.XmlUtils;
053: import com.eviware.soapui.ui.desktop.DesktopPanel;
054: import com.jgoodies.forms.builder.ButtonBarBuilder;
055:
056: /**
057: * DesktopPanel for WsdlGotoTestSteps
058: *
059: * @author Ole.Matzura
060: */
061:
062: public class GotoStepDesktopPanel extends JPanel implements
063: DesktopPanel {
064: private final WsdlGotoTestStep gotoStep;
065: private DefaultListModel listModel;
066: private JList conditionList;
067: private JTextArea expressionArea;
068: private JButton copyButton;
069: private JButton deleteButton;
070: private JButton declareButton;
071: private GotoTestStepsComboBoxModel testStepsModel;
072: private JComboBox testStepsCombo;
073: private JButton testConditionButton;
074: private TestRunComponentEnabler componentEnabler;
075: private GotoCondition currentCondition;
076:
077: public GotoStepDesktopPanel(WsdlGotoTestStep testStep) {
078: super (new BorderLayout());
079: this .gotoStep = testStep;
080: componentEnabler = new TestRunComponentEnabler(testStep
081: .getTestCase());
082:
083: buildUI();
084: }
085:
086: public TestRunComponentEnabler getComponentEnabler() {
087: return componentEnabler;
088: }
089:
090: public JList getConditionList() {
091: return conditionList;
092: }
093:
094: public JButton getCopyButton() {
095: return copyButton;
096: }
097:
098: public JButton getDeclareButton() {
099: return declareButton;
100: }
101:
102: public JButton getDeleteButton() {
103: return deleteButton;
104: }
105:
106: public JTextArea getExpressionArea() {
107: return expressionArea;
108: }
109:
110: public WsdlGotoTestStep getGotoStep() {
111: return gotoStep;
112: }
113:
114: public DefaultListModel getListModel() {
115: return listModel;
116: }
117:
118: public JButton getTestConditionButton() {
119: return testConditionButton;
120: }
121:
122: public JComboBox getTestStepsCombo() {
123: return testStepsCombo;
124: }
125:
126: public GotoTestStepsComboBoxModel getTestStepsModel() {
127: return testStepsModel;
128: }
129:
130: private void buildUI() {
131: JSplitPane splitPane = UISupport.createHorizontalSplit();
132:
133: listModel = new DefaultListModel();
134:
135: for (int c = 0; c < gotoStep.getConditionCount(); c++) {
136: listModel.addElement(gotoStep.getConditionAt(c).getName());
137: }
138:
139: conditionList = new JList(listModel);
140: conditionList
141: .setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
142: conditionList
143: .addListSelectionListener(new ConditionListSelectionListener());
144:
145: JScrollPane listScrollPane = new JScrollPane(conditionList);
146: listScrollPane.setBorder(BorderFactory.createCompoundBorder(
147: BorderFactory.createTitledBorder(BorderFactory
148: .createEmptyBorder(), "Conditions"),
149: BorderFactory.createLineBorder(Color.GRAY)));
150:
151: splitPane.setLeftComponent(listScrollPane);
152:
153: expressionArea = new JUndoableTextArea();
154: expressionArea.setEnabled(false);
155: expressionArea.getDocument().addDocumentListener(
156: new SourceAreaDocumentListener());
157:
158: JPanel expressionPanel = new JPanel(new BorderLayout());
159: expressionPanel.add(new JScrollPane(expressionArea),
160: BorderLayout.CENTER);
161: ButtonBarBuilder builder = new ButtonBarBuilder();
162: builder.addFixed(new JLabel(
163: "<html><b>Condition XPath Expression</b></html>"));
164: builder.addGlue();
165: builder.setBorder(BorderFactory.createEmptyBorder(3, 3, 3, 3));
166: expressionPanel.add(builder.getPanel(), BorderLayout.NORTH);
167: expressionPanel.setBorder(BorderFactory.createEmptyBorder(3, 3,
168: 3, 3));
169:
170: builder = buildToolbar();
171: expressionPanel.add(builder.getPanel(), BorderLayout.SOUTH);
172:
173: splitPane.setRightComponent(expressionPanel);
174: splitPane.setResizeWeight(0.1);
175: splitPane.setDividerLocation(120);
176:
177: add(splitPane, BorderLayout.CENTER);
178:
179: builder = new ButtonBarBuilder();
180: JButton addButton = new JButton(new AddAction());
181: builder.addFixed(addButton);
182: builder.addRelatedGap();
183: copyButton = new JButton(new CopyAction());
184: copyButton.setEnabled(false);
185: builder.addFixed(copyButton);
186: builder.addRelatedGap();
187: deleteButton = new JButton(new DeleteAction());
188: deleteButton.setEnabled(false);
189: builder.addFixed(deleteButton);
190: builder.addRelatedGap();
191: declareButton = new JButton(new DeclareNamespacesAction());
192: declareButton.setEnabled(false);
193: builder.addFixed(declareButton);
194: builder.addRelatedGap();
195: JButton runButton = new JButton(new RunAction());
196: builder.addFixed(runButton);
197:
198: builder.addGlue();
199: builder.addFixed(new JButton(new CloseAction()));
200: builder.addRelatedGap();
201: builder.addFixed(UISupport
202: .createToolbarButton(new ShowOnlineHelpAction(
203: HelpUrls.GOTOSTEPEDITOR_HELP_URL)));
204: builder.setBorder(BorderFactory.createEmptyBorder(3, 3, 3, 3));
205:
206: add(builder.getPanel(), BorderLayout.SOUTH);
207:
208: setBorder(BorderFactory.createEmptyBorder(3, 3, 3, 3));
209: setPreferredSize(new Dimension(550, 300));
210:
211: if (listModel.getSize() > 0)
212: conditionList.setSelectedIndex(0);
213:
214: componentEnabler.add(conditionList);
215: componentEnabler.add(expressionArea);
216: componentEnabler.add(testStepsCombo);
217: componentEnabler.add(testConditionButton);
218: componentEnabler.add(copyButton);
219: componentEnabler.add(declareButton);
220: componentEnabler.add(deleteButton);
221: componentEnabler.add(addButton);
222: componentEnabler.add(runButton);
223: }
224:
225: protected ButtonBarBuilder buildToolbar() {
226: ButtonBarBuilder builder;
227: builder = new ButtonBarBuilder();
228: testStepsModel = new GotoTestStepsComboBoxModel(gotoStep
229: .getTestCase(), null);
230: testStepsCombo = new JComboBox(testStepsModel);
231: testStepsCombo
232: .setToolTipText("The step the test case will go to if the current condition is true");
233: testStepsCombo.setEnabled(false);
234: builder
235: .addFixed(new JLabel("<html><b>Target step:</b></html>"));
236: builder.addRelatedGap();
237: builder.addFixed(testStepsCombo);
238: builder.addGlue();
239: testConditionButton = new JButton(new TestConditionAction());
240: testConditionButton.setEnabled(false);
241: builder.addFixed(testConditionButton);
242: builder.setBorder(BorderFactory.createEmptyBorder(3, 3, 3, 3));
243: return builder;
244: }
245:
246: private final class SourceAreaDocumentListener extends
247: DocumentListenerAdapter {
248: @Override
249: public void update(Document document) {
250: int ix = conditionList.getSelectedIndex();
251: if (ix != -1) {
252: gotoStep.getConditionAt(ix).setExpression(
253: expressionArea.getText());
254: }
255: }
256: }
257:
258: private final class ConditionListSelectionListener implements
259: ListSelectionListener {
260: public void valueChanged(ListSelectionEvent e) {
261: int ix = conditionList.getSelectedIndex();
262: if (ix == -1) {
263: expressionArea.setText("");
264: testStepsModel.setCondition(null);
265: currentCondition = null;
266: } else {
267: currentCondition = gotoStep.getConditionAt(ix);
268: expressionArea
269: .setText(currentCondition.getExpression());
270: testStepsModel.setCondition(currentCondition);
271: }
272:
273: boolean b = ix != -1;
274: enableEditComponents(b);
275: }
276: }
277:
278: private final class AddAction extends AbstractAction {
279: public AddAction() {
280: super ("Add");
281: }
282:
283: public void actionPerformed(ActionEvent e) {
284: String name = UISupport.prompt(
285: "Specify name for condition", "Add Condition",
286: "Condition " + (gotoStep.getConditionCount() + 1));
287: if (name == null || name.trim().length() == 0)
288: return;
289:
290: gotoStep.addCondition(name);
291:
292: listModel.addElement(name);
293: conditionList.setSelectedIndex(listModel.getSize() - 1);
294: }
295: }
296:
297: private final class CopyAction extends AbstractAction {
298: public CopyAction() {
299: super ("Copy");
300: }
301:
302: public void actionPerformed(ActionEvent e) {
303: int ix = conditionList.getSelectedIndex();
304: GotoCondition config = gotoStep.getConditionAt(ix);
305:
306: String name = UISupport.prompt(
307: "Specify name for condition", "Copy Condition",
308: config.getName());
309: if (name == null || name.trim().length() == 0)
310: return;
311:
312: GotoCondition condition = gotoStep.addCondition(name);
313: condition.setExpression(config.getExpression());
314: condition.setTargetStep(config.getTargetStep());
315: condition.setType(config.getType());
316:
317: listModel.addElement(name);
318: conditionList.setSelectedIndex(listModel.getSize() - 1);
319: }
320: }
321:
322: private final class DeleteAction extends AbstractAction {
323: public DeleteAction() {
324: super ("Delete");
325: }
326:
327: public void actionPerformed(ActionEvent e) {
328: if (UISupport.confirm("Delete selected condition",
329: "Delete Condition")) {
330: int ix = conditionList.getSelectedIndex();
331:
332: conditionList.setSelectedIndex(-1);
333:
334: gotoStep.removeConditionAt(ix);
335: listModel.remove(ix);
336:
337: if (listModel.getSize() > 0) {
338: conditionList.setSelectedIndex(ix > listModel
339: .getSize() - 1 ? listModel.getSize() - 1
340: : ix);
341: }
342: }
343: }
344: }
345:
346: private final class DeclareNamespacesAction extends AbstractAction {
347: public DeclareNamespacesAction() {
348: super ("Declare");
349: putValue(Action.SHORT_DESCRIPTION,
350: "Declare available response namespaces in condition expression");
351: }
352:
353: public void actionPerformed(ActionEvent e) {
354: try {
355: WsdlTestRequestStep previousStep = (WsdlTestRequestStep) gotoStep
356: .getTestCase().findPreviousStepOfType(gotoStep,
357: WsdlTestRequestStep.class);
358:
359: if (previousStep != null) {
360: WsdlResponse response = previousStep
361: .getTestRequest().getResponse();
362: String xml = response == null ? null : response
363: .getContentAsString();
364: if (xml != null && xml.trim().length() > 0) {
365: expressionArea.setText(XmlUtils
366: .declareXPathNamespaces(xml)
367: + expressionArea.getText());
368: } else {
369: UISupport
370: .showErrorMessage("Missing response in previous request step ["
371: + previousStep.getName() + "]");
372: }
373: } else {
374: UISupport
375: .showErrorMessage("Missing previous request step");
376: }
377: } catch (Exception e1) {
378: SoapUI.logError(e1);
379: }
380: }
381: }
382:
383: private final class RunAction extends AbstractAction {
384: public RunAction() {
385: super ("Run");
386: }
387:
388: public void actionPerformed(ActionEvent e) {
389: if (listModel.getSize() == 0) {
390: UISupport.showErrorMessage("Missing conditions!");
391: return;
392: }
393:
394: WsdlTestRequestStep previousStep = (WsdlTestRequestStep) gotoStep
395: .getTestCase().findPreviousStepOfType(gotoStep,
396: WsdlTestRequestStep.class);
397:
398: if (previousStep == null) {
399: UISupport
400: .showErrorMessage("Missing previous request step");
401: } else {
402: if (previousStep.getTestRequest().getResponse()
403: .getContentAsString() == null) {
404: UISupport
405: .showErrorMessage("Missing response in previous message");
406: return;
407: }
408:
409: GotoCondition target = gotoStep
410: .runConditions(previousStep);
411: if (target == null) {
412: UISupport
413: .showInfoMessage("No condition true for current response in ["
414: + previousStep.getName() + "]");
415: } else {
416: UISupport
417: .showInfoMessage("Condition triggered for go to ["
418: + target.getTargetStep() + "]");
419: }
420: }
421: }
422: }
423:
424: private final class TestConditionAction extends AbstractAction {
425: public TestConditionAction() {
426: super ("Test Condition");
427: }
428:
429: public void actionPerformed(ActionEvent e) {
430: WsdlTestRequestStep previousStep = (WsdlTestRequestStep) gotoStep
431: .getTestCase().findPreviousStepOfType(gotoStep,
432: WsdlTestRequestStep.class);
433:
434: if (previousStep == null) {
435: UISupport
436: .showErrorMessage("Missing previous request step");
437: } else {
438: if (previousStep.getTestRequest().getResponse() == null
439: || previousStep.getTestRequest().getResponse()
440: .getContentAsString().trim().length() == 0) {
441: UISupport
442: .showErrorMessage("Missing response in previous request step ["
443: + previousStep.getName() + "]");
444: return;
445: }
446:
447: try {
448: GotoCondition condition = gotoStep
449: .getConditionAt(conditionList
450: .getSelectedIndex());
451: boolean evaluate = condition.evaluate(previousStep);
452: if (!evaluate) {
453: UISupport
454: .showInfoMessage("Condition not true for current response in ["
455: + previousStep.getName() + "]");
456: } else {
457: UISupport
458: .showInfoMessage("Condition true for current response in ["
459: + previousStep.getName() + "]");
460: }
461: } catch (Exception e1) {
462: UISupport
463: .showErrorMessage("Error checking condition: "
464: + e1.getMessage());
465: }
466: }
467: }
468: }
469:
470: private final class CloseAction extends AbstractAction {
471: public CloseAction() {
472: super ("Close");
473: }
474:
475: public void actionPerformed(ActionEvent e) {
476: SoapUI.getDesktop().closeDesktopPanel(gotoStep);
477: }
478: }
479:
480: public WsdlGotoTestStep getModelItem() {
481: return gotoStep;
482: }
483:
484: public boolean onClose(boolean canCancel) {
485: componentEnabler.release();
486: return true;
487: }
488:
489: public JComponent getComponent() {
490: return this ;
491: }
492:
493: public boolean dependsOn(ModelItem modelItem) {
494: return modelItem == gotoStep
495: || modelItem == gotoStep.getTestCase()
496: || modelItem == gotoStep.getTestCase().getTestSuite()
497: || modelItem == gotoStep.getTestCase().getTestSuite()
498: .getProject();
499: }
500:
501: public String getTitle() {
502: return gotoStep.getTestCase().getName() + " - "
503: + gotoStep.getName();
504: }
505:
506: public String getDescription() {
507: return "Goto: [" + gotoStep.getName() + "] - "
508: + gotoStep.getTestStepTitle();
509: }
510:
511: public Icon getIcon() {
512: return getModelItem().getIcon();
513: }
514:
515: public GotoCondition getCurrentCondition() {
516: return currentCondition;
517: }
518:
519: protected void enableEditComponents(boolean b) {
520: expressionArea.setEnabled(b);
521: testStepsCombo.setEnabled(b);
522: copyButton.setEnabled(b);
523: deleteButton.setEnabled(b);
524: declareButton.setEnabled(b);
525: testConditionButton.setEnabled(b);
526: }
527: }
|