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.awt.event.ActionEvent;
16 import java.io.ByteArrayInputStream;
17 import java.io.IOException;
18 import java.io.InputStream;
19 import java.net.URL;
20 import java.util.HashMap;
21 import java.util.Map;
22
23 import javax.swing.AbstractAction;
24
25 import org.apache.commons.httpclient.Credentials;
26 import org.apache.commons.httpclient.HostConfiguration;
27 import org.apache.commons.httpclient.HttpClient;
28 import org.apache.commons.httpclient.HttpState;
29 import org.apache.commons.httpclient.NTCredentials;
30 import org.apache.commons.httpclient.UsernamePasswordCredentials;
31 import org.apache.commons.httpclient.auth.AuthScheme;
32 import org.apache.commons.httpclient.auth.CredentialsNotAvailableException;
33 import org.apache.commons.httpclient.auth.CredentialsProvider;
34 import org.apache.commons.httpclient.auth.NTLMScheme;
35 import org.apache.commons.httpclient.auth.RFC2617Scheme;
36 import org.apache.commons.httpclient.methods.GetMethod;
37
38 import com.eviware.soapui.SoapUI;
39 import com.eviware.soapui.impl.wsdl.support.http.HttpClientSupport;
40 import com.eviware.soapui.impl.wsdl.support.http.ProxyUtils;
41 import com.eviware.soapui.model.settings.Settings;
42 import com.eviware.soapui.support.UISupport;
43 import com.eviware.soapui.support.action.swing.ActionList;
44 import com.eviware.soapui.support.action.swing.DefaultActionList;
45 import com.eviware.soapui.support.swing.SwingWorker;
46 import com.eviware.soapui.support.types.StringToStringMap;
47 import com.eviware.x.form.XForm;
48 import com.eviware.x.form.XFormDialog;
49 import com.eviware.x.form.XFormDialogBuilder;
50 import com.eviware.x.form.XFormFactory;
51
52 /***
53 * WsdlLoader for URLs
54 *
55 * @author ole.matzura
56 */
57
58 public class UrlWsdlLoader extends WsdlLoader
59 {
60 private HttpState state;
61 private GetMethod getMethod;
62 private boolean aborted;
63 private Map<String,byte[]> wsdlCache = new HashMap<String,byte[]>();
64 private boolean finished;
65
66 public UrlWsdlLoader(String url)
67 {
68 super( url );
69 state = new HttpState();
70 }
71
72 public synchronized InputStream load( String url ) throws Exception
73 {
74 if( wsdlCache.containsKey( url ))
75 {
76 return new ByteArrayInputStream( wsdlCache.get( url ) );
77 }
78
79 if( url.startsWith( "file:" ))
80 return new URL( url ).openStream();
81
82 log.debug( "Getting wsdl component from [" + url + "]" );
83
84 createGetMethod(url);
85
86 if( aborted )
87 return null;
88
89 LoaderWorker worker = new LoaderWorker();
90 worker.start();
91
92 while( !aborted && !finished )
93 {
94 Thread.sleep( 200 );
95 }
96
97
98 while( !aborted && getMethod.getResponseBody() == null )
99 {
100 Thread.sleep( 200 );
101 }
102
103 try
104 {
105 if (aborted)
106 {
107 throw new Exception("Load of url [" + url + "] was aborted");
108 }
109 else
110 {
111 byte[] content = getMethod.getResponseBody();
112 if( content != null )
113 {
114 if (HttpClientSupport.isZippedResponse( getMethod ))
115 {
116 content = HttpClientSupport.decompress( content );
117 }
118
119 wsdlCache.put(url, content);
120 return new ByteArrayInputStream(content);
121 }
122 else
123 {
124 throw new Exception("Failed to load url; " + getMethod.getStatusCode() + " - " + getMethod.getStatusText());
125 }
126 }
127 }
128
129 finally
130 {
131 getMethod.releaseConnection();
132 }
133 }
134
135 private void createGetMethod(String url)
136 {
137 getMethod = new GetMethod( url );
138 getMethod.getParams().setParameter(CredentialsProvider.PROVIDER, new WsdlCredentialsProvider());
139 getMethod.setDoAuthentication(true);
140 }
141
142 private final class LoaderWorker extends SwingWorker
143 {
144 public Object construct()
145 {
146 HttpClient httpClient = HttpClientSupport.getHttpClient();
147 try
148 {
149 Settings soapuiSettings = SoapUI.getSettings();
150
151 HttpClientSupport.applyHttpSettings( getMethod, soapuiSettings );
152 HostConfiguration hostConfiguration = ProxyUtils.initProxySettings( soapuiSettings, state, new HostConfiguration(), getMethod.getURI().toString() );
153 httpClient.executeMethod( hostConfiguration, getMethod, state );
154 }
155 catch (Exception e)
156 {
157 return e;
158 }
159 finally
160 {
161 finished = true;
162 }
163
164 return null;
165 }
166 }
167
168 public boolean abort()
169 {
170 if( getMethod != null )
171 getMethod.abort();
172
173 aborted = true;
174
175 return true;
176 }
177
178 public boolean isAborted()
179 {
180 return aborted;
181 }
182
183 /***
184 * CredentialsProvider for providing login information during WSDL loading
185 *
186 * @author ole.matzura
187 */
188
189 public static final class WsdlCredentialsProvider implements CredentialsProvider
190 {
191 private XFormDialog basicDialog;
192 private XFormDialog ntDialog;
193 private XFormDialog dialog;
194 public boolean canceled;
195
196 public WsdlCredentialsProvider()
197 {
198 }
199
200 public Credentials getCredentials(final AuthScheme authscheme, final String host, int port, boolean proxy)
201 throws CredentialsNotAvailableException
202 {
203 if (authscheme == null)
204 {
205 return null;
206 }
207 try
208 {
209 if (authscheme instanceof NTLMScheme)
210 {
211 log.info(host + ":" + port + " requires Windows authentication");
212 if( ntDialog == null )
213 {
214 buildNtDialog();
215 }
216
217 dialog = ntDialog;
218
219 StringToStringMap values = new StringToStringMap();
220 values.put( "Info", "Authentication required for [" + host + ":" + port + "]" );
221 ntDialog.setValues( values );
222 ntDialog.setVisible( true );
223
224 if( canceled )
225 throw new CredentialsNotAvailableException("Operation cancelled");
226
227 values = ntDialog.getValues();
228
229 return new NTCredentials(values.get( "Username"), values.get( "Password"), host, values.get( "Domain"));
230 }
231 else if (authscheme instanceof RFC2617Scheme)
232 {
233 log.info(host + ":" + port + " requires authentication with the realm '" + authscheme.getRealm() + "'");
234 if( basicDialog == null )
235 buildBasicDialog();
236
237 dialog = basicDialog;
238
239 StringToStringMap values = new StringToStringMap();
240 values.put( "Info", "Authentication required for [" + host + ":" + port + "]" );
241 basicDialog.setValues( values );
242 basicDialog.setVisible( true );
243
244 if( canceled )
245 throw new CredentialsNotAvailableException("Operation cancelled");
246
247 values = basicDialog.getValues();
248
249 return new UsernamePasswordCredentials(values.get( "Username"), values.get( "Password"));
250 }
251 else
252 {
253 throw new CredentialsNotAvailableException("Unsupported authentication scheme: "
254 + authscheme.getSchemeName());
255 }
256 }
257 catch (IOException e)
258 {
259 throw new CredentialsNotAvailableException(e.getMessage(), e);
260 }
261 }
262
263 private void buildBasicDialog()
264 {
265 XFormDialogBuilder builder = XFormFactory.createDialogBuilder( "Basic Authentication" );
266 XForm mainForm = builder.createForm( "Basic" );
267 mainForm.addLabel( "Info", "" );
268 mainForm.addTextField( "Username", "Username for authentication", XForm.FieldType.TEXT );
269 mainForm.addTextField( "Password", "Password for authentication", XForm.FieldType.PASSWORD );
270
271 basicDialog = builder.buildDialog( buildDefaultActions(),
272 "Specify Basic Authentication Credentials", UISupport.OPTIONS_ICON );
273 }
274
275 private void buildNtDialog()
276 {
277 XFormDialogBuilder builder = XFormFactory.createDialogBuilder( "NT Authentication" );
278 XForm mainForm = builder.createForm( "Basic" );
279 mainForm.addLabel( "Info", "" );
280 mainForm.addTextField( "Username", "Username for authentication", XForm.FieldType.TEXT );
281 mainForm.addTextField( "Password", "Password for authentication", XForm.FieldType.PASSWORD );
282 mainForm.addTextField( "Domain", "NT Domain for authentication", XForm.FieldType.TEXT );
283
284 ntDialog = builder.buildDialog( buildDefaultActions(),
285 "Specify NT Authentication Credentials", UISupport.OPTIONS_ICON );
286 }
287
288 public ActionList buildDefaultActions()
289 {
290 ActionList actions = new DefaultActionList( "Actions" );
291 actions.addAction( new OkAction() );
292 actions.addAction( new CancelAction() );
293 return actions;
294 }
295
296 protected final class CancelAction extends AbstractAction
297 {
298 public CancelAction()
299 {
300 super( "Cancel" );
301 }
302
303 public void actionPerformed(ActionEvent e)
304 {
305 canceled = true;
306 closeDialog();
307 }
308 }
309
310 public void closeDialog()
311 {
312 if( dialog != null )
313 dialog.setVisible( false );
314 }
315
316 protected final class OkAction extends AbstractAction
317 {
318 public OkAction()
319 {
320 super( "OK" );
321 }
322
323 public void actionPerformed(ActionEvent e)
324 {
325 canceled = false;
326 closeDialog();
327 }
328 }
329 }
330
331 public void close()
332 {
333 }
334 }