View Javadoc

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