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