/*
* soapUI, copyright (C) 2004-2007 eviware.com
*
* soapUI is free software; you can redistribute it and/or modify it under the
* terms of version 2.1 of the GNU Lesser General Public License as published by
* the Free Software Foundation.
*
* soapUI is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without
* even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
* See the GNU Lesser General Public License for more details at gnu.org.
*/
package com.eviware.soapui;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.Insets;
import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.awt.event.KeyEvent;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.io.File;
import java.io.IOException;
import java.net.URI;
import java.net.URISyntaxException;
import java.net.URL;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.Properties;
import javax.swing.AbstractAction;
import javax.swing.Action;
import javax.swing.BorderFactory;
import javax.swing.ImageIcon;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JSplitPane;
import javax.swing.JTabbedPane;
import javax.swing.JWindow;
import javax.swing.SwingUtilities;
import javax.swing.ToolTipManager;
import javax.swing.UIManager;
import javax.swing.plaf.ColorUIResource;
import javax.xml.namespace.QName;
import javax.xml.parsers.FactoryConfigurationError;
import org.apache.log4j.Level;
import org.apache.log4j.Logger;
import org.apache.log4j.xml.DOMConfigurator;
import com.eviware.soapui.actions.SoapUIPreferencesAction;
import com.eviware.soapui.config.SoapuiSettingsDocumentConfig;
import com.eviware.soapui.impl.settings.XmlBeansSettingsImpl;
import com.eviware.soapui.impl.wsdl.actions.iface.tools.axis1.Axis1XWSDL2JavaAction;
import com.eviware.soapui.impl.wsdl.actions.iface.tools.axis2.Axis2WSDL2CodeAction;
import com.eviware.soapui.impl.wsdl.actions.iface.tools.dotnet.DotNetWsdlAction;
import com.eviware.soapui.impl.wsdl.actions.iface.tools.gsoap.GSoapAction;
import com.eviware.soapui.impl.wsdl.actions.iface.tools.jaxb.JaxbXjcAction;
import com.eviware.soapui.impl.wsdl.actions.iface.tools.jbossws.JBossWSConsumeAction;
import com.eviware.soapui.impl.wsdl.actions.iface.tools.jbossws.WSToolsWsdl2JavaAction;
import com.eviware.soapui.impl.wsdl.actions.iface.tools.oracle.OracleWsaGenProxyAction;
import com.eviware.soapui.impl.wsdl.actions.iface.tools.support.SwingToolHost;
import com.eviware.soapui.impl.wsdl.actions.iface.tools.tcpmon.TcpMonAction;
import com.eviware.soapui.impl.wsdl.actions.iface.tools.wscompile.WSCompileAction;
import com.eviware.soapui.impl.wsdl.actions.iface.tools.wsimport.WSImportAction;
import com.eviware.soapui.impl.wsdl.actions.iface.tools.xfire.XFireAction;
import com.eviware.soapui.impl.wsdl.actions.iface.tools.xmlbeans.XmlBeans2Action;
import com.eviware.soapui.impl.wsdl.actions.support.OpenUrlAction;
import com.eviware.soapui.impl.wsdl.actions.support.ShowOnlineHelpAction;
import com.eviware.soapui.impl.wsdl.support.HelpUrls;
import com.eviware.soapui.impl.wsdl.support.soap.SoapVersion;
import com.eviware.soapui.model.ModelItem;
import com.eviware.soapui.model.PanelBuilder;
import com.eviware.soapui.model.settings.Settings;
import com.eviware.soapui.model.settings.SettingsListener;
import com.eviware.soapui.model.tree.SoapUITreeNode;
import com.eviware.soapui.model.util.PanelBuilderRegistry;
import com.eviware.soapui.model.workspace.Workspace;
import com.eviware.soapui.model.workspace.WorkspaceFactory;
import com.eviware.soapui.monitor.MockEngine;
import com.eviware.soapui.monitor.TestMonitor;
import com.eviware.soapui.settings.HttpSettings;
import com.eviware.soapui.settings.UISettings;
import com.eviware.soapui.settings.WsdlSettings;
import com.eviware.soapui.support.ClasspathHacker;
import com.eviware.soapui.support.SoapUIException;
import com.eviware.soapui.support.UISupport;
import com.eviware.soapui.support.action.SoapUIActionRegistry;
import com.eviware.soapui.support.action.swing.ActionList;
import com.eviware.soapui.support.action.swing.ActionListBuilder;
import com.eviware.soapui.support.action.swing.ActionSupport;
import com.eviware.soapui.support.action.swing.SwingActionDelegate;
import com.eviware.soapui.support.log.Log4JMonitor;
import com.eviware.soapui.support.log.LogDisablingTestMonitorListener;
import com.eviware.soapui.support.types.StringList;
import com.eviware.soapui.ui.JDesktopPanelsList;
import com.eviware.soapui.ui.Navigator;
import com.eviware.soapui.ui.NavigatorListener;
import com.eviware.soapui.ui.desktop.DesktopPanel;
import com.eviware.soapui.ui.desktop.DesktopRegistry;
import com.eviware.soapui.ui.desktop.SoapUIDesktop;
import com.eviware.soapui.ui.desktop.standalone.StandaloneDesktop;
import com.eviware.soapui.ui.desktop.standalone.StandaloneDesktopFactory;
import com.eviware.soapui.ui.support.DesktopListenerAdapter;
import com.eviware.x.form.XFormFactory;
import com.eviware.x.impl.swing.SwingFileDialogs;
import com.eviware.x.impl.swing.SwingFormFactory;
import com.jgoodies.looks.HeaderStyle;
import com.jgoodies.looks.Options;
import com.jgoodies.looks.plastic.PlasticXPLookAndFeel;
import com.jgoodies.looks.plastic.theme.SkyBluer;
/**
* Main SoapUI entry point.
*
* @author Ole.Matzura
*
* For version 0.6
* @todo improve error assertion reporting +
* @todo find/search/replace +
* @todo undo +
* @todo recreate request and keep values +
* @todo dont create optional elements +
* @todo option to create requests when importing +
* @todo show soapaction +
* @todo save response +
* @todo color-coding +
* @todo rapportera fel vid null-svar +
* @todo fixa bugg vid update interface +
* @todo xmlbeans2 +
* @todo httpclient rc3 +
* @todo refactor request panels +
* @todo refactor project/interface/testsuite listeners +
* @todo create properties table +
*
* For version 0.7
* @todo workspace in home folder +
* @todo allow renaming of operation names in tree +
* @todo add functionality for copying values from test response to following
* test request +
* @todo fix relative xsd imports when loading from file system +
* @todo fix cancelling of request when closing request window -> introduce
* DesktopPanel interface +
* @todo refactor panel creation / listener handling/release +
* @todo fix update of testcase window when adding test steps +
* @todo add delete-line action in xml-editor (Ctrl-D) +
* @todo add submit action to xml request editor (Ctrl Enter) +
* @todo add mousewheel support to xml editor +
* @todo add mousewheel + C support to xml editor (move cursor) +
* @todo fix revalidation problems +
* @todo add validation to xmleditors +
* @todo check localisation of schema errors +
* @todo add possibility to reload schema (neccessary?) +
* @todo fix cloning of assertions when cloning test steps +
* @todo ask for creation of optional elements when (re)creating new request +
* @todo add action to add existing namespaces to xpath in xpathassertion +
*
* For version 0.8
* @todo fix default values when creating requests +
* @todo bug-fixes - creation of namespace declarations creates multiple with
* same name + - check defintion update + - deletion of endpoint always
* deletes first + - deleted assertions result in error during save/exit? + -
* disable submit when missing endpoint + - clone request null-pointer + -
* fix value transfer element <> attribute + - fix cancelling of test
* requests +
* @todo create assertion events / listeners +
* @todo ask to add testcase if missing +
* @todo add alt-enter to response area +
* @todo allow url config of SchemaCompliance assertion +
* @todo add accelerators for common actions +
* @todo fix positions of dialogs +
* @todo add possibility to specify testsuite/testcase in maven-plugin +
* @todo refactoring: replaced SoapUIAction with standard swing Action +
* @todo refactoring: checked all JOptionPanes for correct title, etc. +
* @todo add filename-filters to filechoosers +
* @todo add shortcut for cancel request to editor +
*
* For version 0.9
* @todo initial class/code comments +
* @todo bug-fixes - fix cancelling of test runs + - fix removal of request
* test-steps when associated operations / interfaces are removed + -
* update of request-step status in testcase panel + - focus on find-field
* in find/replace dialog + - fix filters to not remove directories.. + -
* change wsdl file filter to *.wsdl + - disable declare in transfer panel
* when no transfer is selected + - declare in transfer panel declares
* target from target response (should be request) + - ask to cancel when
* closing running testcase + - fix pretty-printing of large xml-documents + -
* fix find and replace + - fix node insert error on multiple clone
* teststep + - fix log-messages from canceled requests + - disable
* replace-related options in find/replace if editor is not editable +
* @todo add possibility to move teststeps within testcase +
* @todo improve/disable disabling of request-editor +
* @todo add addAssertion button to testrequest panel +
* @todo add copy/pase actions to editor popup +
* @todo model-items tests
* @todo improve wsdl/xsd viewer +
* @todo improve line-number reporting in validations +
* @todo added shift-tab to move focus between request/response editors +
* @todo refactorings - SoapUIException + - UIFacade for JOptionPane +
* (partially)
*
* For version 1.0b
* @todo initial user documentation / samples +
* @todo bug-fixes +
* @todo more tests / testing!
* @todo beta release +
*
* For version 1.0
* @todo official release
*
* For version 1.5
* @todo finish LoadTest panels - fix UI + - color legend + - reset action + -
* interactive thread-count change + - error-log + - see responses + -
* assertions + - command-line/maven-plugin + - export results +
* @todo loadtest fixes - resizing/scaling of graphs + - autoreset on restart +
* @todo fix disabling of relevant actions during test-runs + - Add to testcase,
* delete testcase, etc +
* @todo allow TransferValues between any requests/responses +
* @todo fix "global values" in testcases + - properties +
* @todo improve endpoint editing + - add "edit.." to combobox +
* @todo remove xpath/xquery tester.. +
* @todo improve testcase properties dialog +
* @todo fix icons for all tree nodes +
* @todo fix updating of desktop panel titles +
* @todo global settings; + - proxy + - close connections + - user-agent header + -
* preemptive authentication + - editor font + - socket timeout + - ?
* @todo add loop-functionality for testcases +
* @todo support one-way operations +
* @todo fix wsdlcontext initialization in loadtests +
* @todo create testrun summary in commandline
* @todo create loadtest summary in commandline
* @todo add maven.soapui.test.host commandline property +
* @todo add test-suite runner panel +
* @todo option to abort testcase on error +
* @todo ensure unique test-step names +
* @todo grooy-teststep +
* @todo onewayop tree icon +
* @todo fix desktoppanels list +
*
* For version 1.6
* @todo finish SOAP 1.2 request generation +
* @todo finish gsoap integration +
* @todo bugfixes!
* @todo swa-attachments support +
*
* Improvements
* @todo make modifications of response content "alive"
* @todo animated tree icons for testcase/loadtest runs
* @todo add run-testcase action in teststep/testcase editors
* @todo implement testsuite/testcase generation
* @todo refactor XmlObject configurables
* @todo workspace management
* @todo add reload-project!?
* @todo option to reload schemas on run testcase
* @todo option to select visible steps in loadtest statistics
* @todo generate testcase/testsuite actions
* @todo form-based input
*/
public class SoapUI
{
public static final String CURRENT_SOAPUI_WORKSPACE = SoapUI.class.getName() + "@workspace";
public final static Logger log = Logger.getLogger( SoapUI.class );
public final static String SOAPUI_VERSION = "1.7.5";
public static final String DEFAULT_WORKSPACE_FILE = "default-soapui-workspace.xml";
private final static String DEFAULT_SETTINGS_FILE = "soapui-settings.xml";
public static final String SOAPUI_SPLASH_GIF = "soapui-splash.gif";
// ------------------------------ FIELDS ------------------------------
private static SoapUI instance;
private static SoapuiSettingsDocumentConfig settingsDocument;
private static List<Object> logCache = new ArrayList<Object>();
private static Settings settings;
private static JFrame frame;
private Navigator navigator;
private SoapUIDesktop desktop;
private static TestMonitor testMonitor;
static Workspace workspace;
private JDesktopPanelsList desktopPanelsList;
private Log4JMonitor logMonitor;
private JMenu desktopMenu;
private JMenu helpMenu;
private JMenu fileMenu;
private JMenuBar menuBar;
public static boolean checkedGroovyLogMonitor;
private JPanel overviewPanel;
private JMenu toolsMenu;
private boolean saveOnExit = true;
private static MockEngine mockEngine;
private static boolean loadedExtLibs;
private static boolean isStandalone;
private JSplitPane contentSplit;
private InternalDesktopListener internalDesktopListener = new InternalDesktopListener();
private static SoapUIActionRegistry actionRegistry;
private static Logger errorLog = Logger.getLogger( "soapui.errorlog" );
private static boolean logIsInitialized;
// --------------------------- CONSTRUCTORS ---------------------------
public SoapUI()
{
instance = this;
testMonitor = new TestMonitor();
actionRegistry = new SoapUIActionRegistry( SoapUI.class.getResourceAsStream( "/soapui-actions.xml" ));
}
private void buildUI()
{
frame.addWindowListener( new MainFrameWindowListener() );
UISupport.setMainFrame( frame );
navigator = new Navigator( workspace );
navigator.addNavigatorListener( new InternalNavigatorListener() );
desktopPanelsList = new JDesktopPanelsList( desktop );
JSplitPane splitPane = UISupport
.createHorizontalSplit( buildMainPanel(), buildContentPanel() );
frame.setJMenuBar( buildMainMenu() );
frame.getContentPane().add( splitPane, BorderLayout.CENTER );
frame.setDefaultCloseOperation( JFrame.DO_NOTHING_ON_CLOSE );
frame.setSize( 1000, 750 );
splitPane.setDividerLocation( 250 );
navigator.selectModelItem( workspace );
desktop.addDesktopListener( internalDesktopListener );
ToolTipManager.sharedInstance().setInitialDelay( 200 );
}
private JMenuBar buildMainMenu()
{
menuBar = new JMenuBar();
menuBar.putClientProperty( Options.HEADER_STYLE_KEY, HeaderStyle.BOTH );
menuBar.add( buildFileMenu() );
menuBar.add( buildToolsMenu() );
menuBar.add( buildDesktopMenu() );
menuBar.add( buildHelpMenu() );
return menuBar;
}
public static Workspace getWorkspace()
{
return workspace;
}
private JMenu buildDesktopMenu()
{
desktopMenu = new JMenu( "Desktop" );
desktopMenu.setMnemonic( KeyEvent.VK_D );
ActionSupport.addActions( desktop.getActions(), desktopMenu );
return desktopMenu;
}
private JMenu buildHelpMenu()
{
helpMenu = new JMenu( "Help" );
helpMenu.setMnemonic( KeyEvent.VK_H );
helpMenu.add( new ShowOnlineHelpAction( "User Guide", HelpUrls.USERGUIDE_HELP_URL ) );
helpMenu.add( new ShowOnlineHelpAction( "Getting Started",
HelpUrls.GETTINGSTARTED_HELP_URL ) );
helpMenu.addSeparator();
helpMenu.add( new ShowSystemPropertiesAction());
helpMenu.addSeparator();
helpMenu.add( new OpenUrlAction( "soapui.org", "http://www.soapui.org" ) );
helpMenu.add( new AboutAction() );
return helpMenu;
}
@SuppressWarnings("unchecked")
private JMenu buildToolsMenu()
{
toolsMenu = new JMenu( "Tools" );
toolsMenu.setMnemonic( KeyEvent.VK_T );
toolsMenu.add( SwingActionDelegate.createDelegate( WSToolsWsdl2JavaAction.SOAPUI_ACTION_ID ));
toolsMenu.add( SwingActionDelegate.createDelegate( JBossWSConsumeAction.SOAPUI_ACTION_ID ));
toolsMenu.addSeparator();
toolsMenu.add( SwingActionDelegate.createDelegate( WSCompileAction.SOAPUI_ACTION_ID ));
toolsMenu.add( SwingActionDelegate.createDelegate( WSImportAction.SOAPUI_ACTION_ID ));
toolsMenu.addSeparator();
toolsMenu.add( SwingActionDelegate.createDelegate( Axis1XWSDL2JavaAction.SOAPUI_ACTION_ID ));
toolsMenu.add( SwingActionDelegate.createDelegate( Axis2WSDL2CodeAction.SOAPUI_ACTION_ID ));
toolsMenu.add( SwingActionDelegate.createDelegate( XFireAction.SOAPUI_ACTION_ID ));
toolsMenu.add( SwingActionDelegate.createDelegate( OracleWsaGenProxyAction.SOAPUI_ACTION_ID ));
toolsMenu.addSeparator();
toolsMenu.add( SwingActionDelegate.createDelegate( XmlBeans2Action.SOAPUI_ACTION_ID ));
toolsMenu.add( SwingActionDelegate.createDelegate( JaxbXjcAction.SOAPUI_ACTION_ID ));
toolsMenu.addSeparator();
toolsMenu.add( SwingActionDelegate.createDelegate( DotNetWsdlAction.SOAPUI_ACTION_ID ));
toolsMenu.add( SwingActionDelegate.createDelegate( GSoapAction.SOAPUI_ACTION_ID ));
toolsMenu.addSeparator();
toolsMenu.add( SwingActionDelegate.createDelegate( TcpMonAction.SOAPUI_ACTION_ID ));
// toolsMenu.addSeparator();
// toolsMenu.add( new XQueryXPathTesterAction());
return toolsMenu;
}
private JMenu buildFileMenu()
{
fileMenu = new JMenu( "File" );
fileMenu.setMnemonic( KeyEvent.VK_F );
ActionList actions = ActionListBuilder.buildActions( workspace );
actions.removeAction( actions.getActionCount()-1 );
ActionSupport.addActions( actions, fileMenu );
fileMenu.add( SoapUIPreferencesAction.getInstance() );
fileMenu.add( new SavePreferencesAction() );
fileMenu.add( new ImportPreferencesAction() );
fileMenu.addSeparator();
fileMenu.add( new ExitAction() );
fileMenu.add( new ExitWithoutSavingAction() );
fileMenu.addSeparator();
fileMenu.add( new ShowOnlineHelpAction( HelpUrls.OVERVIEW_HELP_URL ));
return fileMenu;
}
public JFrame getFrame()
{
return frame;
}
private JComponent buildMainPanel()
{
JSplitPane splitPane = UISupport.createVerticalSplit();
splitPane.setBorder( BorderFactory.createEmptyBorder( 2, 2, 2, 2 ) );
splitPane.setTopComponent( navigator );
splitPane.setBottomComponent( buildOverviewPanel() );
splitPane.setDividerLocation( 500 );
splitPane.setResizeWeight( 0.6 );
return splitPane;
}
private Component buildOverviewPanel()
{
JTabbedPane detailTabs = new JTabbedPane( JTabbedPane.BOTTOM );
overviewPanel = new JPanel( new BorderLayout() );
detailTabs.addTab( "Details", overviewPanel );
detailTabs.addTab( "Windows", new JScrollPane( desktopPanelsList ) );
return UISupport.createTabPanel( detailTabs, true );
}
private void setOverviewPanel( Component panel )
{
if( overviewPanel.getComponentCount() == 0 && panel == null )
return;
overviewPanel.removeAll();
if( panel != null )
overviewPanel.add( panel, BorderLayout.CENTER );
overviewPanel.revalidate();
overviewPanel.repaint();
}
private Component buildContentPanel()
{
contentSplit = UISupport.createVerticalSplit();
contentSplit.setBorder( BorderFactory.createEmptyBorder( 2, 2, 2, 2 ) );
contentSplit.setTopComponent( desktop.getDesktopComponent() );
contentSplit.setBottomComponent( buildLogPanel( true, "soapUI log" ) );
contentSplit.setDividerLocation( 550 );
contentSplit.setResizeWeight( 1 );
return contentSplit;
}
public Component buildLogPanel( boolean hasDefault, String defaultName )
{
logMonitor = new Log4JMonitor();
logMonitor.addLogArea( defaultName, "com.eviware.soapui", hasDefault ).setLevel( Level.DEBUG );
logMonitor.addLogArea( "http log", "httpclient.wire", false ).setLevel( Level.DEBUG );
logMonitor.addLogArea( "jetty log", "jetty", false ).setLevel( Level.INFO );
logMonitor.addLogArea( "error log", "soapui.errorlog", false ).setLevel( Level.DEBUG );
for( Object message : logCache )
{
logMonitor.logEvent( message );
}
return UISupport.createTabPanel( logMonitor, true );
}
// -------------------------- OTHER METHODS --------------------------
public static synchronized void log( final Object msg )
{
if( instance == null || instance.logMonitor == null )
{
logCache.add( msg );
return;
}
if( SwingUtilities.isEventDispatchThread() )
{
instance.logMonitor.logEvent( msg );
}
else
{
SwingUtilities.invokeLater( new Runnable()
{
public void run()
{
instance.logMonitor.logEvent( msg );
}
} );
}
}
// -------------------------- INNER CLASSES --------------------------
private final class InternalDesktopListener extends DesktopListenerAdapter
{
public void desktopPanelSelected( DesktopPanel desktopPanel )
{
ModelItem modelItem = desktopPanel.getModelItem();
if( modelItem != null )
navigator.selectModelItem( modelItem );
}
}
private final class MainFrameWindowListener extends WindowAdapter
{
public void windowClosing( WindowEvent e )
{
if( saveOnExit )
{
String question = "Exit SoapUI?";
if( getTestMonitor().hasRunningTests() )
question += "\n(Projects with running tests will not be saved)";
if( !UISupport.confirm( question, "Question" ) )
return;
try
{
saveSettings();
workspace.onClose();
}
catch( IOException e1 )
{
SoapUI.logError( e1 );
}
}
else
{
if( !UISupport.confirm( "Exit SoapUI without saving?", "Question" ) )
{
saveOnExit = true;
return;
}
}
frame.dispose();
}
public void windowClosed( WindowEvent e )
{
System.out.println( "exiting.." );
System.exit( 0 );
}
}
/**
* Adapted theme for soapUI Look and Feel
*
* @author ole.matzura
*/
public static class SoapUITheme extends SkyBluer
{
public static final Color BACKGROUND_COLOR = new Color( 240, 240, 240 );
public ColorUIResource getControl()
{
return new ColorUIResource( BACKGROUND_COLOR );
}
public ColorUIResource getMenuBackground()
{
return getControl();
}
public ColorUIResource getMenuItemBackground()
{
return new ColorUIResource( new Color( 248, 248, 248 ) );
}
}
// --------------------------- main() method ---------------------------
public static void main( String[] args ) throws Exception
{
String title = "soapUI " + SOAPUI_VERSION;
String splashImage = "soapui-splash.gif";
startSoapUI( args, title, findSplash( splashImage ));
}
public static URL findSplash( String filename )
{
File file = new File( filename );
URL url = null;
try
{
if( !file.exists() )
url = SoapUI.class.getResource( "/" + filename );
else
url = file.toURL();
}
catch( Exception e1 )
{
}
try
{
if( url == null )
url = new URL( "http://www.soapui.org/images/" + filename );
}
catch( Exception e2 )
{
SoapUI.logError( e2 );
}
return url;
}
public static SoapUI startSoapUI( String[] args, String title, URL splashImage ) throws FactoryConfigurationError, SoapUIException
{
isStandalone = true;
// force loading of SoapVersion
SoapVersion.Soap11.equals( SoapVersion.Soap12 );
initSoapUILog();
frame = new JFrame( title );
new SoapUISplash( splashImage );
initSoapUILookAndFeel();
prepareSwingUI();
loadExtLibs();
DesktopRegistry.getInstance().addDesktop( "Default", new StandaloneDesktopFactory() );
// Run with the currently installed license.
SoapUI soapUI = new SoapUI();
Workspace workspace = null;
if( args.length > 0 )
{
workspace = WorkspaceFactory.getInstance().openWorkspace( args );
getSettings().setString( CURRENT_SOAPUI_WORKSPACE, args[0] );
}
else
{
String wsfile = getSettings().getString( CURRENT_SOAPUI_WORKSPACE, System.getProperty( "user.home" ) + File.separatorChar
+ DEFAULT_WORKSPACE_FILE );
workspace = WorkspaceFactory.getInstance().openWorkspace( new String[] { wsfile } );
}
soapUI.show( workspace );
return soapUI;
}
public static boolean isStandalone()
{
return isStandalone;
}
public static void loadExtLibs()
{
if( loadedExtLibs )
return;
try
{
File dir = new File( "ext" );
if( dir.exists() && dir.isDirectory() )
{
File[] files = dir.listFiles();
for( File file : files )
{
if( file.getName().toLowerCase().endsWith( ".jar" ))
{
ClasspathHacker.addFile( file );
}
}
}
else
{
log.info( "Missing folder [" + dir.getAbsolutePath() + "] for external libraries" );
}
loadedExtLibs = true;
}
catch( IOException e )
{
SoapUI.logError( e );
}
}
public static void prepareSwingUI()
{
UISupport.setToolHost( new SwingToolHost() );
XFormFactory.Factory.instance = new SwingFormFactory();
}
public static void initSoapUILookAndFeel()
{
try
{
if( getSettings().getBoolean( UISettings.NATIVE_LAF ))
{
javax.swing.UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
}
else
{
SoapUITheme theme = new SoapUITheme();
PlasticXPLookAndFeel.setCurrentTheme( theme );
PlasticXPLookAndFeel.setTabStyle( "Metal" );
UIManager.setLookAndFeel( new PlasticXPLookAndFeel() );
UIManager.put( "TabbedPane.tabAreaInsets", new Insets( 3, 2, 0, 0 ) );
UIManager.put( "TabbedPane.unselectedBackground", new Color( 220, 220, 220 ) );
UIManager.put( "TabbedPane.selected", new Color( 240, 240, 240 ) );
PlasticXPLookAndFeel.setPlasticTheme( theme );
}
}
catch( Throwable e )
{
System.err.println( "Error initializing PlasticXPLookAndFeel; " + e.getMessage() );
}
}
public static JMenuBar getMenuBar()
{
return instance == null ? null : instance.menuBar;
}
public static void initSoapUILog() throws FactoryConfigurationError
{
if( !logIsInitialized )
{
File log4jconfig = new File( "soapui-log4j.xml" );
if( log4jconfig.exists() )
{
System.out.println( "Configuring log4j from [" + log4jconfig + "]" );
DOMConfigurator.configureAndWatch( log4jconfig.getAbsolutePath(), 5000 );
}
else
{
URL log4jUrl = SoapUI.class.getResource( "/soapui-log4j.xml" );
System.out.println( "Configuring log4j from [" + log4jUrl + "]" );
DOMConfigurator.configure( log4jUrl );
}
logIsInitialized = true;
}
}
private void show( Workspace workspace )
{
SoapUI.workspace = workspace;
String desktopType = getSettings().getString( UISettings.DESKTOP_TYPE, "Default");
desktop = DesktopRegistry.getInstance().createDesktop( desktopType, workspace );
if( desktop == null )
desktop = new StandaloneDesktop( workspace );
getSettings().addSettingsListener( new SettingsListener() {
public void settingChanged( String name, String newValue, String oldValue )
{
if( name.equals( UISettings.DESKTOP_TYPE ))
{
changeDesktop( DesktopRegistry.getInstance().createDesktop( newValue, SoapUI.workspace ));
}
}
} );
buildUI();
testMonitor.addTestMonitorListener( new LogDisablingTestMonitorListener() );
testMonitor.init( workspace );
frame.setVisible( true );
}
private void changeDesktop(SoapUIDesktop newDesktop )
{
desktopPanelsList.setDesktop( newDesktop );
desktop.removeDesktopListener( internalDesktopListener );
desktop.transferTo( newDesktop );
desktop.release();
desktop = newDesktop;
contentSplit.setTopComponent( desktop.getDesktopComponent() );
desktop.addDesktopListener( internalDesktopListener );
desktopMenu.removeAll();
ActionSupport.addActions( desktop.getActions(), desktopMenu );
}
public static void logError( Throwable e )
{
String msg = e.getMessage();
if( msg == null )
msg = e.toString();
log.error( "An error occured [" + msg + "], see error log for details" );
errorLog.error(e.toString(), e );
}
public static synchronized Logger ensureGroovyLog()
{
if( !checkedGroovyLogMonitor )
{
Log4JMonitor logMonitor = getLogMonitor();
if( logMonitor != null && !logMonitor.hasLogArea( "groovy.log" ))
logMonitor.addLogArea( "groovy log", "groovy.log", false );
checkedGroovyLogMonitor = true;
}
return Logger.getLogger( "groovy.log" );
}
public class InternalNavigatorListener implements NavigatorListener
{
public void nodeSelected( SoapUITreeNode treeNode )
{
if( treeNode == null )
{
setOverviewPanel( null );
}
else
{
PanelBuilder<ModelItem> panelBuilder = PanelBuilderRegistry.getPanelBuilder( treeNode.getModelItem() );
if( panelBuilder != null && panelBuilder.hasOverviewPanel() )
{
setOverviewPanel( panelBuilder.buildOverviewPanel( treeNode.getModelItem() ) );
}
else
{
setOverviewPanel( null );
}
}
}
}
private class ExitAction extends AbstractAction
{
public ExitAction()
{
super( "Exit" );
putValue( Action.SHORT_DESCRIPTION, "Saves all projects and exits SoapUI" );
putValue( Action.ACCELERATOR_KEY, UISupport.getKeyStroke( "menu Q" ) );
}
public void actionPerformed( ActionEvent e )
{
saveOnExit = true;
WindowEvent windowEvent = new WindowEvent( frame, WindowEvent.WINDOW_CLOSING );
frame.dispatchEvent( windowEvent );
}
}
private class ShowSystemPropertiesAction extends AbstractAction
{
public ShowSystemPropertiesAction()
{
super( "System Properties" );
putValue( Action.SHORT_DESCRIPTION, "Shows the current systems properties" );
}
public void actionPerformed( ActionEvent e )
{
StringBuffer buffer = new StringBuffer();
Properties properties = System.getProperties();
List<String> keys = new ArrayList<String>();
for( Object key : properties.keySet() )
keys.add( key.toString() );
Collections.sort( keys );
String lastKey = null;
for( String key : keys )
{
if( lastKey != null )
{
if( !key.startsWith( lastKey ))
buffer.append( "\r\n" );
}
int ix = key.indexOf( '.' );
lastKey = ix == -1 ? key : key.substring( 0, ix );
buffer.append( key ).append( '=' ).append( properties.get( key )).append( "\r\n" );
}
UISupport.showExtendedInfo( "System Properties", "Current system properties",
"<html><body><pre><font size=-1>" + buffer.toString() + "</font></pre></body></html>",
new Dimension( 600, 400 ));
}
}
private class AboutAction extends AbstractAction
{
public AboutAction()
{
super( "About soapUI" );
putValue( Action.SHORT_DESCRIPTION, "Shows information on soapUI" );
}
public void actionPerformed( ActionEvent e )
{
URI splashURI = null;
try
{
splashURI = SoapUI.findSplash( SoapUI.SOAPUI_SPLASH_GIF ).toURI();
}
catch( URISyntaxException e1 )
{
SoapUI.logError( e1 );
}
Properties props = new Properties();
try
{
props.load( SoapUI.class.getResourceAsStream( "/buildinfo.txt" ) );
}
catch( Exception e1 )
{
SoapUI.logError( e1 );
}
UISupport.showExtendedInfo( "About soapUI", null,
"<html><body><p align=center><img src=\"" + splashURI + "\"><br>soapUI " +
SOAPUI_VERSION + ", copyright (C) 2004-2007 eviware.com<br>" +
"<a href=\"http://www.soapui.org\">http://www.soapui.org</a> | " +
"<a href=\"http://www.eviware.com\">http://www.eviware.com</a><br>" +
"Build " + props.getProperty( "build.number" ) + ", Build Date " +
props.getProperty( "build.date" ) + "</p></body></html>",
new Dimension( 470, 350 ));
}
}
private class ExitWithoutSavingAction extends AbstractAction
{
public ExitWithoutSavingAction()
{
super( "Exit without saving" );
putValue( Action.SHORT_DESCRIPTION, "Saves all projects and exits SoapUI" );
putValue( Action.ACCELERATOR_KEY, UISupport.getKeyStroke( "ctrl alt Q" ) );
}
public void actionPerformed( ActionEvent e )
{
saveOnExit = false;
WindowEvent windowEvent = new WindowEvent( frame, WindowEvent.WINDOW_CLOSING );
frame.dispatchEvent( windowEvent );
}
}
private class SavePreferencesAction extends AbstractAction
{
public SavePreferencesAction()
{
super( "Save Preferences" );
putValue( Action.SHORT_DESCRIPTION, "Saves all global preferences" );
}
public void actionPerformed( ActionEvent e )
{
try
{
saveSettings();
}
catch( IOException e1 )
{
UISupport.showErrorMessage( e1 );
}
}
}
private class ImportPreferencesAction extends AbstractAction
{
public ImportPreferencesAction()
{
super( "Import Preferences" );
putValue( Action.SHORT_DESCRIPTION, "Imports soapUI Settings from another settings-file" );
}
public void actionPerformed( ActionEvent e )
{
try
{
// prompt for import
File file = UISupport.getFileDialogs().open( null, "Import Preferences", ".xml", "soapUI Settings XML (*.xml)", null );
if( file != null )
{
SoapuiSettingsDocumentConfig doc = SoapuiSettingsDocumentConfig.Factory.parse( file );
settingsDocument.set( doc );
}
}
catch( Exception e1 )
{
UISupport.showErrorMessage( e1 );
}
}
}
public static TestMonitor getTestMonitor()
{
return testMonitor;
}
public static void setTestMonitor( TestMonitor monitor )
{
testMonitor = monitor;
}
public static Log4JMonitor getLogMonitor()
{
return instance == null ? null : instance.logMonitor;
}
public static void setLogMonitor( Log4JMonitor monitor )
{
if( instance != null )
instance.logMonitor = monitor;
}
public static Settings getSettings()
{
if( settings == null )
{
if( settingsDocument == null )
initSettings( DEFAULT_SETTINGS_FILE );
if( settingsDocument.getSoapuiSettings() == null )
{
settingsDocument.addNewSoapuiSettings();
settings = new XmlBeansSettingsImpl( null, null, settingsDocument.getSoapuiSettings() );
settings.setBoolean( WsdlSettings.CACHE_WSDLS, true );
settings.setBoolean( WsdlSettings.PRETTY_PRINT_RESPONSE_MESSAGES, true );
settings.setBoolean( HttpSettings.INCLUDE_REQUEST_IN_TIME_TAKEN, true );
settings.setBoolean( HttpSettings.INCLUDE_RESPONSE_IN_TIME_TAKEN, true );
}
else
{
settings = new XmlBeansSettingsImpl( null, null, settingsDocument.getSoapuiSettings() );
}
if( !settings.isSet( WsdlSettings.EXCLUDED_TYPES ))
{
StringList list = new StringList();
list.add( "schema@http://www.w3.org/2001/XMLSchema");
settings.setString( WsdlSettings.EXCLUDED_TYPES, list.toXml() );
}
if( !settings.isSet( WsdlSettings.NAME_WITH_BINDING ))
{
settings.setBoolean( WsdlSettings.NAME_WITH_BINDING, true );
}
if( !settings.isSet( HttpSettings.MAX_CONNECTIONS_PER_HOST ))
{
settings.setLong( HttpSettings.MAX_CONNECTIONS_PER_HOST, 500 );
}
if( !settings.isSet( HttpSettings.MAX_TOTAL_CONNECTIONS ))
{
settings.setLong( HttpSettings.MAX_TOTAL_CONNECTIONS, 2000 );
}
}
return settings;
}
public static void saveSettings() throws IOException
{
File file = new File( DEFAULT_SETTINGS_FILE );
settingsDocument.save( file );
log.info( "Saved global preferences to [" + file.getAbsolutePath() + "]" );
}
/**
* Initializes the soapui settings from the specified file. Must be called on
* startup before any model items are created.
*
* @param fileName
*/
public static void initSettings( String fileName )
{
try
{
File settingsFile = new File( fileName );
if( !settingsFile.exists() )
{
if( isStandalone )
{
settingsFile = importSettingsOnStartup( settingsFile );
}
if( settingsDocument == null )
{
log.info( "Creating new settings at [" + settingsFile.getAbsolutePath() + "]" );
settingsDocument = SoapuiSettingsDocumentConfig.Factory.newInstance();
}
}
else
{
settingsDocument = SoapuiSettingsDocumentConfig.Factory.parse( settingsFile );
log.info( "initialized soapui-settings from [" + settingsFile.getAbsolutePath() + "]" );
}
}
catch( Exception e )
{
log.warn( "Failed to load settings from [" + e.getMessage() + "], creating new" );
settingsDocument = SoapuiSettingsDocumentConfig.Factory.newInstance();
}
}
private static File importSettingsOnStartup( File settingsFile ) throws Exception
{
javax.swing.UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
if( JOptionPane.showConfirmDialog( null, "Missing soapUI Settings, import from existing installation?",
"Import Preferences", JOptionPane.YES_NO_OPTION ) == JOptionPane.YES_OPTION )
{
while( true )
{
settingsFile = SwingFileDialogs.openFile( null, "Import Preferences", ".xml", "soapUI settings XML", settingsFile.getAbsolutePath() );
if( settingsFile != null )
{
try
{
settingsDocument = SoapuiSettingsDocumentConfig.Factory.parse( settingsFile );
log.info( "imported soapui-settings from [" + settingsFile.getAbsolutePath() + "]" );
break;
}
catch( Exception e )
{
if( JOptionPane.showConfirmDialog( null, "Error loading settings from [" + settingsFile.getAbsolutePath() + "]\r\nspecify another?",
"Error Importing", JOptionPane.OK_CANCEL_OPTION, JOptionPane.ERROR_MESSAGE ) == JOptionPane.CANCEL_OPTION )
{
break;
}
}
}
}
}
return settingsFile;
}
// instance is null in Eclipse. /Lars
// eclipse-version(s) should provide SoapUIDesktop implementation
public static SoapUIDesktop getDesktop()
{
return instance != null ? instance.desktop : null;
}
public static void setDesktop( SoapUIDesktop desktop )
{
if( instance != null )
instance.desktop = desktop;
}
public static Navigator getNavigator()
{
return instance != null ? instance.navigator : null;
}
public static SoapUIActionRegistry getActionRegistry()
{
return actionRegistry;
}
public static void setNavigator( Navigator navigator )
{
if( instance != null )
instance.navigator = navigator;
}
static class SoapUISplash extends JWindow
{
public SoapUISplash( URL splashImage )
{
super( frame );
JLabel l = new JLabel( new ImageIcon( splashImage ) );
getContentPane().add( l, BorderLayout.CENTER );
pack();
Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
Dimension labelSize = l.getPreferredSize();
setLocation( screenSize.width / 2 - ( labelSize.width / 2 ), screenSize.height / 2
- ( labelSize.height / 2 ) );
addMouseListener( new MouseAdapter()
{
public void mousePressed( MouseEvent e )
{
if( frame.isVisible())
{
setVisible( false );
dispose();
}
}
} );
final int pause = 1000;
final Runnable closerRunner = new Runnable()
{
public void run()
{
setVisible( false );
dispose();
}
};
Runnable waitRunner = new Runnable()
{
public void run()
{
try
{
do
{
Thread.sleep( pause );
}
while( !frame.isVisible() );
SwingUtilities.invokeAndWait( closerRunner );
}
catch( Exception e )
{
SoapUI.logError( e );
// can catch InvocationTargetException
// can catch InterruptedException
}
}
};
setVisible( true );
Thread splashThread = new Thread( waitRunner, "SplashThread" );
splashThread.start();
}
}
public static MockEngine getMockEngine()
{
if( mockEngine == null )
mockEngine = new MockEngine();
return mockEngine;
}
public static String getSchemaDirectory()
{
return SoapUI.getSettings().getString( WsdlSettings.SCHEMA_DIRECTORY, null );
}
public static Collection<? extends QName> getExcludedTypes()
{
List<QName> result = new ArrayList<QName>();
String excluded = SoapUI.getSettings().getString( WsdlSettings.EXCLUDED_TYPES, null );
if( excluded != null && excluded.trim().length() > 0 )
{
try
{
StringList names = StringList.fromXml( excluded );
for( String name : names )
{
int ix = name.indexOf( '@' );
result.add( new QName( name.substring( ix+1 ), name.substring( 0, ix )));
}
}
catch( Exception e )
{
SoapUI.logError( e );
}
}
return result;
}
public static void setStandalone( boolean b )
{
SoapUI.isStandalone = b;
}
}
|