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