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