View Javadoc

    1   /*
    2    *  soapUI, copyright (C) 2004-2007 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.impl;
    14
    15  import java.io.File;
    16  import java.io.IOException;
    17  import java.util.ArrayList;
    18  import java.util.HashSet;
    19  import java.util.Iterator;
    20  import java.util.List;
    21  import java.util.Set;
    22
    23  import javax.swing.ImageIcon;
    24
    25  import org.apache.log4j.Logger;
    26  import org.apache.xmlbeans.XmlException;
    27  import org.apache.xmlbeans.XmlOptions;
    28
    29  import com.eviware.soapui.SoapUI;
    30  import com.eviware.soapui.config.SoapuiWorkspaceDocumentConfig;
    31  import com.eviware.soapui.config.WorkspaceProjectConfig;
    32  import com.eviware.soapui.impl.settings.XmlBeansSettingsImpl;
    33  import com.eviware.soapui.impl.wsdl.WsdlProject;
    34  import com.eviware.soapui.model.ModelItem;
    35  import com.eviware.soapui.model.project.Project;
    36  import com.eviware.soapui.model.settings.Settings;
    37  import com.eviware.soapui.model.support.AbstractModelItem;
    38  import com.eviware.soapui.model.workspace.Workspace;
    39  import com.eviware.soapui.model.workspace.WorkspaceListener;
    40  import com.eviware.soapui.support.SoapUIException;
    41  import com.eviware.soapui.support.UISupport;
    42
    43  /***
    44   * Default Workspace implementation
    45   *
    46   * @author Ole.Matzura
    47   */
    48
    49  public class WorkspaceImpl extends AbstractModelItem implements Workspace
    50  {
    51  	private final static Logger log = Logger.getLogger( WorkspaceImpl.class );
    52  	private List<Project> projectList = new ArrayList<Project>();
    53  	private SoapuiWorkspaceDocumentConfig workspaceConfig;
    54  	private String path = null;
    55  	private Set<WorkspaceListener> listeners = new HashSet<WorkspaceListener>();
    56  	private ImageIcon workspaceIcon;
    57  	private XmlBeansSettingsImpl settings;
    58
    59  	public WorkspaceImpl( String path ) throws XmlException, IOException
    60  	{
    61  		File file = new File( path );
    62  		this.path = file.getAbsolutePath();
    63  		loadWorkspace( file );
    64  		workspaceIcon = UISupport.createImageIcon( "/workspace.gif" );
    65  	}
    66
    67  	public void changeWorkspace( File file ) throws SoapUIException
    68  	{
    69  		// check first if valid workspace file
    70  		if( file.exists() )
    71  		{
    72  			try
    73  			{
    74  				SoapuiWorkspaceDocumentConfig.Factory.parse( file );
    75  			}
    76  			catch( Exception e )
    77  			{
    78  				throw new SoapUIException( "Failed to load workspace: " + e.toString() );
    79  			}
    80  		}
    81
    82  		while( projectList.size() > 0 )
    83  		{
    84  			Project project = projectList.remove( 0 );
    85  			try
    86  			{
    87  				fireProjectRemoved( project );
    88  			}
    89  			finally
    90  			{
    91  				project.release();
    92  			}
    93  		}
    94
    95  		try
    96  		{
    97  			String oldName = getName();
    98
    99  			loadWorkspace( file );
    100 			this.path = file.getAbsolutePath();
    101
    102 			for( Project project : projectList )
    103 			{
    104 				fireProjectAdded( project );
    105 			}
    106
    107 			notifyPropertyChanged( ModelItem.NAME_PROPERTY, oldName, getName() );
    108 		}
    109 		catch(Exception e )
    110 		{
    111 			SoapUI.logError( e );
    112 		}
    113 	}
    114
    115 	private void loadWorkspace( File file ) throws XmlException, IOException
    116 	{
    117 		if( file.exists() )
    118 		{
    119 			log.info( "Loading workspace from [" + file.getAbsolutePath() + "]" );
    120 			workspaceConfig = SoapuiWorkspaceDocumentConfig.Factory.parse( file );
    121 			if( workspaceConfig.getSoapuiWorkspace().getSettings() == null )
    122 				workspaceConfig.getSoapuiWorkspace().addNewSettings();
    123
    124 			settings = new XmlBeansSettingsImpl( this, SoapUI.getSettings(), workspaceConfig
    125 						.getSoapuiWorkspace().getSettings() );
    126
    127 			List<WorkspaceProjectConfig> projects = workspaceConfig.getSoapuiWorkspace()
    128 						.getProjectList();
    129 			for( int i = 0; i < projects.size(); i++ )
    130 			{
    131 				WorkspaceProjectConfig wsc = projects.get( i );
    132 				String str = wsc.getStringValue();
    133
    134 				if( new File( str ).exists() )
    135 				{
    136 					try
    137 					{
    138 						WsdlProject project = new WsdlProject( str, this );
    139 						projectList.add( project );
    140 					}
    141 					catch( Exception e )
    142 					{
    143 						UISupport.showErrorMessage( "Failed to load project [" + str
    144 									+ "]\nfrom workspace; " + e.getMessage() );
    145
    146 						SoapUI.logError( e );
    147 					}
    148 				}
    149 				else
    150 				{
    151 					UISupport.showErrorMessage( "project [" + str
    152 								+ "]\nnot found, disabling in workspace" );
    153
    154 					try
    155 					{
    156 						WsdlProject project = new WsdlProject( str, this, false );
    157 						projectList.add( project );
    158 					}
    159 					catch( Exception e )
    160 					{
    161 						SoapUI.logError( e );
    162 					}
    163 				}
    164 			}
    165 		}
    166 		else
    167 		{
    168 			workspaceConfig = SoapuiWorkspaceDocumentConfig.Factory.newInstance();
    169 			workspaceConfig.addNewSoapuiWorkspace().setName( "Projects" );
    170 			workspaceConfig.getSoapuiWorkspace().addNewSettings();
    171
    172 			settings = new XmlBeansSettingsImpl( this, SoapUI.getSettings(), workspaceConfig
    173 						.getSoapuiWorkspace().getSettings() );
    174 		}
    175 	}
    176
    177 	public void setPath( String path )
    178 	{
    179 		this.path = path;
    180 	}
    181
    182 	public Project[] getProjects()
    183 	{
    184 		return projectList.toArray( new Project[projectList.size()] );
    185 	}
    186
    187 	public void setName( String name )
    188 	{
    189 		String oldName = getName();
    190
    191 		workspaceConfig.getSoapuiWorkspace().setName( name );
    192 		notifyPropertyChanged( ModelItem.NAME_PROPERTY, oldName, name );
    193 	}
    194
    195 	public void setDescription( String description )
    196 	{
    197 		String oldDescription = getDescription();
    198
    199 		workspaceConfig.getSoapuiWorkspace().setDescription( description );
    200 		notifyPropertyChanged( ModelItem.DESCRIPTION_PROPERTY, oldDescription, description );
    201 	}
    202
    203 	public String getName()
    204 	{
    205 		return workspaceConfig.getSoapuiWorkspace().isSetName() ? workspaceConfig.getSoapuiWorkspace().getName() : "Projects";
    206 	}
    207
    208 	public Project getProjectAt( int index )
    209 	{
    210 		return projectList.get( index );
    211 	}
    212
    213 	public Project getProjectByName( String projectName )
    214 	{
    215 		for( Project project : projectList )
    216 		{
    217 			if( project.getName().equals( projectName ) )
    218 				return project;
    219 		}
    220
    221 		return null;
    222 	}
    223
    224 	public int getProjectCount()
    225 	{
    226 		return projectList.size();
    227 	}
    228
    229 	public void onClose()
    230 	{
    231 		save( false );
    232 	}
    233
    234 	public void save( boolean workspaceOnly )
    235 	{
    236 		try
    237 		{
    238 			List<WorkspaceProjectConfig> projects = new ArrayList<WorkspaceProjectConfig>();
    239
    240 			// save projects first
    241 			for( int c = 0; c < getProjectCount(); c++ )
    242 			{
    243 				WsdlProject project = ( WsdlProject ) getProjectAt( c );
    244
    245 				if( !workspaceOnly )
    246 				{
    247 					if( SoapUI.getTestMonitor().hasRunningTests( project ))
    248 					{
    249 						log.warn( "Project [" + project.getName() + "] has running tests.. skipping save" );
    250 					}
    251 					else
    252 					{
    253 						project.save();
    254 					}
    255 				}
    256
    257 				String path = project.getPath();
    258 				if( path != null )
    259 				{
    260 					WorkspaceProjectConfig wpc = WorkspaceProjectConfig.Factory.newInstance();
    261 					wpc.setStringValue( path );
    262 					projects.add( wpc );
    263 				}
    264 			}
    265
    266 			if( path == null )
    267 			{
    268 				File file = UISupport.getFileDialogs().saveAs( this, "Save workspace", ".xml",
    269 							"XML Files (*.xml)", null );
    270 				if( file == null )
    271 					return;
    272
    273 				path = file.getAbsolutePath();
    274 			}
    275
    276 			workspaceConfig.getSoapuiWorkspace().setProjectArray(
    277 						projects.toArray( new WorkspaceProjectConfig[projects.size()] ) );
    278 			workspaceConfig.getSoapuiWorkspace().setSoapuiVersion( SoapUI.SOAPUI_VERSION );
    279
    280 			File workspaceFile = new File( path );
    281 			workspaceConfig.save( workspaceFile, new XmlOptions().setSavePrettyPrint() );
    282
    283 			log.info( "Saved workspace to [" + workspaceFile.getAbsolutePath() + "]" );
    284 		}
    285 		catch( IOException e )
    286 		{
    287 			log.error( "Failed to save workspace: " + e.getMessage(), e );
    288 		}
    289 	}
    290
    291 	public void addWorkspaceListener( WorkspaceListener listener )
    292 	{
    293 		listeners.add( listener );
    294 	}
    295
    296 	public void removeWorkspaceListener( WorkspaceListener listener )
    297 	{
    298 		listeners.remove( listener );
    299 	}
    300
    301 	public Project importProject( String fileName ) throws SoapUIException
    302 	{
    303 		File projectFile = new File( fileName );
    304
    305 		WsdlProject project = new WsdlProject( projectFile.getAbsolutePath(), this );
    306 		projectList.add( project );
    307
    308 		fireProjectAdded( project );
    309
    310 		save( true );
    311
    312 		return project;
    313 	}
    314
    315 	public WsdlProject createProject( String name ) throws SoapUIException
    316 	{
    317 		File projectFile = new File( createProjectFileName( name ) );
    318 		File file = UISupport.getFileDialogs().saveAs( this, "Create Project", ".xml",
    319 					"XML Files (*.xml)", projectFile );
    320 		if( file == null )
    321 			return null;
    322
    323 		return ( WsdlProject ) createProject( name, file );
    324 	}
    325
    326 	public Project createProject( String name, File file ) throws SoapUIException
    327 	{
    328 		File projectFile = file;
    329 		while( projectFile.exists() )
    330 		{
    331 			Boolean result = Boolean.FALSE;
    332 			while( !result.booleanValue() )
    333 			{
    334 				result = UISupport.confirmOrCancel( "Project File exists, overwrite?", "Overwrite Project?" );
    335 				if( result == null )
    336 					return null;
    337 				if( result.booleanValue() )
    338 				{
    339 					projectFile.delete();
    340 				}
    341 				else
    342 				{
    343 					projectFile = UISupport.getFileDialogs().saveAs( this, "Create Project", ".xml",
    344 								"XML Files (*.xml)", projectFile );
    345 					if( projectFile == null )
    346 						return null;
    347 					else
    348 						break;
    349 				}
    350 			}
    351 		}
    352
    353 		WsdlProject project = new WsdlProject( projectFile.getAbsolutePath(), this );
    354
    355 		project.setName( name );
    356 		projectList.add( project );
    357
    358 		fireProjectAdded( project );
    359
    360 		try
    361 		{
    362 			project.save();
    363 		}
    364 		catch( IOException e )
    365 		{
    366 			log.error( "Failed to save project: " + e.getMessage(), e );
    367 		}
    368 		save( true );
    369
    370 		return project;
    371 	}
    372
    373 	private void fireProjectAdded( Project project )
    374 	{
    375 		for( Iterator<WorkspaceListener> iter = listeners.iterator(); iter.hasNext(); )
    376 		{
    377 			WorkspaceListener listener = iter.next();
    378 			listener.projectAdded( project );
    379 		}
    380 	}
    381
    382 	private String createProjectFileName( String name )
    383 	{
    384 		StringBuffer result = new StringBuffer();
    385 		result.append( name );
    386 		result.append( "-soapui-project.xml" );
    387 		return result.toString();
    388 	}
    389
    390 	public void removeProject( Project project )
    391 	{
    392 		int ix = projectList.indexOf( project );
    393 		if( ix == -1 )
    394 			throw new RuntimeException( "Project [" + project.getName()
    395 						+ "] not available in workspace for removal" );
    396
    397 		projectList.remove( ix );
    398
    399 		try
    400 		{
    401 			fireProjectRemoved( project );
    402 		}
    403 		finally
    404 		{
    405 			project.release();
    406 			workspaceConfig.getSoapuiWorkspace().removeProject( ix );
    407 		}
    408 	}
    409
    410 	public void reloadProject( WsdlProject project ) throws SoapUIException
    411 	{
    412 		int ix = projectList.indexOf( project );
    413 		if( ix == -1 )
    414 			throw new RuntimeException( "Project [" + project.getName()
    415 						+ "] not available in workspace for removal" );
    416
    417 		projectList.remove( ix );
    418 		fireProjectRemoved( project );
    419
    420 		project.release();
    421 		project = new WsdlProject( project.getPath(), this );
    422
    423 		projectList.add( ix, project );
    424
    425 		fireProjectAdded( project );
    426
    427 		workspaceConfig.getSoapuiWorkspace().getProjectArray( ix ).setStringValue( project.getPath() );
    428 		save( true );
    429 	}
    430
    431 	private void fireProjectRemoved( Project project )
    432 	{
    433 		WorkspaceListener[] listenerArray = listeners
    434 					.toArray( new WorkspaceListener[listeners.size()] );
    435 		for( int c = 0; c < listenerArray.length; c++ )
    436 		{
    437 			listenerArray[c].projectRemoved( project );
    438 		}
    439 	}
    440
    441 	public ImageIcon getIcon()
    442 	{
    443 		return workspaceIcon;
    444 	}
    445
    446 	public Settings getSettings()
    447 	{
    448 		return settings;
    449 	}
    450
    451 	public int getIndexOfProject( Project project )
    452 	{
    453 		return projectList.indexOf( project );
    454 	}
    455
    456 	public String getPath()
    457 	{
    458 		return path;
    459 	}
    460
    461 	public void release()
    462 	{
    463 		settings.release();
    464
    465 		for( Project project : projectList )
    466 			project.release();
    467 	}
    468
    469 	public List<? extends ModelItem> getProjectList()
    470 	{
    471 		return projectList;
    472 	}
    473
    474 	public String getDescription()
    475 	{
    476 		return workspaceConfig.getSoapuiWorkspace().getDescription();
    477 	}
    478
    479 }