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