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.support.resolver;
14  
15  import java.awt.BorderLayout;
16  import java.awt.Color;
17  import java.awt.Component;
18  import java.awt.event.ActionEvent;
19  import java.awt.event.ActionListener;
20  import java.awt.event.MouseAdapter;
21  import java.awt.event.MouseEvent;
22  import java.awt.event.WindowAdapter;
23  import java.awt.event.WindowEvent;
24  import java.util.ArrayList;
25  import java.util.List;
26  
27  import javax.swing.AbstractCellEditor;
28  import javax.swing.BorderFactory;
29  import javax.swing.JButton;
30  import javax.swing.JComboBox;
31  import javax.swing.JDialog;
32  import javax.swing.JFrame;
33  import javax.swing.JPanel;
34  import javax.swing.JScrollPane;
35  import javax.swing.JTable;
36  import javax.swing.table.AbstractTableModel;
37  import javax.swing.table.DefaultTableCellRenderer;
38  import javax.swing.table.TableCellEditor;
39  import javax.swing.table.TableCellRenderer;
40  
41  import org.jdesktop.swingx.JXTable;
42  
43  import com.eviware.soapui.impl.wsdl.AbstractWsdlModelItem;
44  import com.eviware.soapui.impl.wsdl.actions.project.SimpleDialog;
45  import com.eviware.soapui.model.ModelItem;
46  import com.eviware.soapui.model.project.Project;
47  import com.eviware.soapui.support.UISupport;
48  import com.eviware.soapui.support.resolver.ResolveContext.PathToResolve;
49  import com.eviware.soapui.support.resolver.ResolveContext.Resolver;
50  
51  /***
52   * Utility for resolving items
53   * 
54   * @author Ole.Matzura
55   */
56  
57  public class ResolveDialog
58  {
59  
60  	private JDialog dialog;
61  	private ResolveContextTableModel resolveContextTableModel;
62  	private boolean showOkMessage;
63  	private String title;
64  	private String description;
65  	private String helpUrl;
66  	private JXTable table;
67  
68  	public ResolveDialog( String title, String description, String helpUrl )
69  	{
70  		this.title = title;
71  
72  		this.description = description;
73  		this.helpUrl = helpUrl;
74  
75  	}
76  
77  	@SuppressWarnings( "serial" )
78  	private void buildDialog()
79  	{
80  		dialog = new SimpleDialog( title, description, helpUrl, true )
81  		{
82  			@Override
83  			protected Component buildContent()
84  			{
85  				JPanel panel = new JPanel( new BorderLayout() );
86  				table = new JXTable( resolveContextTableModel );
87  				table.setHorizontalScrollEnabled( true );
88  				table.setDefaultRenderer( JComboBox.class, new ResolverRenderer() );
89  				table.setDefaultEditor( JComboBox.class, new ResolverEditor() );
90  				table.getColumn( 2 ).setCellRenderer( new PathCellRenderer() );
91  				table.getColumn( 3 ).setWidth( 100 );
92  				table.addMouseListener( new MouseAdapter()
93  				{
94  					@Override
95  					public void mouseClicked( MouseEvent e )
96  					{
97  						if( e.getClickCount() > 1 )
98  						{
99  							int ix = table.getSelectedRow();
100 							if( ix != -1 )
101 							{
102 								ResolveContext.PathToResolve pathToResolve = resolveContextTableModel
103 										.getContext().getPathsToResolve().get( ix );
104 
105 								if( pathToResolve != null )
106 									UISupport.selectAndShow( pathToResolve.getOwner() );
107 							}
108 						}
109 					}
110 				} );
111 
112 				panel.add( new JScrollPane( table ), BorderLayout.CENTER );
113 				panel.setBorder( BorderFactory.createEmptyBorder( 5, 5, 5, 5 ) );
114 
115 				return panel;
116 			}
117 
118 			/*
119 			 * Change Cancel into Update
120 			 */
121 			@Override
122 			protected void modifyButtons()
123 			{
124 				super.modifyButtons();
125 				Component[] components = buttons.getComponents();
126 				for( Component component : components )
127 				{
128 					if( component instanceof JButton )
129 					{
130 						JButton button = ( JButton )component;
131 						if( button.getText().equals( "Cancel" ) )
132 						{
133 							button.setText( "Update" );
134 						}
135 					}
136 				}
137 			}
138 
139 			@Override
140 			protected boolean handleCancel()
141 			{
142 				return handleUpdate();
143 			}
144 
145 			@SuppressWarnings( "unchecked" )
146 			private boolean handleUpdate()
147 			{
148 				for( PathToResolve otherPath : resolveContextTableModel.getContext().getPathsToResolve() )
149 				{
150 					if( !otherPath.isResolved() )
151 					{
152 						otherPath.getOwner().afterLoad();
153 						otherPath.getOwner().resolve( resolveContextTableModel.getContext() );
154 					}
155 				}
156 
157 				dialog = null;
158 				setVisible( false );
159 				resolve( resolveContextTableModel.getContext().getModelItem() );
160 				return true;
161 			}
162 
163 			@SuppressWarnings( "unchecked" )
164 			@Override
165 			protected boolean handleOk()
166 			{
167 				for( PathToResolve path : resolveContextTableModel.getContext().getPathsToResolve() )
168 				{
169 					if( !path.isResolved() )
170 					{
171 						if( UISupport.confirm( "There are unresolved paths, continue?", "Unresolved paths - Warning" ) )
172 						{
173 							return true;
174 						}
175 						return false;
176 					}
177 				}
178 				return true;
179 			}
180 
181 		};
182 
183 		dialog.setSize( 550, 300 );
184 		dialog.setModal( false );
185 		dialog.setDefaultCloseOperation( JFrame.DO_NOTHING_ON_CLOSE );
186 		dialog.addWindowListener( new WindowAdapter()
187 		{
188 
189 			@SuppressWarnings( "unchecked" )
190 			@Override
191 			public void windowClosing( WindowEvent arg0 )
192 			{
193 				for( PathToResolve path : resolveContextTableModel.getContext().getPathsToResolve() )
194 				{
195 					if( !path.isResolved() )
196 					{
197 						if( UISupport.confirm( "There are unresolved paths, continue?", "Unresolved paths - Warning" ) )
198 						{
199 							dialog.setVisible( false );
200 						}
201 						break;
202 					}
203 				}
204 			}
205 		} );
206 
207 	}
208 
209 	public boolean isShowOkMessage()
210 	{
211 		return showOkMessage;
212 	}
213 
214 	public void setShowOkMessage( boolean showOkMessage )
215 	{
216 		this.showOkMessage = showOkMessage;
217 	}
218 
219 	public ResolveContext<?> resolve( AbstractWsdlModelItem<?> modelItem )
220 	{
221 		ResolveContext<?> context = new ResolveContext<AbstractWsdlModelItem<?>>( modelItem );
222 		modelItem.resolve( context );
223 		if( context.isEmpty() )
224 		{
225 			if( isShowOkMessage() )
226 			{
227 				UISupport.showInfoMessage( "No resolve problems found", title );
228 			}
229 		}
230 		else
231 		{
232 			resolveContextTableModel = new ResolveContextTableModel( context );
233 			if( dialog == null )
234 				buildDialog();
235 			else
236 				table.setModel( resolveContextTableModel );
237 
238 			UISupport.centerDialog( dialog );
239 			dialog.setVisible( true );
240 		}
241 
242 		return context;
243 	}
244 
245 	@SuppressWarnings( "serial" )
246 	private class ResolveContextTableModel extends AbstractTableModel
247 	{
248 		private ResolveContext<?> context;
249 		private ArrayList<JComboBox> jbcList = new ArrayList<JComboBox>();
250 
251 		@SuppressWarnings( "unchecked" )
252 		public ResolveContextTableModel( ResolveContext<?> context2 )
253 		{
254 			context = context2;
255 			for( PathToResolve path : context.getPathsToResolve() )
256 			{
257 				ArrayList<Object> resolversAndDefaultAction = new ArrayList<Object>();
258 				resolversAndDefaultAction.add( "Choose one..." );
259 				for( Object resolver : path.getResolvers() )
260 				{
261 					resolversAndDefaultAction.add( resolver );
262 				}
263 				JComboBox jbc = new JComboBox( resolversAndDefaultAction.toArray() );
264 				jbcList.add( jbc );
265 			}
266 
267 		}
268 
269 		public JComboBox getResolversAndActions( int row )
270 		{
271 			return jbcList.get( row );
272 		}
273 
274 		public int getColumnCount()
275 		{
276 			return 4;
277 		}
278 
279 		public void setContext( ResolveContext<?> context )
280 		{
281 			this.context = context;
282 			fireTableDataChanged();
283 		}
284 
285 		@Override
286 		public String getColumnName( int column )
287 		{
288 			switch( column )
289 			{
290 			case 0 :
291 				return "Item";
292 			case 1 :
293 				return "Description";
294 			case 2 :
295 				return "Value";
296 			case 3 :
297 				return "Action";
298 			}
299 
300 			return super.getColumnName( column );
301 		}
302 
303 		@Override
304 		public Class<?> getColumnClass( int arg0 )
305 		{
306 			if( arg0 == 3 )
307 				return JComboBox.class;
308 			else
309 				return String.class;
310 		}
311 
312 		public int getRowCount()
313 		{
314 			return context.getPathsToResolve().size();
315 		}
316 
317 		@Override
318 		public boolean isCellEditable( int rowIndex, int columnIndex )
319 		{
320 			return columnIndex == 3;
321 		}
322 
323 		@SuppressWarnings( "unchecked" )
324 		public Object getValueAt( int arg0, int arg1 )
325 		{
326 			PathToResolve ptr = context.getPathsToResolve().get( arg0 );
327 			switch( arg1 )
328 			{
329 			case 0 :
330 				return createItemName( ptr );
331 			case 1 :
332 				return ptr.getDescription();
333 			case 2 :
334 				return ptr.getPath();
335 
336 			}
337 
338 			return null;
339 		}
340 
341 		@SuppressWarnings( "unchecked" )
342 		private String createItemName( PathToResolve ptr )
343 		{
344 			String name = "";
345 			ModelItem modelItem = ptr.getOwner();
346 			try
347 			{
348 				name = modelItem.getName();
349 			}
350 			catch( Exception e )
351 			{
352 				e.getStackTrace();
353 			}
354 
355 			while( modelItem.getParent() != null && !( modelItem.getParent() instanceof Project ) )
356 			{
357 				modelItem = modelItem.getParent();
358 				name = modelItem.getName() + " - " + name;
359 			}
360 
361 			return name;
362 		}
363 
364 		public ResolveContext<?> getContext()
365 		{
366 			return context;
367 		}
368 
369 		@SuppressWarnings( "unchecked" )
370 		public void setResolver( int pathIndex, Object resolveOrDefaultAction )
371 		{
372 			PathToResolve path = context.getPathsToResolve().get( pathIndex );
373 			if( resolveOrDefaultAction instanceof Resolver )
374 			{
375 				path.setResolver( resolveOrDefaultAction );
376 			}
377 
378 		}
379 	}
380 
381 	private class ResolverRenderer implements TableCellRenderer
382 	{
383 
384 		public Component getTableCellRendererComponent( JTable table, Object value, boolean isSelected, boolean hasFocus,
385 				int row, int column )
386 		{
387 			return ( ( ResolveContextTableModel )table.getModel() ).getResolversAndActions( row );
388 		}
389 	}
390 
391 	@SuppressWarnings( "serial" )
392 	private class ResolverEditor extends AbstractCellEditor implements TableCellEditor
393 	{
394 		private JComboBox jbc = new JComboBox();
395 
396 		@SuppressWarnings( "unchecked" )
397 		public Component getTableCellEditorComponent( final JTable table, Object value, boolean isSelected, int row,
398 				int column )
399 		{
400 			jbc = ( ( ResolveContextTableModel )table.getModel() ).getResolversAndActions( row );
401 			final PathToResolve path = resolveContextTableModel.getContext().getPathsToResolve().get( row );
402 
403 			jbc.addActionListener( new ActionListener()
404 			{
405 
406 				public void actionPerformed( ActionEvent e )
407 				{
408 					Object key = jbc.getSelectedItem();
409 					if( key instanceof Resolver )
410 					{
411 						path.setResolver( key );
412 					}
413 					if( path.resolve() )
414 					{
415 						path.setSolved( true );
416 						jbc.addItem( "Resolved" );
417 						jbc.setSelectedIndex( jbc.getItemCount() - 1 );
418 
419 						// for (int cnt = 0; cnt <
420 						// resolveContextTableModel.getContext().getPathsToResolve().size();
421 						// cnt++)
422 						// {
423 						// PathToResolve otherPath =
424 						// resolveContextTableModel.getContext().getPathsToResolve().get(cnt);
425 						// if (path != otherPath & !otherPath.isResolved())
426 						// {
427 						// otherPath.getOwner().afterLoad();
428 						// otherPath.getOwner().resolve(resolveContextTableModel.getContext());
429 						// if (otherPath.isResolved())
430 						// {
431 						// JComboBox jbcOther = ((ResolveContextTableModel)
432 						// table.getModel())
433 						// .getResolversAndActions(cnt);
434 						// jbcOther.addItem("Resolved");
435 						// jbcOther.setSelectedIndex(jbcOther.getItemCount() - 1);
436 						// }
437 						// }
438 						// }
439 					}
440 				}
441 
442 			} );
443 			return jbc;
444 		}
445 
446 		public Object getCellEditorValue()
447 		{
448 			return null;
449 		}
450 
451 	}
452 
453 	@SuppressWarnings( "serial" )
454 	private class PathCellRenderer extends DefaultTableCellRenderer
455 	{
456 		private Color greenColor = Color.GREEN.darker().darker();
457 		private Color redColor = Color.RED.darker().darker();
458 
459 		@SuppressWarnings( "unchecked" )
460 		@Override
461 		public Component getTableCellRendererComponent( JTable arg0, Object arg1, boolean arg2, boolean arg3, int arg4,
462 				int arg5 )
463 		{
464 			Component comp = super.getTableCellRendererComponent( arg0, arg1, arg2, arg3, arg4, arg5 );
465 
466 			List<? extends PathToResolve> paths = resolveContextTableModel.getContext().getPathsToResolve();
467 			PathToResolve ptr = arg4 >= paths.size() ? null : paths.get( arg4 );
468 			// boolean resolved = ptr.getResolver() != null &&
469 			// ptr.getResolver().isResolved();
470 
471 			if( ptr != null && ptr.isResolved() )
472 			{
473 				comp.setForeground( greenColor );
474 				setText( ptr.getPath() );
475 			}
476 			else
477 			{
478 				comp.setForeground( redColor );
479 			}
480 
481 			return comp;
482 		}
483 	}
484 
485 }