View Javadoc

1   /*
2    *  soapUI, copyright (C) 2004-2009 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.mockoperation;
14  
15  import java.awt.BorderLayout;
16  import java.awt.Component;
17  import java.awt.Dimension;
18  import java.awt.event.ItemEvent;
19  import java.awt.event.ItemListener;
20  import java.beans.PropertyChangeEvent;
21  import java.beans.PropertyChangeListener;
22  import java.util.ArrayList;
23  import java.util.List;
24  
25  import javax.swing.AbstractListModel;
26  import javax.swing.BorderFactory;
27  import javax.swing.JComboBox;
28  import javax.swing.JComponent;
29  import javax.swing.JLabel;
30  import javax.swing.JList;
31  import javax.swing.JPanel;
32  import javax.swing.JScrollPane;
33  import javax.swing.JTabbedPane;
34  import javax.swing.ListCellRenderer;
35  import javax.swing.ListModel;
36  
37  import com.eviware.soapui.impl.support.actions.ShowOnlineHelpAction;
38  import com.eviware.soapui.impl.wsdl.WsdlInterface;
39  import com.eviware.soapui.impl.wsdl.WsdlOperation;
40  import com.eviware.soapui.impl.wsdl.actions.mockoperation.NewMockResponseAction;
41  import com.eviware.soapui.impl.wsdl.actions.mockoperation.OpenRequestForMockOperationAction;
42  import com.eviware.soapui.impl.wsdl.mock.WsdlMockOperation;
43  import com.eviware.soapui.impl.wsdl.mock.WsdlMockResponse;
44  import com.eviware.soapui.impl.wsdl.mock.dispatch.MockOperationDispatchRegistry;
45  import com.eviware.soapui.impl.wsdl.mock.dispatch.MockOperationDispatcher;
46  import com.eviware.soapui.impl.wsdl.support.HelpUrls;
47  import com.eviware.soapui.model.ModelItem;
48  import com.eviware.soapui.model.iface.Interface;
49  import com.eviware.soapui.model.iface.Operation;
50  import com.eviware.soapui.model.mock.MockOperation;
51  import com.eviware.soapui.model.mock.MockResponse;
52  import com.eviware.soapui.model.mock.MockServiceListener;
53  import com.eviware.soapui.model.support.InterfaceListenerAdapter;
54  import com.eviware.soapui.model.support.ModelSupport;
55  import com.eviware.soapui.model.support.ProjectListenerAdapter;
56  import com.eviware.soapui.model.util.ModelItemNames;
57  import com.eviware.soapui.support.UISupport;
58  import com.eviware.soapui.support.action.swing.ActionList;
59  import com.eviware.soapui.support.action.swing.ActionSupport;
60  import com.eviware.soapui.support.action.swing.DefaultActionList;
61  import com.eviware.soapui.support.action.swing.SwingActionDelegate;
62  import com.eviware.soapui.support.components.JComponentInspector;
63  import com.eviware.soapui.support.components.JInspectorPanel;
64  import com.eviware.soapui.support.components.JInspectorPanelFactory;
65  import com.eviware.soapui.support.components.JXToolBar;
66  import com.eviware.soapui.support.swing.ExtendedComboBoxModel;
67  import com.eviware.soapui.support.swing.ModelItemListKeyListener;
68  import com.eviware.soapui.support.swing.ModelItemListMouseListener;
69  import com.eviware.soapui.ui.support.ModelItemDesktopPanel;
70  import com.jgoodies.forms.builder.ButtonBarBuilder;
71  
72  /***
73   * DesktopPanel for WsdlGroovyTestSteps
74   * 
75   * @author Ole.Matzura
76   */
77  
78  public class WsdlMockOperationDesktopPanel extends ModelItemDesktopPanel<WsdlMockOperation>
79  {
80  	private JList responseList;
81  	private JComboBox interfaceCombo;
82  	private JComboBox operationCombo;
83  	private JComboBox dispatchCombo;
84  	private JPanel dispatchPanel;
85  	private InternalInterfaceListener interfaceListener = new InternalInterfaceListener();
86  	private InternalProjectListener projectListener = new InternalProjectListener();
87  	private WsdlInterface currentInterface;
88  	private JComboBox defaultResponseCombo;
89  	private ResponseListModel responseListModel;
90  	private JComponentInspector<JComponent> dispatchInspector;
91  	private JInspectorPanel inspectorPanel;
92  
93  	public WsdlMockOperationDesktopPanel( WsdlMockOperation mockOperation )
94  	{
95  		super( mockOperation );
96  
97  		buildUI();
98  		setPreferredSize( new Dimension( 600, 440 ) );
99  
100 		mockOperation.getMockService().getProject().addProjectListener( projectListener );
101 
102 		WsdlOperation operation = getModelItem().getOperation();
103 		if( operation != null )
104 		{
105 			currentInterface = operation.getInterface();
106 			currentInterface.addInterfaceListener( interfaceListener );
107 		}
108 	}
109 
110 	private void buildUI()
111 	{
112 		add( buildToolbar(), BorderLayout.NORTH );
113 
114 		inspectorPanel = JInspectorPanelFactory.build( buildResponseList() );
115 		inspectorPanel.setDefaultDividerLocation( 0.5F );
116 		dispatchInspector = new JComponentInspector<JComponent>( buildDispatchEditor(), "Dispatch ("
117 				+ getModelItem().getDispatchStyle().toString() + ")", "Configures current dispatch style", true );
118 		inspectorPanel.addInspector( dispatchInspector );
119 		inspectorPanel.activate( dispatchInspector );
120 
121 		add( inspectorPanel.getComponent(), BorderLayout.CENTER );
122 	}
123 
124 	private JComponent buildResponseList()
125 	{
126 		responseListModel = new ResponseListModel();
127 		responseList = new JList( responseListModel );
128 		responseList.addKeyListener( new ModelItemListKeyListener()
129 		{
130 			@Override
131 			public ModelItem getModelItemAt( int ix )
132 			{
133 				return getModelItem().getMockResponseAt( ix );
134 			}
135 		} );
136 
137 		responseList.addMouseListener( new ModelItemListMouseListener()
138 		{
139 
140 			private DefaultActionList defaultActions;
141 
142 			@Override
143 			protected ActionList getActionsForRow( JList list, int row )
144 			{
145 				ActionList actions = super.getActionsForRow( list, row );
146 
147 				actions.insertAction( SwingActionDelegate.createDelegate( NewMockResponseAction.SOAPUI_ACTION_ID,
148 						getModelItem(), null, "/addToMockService.gif" ), 0 );
149 
150 				actions.insertAction( SwingActionDelegate.createDelegate(
151 						OpenRequestForMockOperationAction.SOAPUI_ACTION_ID, getModelItem(), null, "/open_request.gif" ), 1 );
152 
153 				if( actions.getActionCount() > 2 )
154 					actions.insertAction( ActionSupport.SEPARATOR_ACTION, 2 );
155 
156 				return actions;
157 			}
158 
159 			@Override
160 			protected ActionList getDefaultActions()
161 			{
162 				if( defaultActions == null )
163 				{
164 					defaultActions = new DefaultActionList();
165 					defaultActions.addAction( SwingActionDelegate.createDelegate( NewMockResponseAction.SOAPUI_ACTION_ID,
166 							getModelItem(), null, "/addToMockService.gif" ) );
167 				}
168 
169 				return defaultActions;
170 			}
171 
172 		} );
173 		responseList.setCellRenderer( new ResponseListCellRenderer() );
174 
175 		JScrollPane scrollPane = new JScrollPane( responseList );
176 		JTabbedPane tabs = new JTabbedPane();
177 		tabs.addTab( "MockResponses", UISupport.buildPanelWithToolbar( buildMockResponseListToolbar(), scrollPane ) );
178 
179 		return UISupport.createTabPanel( tabs, true );
180 	}
181 
182 	private JComponent buildMockResponseListToolbar()
183 	{
184 		JXToolBar toolbar = UISupport.createToolbar();
185 		toolbar.add( UISupport.createToolbarButton( SwingActionDelegate.createDelegate(
186 				NewMockResponseAction.SOAPUI_ACTION_ID, getModelItem(), null, "/mockResponse.gif" ) ) );
187 
188 		return toolbar;
189 	}
190 
191 	private JComponent buildDispatchEditor()
192 	{
193 		dispatchPanel = new JPanel( new BorderLayout() );
194 		dispatchPanel.setOpaque( true );
195 		ButtonBarBuilder builder = new ButtonBarBuilder();
196 		builder.addFixed( new JLabel( "Dispatch: " ) );
197 		builder.addRelatedGap();
198 		dispatchCombo = new JComboBox( MockOperationDispatchRegistry.getDispatchTypes() );
199 		dispatchCombo.setSelectedItem( null );
200 
201 		dispatchCombo.addItemListener( new ItemListener()
202 		{
203 			public void itemStateChanged( ItemEvent e )
204 			{
205 				if( dispatchPanel.getComponentCount() > 1 )
206 					dispatchPanel.remove( 1 );
207 
208 				String item = ( String )dispatchCombo.getSelectedItem();
209 				MockOperationDispatcher dispatcher = getModelItem().setDispatchStyle( item );
210 
211 				dispatchPanel.add( dispatcher.buildEditorComponent(), BorderLayout.CENTER );
212 				dispatchPanel.revalidate();
213 				dispatchPanel.repaint();
214 
215 				if( dispatchInspector != null && item != null )
216 				{
217 					dispatchInspector.setTitle( "Dispatch (" + item + ")" );
218 				}
219 			}
220 		} );
221 
222 		builder.addFixed( dispatchCombo );
223 
224 		builder.addUnrelatedGap();
225 		builder.addFixed( new JLabel( "Default Response: " ) );
226 		builder.addRelatedGap();
227 
228 		ModelItemNames<MockResponse> names = new ModelItemNames<MockResponse>( getModelItem().getMockResponses() );
229 		defaultResponseCombo = new JComboBox( new ExtendedComboBoxModel( names.getNames() ) );
230 		defaultResponseCombo.setPreferredSize( new Dimension( 150, 20 ) );
231 		defaultResponseCombo.addItemListener( new ItemListener()
232 		{
233 			public void itemStateChanged( ItemEvent e )
234 			{
235 				Object selectedItem = defaultResponseCombo.getSelectedItem();
236 				getModelItem().setDefaultResponse( ( String )selectedItem );
237 			}
238 		} );
239 
240 		builder.addFixed( defaultResponseCombo );
241 		builder.setBorder( BorderFactory.createEmptyBorder( 2, 3, 3, 3 ) );
242 
243 		dispatchPanel.add( builder.getPanel(), BorderLayout.NORTH );
244 
245 		// init data
246 		defaultResponseCombo.setSelectedItem( getModelItem().getDefaultResponse() );
247 		dispatchCombo.setSelectedItem( getModelItem().getDispatchStyle() );
248 
249 		return dispatchPanel;
250 	}
251 
252 	private Component buildToolbar()
253 	{
254 		JXToolBar toolbar = UISupport.createToolbar();
255 		toolbar.addSpace( 3 );
256 
257 		toolbar.addFixed( UISupport.createToolbarButton( SwingActionDelegate.createDelegate(
258 				NewMockResponseAction.SOAPUI_ACTION_ID, getModelItem(), null, "/addToMockService.gif" ) ) );
259 		toolbar.addFixed( UISupport.createToolbarButton( SwingActionDelegate.createDelegate(
260 				OpenRequestForMockOperationAction.SOAPUI_ACTION_ID, getModelItem(), null, "/open_request.gif" ) ) );
261 		toolbar.addUnrelatedGap();
262 
263 		ModelItemNames<WsdlInterface> names = new ModelItemNames<WsdlInterface>( ModelSupport.getChildren( getModelItem()
264 				.getMockService().getProject(), WsdlInterface.class ) );
265 
266 		interfaceCombo = new JComboBox( names.getNames() );
267 		interfaceCombo.setSelectedIndex( -1 );
268 		interfaceCombo.addItemListener( new InterfaceComboListener() );
269 
270 		toolbar.addLabeledFixed( "Interface", interfaceCombo );
271 		toolbar.addUnrelatedGap();
272 		operationCombo = new JComboBox( new ExtendedComboBoxModel() );
273 		operationCombo.setPreferredSize( new Dimension( 150, 20 ) );
274 		operationCombo.addItemListener( new OperationComboListener() );
275 
276 		toolbar.addLabeledFixed( "Operation", operationCombo );
277 
278 		WsdlOperation operation = getModelItem().getOperation();
279 		interfaceCombo.setSelectedItem( operation == null ? null : operation.getInterface().getName() );
280 		operationCombo.setSelectedItem( operation == null ? null : operation.getName() );
281 
282 		toolbar.addGlue();
283 		toolbar.addFixed( createActionButton( new ShowOnlineHelpAction( HelpUrls.MOCKOPERATION_HELP_URL ), true ) );
284 
285 		return toolbar;
286 	}
287 
288 	public boolean onClose( boolean canCancel )
289 	{
290 		if( currentInterface != null )
291 			currentInterface.removeInterfaceListener( interfaceListener );
292 
293 		getModelItem().getMockService().getProject().removeProjectListener( projectListener );
294 		responseListModel.release();
295 
296 		inspectorPanel.release();
297 		return release();
298 	}
299 
300 	public boolean dependsOn( ModelItem modelItem )
301 	{
302 		return modelItem == getModelItem() || modelItem == getModelItem().getMockService()
303 				|| modelItem == getModelItem().getMockService().getProject();
304 	}
305 
306 	private final class OperationComboListener implements ItemListener
307 	{
308 		public void itemStateChanged( ItemEvent e )
309 		{
310 			WsdlInterface iface = ( WsdlInterface )getModelItem().getMockService().getProject().getInterfaceByName(
311 					interfaceCombo.getSelectedItem().toString() );
312 			WsdlOperation operation = iface.getOperationByName( operationCombo.getSelectedItem().toString() );
313 			getModelItem().setOperation( operation );
314 		}
315 	}
316 
317 	private final class InterfaceComboListener implements ItemListener
318 	{
319 		public void itemStateChanged( ItemEvent e )
320 		{
321 			if( currentInterface != null )
322 			{
323 				currentInterface.removeInterfaceListener( interfaceListener );
324 			}
325 
326 			Object selectedItem = interfaceCombo.getSelectedItem();
327 			if( selectedItem == null )
328 			{
329 				operationCombo.setModel( new ExtendedComboBoxModel() );
330 				currentInterface = null;
331 			}
332 			else
333 			{
334 				currentInterface = ( WsdlInterface )getModelItem().getMockService().getProject().getInterfaceByName(
335 						selectedItem.toString() );
336 				ModelItemNames<Operation> names = new ModelItemNames<Operation>( currentInterface.getOperationList() );
337 				operationCombo.setModel( new ExtendedComboBoxModel( names.getNames() ) );
338 
339 				currentInterface.addInterfaceListener( interfaceListener );
340 			}
341 		}
342 	}
343 
344 	private final class InternalProjectListener extends ProjectListenerAdapter
345 	{
346 		@Override
347 		public void interfaceAdded( Interface iface )
348 		{
349 			interfaceCombo.addItem( iface.getName() );
350 		}
351 
352 		@Override
353 		public void interfaceRemoved( Interface iface )
354 		{
355 			if( interfaceCombo.getSelectedItem().equals( iface.getName() ) )
356 			{
357 				getModelItem().setOperation( null );
358 			}
359 		}
360 	}
361 
362 	private final class InternalInterfaceListener extends InterfaceListenerAdapter
363 	{
364 		@Override
365 		public void operationAdded( Operation operation )
366 		{
367 			operationCombo.addItem( operation.getName() );
368 		}
369 
370 		@Override
371 		public void operationRemoved( Operation operation )
372 		{
373 			Object selectedItem = operationCombo.getSelectedItem();
374 			operationCombo.removeItem( operation.getName() );
375 
376 			if( selectedItem.equals( operation.getName() ) )
377 			{
378 				getModelItem().setOperation( null );
379 				interfaceCombo.setSelectedIndex( -1 );
380 			}
381 		}
382 
383 		@Override
384 		public void operationUpdated( Operation operation )
385 		{
386 			ExtendedComboBoxModel model = ( ( ExtendedComboBoxModel )operationCombo.getModel() );
387 			int ix = model.getIndexOf( operation.getName() );
388 			if( ix != -1 )
389 			{
390 				model.setElementAt( operation.getName(), ix );
391 			}
392 		}
393 	}
394 
395 	public class ResponseListModel extends AbstractListModel implements ListModel, MockServiceListener,
396 			PropertyChangeListener
397 	{
398 		private List<WsdlMockResponse> responses = new ArrayList<WsdlMockResponse>();
399 
400 		public ResponseListModel()
401 		{
402 			for( int c = 0; c < getModelItem().getMockResponseCount(); c++ )
403 			{
404 				WsdlMockResponse mockResponse = ( WsdlMockResponse )getModelItem().getMockResponseAt( c );
405 				mockResponse.addPropertyChangeListener( this );
406 
407 				responses.add( mockResponse );
408 			}
409 
410 			getModelItem().getMockService().addMockServiceListener( this );
411 		}
412 
413 		public Object getElementAt( int arg0 )
414 		{
415 			return responses.get( arg0 );
416 		}
417 
418 		public int getSize()
419 		{
420 			return responses.size();
421 		}
422 
423 		public void mockOperationAdded( MockOperation operation )
424 		{
425 
426 		}
427 
428 		public void mockOperationRemoved( MockOperation operation )
429 		{
430 
431 		}
432 
433 		public void mockResponseAdded( MockResponse response )
434 		{
435 			if( response.getMockOperation() != getModelItem() )
436 				return;
437 
438 			responses.add( ( WsdlMockResponse )response );
439 			response.addPropertyChangeListener( this );
440 			fireIntervalAdded( this, responses.size() - 1, responses.size() - 1 );
441 
442 			defaultResponseCombo.addItem( response.getName() );
443 		}
444 
445 		public void mockResponseRemoved( MockResponse response )
446 		{
447 			if( response.getMockOperation() != getModelItem() )
448 				return;
449 
450 			int ix = responses.indexOf( response );
451 			responses.remove( ix );
452 			response.removePropertyChangeListener( this );
453 			fireIntervalRemoved( this, ix, ix );
454 
455 			defaultResponseCombo.removeItem( response.getName() );
456 		}
457 
458 		public void propertyChange( PropertyChangeEvent arg0 )
459 		{
460 			if( arg0.getPropertyName().equals( WsdlMockOperation.NAME_PROPERTY ) )
461 			{
462 				int ix = responses.indexOf( arg0.getSource() );
463 				fireContentsChanged( this, ix, ix );
464 
465 				ExtendedComboBoxModel model = ( ExtendedComboBoxModel )defaultResponseCombo.getModel();
466 				model.setElementAt( arg0.getNewValue(), ix );
467 
468 				if( model.getSelectedItem().equals( arg0.getOldValue() ) )
469 					model.setSelectedItem( arg0.getNewValue() );
470 			}
471 		}
472 
473 		public void release()
474 		{
475 			for( WsdlMockResponse operation : responses )
476 			{
477 				operation.removePropertyChangeListener( this );
478 			}
479 
480 			getModelItem().getMockService().removeMockServiceListener( this );
481 		}
482 	}
483 
484 	private final static class ResponseListCellRenderer extends JLabel implements ListCellRenderer
485 	{
486 		public Component getListCellRendererComponent( JList list, Object value, int index, boolean isSelected,
487 				boolean cellHasFocus )
488 		{
489 			MockResponse testStep = ( MockResponse )value;
490 			setText( testStep.getName() );
491 			setIcon( testStep.getIcon() );
492 
493 			if( isSelected )
494 			{
495 				setBackground( list.getSelectionBackground() );
496 				setForeground( list.getSelectionForeground() );
497 			}
498 			else
499 			{
500 				setBackground( list.getBackground() );
501 				setForeground( list.getForeground() );
502 			}
503 
504 			setEnabled( list.isEnabled() );
505 			setFont( list.getFont() );
506 			setOpaque( true );
507 			setBorder( BorderFactory.createEmptyBorder( 3, 3, 3, 3 ) );
508 
509 			return this;
510 		}
511 	}
512 
513 }