001: /*
002: * soapUI, copyright (C) 2004-2007 eviware.com
003: *
004: * soapUI is free software; you can redistribute it and/or modify it under the
005: * terms of version 2.1 of the GNU Lesser General Public License as published by
006: * the Free Software Foundation.
007: *
008: * soapUI is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without
009: * even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
010: * See the GNU Lesser General Public License for more details at gnu.org.
011: */
012:
013: package com.eviware.soapui.impl.wsdl;
014:
015: import java.io.ByteArrayOutputStream;
016: import java.io.File;
017: import java.io.FileOutputStream;
018: import java.io.IOException;
019: import java.util.ArrayList;
020: import java.util.HashSet;
021: import java.util.List;
022: import java.util.Set;
023:
024: import javax.swing.ImageIcon;
025: import javax.xml.namespace.QName;
026:
027: import org.apache.log4j.Logger;
028: import org.apache.xmlbeans.XmlException;
029: import org.apache.xmlbeans.XmlOptions;
030:
031: import com.eviware.soapui.SoapUI;
032: import com.eviware.soapui.config.InterfaceConfig;
033: import com.eviware.soapui.config.MockServiceConfig;
034: import com.eviware.soapui.config.ProjectConfig;
035: import com.eviware.soapui.config.SoapuiProjectDocumentConfig;
036: import com.eviware.soapui.config.TestSuiteConfig;
037: import com.eviware.soapui.impl.WorkspaceImpl;
038: import com.eviware.soapui.impl.wsdl.mock.WsdlMockService;
039: import com.eviware.soapui.impl.wsdl.support.wsdl.WsdlImporter;
040: import com.eviware.soapui.impl.wsdl.support.wsdl.WsdlLoader;
041: import com.eviware.soapui.model.iface.Interface;
042: import com.eviware.soapui.model.mock.MockService;
043: import com.eviware.soapui.model.project.Project;
044: import com.eviware.soapui.model.project.ProjectListener;
045: import com.eviware.soapui.model.settings.Settings;
046: import com.eviware.soapui.model.testsuite.TestSuite;
047: import com.eviware.soapui.settings.ProjectSettings;
048: import com.eviware.soapui.settings.UISettings;
049: import com.eviware.soapui.settings.WsdlSettings;
050: import com.eviware.soapui.support.SoapUIException;
051: import com.eviware.soapui.support.Tools;
052: import com.eviware.soapui.support.UISupport;
053:
054: /**
055: * WSDL project implementation
056: *
057: * @author Ole.Matzura
058: */
059:
060: public class WsdlProject extends AbstractWsdlModelItem<ProjectConfig>
061: implements Project {
062: private WorkspaceImpl workspace;
063: private String path;
064: private List<WsdlInterface> interfaces = new ArrayList<WsdlInterface>();
065: private List<WsdlTestSuite> testSuites = new ArrayList<WsdlTestSuite>();
066: private List<WsdlMockService> mockServices = new ArrayList<WsdlMockService>();
067: private Set<ProjectListener> listeners = new HashSet<ProjectListener>();
068: private SoapuiProjectDocumentConfig projectDocument;
069: private ImageIcon disabledIcon;
070: private long lastModified;
071:
072: private final static Logger log = Logger
073: .getLogger(WsdlProject.class);
074:
075: public WsdlProject() throws XmlException, IOException {
076: this ((WorkspaceImpl) null);
077: }
078:
079: public WsdlProject(String path) throws XmlException, IOException,
080: SoapUIException {
081: this (path, null);
082: }
083:
084: public WsdlProject(WorkspaceImpl workspace) throws XmlException,
085: IOException {
086: super (null, workspace, "/project.gif");
087: this .workspace = workspace;
088: projectDocument = SoapuiProjectDocumentConfig.Factory
089: .newInstance();
090:
091: setConfig(projectDocument.addNewSoapuiProject());
092: }
093:
094: public WsdlProject(String path, WorkspaceImpl workspace)
095: throws SoapUIException {
096: this (path, workspace, true);
097: }
098:
099: public WsdlProject(String path, WorkspaceImpl workspace,
100: boolean create) throws SoapUIException {
101: super (null, workspace, "/project.gif");
102:
103: this .workspace = workspace;
104: this .path = path;
105: File file = new File(path);
106:
107: if (file.exists()) {
108: loadProject(file);
109: } else if (create) {
110: projectDocument = SoapuiProjectDocumentConfig.Factory
111: .newInstance();
112: setConfig(projectDocument.addNewSoapuiProject());
113: } else {
114: disabledIcon = UISupport
115: .createImageIcon("/disabledProject.gif");
116: }
117:
118: setProjectRoot(path);
119: }
120:
121: private void loadProject(File file) throws SoapUIException {
122: try {
123: lastModified = file.lastModified();
124: projectDocument = SoapuiProjectDocumentConfig.Factory
125: .parse(file);
126: } catch (Exception e) {
127: throw new SoapUIException(
128: "Failed to create project from file ["
129: + file.getName() + "]", e);
130: }
131:
132: setConfig(projectDocument.getSoapuiProject());
133:
134: // removed cached definitions if caching is disabled
135: if (!getSettings().getBoolean(WsdlSettings.CACHE_WSDLS)) {
136: removeDefinitionCaches(projectDocument);
137: }
138:
139: log
140: .info("Loaded project from [" + file.getAbsolutePath()
141: + "]");
142:
143: List<InterfaceConfig> interfaceConfigs = getConfig()
144: .getInterfaceList();
145: for (InterfaceConfig config : interfaceConfigs) {
146: interfaces.add(new WsdlInterface(this , config));
147: }
148:
149: List<TestSuiteConfig> testSuiteConfigs = getConfig()
150: .getTestSuiteList();
151: for (TestSuiteConfig config : testSuiteConfigs) {
152: testSuites.add(new WsdlTestSuite(this , config));
153: }
154:
155: List<MockServiceConfig> mockServiceConfigs = getConfig()
156: .getMockServiceList();
157: for (MockServiceConfig config : mockServiceConfigs) {
158: mockServices.add(new WsdlMockService(this , config));
159: }
160: }
161:
162: private void setProjectRoot(String path) {
163: if (path != null && projectDocument != null) {
164: int ix = path.lastIndexOf(File.separatorChar);
165: if (ix > 0)
166: getSettings().setString(ProjectSettings.PROJECT_ROOT,
167: path.substring(0, ix));
168: }
169: }
170:
171: @Override
172: public ImageIcon getIcon() {
173: if (projectDocument != null)
174: return super .getIcon();
175: else
176: return disabledIcon;
177: }
178:
179: @Override
180: public String getName() {
181: if (projectDocument != null)
182: return super .getName();
183: else {
184: int ix = path.lastIndexOf(File.separatorChar);
185: String name = ix == -1 ? path : path.substring(ix + 1);
186: return name + " (disabled)";
187: }
188: }
189:
190: @Override
191: public String getDescription() {
192: return projectDocument == null ? getName() : super
193: .getDescription();
194: }
195:
196: public WorkspaceImpl getWorkspace() {
197: return workspace;
198: }
199:
200: public WsdlInterface getInterfaceAt(int index) {
201: return interfaces.get(index);
202: }
203:
204: public WsdlInterface getInterfaceByName(String interfaceName) {
205: return (WsdlInterface) getWsdlModelItemByName(interfaces,
206: interfaceName);
207: }
208:
209: public WsdlInterface getInterfaceByBindingName(QName bindingName) {
210: for (int c = 0; c < getInterfaceCount(); c++) {
211: if (getInterfaceAt(c).getBindingName().equals(bindingName))
212: return getInterfaceAt(c);
213: }
214:
215: return null;
216: }
217:
218: public int getInterfaceCount() {
219: return interfaces.size();
220: }
221:
222: public String getPath() {
223: return path;
224: }
225:
226: public boolean save() throws IOException {
227: if (projectDocument == null)
228: return true;
229:
230: if (path == null) {
231: File file = UISupport.getFileDialogs().saveAs(this ,
232: "Save project " + getName());
233: if (file == null)
234: return false;
235:
236: path = file.getAbsolutePath();
237: }
238:
239: File projectFile = new File(path);
240:
241: while (projectFile.exists() && !projectFile.canWrite()) {
242: if (UISupport.confirm("Project file [" + path
243: + "] can not be written to, save to new file?",
244: "Save Project")) {
245: projectFile = UISupport.getFileDialogs().saveAs(this ,
246: "Save project " + getName());
247: if (projectFile == null)
248: return false;
249:
250: path = projectFile.getAbsolutePath();
251: } else
252: return false;
253: }
254:
255: // check modified
256: if (projectFile.exists() && lastModified != 0
257: && lastModified < projectFile.lastModified()) {
258: if (!UISupport.confirm("Project file for [" + getName()
259: + "] has been modified externally, overwrite?",
260: "Save Project"))
261: return false;
262: }
263:
264: long size = 0;
265:
266: if (projectFile.exists()
267: && getSettings().getBoolean(UISettings.CREATE_BACKUP)) {
268: createBackup(projectFile);
269: }
270:
271: onSave();
272:
273: XmlOptions options = new XmlOptions();
274: if (SoapUI.getSettings().getBoolean(
275: WsdlSettings.PRETTY_PRINT_PROJECT_FILES))
276: options.setSavePrettyPrint();
277:
278: // check for caching
279: if (!getSettings().getBoolean(WsdlSettings.CACHE_WSDLS)) {
280: // no caching -> create copy and remove definition cachings
281: SoapuiProjectDocumentConfig config = (SoapuiProjectDocumentConfig) projectDocument
282: .copy();
283: removeDefinitionCaches(config);
284:
285: config.getSoapuiProject().setSoapuiVersion(
286: SoapUI.SOAPUI_VERSION);
287: config.save(projectFile, options);
288: } else {
289: try {
290: // save to temporary buffer to avoid corruption of file
291: projectDocument.getSoapuiProject().setSoapuiVersion(
292: SoapUI.SOAPUI_VERSION);
293: ByteArrayOutputStream writer = new ByteArrayOutputStream(
294: 8192);
295: projectDocument.save(writer, options);
296: FileOutputStream out = new FileOutputStream(projectFile);
297: writer.writeTo(out);
298: out.close();
299: size = writer.size();
300: } catch (Throwable t) {
301: SoapUI.logError(t);
302: UISupport.showErrorMessage("Failed to save project ["
303: + getName() + "]: " + t.toString());
304: return false;
305: }
306: }
307:
308: lastModified = projectFile.lastModified();
309: log.info("Saved project [" + getName() + "] to ["
310: + projectFile.getAbsolutePath() + " - " + size
311: + " bytes");
312: setProjectRoot(path);
313: return true;
314: }
315:
316: public void onSave() {
317: // notify
318: for (WsdlInterface iface : interfaces)
319: iface.onSave();
320:
321: for (WsdlTestSuite testSuite : testSuites)
322: testSuite.onSave();
323:
324: for (WsdlMockService mockService : mockServices)
325: mockService.onSave();
326: }
327:
328: private void createBackup(File projectFile) throws IOException {
329: String backupFolderName = getSettings().getString(
330: UISettings.BACKUP_FOLDER, "");
331:
332: File backupFolder = new File(backupFolderName);
333: if (!backupFolder.isAbsolute()) {
334: backupFolder = new File(projectFile.getParentFile(),
335: backupFolderName);
336: }
337:
338: if (!backupFolder.exists())
339: backupFolder.mkdirs();
340:
341: File backupFile = new File(backupFolder, projectFile.getName()
342: + ".backup");
343: log.info("Backing up [" + projectFile + "] to [" + backupFile
344: + "]");
345:
346: Tools.copyFile(projectFile, backupFile, true);
347: }
348:
349: private void removeDefinitionCaches(
350: SoapuiProjectDocumentConfig config) {
351: for (InterfaceConfig ifaceConfig : config.getSoapuiProject()
352: .getInterfaceList()) {
353: if (ifaceConfig.isSetDefinitionCache()) {
354: log.info("Removing definition cache from interface ["
355: + ifaceConfig.getName() + "]");
356: ifaceConfig.unsetDefinitionCache();
357: }
358: }
359: }
360:
361: public WsdlInterface[] importWsdl(String url, boolean createRequests)
362: throws SoapUIException {
363: return importWsdl(url, createRequests, null, null);
364: }
365:
366: public WsdlInterface[] importWsdl(String url,
367: boolean createRequests, WsdlLoader wsdlLoader)
368: throws SoapUIException {
369: return importWsdl(url, createRequests, null, wsdlLoader);
370: }
371:
372: public WsdlInterface[] importWsdl(String url,
373: boolean createRequests, QName bindingName,
374: WsdlLoader wsdlLoader) throws SoapUIException {
375: if (projectDocument == null)
376: return null;
377:
378: WsdlInterface[] result;
379:
380: try {
381: result = WsdlImporter.getInstance().importWsdl(this , url,
382: bindingName, wsdlLoader);
383: } catch (Exception e) {
384: log.error("Error importing wsdl: " + e);
385: SoapUI.logError(e);
386: throw new SoapUIException("Error importing wsdl", e);
387: }
388:
389: try {
390: if (createRequests && result != null) {
391: for (WsdlInterface iface : result) {
392: for (int c = 0; c < iface.getOperationCount(); c++) {
393: WsdlOperation operation = (WsdlOperation) iface
394: .getOperationAt(c);
395: WsdlRequest request = operation
396: .addNewRequest("Request 1");
397: try {
398: String requestContent = operation
399: .createRequest(true);
400: request.setRequestContent(requestContent);
401: } catch (Exception e) {
402: SoapUI.logError(e);
403: }
404: }
405: }
406: }
407: } catch (Exception e) {
408: log.error("Error creating requests: " + e.getMessage());
409: throw new SoapUIException("Error creating requests", e);
410: }
411:
412: return result;
413: }
414:
415: public WsdlInterface addNewInterface(String name) {
416: WsdlInterface iface = new WsdlInterface(this , getConfig()
417: .addNewInterface());
418: iface.setName(name);
419: interfaces.add(iface);
420: fireInterfaceAdded(iface);
421:
422: return iface;
423: }
424:
425: public void addProjectListener(ProjectListener listener) {
426: listeners.add(listener);
427: }
428:
429: public void removeProjectListener(ProjectListener listener) {
430: listeners.remove(listener);
431: }
432:
433: public void fireInterfaceAdded(WsdlInterface iface) {
434: ProjectListener[] a = listeners
435: .toArray(new ProjectListener[listeners.size()]);
436:
437: for (int c = 0; c < a.length; c++) {
438: a[c].interfaceAdded(iface);
439: }
440: }
441:
442: public void fireInterfaceRemoved(WsdlInterface iface) {
443: ProjectListener[] a = listeners
444: .toArray(new ProjectListener[listeners.size()]);
445:
446: for (int c = 0; c < a.length; c++) {
447: a[c].interfaceRemoved(iface);
448: }
449: }
450:
451: public void fireTestSuiteAdded(WsdlTestSuite testSuite) {
452: ProjectListener[] a = listeners
453: .toArray(new ProjectListener[listeners.size()]);
454:
455: for (int c = 0; c < a.length; c++) {
456: a[c].testSuiteAdded(testSuite);
457: }
458: }
459:
460: public void fireTestSuiteRemoved(WsdlTestSuite testSuite) {
461: ProjectListener[] a = listeners
462: .toArray(new ProjectListener[listeners.size()]);
463:
464: for (int c = 0; c < a.length; c++) {
465: a[c].testSuiteRemoved(testSuite);
466: }
467: }
468:
469: public void fireMockServiceAdded(WsdlMockService mockService) {
470: ProjectListener[] a = listeners
471: .toArray(new ProjectListener[listeners.size()]);
472:
473: for (int c = 0; c < a.length; c++) {
474: a[c].mockServiceAdded(mockService);
475: }
476: }
477:
478: public void fireMockServiceRemoved(WsdlMockService mockService) {
479: ProjectListener[] a = listeners
480: .toArray(new ProjectListener[listeners.size()]);
481:
482: for (int c = 0; c < a.length; c++) {
483: a[c].mockServiceRemoved(mockService);
484: }
485: }
486:
487: public void removeInterface(WsdlInterface iface) {
488: int ix = interfaces.indexOf(iface);
489: interfaces.remove(ix);
490: try {
491: fireInterfaceRemoved(iface);
492: } finally {
493: iface.release();
494: getConfig().removeInterface(ix);
495: }
496: }
497:
498: public void removeTestSuite(WsdlTestSuite testSuite) {
499: int ix = testSuites.indexOf(testSuite);
500: testSuites.remove(ix);
501:
502: try {
503: fireTestSuiteRemoved(testSuite);
504: } finally {
505: testSuite.release();
506: getConfig().removeTestSuite(ix);
507: }
508: }
509:
510: public boolean isDisabled() {
511: return projectDocument == null;
512: }
513:
514: public int getTestSuiteCount() {
515: return testSuites.size();
516: }
517:
518: public WsdlTestSuite getTestSuiteAt(int index) {
519: return testSuites.get(index);
520: }
521:
522: public WsdlTestSuite getTestSuiteByName(String testSuiteName) {
523: return (WsdlTestSuite) getWsdlModelItemByName(testSuites,
524: testSuiteName);
525: }
526:
527: public WsdlTestSuite addNewTestSuite(String name) {
528: WsdlTestSuite testSuite = new WsdlTestSuite(this , getConfig()
529: .addNewTestSuite());
530: testSuite.setName(name);
531: testSuites.add(testSuite);
532: fireTestSuiteAdded(testSuite);
533:
534: return testSuite;
535: }
536:
537: public WsdlTestSuite cloneTestSuite(WsdlTestSuite testSuite,
538: String name) {
539: testSuite.onSave();
540: TestSuiteConfig testSuiteConfig = getConfig().addNewTestSuite();
541: testSuiteConfig.set(testSuite.getConfig());
542: WsdlTestSuite newTestSuite = new WsdlTestSuite(this ,
543: testSuiteConfig);
544: newTestSuite.setName(name);
545: testSuites.add(newTestSuite);
546: fireTestSuiteAdded(newTestSuite);
547:
548: return newTestSuite;
549: }
550:
551: public boolean isCacheDefinitions() {
552: return getSettings().getBoolean(WsdlSettings.CACHE_WSDLS);
553: }
554:
555: public void setCacheDefinitions(boolean cacheDefinitions) {
556: getSettings().setBoolean(WsdlSettings.CACHE_WSDLS,
557: cacheDefinitions);
558: }
559:
560: public boolean saveTo(String fileName) throws IOException {
561: String oldPath = path;
562: path = fileName;
563: boolean result = save();
564: if (!result)
565: path = oldPath;
566:
567: setProjectRoot(path);
568:
569: return result;
570: }
571:
572: public void release() {
573: super .release();
574:
575: for (WsdlTestSuite testSuite : testSuites)
576: testSuite.release();
577:
578: for (WsdlInterface iface : interfaces)
579: iface.release();
580:
581: for (WsdlMockService mockService : mockServices)
582: mockService.release();
583: }
584:
585: public WsdlMockService cloneMockService(
586: WsdlMockService mockService, String name) {
587: mockService.onSave();
588: MockServiceConfig testSuiteConfig = getConfig()
589: .addNewMockService();
590: testSuiteConfig.set(mockService.getConfig());
591: WsdlMockService newMockService = new WsdlMockService(this ,
592: testSuiteConfig);
593: newMockService.setName(name);
594: mockServices.add(newMockService);
595: fireMockServiceAdded(newMockService);
596:
597: return newMockService;
598: }
599:
600: public WsdlMockService addNewMockService(String name) {
601: WsdlMockService mockService = new WsdlMockService(this ,
602: getConfig().addNewMockService());
603: mockService.setName(name);
604: mockServices.add(mockService);
605: fireMockServiceAdded(mockService);
606:
607: return mockService;
608: }
609:
610: public WsdlMockService getMockServiceAt(int index) {
611: return mockServices.get(index);
612: }
613:
614: public WsdlMockService getMockServiceByName(String mockServiceName) {
615: return (WsdlMockService) getWsdlModelItemByName(mockServices,
616: mockServiceName);
617: }
618:
619: public int getMockServiceCount() {
620: return mockServices.size();
621: }
622:
623: public void removeMockService(WsdlMockService mockService) {
624: int ix = mockServices.indexOf(mockService);
625: mockServices.remove(ix);
626:
627: try {
628: fireMockServiceRemoved(mockService);
629: } finally {
630: mockService.release();
631: getConfig().removeMockService(ix);
632: }
633: }
634:
635: public List<TestSuite> getTestSuites() {
636: return new ArrayList<TestSuite>(testSuites);
637: }
638:
639: public List<MockService> getMockServices() {
640: return new ArrayList<MockService>(mockServices);
641: }
642:
643: public List<Interface> getInterfaces() {
644: return new ArrayList<Interface>(interfaces);
645: }
646:
647: public void reload() throws SoapUIException {
648: reload(new File(path));
649: }
650:
651: public void reload(File file) throws SoapUIException {
652: this .path = file.getAbsolutePath();
653: getWorkspace().reloadProject(this );
654: }
655:
656: public boolean hasNature(String natureId) {
657: Settings projectSettings = getSettings();
658: String projectNature = projectSettings.getString(
659: ProjectSettings.PROJECT_NATURE, null);
660: return natureId.equals(projectNature);
661: }
662:
663: public WsdlInterface importInterface(WsdlInterface iface) {
664: iface.onSave();
665: InterfaceConfig ifaceConfig = (InterfaceConfig) getConfig()
666: .addNewInterface().set(iface.getConfig().copy());
667: iface = new WsdlInterface(this , ifaceConfig);
668: interfaces.add(iface);
669: fireInterfaceAdded(iface);
670:
671: return iface;
672: }
673:
674: public WsdlTestSuite importTestSuite(WsdlTestSuite testSuite,
675: String name) {
676: testSuite.onSave();
677: TestSuiteConfig testSuiteConfig = (TestSuiteConfig) getConfig()
678: .addNewTestSuite().set(testSuite.getConfig().copy());
679: testSuiteConfig.setName(name);
680: testSuite = new WsdlTestSuite(this , testSuiteConfig);
681: testSuites.add(testSuite);
682: fireTestSuiteAdded(testSuite);
683:
684: return testSuite;
685: }
686:
687: public WsdlMockService importMockService(
688: WsdlMockService mockService, String name) {
689: mockService.onSave();
690: MockServiceConfig mockServiceConfig = (MockServiceConfig) getConfig()
691: .addNewMockService()
692: .set(mockService.getConfig().copy());
693: mockServiceConfig.setName(name);
694: mockService = new WsdlMockService(this, mockServiceConfig);
695: mockServices.add(mockService);
696: fireMockServiceAdded(mockService);
697:
698: return mockService;
699: }
700: }
|