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