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
34 import com.eviware.soapui.SoapUI;
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 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 WsdlInterface getInterface()
78 {
79 return iface;
80 }
81
82 public DefinitionCacheConfig getCacheConfig()
83 {
84 return cache;
85 }
86
87 public Definition getDefinition() throws Exception
88 {
89 loadIfNecessary();
90 return definition;
91 }
92
93 public Definition getDefinitionSilently() throws Exception
94 {
95 if( load(true) )
96 {
97 return getDefinition();
98 }
99 else
100 {
101 return null;
102 }
103 }
104
105 public boolean isLoaded()
106 {
107 return loaded;
108 }
109
110 public synchronized boolean loadIfNecessary() throws Exception
111 {
112 return loadIfNecessary( false );
113 }
114
115 public synchronized boolean loadIfNecessary( boolean silent ) throws Exception
116 {
117 if( !loaded )
118 load( silent );
119
120 return loaded;
121 }
122
123 public synchronized void setDefinition( String url, DefinitionCacheConfig cache )
124 {
125 this.url = url;
126 this.cache = null;
127 loaded = false;
128 }
129
130 public synchronized boolean load() throws Exception
131 {
132 return load( null, false );
133 }
134
135 public synchronized boolean load(boolean silent) throws Exception
136 {
137 return load( null, silent );
138 }
139
140 public synchronized boolean load( WsdlLoader wsdlLoader ) throws Exception
141 {
142 return load( wsdlLoader, false );
143 }
144
145 public synchronized boolean load( WsdlLoader wsdlLoader, boolean silent ) throws Exception
146 {
147 if( loaded )
148 return true;
149
150 XProgressDialog progressDialog;
151 if( silent || url.startsWith("file:") )
152 {
153 progressDialog = new NullProgressDialog();
154 }
155 else
156 {
157 progressDialog = UISupport.getDialogs().createProgressDialog(
158 "Loading WSDL", 3, "Loading definition..", true );
159 }
160
161 Loader loader = new Loader( wsdlLoader );
162 progressDialog.run( loader);
163
164
165
166 if( loader.hasError() )
167 {
168 if( loader.getError() instanceof SchemaException )
169 {
170 schemaException = (SchemaException) loader.getError();
171 ArrayList errorList = schemaException.getErrorList();
172
173 if( errorList != null )
174 {
175 log.error( "Error loading schema types from " + url + ", see log for details" );
176 for( int c = 0; c < errorList.size(); c++ )
177 {
178 log.error( errorList.get( c ).toString() );
179 }
180 }
181
182 if(!silent)
183 UISupport.showErrorMessage( "Error loading schema types from " + url + ", see log for details" );
184 }
185 else throw loader.getError();
186 }
187 else loaded = true;
188
189 return loaded;
190 }
191
192 public SchemaTypeLoader getSchemaTypeLoader() throws Exception
193 {
194 loadIfNecessary();
195 return schemaTypes;
196 }
197
198 public SchemaException getSchemaException()
199 {
200 return schemaException;
201 }
202
203 private class Loader extends Worker.WorkerAdapter
204 {
205 private Exception error;
206 private WsdlLoader wsdlLoader;
207
208 public Loader(WsdlLoader wsdlLoader)
209 {
210 super();
211 this.wsdlLoader = wsdlLoader;
212 }
213
214 private WsdlLoader getWsdlLoader()
215 {
216 if(wsdlLoader != null) {
217 return wsdlLoader;
218 } else {
219 return new UrlWsdlLoader( url );
220 }
221 }
222
223 public boolean hasError()
224 {
225 return error != null;
226 }
227
228 public Object construct(XProgressMonitor monitor)
229 {
230 try
231 {
232 if( !validateCache( cache ) )
233 {
234 monitor.setProgress( 1, "Caching definition from url [" + url + "]" );
235
236 currentLoader = getWsdlLoader();
237 cache = iface == null ? WsdlLoader.cacheWsdl( currentLoader ) :
238 iface.cacheDefinition( currentLoader );
239
240 if( currentLoader.isAborted() )
241 throw new Exception( "Loading of WSDL from [" + url + "] was aborted" );
242 }
243
244 monitor.setProgress( 1, "Loading definition from " + (cache == null ? "url" : "cache") );
245
246 log.debug( "Loading definition from " + (cache == null ? "url" : "cache") );
247 loadDefinitions( cache == null ? getWsdlLoader() : new CachedWsdlLoader( cache ));
248 return null;
249 }
250 catch (Exception e)
251 {
252 log.error( "Loading of definition failed for [" + url + "]; " + e );
253 SoapUI.logError( e );
254 this.error = e;
255 return e;
256 }
257 finally
258 {
259 currentLoader = null;
260 }
261 }
262
263 public Exception getError()
264 {
265 return error;
266 }
267
268 public boolean onCancel()
269 {
270 if( currentLoader == null )
271 return false;
272
273 return currentLoader.abort();
274 }
275 }
276
277 private void loadDefinitions( WsdlLoader loader ) throws Exception
278 {
279 currentLoader = loader;
280
281 if( factory == null )
282 {
283 factory = WSDLFactory.newInstance();
284 wsdlReader = factory.newWSDLReader();
285 wsdlReader.setFeature("javax.wsdl.verbose", true);
286 wsdlReader.setFeature("javax.wsdl.importDocuments", true);
287 }
288
289 definition = wsdlReader.readWSDL( loader );
290 log.debug( "Loaded definition: " + (definition != null ? "ok" : "null") );
291
292 if( !currentLoader.isAborted() )
293 schemaTypes = SchemaUtils.loadSchemaTypes(url, soapVersion, loader);
294 else
295 throw new Exception( "Loading of WSDL from [" + url + "] was aborted" );
296 }
297
298 public boolean validateCache(DefinitionCacheConfig cache)
299 {
300 if( cache == null )
301 return false;
302
303 if( cache.getRootPart() == null )
304 return false;
305
306 if( cache.sizeOfPartArray() == 0 )
307 return false;
308
309 return true;
310 }
311
312 public SchemaTypeSystem getSchemaTypeSystem() throws Exception
313 {
314 if( !loaded )
315 load();
316
317 if( schemaTypes == null )
318 return null;
319
320 return schemaTypes.findElement( soapVersion.getEnvelopeQName() ).getTypeSystem();
321 }
322
323 public boolean hasSchemaTypes() throws Exception
324 {
325 loadIfNecessary();
326 return schemaTypes != null;
327 }
328
329 public SchemaType findType(QName typeName) throws Exception
330 {
331 loadIfNecessary();
332 return schemaTypes == null ? null : schemaTypes.findType( typeName );
333 }
334
335 public String getUrl()
336 {
337 return url;
338 }
339
340 public Collection<String> getDefinedNamespaces() throws Exception
341 {
342 loadIfNecessary();
343 Set<String> namespaces = new HashSet<String>();
344
345 if( schemaTypes != null )
346 {
347 namespaces.addAll( SchemaUtils.extractNamespaces( getSchemaTypeSystem(), true ));
348 }
349
350 if( definition != null )
351 namespaces.add( definition.getTargetNamespace() );
352
353 return namespaces;
354 }
355
356 public SoapVersion getSoapVersion()
357 {
358 return soapVersion;
359 }
360
361 public void setSoapVersion(SoapVersion soapVersion)
362 {
363 this.soapVersion = soapVersion;
364 }
365
366 public Map<String, XmlObject> getDefinitionParts() throws Exception
367 {
368 Map<String,XmlObject> result = new HashMap<String,XmlObject>();
369
370 if( cache == null )
371 return SchemaUtils.getDefinitionParts( new UrlWsdlLoader( url ));
372
373 List<DefintionPartConfig> partList = cache.getPartList();
374 for( DefintionPartConfig part : partList )
375 {
376 result.put( part.getUrl(), CachedWsdlLoader.getPartContent( cache, part ) );
377 }
378
379 return result;
380 }
381
382 public void setDefinitionCache(DefinitionCacheConfig definitionCache)
383 {
384 this.cache = definitionCache;
385 }
386
387 public void setInterface( WsdlInterface iface )
388 {
389 this.iface = iface;
390 }
391 }