1
2
3
4
5
6
7
8
9
10
11
12
13 package com.eviware.soapui.impl.wsdl.panels.iface;
14
15 import com.eviware.soapui.SoapUI;
16 import com.eviware.soapui.actions.SoapUIPreferencesAction;
17 import com.eviware.soapui.impl.support.actions.ShowOnlineHelpAction;
18 import com.eviware.soapui.impl.support.definition.InterfaceDefinitionPart;
19 import com.eviware.soapui.impl.wsdl.WsdlInterface;
20 import com.eviware.soapui.impl.wsdl.WsdlOperation;
21 import com.eviware.soapui.impl.wsdl.actions.iface.CreateWsdlDocumentationAction;
22 import com.eviware.soapui.impl.wsdl.actions.iface.ExportDefinitionAction;
23 import com.eviware.soapui.impl.wsdl.actions.iface.UpdateInterfaceAction;
24 import com.eviware.soapui.impl.wsdl.actions.iface.tools.wsi.WSIAnalyzeAction;
25 import com.eviware.soapui.impl.wsdl.actions.iface.tools.wsi.WSIReportPanel;
26 import com.eviware.soapui.impl.wsdl.panels.teststeps.support.LineNumbersPanel;
27 import com.eviware.soapui.impl.wsdl.support.HelpUrls;
28 import com.eviware.soapui.impl.wsdl.support.wsdl.WsdlUtils;
29 import com.eviware.soapui.impl.wsdl.support.xsd.SchemaUtils;
30 import com.eviware.soapui.model.ModelItem;
31 import com.eviware.soapui.model.iface.Interface;
32 import com.eviware.soapui.model.support.ProjectListenerAdapter;
33 import com.eviware.soapui.support.UISupport;
34 import com.eviware.soapui.support.action.swing.SwingActionDelegate;
35 import com.eviware.soapui.support.components.JEditorStatusBar;
36 import com.eviware.soapui.support.components.JXToolBar;
37 import com.eviware.soapui.support.components.MetricsPanel;
38 import com.eviware.soapui.support.components.MetricsPanel.MetricType;
39 import com.eviware.soapui.support.components.MetricsPanel.MetricsSection;
40 import com.eviware.soapui.support.components.ProgressDialog;
41 import com.eviware.soapui.support.types.StringList;
42 import com.eviware.soapui.support.xml.JXEditTextArea;
43 import com.eviware.soapui.support.xml.XmlUtils;
44 import com.eviware.soapui.ui.support.ModelItemDesktopPanel;
45 import com.eviware.x.dialogs.Worker;
46 import com.eviware.x.dialogs.XProgressDialog;
47 import com.eviware.x.dialogs.XProgressMonitor;
48 import com.jgoodies.forms.builder.ButtonBarBuilder;
49 import org.apache.log4j.Logger;
50 import org.apache.xmlbeans.XmlCursor;
51 import org.apache.xmlbeans.XmlLineNumber;
52 import org.apache.xmlbeans.XmlObject;
53 import org.apache.xmlbeans.XmlOptions;
54 import org.jdesktop.swingx.JXTable;
55 import org.syntax.jedit.JEditTextArea;
56 import org.w3c.dom.Element;
57
58 import javax.swing.*;
59 import javax.swing.event.TreeSelectionEvent;
60 import javax.swing.event.TreeSelectionListener;
61 import javax.swing.table.AbstractTableModel;
62 import javax.swing.tree.DefaultMutableTreeNode;
63 import javax.swing.tree.DefaultTreeModel;
64 import javax.swing.tree.TreePath;
65 import javax.wsdl.BindingOperation;
66 import java.awt.*;
67 import java.awt.event.ActionEvent;
68 import java.awt.event.MouseAdapter;
69 import java.awt.event.MouseEvent;
70 import java.io.File;
71 import java.io.StringWriter;
72 import java.util.*;
73 import java.util.List;
74
75 /***
76 * DesktopPanel for WsdlInterface. Loads all referenced wsdls/xsds for the specified WsdlInterface
77 * and displays these in seperate tabs
78 *
79 * @author Ole.Matzura
80 */
81
82 public class WsdlInterfaceDesktopPanel extends ModelItemDesktopPanel<WsdlInterface>
83 {
84 private final static Logger logger = Logger.getLogger( WsdlInterfaceDesktopPanel.class );
85 private JTabbedPane partTabs;
86 private List<JEditTextArea> editors = new ArrayList<JEditTextArea>();
87 private JTree tree;
88 private Map<String,DefaultMutableTreeNode> groupNodes = new HashMap<String,DefaultMutableTreeNode>();
89 private Map<String,TreePath> pathMap = new HashMap<String,TreePath>();
90 private List<TreePath> navigationHistory = new ArrayList<TreePath>();
91 private StringList targetNamespaces = new StringList();
92 private int historyIndex;
93 private boolean navigating;
94 private JEditorStatusBar statusBar;
95 private DefaultMutableTreeNode rootNode;
96 private DefaultTreeModel treeModel;
97 private InternalProjectListener projectListener;
98 private final WsdlInterface iface;
99 private JPanel wsiPanel;
100 private WSIReportPanel reportPanel;
101 private SaveWsiReportAction saveWsiReportAction;
102 private MetricsPanel metrics;
103 private boolean updatingInterface;
104 private OperationsTableModel operationsTableModel;
105
106 public WsdlInterfaceDesktopPanel(WsdlInterface iface)
107 {
108 super( iface );
109 this.iface = iface;
110
111 try
112 {
113 iface.getWsdlContext().loadIfNecessary();
114 buildUI();
115 }
116 catch( Exception e )
117 {
118 UISupport.showErrorMessage( e );
119 SwingUtilities.invokeLater( new Runnable() {
120
121 public void run()
122 {
123 SoapUI.getDesktop().closeDesktopPanel( WsdlInterfaceDesktopPanel.this );
124 }} );
125 }
126 }
127
128 private void buildUI()
129 {
130 JTabbedPane tabs = new JTabbedPane();
131 tabs.addTab( "Overview", buildInterfaceOverviewTab() );
132 tabs.addTab( "Service Endpoints", buildEndpointsTab() );
133 tabs.addTab( "WSDL Content", buildWsdlContentTab() );
134 tabs.addTab( "WS-I Compliance", buildWSITab() );
135
136 add( UISupport.createTabPanel( tabs, true ), BorderLayout.CENTER );
137 }
138
139 private Component buildWSITab()
140 {
141 wsiPanel = new JPanel( new BorderLayout() );
142 wsiPanel.setBackground( Color.WHITE );
143 wsiPanel.setOpaque( true );
144
145 wsiPanel.add( builderWsiToolbar(), BorderLayout.NORTH );
146
147 return wsiPanel;
148 }
149
150 private Component builderWsiToolbar()
151 {
152 JXToolBar toolbar = UISupport.createToolbar();
153
154 toolbar.addFixed( UISupport.createToolbarButton( new RunWSIAction() ) );
155 toolbar.addFixed( UISupport.createToolbarButton( new WSIOptionsAction() ));
156 toolbar.addRelatedGap();
157 saveWsiReportAction = new SaveWsiReportAction();
158 toolbar.addFixed( UISupport.createToolbarButton(saveWsiReportAction ));
159
160 toolbar.addGlue();
161 toolbar.addFixed( UISupport.createToolbarButton( new ShowOnlineHelpAction( HelpUrls.WSI_COMPLIANCE_HELP_URL ) ) );
162
163 return toolbar;
164 }
165
166 private Component buildInterfaceOverviewTab()
167 {
168 metrics = new MetricsPanel();
169 JXToolBar toolbar = UISupport.createSmallToolbar();
170 toolbar.addGlue();
171 toolbar.addFixed( UISupport.createToolbarButton( new ShowOnlineHelpAction( HelpUrls.INTERFACE_OVERVIEW_HELP_URL ) ) );
172 metrics.add(toolbar,BorderLayout.NORTH );
173 MetricsSection section = metrics.addSection( "WSDL Definition" );
174
175 try
176 {
177 section.addMetric( "WSDL URL", MetricType.URL ).set( iface.getDefinition() );
178 section.addMetric( "Namespace" ).set( iface.getBindingName().getNamespaceURI() );
179 section.addMetric( "Binding" ).set( iface.getBindingName().getLocalPart() );
180 section.addMetric( "SOAP Version" ).set( iface.getSoapVersion().toString() );
181 section.addMetric( "Style" ).set( iface.getStyle() );
182 section.addMetric( "WS-A version" ).set( iface.getWsaVersion());
183 }
184 catch( Exception e )
185 {
186 UISupport.showErrorMessage( e );
187 }
188
189 section.finish();
190
191 metrics.addSection( "Definition Parts" );
192 section = metrics.addSection( "Operations" );
193 operationsTableModel = new OperationsTableModel();
194 JXTable table = section.addTable( operationsTableModel );
195 table.getColumn( 1 ).setPreferredWidth( 60 );
196 table.getColumn( 2 ).setPreferredWidth( 60 );
197 section.finish();
198
199 table.packColumn( 3, 10 );
200 if( table.getColumn( 3 ).getPreferredWidth() < 250 )
201 table.getColumn( 3 ).setPreferredWidth( 250 );
202
203 return new JScrollPane( metrics );
204 }
205
206 private Component buildEndpointsTab()
207 {
208 return iface.getProject().getEndpointStrategy().getConfigurationPanel( iface );
209 }
210
211 private JComponent buildWsdlContentTab()
212 {
213 partTabs = new JTabbedPane();
214 partTabs.setTabLayoutPolicy( JTabbedPane.SCROLL_TAB_LAYOUT );
215
216 rootNode = new DefaultMutableTreeNode( iface.getName() );
217 treeModel = new DefaultTreeModel( rootNode );
218 tree = new JTree( treeModel );
219 tree.setBorder( BorderFactory.createEmptyBorder( 2, 2, 2, 2) );
220 tree.setExpandsSelectedPaths( true );
221 tree.addTreeSelectionListener( new InternalTreeSelectionListener() );
222 tree.addMouseListener( new MouseAdapter() {
223
224 @Override
225 public void mouseClicked( MouseEvent arg0 )
226 {
227 if( arg0.getClickCount() > 1 )
228 {
229 TreePath selectionPath = tree.getSelectionPath();
230 if( selectionPath != null )
231 {
232 DefaultMutableTreeNode treeNode = ( DefaultMutableTreeNode ) selectionPath.getLastPathComponent();
233 Object userObject = treeNode.getUserObject();
234 if( userObject instanceof InspectItem )
235 {
236 InspectItem item = ( InspectItem ) userObject;
237 if( item != null && item.selector != null )
238 {
239 item.selector.selectNode( item );
240 }
241 }
242 }
243 }
244 }} );
245
246 JScrollPane scrollPane = new JScrollPane( tree );
247 JSplitPane split = UISupport.createHorizontalSplit( scrollPane,
248 UISupport.createTabPanel( partTabs, true ));
249
250 split.setDividerLocation( 250 );
251 split.setResizeWeight( 0.3 );
252
253 initTreeModel( iface );
254
255 JPanel panel = new JPanel( new BorderLayout() );
256
257 panel.add( split, BorderLayout.CENTER );
258 panel.add( buildWsdlTabToolbar(), BorderLayout.PAGE_START );
259 statusBar = new JEditorStatusBar( );
260 panel.add( statusBar, BorderLayout.PAGE_END );
261 setPreferredSize( new Dimension( 600, 500 ));
262
263 projectListener = new InternalProjectListener();
264 iface.getProject().addProjectListener( projectListener );
265
266 return panel;
267 }
268
269 private void initTreeModel( WsdlInterface iface )
270 {
271 try
272 {
273 if( iface.getWsdlContext().loadIfNecessary())
274 {
275 XProgressDialog progressDialog = UISupport.getDialogs().createProgressDialog(
276 "Loading Defintion", 3, "Initializing definition..", true );
277 Loader loader = new Loader( iface );
278
279 if( progressDialog != null )
280 progressDialog.setCancelLabel( "Run in background" );
281
282 progressDialog.run( loader );
283 loader = null;
284 treeModel.nodeStructureChanged( rootNode );
285 }
286 }
287 catch (Exception e)
288 {
289 SoapUI.logError( e );
290 }
291 }
292
293 private Component buildWsdlTabToolbar()
294 {
295 JXToolBar toolbar = UISupport.createToolbar();
296
297 toolbar.addFixed( UISupport.createToolbarButton( new BackwardAction() ) );
298 toolbar.addFixed( UISupport.createToolbarButton( new ForwardAction() ) );
299 toolbar.addUnrelatedGap();
300 JButton button = UISupport.createToolbarButton( SwingActionDelegate.createDelegate( UpdateInterfaceAction.SOAPUI_ACTION_ID, getModelItem(),
301 null, "/updateDefinition.gif" ));
302 button.setText( null );
303 toolbar.addFixed( button);
304 button = UISupport.createToolbarButton( SwingActionDelegate.createDelegate( ExportDefinitionAction.SOAPUI_ACTION_ID, getModelItem(),
305 null, "/exportDefinition.gif"));
306 button.setText( null );
307 toolbar.addFixed(UISupport.createToolbarButton(
308 SwingActionDelegate.createDelegate( CreateWsdlDocumentationAction.SOAPUI_ACTION_ID, iface, null, "/export.gif")));
309 toolbar.addFixed( button);
310 toolbar.addGlue();
311 button = UISupport.createToolbarButton( new ShowOnlineHelpAction( HelpUrls.WSDL_CONTENT_HELP_URL ));
312 button.setText( null );
313 toolbar.addFixed( button);
314
315 return toolbar;
316 }
317
318 private final class InternalProjectListener extends ProjectListenerAdapter
319 {
320 @Override
321 public void interfaceUpdated( Interface iface )
322 {
323 if( iface == getModelItem() )
324 {
325 updatingInterface = true;
326 partTabs.removeAll();
327 tree.setSelectionRow( -1 );
328 rootNode.removeAllChildren();
329 editors.clear();
330 groupNodes.clear();
331 pathMap.clear();
332 targetNamespaces.clear();
333 initTreeModel( ( WsdlInterface ) iface );
334 operationsTableModel.fireTableDataChanged();
335 updatingInterface = false;
336 }
337 }
338 }
339
340 private final class InternalTreeSelectionListener implements TreeSelectionListener
341 {
342 public void valueChanged( TreeSelectionEvent e )
343 {
344 TreePath newLeadSelectionPath = e.getNewLeadSelectionPath();
345 if( newLeadSelectionPath != null )
346 {
347 if( !navigating )
348 {
349
350 while( historyIndex < navigationHistory.size()-1 )
351 {
352 TreePath path = navigationHistory.remove( navigationHistory.size()-1 );
353 navigationHistory.add( historyIndex++, path );
354 }
355
356 navigationHistory.add( newLeadSelectionPath );
357 historyIndex = navigationHistory.size()-1;
358 }
359
360 DefaultMutableTreeNode tn = ( DefaultMutableTreeNode ) newLeadSelectionPath.getLastPathComponent();
361 if( tn.getUserObject() instanceof InspectItem )
362 {
363 InspectItem item = ( InspectItem ) tn.getUserObject();
364
365 partTabs.setSelectedIndex( item.getTabIndex() );
366 statusBar.setInfo( item.getDescription() );
367
368 JEditTextArea editor = editors.get( item.getTabIndex() );
369 int lineNumber = item.getLineNumber();
370 if( lineNumber > 0 && editor.getLineStartOffset( lineNumber ) >= 0 )
371 {
372 editor.setCaretPosition( editor.getLineStartOffset( lineNumber ) );
373 }
374 else
375 {
376 editor.setCaretPosition( 0 );
377 }
378 }
379
380 tree.scrollPathToVisible( newLeadSelectionPath );
381 tree.expandPath( newLeadSelectionPath );
382 }
383 }
384 }
385
386 private class Loader implements Worker
387 {
388 private static final String DEFINITION_PARTS_SECTION = "Definition Parts";
389 private ProgressDialog progressDialog;
390 private final WsdlInterface iface;
391 private JProgressBar progressBar;
392
393 public Loader( WsdlInterface iface )
394 {
395 this.iface = iface;
396 }
397
398 public Object construct( XProgressMonitor monitor )
399 {
400 MetricsSection section = metrics.getSection( DEFINITION_PARTS_SECTION );
401 section.clear();
402
403 try
404 {
405 List<InterfaceDefinitionPart> schemas = iface.getWsdlContext().getDefinitionParts();
406 int tabCount = partTabs.getTabCount();
407
408 for (InterfaceDefinitionPart part : schemas )
409 {
410 addTab( part.getUrl(), part.getContent() );
411 }
412
413 while( tabCount-- > 0 )
414 partTabs.remove( 0 );
415
416 return null;
417 }
418 catch (Exception e)
419 {
420 logger.error( "Failed to load WSDL; " + e.getClass().getSimpleName() + "; " + e.getMessage() );
421 add( new JLabel( "Failed to load WSDL; " + e.toString() ), BorderLayout.NORTH );
422
423 SoapUI.logError( e );
424
425 return e;
426 }
427 finally
428 {
429 section.finish();
430 }
431
432
433 }
434
435 private void addTab(String url, String content) throws Exception
436 {
437 int ix = url.startsWith( "file:" ) ? url.lastIndexOf( File.separatorChar ) : url.lastIndexOf( '/' );
438 if( ix == -1 )
439 ix = url.lastIndexOf( '/' );
440
441 String title = url.substring( ix+1);
442
443 metrics.getSection( DEFINITION_PARTS_SECTION ).addMetric( title, MetricType.URL ).set( url );
444
445 if( progressBar != null )
446 progressBar.setString( title );
447 else if( progressDialog != null )
448 progressDialog.setProgress( 1, title );
449
450 JPanel panel = new JPanel( new BorderLayout() );
451 JLabel label = new JLabel( url );
452 label.setBorder( BorderFactory.createEmptyBorder( 3, 3, 3, 3 ));
453 panel.add( label, BorderLayout.NORTH );
454
455 JXEditTextArea inputArea = JXEditTextArea.createXmlEditor( false );
456 StringWriter writer = new StringWriter();
457 XmlUtils.serializePretty( XmlObject.Factory.parse( content ), writer );
458 String xmlString = writer.toString();
459
460
461 XmlObject xmlObject = XmlObject.Factory.parse(xmlString, new XmlOptions().setLoadLineNumbers());
462
463 inputArea.setText( xmlString );
464 inputArea.setEditable( false );
465 inputArea.getPainter().setLineHighlightEnabled( true );
466
467 JPanel p = new JPanel( new BorderLayout() );
468 p.add( inputArea, BorderLayout.CENTER );
469 p.add( new LineNumbersPanel( inputArea ), BorderLayout.WEST );
470
471 panel.add( new JScrollPane( p ), BorderLayout.CENTER );
472 partTabs.addTab( title, panel );
473
474 if( tree != null )
475 {
476 initInspectionTree( xmlObject, inputArea );
477 }
478 }
479
480 private void initInspectionTree( XmlObject xmlObject, JXEditTextArea inputArea )
481 {
482 DefaultMutableTreeNode treeRoot = rootNode;
483
484 targetNamespaces.add( SchemaUtils.getTargetNamespace( xmlObject ));
485
486 int tabCount = partTabs.getTabCount()-1;
487 mapTreeItems( xmlObject, treeRoot, false, tabCount, "Complex Types",
488 "declare namespace xs='http://www.w3.org/2001/XMLSchema';//xs:complexType[@name!='']", "@name", true, null );
489
490 mapTreeItems( xmlObject, treeRoot, false, tabCount, "Simple Types",
491 "declare namespace xs='http://www.w3.org/2001/XMLSchema';//xs:simpleType[@name!='']", "@name", true, null );
492
493 mapTreeItems( xmlObject, treeRoot, false, tabCount, "Anonymous Complex Types",
494 "declare namespace xs='http://www.w3.org/2001/XMLSchema';//xs:complexType[not(exists(@name))]",
495 "parent::node()/@name", true, null );
496
497 mapTreeItems( xmlObject, treeRoot, false, tabCount, "Global Elements",
498 "declare namespace xs='http://www.w3.org/2001/XMLSchema';//xs:schema/xs:element[@name!='']", "@name",
499 true, new GlobalElementSelector() );
500
501 mapTreeItems( xmlObject, treeRoot, false, tabCount, "Schemas",
502 "declare namespace xs='http://www.w3.org/2001/XMLSchema';//xs:schema", "@targetNamespace", true, null );
503
504 List<DefaultMutableTreeNode> messages = mapTreeItems( xmlObject, treeRoot, false, tabCount, "Messages",
505 "declare namespace wsdl='http://schemas.xmlsoap.org/wsdl/';//wsdl:message", "@name", true, null );
506
507
508 for( DefaultMutableTreeNode treeNode : messages )
509 {
510 mapTreeItems( ((InspectItem)treeNode.getUserObject()).item, treeNode, false,
511 tabCount, null, "declare namespace wsdl='http://schemas.xmlsoap.org/wsdl/';wsdl:part",
512 "declare namespace wsdl='http://schemas.xmlsoap.org/wsdl/';concat('part: name=[', @name, '] type=[', @type, '] element=[', @element, ']' )",
513 true, new PartSelector() );
514 }
515
516 List<DefaultMutableTreeNode> portTypes = mapTreeItems( xmlObject, treeRoot, false, tabCount, "PortTypes",
517 "declare namespace wsdl='http://schemas.xmlsoap.org/wsdl/';//wsdl:portType", "@name", true, null );
518
519
520 for( DefaultMutableTreeNode treeNode : portTypes )
521 {
522 List<DefaultMutableTreeNode> operationNodes = mapTreeItems( ((InspectItem)treeNode.getUserObject()).item, treeNode, false,
523 tabCount, null, "declare namespace wsdl='http://schemas.xmlsoap.org/wsdl/';wsdl:operation", "@name", true, null );
524
525 for( DefaultMutableTreeNode treeNode2 : operationNodes )
526 {
527 mapTreeItems( ((InspectItem)treeNode2.getUserObject()).item, treeNode2, false, tabCount, null,
528 "declare namespace wsdl='http://schemas.xmlsoap.org/wsdl/';wsdl:*", "concat( @name, ' [', local-name(), '], message=[', @message, ']' )", false,
529 new MessageSelector());
530 }
531 }
532
533 List<DefaultMutableTreeNode> bindings = mapTreeItems( xmlObject, treeRoot, false, tabCount, "Bindings",
534 "declare namespace wsdl='http://schemas.xmlsoap.org/wsdl/';//wsdl:binding",
535 "declare namespace wsdlsoap='http://schemas.xmlsoap.org/wsdl/soap/';concat( @name, ' [style=', wsdlsoap:binding[1]/@style, ']' )", true, null );
536
537 for( DefaultMutableTreeNode treeNode : bindings )
538 {
539 List<DefaultMutableTreeNode> operationNodes = mapTreeItems( ((InspectItem)treeNode.getUserObject()).item, treeNode, false,
540 tabCount, null, "declare namespace wsdl='http://schemas.xmlsoap.org/wsdl/';wsdl:operation",
541 "declare namespace wsdlsoap='http://schemas.xmlsoap.org/wsdl/soap/';concat( @name, ' [soapAction=', wsdlsoap:operation/@soapAction, ']' )",
542 true, null );
543
544 for( DefaultMutableTreeNode treeNode2 : operationNodes )
545 {
546 mapTreeItems( ((InspectItem)treeNode2.getUserObject()).item, treeNode2, false, tabCount, null,
547 "declare namespace wsdl='http://schemas.xmlsoap.org/wsdl/';wsdl:*", "concat( @name, ' [', local-name(), ']' )", false,
548 new BindingOperationSelector() );
549 }
550 }
551
552 List<DefaultMutableTreeNode> services = mapTreeItems( xmlObject, treeRoot, false, tabCount, "Services",
553 "declare namespace wsdl='http://schemas.xmlsoap.org/wsdl/';//wsdl:service", "@name", true, null );
554
555 for( DefaultMutableTreeNode treeNode : services )
556 {
557 mapTreeItems( ((InspectItem)treeNode.getUserObject()).item, treeNode, false, tabCount, null,
558 "declare namespace wsdl='http://schemas.xmlsoap.org/wsdl/';wsdl:port", "concat( 'port: name=[', @name, '] binding=[', @binding, ']' )", true,
559 new PortSelector() );
560 }
561
562 tree.expandRow( 0 );
563 editors.add( inputArea );
564 }
565
566 public void finished()
567 {
568 if( progressDialog != null )
569 progressDialog.setVisible( false );
570
571 progressDialog = null;
572 }
573
574 public boolean onCancel()
575 {
576 progressBar = new JProgressBar(0, 1);
577 progressBar.setSize( new Dimension( 120, 20 ));
578 progressBar.setStringPainted(true);
579 progressBar.setString("Loading Definition.." );
580 progressBar.setIndeterminate(true);
581
582 ButtonBarBuilder builder = ButtonBarBuilder.createLeftToRightBuilder();
583 builder.addGlue();
584 builder.addFixed( progressBar );
585 builder.addGlue();
586 builder.setBorder( BorderFactory.createEmptyBorder( 10, 10, 10, 10 ));
587
588 partTabs.addTab( "Loading.. ", builder.getPanel() );
589 return true;
590 }
591 }
592
593 public boolean dependsOn(ModelItem modelItem)
594 {
595 return modelItem == getModelItem() || modelItem == getModelItem().getProject();
596 }
597
598 public List<DefaultMutableTreeNode> mapTreeItems( XmlObject xmlObject, DefaultMutableTreeNode treeRoot, boolean createEmpty,
599 int tabIndex, String groupName, String query, String nameQuery, boolean sort, NodeSelector selector )
600 {
601 List<DefaultMutableTreeNode> resultNodes = new ArrayList<DefaultMutableTreeNode>();
602
603 try
604 {
605 XmlObject[] items = xmlObject.selectPath( query );
606 List<DefaultMutableTreeNode> treeNodes = new ArrayList<DefaultMutableTreeNode>();
607
608 DefaultMutableTreeNode root = treeRoot;
609 if( groupName != null )
610 {
611 String groupKey = new TreePath( root.getPath() ).toString() + "/" + groupName;
612 root = groupNodes.get( groupKey );
613 if( root == null && (items.length > 0 || createEmpty))
614 {
615 root = new DefaultMutableTreeNode( groupName );
616 treeRoot.add( root );
617 groupNodes.put( groupKey, root );
618 }
619 else if( root != null )
620 {
621 Enumeration<?> children = root.children();
622 while( children.hasMoreElements() )
623 treeNodes.add( ( DefaultMutableTreeNode ) children.nextElement() );
624 }
625 }
626
627 if( items.length == 0 )
628 return resultNodes;
629
630 for( XmlObject item : items )
631 {
632 XmlObject[] selectPath = item.selectPath( nameQuery );
633 if( selectPath.length > 0 )
634 {
635 DefaultMutableTreeNode treeNode = new DefaultMutableTreeNode( new InspectItem( item, selectPath[0], tabIndex, selector ));
636 treeNodes.add( treeNode);
637 resultNodes.add( treeNode );
638 }
639 }
640
641 if( sort )
642 {
643 Collections.sort( treeNodes, new Comparator<DefaultMutableTreeNode>() {
644
645 public int compare( DefaultMutableTreeNode o1, DefaultMutableTreeNode o2 )
646 {
647 return o1.toString().compareTo( o2.toString() );
648 }} );
649 }
650
651 root.removeAllChildren();
652
653 for( DefaultMutableTreeNode treeNode : treeNodes )
654 {
655 root.add( treeNode );
656
657 String path = "/" + getTreeNodeName( treeNode );
658 TreePath treePath = new TreePath( treeNode.getPath());
659 while( treeNode.getParent() != null )
660 {
661 treeNode = ( DefaultMutableTreeNode ) treeNode.getParent();
662 path = "/" + getTreeNodeName( treeNode ) + path;
663 }
664
665 pathMap.put( path, treePath );
666 }
667 }
668 catch( Throwable e )
669 {
670 SoapUI.log( "Failed to map items for query [" + query + "]:[" + nameQuery + "]" );
671 SoapUI.logError( e );
672 }
673
674 return resultNodes;
675 }
676
677 private String getTreeNodeName( DefaultMutableTreeNode treeNode )
678 {
679 Object userObject = treeNode.getUserObject();
680 if( userObject instanceof InspectItem )
681 return (( InspectItem ) userObject ).getName();
682 else
683 return treeNode.toString();
684 }
685
686 private final class InspectItem
687 {
688 private final XmlObject item;
689 private String name;
690 private final int tabIndex;
691 private XmlLineNumber lineNumber;
692 private final NodeSelector selector;
693
694 public InspectItem( XmlObject item, XmlObject nameObj, int tabIndex, NodeSelector selector )
695 {
696 this.item = item;
697 this.selector = selector;
698 this.name = XmlUtils.getNodeValue( nameObj.getDomNode() );
699 if( name == null )
700 name = nameObj.toString();
701 this.tabIndex = tabIndex;
702
703 ArrayList<?> list = new ArrayList<Object>();
704 XmlCursor cursor = item.newCursor();
705 cursor.getAllBookmarkRefs( list );
706
707 for( Object o : list )
708 if( o instanceof XmlLineNumber )
709 lineNumber = (XmlLineNumber) o;
710
711 cursor.dispose();
712 }
713
714 public String getDescription()
715 {
716 return getName() + "@" + targetNamespaces.get( tabIndex );
717 }
718
719 public String getName()
720 {
721 int ix = name.indexOf( ' ' );
722 return ix == -1 ? name : name.substring( 0, ix );
723 }
724
725 public int getTabIndex()
726 {
727 return tabIndex;
728 }
729
730 public int getLineNumber()
731 {
732 return lineNumber == null ? -1 : lineNumber.getLine()-1;
733 }
734
735 @Override
736 public String toString()
737 {
738 return name;
739 }
740
741 public NodeSelector getSelector()
742 {
743 return selector;
744 }
745
746 public Element getElement()
747 {
748 return ( Element ) item.getDomNode();
749 }
750 }
751
752 public boolean onClose( boolean canCancel )
753 {
754 if( projectListener != null )
755 getModelItem().getProject().removeProjectListener( projectListener );
756
757 return release();
758 }
759
760 private void simpleSelect( InspectItem item, String attribute, String targetGroup )
761 {
762 Element elm = item.getElement();
763 String type = elm.getAttribute( attribute );
764 if( type.length() > 0 )
765 {
766 int ix = type.indexOf( ':' );
767 if( ix != -1 )
768 type = type.substring( ix+1 );
769
770
771 TreePath treePath = pathMap.get( "/" + getModelItem().getName() + "/" + targetGroup + "/" + type );
772 if( treePath != null )
773 {
774 tree.setSelectionPath( treePath );
775 }
776 }
777 }
778
779 protected interface NodeSelector
780 {
781 public void selectNode( InspectItem item );
782 }
783
784 public class PartSelector implements NodeSelector
785 {
786 public void selectNode( InspectItem item )
787 {
788 Element elm = item.getElement();
789 String type = elm.getAttribute( "type" );
790 String element = elm.getAttribute( "element" );
791 if( type.length() > 0 )
792 {
793 simpleSelect( item, "type", "Complex Types" );
794 }
795 else if( element.length() > 0 )
796 {
797 simpleSelect( item, "element", "Global Elements" );
798 }
799 }}
800
801 public class MessageSelector implements NodeSelector
802 {
803 public void selectNode( InspectItem item )
804 {
805 simpleSelect( item, "message", "Messages" );
806 }}
807
808 public class GlobalElementSelector implements NodeSelector
809 {
810 public void selectNode( InspectItem item )
811 {
812 simpleSelect( item, "type", "Complex Types" );
813 }}
814
815 public class PortSelector implements NodeSelector
816 {
817 public void selectNode( InspectItem item )
818 {
819 simpleSelect( item, "binding", "Bindings" );
820 }}
821
822 public class BindingOperationSelector implements NodeSelector
823 {
824 public void selectNode( InspectItem item )
825 {
826 Element elm = item.getElement();
827 String name = elm.getAttribute( "name" );
828
829 Element operationElm = ( Element ) elm.getParentNode();
830 Element bindingElm = ( Element ) operationElm.getParentNode();
831
832 String type = bindingElm.getAttribute( "type" );
833
834 if( type.length() > 0 )
835 {
836 int ix = type.indexOf( ':' );
837 if( ix != -1 )
838 type = type.substring( ix+1 );
839
840 TreePath treePath = pathMap.get( "/" + getModelItem().getName() + "/PortTypes/" + type + "/" +
841 operationElm.getAttribute( "name" ) + "/" + name );
842 if( treePath != null )
843 {
844 tree.setSelectionPath( treePath );
845 }
846 }
847 }}
848
849 private class BackwardAction extends AbstractAction
850 {
851 public BackwardAction()
852 {
853 putValue( SMALL_ICON, UISupport.createImageIcon( "/arrow_left.png" ));
854 putValue( Action.SHORT_DESCRIPTION, "Navigate to previous selection" );
855 }
856
857 public void actionPerformed( ActionEvent arg0 )
858 {
859 if( historyIndex > 0 )
860 {
861 historyIndex--;
862 navigating = true;
863 tree.setSelectionPath( navigationHistory.get( historyIndex ) );
864 navigating = false;
865 }
866 }}
867
868 private class ForwardAction extends AbstractAction
869 {
870 public ForwardAction()
871 {
872 putValue( SMALL_ICON, UISupport.createImageIcon( "/arrow_right.png" ));
873 putValue( Action.SHORT_DESCRIPTION, "Navigate to next selection" );
874 }
875
876 public void actionPerformed( ActionEvent arg0 )
877 {
878 if( historyIndex < navigationHistory.size()-1 )
879 {
880 historyIndex++;
881 navigating = true;
882 tree.setSelectionPath( navigationHistory.get( historyIndex ) );
883 navigating = false;
884 }
885
886 }}
887
888 private class RunWSIAction extends AbstractAction
889 {
890 public RunWSIAction()
891 {
892 putValue( SMALL_ICON, UISupport.createImageIcon( "/run.gif" ));
893 putValue( Action.SHORT_DESCRIPTION, "Creates a WS-I report for this interface" );
894 }
895
896 public void actionPerformed( ActionEvent arg0 )
897 {
898 WSIAnalyzeAction action = new WSIAnalyzeAction()
899 {
900 @Override
901 protected void showReport( File reportFile, String configFile ) throws Exception
902 {
903 reportPanel = new WSIReportPanel( reportFile, configFile, null, false );
904 reportPanel.setPreferredSize( new Dimension( 600, 400 ));
905 if( wsiPanel.getComponentCount() > 1 )
906 wsiPanel.remove( 1 );
907
908 wsiPanel.add( reportPanel, BorderLayout.CENTER );
909 wsiPanel.revalidate();
910 saveWsiReportAction.setEnabled( true );
911 }
912 };
913
914 action.perform( getModelItem(), null );
915 }}
916
917 private class WSIOptionsAction extends AbstractAction
918 {
919 public WSIOptionsAction()
920 {
921 putValue( SMALL_ICON, UISupport.createImageIcon( "/options.gif" ));
922 putValue( Action.SHORT_DESCRIPTION, "Sets WS-I report creation options" );
923 }
924
925 public void actionPerformed( ActionEvent arg0 )
926 {
927 SoapUIPreferencesAction.getInstance().show( SoapUIPreferencesAction.WS_I_SETTINGS );
928 }
929 }
930
931 private class SaveWsiReportAction extends AbstractAction
932 {
933 public SaveWsiReportAction()
934 {
935 putValue( SMALL_ICON, UISupport.createImageIcon( "/export.gif" ));
936 putValue( Action.SHORT_DESCRIPTION, "Saved the current WS-I report to a file" );
937
938 setEnabled( false );
939 }
940
941 public void actionPerformed( ActionEvent arg0 )
942 {
943 if( reportPanel != null )
944 reportPanel.getSaveReportAction().actionPerformed( null );
945 }
946 }
947
948 private class OperationsTableModel extends AbstractTableModel
949 {
950 public int getColumnCount()
951 {
952 return 4;
953 }
954
955 public int getRowCount()
956 {
957 return iface.getOperationCount();
958 }
959
960 @Override
961 public String getColumnName( int column )
962 {
963 switch( column )
964 {
965 case 0 : return "Name";
966 case 1 : return "Use";
967 case 2 : return "One-Way";
968 case 3 : return "Action";
969 }
970
971 return null;
972 }
973
974 public Object getValueAt( int rowIndex, int columnIndex )
975 {
976 if( updatingInterface )
977 return "<updating>";
978
979 WsdlOperation operation = iface.getOperationAt( rowIndex );
980 BindingOperation bindingOperation = operation.getBindingOperation();
981
982 switch( columnIndex )
983 {
984 case 0 : return operation.getName();
985 case 1 :
986 {
987 boolean in = WsdlUtils.isInputSoapEncoded( bindingOperation );
988 boolean out = operation.isUnidirectional() ? false : WsdlUtils.isOutputSoapEncoded( bindingOperation );
989
990 if( out && in )
991 return "SOAP Encoding";
992 if( !out && !in )
993 return "Literal";
994
995 return "Mixed";
996 }
997 case 3 : return operation.getAction();
998 case 2 : return Boolean.valueOf( operation.isUnidirectional() );
999 }
1000
1001 return null;
1002 }}
1003 }