1
2
3
4
5
6
7
8
9
10
11
12
13 package com.eviware.soapui.impl.wsdl.panels.iface;
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.awt.event.MouseAdapter;
20 import java.awt.event.MouseEvent;
21 import java.io.File;
22 import java.io.StringWriter;
23 import java.util.ArrayList;
24 import java.util.Collections;
25 import java.util.Comparator;
26 import java.util.Enumeration;
27 import java.util.HashMap;
28 import java.util.Iterator;
29 import java.util.List;
30 import java.util.Map;
31
32 import javax.swing.AbstractAction;
33 import javax.swing.Action;
34 import javax.swing.BorderFactory;
35 import javax.swing.JButton;
36 import javax.swing.JLabel;
37 import javax.swing.JPanel;
38 import javax.swing.JProgressBar;
39 import javax.swing.JScrollPane;
40 import javax.swing.JSplitPane;
41 import javax.swing.JTabbedPane;
42 import javax.swing.JTree;
43 import javax.swing.event.TreeSelectionEvent;
44 import javax.swing.event.TreeSelectionListener;
45 import javax.swing.tree.DefaultMutableTreeNode;
46 import javax.swing.tree.DefaultTreeModel;
47 import javax.swing.tree.TreePath;
48
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.syntax.jedit.JEditTextArea;
55 import org.w3c.dom.Element;
56
57 import com.eviware.soapui.SoapUI;
58 import com.eviware.soapui.impl.wsdl.WsdlInterface;
59 import com.eviware.soapui.impl.wsdl.actions.iface.ExportDefinitionAction;
60 import com.eviware.soapui.impl.wsdl.actions.iface.UpdateInterfaceAction;
61 import com.eviware.soapui.impl.wsdl.actions.support.ShowOnlineHelpAction;
62 import com.eviware.soapui.impl.wsdl.support.HelpUrls;
63 import com.eviware.soapui.impl.wsdl.support.xsd.SchemaUtils;
64 import com.eviware.soapui.model.ModelItem;
65 import com.eviware.soapui.model.iface.Interface;
66 import com.eviware.soapui.model.support.ProjectListenerAdapter;
67 import com.eviware.soapui.support.UISupport;
68 import com.eviware.soapui.support.action.swing.SwingActionDelegate;
69 import com.eviware.soapui.support.components.JEditorStatusBar;
70 import com.eviware.soapui.support.components.JXToolBar;
71 import com.eviware.soapui.support.components.ProgressDialog;
72 import com.eviware.soapui.support.types.StringList;
73 import com.eviware.soapui.support.xml.JXEditTextArea;
74 import com.eviware.soapui.support.xml.XmlUtils;
75 import com.eviware.soapui.ui.support.ModelItemDesktopPanel;
76 import com.eviware.x.dialogs.Worker;
77 import com.eviware.x.dialogs.XProgressDialog;
78 import com.eviware.x.dialogs.XProgressMonitor;
79 import com.jgoodies.forms.builder.ButtonBarBuilder;
80
81 /***
82 * DesktopPanel for WsdlInterface. Loads all referenced wsdls/xsds for the specified WsdlInterface
83 * and displays these in seperate tabs
84 *
85 * @author Ole.Matzura
86 */
87
88 public class WsdlInterfaceDesktopPanel extends ModelItemDesktopPanel<WsdlInterface>
89 {
90 private final static Logger logger = Logger.getLogger( WsdlInterfaceDesktopPanel.class );
91 private JTabbedPane tabbedPane;
92 private List<JEditTextArea> editors = new ArrayList<JEditTextArea>();
93 private JTree tree;
94 private Map<String,DefaultMutableTreeNode> groupNodes = new HashMap<String,DefaultMutableTreeNode>();
95 private Map<String,TreePath> pathMap = new HashMap<String,TreePath>();
96 private List<TreePath> navigationHistory = new ArrayList<TreePath>();
97 private StringList targetNamespaces = new StringList();
98 public int historyIndex;
99 public boolean navigating;
100 private JEditorStatusBar statusBar;
101 private DefaultMutableTreeNode rootNode;
102 private DefaultTreeModel treeModel;
103 private InternalProjectListener projectListener;
104
105 public WsdlInterfaceDesktopPanel(WsdlInterface iface)
106 {
107 super( iface );
108
109 tabbedPane = new JTabbedPane();
110 tabbedPane.setTabLayoutPolicy( JTabbedPane.SCROLL_TAB_LAYOUT );
111
112 rootNode = new DefaultMutableTreeNode( iface.getName() );
113 treeModel = new DefaultTreeModel( rootNode );
114 tree = new JTree( treeModel );
115 tree.setBorder( BorderFactory.createEmptyBorder( 2, 2, 2, 2) );
116 tree.setExpandsSelectedPaths( true );
117 tree.addTreeSelectionListener( new InternalTreeSelectionListener() );
118 tree.addMouseListener( new MouseAdapter() {
119
120 @Override
121 public void mouseClicked( MouseEvent arg0 )
122 {
123 if( arg0.getClickCount() > 1 )
124 {
125 TreePath selectionPath = tree.getSelectionPath();
126 if( selectionPath != null )
127 {
128 DefaultMutableTreeNode treeNode = ( DefaultMutableTreeNode ) selectionPath.getLastPathComponent();
129 Object userObject = treeNode.getUserObject();
130 if( userObject instanceof InspectItem )
131 {
132 InspectItem item = ( InspectItem ) userObject;
133 if( item != null && item.selector != null )
134 {
135 item.selector.selectNode( item );
136 }
137 }
138 }
139 }
140 }} );
141
142 JScrollPane scrollPane = new JScrollPane( tree );
143 JSplitPane split = UISupport.createHorizontalSplit( scrollPane,
144 UISupport.createTabPanel( tabbedPane, true ));
145
146 add( split, BorderLayout.CENTER );
147
148 split.setDividerLocation( 250 );
149 split.setResizeWeight( 0.3 );
150
151 initTreeModel( iface );
152
153 add( buildToolbar(), BorderLayout.PAGE_START );
154 statusBar = new JEditorStatusBar( );
155 add( statusBar, BorderLayout.PAGE_END );
156 setPreferredSize( new Dimension( 600, 500 ));
157
158 projectListener = new InternalProjectListener();
159 iface.getProject().addProjectListener( projectListener );
160 }
161
162 private void initTreeModel( WsdlInterface iface )
163 {
164 try
165 {
166 if( iface.getWsdlContext().loadIfNecessary( false ))
167 {
168 XProgressDialog progressDialog = UISupport.getDialogs().createProgressDialog(
169 "Loading Defintion", 3, "Initializing definition..", true );
170 Loader loader = new Loader( iface );
171
172 if( progressDialog != null )
173 progressDialog.setCancelLabel( "Run in background" );
174
175 progressDialog.run( loader );
176 loader = null;
177 treeModel.nodeStructureChanged( rootNode );
178 }
179 }
180 catch (Exception e)
181 {
182 SoapUI.logError( e );
183 }
184 }
185
186 private Component buildToolbar()
187 {
188 JXToolBar toolbar = UISupport.createToolbar();
189
190 toolbar.addFixed( new JButton( new BackwardAction() ) );
191 toolbar.addFixed( new JButton( new ForwardAction() ) );
192 toolbar.addUnrelatedGap();
193 JButton button = new JButton( SwingActionDelegate.createDelegate( UpdateInterfaceAction.SOAPUI_ACTION_ID, getModelItem(),
194 null, "/updateDefinition.gif" ));
195 button.setText( null );
196 toolbar.addFixed( button);
197 button = new JButton( SwingActionDelegate.createDelegate( ExportDefinitionAction.SOAPUI_ACTION_ID, getModelItem(),
198 null, "/exportDefinition.gif"));
199 button.setText( null );
200 toolbar.addFixed( button);
201 toolbar.addGlue();
202 button = new JButton( new ShowOnlineHelpAction( HelpUrls.INTERFACE_HELP_URL ));
203 button.setText( null );
204 toolbar.addFixed( button);
205
206 return toolbar;
207 }
208
209 private final class InternalProjectListener extends ProjectListenerAdapter
210 {
211 @Override
212 public void interfaceUpdated( Interface iface )
213 {
214 if( iface == getModelItem() )
215 {
216 tabbedPane.removeAll();
217 tree.setSelectionRow( -1 );
218 rootNode.removeAllChildren();
219 editors.clear();
220 groupNodes.clear();
221 pathMap.clear();
222 targetNamespaces.clear();
223 initTreeModel( ( WsdlInterface ) iface );
224 }
225 }
226 }
227
228 private final class InternalTreeSelectionListener implements TreeSelectionListener
229 {
230 public void valueChanged( TreeSelectionEvent e )
231 {
232 TreePath newLeadSelectionPath = e.getNewLeadSelectionPath();
233 if( newLeadSelectionPath != null )
234 {
235 if( !navigating )
236 {
237
238 while( historyIndex < navigationHistory.size()-1 )
239 {
240 TreePath path = navigationHistory.remove( navigationHistory.size()-1 );
241 navigationHistory.add( historyIndex++, path );
242 }
243
244 navigationHistory.add( newLeadSelectionPath );
245 historyIndex = navigationHistory.size()-1;
246 }
247
248 DefaultMutableTreeNode tn = ( DefaultMutableTreeNode ) newLeadSelectionPath.getLastPathComponent();
249 if( tn.getUserObject() instanceof InspectItem )
250 {
251 InspectItem item = ( InspectItem ) tn.getUserObject();
252
253 tabbedPane.setSelectedIndex( item.getTabIndex() );
254 statusBar.setInfo( item.getDescription() );
255
256 JEditTextArea editor = editors.get( item.getTabIndex() );
257 int lineNumber = item.getLineNumber();
258 if( lineNumber > 0 && editor.getLineStartOffset( lineNumber ) >= 0 )
259 {
260 editor.setCaretPosition( editor.getLineStartOffset( lineNumber ) );
261 }
262 else
263 {
264 editor.setCaretPosition( 0 );
265 }
266 }
267
268 tree.scrollPathToVisible( newLeadSelectionPath );
269 tree.expandPath( newLeadSelectionPath );
270 }
271 }
272 }
273
274 private class Loader implements Worker
275 {
276 private ProgressDialog progressDialog;
277 private final WsdlInterface iface;
278 private JProgressBar progressBar;
279
280 public Loader( WsdlInterface iface )
281 {
282 this.iface = iface;
283 }
284
285 public Object construct( XProgressMonitor monitor )
286 {
287 try
288 {
289 Map<String, XmlObject> schemas = iface.getWsdlContext().getDefinitionParts();
290 int tabCount = tabbedPane.getTabCount();
291
292 for (Iterator<String> iter = schemas.keySet().iterator(); iter.hasNext();)
293 {
294 String url = iter.next();
295 addTab( url, schemas.get( url ) );
296 }
297
298 while( tabCount-- > 0 )
299 tabbedPane.remove( 0 );
300
301 return null;
302 }
303 catch (Exception e)
304 {
305 logger.error( "Failed to load WSDL; " + e.getClass().getSimpleName() + "; " + e.getMessage() );
306 add( new JLabel( "Failed to load WSDL; " + e.toString() ), BorderLayout.NORTH );
307
308 SoapUI.logError( e );
309
310 return e;
311 }
312 }
313
314 private void addTab(String url, XmlObject xmlObject) throws Exception
315 {
316 int ix = url.startsWith( "file:" ) ? url.lastIndexOf( File.separatorChar ) : url.lastIndexOf( '/' );
317 String title = url.substring( ix+1);
318
319 if( progressBar != null )
320 progressBar.setString( title );
321 else if( progressDialog != null )
322 progressDialog.setProgress( 1, title );
323
324 JPanel panel = new JPanel( new BorderLayout() );
325 JLabel label = new JLabel( url );
326 label.setBorder( BorderFactory.createEmptyBorder( 3, 3, 3, 3 ));
327 panel.add( label, BorderLayout.NORTH );
328
329 JXEditTextArea inputArea = JXEditTextArea.createXmlEditor();
330 StringWriter writer = new StringWriter();
331 XmlUtils.serializePretty( xmlObject, writer );
332 String xmlString = writer.toString();
333
334
335 xmlObject = XmlObject.Factory.parse( xmlString, new XmlOptions().setLoadLineNumbers() );
336
337 inputArea.setText( xmlString );
338 inputArea.setEditable( false );
339 inputArea.getPainter().setLineHighlightEnabled( true );
340
341 panel.add( new JScrollPane( inputArea ), BorderLayout.CENTER );
342 tabbedPane.addTab( title, panel );
343
344 if( tree != null )
345 {
346 initInspectionTree( xmlObject, inputArea );
347 }
348 }
349
350 private void initInspectionTree( XmlObject xmlObject, JXEditTextArea inputArea )
351 {
352 DefaultMutableTreeNode treeRoot = rootNode;
353
354 targetNamespaces.add( SchemaUtils.getTargetNamespace( xmlObject ));
355
356 int tabCount = tabbedPane.getTabCount()-1;
357 mapTreeItems( xmlObject, treeRoot, false, tabCount, "Complex Types",
358 "declare namespace xs='http://www.w3.org/2001/XMLSchema';//xs:complexType[@name!='']", "@name", true, null );
359
360 mapTreeItems( xmlObject, treeRoot, false, tabCount, "Simple Types",
361 "declare namespace xs='http://www.w3.org/2001/XMLSchema';//xs:simpleType[@name!='']", "@name", true, null );
362
363 mapTreeItems( xmlObject, treeRoot, false, tabCount, "Anonymous Complex Types",
364 "declare namespace xs='http://www.w3.org/2001/XMLSchema';//xs:complexType[not(exists(@name))]",
365 "parent::node()/@name", true, null );
366
367 mapTreeItems( xmlObject, treeRoot, false, tabCount, "Global Elements",
368 "declare namespace xs='http://www.w3.org/2001/XMLSchema';//xs:schema/xs:element[@name!='']", "@name",
369 true, new GlobalElementSelector() );
370
371 mapTreeItems( xmlObject, treeRoot, false, tabCount, "Schemas",
372 "declare namespace xs='http://www.w3.org/2001/XMLSchema';//xs:schema", "@targetNamespace", true, null );
373
374 List<DefaultMutableTreeNode> messages = mapTreeItems( xmlObject, treeRoot, false, tabCount, "Messages",
375 "declare namespace wsdl='http://schemas.xmlsoap.org/wsdl/';//wsdl:message", "@name", true, null );
376
377
378 for( DefaultMutableTreeNode treeNode : messages )
379 {
380 mapTreeItems( ((InspectItem)treeNode.getUserObject()).item, treeNode, false,
381 tabCount, null, "declare namespace wsdl='http://schemas.xmlsoap.org/wsdl/';wsdl:part",
382 "declare namespace wsdl='http://schemas.xmlsoap.org/wsdl/';concat('part: name=[', @name, '] type=[', @type, '] element=[', @element, ']' )",
383 true, new PartSelector() );
384 }
385
386 List<DefaultMutableTreeNode> portTypes = mapTreeItems( xmlObject, treeRoot, false, tabCount, "PortTypes",
387 "declare namespace wsdl='http://schemas.xmlsoap.org/wsdl/';//wsdl:portType", "@name", true, null );
388
389
390 for( DefaultMutableTreeNode treeNode : portTypes )
391 {
392 List<DefaultMutableTreeNode> operationNodes = mapTreeItems( ((InspectItem)treeNode.getUserObject()).item, treeNode, false,
393 tabCount, null, "declare namespace wsdl='http://schemas.xmlsoap.org/wsdl/';wsdl:operation", "@name", true, null );
394
395 for( DefaultMutableTreeNode treeNode2 : operationNodes )
396 {
397 mapTreeItems( ((InspectItem)treeNode2.getUserObject()).item, treeNode2, false, tabCount, null,
398 "declare namespace wsdl='http://schemas.xmlsoap.org/wsdl/';wsdl:*", "concat( @name, ' [', local-name(), '], message=[', @message, ']' )", false,
399 new MessageSelector());
400 }
401 }
402
403 List<DefaultMutableTreeNode> bindings = mapTreeItems( xmlObject, treeRoot, false, tabCount, "Bindings",
404 "declare namespace wsdl='http://schemas.xmlsoap.org/wsdl/';//wsdl:binding",
405 "declare namespace wsdlsoap='http://schemas.xmlsoap.org/wsdl/soap/';concat( @name, ' [style=', wsdlsoap:binding[1]/@style, ']' )", true, null );
406
407 for( DefaultMutableTreeNode treeNode : bindings )
408 {
409 List<DefaultMutableTreeNode> operationNodes = mapTreeItems( ((InspectItem)treeNode.getUserObject()).item, treeNode, false,
410 tabCount, null, "declare namespace wsdl='http://schemas.xmlsoap.org/wsdl/';wsdl:operation",
411 "declare namespace wsdlsoap='http://schemas.xmlsoap.org/wsdl/soap/';concat( @name, ' [soapAction=', wsdlsoap:operation/@soapAction, ']' )",
412 true, null );
413
414 for( DefaultMutableTreeNode treeNode2 : operationNodes )
415 {
416 mapTreeItems( ((InspectItem)treeNode2.getUserObject()).item, treeNode2, false, tabCount, null,
417 "declare namespace wsdl='http://schemas.xmlsoap.org/wsdl/';wsdl:*", "concat( @name, ' [', local-name(), ']' )", false,
418 new BindingOperationSelector() );
419 }
420 }
421
422 List<DefaultMutableTreeNode> services = mapTreeItems( xmlObject, treeRoot, false, tabCount, "Services",
423 "declare namespace wsdl='http://schemas.xmlsoap.org/wsdl/';//wsdl:service", "@name", true, null );
424
425 for( DefaultMutableTreeNode treeNode : services )
426 {
427 mapTreeItems( ((InspectItem)treeNode.getUserObject()).item, treeNode, false, tabCount, null,
428 "declare namespace wsdl='http://schemas.xmlsoap.org/wsdl/';wsdl:port", "concat( 'port: name=[', @name, '] binding=[', @binding, ']' )", true,
429 new PortSelector() );
430 }
431
432 tree.expandRow( 0 );
433 editors.add( inputArea );
434 }
435
436 public void finished()
437 {
438 if( progressDialog != null )
439 progressDialog.setVisible( false );
440
441 progressDialog = null;
442 }
443
444 public boolean onCancel()
445 {
446 progressBar = new JProgressBar(0, 1);
447 progressBar.setSize( new Dimension( 120, 20 ));
448 progressBar.setStringPainted(true);
449 progressBar.setString("Loading Definition.." );
450 progressBar.setIndeterminate(true);
451
452 ButtonBarBuilder builder = ButtonBarBuilder.createLeftToRightBuilder();
453 builder.addGlue();
454 builder.addFixed( progressBar );
455 builder.addGlue();
456 builder.setBorder( BorderFactory.createEmptyBorder( 10, 10, 10, 10 ));
457
458 tabbedPane.addTab( "Loading.. ", builder.getPanel() );
459 return true;
460 }
461 }
462
463 public boolean dependsOn(ModelItem modelItem)
464 {
465 return modelItem == getModelItem() || modelItem == getModelItem().getProject();
466 }
467
468 public List<DefaultMutableTreeNode> mapTreeItems( XmlObject xmlObject, DefaultMutableTreeNode treeRoot, boolean createEmpty,
469 int tabIndex, String groupName, String query, String nameQuery, boolean sort, NodeSelector selector )
470 {
471 List<DefaultMutableTreeNode> resultNodes = new ArrayList<DefaultMutableTreeNode>();
472
473 try
474 {
475 XmlObject[] items = xmlObject.selectPath( query );
476 List<DefaultMutableTreeNode> treeNodes = new ArrayList<DefaultMutableTreeNode>();
477
478 DefaultMutableTreeNode root = treeRoot;
479 if( groupName != null )
480 {
481 String groupKey = new TreePath( root.getPath() ).toString() + "/" + groupName;
482 root = groupNodes.get( groupKey );
483 if( root == null && (items.length > 0 || createEmpty))
484 {
485 root = new DefaultMutableTreeNode( groupName );
486 treeRoot.add( root );
487 groupNodes.put( groupKey, root );
488 }
489 else if( root != null )
490 {
491 Enumeration children = root.children();
492 while( children.hasMoreElements() )
493 treeNodes.add( ( DefaultMutableTreeNode ) children.nextElement() );
494 }
495 }
496
497 if( items.length == 0 )
498 return resultNodes;
499
500 for( XmlObject item : items )
501 {
502 XmlObject[] selectPath = item.selectPath( nameQuery );
503 if( selectPath.length > 0 )
504 {
505 DefaultMutableTreeNode treeNode = new DefaultMutableTreeNode( new InspectItem( item, selectPath[0], tabIndex, selector ));
506 treeNodes.add( treeNode);
507 resultNodes.add( treeNode );
508 }
509 }
510
511 if( sort )
512 {
513 Collections.sort( treeNodes, new Comparator<DefaultMutableTreeNode>() {
514
515 public int compare( DefaultMutableTreeNode o1, DefaultMutableTreeNode o2 )
516 {
517 return o1.toString().compareTo( o2.toString() );
518 }} );
519 }
520
521 root.removeAllChildren();
522
523 for( DefaultMutableTreeNode treeNode : treeNodes )
524 {
525 root.add( treeNode );
526
527 String path = "/" + getTreeNodeName( treeNode );
528 TreePath treePath = new TreePath( treeNode.getPath());
529 while( treeNode.getParent() != null )
530 {
531 treeNode = ( DefaultMutableTreeNode ) treeNode.getParent();
532 path = "/" + getTreeNodeName( treeNode ) + path;
533 }
534
535 pathMap.put( path, treePath );
536 }
537 }
538 catch( Throwable e )
539 {
540 SoapUI.log( "Failed to map items for query [" + query + "]:[" + nameQuery + "]" );
541 SoapUI.logError( e );
542 }
543
544 return resultNodes;
545 }
546
547 private String getTreeNodeName( DefaultMutableTreeNode treeNode )
548 {
549 Object userObject = treeNode.getUserObject();
550 if( userObject instanceof InspectItem )
551 return (( InspectItem ) userObject ).getName();
552 else
553 return treeNode.toString();
554 }
555
556 private final class InspectItem
557 {
558 private final XmlObject item;
559 private String name;
560 private final int tabIndex;
561 private XmlLineNumber lineNumber;
562 private final NodeSelector selector;
563
564 public InspectItem( XmlObject item, XmlObject nameObj, int tabIndex, NodeSelector selector )
565 {
566 this.item = item;
567 this.selector = selector;
568 this.name = XmlUtils.getNodeValue( nameObj.getDomNode() );
569 if( name == null )
570 name = nameObj.toString();
571 this.tabIndex = tabIndex;
572
573 ArrayList list = new ArrayList();
574 XmlCursor cursor = item.newCursor();
575 cursor.getAllBookmarkRefs( list );
576
577 for( Object o : list )
578 if( o instanceof XmlLineNumber )
579 lineNumber = (XmlLineNumber) o;
580
581 cursor.dispose();
582 }
583
584 public String getDescription()
585 {
586 return getName() + "@" + targetNamespaces.get( tabIndex );
587 }
588
589 public String getName()
590 {
591 int ix = name.indexOf( ' ' );
592 return ix == -1 ? name : name.substring( 0, ix );
593 }
594
595 public int getTabIndex()
596 {
597 return tabIndex;
598 }
599
600 public int getLineNumber()
601 {
602 return lineNumber == null ? -1 : lineNumber.getLine()-1;
603 }
604
605 @Override
606 public String toString()
607 {
608 return name;
609 }
610
611 public NodeSelector getSelector()
612 {
613 return selector;
614 }
615
616 public Element getElement()
617 {
618 return ( Element ) item.getDomNode();
619 }
620 }
621
622 public boolean onClose( boolean canCancel )
623 {
624 getModelItem().getProject().removeProjectListener( projectListener );
625 return release();
626 }
627
628 private void simpleSelect( InspectItem item, String attribute, String targetGroup )
629 {
630 Element elm = item.getElement();
631 String type = elm.getAttribute( attribute );
632 if( type.length() > 0 )
633 {
634 int ix = type.indexOf( ':' );
635 if( ix != -1 )
636 type = type.substring( ix+1 );
637
638
639 TreePath treePath = pathMap.get( "/" + getModelItem().getName() + "/" + targetGroup + "/" + type );
640 if( treePath != null )
641 {
642 tree.setSelectionPath( treePath );
643 }
644 }
645 }
646
647 protected interface NodeSelector
648 {
649 public void selectNode( InspectItem item );
650 }
651
652 public class PartSelector implements NodeSelector
653 {
654 public void selectNode( InspectItem item )
655 {
656 Element elm = item.getElement();
657 String type = elm.getAttribute( "type" );
658 String element = elm.getAttribute( "element" );
659 if( type.length() > 0 )
660 {
661 simpleSelect( item, "type", "Complex Types" );
662 }
663 else if( element.length() > 0 )
664 {
665 simpleSelect( item, "element", "Global Elements" );
666 }
667 }}
668
669 public class MessageSelector implements NodeSelector
670 {
671 public void selectNode( InspectItem item )
672 {
673 simpleSelect( item, "message", "Messages" );
674 }}
675
676 public class GlobalElementSelector implements NodeSelector
677 {
678 public void selectNode( InspectItem item )
679 {
680 simpleSelect( item, "type", "Complex Types" );
681 }}
682
683 public class PortSelector implements NodeSelector
684 {
685 public void selectNode( InspectItem item )
686 {
687 simpleSelect( item, "binding", "Bindings" );
688 }}
689
690 public class BindingOperationSelector implements NodeSelector
691 {
692 public void selectNode( InspectItem item )
693 {
694 Element elm = item.getElement();
695 String name = elm.getAttribute( "name" );
696
697 Element operationElm = ( Element ) elm.getParentNode();
698 Element bindingElm = ( Element ) operationElm.getParentNode();
699
700 String type = bindingElm.getAttribute( "type" );
701
702 if( type.length() > 0 )
703 {
704 int ix = type.indexOf( ':' );
705 if( ix != -1 )
706 type = type.substring( ix+1 );
707
708 TreePath treePath = pathMap.get( "/" + getModelItem().getName() + "/PortTypes/" + type + "/" +
709 operationElm.getAttribute( "name" ) + "/" + name );
710 if( treePath != null )
711 {
712 tree.setSelectionPath( treePath );
713 }
714 }
715 }}
716
717 private class BackwardAction extends AbstractAction
718 {
719 public BackwardAction()
720 {
721 super( "<");
722 putValue( Action.SHORT_DESCRIPTION, "Navigate to previous selection" );
723 }
724
725 public void actionPerformed( ActionEvent arg0 )
726 {
727 if( historyIndex > 0 )
728 {
729 historyIndex--;
730 navigating = true;
731 tree.setSelectionPath( navigationHistory.get( historyIndex ) );
732 navigating = false;
733 }
734 }}
735
736 private class ForwardAction extends AbstractAction
737 {
738 public ForwardAction()
739 {
740 super( ">");
741 putValue( Action.SHORT_DESCRIPTION, "Navigate to next selection" );
742 }
743
744 public void actionPerformed( ActionEvent arg0 )
745 {
746 if( historyIndex < navigationHistory.size()-1 )
747 {
748 historyIndex++;
749 navigating = true;
750 tree.setSelectionPath( navigationHistory.get( historyIndex ) );
751 navigating = false;
752 }
753
754 }}
755
756 }