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