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;
14  
15  import com.eviware.soapui.actions.SaveAllProjectsAction;
16  import com.eviware.soapui.actions.SoapUIPreferencesAction;
17  import com.eviware.soapui.actions.SwitchDesktopPanelAction;
18  import com.eviware.soapui.impl.WorkspaceImpl;
19  import com.eviware.soapui.impl.actions.ImportWsdlProjectAction;
20  import com.eviware.soapui.impl.actions.NewWsdlProjectAction;
21  import com.eviware.soapui.impl.support.actions.ShowOnlineHelpAction;
22  import com.eviware.soapui.impl.wsdl.actions.iface.tools.axis1.Axis1XWSDL2JavaAction;
23  import com.eviware.soapui.impl.wsdl.actions.iface.tools.axis2.Axis2WSDL2CodeAction;
24  import com.eviware.soapui.impl.wsdl.actions.iface.tools.cxf.CXFAction;
25  import com.eviware.soapui.impl.wsdl.actions.iface.tools.dotnet.DotNetWsdlAction;
26  import com.eviware.soapui.impl.wsdl.actions.iface.tools.gsoap.GSoapAction;
27  import com.eviware.soapui.impl.wsdl.actions.iface.tools.jaxb.JaxbXjcAction;
28  import com.eviware.soapui.impl.wsdl.actions.iface.tools.jbossws.JBossWSConsumeAction;
29  import com.eviware.soapui.impl.wsdl.actions.iface.tools.jbossws.WSToolsWsdl2JavaAction;
30  import com.eviware.soapui.impl.wsdl.actions.iface.tools.oracle.OracleWsaGenProxyAction;
31  import com.eviware.soapui.impl.wsdl.actions.iface.tools.tcpmon.TcpMonAction;
32  import com.eviware.soapui.impl.wsdl.actions.iface.tools.wscompile.WSCompileAction;
33  import com.eviware.soapui.impl.wsdl.actions.iface.tools.wsimport.WSImportAction;
34  import com.eviware.soapui.impl.wsdl.actions.iface.tools.xfire.XFireAction;
35  import com.eviware.soapui.impl.wsdl.actions.iface.tools.xmlbeans.XmlBeans2Action;
36  import com.eviware.soapui.impl.wsdl.actions.support.OpenUrlAction;
37  import com.eviware.soapui.impl.wsdl.panels.teststeps.support.PropertyHolderTable;
38  import com.eviware.soapui.impl.wsdl.support.HelpUrls;
39  import com.eviware.soapui.model.ModelItem;
40  import com.eviware.soapui.model.PanelBuilder;
41  import com.eviware.soapui.model.TestPropertyHolder;
42  import com.eviware.soapui.model.propertyexpansion.PropertyExpansionUtils;
43  import com.eviware.soapui.model.settings.Settings;
44  import com.eviware.soapui.model.settings.SettingsListener;
45  import com.eviware.soapui.model.tree.SoapUITreeNode;
46  import com.eviware.soapui.model.util.PanelBuilderRegistry;
47  import com.eviware.soapui.model.workspace.Workspace;
48  import com.eviware.soapui.model.workspace.WorkspaceFactory;
49  import com.eviware.soapui.monitor.MockEngine;
50  import com.eviware.soapui.monitor.TestMonitor;
51  import com.eviware.soapui.settings.UISettings;
52  import com.eviware.soapui.support.UISupport;
53  import com.eviware.soapui.support.action.SoapUIActionRegistry;
54  import com.eviware.soapui.support.action.swing.ActionList;
55  import com.eviware.soapui.support.action.swing.ActionListBuilder;
56  import com.eviware.soapui.support.action.swing.ActionSupport;
57  import com.eviware.soapui.support.action.swing.SwingActionDelegate;
58  import com.eviware.soapui.support.components.*;
59  import com.eviware.soapui.support.dnd.DropType;
60  import com.eviware.soapui.support.dnd.NavigatorDragAndDropable;
61  import com.eviware.soapui.support.dnd.SoapUIDragAndDropHandler;
62  import com.eviware.soapui.support.listener.SoapUIListenerRegistry;
63  import com.eviware.soapui.support.log.InspectorLog4JMonitor;
64  import com.eviware.soapui.support.log.JLogList;
65  import com.eviware.soapui.support.log.Log4JMonitor;
66  import com.eviware.soapui.support.log.LogDisablingTestMonitorListener;
67  import com.eviware.soapui.support.monitor.MonitorPanel;
68  import com.eviware.soapui.support.monitor.RuntimeMemoryMonitorSource;
69  import com.eviware.soapui.ui.JDesktopPanelsList;
70  import com.eviware.soapui.ui.Navigator;
71  import com.eviware.soapui.ui.NavigatorListener;
72  import com.eviware.soapui.ui.URLDesktopPanel;
73  import com.eviware.soapui.ui.desktop.DesktopPanel;
74  import com.eviware.soapui.ui.desktop.DesktopRegistry;
75  import com.eviware.soapui.ui.desktop.SoapUIDesktop;
76  import com.eviware.soapui.ui.desktop.standalone.StandaloneDesktop;
77  import com.eviware.soapui.ui.support.DesktopListenerAdapter;
78  import com.jgoodies.looks.HeaderStyle;
79  import com.jgoodies.looks.Options;
80  import org.apache.commons.cli.CommandLine;
81  import org.apache.commons.cli.CommandLineParser;
82  import org.apache.commons.cli.HelpFormatter;
83  import org.apache.commons.cli.PosixParser;
84  import org.apache.log4j.Level;
85  import org.apache.log4j.Logger;
86  
87  import javax.swing.*;
88  import java.awt.*;
89  import java.awt.dnd.DnDConstants;
90  import java.awt.dnd.DragSource;
91  import java.awt.event.ActionEvent;
92  import java.awt.event.KeyEvent;
93  import java.awt.event.WindowAdapter;
94  import java.awt.event.WindowEvent;
95  import java.io.File;
96  import java.net.URI;
97  import java.net.URISyntaxException;
98  import java.util.*;
99  import java.util.List;
100 import java.util.Timer;
101 
102 /***
103  * Main SoapUI entry point.
104  */
105 
106 public class SoapUI
107 {
108    public static final String DEFAULT_DESKTOP = "Default";
109    public static final String CURRENT_SOAPUI_WORKSPACE = SoapUI.class.getName() + "@workspace";
110    public final static Logger log = Logger.getLogger( SoapUI.class );
111    public final static String SOAPUI_VERSION = "2.5 beta1";
112    public static final String DEFAULT_WORKSPACE_FILE = "default-soapui-workspace.xml";
113    public static final String SOAPUI_SPLASH_GIF = "soapui-splash.jpg";
114    private static final int DEFAULT_DESKTOP_ACTIONS_COUNT = 3;
115    public static final String BUILDINFO_RESOURCE = "/com/eviware/soapui/resources/conf/buildinfo.txt";
116 
117    // ------------------------------ FIELDS ------------------------------
118 
119    //	private static SoapUI instance;
120    private static List<Object> logCache = new ArrayList<Object>();
121 
122    private static SoapUICore soapUICore;
123    private static JFrame frame;
124 
125    private static Navigator navigator;
126    private static SoapUIDesktop desktop;
127    private static Workspace workspace;
128    private static Log4JMonitor logMonitor;
129    private static Logger errorLog = Logger.getLogger( "soapui.errorlog" );
130    private static boolean isStandalone;
131    private static TestMonitor testMonitor;
132 
133    private JMenu desktopMenu;
134    private JMenu helpMenu;
135    private JMenu fileMenu;
136    private static JMenuBar menuBar;
137    private JDesktopPanelsList desktopPanelsList;
138 
139    public static boolean checkedGroovyLogMonitor;
140 
141    private JPanel overviewPanel;
142    private JMenu toolsMenu;
143    private boolean saveOnExit = true;
144    private InternalDesktopListener internalDesktopListener = new InternalDesktopListener();
145    private JInspectorPanel mainInspector;
146 
147    private static Timer autoSaveTimer;
148    private static AutoSaveTimerTask autoSaveTimerTask;
149    private static String workspaceName;
150    private static TreeMap<String, String> projectOptions = new TreeMap<String, String>();
151 
152    // --------------------------- CONSTRUCTORS ---------------------------
153 
154    private SoapUI()
155    {
156    }
157 
158    private void buildUI()
159    {
160       frame.addWindowListener( new MainFrameWindowListener() );
161       UISupport.setMainFrame( frame );
162 
163       navigator = new Navigator( workspace );
164       navigator.addNavigatorListener( new InternalNavigatorListener() );
165 
166       desktopPanelsList = new JDesktopPanelsList( desktop );
167 
168       mainInspector = JInspectorPanelFactory.build( buildContentPanel(), SwingConstants.LEFT );
169       mainInspector.addInspector( new JComponentInspector<JComponent>( buildMainPanel(), "Navigator", "The soapUI Navigator", true ) );
170       mainInspector.setCurrentInspector( "Navigator" );
171 
172       frame.setJMenuBar( buildMainMenu() );
173       frame.getContentPane().add( buildToolbar(), BorderLayout.NORTH );
174       frame.getContentPane().add( mainInspector.getComponent(), BorderLayout.CENTER );
175       frame.setDefaultCloseOperation( JFrame.DO_NOTHING_ON_CLOSE );
176       frame.setSize( 1000, 750 );
177 
178       mainInspector.setDividerLocation( 250 );
179       mainInspector.setResizeWeight( 0.1 );
180       navigator.selectModelItem( workspace );
181 
182       desktop.addDesktopListener( internalDesktopListener );
183 
184       ToolTipManager.sharedInstance().setInitialDelay( 200 );
185 
186       JTree mainTree = navigator.getMainTree();
187       DragSource dragSource = DragSource.getDefaultDragSource();
188       SoapUIDragAndDropHandler navigatorDragAndDropHandler = new SoapUIDragAndDropHandler(
189               new NavigatorDragAndDropable( mainTree ), DropType.ON + DropType.AFTER );
190 
191       dragSource.createDefaultDragGestureRecognizer( mainTree, DnDConstants.ACTION_COPY_OR_MOVE,
192               navigatorDragAndDropHandler );
193 
194       desktop.init();
195    }
196 
197    private JComponent buildToolbar()
198    {
199       JXToolBar toolbar = new JXToolBar();
200       toolbar.setRollover( true );
201       toolbar.putClientProperty( Options.HEADER_STYLE_KEY, HeaderStyle.BOTH );
202       toolbar.add( new NewWsdlProjectActionDelegate() );
203       toolbar.add( new ImportWsdlProjectActionDelegate() );
204       toolbar.add( new SaveAllActionDelegate() );
205       toolbar.addSeparator();
206       toolbar.add( new PreferencesActionDelegate() );
207       toolbar.add( new ExitButtonAction() );
208       toolbar.addGlue();
209 
210       toolbar.add( new ShowOnlineHelpAction( HelpUrls.USERGUIDE_HELP_URL ) );
211 
212       toolbar.setBorder( BorderFactory.createEtchedBorder() );
213 
214       return toolbar;
215    }
216 
217    private JMenuBar buildMainMenu()
218    {
219       menuBar = new JMenuBar();
220       menuBar.putClientProperty( Options.HEADER_STYLE_KEY, HeaderStyle.BOTH );
221 
222       menuBar.add( buildFileMenu() );
223       menuBar.add( buildToolsMenu() );
224       menuBar.add( buildDesktopMenu() );
225       menuBar.add( buildHelpMenu() );
226 
227       return menuBar;
228    }
229 
230    public static Workspace getWorkspace()
231    {
232       return workspace;
233    }
234 
235    private JMenu buildDesktopMenu()
236    {
237       desktopMenu = new JMenu( "Desktop" );
238       desktopMenu.setMnemonic( KeyEvent.VK_D );
239       desktopMenu.add( new SwitchDesktopPanelAction( desktopPanelsList ) );
240       desktopMenu.add( new MaximizeDesktopAction( (InspectorLog4JMonitor) logMonitor ) );
241       desktopMenu.addSeparator();
242 
243       ActionSupport.addActions( desktop.getActions(), desktopMenu );
244 
245       return desktopMenu;
246    }
247 
248    private JMenu buildHelpMenu()
249    {
250       helpMenu = new JMenu( "Help" );
251       helpMenu.setMnemonic( KeyEvent.VK_H );
252 
253       helpMenu.add( new ShowPushPageAction() );
254       helpMenu.add( new ShowOnlineHelpAction( "User Guide", HelpUrls.USERGUIDE_HELP_URL ) );
255       helpMenu.add( new ShowOnlineHelpAction( "Getting Started",
256               HelpUrls.GETTINGSTARTED_HELP_URL ) );
257       helpMenu.addSeparator();
258 
259       helpMenu.add( new ShowSystemPropertiesAction() );
260 
261       helpMenu.addSeparator();
262       helpMenu.add( new OpenUrlAction( "soapui.org", "http://www.soapui.org" ) );
263       helpMenu.add( new AboutAction() );
264       return helpMenu;
265    }
266 
267    private JMenu buildToolsMenu()
268    {
269       toolsMenu = new JMenu( "Tools" );
270       toolsMenu.setMnemonic( KeyEvent.VK_T );
271 
272       toolsMenu.add( SwingActionDelegate.createDelegate( WSToolsWsdl2JavaAction.SOAPUI_ACTION_ID ) );
273       toolsMenu.add( SwingActionDelegate.createDelegate( JBossWSConsumeAction.SOAPUI_ACTION_ID ) );
274       toolsMenu.addSeparator();
275       toolsMenu.add( SwingActionDelegate.createDelegate( WSCompileAction.SOAPUI_ACTION_ID ) );
276       toolsMenu.add( SwingActionDelegate.createDelegate( WSImportAction.SOAPUI_ACTION_ID ) );
277       toolsMenu.addSeparator();
278       toolsMenu.add( SwingActionDelegate.createDelegate( Axis1XWSDL2JavaAction.SOAPUI_ACTION_ID ) );
279       toolsMenu.add( SwingActionDelegate.createDelegate( Axis2WSDL2CodeAction.SOAPUI_ACTION_ID ) );
280       toolsMenu.add( SwingActionDelegate.createDelegate( CXFAction.SOAPUI_ACTION_ID ) );
281       toolsMenu.add( SwingActionDelegate.createDelegate( XFireAction.SOAPUI_ACTION_ID ) );
282       toolsMenu.add( SwingActionDelegate.createDelegate( OracleWsaGenProxyAction.SOAPUI_ACTION_ID ) );
283       toolsMenu.addSeparator();
284       toolsMenu.add( SwingActionDelegate.createDelegate( XmlBeans2Action.SOAPUI_ACTION_ID ) );
285       toolsMenu.add( SwingActionDelegate.createDelegate( JaxbXjcAction.SOAPUI_ACTION_ID ) );
286       toolsMenu.addSeparator();
287       toolsMenu.add( SwingActionDelegate.createDelegate( DotNetWsdlAction.SOAPUI_ACTION_ID ) );
288       toolsMenu.add( SwingActionDelegate.createDelegate( GSoapAction.SOAPUI_ACTION_ID ) );
289       toolsMenu.addSeparator();
290       toolsMenu.add( SwingActionDelegate.createDelegate( TcpMonAction.SOAPUI_ACTION_ID ) );
291       // toolsMenu.addSeparator();
292       // toolsMenu.add( new XQueryXPathTesterAction());
293 
294       return toolsMenu;
295    }
296 
297    private JMenu buildFileMenu()
298    {
299       fileMenu = new JMenu( "File" );
300       fileMenu.setMnemonic( KeyEvent.VK_F );
301 
302       ActionList actions = ActionListBuilder.buildActions( workspace );
303       actions.removeAction( actions.getActionCount() - 1 );
304 
305       ActionSupport.addActions( actions, fileMenu );
306 
307       fileMenu.add( SoapUIPreferencesAction.getInstance() );
308       fileMenu.add( new SavePreferencesAction() );
309       fileMenu.add( new ImportPreferencesAction() );
310 
311       fileMenu.addSeparator();
312       fileMenu.add( buildRecentMenu() );
313       fileMenu.addSeparator();
314       fileMenu.add( new ExitAction() );
315       fileMenu.add( new ExitWithoutSavingAction() );
316       fileMenu.addSeparator();
317       fileMenu.add( new ShowOnlineHelpAction( HelpUrls.OVERVIEW_HELP_URL ) );
318 
319       return fileMenu;
320    }
321 
322    private JMenuItem buildRecentMenu()
323    {
324       JMenu recentMenu = new JMenu( "Recent" );
325 
326       JMenu recentProjectsMenu = new JMenu( "Projects" );
327       JMenu recentWorkspacesMenu = new JMenu( "Workspaces" );
328       JMenu recentEditorsMenu = new JMenu( "Editors" );
329 
330       recentMenu.add( recentEditorsMenu );
331       recentMenu.add( recentProjectsMenu );
332       recentMenu.add( recentWorkspacesMenu );
333 
334       RecentItemsListener recentItemsListener = new RecentItemsListener( recentWorkspacesMenu, recentProjectsMenu, recentEditorsMenu );
335       workspace.addWorkspaceListener( recentItemsListener );
336       desktop.addDesktopListener( recentItemsListener );
337 
338       return recentMenu;
339    }
340 
341    public JFrame getFrame()
342    {
343       return frame;
344    }
345 
346    private JComponent buildMainPanel()
347    {
348       JInspectorPanel inspectorPanel = JInspectorPanelFactory.build( navigator );
349       inspectorPanel.addInspector( new JComponentInspector<JComponent>( buildOverviewPanel(),
350               "Properties", "Properties for the currently selected item", true ) );
351       inspectorPanel.setDividerLocation( 500 );
352       inspectorPanel.setResizeWeight( 0.6 );
353       inspectorPanel.setCurrentInspector( "Properties" );
354 
355       return inspectorPanel.getComponent();
356    }
357 
358    private JComponent buildOverviewPanel()
359    {
360       overviewPanel = new JPanel( new BorderLayout() );
361       overviewPanel.setBorder( BorderFactory.createEmptyBorder( 3, 0, 0, 2 ) );
362 
363       return overviewPanel;
364    }
365 
366    private void setOverviewPanel( Component panel )
367    {
368       if( overviewPanel.getComponentCount() == 0 && panel == null )
369          return;
370 
371       overviewPanel.removeAll();
372       if( panel != null )
373          overviewPanel.add( panel, BorderLayout.CENTER );
374       overviewPanel.revalidate();
375       overviewPanel.repaint();
376    }
377 
378    private JComponent buildContentPanel()
379    {
380       return buildLogPanel( true, "soapUI log" );
381    }
382 
383    private JComponent buildLogPanel( boolean hasDefault, String defaultName )
384    {
385       InspectorLog4JMonitor inspectorLog4JMonitor = new InspectorLog4JMonitor( desktop.getDesktopComponent() );
386 
387       JComponent monitor = initLogMonitor( hasDefault, defaultName, inspectorLog4JMonitor );
388 
389       if( !SoapUI.getSettings().getBoolean( UISettings.SHOW_LOGS_AT_STARTUP ) )
390          inspectorLog4JMonitor.activate( null );
391 
392       MonitorPanel monitorPanel = new MonitorPanel( new RuntimeMemoryMonitorSource() );
393       monitorPanel.start();
394       inspectorLog4JMonitor.addInspector( new JComponentInspector<JComponent>(
395               monitorPanel, "memory log", "Shows runtime memory consumtion", true ) );
396 
397       return monitor;
398    }
399 
400    public static JComponent initLogMonitor( boolean hasDefault, String defaultName, Log4JMonitor logMonitor )
401    {
402       SoapUI.logMonitor = logMonitor;
403       logMonitor.addLogArea( defaultName, "com.eviware.soapui", hasDefault ).setLevel( Level.DEBUG );
404       logMonitor.addLogArea( "http log", "httpclient.wire", false ).setLevel( Level.DEBUG );
405       logMonitor.addLogArea( "jetty log", "jetty", false ).setLevel( Level.INFO );
406       logMonitor.addLogArea( "error log", "soapui.errorlog", false ).setLevel( Level.DEBUG );
407 
408       for( Object message : logCache )
409       {
410          logMonitor.logEvent( message );
411       }
412 
413       return logMonitor.getComponent();
414    }
415 
416    // -------------------------- OTHER METHODS --------------------------
417 
418    public static synchronized void log( final Object msg )
419    {
420       if( logMonitor == null )
421       {
422          logCache.add( msg );
423          return;
424       }
425 
426       if( SwingUtilities.isEventDispatchThread() )
427       {
428          logMonitor.logEvent( msg );
429       }
430       else
431       {
432          SwingUtilities.invokeLater( new Runnable()
433          {
434             public void run()
435             {
436                logMonitor.logEvent( msg );
437             }
438          } );
439       }
440    }
441 
442    // -------------------------- INNER CLASSES --------------------------
443 
444    private final class InternalDesktopListener extends DesktopListenerAdapter
445    {
446       public void desktopPanelSelected( DesktopPanel desktopPanel )
447       {
448          ModelItem modelItem = desktopPanel.getModelItem();
449          if( modelItem != null )
450             navigator.selectModelItem( modelItem );
451       }
452    }
453 
454    private final class MainFrameWindowListener extends WindowAdapter
455    {
456       public void windowClosing( WindowEvent e )
457       {
458          if( onExit() )
459             frame.dispose();
460       }
461 
462       public void windowClosed( WindowEvent e )
463       {
464          System.out.println( "exiting.." );
465          System.exit( 0 );
466       }
467    }
468 
469    public static void main( String[] args ) throws Exception
470    {
471       startSoapUI( args, "soapUI " + SOAPUI_VERSION, "soapui-splash.gif", new StandaloneSoapUICore( true ) );
472    }
473 
474    public static SoapUI startSoapUI( String[] args, String title, String splashImage, SwingSoapUICore core ) throws Exception
475    {
476       frame = new JFrame( title );
477 
478       SoapUISplash splash = new SoapUISplash( splashImage, frame );
479 
480       isStandalone = true;
481       soapUICore = core;
482 
483       SoapUI soapUI = new SoapUI();
484       Workspace workspace = null;
485 
486       org.apache.commons.cli.Options options = initSoapUIOptions();
487       CommandLineParser parser = new PosixParser();
488       CommandLine cmd = parser.parse( options, args );
489 
490       if( validateCommandLineArgs( cmd, options ) )
491       {
492          System.exit( 1 );
493       }
494 
495       if( workspaceName != null )
496       {
497          workspace = WorkspaceFactory.getInstance().openWorkspace( workspaceName, projectOptions );
498          soapUICore.getSettings().setString( CURRENT_SOAPUI_WORKSPACE, workspaceName );
499       }
500       else
501       {
502          String wsfile = soapUICore.getSettings().getString( CURRENT_SOAPUI_WORKSPACE, System.getProperty( "user.home" ) + File.separatorChar
503                  + DEFAULT_WORKSPACE_FILE );
504          workspace = WorkspaceFactory.getInstance().openWorkspace( wsfile, projectOptions );
505       }
506 
507       core.prepareUI();
508       soapUI.show( workspace );
509       core.afterStartup( workspace );
510       Thread.sleep( 500 );
511       splash.setVisible( false );
512 
513       if( getSettings().getBoolean( UISettings.SHOW_STARTUP_PAGE ) )
514       {
515          SwingUtilities.invokeLater( new Runnable()
516          {
517             public void run()
518             {
519                showPushPage();
520             }
521          } );
522 
523       }
524 //		SoapUI.workspace.inspectProjects();
525 
526       return soapUI;
527    }
528 
529    private static boolean validateCommandLineArgs( CommandLine cmd, org.apache.commons.cli.Options options )
530    {
531       if( cmd.hasOption( 'w' ) )
532       {
533          workspaceName = cmd.getOptionValue( 'w' );
534       }
535 
536       if( cmd.hasOption( 'p' ) )
537       {
538          for( String projectNamePassword : cmd.getOptionValues( 'p' ) )
539          {
540             String[] nameAndPassword = projectNamePassword.split( ":" );
541             projectOptions.put( nameAndPassword[0], nameAndPassword[1] );
542          }
543       }
544 
545       if( cmd.getArgs().length > 0 )
546       {
547          HelpFormatter formatter = new HelpFormatter();
548          formatter.printHelp( "soapui.sh [options]", options );
549          return true;
550       }
551 
552       return false;
553 
554    }
555 
556    private static org.apache.commons.cli.Options initSoapUIOptions()
557    {
558 
559       org.apache.commons.cli.Options options = new org.apache.commons.cli.Options();
560       options.addOption( "w", true, "Specified the name of the workspace xml file" );
561       options.addOption( "p", true, "Sets project name and its password in format <project name>:<password>" );
562 
563       return options;
564    }
565 
566    public static SoapUICore getSoapUICore()
567    {
568       return soapUICore;
569    }
570 
571    public static TestPropertyHolder getGlobalProperties()
572    {
573       return PropertyExpansionUtils.getGlobalProperties();
574    }
575 
576    public static void setSoapUICore( SoapUICore soapUICore )
577    {
578       SoapUI.soapUICore = soapUICore;
579    }
580 
581    public static boolean isStandalone()
582    {
583       return isStandalone;
584    }
585 
586    public static JMenuBar getMenuBar()
587    {
588       return menuBar;
589    }
590 
591    private void show( Workspace workspace )
592    {
593       SoapUI.workspace = workspace;
594 
595       String desktopType = soapUICore.getSettings().getString( UISettings.DESKTOP_TYPE, SoapUI.DEFAULT_DESKTOP );
596       desktop = DesktopRegistry.getInstance().createDesktop( desktopType, workspace );
597 
598       if( desktop == null )
599          desktop = new StandaloneDesktop( workspace );
600 
601       if( testMonitor == null )
602          testMonitor = new TestMonitor();
603 
604       soapUICore.getSettings().addSettingsListener( new SettingsListener()
605       {
606 
607          public void settingChanged( String name, String newValue, String oldValue )
608          {
609             if( name.equals( UISettings.DESKTOP_TYPE ) )
610             {
611                changeDesktop( DesktopRegistry.getInstance().createDesktop( newValue, SoapUI.workspace ) );
612             }
613          }
614       } );
615 
616       buildUI();
617 
618       testMonitor.addTestMonitorListener( new LogDisablingTestMonitorListener() );
619       testMonitor.init( workspace );
620       frame.setVisible( true );
621 
622       initAutoSaveTimer();
623 
624 //		DesktopPanel dp = UISupport.showDesktopPanel(new URLDesktopPanel( "soapUI Rocks!", "Info on soapUI", "http://www.soapui.org"));
625 //		desktop.maximize( dp );
626    }
627 
628    private void changeDesktop( SoapUIDesktop newDesktop )
629    {
630       desktopPanelsList.setDesktop( newDesktop );
631       desktop.removeDesktopListener( internalDesktopListener );
632 
633       desktop.transferTo( newDesktop );
634       desktop.release();
635 
636       desktop = newDesktop;
637 
638       if( logMonitor instanceof InspectorLog4JMonitor )
639          ( (InspectorLog4JMonitor) logMonitor ).setContentComponent( desktop.getDesktopComponent() );
640 
641       desktop.addDesktopListener( internalDesktopListener );
642 
643       while( desktopMenu.getItemCount() > DEFAULT_DESKTOP_ACTIONS_COUNT )
644          desktopMenu.remove( DEFAULT_DESKTOP_ACTIONS_COUNT );
645 
646       ActionSupport.addActions( desktop.getActions(), desktopMenu );
647 
648       desktop.init();
649    }
650 
651    protected boolean onExit()
652    {
653       if( saveOnExit )
654       {
655          String question = "Exit SoapUI?";
656 
657          if( getTestMonitor().hasRunningTests() )
658             question += "\n(Projects with running tests will not be saved)";
659 
660          if( !UISupport.confirm( question, "Question" ) )
661             return false;
662 
663          try
664          {
665             PropertyExpansionUtils.saveGlobalProperties();
666             soapUICore.saveSettings();
667             workspace.onClose();
668          }
669          catch( Exception e1 )
670          {
671             SoapUI.logError( e1 );
672          }
673       }
674       else
675       {
676          if( !UISupport.confirm( "Exit SoapUI without saving?", "Question" ) )
677          {
678             saveOnExit = true;
679             return false;
680          }
681       }
682 
683       return true;
684    }
685 
686    public static void logError( Throwable e )
687    {
688       String msg = e.getMessage();
689       if( msg == null )
690          msg = e.toString();
691 
692       log.error( "An error occured [" + msg + "], see error log for details" );
693       errorLog.error( e.toString(), e );
694       if( !isStandalone() || "true".equals( System.getProperty( "soapui.stacktrace" ) ) )
695          e.printStackTrace();
696    }
697 
698    public static synchronized Logger ensureGroovyLog()
699    {
700       if( !checkedGroovyLogMonitor )
701       {
702          Log4JMonitor logMonitor = getLogMonitor();
703          if( logMonitor != null && !logMonitor.hasLogArea( "groovy.log" ) )
704          {
705             logMonitor.addLogArea( "groovy log", "groovy.log", false );
706             checkedGroovyLogMonitor = true;
707          }
708       }
709 
710       return Logger.getLogger( "groovy.log" );
711    }
712 
713    public class InternalNavigatorListener implements NavigatorListener
714    {
715       public void nodeSelected( SoapUITreeNode treeNode )
716       {
717          if( treeNode == null )
718          {
719             setOverviewPanel( null );
720          }
721          else
722          {
723             ModelItem modelItem = treeNode.getModelItem();
724             PropertyHolderTable propertyHolderTable = null;
725 
726             if( modelItem instanceof TestPropertyHolder )
727             {
728                propertyHolderTable = new PropertyHolderTable( (TestPropertyHolder) modelItem );
729             }
730 
731             PanelBuilder<ModelItem> panelBuilder = PanelBuilderRegistry.getPanelBuilder( modelItem );
732             if( panelBuilder != null && panelBuilder.hasOverviewPanel() )
733             {
734                Component overviewPanel = panelBuilder.buildOverviewPanel( modelItem );
735                if( propertyHolderTable != null )
736                {
737                   JTabbedPane tabs = new JTabbedPane();
738                   if( overviewPanel instanceof JPropertiesTable )
739                   {
740                      JPropertiesTable<?> t = (JPropertiesTable<?>) overviewPanel;
741                      tabs.addTab( t.getTitle(), overviewPanel );
742                      t.setTitle( null );
743                   }
744                   else
745                   {
746                      tabs.addTab( "Overview", overviewPanel );
747                   }
748 
749                   tabs.addTab( ( (TestPropertyHolder) modelItem ).getPropertiesLabel(), propertyHolderTable );
750                   overviewPanel = UISupport.createTabPanel( tabs, false );
751                }
752 
753                setOverviewPanel( overviewPanel );
754             }
755             else
756             {
757                setOverviewPanel( null );
758             }
759          }
760       }
761    }
762 
763    private class ExitAction extends AbstractAction
764    {
765       public ExitAction()
766       {
767          super( "Exit" );
768          putValue( Action.SHORT_DESCRIPTION, "Saves all projects and exits SoapUI" );
769          putValue( Action.ACCELERATOR_KEY, UISupport.getKeyStroke( "menu Q" ) );
770       }
771 
772       public void actionPerformed( ActionEvent e )
773       {
774          saveOnExit = true;
775          WindowEvent windowEvent = new WindowEvent( frame, WindowEvent.WINDOW_CLOSING );
776          frame.dispatchEvent( windowEvent );
777       }
778    }
779 
780    private class ExitButtonAction extends AbstractAction
781    {
782       public ExitButtonAction()
783       {
784          putValue( Action.SMALL_ICON, UISupport.createImageIcon( "/system-log-out.png" ) );
785          putValue( Action.SHORT_DESCRIPTION, "Saves all projects and exits SoapUI" );
786       }
787 
788       public void actionPerformed( ActionEvent e )
789       {
790          saveOnExit = true;
791          WindowEvent windowEvent = new WindowEvent( frame, WindowEvent.WINDOW_CLOSING );
792          frame.dispatchEvent( windowEvent );
793       }
794    }
795 
796    private class ShowPushPageAction extends AbstractAction
797    {
798       public ShowPushPageAction()
799       {
800          super( "Starter Page" );
801          putValue( Action.SHORT_DESCRIPTION, "Shows the starter page" );
802       }
803 
804       public void actionPerformed( ActionEvent e )
805       {
806          showPushPage();
807       }
808    }
809 
810    public static String PUSH_PAGE_URL = "http://www.soapui.org/appindex/soapui_start.htm";
811 
812    public static void showPushPage()
813    {
814       DesktopPanel dp = UISupport.showDesktopPanel( new URLDesktopPanel( "soapUI Starter Page", "Info on soapUI", PUSH_PAGE_URL ) );
815       desktop.maximize( dp );
816    }
817 
818    private static class ShowSystemPropertiesAction extends AbstractAction
819    {
820       public ShowSystemPropertiesAction()
821       {
822          super( "System Properties" );
823          putValue( Action.SHORT_DESCRIPTION, "Shows the current systems properties" );
824       }
825 
826       public void actionPerformed( ActionEvent e )
827       {
828          StringBuffer buffer = new StringBuffer();
829          Properties properties = System.getProperties();
830 
831          List<String> keys = new ArrayList<String>();
832          for( Object key : properties.keySet() )
833             keys.add( key.toString() );
834 
835          Collections.sort( keys );
836 
837          String lastKey = null;
838 
839          for( String key : keys )
840          {
841             if( lastKey != null )
842             {
843                if( !key.startsWith( lastKey ) )
844                   buffer.append( "\r\n" );
845             }
846 
847             int ix = key.indexOf( '.' );
848             lastKey = ix == -1 ? key : key.substring( 0, ix );
849 
850             buffer.append( key ).append( '=' ).append( properties.get( key ) ).append( "\r\n" );
851          }
852 
853          UISupport.showExtendedInfo( "System Properties", "Current system properties",
854                  "<html><body><pre><font size=-1>" + buffer.toString() + "</font></pre></body></html>",
855                  new Dimension( 600, 400 ) );
856       }
857    }
858 
859    private static class AboutAction extends AbstractAction
860    {
861       public AboutAction()
862       {
863          super( "About soapUI" );
864          putValue( Action.SHORT_DESCRIPTION, "Shows information on soapUI" );
865       }
866 
867       public void actionPerformed( ActionEvent e )
868       {
869          URI splashURI = null;
870          try
871          {
872             splashURI = UISupport.findSplash( SoapUI.SOAPUI_SPLASH_GIF ).toURI();
873          }
874          catch( URISyntaxException e1 )
875          {
876             SoapUI.logError( e1 );
877          }
878 
879          Properties props = new Properties();
880          try
881          {
882             props.load( SoapUI.class.getResourceAsStream( BUILDINFO_RESOURCE ) );
883          }
884          catch( Exception e1 )
885          {
886             SoapUI.logError( e1 );
887          }
888 
889          UISupport.showExtendedInfo( "About soapUI", null,
890                  "<html><body><p align=center><img src=\"" + splashURI + "\"><br>soapUI " +
891                          SOAPUI_VERSION + ", copyright (C) 2004-2008 eviware.com<br>" +
892                          "<a href=\"http://www.soapui.org\">http://www.soapui.org</a> | " +
893                          "<a href=\"http://www.eviware.com\">http://www.eviware.com</a><br>" +
894                          "Build " + props.getProperty( "build.number" ) + ", Build Date " +
895                          props.getProperty( "build.date" ) + "</p></body></html>",
896 
897                  new Dimension( 470, 350 ) );
898       }
899    }
900 
901    private class ExitWithoutSavingAction extends AbstractAction
902    {
903       public ExitWithoutSavingAction()
904       {
905          super( "Exit without saving" );
906          putValue( Action.SHORT_DESCRIPTION, "Saves all projects and exits SoapUI" );
907          putValue( Action.ACCELERATOR_KEY, UISupport.getKeyStroke( "ctrl alt Q" ) );
908       }
909 
910       public void actionPerformed( ActionEvent e )
911       {
912          saveOnExit = false;
913          WindowEvent windowEvent = new WindowEvent( frame, WindowEvent.WINDOW_CLOSING );
914          frame.dispatchEvent( windowEvent );
915       }
916    }
917 
918    private class SavePreferencesAction extends AbstractAction
919    {
920       public SavePreferencesAction()
921       {
922          super( "Save Preferences" );
923          putValue( Action.SHORT_DESCRIPTION, "Saves all global preferences" );
924       }
925 
926       public void actionPerformed( ActionEvent e )
927       {
928          try
929          {
930             soapUICore.saveSettings();
931          }
932          catch( Exception e1 )
933          {
934             UISupport.showErrorMessage( e1 );
935          }
936       }
937    }
938 
939    public static TestMonitor getTestMonitor()
940    {
941       if( testMonitor == null )
942          testMonitor = new TestMonitor();
943 
944       return testMonitor;
945    }
946 
947    public static void setTestMonitor( TestMonitor monitor )
948    {
949       testMonitor = monitor;
950    }
951 
952    public static Log4JMonitor getLogMonitor()
953    {
954       return logMonitor;
955    }
956 
957    public static void setLogMonitor( Log4JMonitor monitor )
958    {
959       logMonitor = monitor;
960    }
961 
962    // instance is null in Eclipse. /Lars
963    // eclipse-version(s) should provide SoapUIDesktop implementation
964    public static SoapUIDesktop getDesktop()
965    {
966       return desktop;
967    }
968 
969    public static void setDesktop( SoapUIDesktop desktop )
970    {
971       SoapUI.desktop = desktop;
972    }
973 
974    public static Navigator getNavigator()
975    {
976       return navigator;
977    }
978 
979    public static SoapUIActionRegistry getActionRegistry()
980    {
981       if( soapUICore == null )
982          soapUICore = new DefaultSoapUICore();
983 
984       return soapUICore.getActionRegistry();
985    }
986 
987    public static void setNavigator( Navigator navigator )
988    {
989       SoapUI.navigator = navigator;
990    }
991 
992    public static void setStandalone( boolean standalone )
993    {
994       SoapUI.isStandalone = standalone;
995    }
996 
997    private static class NewWsdlProjectActionDelegate extends AbstractAction
998    {
999       public NewWsdlProjectActionDelegate()
1000       {
1001          putValue( Action.SMALL_ICON, UISupport.createImageIcon( "/project.gif" ) );
1002          putValue( Action.SHORT_DESCRIPTION, "Creates a new WSDL Project" );
1003       }
1004 
1005       public void actionPerformed( ActionEvent e )
1006       {
1007          SoapUI.getActionRegistry().getAction( NewWsdlProjectAction.SOAPUI_ACTION_ID ).perform( workspace, null );
1008       }
1009    }
1010 
1011    private static class ImportWsdlProjectActionDelegate extends AbstractAction
1012    {
1013       public ImportWsdlProjectActionDelegate()
1014       {
1015          putValue( Action.SMALL_ICON, UISupport.createImageIcon( "/import_project.gif" ) );
1016          putValue( Action.SHORT_DESCRIPTION, "Imports an existing WSDL Project into the current workspace" );
1017       }
1018 
1019       public void actionPerformed( ActionEvent e )
1020       {
1021          SoapUI.getActionRegistry().getAction( ImportWsdlProjectAction.SOAPUI_ACTION_ID ).perform( workspace, null );
1022       }
1023    }
1024 
1025    private static class SaveAllActionDelegate extends AbstractAction
1026    {
1027       public SaveAllActionDelegate()
1028       {
1029          putValue( Action.SMALL_ICON, UISupport.createImageIcon( "/disk_multiple.png" ) );
1030          putValue( Action.SHORT_DESCRIPTION, "Saves all projects in the current workspace" );
1031       }
1032 
1033       public void actionPerformed( ActionEvent e )
1034       {
1035          SoapUI.getActionRegistry().getAction( SaveAllProjectsAction.SOAPUI_ACTION_ID ).perform( workspace, null );
1036       }
1037    }
1038 
1039    private class PreferencesActionDelegate extends AbstractAction
1040    {
1041       public PreferencesActionDelegate()
1042       {
1043          putValue( Action.SMALL_ICON, UISupport.createImageIcon( "/options.gif" ) );
1044          putValue( Action.SHORT_DESCRIPTION, "Sets Global soapUI Options" );
1045       }
1046 
1047       public void actionPerformed( ActionEvent e )
1048       {
1049          SoapUIPreferencesAction.getInstance().actionPerformed( null );
1050       }
1051    }
1052 
1053    public static class ImportPreferencesAction extends AbstractAction
1054    {
1055       public static final String IMPORT_PREFERENCES_ACTION_NAME = "Import Preferences";
1056 
1057       public ImportPreferencesAction()
1058       {
1059          super( ImportPreferencesAction.IMPORT_PREFERENCES_ACTION_NAME );
1060          putValue( Action.SHORT_DESCRIPTION, "Imports soapUI Settings from another settings-file" );
1061       }
1062 
1063       public void actionPerformed( ActionEvent e )
1064       {
1065          try
1066          {
1067             // prompt for import
1068             File file = UISupport.getFileDialogs().open( null, ImportPreferencesAction.IMPORT_PREFERENCES_ACTION_NAME, ".xml", "soapUI Settings XML (*.xml)", null );
1069             if( file != null )
1070                soapUICore.importSettings( file );
1071          }
1072          catch( Exception e1 )
1073          {
1074             UISupport.showErrorMessage( e1 );
1075          }
1076       }
1077    }
1078 
1079    public static SoapUIListenerRegistry getListenerRegistry()
1080    {
1081       if( soapUICore == null )
1082          soapUICore = DefaultSoapUICore.createDefault();
1083 
1084       return soapUICore.getListenerRegistry();
1085    }
1086 
1087    public static Settings getSettings()
1088    {
1089       if( soapUICore == null )
1090          soapUICore = DefaultSoapUICore.createDefault();
1091 
1092       return soapUICore.getSettings();
1093    }
1094 
1095    public static void importPreferences( File file ) throws Exception
1096    {
1097       if( soapUICore != null )
1098          soapUICore.importSettings( file );
1099    }
1100 
1101    public static MockEngine getMockEngine()
1102    {
1103       if( soapUICore == null )
1104          soapUICore = DefaultSoapUICore.createDefault();
1105 
1106       return soapUICore.getMockEngine();
1107    }
1108 
1109    public static String saveSettings() throws Exception
1110    {
1111       return soapUICore == null ? null : soapUICore.saveSettings();
1112    }
1113 
1114    public static void initDefaultCore()
1115    {
1116       if( soapUICore == null )
1117          soapUICore = DefaultSoapUICore.createDefault();
1118    }
1119 
1120    public class MaximizeDesktopAction extends AbstractAction
1121    {
1122       private JLogList lastLog;
1123       private int lastMainDividerLocation;
1124       private final InspectorLog4JMonitor log4JMonitor;
1125       private int lastLogDividerLocation;
1126 
1127       public MaximizeDesktopAction( InspectorLog4JMonitor log4JMonitor )
1128       {
1129          super( "Maximize Desktop" );
1130          this.log4JMonitor = log4JMonitor;
1131 
1132          putValue( SHORT_DESCRIPTION, "Hides/Shows the Navigator and Log tabs" );
1133          putValue( ACCELERATOR_KEY, UISupport.getKeyStroke( "menu M" ) );
1134       }
1135 
1136       public void actionPerformed( ActionEvent e )
1137       {
1138          if( mainInspector.getCurrentInspector() != null || logMonitor.getCurrentLog() != null )
1139          {
1140             lastMainDividerLocation = mainInspector.getDividerLocation();
1141             mainInspector.deactivate();
1142 
1143             lastLog = logMonitor.getCurrentLog();
1144             lastLogDividerLocation = log4JMonitor.getDividerLocation();
1145 
1146             log4JMonitor.deactivate();
1147          }
1148          else
1149          {
1150             mainInspector.setCurrentInspector( "Navigator" );
1151             mainInspector.setDividerLocation( lastMainDividerLocation == 0 ? 250 : lastMainDividerLocation );
1152 
1153             log4JMonitor.setCurrentLog( lastLog );
1154             log4JMonitor.setDividerLocation( lastLogDividerLocation == 0 ? 500 : lastLogDividerLocation );
1155          }
1156       }
1157    }
1158 
1159    public static void initAutoSaveTimer()
1160    {
1161       Settings settings = SoapUI.getSettings();
1162       long interval = settings.getLong( UISettings.AUTO_SAVE_INTERVAL, 0 );
1163 
1164       if( autoSaveTimerTask != null )
1165       {
1166          if( interval == 0 )
1167             SoapUI.log( "Cancelling AutoSave Timer" );
1168 
1169          autoSaveTimerTask.cancel();
1170          autoSaveTimerTask = null;
1171       }
1172 
1173       if( interval > 0 )
1174       {
1175          autoSaveTimerTask = new AutoSaveTimerTask();
1176 
1177          SoapUI.log( "Scheduling autosave every " + interval + " minutes" );
1178 
1179          if( autoSaveTimer == null )
1180             autoSaveTimer = new Timer( "AutoSave Timer" );
1181 
1182          autoSaveTimer.schedule( autoSaveTimerTask, interval * 1000 * 60, interval * 1000 * 60 );
1183       }
1184    }
1185 
1186    private static class AutoSaveTimerTask extends TimerTask
1187    {
1188       @Override
1189       public void run()
1190       {
1191          SoapUI.log( "Autosaving Workspace" );
1192          ( (WorkspaceImpl) SoapUI.getWorkspace() ).save( false, true );
1193       }
1194    }
1195 }