1
2
3
4
5
6
7
8
9
10
11
12
13 package com.eviware.soapui.impl.wsdl.support.wsdl;
14
15 import java.util.ArrayList;
16 import java.util.Collection;
17 import java.util.HashMap;
18 import java.util.HashSet;
19 import java.util.List;
20 import java.util.Map;
21 import java.util.Set;
22
23 import javax.wsdl.Definition;
24 import javax.wsdl.factory.WSDLFactory;
25 import javax.wsdl.xml.WSDLReader;
26 import javax.xml.namespace.QName;
27
28 import org.apache.log4j.Logger;
29 import org.apache.xmlbeans.SchemaType;
30 import org.apache.xmlbeans.SchemaTypeLoader;
31 import org.apache.xmlbeans.SchemaTypeSystem;
32 import org.apache.xmlbeans.XmlObject;
33 import org.apache.xmlbeans.XmlOptions;
34
35 import com.eviware.soapui.config.DefinitionCacheConfig;
36 import com.eviware.soapui.config.DefintionPartConfig;
37 import com.eviware.soapui.impl.wsdl.WsdlInterface;
38 import com.eviware.soapui.impl.wsdl.support.soap.SoapVersion;
39 import com.eviware.soapui.impl.wsdl.support.xsd.SchemaException;
40 import com.eviware.soapui.impl.wsdl.support.xsd.SchemaUtils;
41 import com.eviware.soapui.support.NullProgressDialog;
42 import com.eviware.soapui.support.UISupport;
43 import com.eviware.x.dialogs.Worker;
44 import com.eviware.x.dialogs.XProgressDialog;
45 import com.eviware.x.dialogs.XProgressMonitor;
46
47 /***
48 * Holder for WSDL4J Definitions and related SchemaTypeLoader types
49 *
50 * @author Ole.Matzura
51 */
52
53 public class WsdlContext
54 {
55 private String url;
56 private Definition definition;
57 private SchemaTypeLoader schemaTypes;
58 private boolean loaded;
59 private SchemaException schemaException;
60
61 private final static Logger log = Logger.getLogger( WsdlContext.class );
62 private SoapVersion soapVersion;
63 private DefinitionCacheConfig cache;
64 private WsdlLoader currentLoader;
65 private final WsdlInterface iface;
66 private WSDLFactory factory;
67 private WSDLReader wsdlReader;
68
69 public WsdlContext( String url, SoapVersion soapVersion, DefinitionCacheConfig cache, WsdlInterface iface )
70 {
71 this.url = url;
72 this.soapVersion = soapVersion;
73 this.cache = cache;
74 this.iface = iface;
75 }
76
77 public DefinitionCacheConfig getCacheConfig()
78 {
79 return cache;
80 }
81
82 public Definition getDefinition() throws Exception
83 {
84 loadIfNecessary();
85 return definition;
86 }
87
88 public boolean isLoaded()
89 {
90 return loaded;
91 }
92
93 public synchronized boolean loadIfNecessary() throws Exception
94 {
95 if( !loaded )
96 load();
97
98 return loaded;
99 }
100
101 public synchronized void setDefinition( String url, DefinitionCacheConfig cache )
102 {
103 this.url = url;
104 this.cache = null;
105 loaded = false;
106 }
107
108 public synchronized void load() throws Exception
109 {
110 if( loaded )
111 return;
112
113
114 XProgressDialog progressDialog;
115 if( url.startsWith("file:") )
116 {
117 progressDialog = new NullProgressDialog();
118 }
119 else
120 {
121 progressDialog = UISupport.getDialogs().createProgressDialog(
122 "Loading WSDL", 3, "Loading definition..", true );
123 }
124
125 Loader loader = new Loader();
126 progressDialog.run( loader);
127
128
129
130 if( loader.hasError() )
131 {
132 if( loader.getError() instanceof SchemaException )
133 {
134 schemaException = (SchemaException) loader.getError();
135 ArrayList errorList = schemaException.getErrorList();
136
137 if( errorList != null )
138 {
139 log.error( "Error loading schema types from " + url + ", see log for details" );
140 for( int c = 0; c < errorList.size(); c++ )
141 {
142 log.error( errorList.get( c ).toString() );
143 }
144 }
145
146 UISupport.showErrorMessage( "Error loading schema types from " + url + ", see log for details" );
147 }
148 else throw loader.getError();
149 }
150 else loaded = true;
151 }
152
153 public SchemaTypeLoader getSchemaTypeLoader() throws Exception
154 {
155 loadIfNecessary();
156 return schemaTypes;
157 }
158
159 public SchemaException getSchemaException()
160 {
161 return schemaException;
162 }
163
164 private class Loader extends Worker.WorkerAdapter
165 {
166 private Exception error;
167
168 public boolean hasError()
169 {
170 return error != null;
171 }
172
173 public Object construct(XProgressMonitor monitor)
174 {
175 try
176 {
177 if( !validateCache( cache ) )
178 {
179 monitor.setProgress( 1, "Caching definition from url [" + url + "]" );
180
181 currentLoader = new UrlWsdlLoader( url );
182 cache = iface == null ? WsdlLoader.cacheWsdl( (UrlWsdlLoader) currentLoader ) :
183 iface.cacheDefinition( (UrlWsdlLoader) currentLoader );
184
185 if( currentLoader.isAborted() )
186 throw new Exception( "Loading of WSDL from [" + url + "] was aborted" );
187 }
188
189 monitor.setProgress( 1, "Loading definition from " + (cache == null ? "url" : "cache") );
190
191 log.debug( "Loading definition from " + (cache == null ? "url" : "cache") );
192 loadDefinitions( cache == null ? new UrlWsdlLoader( url ) : new CachedWsdlLoader( cache ));
193 return null;
194 }
195 catch (Exception e)
196 {
197 log.error( "Loading of definition failed for [" + url + "]; " + e );
198 e.printStackTrace();
199 this.error = e;
200 return e;
201 }
202 finally
203 {
204 currentLoader = null;
205 }
206 }
207
208 public Exception getError()
209 {
210 return error;
211 }
212
213 public boolean onCancel()
214 {
215 if( currentLoader == null )
216 return false;
217
218 return currentLoader.abort();
219 }
220 }
221
222 private void loadDefinitions( WsdlLoader loader ) throws Exception
223 {
224 currentLoader = loader;
225
226 if( factory == null )
227 {
228 factory = WSDLFactory.newInstance();
229 wsdlReader = factory.newWSDLReader();
230 wsdlReader.setFeature("javax.wsdl.verbose", true);
231 wsdlReader.setFeature("javax.wsdl.importDocuments", true);
232 }
233
234 definition = wsdlReader.readWSDL( loader );
235 log.debug( "Loaded definition: " + (definition != null ? "ok" : "null") );
236
237 if( !currentLoader.isAborted() )
238 schemaTypes = SchemaUtils.loadSchemaTypes(url, soapVersion, loader);
239 else
240 throw new Exception( "Loading of WSDL from [" + url + "] was aborted" );
241 }
242
243 public boolean validateCache(DefinitionCacheConfig cache)
244 {
245 if( cache == null )
246 return false;
247
248 if( cache.getRootPart() == null )
249 return false;
250
251 if( cache.sizeOfPartArray() == 0 )
252 return false;
253
254 return true;
255 }
256
257 public SchemaTypeSystem getSchemaTypeSystem() throws Exception
258 {
259 if( !loaded )
260 load();
261
262 if( schemaTypes == null )
263 return null;
264
265 return schemaTypes.findElement( new QName("http://schemas.xmlsoap.org/soap/envelope/", "Envelope")).getTypeSystem();
266 }
267
268 public boolean hasSchemaTypes() throws Exception
269 {
270 loadIfNecessary();
271 return schemaTypes != null;
272 }
273
274 public SchemaType findType(QName typeName) throws Exception
275 {
276 loadIfNecessary();
277 return schemaTypes == null ? null : schemaTypes.findType( typeName );
278 }
279
280 public String getUrl()
281 {
282 return url;
283 }
284
285 public Collection<String> getDefinedNamespaces() throws Exception
286 {
287 loadIfNecessary();
288 Set<String> namespaces = new HashSet<String>();
289
290 if( schemaTypes != null )
291 {
292 namespaces.addAll( SchemaUtils.extractNamespaces( getSchemaTypeSystem() ));
293
294 namespaces.remove( "http://www.w3.org/2005/05/xmlmime" );
295 namespaces.remove( "http://ws-i.org/profiles/basic/1.1/xsd" );
296 namespaces.remove( "http://www.w3.org/2004/08/xop/include" );
297 }
298
299 if( definition != null )
300 namespaces.add( definition.getTargetNamespace() );
301
302 return namespaces;
303 }
304
305 public SoapVersion getSoapVersion()
306 {
307 return soapVersion;
308 }
309
310 public void setSoapVersion(SoapVersion soapVersion)
311 {
312 this.soapVersion = soapVersion;
313 }
314
315 public Map<String, XmlObject> getDefinitionParts() throws Exception
316 {
317 Map<String,XmlObject> result = new HashMap<String,XmlObject>();
318
319 if( cache == null )
320 return SchemaUtils.getDefinitionParts( new UrlWsdlLoader( url ));
321
322 List<DefintionPartConfig> partList = cache.getPartList();
323 for( DefintionPartConfig part : partList )
324 {
325 String str = part.getContent().toString();
326 result.put( part.getUrl(), XmlObject.Factory.parse( str, new XmlOptions().setLoadLineNumbers() ) );
327 }
328
329 return result;
330 }
331
332 public void setDefinitionCache(DefinitionCacheConfig definitionCache)
333 {
334 this.cache = definitionCache;
335 }
336 }