1
2
3
4
5
6
7
8
9
10
11
12
13 package com.eviware.soapui.impl.support.definition.export;
14
15 import com.eviware.soapui.impl.support.definition.InterfaceDefinition;
16 import com.eviware.soapui.impl.support.definition.InterfaceDefinitionPart;
17 import com.eviware.soapui.impl.wsdl.support.Constants;
18 import com.eviware.soapui.model.iface.Interface;
19 import com.eviware.soapui.support.Tools;
20 import com.eviware.soapui.support.types.StringToStringMap;
21 import org.apache.xmlbeans.SimpleValue;
22 import org.apache.xmlbeans.XmlObject;
23
24 import java.io.File;
25 import java.net.MalformedURLException;
26 import java.net.URL;
27 import java.util.HashMap;
28 import java.util.List;
29 import java.util.Map;
30
31 public abstract class AbstractDefinitionExporter<T extends Interface> implements DefinitionExporter
32 {
33 private InterfaceDefinition definition;
34
35 public AbstractDefinitionExporter( InterfaceDefinition<T> definition )
36 {
37 this.definition = definition;
38 }
39
40 public InterfaceDefinition<T> getDefinition()
41 {
42 return definition;
43 }
44
45 public void setDefinition( InterfaceDefinition definition )
46 {
47 this.definition = definition;
48 }
49
50 public String export( String folderName ) throws Exception
51 {
52 if( definition.getDefinitionCache() == null || !definition.getDefinitionCache().validate() )
53 throw new Exception( "Definition is not cached for export" );
54
55 File outFolder = new File( folderName );
56 if( !outFolder.exists() && !outFolder.mkdirs() )
57 throw new Exception( "Failed to create directory [" + folderName + "]" );
58
59 Map<String, String> urlToFileMap = new HashMap<String, String>();
60
61 setFilenameForPart( definition.getDefinitionCache().getRootPart(), urlToFileMap, null );
62
63 List<InterfaceDefinitionPart> partList = definition.getDefinitionCache().getDefinitionParts();
64 for( InterfaceDefinitionPart part : partList )
65 {
66 setFilenameForPart( part, urlToFileMap, null );
67 }
68
69 for( InterfaceDefinitionPart part : partList )
70 {
71 XmlObject obj = XmlObject.Factory.parse( part.getContent() );
72 replaceImportsAndIncludes( obj, urlToFileMap, part.getUrl() );
73 obj.save( new File( outFolder, urlToFileMap.get( part.getUrl() ) ) );
74 }
75
76 return folderName + File.separatorChar + urlToFileMap.get( definition.getDefinitionCache().getRootPart().getUrl() );
77 }
78
79 public StringToStringMap createFilesForExport( String urlPrefix ) throws Exception
80 {
81 StringToStringMap result = new StringToStringMap();
82 Map<String, String> urlToFileMap = new HashMap<String, String>();
83
84 if( urlPrefix == null )
85 urlPrefix = "";
86
87 setFilenameForPart( definition.getDefinitionCache().getRootPart(), urlToFileMap, urlPrefix );
88
89 List<InterfaceDefinitionPart> partList = definition.getDefinitionCache().getDefinitionParts();
90 for( InterfaceDefinitionPart part : partList )
91 {
92 if( !part.isRootPart() )
93 setFilenameForPart( part, urlToFileMap, urlPrefix );
94 }
95
96 for( InterfaceDefinitionPart part : partList )
97 {
98 XmlObject obj = XmlObject.Factory.parse( part.getContent() );
99 replaceImportsAndIncludes( obj, urlToFileMap, part.getUrl() );
100 String urlString = urlToFileMap.get( part.getUrl() );
101 if( urlString.startsWith( urlPrefix ) )
102 urlString = urlString.substring( urlPrefix.length() );
103
104 result.put( urlString, obj.xmlText() );
105
106 if( part.isRootPart() )
107 result.put( "#root#", urlString );
108 }
109
110 return result;
111 }
112
113 private void setFilenameForPart( InterfaceDefinitionPart part, Map<String, String> urlToFileMap, String urlPrefix )
114 throws MalformedURLException
115 {
116
117 String path = part.getUrl();
118
119 try
120 {
121 URL url = new URL( path );
122 path = url.getPath();
123 }
124 catch( MalformedURLException e )
125 {
126 }
127
128 int ix = path.lastIndexOf( '/' );
129 String fileName = ix == -1 ? path : path.substring( ix + 1 );
130
131 ix = fileName.lastIndexOf( '.' );
132 if( ix != -1 )
133 fileName = fileName.substring( 0, ix );
134
135 String type = part.getType();
136
137 if( type.equals( Constants.WSDL11_NS ) )
138 fileName += ".wsdl";
139 else if( part.getType().equals( Constants.XSD_NS ) )
140 fileName += ".xsd";
141 else if( part.getType().equals( Constants.WADL10_NS ) )
142 fileName += ".wadl";
143 else
144 fileName += ".xml";
145
146 if( urlPrefix != null )
147 fileName = urlPrefix + fileName;
148
149 int cnt = 1;
150 while( urlToFileMap.containsValue( fileName ) )
151 {
152 ix = fileName.lastIndexOf( '.' );
153 fileName = fileName.substring( 0, ix ) + "_" + cnt + fileName.substring( ix );
154 cnt++;
155 }
156
157 urlToFileMap.put( part.getUrl(), fileName );
158 }
159
160 private void replaceImportsAndIncludes( XmlObject xmlObject, Map<String, String> urlToFileMap, String baseUrl )
161 throws Exception
162 {
163 String[] paths = getLocationXPathsToReplace();
164
165 for( String path : paths )
166 {
167 XmlObject[] locations = xmlObject.selectPath( path );
168
169 for( int i = 0; i < locations.length; i++ )
170 {
171 SimpleValue wsdlImport = ( ( SimpleValue ) locations[i] );
172 replaceLocation( urlToFileMap, baseUrl, wsdlImport );
173 }
174 }
175 }
176
177 protected abstract String[] getLocationXPathsToReplace();
178
179 private void replaceLocation( Map<String, String> urlToFileMap, String baseUrl, SimpleValue wsdlImport )
180 throws Exception
181 {
182 String location = wsdlImport.getStringValue();
183 if( location != null )
184 {
185 if( location.startsWith( "file:" ) || location.indexOf( "://" ) > 0 )
186 {
187 String newLocation = urlToFileMap.get( location );
188 if( newLocation != null )
189 wsdlImport.setStringValue( newLocation );
190 else
191 throw new Exception( "Missing local file for [" + newLocation + "]" );
192 }
193 else
194 {
195 String loc = Tools.joinRelativeUrl( baseUrl, location );
196 String newLocation = urlToFileMap.get( loc );
197 if( newLocation != null )
198 wsdlImport.setStringValue( newLocation );
199 else
200 throw new Exception( "Missing local file for [" + loc + "]" );
201 }
202 }
203 }
204
205 }