View Javadoc

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