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.project;
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.security.Provider;
21  import java.security.Security;
22  import java.util.List;
23  
24  import javax.swing.AbstractAction;
25  import javax.swing.DefaultCellEditor;
26  import javax.swing.JButton;
27  import javax.swing.JComboBox;
28  import javax.swing.JComponent;
29  import javax.swing.JPanel;
30  import javax.swing.JScrollPane;
31  import javax.swing.JSplitPane;
32  import javax.swing.JTabbedPane;
33  import javax.swing.event.ChangeEvent;
34  import javax.swing.event.ChangeListener;
35  import javax.swing.event.ListSelectionEvent;
36  import javax.swing.event.ListSelectionListener;
37  import javax.swing.table.AbstractTableModel;
38  
39  import org.jdesktop.swingx.JXTable;
40  
41  import com.eviware.soapui.SoapUI;
42  import com.eviware.soapui.impl.WorkspaceImpl;
43  import com.eviware.soapui.impl.wsdl.WsdlProject;
44  import com.eviware.soapui.impl.wsdl.actions.support.ShowOnlineHelpAction;
45  import com.eviware.soapui.impl.wsdl.support.HelpUrls;
46  import com.eviware.soapui.impl.wsdl.support.wss.IncomingWss;
47  import com.eviware.soapui.impl.wsdl.support.wss.OutgoingWss;
48  import com.eviware.soapui.impl.wsdl.support.wss.WssContainer;
49  import com.eviware.soapui.impl.wsdl.support.wss.WssContainerListener;
50  import com.eviware.soapui.impl.wsdl.support.wss.WssCrypto;
51  import com.eviware.soapui.impl.wsdl.support.wss.WssEntry;
52  import com.eviware.soapui.impl.wsdl.support.wss.WssEntryRegistry;
53  import com.eviware.soapui.impl.wsdl.support.wss.crypto.KeyMaterialWssCrypto;
54  import com.eviware.soapui.impl.wsdl.support.wss.support.KeystoresComboBoxModel;
55  import com.eviware.soapui.model.support.ModelSupport;
56  import com.eviware.soapui.support.StringUtils;
57  import com.eviware.soapui.support.UISupport;
58  import com.eviware.soapui.support.components.JXToolBar;
59  import com.eviware.soapui.support.types.StringList;
60  
61  public class WSSTabPanel extends JPanel
62  {
63  	private JXTable cryptosTable;
64  	private RemoveCryptoAction removeCryptoAction;
65  	private RemoveIncomingWssAction removeIncomingWssAction;
66  	private JXTable incomingWssTable;
67  	private JComboBox incomingWssDecryptionCryptoComboBox;
68  	private JComboBox incomingWssSignatureCryptoComboBox;
69  	private JXTable outgoingWssTable;
70  	private RemoveOutgoingWssAction removeOutgoingWssAction;
71  //	private JPanel entriesConfigPanel;
72  	private JButton removeOutgoingEntryButton;
73  //	private JList entryList;
74  //	private WssEntriesListModel entriesModel;
75  	private WssEntry selectedEntry;
76  	private OutgoingWss selectedOutgoing;
77  	private JButton addOutgoingEntryButton;
78  	private final WssContainer wssContainer;
79  	private InternalWssContainerListener wssContainerListener;
80  	private JTabbedPane entriesTabs;
81  
82  	public WSSTabPanel( WssContainer wssContainer )
83  	{
84  		super( new BorderLayout() );
85  		this.wssContainer = wssContainer;
86  		
87  		wssContainerListener = new InternalWssContainerListener();
88  		wssContainer.addWssContainerListener( wssContainerListener );
89  
90  		buildUI();
91  	}
92  
93  	private void buildUI()
94  	{
95  		add( buildMainToolbar(), BorderLayout.NORTH );
96  		add( buildContent(), BorderLayout.CENTER );
97  	}
98  
99  	private JComponent buildContent()
100 	{
101 		JTabbedPane tabs = new JTabbedPane();
102 		tabs.addTab( "Outgoing Configurations", buildOutgoingConfigurationsTab() );
103 		tabs.addTab( "Incoming Configurations", buildIncomingConfigurationsTab() );
104 		tabs.addTab( "Keystores / Certificates", buildCryptosTable() );
105 		
106 		tabs.setMinimumSize( new Dimension( 10, 10 ) );
107 		
108 		return UISupport.createTabPanel( tabs, true );
109 	}
110 
111 	private JPanel buildIncomingConfigurationsTab()
112 	{
113 		JPanel panel = new JPanel( new BorderLayout() );
114 		
115 		JPanel p = new JPanel( new BorderLayout() );
116 		p.add( buildIncomingWssToolbar(), BorderLayout.NORTH );
117 
118 		incomingWssTable = new JXTable( new IncomingWssTableModel() );
119 		incomingWssTable.setSortable( false );
120 		incomingWssTable.getSelectionModel().addListSelectionListener( new ListSelectionListener() {
121 
122 			public void valueChanged( ListSelectionEvent e )
123 			{
124 				removeIncomingWssAction.setEnabled( incomingWssTable.getSelectedRow() != -1 );
125 			}} );
126 		
127 		incomingWssDecryptionCryptoComboBox = new JComboBox( new KeystoresComboBoxModel( wssContainer, null ));
128 		incomingWssTable.getColumn( 1 ).setCellEditor( new DefaultCellEditor( incomingWssDecryptionCryptoComboBox ) );
129 		
130 		incomingWssSignatureCryptoComboBox = new JComboBox( new KeystoresComboBoxModel( wssContainer, null ) );
131 		incomingWssTable.getColumn( 2 ).setCellEditor( new DefaultCellEditor( incomingWssSignatureCryptoComboBox ) );
132 		
133 		p.add( new JScrollPane( incomingWssTable ), BorderLayout.CENTER );
134 		panel.add( p, BorderLayout.CENTER );
135 		return panel;
136 	}
137 
138 	private JPanel buildOutgoingConfigurationsTab()
139 	{
140 		JPanel panel = new JPanel( new BorderLayout() );
141 		
142 		JPanel p = new JPanel( new BorderLayout() );
143 		p.add( buildOutgoingWssToolbar(), BorderLayout.NORTH );
144 
145 		outgoingWssTable = new JXTable( new OutgoingWssTableModel() );
146 		outgoingWssTable.setSortable( false );
147 		outgoingWssTable.getSelectionModel().addListSelectionListener( new ListSelectionListener() {
148 
149 			public void valueChanged( ListSelectionEvent e )
150 			{
151 				int selectedRow = outgoingWssTable.getSelectedRow();
152 				selectedOutgoing = selectedRow == -1 ? null : wssContainer.getOutgoingWssAt( selectedRow );
153 				removeOutgoingWssAction.setEnabled( selectedRow != -1 );
154 				addOutgoingEntryButton.setEnabled( selectedRow != -1 );
155 //				entriesModel.setOutgoingWss( selectedOutgoing );
156 				
157 				entriesTabs.removeAll();
158 				if( selectedOutgoing != null )
159 				{
160 					for( WssEntry entry : selectedOutgoing.getEntries())
161 					{
162 						entriesTabs.addTab( entry.getLabel(), entry.getConfigurationPanel() );
163 					}
164 				}
165 				
166 				entriesTabs.getParent().setVisible( entriesTabs.getTabCount() > 0 );
167 			}} );
168 		
169 		JSplitPane split = UISupport.createVerticalSplit( new JScrollPane( outgoingWssTable ), buildOutgoingWssDetails() );
170 		split.setDividerLocation( 140 );
171 		p.add( split, BorderLayout.CENTER );
172 		panel.add( p, BorderLayout.CENTER );
173 		return panel;
174 	}
175 
176 	private Component buildOutgoingWssDetails()
177 	{
178 		JPanel panel = new JPanel( new BorderLayout() );
179 		panel.add( buildOutgoingEntriesToolbar(), BorderLayout.NORTH );
180 		panel.add( buildOutgoingEntryList(), BorderLayout.CENTER );
181 		
182 		entriesTabs.getParent().setVisible( false );
183 		
184 //		JSplitPane split = UISupport.createHorizontalSplit( buildOutgoingEntryList(), buildOutgoingEntryConfigPanel() );
185 //		split.setDividerLocation( 150 );
186 //
187 //		panel.add( split, BorderLayout.CENTER );
188 
189 		return panel;
190 	}
191 
192 //	private Component buildOutgoingEntryConfigPanel()
193 //	{
194 //		entriesConfigPanel = new JPanel( new BorderLayout() );
195 //		entriesConfigPanel.setBorder( BorderFactory.createEmptyBorder( 5, 5, 5, 5 ) );
196 //		JScrollPane scrollPane = new JScrollPane( entriesConfigPanel );
197 //		scrollPane.setBorder( null );
198 //		return scrollPane;
199 //	}
200 
201 	private Component buildOutgoingEntryList()
202 	{
203 //		entriesModel = new WssEntriesListModel();
204 //		entryList = new JList( entriesModel );
205 //		entryList.setSelectionMode( ListSelectionModel.SINGLE_SELECTION );
206 //		entryList.addListSelectionListener( new ListSelectionListener()
207 //		{
208 //			public void valueChanged( ListSelectionEvent e )
209 //			{
210 //				int index = entryList.getSelectedIndex();
211 //				setSelectedEntry( index == -1 ? null : ( ( WssEntry ) entriesModel.getElementAt( index ) ) );
212 //			}
213 //		} );
214 //		
215 		entriesTabs = new JTabbedPane();
216 		entriesTabs.addChangeListener( new ChangeListener() {
217 
218 			public void stateChanged( ChangeEvent e )
219 			{
220 				selectedEntry = entriesTabs.getSelectedIndex() == -1 ? null : 
221 					selectedOutgoing.getEntries().get( entriesTabs.getSelectedIndex() );
222 				removeOutgoingEntryButton.setEnabled( selectedEntry != null );
223 			}} );
224 		
225 		//return new JScrollPane( entryList );
226 		return UISupport.createTabPanel( entriesTabs, true );
227 	}
228 	
229 //	protected void setSelectedEntry( WssEntry entry )
230 //	{
231 //		this.selectedEntry = entry;
232 //		entriesConfigPanel.removeAll();
233 //
234 //		if( entry != null )
235 //		{
236 //			entriesConfigPanel.add( selectedEntry.getConfigurationPanel(), BorderLayout.CENTER );
237 //		}
238 //
239 //		removeOutgoingEntryButton.setEnabled( entry != null );
240 //
241 //		entriesConfigPanel.revalidate();
242 //		entriesConfigPanel.repaint();
243 //	}
244 	
245 	private Component buildOutgoingEntriesToolbar()
246 	{
247 		JXToolBar toolbar = UISupport.createSmallToolbar();
248 
249 		toolbar.addFixed( addOutgoingEntryButton = UISupport.createToolbarButton( new AddOutgoingEntryAction() ) );
250 		toolbar.addFixed( removeOutgoingEntryButton = UISupport.createToolbarButton( new RemoveOutgoingEntryAction(), false ) );
251 
252 		return toolbar;
253 	}
254 	
255 	private Component buildOutgoingWssToolbar()
256 	{
257 		JXToolBar toolbar = UISupport.createSmallToolbar();
258 		
259 		toolbar.addFixed( UISupport.createToolbarButton( new AddOutgoingWssAction() ));
260 		removeOutgoingWssAction = new RemoveOutgoingWssAction();
261 		toolbar.addFixed( UISupport.createToolbarButton( removeOutgoingWssAction ));
262 		toolbar.addGlue();
263 		toolbar.addFixed( UISupport.createToolbarButton( new ShowOnlineHelpAction(HelpUrls.OUTGOINGWSS_HELP_URL)));
264 		
265 		return toolbar;
266 	}
267 
268 	private JPanel buildCryptosTable()
269 	{
270 		JPanel panel = new JPanel( new BorderLayout() );
271 		JPanel p = new JPanel( new BorderLayout() );
272 		
273 		p.add( buildCryptosToolbar(), BorderLayout.NORTH );
274 
275 		cryptosTable = new JXTable( new CryptosTableModel() );
276 		cryptosTable.setSortable( false );
277 		cryptosTable.getSelectionModel().addListSelectionListener( new ListSelectionListener() {
278 
279 			public void valueChanged( ListSelectionEvent e )
280 			{
281 				removeCryptoAction.setEnabled( cryptosTable.getSelectedRow() != -1 );
282 			}} );
283 		
284 		StringList providers = new StringList();
285 		providers.add( "<Default>" );
286 		for( Provider provider : Security.getProviders())
287 		{
288 			providers.add( provider.getName() );
289 		}
290 		
291 		JComboBox comboBox = new JComboBox( providers.toArray() );
292 		cryptosTable.getColumn( 5 ).setCellEditor( new DefaultCellEditor( comboBox ) );
293 		
294 		p.add( new JScrollPane( cryptosTable ), BorderLayout.CENTER );
295 		
296 		panel.add( p, BorderLayout.CENTER );
297 		return panel;
298 	}
299 
300 	private Component buildCryptosToolbar()
301 	{
302 		JXToolBar toolbar = UISupport.createSmallToolbar();
303 		
304 		toolbar.addFixed( UISupport.createToolbarButton( new AddCryptoAction() ));
305 		removeCryptoAction = new RemoveCryptoAction();
306 		toolbar.addFixed( UISupport.createToolbarButton( removeCryptoAction ));
307 		toolbar.addGlue();
308 		toolbar.addFixed( UISupport.createToolbarButton( new ShowOnlineHelpAction(HelpUrls.CRYPTOSWSS_HELP_URL)));
309 		return toolbar;
310 	}
311 	
312 	private Component buildIncomingWssToolbar()
313 	{
314 		JXToolBar toolbar = UISupport.createSmallToolbar();
315 		
316 		toolbar.addFixed( UISupport.createToolbarButton( new AddIncomingWssAction() ));
317 		removeIncomingWssAction = new RemoveIncomingWssAction();
318 		toolbar.addFixed( UISupport.createToolbarButton( removeIncomingWssAction ));
319 		
320 		toolbar.addGlue();
321 		toolbar.addFixed( UISupport.createToolbarButton( new ShowOnlineHelpAction(HelpUrls.INCOMINGWSS_HELP_URL)));
322 		
323 		return toolbar;
324 	}
325 
326 	private Component buildMainToolbar()
327 	{
328 		JXToolBar toolbar = UISupport.createSmallToolbar();
329 //		toolbar.addFixed( UISupport.createToolbarButton( new ImportWssSettingsAction() ));
330 		toolbar.addGlue();
331 		toolbar.addFixed( UISupport.createToolbarButton( new ShowOnlineHelpAction(HelpUrls.WSS_HELP_URL)));
332 		return toolbar;
333 	}
334 
335 	public void release()
336 	{
337 		wssContainer.removeWssContainerListener( wssContainerListener );
338 		
339 		((IncomingWssTableModel)incomingWssTable.getModel()).release();
340 		((OutgoingWssTableModel)outgoingWssTable.getModel()).release();
341 		((CryptosTableModel)cryptosTable.getModel()).release();
342 		
343 		((KeystoresComboBoxModel)incomingWssDecryptionCryptoComboBox.getModel()).release();
344 		((KeystoresComboBoxModel)incomingWssSignatureCryptoComboBox.getModel()).release();
345 		
346 		entriesTabs.removeAll();
347 	}
348 
349 	public class CryptosTableModel extends AbstractTableModel 
350 	{
351 		private static final String DEFAULT_OPTION = "<Default>";
352 		private List<WssCrypto> cryptos;
353 
354 		public CryptosTableModel()
355 		{
356 			cryptos = wssContainer.getCryptoList();
357 		}
358 
359 		public void release()
360 		{
361 			cryptos = null;
362 		}
363 
364 		public int getColumnCount()
365 		{
366 			return 6;
367 		}
368 
369 		@Override
370 		public String getColumnName( int column )
371 		{
372 			switch( column )
373 			{
374 			case 0:
375 				return "Source";
376 			case 1:
377 				return "Status";
378 			case 2:
379 				return "Password";
380 			case 3:
381 				return "Default Alias";
382 			case 4:
383 				return "Alias Password";
384 			case 5:
385 				return "Security Provider";
386 			}
387 
388 			return null;
389 		}
390 
391 		public int getRowCount()
392 		{
393 			return cryptos == null ? null : cryptos.size();
394 		}
395 		
396 		@Override
397 		public boolean isCellEditable( int rowIndex, int columnIndex )
398 		{
399 			return columnIndex > 1;
400 		}
401 
402 		public Object getValueAt( int rowIndex, int columnIndex )
403 		{
404 			KeyMaterialWssCrypto crypto = ( KeyMaterialWssCrypto ) cryptos.get( rowIndex );
405 
406 			switch( columnIndex )
407 			{
408 			case 0:
409 				return crypto.getSource();
410 			case 1:
411 				return crypto.getStatus();
412 			case 2:
413 				return crypto.getPassword();
414 			case 3:
415 				return crypto.getDefaultAlias();
416 			case 4:
417 				return crypto.getAliasPassword();
418 			case 5:
419 				return StringUtils.hasContent( crypto.getCryptoProvider() ) ? crypto.getCryptoProvider() : DEFAULT_OPTION;
420 			}
421 
422 			return null;
423 		}
424 		
425 		@Override
426 		public void setValueAt( Object aValue, int rowIndex, int columnIndex )
427 		{
428 			KeyMaterialWssCrypto crypto = ( KeyMaterialWssCrypto ) cryptos.get( rowIndex );
429 			if( aValue == null || aValue.equals( DEFAULT_OPTION ) )
430 				aValue = "";
431 
432 			switch( columnIndex )
433 			{
434 			case 2:
435 				crypto.setPassword( aValue.toString() ); break;
436 			case 3:
437 				crypto.setDefaultAlias( aValue.toString() ); break;
438 			case 4:
439 				crypto.setAliasPassword( aValue.toString() ); break;
440 			case 5:
441 				crypto.setCryptoProvider( aValue.toString() ); break;
442 			}
443 		}
444 
445 		public void cryptoAdded( WssCrypto crypto )
446 		{
447 			cryptos.add( crypto );
448 			fireTableRowsInserted( cryptos.size()-1, cryptos.size()-1 );
449 		}
450 
451 		public void cryptoRemoved( WssCrypto crypto )
452 		{
453 			int ix = cryptos.indexOf( crypto );
454 			if( ix != -1 )
455 			{
456 				cryptos.remove( ix );
457 				fireTableRowsDeleted( ix, ix );
458 			}
459 		}
460 	}
461 
462 	private class AddCryptoAction extends AbstractAction
463 	{
464 		public AddCryptoAction()
465 		{
466 			putValue( SMALL_ICON, UISupport.createImageIcon( "/add_property.gif" ));
467 			putValue( SHORT_DESCRIPTION, "Adds a new crypto to this configuration" );
468 		}
469 
470 		public void actionPerformed( ActionEvent e )
471 		{
472 			File file = UISupport.getFileDialogs().open( this, "Select Key Material", null, null, null );
473 			if( file != null )
474 			{
475 				String password = UISupport.prompt( "Specify password for [" + file.getName() + "]", "Add Key Material", "" );
476 				wssContainer.addCrypto( file.getAbsolutePath(), password );
477 				cryptosTable.setRowSelectionInterval( cryptosTable.getRowCount()-1, cryptosTable.getRowCount()-1 );
478 			}
479 		}
480 	}
481 	
482 	private class RemoveCryptoAction extends AbstractAction
483 	{
484 		public RemoveCryptoAction()
485 		{
486 			putValue( SMALL_ICON, UISupport.createImageIcon( "/remove_property.gif" ));
487 			putValue( SHORT_DESCRIPTION, "Removes the selected crypto from this configuration" );
488 			
489 			setEnabled( false );
490 		}
491 
492 		public void actionPerformed( ActionEvent e )
493 		{
494 			int row = cryptosTable.getSelectedRow();
495 			if( row == -1 )
496 				return;
497 			
498 			if( UISupport.confirm( "Removes selected crypto?", "Remove Crypto" ))
499 			{
500 				wssContainer.removeCryptoAt( row );
501 			}
502 		}
503 	}
504 	
505 	public class IncomingWssTableModel extends AbstractTableModel 
506 	{
507 		private List<IncomingWss> incomingWss;
508 
509 		public IncomingWssTableModel()
510 		{
511 			incomingWss = wssContainer.getIncomingWssList();
512 		}
513 
514 		public void release()
515 		{
516 			incomingWss = null;
517 		}
518 
519 		public int getColumnCount()
520 		{
521 			return 4;
522 		}
523 
524 		@Override
525 		public String getColumnName( int column )
526 		{
527 			switch( column )
528 			{
529 			case 0:
530 				return "Name";
531 			case 1:
532 				return "Decrypt Keystore";
533 			case 2:
534 				return "Signature Keystore";
535 			case 3:
536 				return "Password";
537 			}
538 
539 			return null;
540 		}
541 
542 		public int getRowCount()
543 		{
544 			return incomingWss == null ? 0 : incomingWss.size();
545 		}
546 		
547 		@Override
548 		public boolean isCellEditable( int rowIndex, int columnIndex )
549 		{
550 			return columnIndex > 0;
551 		}
552 
553 		public Object getValueAt( int rowIndex, int columnIndex )
554 		{
555 			IncomingWss incoming =  incomingWss.get( rowIndex );
556 
557 			switch( columnIndex )
558 			{
559 			case 0:
560 				return incoming.getName();
561 			case 1:
562 				return wssContainer.getCryptoByName( incoming.getDecryptCrypto() );
563 			case 2:
564 				return wssContainer.getCryptoByName( incoming.getSignatureCrypto() );
565 			case 3:
566 				return incoming.getDecryptPassword();
567 			}
568 
569 			return null;
570 		}
571 		
572 		@Override
573 		public void setValueAt( Object aValue, int rowIndex, int columnIndex )
574 		{
575 			IncomingWss incoming =  incomingWss.get( rowIndex );
576 
577 			switch( columnIndex )
578 			{
579 			case 1:
580 				incoming.setDecryptCrypto( aValue == null ? null : aValue.toString() ); break;
581 			case 2:
582 				incoming.setSignatureCrypto( aValue == null ? null : aValue.toString() ); break;
583 			case 3:
584 				incoming.setDecryptPassword( aValue == null ? null : aValue.toString() ); break;
585 			}
586 		}
587 
588 		public void incomingWssAdded( IncomingWss incoming )
589 		{
590 			incomingWss.add( incoming );
591 			fireTableRowsInserted( incomingWss.size()-1, incomingWss.size()-1 );
592 			
593 		}
594 
595 		public void incomingWssRemoved( IncomingWss incoming )
596 		{
597 			int ix = incomingWss.indexOf( incoming );
598 			if( ix != -1 )
599 			{
600 				incomingWss.remove( ix );
601 				fireTableRowsDeleted( ix, ix );
602 			}
603 		}
604 	}
605 
606 	private class AddIncomingWssAction extends AbstractAction
607 	{
608 		public AddIncomingWssAction()
609 		{
610 			putValue( SMALL_ICON, UISupport.createImageIcon( "/add_property.gif" ));
611 			putValue( SHORT_DESCRIPTION, "Adds a new Incoming WSS Configuration" );
612 		}
613 
614 		public void actionPerformed( ActionEvent e )
615 		{
616 			String name = UISupport.prompt( "Specify unique name for configuration", "New Incoming WSS Configuration", "" );
617 			if( StringUtils.hasContent( name ) && wssContainer.getIncomingWssByName( name ) == null )
618 			{
619 				wssContainer.addIncomingWss( name );
620 				incomingWssTable.setRowSelectionInterval( incomingWssTable.getRowCount()-1, incomingWssTable.getRowCount()-1 );
621 			}
622 		}
623 	}
624 	
625 	private class RemoveIncomingWssAction extends AbstractAction
626 	{
627 		public RemoveIncomingWssAction()
628 		{
629 			putValue( SMALL_ICON, UISupport.createImageIcon( "/remove_property.gif" ));
630 			putValue( SHORT_DESCRIPTION, "Removes the selected Incoming WSS Configuration" );
631 			
632 			setEnabled( false );
633 		}
634 
635 		public void actionPerformed( ActionEvent e )
636 		{
637 			int row = incomingWssTable.getSelectedRow();
638 			if( row == -1 )
639 				return;
640 			
641 			if( UISupport.confirm( "Removes selected configuration?", "Remove Configuration" ))
642 			{
643 				wssContainer.removeIncomingWssAt( row );
644 			}
645 		}
646 	}
647 	
648 	public class OutgoingWssTableModel extends AbstractTableModel
649 	{
650 		private List<OutgoingWss> outgoingWss;
651 
652 		public OutgoingWssTableModel()
653 		{
654 			outgoingWss = wssContainer.getOutgoingWssList();
655 		}
656 
657 		public void release()
658 		{
659 			outgoingWss = null;
660 		}
661 
662 		public int getColumnCount()
663 		{
664 			return 3;
665 		}
666 
667 		@Override
668 		public String getColumnName( int column )
669 		{
670 			switch( column )
671 			{
672 			case 0:
673 				return "Name";
674 			case 1:
675 				return "Default Username/Alias";
676 			case 2:
677 				return "Default Password";
678 			}
679 
680 			return null;
681 		}
682 
683 		public int getRowCount()
684 		{
685 			return outgoingWss == null ? 0 : outgoingWss.size();
686 		}
687 		
688 		@Override
689 		public boolean isCellEditable( int rowIndex, int columnIndex )
690 		{
691 			return columnIndex > 0;
692 		}
693 
694 		public Object getValueAt( int rowIndex, int columnIndex )
695 		{
696 			OutgoingWss incoming =  outgoingWss.get( rowIndex );
697 
698 			switch( columnIndex )
699 			{
700 			case 0:
701 				return incoming.getName();
702 			case 1:
703 				return incoming.getUsername();
704 			case 2:
705 				return incoming.getPassword();
706 			}
707 
708 			return null;
709 		}
710 		
711 		@Override
712 		public void setValueAt( Object aValue, int rowIndex, int columnIndex )
713 		{
714 			OutgoingWss incoming =  outgoingWss.get( rowIndex );
715 
716 			switch( columnIndex )
717 			{
718 			case 1:
719 				incoming.setUsername( aValue == null ? null : aValue.toString() ); break;
720 			case 2:
721 				incoming.setPassword( aValue == null ? null : aValue.toString() ); break;
722 			}
723 		}
724 
725 		public void outgoingWssAdded( OutgoingWss outgoing )
726 		{
727 			outgoingWss.add( outgoing );
728 			fireTableRowsInserted( outgoingWss.size()-1, outgoingWss.size()-1 );
729 			
730 		}
731 
732 		public void outgoingWssRemoved( OutgoingWss outgoing )
733 		{
734 			int ix = outgoingWss.indexOf( outgoing );
735 			if( ix != -1 )
736 			{
737 				outgoingWss.remove( ix );
738 				fireTableRowsDeleted( ix, ix );
739 			}
740 		}
741 	}
742 
743 	private class AddOutgoingWssAction extends AbstractAction
744 	{
745 		public AddOutgoingWssAction()
746 		{
747 			putValue( SMALL_ICON, UISupport.createImageIcon( "/add_property.gif" ));
748 			putValue( SHORT_DESCRIPTION, "Adds a new Outgoing WSS Configuration" );
749 		}
750 
751 		public void actionPerformed( ActionEvent e )
752 		{
753 			String name = UISupport.prompt( "Specify unique name for configuration", "New Outgoing WSS Configuration", "" );
754 			if( StringUtils.hasContent( name ) && wssContainer.getOutgoingWssByName( name ) == null )
755 			{
756 				wssContainer.addOutgoingWss( name );
757 				outgoingWssTable.setRowSelectionInterval( outgoingWssTable.getRowCount()-1, outgoingWssTable.getRowCount()-1 );
758 			}
759 		}
760 	}
761 	
762 	private class RemoveOutgoingWssAction extends AbstractAction
763 	{
764 		public RemoveOutgoingWssAction()
765 		{
766 			putValue( SMALL_ICON, UISupport.createImageIcon( "/remove_property.gif" ));
767 			putValue( SHORT_DESCRIPTION, "Removes the selected Outgoing WSS Configuration" );
768 			
769 			setEnabled( false );
770 		}
771 
772 		public void actionPerformed( ActionEvent e )
773 		{
774 			int row = outgoingWssTable.getSelectedRow();
775 			if( row == -1 )
776 				return;
777 			
778 			if( UISupport.confirm( "Removes selected configuration?", "Remove Configuration" ))
779 			{
780 				wssContainer.removeOutgoingWssAt( row );
781 			}
782 		}
783 	}
784 	
785 //	private class WssEntriesListModel extends AbstractListModel 
786 //	{
787 //		private List<WssEntry> entries = new ArrayList<WssEntry>();
788 //
789 //		public WssEntriesListModel()
790 //		{
791 //		}
792 //		
793 //		public void release()
794 //		{
795 //			entries.clear();
796 //		}
797 //
798 //		public void setOutgoingWss( OutgoingWss outgoingWss )
799 //		{
800 //			if( entries.size() > 0 )
801 //			{
802 //				int sz = entries.size();
803 //				entries.clear();
804 //				fireIntervalRemoved( this, 0, sz-1 );
805 //			}
806 //			
807 //			if( outgoingWss == null )
808 //				return;
809 //			
810 //			entries.addAll( outgoingWss.getEntries() );
811 //			
812 //			if( !entries.isEmpty())
813 //				fireIntervalAdded( this, 0, entries.size()-1 );
814 //		}
815 //
816 //		public Object getElementAt( int index )
817 //		{
818 //			return entries.get( index );
819 //		}
820 //
821 //		public int getSize()
822 //		{
823 //			return entries == null ? 0 : entries.size();
824 //		}
825 //
826 //		public void entryAdded( WssEntry entry )
827 //		{
828 //			entries.add( entry );
829 //			fireIntervalAdded( this, entries.size() - 1, entries.size() - 1 );
830 //		}
831 //
832 //		public void entryRemoved( WssEntry entry )
833 //		{
834 //			int ix = entries.indexOf( entry );
835 //			if( ix != -1 )
836 //			{
837 //				entries.remove( ix );
838 //				fireIntervalRemoved( this, ix, ix );
839 //			}
840 //		}
841 //	}
842 	
843 	public class AddOutgoingEntryAction extends AbstractAction
844 	{
845 		public AddOutgoingEntryAction()
846 		{
847 			putValue( SHORT_DESCRIPTION, "Adds a new WSS Entry" );
848 			putValue( SMALL_ICON, UISupport.createImageIcon( "/add_property.gif" ) );
849 			setEnabled( false );
850 		}
851 
852 		public void actionPerformed( ActionEvent e )
853 		{
854 			if( selectedOutgoing == null )
855 				return;
856 			
857 			String type = UISupport.prompt( "Select type of entry to add", "Add WSS Entry", WssEntryRegistry.get()
858 						.getTypes() );
859 			if( type != null )
860 			{
861 				WssEntry entry = selectedOutgoing.addEntry( type );
862 				entriesTabs.setSelectedComponent( entry.getConfigurationPanel() );
863 				
864 //				entriesTabs.addTab( entry.getLabel(), entry.getConfigurationPanel() );
865 //				entryList.setSelectedValue( entry, true );
866 			}
867 		}
868 	}
869 
870 	public class RemoveOutgoingEntryAction extends AbstractAction
871 	{
872 		public RemoveOutgoingEntryAction()
873 		{
874 			putValue( SHORT_DESCRIPTION, "Removes the selected WSS-Entry" );
875 			putValue( SMALL_ICON, UISupport.createImageIcon( "/remove_property.gif" ) );
876 		}
877 
878 		public void actionPerformed( ActionEvent e )
879 		{
880 			if( selectedEntry == null )
881 				return;
882 
883 			if( UISupport.confirm( "Remove entry [" + selectedEntry.getLabel() + "]", "Remove WSS Entry" ) )
884 			{
885 				selectedOutgoing.removeEntry( selectedEntry );
886 			}
887 		}
888 	}
889 	
890 	private class InternalWssContainerListener implements WssContainerListener
891 	{
892 		public void cryptoAdded( WssCrypto crypto )
893 		{
894 			((CryptosTableModel)cryptosTable.getModel()).cryptoAdded( crypto );
895 		}
896 
897 		public void cryptoRemoved( WssCrypto crypto )
898 		{
899 			((CryptosTableModel)cryptosTable.getModel()).cryptoRemoved( crypto );
900 		}
901 
902 		public void incomingWssAdded( IncomingWss incomingWss )
903 		{
904 			((IncomingWssTableModel)incomingWssTable.getModel()).incomingWssAdded( incomingWss );
905 			
906 		}
907 
908 		public void incomingWssRemoved( IncomingWss incomingWss )
909 		{
910 			((IncomingWssTableModel)incomingWssTable.getModel()).incomingWssRemoved( incomingWss );
911 			
912 		}
913 
914 		public void outgoingWssAdded( OutgoingWss outgoingWss )
915 		{
916 			((OutgoingWssTableModel)outgoingWssTable.getModel()).outgoingWssAdded( outgoingWss );
917 		}
918 
919 		public void outgoingWssEntryAdded( WssEntry entry )
920 		{
921 			if( entry.getOutgoingWss() == selectedOutgoing )
922 			{
923 				entriesTabs.addTab( entry.getLabel(), entry.getConfigurationPanel() );
924 				entriesTabs.getParent().setVisible( true);
925 			}
926 //				entriesModel.entryAdded( entry );
927 		}
928 
929 		public void outgoingWssEntryRemoved( WssEntry entry )
930 		{
931 			if( entry.getOutgoingWss() == selectedOutgoing )
932 			{
933 				int ix = entriesTabs.indexOfComponent( entry.getConfigurationPanel() );
934 				if( ix != -1 )
935 					entriesTabs.remove( ix );
936 				
937 				entriesTabs.getParent().setVisible( entriesTabs.getTabCount() > 0 );
938 			}
939 //				entriesModel.entryRemoved( entry );
940 		}
941 
942 		public void outgoingWssRemoved( OutgoingWss outgoingWss )
943 		{
944 			((OutgoingWssTableModel)outgoingWssTable.getModel()).outgoingWssRemoved( outgoingWss );
945 		}
946 
947 		public void cryptoUpdated( WssCrypto crypto )
948 		{
949 		}
950 	}
951 	
952 	public class ImportWssSettingsAction extends AbstractAction
953 	{
954 		public ImportWssSettingsAction()
955 		{
956 			putValue( SHORT_DESCRIPTION, "Imports an existing WS-Security configuration from another project" );
957 			putValue( SMALL_ICON, UISupport.createImageIcon( "/load_properties.gif" ) );
958 		}
959 
960 		public void actionPerformed( ActionEvent e )
961 		{
962 			String[] names = ModelSupport.getNames( ((WorkspaceImpl)SoapUI.getWorkspace()).getOpenProjectList() );
963 			String projectName = UISupport.prompt( "Select project to import from", "Import WSS Settings", names );
964 			if( projectName != null )
965 			{
966 				WsdlProject prj = ( WsdlProject ) SoapUI.getWorkspace().getProjectByName( projectName );
967 				wssContainer.importConfig( prj.getWssContainer() );
968 			}
969 		}
970 	}
971 }