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