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