1
2
3
4
5
6
7
8
9
10
11
12
13 package com.eviware.soapui.impl;
14
15 import com.eviware.soapui.SoapUI;
16 import com.eviware.soapui.config.SoapuiWorkspaceDocumentConfig;
17 import com.eviware.soapui.config.WorkspaceProjectConfig;
18 import com.eviware.soapui.config.WorkspaceProjectConfig.Status;
19 import com.eviware.soapui.config.WorkspaceProjectConfig.Type;
20 import com.eviware.soapui.impl.settings.XmlBeansSettingsImpl;
21 import com.eviware.soapui.impl.wsdl.WsdlProject;
22 import com.eviware.soapui.impl.wsdl.WsdlProjectFactory;
23 import com.eviware.soapui.impl.wsdl.support.PathUtils;
24 import com.eviware.soapui.model.ModelItem;
25 import com.eviware.soapui.model.project.Project;
26 import com.eviware.soapui.model.project.ProjectFactoryRegistry;
27 import com.eviware.soapui.model.settings.Settings;
28 import com.eviware.soapui.model.support.AbstractModelItem;
29 import com.eviware.soapui.model.workspace.Workspace;
30 import com.eviware.soapui.model.workspace.WorkspaceListener;
31 import com.eviware.soapui.settings.UISettings;
32 import com.eviware.soapui.support.MessageSupport;
33 import com.eviware.soapui.support.SoapUIException;
34 import com.eviware.soapui.support.UISupport;
35 import com.eviware.soapui.support.resolver.ResolveDialog;
36 import com.eviware.soapui.support.types.StringToStringMap;
37 import org.apache.log4j.Logger;
38 import org.apache.xmlbeans.XmlException;
39 import org.apache.xmlbeans.XmlOptions;
40
41 import javax.swing.*;
42 import java.io.File;
43 import java.io.IOException;
44 import java.util.*;
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 public static final MessageSupport messages = MessageSupport.getMessages( WorkspaceImpl.class );
56
57 private List<Project> projectList = new ArrayList<Project>();
58 private SoapuiWorkspaceDocumentConfig workspaceConfig;
59 private String path = null;
60 private Set<WorkspaceListener> listeners = new HashSet<WorkspaceListener>();
61 private ImageIcon workspaceIcon;
62 private XmlBeansSettingsImpl settings;
63 private StringToStringMap projectOptions;
64 private ResolveDialog resolver;
65
66 public WorkspaceImpl( String path, StringToStringMap projectOptions ) throws XmlException, IOException
67 {
68 if( projectOptions == null )
69 {
70 this.projectOptions = new StringToStringMap();
71 }
72 else
73 {
74 this.projectOptions = projectOptions;
75 }
76 File file = new File( path );
77 this.path = file.getAbsolutePath();
78 loadWorkspace( file );
79 workspaceIcon = UISupport.createImageIcon( "/workspace.gif" );
80 }
81
82 public void switchWorkspace( File file ) throws SoapUIException
83 {
84
85 if( file.exists() )
86 {
87 try
88 {
89 SoapuiWorkspaceDocumentConfig.Factory.parse( file );
90 }
91 catch( Exception e )
92 {
93 throw new SoapUIException( messages.get( "FailedToLoadWorkspaceException" ) + e.toString() );
94 }
95 }
96
97 fireWorkspaceSwitching();
98
99 while( projectList.size() > 0 )
100 {
101 Project project = projectList.remove( 0 );
102 try
103 {
104 fireProjectRemoved( project );
105 }
106 finally
107 {
108 project.release();
109 }
110 }
111
112 try
113 {
114 String oldName = getName();
115
116 loadWorkspace( file );
117 this.path = file.getAbsolutePath();
118
119 for( Project project : projectList )
120 {
121 fireProjectAdded( project );
122 }
123
124 notifyPropertyChanged( ModelItem.NAME_PROPERTY, oldName, getName() );
125 }
126 catch( Exception e )
127 {
128 SoapUI.logError( e );
129 }
130
131 fireWorkspaceSwitched();
132 }
133
134 public void loadWorkspace( File file ) throws XmlException, IOException
135 {
136 if( file.exists() )
137 {
138 log.info( messages.get( "FailedToLoadWorkspaceFrom", file.getAbsolutePath() ) );
139 workspaceConfig = SoapuiWorkspaceDocumentConfig.Factory.parse( file );
140 if( workspaceConfig.getSoapuiWorkspace().getSettings() == null )
141 workspaceConfig.getSoapuiWorkspace().addNewSettings();
142
143 settings = new XmlBeansSettingsImpl( this, SoapUI.getSettings(), workspaceConfig
144 .getSoapuiWorkspace().getSettings() );
145
146 boolean closeOnStartup = getSettings().getBoolean( UISettings.CLOSE_PROJECTS );
147 List<WorkspaceProjectConfig> projects = workspaceConfig.getSoapuiWorkspace().getProjectList();
148 for( int i = 0; i < projects.size(); i++ )
149 {
150 WorkspaceProjectConfig wsc = projects.get( i );
151 String str = PathUtils.denormalizePath( wsc.getStringValue() );
152
153 str = PathUtils.adjustRelativePath( str, getProjectRoot(), this );
154
155 try
156 {
157
158
159 WsdlProject project = (WsdlProject) ProjectFactoryRegistry.getProjectFactory( "wsdl" ).createNew( str, this, false, !closeOnStartup &&
160 wsc.getStatus() != Status.CLOSED && wsc.getType() != Type.REMOTE, wsc.getName(), null );
161
162 projectList.add( project );
163 }
164 catch( Exception e )
165 {
166 UISupport.showErrorMessage( messages.get( "FailedToLoadProjectInWorkspace", str )
167 + e.getMessage() );
168
169 SoapUI.logError( e );
170 }
171 }
172 }
173 else
174 {
175 workspaceConfig = SoapuiWorkspaceDocumentConfig.Factory.newInstance();
176 workspaceConfig.addNewSoapuiWorkspace().setName( messages.get( "DefaultWorkspaceName" ) );
177 workspaceConfig.getSoapuiWorkspace().addNewSettings();
178
179 settings = new XmlBeansSettingsImpl( this, SoapUI.getSettings(), workspaceConfig
180 .getSoapuiWorkspace().getSettings() );
181 }
182 }
183
184 public void setPath( String path )
185 {
186 this.path = path;
187 }
188
189 public Project[] getProjects()
190 {
191 return projectList.toArray( new Project[projectList.size()] );
192 }
193
194 public void setName( String name )
195 {
196 String oldName = getName();
197
198 workspaceConfig.getSoapuiWorkspace().setName( name );
199 notifyPropertyChanged( ModelItem.NAME_PROPERTY, oldName, name );
200 }
201
202 public void setDescription( String description )
203 {
204 String oldDescription = getDescription();
205
206 workspaceConfig.getSoapuiWorkspace().setDescription( description );
207 notifyPropertyChanged( ModelItem.DESCRIPTION_PROPERTY, oldDescription, description );
208 }
209
210 public String getName()
211 {
212 return workspaceConfig.getSoapuiWorkspace().isSetName() ? workspaceConfig.getSoapuiWorkspace().getName() : messages.get( "DefaultWorkspaceName" );
213 }
214
215 public Project getProjectAt( int index )
216 {
217 return projectList.get( index );
218 }
219
220 public Project getProjectByName( String projectName )
221 {
222 for( Project project : projectList )
223 {
224 if( project.getName().equals( projectName ) )
225 return project;
226 }
227
228 return null;
229 }
230
231 public int getProjectCount()
232 {
233 return projectList.size();
234 }
235
236 public void onClose()
237 {
238 save( !getSettings().getBoolean( UISettings.AUTO_SAVE_PROJECTS_ON_EXIT ) );
239 }
240
241 public void save( boolean workspaceOnly )
242 {
243 save( workspaceOnly, false );
244 }
245
246 public void save( boolean workspaceOnly, boolean skipProjectsWithRunningTests )
247 {
248 try
249 {
250
251 if( path == null )
252 {
253 File file = UISupport.getFileDialogs().saveAs( this, messages.get( "SaveWorkspace.Title" ), ".xml",
254 "XML Files (*.xml)", null );
255 if( file == null )
256 return;
257
258 path = file.getAbsolutePath();
259 }
260
261 List<WorkspaceProjectConfig> projects = new ArrayList<WorkspaceProjectConfig>();
262
263
264 for( int c = 0; c < getProjectCount(); c++ )
265 {
266 WsdlProject project = (WsdlProject) getProjectAt( c );
267
268 if( !workspaceOnly )
269 {
270 if( skipProjectsWithRunningTests && SoapUI.getTestMonitor().hasRunningTests( project ) )
271 {
272 log.warn( messages.get( "ProjectHasRunningTests.Warning", project.getName() ) );
273 }
274 else
275 {
276 String path = project.getPath();
277 if( path == null )
278 {
279 if( UISupport.confirm( messages.get( "ProjectHasNotBeenSaved.Label", project.getName() ),
280 messages.get( "ProjectHasNotBeenSaved.Title" ) ) )
281 {
282 project.save();
283 }
284 }
285 else
286 {
287 project.save();
288 }
289 }
290 }
291
292 String path = project.getPath();
293 if( path != null )
294 {
295 path = PathUtils.createRelativePath( path, getProjectRoot(), this );
296
297 WorkspaceProjectConfig wpc = WorkspaceProjectConfig.Factory.newInstance();
298 wpc.setStringValue( PathUtils.normalizePath( path ) );
299 if( project.isRemote() )
300 wpc.setType( Type.REMOTE );
301
302 if( !project.isOpen() )
303 {
304 if( project.getEncrypted() == 0 )
305 {
306 wpc.setStatus( Status.CLOSED );
307 }
308 else
309 {
310 wpc.setStatus( Status.CLOSED_AND_ENCRYPTED );
311 }
312 }
313
314 wpc.setName( project.getName() );
315 projects.add( wpc );
316 }
317 }
318
319 workspaceConfig.getSoapuiWorkspace().setProjectArray(
320 projects.toArray( new WorkspaceProjectConfig[projects.size()] ) );
321 workspaceConfig.getSoapuiWorkspace().setSoapuiVersion( SoapUI.SOAPUI_VERSION );
322
323 File workspaceFile = new File( path );
324 workspaceConfig.save( workspaceFile, new XmlOptions().setSavePrettyPrint() );
325
326 log.info( messages.get( "SavedWorkspace.Info", workspaceFile.getAbsolutePath() ) );
327 }
328 catch( IOException e )
329 {
330 log.error( messages.get( "FailedToSaveWorkspace.Error" ) + e.getMessage(), e );
331 }
332 }
333
334 public void addWorkspaceListener( WorkspaceListener listener )
335 {
336 listeners.add( listener );
337 }
338
339 public void removeWorkspaceListener( WorkspaceListener listener )
340 {
341 listeners.remove( listener );
342 }
343
344 public Project importProject( String fileName ) throws SoapUIException
345 {
346 File projectFile = new File( fileName );
347 WsdlProject project = (WsdlProject) ProjectFactoryRegistry.getProjectFactory( "wsdl" ).createNew( projectFile.getAbsolutePath(), this );
348
349 projectList.add( project );
350 fireProjectAdded( project );
351
352 resolveProject( project );
353
354 save( true );
355
356 return project;
357 }
358
359 public void resolveProject( WsdlProject project )
360 {
361 if( resolver == null )
362 {
363 resolver = new ResolveDialog( "Resolve Project", "Resolve imported project", null );
364 resolver.setShowOkMessage( false );
365 }
366
367 resolver.resolve( project );
368 }
369
370 public WsdlProject createProject( String name ) throws SoapUIException
371 {
372 File projectFile = new File( createProjectFileName( name ) );
373 File file = UISupport.getFileDialogs().saveAs( this, messages.get( "CreateProject.Title" ), ".xml",
374 "XML Files (*.xml)", projectFile );
375 if( file == null )
376 return null;
377
378 return createProject( name, file );
379 }
380
381 public WsdlProject createProject( String name, File file ) throws SoapUIException
382 {
383 File projectFile = file;
384 while( projectFile != null && projectFile.exists() )
385 {
386 Boolean result = Boolean.FALSE;
387 while( !result.booleanValue() )
388 {
389 result = UISupport.confirmOrCancel( messages.get( "OverwriteProject.Label" ), messages.get( "OverwriteProject.Title" ) );
390 if( result == null )
391 return null;
392 if( result.booleanValue() )
393 {
394 projectFile.delete();
395 }
396 else
397 {
398 projectFile = UISupport.getFileDialogs().saveAs( this, messages.get( "CreateProject.Title" ), ".xml",
399 "XML Files (*.xml)", projectFile );
400 if( projectFile == null )
401 return null;
402 else
403 break;
404 }
405 }
406 }
407
408
409 WsdlProject project = (WsdlProject) ProjectFactoryRegistry.getProjectFactory( WsdlProjectFactory.WSDL_TYPE ).createNew( projectFile == null ? null : projectFile.getAbsolutePath(), this );
410
411 project.setName( name );
412 projectList.add( project );
413
414 fireProjectAdded( project );
415
416 try
417 {
418 if( projectFile != null )
419 project.save();
420 }
421 catch( IOException e )
422 {
423 log.error( messages.get( "FailedToSaveProject.Error" ) + e.getMessage(), e );
424 }
425
426
427 return project;
428 }
429
430 private void fireProjectAdded( Project project )
431 {
432 for( Iterator<WorkspaceListener> iter = listeners.iterator(); iter.hasNext(); )
433 {
434 WorkspaceListener listener = iter.next();
435 listener.projectAdded( project );
436 }
437 }
438
439 private void fireWorkspaceSwitching()
440 {
441 for( Iterator<WorkspaceListener> iter = listeners.iterator(); iter.hasNext(); )
442 {
443 WorkspaceListener listener = iter.next();
444 listener.workspaceSwitching( this );
445 }
446 }
447
448 private void fireWorkspaceSwitched()
449 {
450 for( Iterator<WorkspaceListener> iter = listeners.iterator(); iter.hasNext(); )
451 {
452 WorkspaceListener listener = iter.next();
453 listener.workspaceSwitched( this );
454 }
455 }
456
457 private String createProjectFileName( String name )
458 {
459 return name + "-soapui-project.xml";
460 }
461
462 public void removeProject( Project project )
463 {
464 int ix = projectList.indexOf( project );
465 if( ix == -1 )
466 throw new RuntimeException( "Project [" + project.getName()
467 + "] not available in workspace for removal" );
468
469 projectList.remove( ix );
470
471 try
472 {
473 fireProjectRemoved( project );
474 }
475 finally
476 {
477 project.release();
478
479 }
480 }
481
482 public Project reloadProject( Project project ) throws SoapUIException
483 {
484 int ix = projectList.indexOf( project );
485 if( ix == -1 )
486 throw new RuntimeException( "Project [" + project.getName()
487 + "] not available in workspace for reload" );
488
489 projectList.remove( ix );
490 fireProjectRemoved( project );
491
492 String tempName = project.getName();
493 project.release();
494 project = (WsdlProject) ProjectFactoryRegistry.getProjectFactory( "wsdl" ).createNew( project.getPath(), this, false, true, tempName, null );
495 projectList.add( ix, project );
496
497 fireProjectAdded( project );
498
499 return project;
500 }
501
502 private void fireProjectRemoved( Project project )
503 {
504 WorkspaceListener[] listenerArray = listeners
505 .toArray( new WorkspaceListener[listeners.size()] );
506 for( int c = 0; c < listenerArray.length; c++ )
507 {
508 listenerArray[c].projectRemoved( project );
509 }
510 }
511
512 public ImageIcon getIcon()
513 {
514 return workspaceIcon;
515 }
516
517 public Settings getSettings()
518 {
519 return settings;
520 }
521
522 public int getIndexOfProject( Project project )
523 {
524 return projectList.indexOf( project );
525 }
526
527 public String getPath()
528 {
529 return path;
530 }
531
532 public String getProjectRoot()
533 {
534 return workspaceConfig.getSoapuiWorkspace().getProjectRoot();
535 }
536
537 public void setProjectRoot( String workspaceRoot )
538 {
539 workspaceConfig.getSoapuiWorkspace().setProjectRoot( workspaceRoot );
540 }
541
542 public void release()
543 {
544 settings.release();
545
546 for( Project project : projectList )
547 project.release();
548 }
549
550 public List<? extends Project> getProjectList()
551 {
552 return projectList;
553 }
554
555 public String getDescription()
556 {
557 return workspaceConfig.getSoapuiWorkspace().getDescription();
558 }
559
560 public WsdlProject importRemoteProject( String url ) throws SoapUIException
561 {
562
563 WsdlProject project = (WsdlProject) ProjectFactoryRegistry.getProjectFactory( "wsdl" ).createNew( url, this, false );
564 projectList.add( project );
565 fireProjectAdded( project );
566
567 resolveProject( project );
568
569 save( true );
570
571 return project;
572 }
573
574 public void closeProject( Project project )
575 {
576 int oldProjectEncrypt = ( (WsdlProject) project ).getEncrypted();
577 int ix = projectList.indexOf( project );
578 if( ix == -1 )
579 throw new RuntimeException( "Project [" + project.getName()
580 + "] not available in workspace for close" );
581
582 projectList.remove( ix );
583 fireProjectRemoved( project );
584
585 String name = project.getName();
586 project.release();
587
588 try
589 {
590
591 project = ProjectFactoryRegistry.getProjectFactory( WsdlProjectFactory.WSDL_TYPE ).createNew( project.getPath(), this, false, false, name, null );
592 ( (WsdlProject) project ).setEncrypted( oldProjectEncrypt );
593 projectList.add( ix, project );
594 fireProjectAdded( project );
595 }
596 catch( Exception e )
597 {
598 UISupport.showErrorMessage( messages.get( "FailedToCloseProject.Error", name ) + e.getMessage() );
599 SoapUI.logError( e );
600 }
601 }
602
603 public List<Project> getOpenProjectList()
604 {
605 List<Project> availableProjects = new ArrayList<Project>();
606
607 for( Project project : projectList )
608 if( project.isOpen() )
609 availableProjects.add( project );
610
611 return availableProjects;
612 }
613
614 public Project openProject( Project project ) throws SoapUIException
615 {
616 return reloadProject( project );
617 }
618
619 public String getId()
620 {
621 return String.valueOf( hashCode() );
622 }
623
624 public List<? extends ModelItem> getChildren()
625 {
626 return getProjectList();
627 }
628
629 public ModelItem getParent()
630 {
631 return null;
632 }
633
634 public void inspectProjects()
635 {
636 for( int cnt = 0; cnt < projectList.size(); cnt++ )
637 {
638 Project project = projectList.get( cnt );
639 if( project.isOpen() )
640 project.inspect();
641 }
642 }
643
644 public String getProjectPassword( String name )
645 {
646 return projectOptions.get( name );
647 }
648
649 public void clearProjectPassword( String name )
650 {
651 projectOptions.remove( name );
652 }
653
654 }