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