View Javadoc

1   /*
2    *  soapUI, copyright (C) 2004-2007 eviware.com 
3    *
4    *  soapUI is free software; you can redistribute it and/or modify it under the 
5    *  terms of version 2.1 of the GNU Lesser General Public License as published by 
6    *  the Free Software Foundation.
7    *
8    *  soapUI is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without 
9    *  even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 
10   *  See the GNU Lesser General Public License for more details at gnu.org.
11   */
12  
13  package com.eviware.soapui.impl.wsdl.panels.teststeps;
14  
15  import java.awt.BorderLayout;
16  import java.awt.Component;
17  import java.awt.Dimension;
18  import java.awt.event.ActionEvent;
19  import java.io.File;
20  import java.io.IOException;
21  
22  import javax.swing.AbstractAction;
23  import javax.swing.Action;
24  import javax.swing.Box;
25  import javax.swing.JButton;
26  import javax.swing.JComponent;
27  import javax.swing.JLabel;
28  import javax.swing.JScrollPane;
29  import javax.swing.JTable;
30  import javax.swing.JTextField;
31  import javax.swing.SwingUtilities;
32  import javax.swing.event.ListSelectionEvent;
33  import javax.swing.event.ListSelectionListener;
34  import javax.swing.table.AbstractTableModel;
35  import javax.swing.text.Document;
36  
37  import com.eviware.soapui.impl.wsdl.actions.support.ShowOnlineHelpAction;
38  import com.eviware.soapui.impl.wsdl.panels.support.TestRunComponentEnabler;
39  import com.eviware.soapui.impl.wsdl.support.HelpUrls;
40  import com.eviware.soapui.impl.wsdl.teststeps.WsdlPropertiesTestStep;
41  import com.eviware.soapui.impl.wsdl.teststeps.WsdlTestStepListenerAdapter;
42  import com.eviware.soapui.impl.wsdl.teststeps.WsdlPropertiesTestStep.StepProperty;
43  import com.eviware.soapui.model.ModelItem;
44  import com.eviware.soapui.model.testsuite.TestStepProperty;
45  import com.eviware.soapui.support.DocumentListenerAdapter;
46  import com.eviware.soapui.support.StringUtils;
47  import com.eviware.soapui.support.UISupport;
48  import com.eviware.soapui.support.components.JXToolBar;
49  import com.eviware.soapui.ui.support.ModelItemDesktopPanel;
50  
51  /***
52   * DesktopPanel for WsdlPropertiesTestSteps
53   * 
54   * @author Ole.Matzura
55   */
56  
57  public class PropertiesStepDesktopPanel extends ModelItemDesktopPanel<WsdlPropertiesTestStep>
58  {
59  	private final WsdlPropertiesTestStep testStep;
60  	private JTextField sourceField;
61  	private JTextField targetField;
62  	private PropertiesModel propertiesModel;
63  	private JTable propertiesTable;
64  	private RemovePropertyAction removePropertyAction;
65  	private TestRunComponentEnabler componentEnabler;
66  	private InternalWsdlTestStepListener wsdlTestStepListener;
67  
68  	public PropertiesStepDesktopPanel(WsdlPropertiesTestStep testStep)
69  	{
70  		super(testStep);
71  		this.testStep = testStep;
72  		componentEnabler = new TestRunComponentEnabler(testStep.getTestCase());
73  		buildUI();
74  
75  		wsdlTestStepListener = new InternalWsdlTestStepListener();
76  		testStep.addTestStepListener(wsdlTestStepListener);
77  	}
78  
79  	private void buildUI()
80  	{
81  		add(buildToolbar(), BorderLayout.NORTH);
82  		add(buildPropertiesTable(), BorderLayout.CENTER);
83  
84  		setPreferredSize(new Dimension(600, 400));
85  	}
86  
87  	private Component buildPropertiesTable()
88  	{
89  		propertiesModel = new PropertiesModel();
90  		propertiesTable = new JTable(propertiesModel);
91  		propertiesTable.setSurrendersFocusOnKeystroke( true );
92  
93  //		propertiesTable.setDragEnabled(true);
94  //		propertiesTable.setTransferHandler(new PropertiesTransferHandler( propertiesTable ));
95  
96  		propertiesTable.putClientProperty("terminateEditOnFocusLost", Boolean.TRUE);
97  		propertiesTable.getSelectionModel().addListSelectionListener(new ListSelectionListener()
98  		{
99  			public void valueChanged(ListSelectionEvent e)
100 			{
101 				removePropertyAction.setEnabled(propertiesTable.getSelectedRow() != -1);
102 			}
103 		});
104 
105 		componentEnabler.add(propertiesTable);
106 
107 		return new JScrollPane(propertiesTable);
108 	}
109 
110 	private JComponent buildToolbar()
111 	{
112 		JXToolBar toolbar = UISupport.createToolbar();
113 
114 		JButton addPropertyButton = UISupport.createToolbarButton(new AddPropertyAction());
115 		toolbar.add(addPropertyButton);
116 		removePropertyAction = new RemovePropertyAction();
117 		JButton removePropertyButton = UISupport.createToolbarButton(removePropertyAction);
118 		toolbar.add(removePropertyButton);
119 		JButton clearPropertiesButton = UISupport.createToolbarButton(new ClearPropertiesAction());
120 		toolbar.add(clearPropertiesButton);
121 
122 		toolbar.addRelatedGap();
123 		JButton reloadButton = UISupport.createToolbarButton(new ReloadPropertiesFromSourceAction());
124 		toolbar.add(reloadButton);
125 		
126 		toolbar.addSeparator();
127 		toolbar.add(new JLabel("Load from:"));
128 		sourceField = new JTextField(testStep.getSource(), 15);
129 		sourceField.setToolTipText("The filename/url or referring system-property to load properties from");
130 		sourceField.getDocument().addDocumentListener(new DocumentListenerAdapter()
131 		{
132 			public void update(Document document)
133 			{
134 				testStep.setSource(sourceField.getText());
135 
136 			}
137 		});
138 
139 		toolbar.addFixed(sourceField);
140 		JButton setSourceButton = UISupport.createToolbarButton(new SetPropertiesSourceAction());
141 		toolbar.add(setSourceButton);
142 
143 		toolbar.addSeparator();
144 		toolbar.add(new JLabel("Save to:"));
145 		targetField = new JTextField(testStep.getTarget(), 15);
146 		targetField.setToolTipText("The filename/url or referring system-property to save properties to");
147 		targetField.getDocument().addDocumentListener(new DocumentListenerAdapter()
148 		{
149 			public void update(Document document)
150 			{
151 				testStep.setTarget(targetField.getText());
152 
153 			}
154 		});
155 
156 		toolbar.addFixed(targetField);
157 		JButton setTargetButton = UISupport.createToolbarButton(new SetPropertiesTargetAction());
158 		toolbar.add(setTargetButton);
159 
160 		toolbar.add(Box.createHorizontalGlue());
161 		toolbar.addSeparator();
162 		toolbar.add(UISupport.createToolbarButton(new ShowOnlineHelpAction(HelpUrls.PROPERTIESSTEPEDITOR_HELP_URL)));
163 
164 		componentEnabler.add(sourceField);
165 		componentEnabler.add(targetField);
166 		componentEnabler.add(setTargetButton);
167 		componentEnabler.add(setSourceButton);
168 		componentEnabler.add(addPropertyButton);
169 		componentEnabler.add(removePropertyButton);
170 
171 		return toolbar;
172 	}
173 
174 	public boolean onClose(boolean canCancel)
175 	{
176 		if( propertiesTable.isEditing() )
177 			propertiesTable.getCellEditor().stopCellEditing();
178 		
179 		componentEnabler.release();
180 		testStep.removeTestStepListener(wsdlTestStepListener);
181 		super.release();
182 		return true;
183 	}
184 
185 	public JComponent getComponent()
186 	{
187 		return this;
188 	}
189 
190 	public boolean dependsOn(ModelItem modelItem)
191 	{
192 		return modelItem == testStep || modelItem == testStep.getTestCase()
193 				|| modelItem == testStep.getTestCase().getTestSuite()
194 				|| modelItem == testStep.getTestCase().getTestSuite().getProject();
195 	}
196 
197 	private final class InternalWsdlTestStepListener extends WsdlTestStepListenerAdapter
198 	{
199 		private boolean enabled = true;
200 
201 		public boolean isEnabled()
202 		{
203 			return enabled;
204 		}
205 
206 		public void setEnabled(boolean enabled)
207 		{
208 			this.enabled = enabled;
209 		}
210 
211 		public void propertyAdded(String name)
212 		{
213 			if (enabled)
214 				propertiesModel.fireTableDataChanged();
215 		}
216 
217 		public void propertyRemoved(String name)
218 		{
219 			if (enabled)
220 				propertiesModel.fireTableDataChanged();
221 		}
222 
223 		public void propertyRenamed(String oldName, String newName)
224 		{
225 			if (enabled)
226 				propertiesModel.fireTableDataChanged();
227 		}
228 
229 		public void propertyValueChanged(String name, String oldValue, String newValue)
230 		{
231 			if (enabled)
232 				propertiesModel.fireTableDataChanged();
233 		}
234 	}
235 
236 	private class PropertiesModel extends AbstractTableModel
237 	{
238 		public int getRowCount()
239 		{
240 			return testStep.getStepPropertyCount();
241 		}
242 
243 		public int getColumnCount()
244 		{
245 			return 2;
246 		}
247 
248 		public String getColumnName(int columnIndex)
249 		{
250 			switch (columnIndex)
251 			{
252 			case 0:
253 				return "Name";
254 			case 1:
255 				return "Value";
256 			}
257 
258 			return null;
259 		}
260 
261 		public boolean isCellEditable(int rowIndex, int columnIndex)
262 		{
263 			return true;
264 		}
265 
266 		public void setValueAt(Object aValue, int rowIndex, int columnIndex)
267 		{
268 			StepProperty property = testStep.getTestStepPropertyAt(rowIndex);
269 			switch (columnIndex)
270 			{
271 			case 0:
272 			{
273 				TestStepProperty prop = testStep.getProperty((String) aValue);
274 				if (prop != null && prop != property)
275 				{
276 					UISupport.showErrorMessage("Property name exists!");
277 					return;
278 				}
279 				wsdlTestStepListener.setEnabled(false);
280 				property.setName(aValue.toString());
281 				wsdlTestStepListener.setEnabled(true);
282 				break;
283 			}
284 			case 1:
285 			{
286 				wsdlTestStepListener.setEnabled(false);
287 				property.setValue(aValue.toString());
288 				wsdlTestStepListener.setEnabled(true);
289 				break;
290 			}
291 			}
292 		}
293 
294 		public Object getValueAt(int rowIndex, int columnIndex)
295 		{
296 			TestStepProperty property = testStep.getTestStepPropertyAt(rowIndex);
297 
298 			switch (columnIndex)
299 			{
300 			case 0:
301 				return property.getName();
302 			case 1:
303 				return property.getValue();
304 			}
305 
306 			return null;
307 		}
308 	}
309 
310 	private class AddPropertyAction extends AbstractAction
311 	{
312 		public AddPropertyAction()
313 		{
314 			putValue(Action.SMALL_ICON, UISupport.createImageIcon("/add_property.gif"));
315 			putValue(Action.SHORT_DESCRIPTION, "Adds a property to the property list");
316 		}
317 
318 		public void actionPerformed(ActionEvent e)
319 		{
320 			String name = UISupport.prompt("Specify property name", "Add Property", "");
321 			if (name != null)
322 			{
323 				wsdlTestStepListener.setEnabled(false);
324 				testStep.addProperty(name);
325 				wsdlTestStepListener.setEnabled(true);
326 				final int row = testStep.getStepPropertyCount() - 1;
327 				propertiesModel.fireTableRowsInserted(row, row);
328 				SwingUtilities.invokeLater( new Runnable()
329 				{
330 					public void run()
331 					{
332 						propertiesTable.requestFocusInWindow();
333 						propertiesTable.scrollRectToVisible( propertiesTable.getCellRect( row,1,true ) );
334 						SwingUtilities.invokeLater( new Runnable()
335 						{
336 							public void run()
337 							{
338 								propertiesTable.editCellAt(row, 1);
339 								propertiesTable.getEditorComponent().requestFocusInWindow();
340 							}
341 						} );
342 					}
343 				} );
344 				
345 			}
346 		}
347 	}
348 
349 	private class RemovePropertyAction extends AbstractAction
350 	{
351 		public RemovePropertyAction()
352 		{
353 			putValue(Action.SMALL_ICON, UISupport.createImageIcon("/remove_property.gif"));
354 			putValue(Action.SHORT_DESCRIPTION, "Removes the selected property from the property list");
355 			setEnabled(false);
356 		}
357 
358 		public void actionPerformed(ActionEvent e)
359 		{
360 			int row = propertiesTable.getSelectedRow();
361 			if (row == -1)
362 				return;
363 
364 			UISupport.stopCellEditing(propertiesTable);
365 
366 			if (UISupport.confirm("Remove property [" + propertiesModel.getValueAt(row, 0) + "]?", "Remove Property"))
367 			{
368 				wsdlTestStepListener.setEnabled(false);
369 				testStep.removePropertyAt(row);
370 				wsdlTestStepListener.setEnabled(true);
371 				propertiesModel.fireTableRowsDeleted(row, row);
372 			}
373 		}
374 	}
375 
376 	private class SetPropertiesSourceAction extends AbstractAction
377 	{
378 		public SetPropertiesSourceAction()
379 		{
380 			putValue(Action.SMALL_ICON, UISupport.createImageIcon("/set_properties_source.gif"));
381 			putValue(Action.SHORT_DESCRIPTION, "Selects the properties source file");
382 		}
383 
384 		public void actionPerformed(ActionEvent e)
385 		{
386 			File file = UISupport.getFileDialogs().open(this, "Set properties source", null, null, null);
387 			if (file != null)
388 			{
389 				testStep.setSource(file.getAbsolutePath());
390 				sourceField.setText(testStep.getSource());
391 				try
392 				{
393 					boolean createMissing = UISupport.confirm("Create missing properties?", "Set Properties Source");
394 					int cnt = testStep.loadProperties(createMissing);
395 					UISupport.showInfoMessage("Loaded " + cnt + " properties from [" + testStep.getSource() + "]");
396 				}
397 				catch (IOException e1)
398 				{
399 					UISupport.showErrorMessage("Failed to load properties from [" + testStep.getSource() + "]; " + e1);
400 				}
401 			}
402 		}
403 	}
404 	
405 	private class ReloadPropertiesFromSourceAction extends AbstractAction
406 	{
407 		public ReloadPropertiesFromSourceAction()
408 		{
409 			putValue(Action.SMALL_ICON, UISupport.createImageIcon("/reload_properties.gif"));
410 			putValue(Action.SHORT_DESCRIPTION, "Reloads the current properties from the selected file");
411 		}
412 
413 		public void actionPerformed(ActionEvent e)
414 		{
415 			if( StringUtils.isNullOrEmpty( testStep.getSource() ))
416 			{
417 				UISupport.showErrorMessage( "Missing source-file to load from" );
418 				return;
419 			}
420 			
421 			try
422 			{
423 				boolean createMissing = UISupport.confirm("Create missing properties?", "Reload Properties");
424 				int cnt = testStep.loadProperties(createMissing);
425 				UISupport.showInfoMessage("Loaded " + cnt + " properties from [" + testStep.getSource() + "]");
426 			}
427 			catch (Exception e1)
428 			{
429 				UISupport.showErrorMessage("Failed to load properties from [" + testStep.getSource() + "]; " + e1);
430 			}
431 		}
432 	}
433 	
434 	private class ClearPropertiesAction extends AbstractAction
435 	{
436 		public ClearPropertiesAction()
437 		{
438 			putValue(Action.SMALL_ICON, UISupport.createImageIcon("/clear_properties.gif"));
439 			putValue(Action.SHORT_DESCRIPTION, "Clears all current property values");
440 		}
441 
442 		public void actionPerformed(ActionEvent e)
443 		{
444 			if( UISupport.confirm("Clear all property values?", "Clear Properties"))
445 				testStep.clearPropertyValues();
446 		}
447 	}
448 
449 	private class SetPropertiesTargetAction extends AbstractAction
450 	{
451 		public SetPropertiesTargetAction()
452 		{
453 			putValue(Action.SMALL_ICON, UISupport.createImageIcon("/set_properties_target.gif"));
454 			putValue(Action.SHORT_DESCRIPTION, "Selects the properties target file");
455 		}
456 
457 		public void actionPerformed(ActionEvent e)
458 		{
459 			File file = UISupport.getFileDialogs().saveAs(this, "Set properties target");
460 			if (file != null)
461 			{
462 				testStep.setTarget(file.getAbsolutePath());
463 				targetField.setText(testStep.getTarget());
464 
465 				try
466 				{
467 					int cnt = testStep.saveProperties();
468 					UISupport.showInfoMessage("Saved " + cnt + " properties to [" + testStep.getTarget() + "]");
469 				}
470 				catch (IOException e1)
471 				{
472 					UISupport.showErrorMessage("Failed to save properties to [" + testStep.getTarget() + "]; " + e1);
473 				}
474 			}
475 		}
476 	}
477 
478 	/*
479 	public class PropertiesTransferHandler extends AbstractPropertiesTransferHandler
480 	{
481 		public PropertiesTransferHandler(JComponent component)
482 		{
483 			super(component);
484 		}
485 
486 		protected StepProperty getSelectedProperty(JComponent c)
487 		{
488 			int rowIndex = propertiesTable.getSelectedRow();
489 			if (rowIndex == -1)
490 				return null;
491 
492 			return testStep.getTestStepPropertyAt(rowIndex);
493 		}
494 	}*/
495 }