View Javadoc

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