1
2
3
4
5
6
7
8
9
10
11
12
13 package com.eviware.soapui.impl.wsdl;
14
15 import java.io.ByteArrayOutputStream;
16 import java.io.File;
17 import java.io.FileOutputStream;
18 import java.io.IOException;
19 import java.util.ArrayList;
20 import java.util.HashSet;
21 import java.util.List;
22 import java.util.Set;
23
24 import javax.swing.ImageIcon;
25
26 import org.apache.commons.logging.Log;
27 import org.apache.commons.logging.LogFactory;
28 import org.apache.xmlbeans.XmlException;
29
30 import com.eviware.soapui.SoapUI;
31 import com.eviware.soapui.config.InterfaceConfig;
32 import com.eviware.soapui.config.MockServiceConfig;
33 import com.eviware.soapui.config.ProjectConfig;
34 import com.eviware.soapui.config.SoapuiProjectDocumentConfig;
35 import com.eviware.soapui.config.TestSuiteConfig;
36 import com.eviware.soapui.impl.WorkspaceImpl;
37 import com.eviware.soapui.impl.wsdl.actions.iface.tools.jbossws.WSToolsJava2WsdlAction;
38 import com.eviware.soapui.impl.wsdl.actions.project.AddInterfaceActionFromFile;
39 import com.eviware.soapui.impl.wsdl.actions.project.AddInterfaceActionFromURL;
40 import com.eviware.soapui.impl.wsdl.actions.project.AddNewMockServiceAction;
41 import com.eviware.soapui.impl.wsdl.actions.project.AddNewTestSuiteAction;
42 import com.eviware.soapui.impl.wsdl.actions.project.ReloadProjectAction;
43 import com.eviware.soapui.impl.wsdl.actions.project.RemoveProjectAction;
44 import com.eviware.soapui.impl.wsdl.actions.project.RenameProjectAction;
45 import com.eviware.soapui.impl.wsdl.actions.project.SaveProjectAction;
46 import com.eviware.soapui.impl.wsdl.actions.project.SaveProjectAsAction;
47 import com.eviware.soapui.impl.wsdl.actions.support.ShowOnlineHelpAction;
48 import com.eviware.soapui.impl.wsdl.mock.WsdlMockService;
49 import com.eviware.soapui.impl.wsdl.support.HelpUrls;
50 import com.eviware.soapui.impl.wsdl.support.wsdl.WsdlImporter;
51 import com.eviware.soapui.model.iface.Interface;
52 import com.eviware.soapui.model.mock.MockService;
53 import com.eviware.soapui.model.project.Project;
54 import com.eviware.soapui.model.project.ProjectListener;
55 import com.eviware.soapui.model.settings.Settings;
56 import com.eviware.soapui.model.testsuite.TestSuite;
57 import com.eviware.soapui.settings.ProjectSettings;
58 import com.eviware.soapui.settings.UISettings;
59 import com.eviware.soapui.settings.WsdlSettings;
60 import com.eviware.soapui.support.SoapUIException;
61 import com.eviware.soapui.support.Tools;
62 import com.eviware.soapui.support.UISupport;
63 import com.eviware.soapui.support.action.ActionSupport;
64
65 /***
66 * WSDL project implementation
67 *
68 * @author Ole.Matzura
69 */
70
71 public class WsdlProject extends AbstractWsdlModelItem<ProjectConfig> implements Project
72 {
73 private WorkspaceImpl workspace;
74 private String path;
75 private List<WsdlInterface> interfaces = new ArrayList<WsdlInterface>();
76 private List<WsdlTestSuite> testSuites = new ArrayList<WsdlTestSuite>();
77 private List<WsdlMockService> mockServices = new ArrayList<WsdlMockService>();
78 private Set<ProjectListener> listeners = new HashSet<ProjectListener>();
79 private SoapuiProjectDocumentConfig projectDocument;
80 private ImageIcon disabledIcon;
81 private long lastModified;
82
83 private final static Log log = LogFactory.getLog( WsdlProject.class );
84
85 public WsdlProject() throws XmlException, IOException
86 {
87 this( (WorkspaceImpl)null );
88 }
89
90 public WsdlProject( String path ) throws XmlException, IOException, SoapUIException
91 {
92 this( path, null );
93 }
94
95 public WsdlProject( WorkspaceImpl workspace ) throws XmlException, IOException
96 {
97 super( null, workspace, "/project.gif" );
98 this.workspace = workspace;
99 projectDocument = SoapuiProjectDocumentConfig.Factory.newInstance();
100
101 setConfig( projectDocument.addNewSoapuiProject() );
102
103 initActions();
104 }
105
106 public WsdlProject(String path, WorkspaceImpl workspace ) throws SoapUIException
107 {
108 this( path, workspace, true );
109 }
110
111 public WsdlProject(String path, WorkspaceImpl workspace, boolean create ) throws SoapUIException
112 {
113 super( null, workspace, "/project.gif" );
114
115 this.workspace = workspace;
116 this.path = path;
117 File file = new File(path);
118
119 if( file.exists())
120 {
121 loadProject( file );
122 }
123 else if( create )
124 {
125 projectDocument = SoapuiProjectDocumentConfig.Factory.newInstance();
126 setConfig( projectDocument.addNewSoapuiProject() );
127 }
128 else
129 {
130 disabledIcon = UISupport.createImageIcon( "/disabledProject.gif" );
131 }
132
133 setProjectRoot(path);
134 initActions();
135 }
136
137 private void loadProject( File file ) throws SoapUIException
138 {
139 try
140 {
141 lastModified = file.lastModified();
142 projectDocument = SoapuiProjectDocumentConfig.Factory.parse( file );
143 }
144 catch (Exception e)
145 {
146 throw new SoapUIException( "Failed to create project from file [" + file.getName() + "]", e );
147 }
148
149 setConfig( projectDocument.getSoapuiProject() );
150
151
152 if( !getSettings().getBoolean( WsdlSettings.CACHE_WSDLS ))
153 {
154 removeDefinitionCaches( projectDocument );
155 }
156
157 log.info( "Loaded project from [" + file.getAbsolutePath() + "]" );
158
159 List<InterfaceConfig> interfaceConfigs = getConfig().getInterfaceList();
160 for (InterfaceConfig config : interfaceConfigs)
161 {
162 interfaces.add( new WsdlInterface( this, config ));
163 }
164
165 List<TestSuiteConfig> testSuiteConfigs = getConfig().getTestSuiteList();
166 for( TestSuiteConfig config : testSuiteConfigs )
167 {
168 testSuites.add( new WsdlTestSuite( this, config ));
169 }
170
171 List<MockServiceConfig> mockServiceConfigs = getConfig().getMockServiceList();
172 for( MockServiceConfig config : mockServiceConfigs )
173 {
174 mockServices.add( new WsdlMockService( this, config ));
175 }
176 }
177
178 private void setProjectRoot(String path)
179 {
180 if( path != null && projectDocument != null )
181 {
182 int ix = path.lastIndexOf( File.separatorChar );
183 if( ix > 0 )
184 getSettings().setString( ProjectSettings.PROJECT_ROOT, path.substring( 0, ix ) );
185 }
186 }
187
188 @Override
189 public ImageIcon getIcon()
190 {
191 if( projectDocument != null )
192 return super.getIcon();
193 else
194 return disabledIcon;
195 }
196
197 @Override
198 public String getName()
199 {
200 if( projectDocument != null )
201 return super.getName();
202 else
203 {
204 int ix = path.lastIndexOf( File.separatorChar );
205 String name = ix == -1 ? path : path.substring( ix+1 );
206 return name + " (disabled)";
207 }
208 }
209
210 @Override
211 public String getDescription()
212 {
213 return projectDocument == null ? getName() : super.getDescription();
214 }
215
216 private void initActions()
217 {
218 if( projectDocument == null )
219 {
220 addAction( new ReloadProjectAction( this ));
221 addAction( new RemoveProjectAction( this ));
222 addAction( ActionSupport.SEPARATOR_ACTION );
223 addAction( new ShowOnlineHelpAction( HelpUrls.PROJECT_HELP_URL ));
224 }
225 else
226 {
227 addAction( new AddInterfaceActionFromURL( this ) );
228 addAction( new AddInterfaceActionFromFile( this ) );
229 addAction( ActionSupport.SEPARATOR_ACTION );
230 addAction( new WSToolsJava2WsdlAction( this ) );
231 addAction( ActionSupport.SEPARATOR_ACTION );
232 addAction( new AddNewTestSuiteAction( this ) );
233 addAction( new AddNewMockServiceAction( this ) );
234 addAction( ActionSupport.SEPARATOR_ACTION );
235 addAction( new RenameProjectAction( this ) );
236 addAction( new RemoveProjectAction( this ) );
237 addAction( new ReloadProjectAction( this ));
238 addAction( ActionSupport.SEPARATOR_ACTION );
239 addAction( new SaveProjectAction( this ));
240 addAction( new SaveProjectAsAction( this ));
241 addAction( ActionSupport.SEPARATOR_ACTION );
242 addAction( new ShowOnlineHelpAction( HelpUrls.PROJECT_HELP_URL ));
243 }
244 }
245
246 public WorkspaceImpl getWorkspace()
247 {
248 return workspace;
249 }
250
251 public WsdlInterface getInterfaceAt(int index)
252 {
253 return interfaces.get( index );
254 }
255
256 public WsdlInterface getInterfaceByName(String interfaceName)
257 {
258 return (WsdlInterface) getWsdlModelItemByName( interfaces, interfaceName );
259 }
260
261 public int getInterfaceCount()
262 {
263 return interfaces.size();
264 }
265
266 public String getPath()
267 {
268 return path;
269 }
270
271 public boolean save() throws IOException
272 {
273 if( projectDocument == null )
274 return true;
275
276 if( path == null )
277 {
278 File file = UISupport.getFileDialogs().saveAs(this, "Save project " + getName());
279 if( file == null ) return false;
280
281 path = file.getAbsolutePath();
282 }
283
284 File projectFile = new File( path );
285
286 while( projectFile.exists() && !projectFile.canWrite() )
287 {
288 if( UISupport.confirm( "Project file [" + path + "] can not be written to, save to new file?", "Save Project" ))
289 {
290 projectFile = UISupport.getFileDialogs().saveAs(this, "Save project " + getName());
291 if( projectFile == null ) return false;
292
293 path = projectFile.getAbsolutePath();
294 }
295 else return false;
296 }
297
298
299
300 if( projectFile.exists() && lastModified != 0 && lastModified < projectFile.lastModified() )
301 {
302 if( !UISupport.confirm(
303 "Project file for [" + getName() + "] has been modified externally, overwrite?",
304 "Save Project" ))
305 return false;
306 }
307
308 long size = 0;
309
310 if( projectFile.exists() && getSettings().getBoolean( UISettings.CREATE_BACKUP ))
311 {
312 createBackup( projectFile );
313 }
314
315
316 if( !getSettings().getBoolean( WsdlSettings.CACHE_WSDLS ))
317 {
318
319 SoapuiProjectDocumentConfig config = (SoapuiProjectDocumentConfig) projectDocument.copy();
320 removeDefinitionCaches(config);
321
322 config.getSoapuiProject().setSoapuiVersion( SoapUI.SOAPUI_VERSION );
323 config.save( projectFile );
324 }
325 else
326 {
327 try
328 {
329
330 projectDocument.getSoapuiProject().setSoapuiVersion( SoapUI.SOAPUI_VERSION );
331 ByteArrayOutputStream writer = new ByteArrayOutputStream( 8192 );
332 projectDocument.save( writer );
333 FileOutputStream out = new FileOutputStream( projectFile );
334 writer.writeTo( out );
335 out.close();
336 lastModified = projectFile.lastModified();
337 size = writer.size();
338 }
339 catch (Throwable t)
340 {
341 t.printStackTrace();
342 UISupport.showErrorMessage( "Failed to save project [" + getName() + "]: " + t.toString() );
343 return false;
344 }
345 }
346
347 log.info( "Saved project [" + getName() + "] to [" + projectFile.getAbsolutePath() + " - " +
348 size + " bytes" );
349 setProjectRoot(path);
350 return true;
351 }
352
353 private void createBackup(File projectFile) throws IOException
354 {
355 String backupFolderName = getSettings().getString( UISettings.BACKUP_FOLDER, "" );
356
357 File backupFolder = new File( backupFolderName );
358 if( !backupFolder.isAbsolute() )
359 {
360 backupFolder = new File( projectFile.getParentFile(), backupFolderName );
361 }
362
363 if( !backupFolder.exists() )
364 backupFolder.mkdirs();
365
366 File backupFile = new File( backupFolder, projectFile.getName() + ".backup" );
367 log.info( "Backing up [" + projectFile + "] to [" + backupFile + "]" );
368
369 Tools.copyFile( projectFile, backupFile, true );
370 }
371
372 private void removeDefinitionCaches(SoapuiProjectDocumentConfig config)
373 {
374 for( InterfaceConfig ifaceConfig : config.getSoapuiProject().getInterfaceList() )
375 {
376 if( ifaceConfig.isSetDefinitionCache() )
377 {
378 log.info( "Removing definition cache from interface [" + ifaceConfig.getName() + "]" );
379 ifaceConfig.unsetDefinitionCache();
380 }
381 }
382 }
383
384 public WsdlInterface [] importWsdl( String url, boolean createRequests ) throws SoapUIException
385 {
386 if( projectDocument == null )
387 return null;
388
389 WsdlInterface[] result;
390
391 try
392 {
393 result = WsdlImporter.getInstance().importWsdl( this, url );
394 }
395 catch (Exception e)
396 {
397 log.error( "Error importing wsdl: " + e );
398 e.printStackTrace();
399 throw new SoapUIException( "Error importing wsdl", e );
400 }
401
402 try
403 {
404 if( createRequests && result != null )
405 {
406 for (WsdlInterface iface : result)
407 {
408 for( int c = 0; c < iface.getOperationCount(); c++ )
409 {
410 WsdlOperation operation = (WsdlOperation) iface.getOperationAt( c );
411 WsdlRequest request = operation.addNewRequest( "Request 1");
412 try
413 {
414 request.setRequestContent( operation.createRequest( true ));
415 }
416 catch (Exception e)
417 {
418 e.printStackTrace();
419 }
420 }
421 }
422 }
423 }
424 catch (Exception e)
425 {
426 log.error( "Error creating requests: " + e.getMessage() );
427 throw new SoapUIException( "Error creating requests", e );
428 }
429
430 return result;
431 }
432
433 public WsdlInterface addNewInterface( String name )
434 {
435 WsdlInterface iface = new WsdlInterface( this, getConfig().addNewInterface());
436 iface.setName( name );
437 interfaces.add( iface );
438 fireInterfaceAdded( iface );
439
440 return iface;
441 }
442
443 public void addProjectListener(ProjectListener listener)
444 {
445 listeners.add( listener );
446 }
447
448 public void removeProjectListener(ProjectListener listener)
449 {
450 listeners.remove( listener );
451 }
452
453 public void fireInterfaceAdded( WsdlInterface iface )
454 {
455 ProjectListener[] a = listeners.toArray( new ProjectListener[listeners.size()] );
456
457 for (int c = 0; c < a.length; c++ )
458 {
459 a[c].interfaceAdded( iface );
460 }
461 }
462
463 public void fireInterfaceRemoved( WsdlInterface iface )
464 {
465 ProjectListener[] a = listeners.toArray( new ProjectListener[listeners.size()] );
466
467 for (int c = 0; c < a.length; c++ )
468 {
469 a[c].interfaceRemoved( iface );
470 }
471 }
472
473
474 public void fireTestSuiteAdded( WsdlTestSuite testSuite )
475 {
476 ProjectListener[] a = listeners.toArray( new ProjectListener[listeners.size()] );
477
478 for (int c = 0; c < a.length; c++ )
479 {
480 a[c].testSuiteAdded( testSuite );
481 }
482 }
483
484 public void fireTestSuiteRemoved( WsdlTestSuite testSuite )
485 {
486 ProjectListener[] a = listeners.toArray( new ProjectListener[listeners.size()] );
487
488 for (int c = 0; c < a.length; c++ )
489 {
490 a[c].testSuiteRemoved( testSuite );
491 }
492 }
493
494 public void fireMockServiceAdded( WsdlMockService mockService )
495 {
496 ProjectListener[] a = listeners.toArray( new ProjectListener[listeners.size()] );
497
498 for (int c = 0; c < a.length; c++ )
499 {
500 a[c].mockServiceAdded( mockService );
501 }
502 }
503
504 public void fireMockServiceRemoved( WsdlMockService mockService )
505 {
506 ProjectListener[] a = listeners.toArray( new ProjectListener[listeners.size()] );
507
508 for (int c = 0; c < a.length; c++ )
509 {
510 a[c].mockServiceRemoved( mockService );
511 }
512 }
513
514 public void removeInterface(WsdlInterface iface )
515 {
516 int ix = interfaces.indexOf( iface );
517 interfaces.remove( ix );
518 try
519 {
520 fireInterfaceRemoved( iface );
521 }
522 finally
523 {
524 iface.release();
525 getConfig().removeInterface( ix );
526 }
527 }
528
529 public void removeTestSuite(WsdlTestSuite testSuite )
530 {
531 int ix = testSuites.indexOf( testSuite );
532 testSuites.remove( ix );
533
534 try
535 {
536 fireTestSuiteRemoved( testSuite );
537 }
538 finally
539 {
540 testSuite.release();
541 getConfig().removeTestSuite( ix );
542 }
543 }
544
545 public boolean isDisabled()
546 {
547 return projectDocument == null;
548 }
549
550 public int getTestSuiteCount()
551 {
552 return testSuites.size();
553 }
554
555 public TestSuite getTestSuiteAt(int index)
556 {
557 return testSuites.get( index );
558 }
559
560 public WsdlTestSuite getTestSuiteByName(String testSuiteName)
561 {
562 return ( WsdlTestSuite ) getWsdlModelItemByName( testSuites, testSuiteName );
563 }
564
565 public WsdlTestSuite addNewTestSuite(String name)
566 {
567 WsdlTestSuite testSuite = new WsdlTestSuite( this, getConfig().addNewTestSuite());
568 testSuite.setName( name );
569 testSuites.add( testSuite );
570 fireTestSuiteAdded( testSuite );
571
572 return testSuite;
573 }
574
575 public WsdlTestSuite cloneTestSuite(WsdlTestSuite testSuite, String name)
576 {
577 TestSuiteConfig testSuiteConfig = getConfig().addNewTestSuite();
578 testSuiteConfig.set( testSuite.getConfig() );
579 WsdlTestSuite newTestSuite = new WsdlTestSuite( this, testSuiteConfig );
580 newTestSuite.setName( name );
581 testSuites.add( newTestSuite );
582 fireTestSuiteAdded( newTestSuite );
583
584 return newTestSuite;
585 }
586
587 public boolean isCacheDefinitions()
588 {
589 return getSettings().getBoolean( WsdlSettings.CACHE_WSDLS );
590 }
591
592 public void setCacheDefinitions( boolean cacheDefinitions )
593 {
594 getSettings().setBoolean( WsdlSettings.CACHE_WSDLS, cacheDefinitions );
595 }
596
597 public boolean saveTo(String fileName) throws IOException
598 {
599 String oldPath = path;
600 path = fileName;
601 boolean result = save();
602 if( !result )
603 path = oldPath;
604
605 setProjectRoot(path);
606
607 return result;
608 }
609
610 public void release()
611 {
612 super.release();
613
614 for( WsdlTestSuite testSuite : testSuites )
615 testSuite.release();
616
617 for( WsdlInterface iface : interfaces )
618 iface.release();
619 }
620
621 public WsdlMockService cloneMockService( WsdlMockService mockService, String name )
622 {
623 MockServiceConfig testSuiteConfig = getConfig().addNewMockService();
624 testSuiteConfig.set( mockService.getConfig() );
625 WsdlMockService newMockService = new WsdlMockService( this, testSuiteConfig );
626 newMockService.setName( name );
627 mockServices.add( newMockService );
628 fireMockServiceAdded( newMockService );
629
630 return newMockService;
631 }
632
633 public WsdlMockService addNewMockService( String name )
634 {
635 WsdlMockService mockService = new WsdlMockService( this, getConfig().addNewMockService());
636 mockService.setName( name );
637 mockServices.add( mockService );
638 fireMockServiceAdded( mockService );
639
640 return mockService;
641 }
642
643 public MockService getMockServiceAt( int index )
644 {
645 return mockServices.get( index );
646 }
647
648 public MockService getMockServiceByName( String mockServiceName )
649 {
650 return (MockService) getWsdlModelItemByName( mockServices, mockServiceName );
651 }
652
653 public int getMockServiceCount()
654 {
655 return mockServices.size();
656 }
657
658 public void removeMockService(WsdlMockService mockService )
659 {
660 int ix = mockServices.indexOf( mockService );
661 mockServices.remove( ix );
662
663 try
664 {
665 fireMockServiceRemoved( mockService );
666 }
667 finally
668 {
669 mockService.release();
670 getConfig().removeMockService( ix );
671 }
672 }
673
674 public List<TestSuite> getTestSuites()
675 {
676 return new ArrayList<TestSuite>( testSuites );
677 }
678
679 public List<MockService> getMockServices()
680 {
681 return new ArrayList<MockService>( mockServices );
682 }
683
684 public List<Interface> getInterfaces()
685 {
686 return new ArrayList<Interface>( interfaces );
687 }
688
689 public void reload( File file ) throws SoapUIException
690 {
691 this.path = file.getAbsolutePath();
692 getWorkspace().reloadProject( this );
693 }
694
695 public boolean hasNature(String natureId)
696 {
697 Settings projectSettings = getSettings();
698 String projectNature = projectSettings.getString( ProjectSettings.PROJECT_NATURE, null );
699 return natureId.equals(projectNature);
700 }
701 }