1
2
3
4
5
6
7
8
9
10
11
12
13 package com.eviware.soapui.impl.support.definition.support;
14
15 import java.util.ArrayList;
16 import java.util.HashMap;
17 import java.util.List;
18 import java.util.Map;
19
20 import org.apache.log4j.Logger;
21 import org.apache.xmlbeans.SchemaTypeLoader;
22 import org.apache.xmlbeans.SchemaTypeSystem;
23
24 import com.eviware.soapui.SoapUI;
25 import com.eviware.soapui.impl.support.AbstractInterface;
26 import com.eviware.soapui.impl.support.DefinitionContext;
27 import com.eviware.soapui.impl.support.definition.DefinitionCache;
28 import com.eviware.soapui.impl.support.definition.DefinitionLoader;
29 import com.eviware.soapui.impl.support.definition.InterfaceDefinition;
30 import com.eviware.soapui.impl.support.definition.InterfaceDefinitionPart;
31 import com.eviware.soapui.impl.wsdl.support.PathUtils;
32 import com.eviware.soapui.impl.wsdl.support.xsd.SchemaException;
33 import com.eviware.soapui.support.UISupport;
34 import com.eviware.x.dialogs.Worker;
35 import com.eviware.x.dialogs.XProgressDialog;
36 import com.eviware.x.dialogs.XProgressMonitor;
37
38 /***
39 * Holder for InterfaceDefinitions and related SchemaTypeLoader types
40 *
41 * @author Ole.Matzura
42 */
43
44 public abstract class AbstractDefinitionContext<T extends AbstractInterface, T2 extends DefinitionLoader, T3 extends AbstractInterfaceDefinition<T>>
45 implements DefinitionContext
46 {
47 private String url;
48 private T3 definition;
49 private boolean loaded;
50 private SchemaException schemaException;
51
52 private final static Logger log = Logger.getLogger( AbstractDefinitionContext.class );
53
54 private T2 currentLoader;
55 private T iface;
56
57 private static Map<String, InterfaceDefinition> definitionCache = new HashMap<String, InterfaceDefinition>();
58 private static Map<String, Integer> urlReferences = new HashMap<String, Integer>();
59
60 public AbstractDefinitionContext( String url, T iface )
61 {
62 this.url = PathUtils.ensureFilePathIsUrl( url );
63 this.iface = iface;
64 }
65
66 public AbstractDefinitionContext( String url )
67 {
68 this( url, null );
69 }
70
71 public T getInterface()
72 {
73 return iface;
74 }
75
76 public T3 getInterfaceDefinition() throws Exception
77 {
78 loadIfNecessary();
79 return ( T3 )( definition == null ? definitionCache.get( url ) : definition );
80 }
81
82 public synchronized boolean isLoaded()
83 {
84 return loaded;
85 }
86
87 public synchronized boolean loadIfNecessary() throws Exception
88 {
89 if( !loaded )
90 load();
91 return loaded;
92 }
93
94 public synchronized void setDefinition( String url, boolean updateCache ) throws Exception
95 {
96 if( !url.equals( this.url ) )
97 {
98 this.url = url;
99
100 if( updateCache )
101 {
102 definitionCache.remove( url );
103 loaded = false;
104 load();
105 }
106
107
108 loaded = iface != null && definitionCache.containsKey( url );
109 }
110 }
111
112 public synchronized boolean load() throws Exception
113 {
114 return load( null );
115 }
116
117 public synchronized boolean load( T2 wsdlLoader ) throws Exception
118 {
119
120 if( !loaded && iface != null )
121 {
122
123 loaded = definitionCache.containsKey( url );
124 }
125
126 if( loaded )
127 return true;
128
129
130 XProgressDialog progressDialog = UISupport.getDialogs().createProgressDialog( "Loading Definition", 3,
131 "Loading definition..", true );
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 log.error( "Error loading schema types from " + url + ", see log for details" );
146
147 if( errorList != null )
148 {
149 for( int c = 0; c < errorList.size(); c++ )
150 {
151 log.error( errorList.get( c ).toString() );
152 }
153 }
154 }
155 else
156 throw new Exception( loader.getError() );
157 }
158 else
159 {
160 loaded = true;
161 }
162
163 return loaded;
164 }
165
166 public SchemaTypeLoader getSchemaTypeLoader() throws Exception
167 {
168 loadIfNecessary();
169 return iface != null ? definitionCache.get( url ).getSchemaTypeLoader() : definition != null ? definition
170 .getSchemaTypeLoader() : null;
171 }
172
173 public SchemaException getSchemaException()
174 {
175 return schemaException;
176 }
177
178 private class Loader extends Worker.WorkerAdapter
179 {
180 private Throwable error;
181 private T2 wsdlLoader;
182
183 public Loader( T2 wsdlLoader )
184 {
185 super();
186 this.wsdlLoader = wsdlLoader;
187 }
188
189 private T2 getDefinitionLoader()
190 {
191 if( wsdlLoader != null )
192 {
193 return wsdlLoader;
194 }
195 else
196 {
197 return createDefinitionLoader( url );
198 }
199 }
200
201 public boolean hasError()
202 {
203 return error != null;
204 }
205
206 public Object construct( XProgressMonitor monitor )
207 {
208 try
209 {
210 DefinitionCache cache = iface == null ? new StandaloneDefinitionCache<T>()
211 : new InterfaceConfigDefinitionCache<T>( iface );
212
213 if( !cache.validate() )
214 {
215 monitor.setProgress( 1, "Caching Definition from url [" + url + "]" );
216
217 currentLoader = getDefinitionLoader();
218 currentLoader.setProgressMonitor( monitor, 2 );
219
220 cache.update( currentLoader );
221
222 if( currentLoader.isAborted() )
223 throw new Exception( "Loading of Definition from [" + url + "] was aborted" );
224 }
225
226 monitor.setProgress( 1, "Loading Definition from " + ( iface == null ? "url" : "cache" ) );
227
228 log.debug( "Loading Definition..." );
229 cacheDefinition( cache );
230 return null;
231 }
232 catch( Throwable e )
233 {
234 log.error( "Loading of definition failed for [" + url + "]; " + e );
235 SoapUI.logError( e );
236 this.error = e;
237 return e;
238 }
239 finally
240 {
241 currentLoader = null;
242 }
243 }
244
245 public Throwable getError()
246 {
247 return error;
248 }
249
250 public boolean onCancel()
251 {
252 if( currentLoader == null )
253 return false;
254
255 return currentLoader.abort();
256 }
257 }
258
259 private void cacheDefinition( DefinitionCache cache ) throws Exception
260 {
261 currentLoader = createDefinitionLoader( cache );
262 currentLoader.setProgressInfo( "Loading Definition" );
263 definition = loadDefinition( currentLoader );
264 definition.setDefinitionCache( cache );
265
266 log.debug( "Loaded Definition: " + ( definition != null ? "ok" : "null" ) );
267
268 if( !currentLoader.isAborted() && iface != null && iface.isDefinitionShareble() )
269 {
270 definitionCache.put( url, definition );
271 if( urlReferences.containsKey( url ) )
272 {
273 urlReferences.put( url, urlReferences.get( url ) + 1 );
274 }
275 else
276 {
277 urlReferences.put( url, 1 );
278 }
279 }
280
281 if( currentLoader.isAborted() )
282 throw new Exception( "Loading of Definition from [" + url + "] was aborted" );
283
284 loaded = true;
285 }
286
287 protected abstract T2 createDefinitionLoader( DefinitionCache definitionCache );
288
289 protected abstract T2 createDefinitionLoader( String url );
290
291 protected abstract T3 loadDefinition( T2 loader ) throws Exception;
292
293 public void release()
294 {
295 if( iface != null && urlReferences.containsKey( url ) )
296 {
297 Integer i = urlReferences.get( url );
298 if( i.intValue() <= 1 )
299 {
300 urlReferences.remove( url );
301 definitionCache.remove( url );
302 }
303 else
304 {
305 urlReferences.put( url, i - 1 );
306 }
307 }
308 }
309
310 public SchemaTypeSystem getSchemaTypeSystem() throws Exception
311 {
312 if( !isLoaded() )
313 load();
314
315 if( !definitionCache.containsKey( url ) )
316 return null;
317
318 return definitionCache.get( url ).getSchemaTypeSystem();
319 }
320
321 public boolean hasSchemaTypes()
322 {
323 try
324 {
325 loadIfNecessary();
326 }
327 catch( Exception e )
328 {
329 SoapUI.logError( e );
330 return false;
331 }
332
333 InterfaceDefinition def = ( definition != null ? definition : definitionCache.get( url ) );
334 return def != null && def.hasSchemaTypes();
335 }
336
337 public String getUrl()
338 {
339 return url;
340 }
341
342 public void setInterface( T iface )
343 {
344 if( this.iface == null && iface != null )
345 {
346 if( definition != null )
347 {
348 if( definition.getDefinitionCache().validate() )
349 {
350 InterfaceConfigDefinitionCache cache = new InterfaceConfigDefinitionCache( iface );
351 try
352 {
353 cache.importCache( definition.getDefinitionCache() );
354 }
355 catch( Exception e )
356 {
357 SoapUI.logError( e );
358 }
359
360 definition.setDefinitionCache( cache );
361 }
362
363 definition.setIface( iface );
364 definitionCache.put( url, definition );
365 }
366 else
367 {
368 loaded = false;
369 }
370 }
371
372 this.iface = iface;
373 }
374
375 public static void uncache( String url )
376 {
377 definitionCache.remove( url );
378 urlReferences.remove( url );
379 }
380
381 public void reload() throws Exception
382 {
383 getDefinitionCache().clear();
384 definitionCache.remove( url );
385 loaded = false;
386 load();
387 }
388
389 public boolean isCached()
390 {
391 return isLoaded() && definition != null && definition.getDefinitionCache() != null;
392 }
393
394 public List<InterfaceDefinitionPart> getDefinitionParts() throws Exception
395 {
396 loadIfNecessary();
397
398 return getInterfaceDefinition().getDefinitionParts();
399 }
400
401 public DefinitionCache getDefinitionCache() throws Exception
402 {
403 loadIfNecessary();
404
405 return getInterfaceDefinition().getDefinitionCache();
406 }
407 }