View Javadoc

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