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