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