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 import javax.xml.namespace.QName;
26
27 import org.apache.log4j.Logger;
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 Logger log = Logger.getLogger( 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 WsdlInterface getInterfaceByBindingName( QName bindingName )
262 {
263 for( int c = 0; c < getInterfaceCount(); c++ )
264 {
265 if( getInterfaceAt( c ).getBindingName().equals( bindingName ))
266 return getInterfaceAt( c );
267 }
268
269 return null;
270 }
271
272 public int getInterfaceCount()
273 {
274 return interfaces.size();
275 }
276
277 public String getPath()
278 {
279 return path;
280 }
281
282 public boolean save() throws IOException
283 {
284 if( projectDocument == null )
285 return true;
286
287 if( path == null )
288 {
289 File file = UISupport.getFileDialogs().saveAs(this, "Save project " + getName());
290 if( file == null ) return false;
291
292 path = file.getAbsolutePath();
293 }
294
295 File projectFile = new File( path );
296
297 while( projectFile.exists() && !projectFile.canWrite() )
298 {
299 if( UISupport.confirm( "Project file [" + path + "] can not be written to, save to new file?", "Save Project" ))
300 {
301 projectFile = UISupport.getFileDialogs().saveAs(this, "Save project " + getName());
302 if( projectFile == null ) return false;
303
304 path = projectFile.getAbsolutePath();
305 }
306 else return false;
307 }
308
309
310
311 if( projectFile.exists() && lastModified != 0 && lastModified < projectFile.lastModified() )
312 {
313 if( !UISupport.confirm(
314 "Project file for [" + getName() + "] has been modified externally, overwrite?",
315 "Save Project" ))
316 return false;
317 }
318
319 long size = 0;
320
321 if( projectFile.exists() && getSettings().getBoolean( UISettings.CREATE_BACKUP ))
322 {
323 createBackup( projectFile );
324 }
325
326
327 if( !getSettings().getBoolean( WsdlSettings.CACHE_WSDLS ))
328 {
329
330 SoapuiProjectDocumentConfig config = (SoapuiProjectDocumentConfig) projectDocument.copy();
331 removeDefinitionCaches(config);
332
333 config.getSoapuiProject().setSoapuiVersion( SoapUI.SOAPUI_VERSION );
334 config.save( projectFile );
335 }
336 else
337 {
338 try
339 {
340
341 projectDocument.getSoapuiProject().setSoapuiVersion( SoapUI.SOAPUI_VERSION );
342 ByteArrayOutputStream writer = new ByteArrayOutputStream( 8192 );
343 projectDocument.save( writer );
344 FileOutputStream out = new FileOutputStream( projectFile );
345 writer.writeTo( out );
346 out.close();
347 size = writer.size();
348 }
349 catch (Throwable t)
350 {
351 t.printStackTrace();
352 UISupport.showErrorMessage( "Failed to save project [" + getName() + "]: " + t.toString() );
353 return false;
354 }
355 }
356
357 lastModified = projectFile.lastModified();
358 log.info( "Saved project [" + getName() + "] to [" + projectFile.getAbsolutePath() + " - " +
359 size + " bytes" );
360 setProjectRoot(path);
361 return true;
362 }
363
364 private void createBackup(File projectFile) throws IOException
365 {
366 String backupFolderName = getSettings().getString( UISettings.BACKUP_FOLDER, "" );
367
368 File backupFolder = new File( backupFolderName );
369 if( !backupFolder.isAbsolute() )
370 {
371 backupFolder = new File( projectFile.getParentFile(), backupFolderName );
372 }
373
374 if( !backupFolder.exists() )
375 backupFolder.mkdirs();
376
377 File backupFile = new File( backupFolder, projectFile.getName() + ".backup" );
378 log.info( "Backing up [" + projectFile + "] to [" + backupFile + "]" );
379
380 Tools.copyFile( projectFile, backupFile, true );
381 }
382
383 private void removeDefinitionCaches(SoapuiProjectDocumentConfig config)
384 {
385 for( InterfaceConfig ifaceConfig : config.getSoapuiProject().getInterfaceList() )
386 {
387 if( ifaceConfig.isSetDefinitionCache() )
388 {
389 log.info( "Removing definition cache from interface [" + ifaceConfig.getName() + "]" );
390 ifaceConfig.unsetDefinitionCache();
391 }
392 }
393 }
394
395 public WsdlInterface [] importWsdl( String url, boolean createRequests ) throws SoapUIException
396 {
397 return importWsdl( url, createRequests, null );
398 }
399
400 public WsdlInterface [] importWsdl( String url, boolean createRequests, QName bindingName ) throws SoapUIException
401 {
402 if( projectDocument == null )
403 return null;
404
405 WsdlInterface[] result;
406
407 try
408 {
409 result = WsdlImporter.getInstance().importWsdl( this, url, bindingName );
410 }
411 catch (Exception e)
412 {
413 log.error( "Error importing wsdl: " + e );
414 e.printStackTrace();
415 throw new SoapUIException( "Error importing wsdl", e );
416 }
417
418 try
419 {
420 if( createRequests && result != null )
421 {
422 for (WsdlInterface iface : result)
423 {
424 for( int c = 0; c < iface.getOperationCount(); c++ )
425 {
426 WsdlOperation operation = (WsdlOperation) iface.getOperationAt( c );
427 WsdlRequest request = operation.addNewRequest( "Request 1");
428 try
429 {
430 request.setRequestContent( operation.createRequest( true ));
431 }
432 catch (Exception e)
433 {
434 e.printStackTrace();
435 }
436 }
437 }
438 }
439 }
440 catch (Exception e)
441 {
442 log.error( "Error creating requests: " + e.getMessage() );
443 throw new SoapUIException( "Error creating requests", e );
444 }
445
446 return result;
447 }
448
449 public WsdlInterface addNewInterface( String name )
450 {
451 WsdlInterface iface = new WsdlInterface( this, getConfig().addNewInterface());
452 iface.setName( name );
453 interfaces.add( iface );
454 fireInterfaceAdded( iface );
455
456 return iface;
457 }
458
459 public void addProjectListener(ProjectListener listener)
460 {
461 listeners.add( listener );
462 }
463
464 public void removeProjectListener(ProjectListener listener)
465 {
466 listeners.remove( listener );
467 }
468
469 public void fireInterfaceAdded( WsdlInterface iface )
470 {
471 ProjectListener[] a = listeners.toArray( new ProjectListener[listeners.size()] );
472
473 for (int c = 0; c < a.length; c++ )
474 {
475 a[c].interfaceAdded( iface );
476 }
477 }
478
479 public void fireInterfaceRemoved( WsdlInterface iface )
480 {
481 ProjectListener[] a = listeners.toArray( new ProjectListener[listeners.size()] );
482
483 for (int c = 0; c < a.length; c++ )
484 {
485 a[c].interfaceRemoved( iface );
486 }
487 }
488
489
490 public void fireTestSuiteAdded( WsdlTestSuite testSuite )
491 {
492 ProjectListener[] a = listeners.toArray( new ProjectListener[listeners.size()] );
493
494 for (int c = 0; c < a.length; c++ )
495 {
496 a[c].testSuiteAdded( testSuite );
497 }
498 }
499
500 public void fireTestSuiteRemoved( WsdlTestSuite testSuite )
501 {
502 ProjectListener[] a = listeners.toArray( new ProjectListener[listeners.size()] );
503
504 for (int c = 0; c < a.length; c++ )
505 {
506 a[c].testSuiteRemoved( testSuite );
507 }
508 }
509
510 public void fireMockServiceAdded( WsdlMockService mockService )
511 {
512 ProjectListener[] a = listeners.toArray( new ProjectListener[listeners.size()] );
513
514 for (int c = 0; c < a.length; c++ )
515 {
516 a[c].mockServiceAdded( mockService );
517 }
518 }
519
520 public void fireMockServiceRemoved( WsdlMockService mockService )
521 {
522 ProjectListener[] a = listeners.toArray( new ProjectListener[listeners.size()] );
523
524 for (int c = 0; c < a.length; c++ )
525 {
526 a[c].mockServiceRemoved( mockService );
527 }
528 }
529
530 public void removeInterface(WsdlInterface iface )
531 {
532 int ix = interfaces.indexOf( iface );
533 interfaces.remove( ix );
534 try
535 {
536 fireInterfaceRemoved( iface );
537 }
538 finally
539 {
540 iface.release();
541 getConfig().removeInterface( ix );
542 }
543 }
544
545 public void removeTestSuite(WsdlTestSuite testSuite )
546 {
547 int ix = testSuites.indexOf( testSuite );
548 testSuites.remove( ix );
549
550 try
551 {
552 fireTestSuiteRemoved( testSuite );
553 }
554 finally
555 {
556 testSuite.release();
557 getConfig().removeTestSuite( ix );
558 }
559 }
560
561 public boolean isDisabled()
562 {
563 return projectDocument == null;
564 }
565
566 public int getTestSuiteCount()
567 {
568 return testSuites.size();
569 }
570
571 public WsdlTestSuite getTestSuiteAt(int index)
572 {
573 return testSuites.get( index );
574 }
575
576 public WsdlTestSuite getTestSuiteByName(String testSuiteName)
577 {
578 return ( WsdlTestSuite ) getWsdlModelItemByName( testSuites, testSuiteName );
579 }
580
581 public WsdlTestSuite addNewTestSuite(String name)
582 {
583 WsdlTestSuite testSuite = new WsdlTestSuite( this, getConfig().addNewTestSuite());
584 testSuite.setName( name );
585 testSuites.add( testSuite );
586 fireTestSuiteAdded( testSuite );
587
588 return testSuite;
589 }
590
591 public WsdlTestSuite cloneTestSuite(WsdlTestSuite testSuite, String name)
592 {
593 TestSuiteConfig testSuiteConfig = getConfig().addNewTestSuite();
594 testSuiteConfig.set( testSuite.getConfig() );
595 WsdlTestSuite newTestSuite = new WsdlTestSuite( this, testSuiteConfig );
596 newTestSuite.setName( name );
597 testSuites.add( newTestSuite );
598 fireTestSuiteAdded( newTestSuite );
599
600 return newTestSuite;
601 }
602
603 public boolean isCacheDefinitions()
604 {
605 return getSettings().getBoolean( WsdlSettings.CACHE_WSDLS );
606 }
607
608 public void setCacheDefinitions( boolean cacheDefinitions )
609 {
610 getSettings().setBoolean( WsdlSettings.CACHE_WSDLS, cacheDefinitions );
611 }
612
613 public boolean saveTo(String fileName) throws IOException
614 {
615 String oldPath = path;
616 path = fileName;
617 boolean result = save();
618 if( !result )
619 path = oldPath;
620
621 setProjectRoot(path);
622
623 return result;
624 }
625
626 public void release()
627 {
628 super.release();
629
630 for( WsdlTestSuite testSuite : testSuites )
631 testSuite.release();
632
633 for( WsdlInterface iface : interfaces )
634 iface.release();
635
636 for( WsdlMockService mockService : mockServices )
637 mockService.release();
638 }
639
640 public WsdlMockService cloneMockService( WsdlMockService mockService, String name )
641 {
642 MockServiceConfig testSuiteConfig = getConfig().addNewMockService();
643 testSuiteConfig.set( mockService.getConfig() );
644 WsdlMockService newMockService = new WsdlMockService( this, testSuiteConfig );
645 newMockService.setName( name );
646 mockServices.add( newMockService );
647 fireMockServiceAdded( newMockService );
648
649 return newMockService;
650 }
651
652 public WsdlMockService addNewMockService( String name )
653 {
654 WsdlMockService mockService = new WsdlMockService( this, getConfig().addNewMockService());
655 mockService.setName( name );
656 mockServices.add( mockService );
657 fireMockServiceAdded( mockService );
658
659 return mockService;
660 }
661
662 public WsdlMockService getMockServiceAt( int index )
663 {
664 return mockServices.get( index );
665 }
666
667 public WsdlMockService getMockServiceByName( String mockServiceName )
668 {
669 return (WsdlMockService) getWsdlModelItemByName( mockServices, mockServiceName );
670 }
671
672 public int getMockServiceCount()
673 {
674 return mockServices.size();
675 }
676
677 public void removeMockService(WsdlMockService mockService )
678 {
679 int ix = mockServices.indexOf( mockService );
680 mockServices.remove( ix );
681
682 try
683 {
684 fireMockServiceRemoved( mockService );
685 }
686 finally
687 {
688 mockService.release();
689 getConfig().removeMockService( ix );
690 }
691 }
692
693 public List<TestSuite> getTestSuites()
694 {
695 return new ArrayList<TestSuite>( testSuites );
696 }
697
698 public List<MockService> getMockServices()
699 {
700 return new ArrayList<MockService>( mockServices );
701 }
702
703 public List<Interface> getInterfaces()
704 {
705 return new ArrayList<Interface>( interfaces );
706 }
707
708 public void reload( File file ) throws SoapUIException
709 {
710 this.path = file.getAbsolutePath();
711 getWorkspace().reloadProject( this );
712 }
713
714 public boolean hasNature(String natureId)
715 {
716 Settings projectSettings = getSettings();
717 String projectNature = projectSettings.getString( ProjectSettings.PROJECT_NATURE, null );
718 return natureId.equals(projectNature);
719 }
720 }