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