View Javadoc

1   /*
2    *  soapUI, copyright (C) 2004-2007 eviware.com 
3    *
4    *  soapUI is free software; you can redistribute it and/or modify it under the 
5    *  terms of version 2.1 of the GNU Lesser General Public License as published by 
6    *  the Free Software Foundation.
7    *
8    *  soapUI is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without 
9    *  even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 
10   *  See the GNU Lesser General Public License for more details at gnu.org.
11   */
12  
13  package com.eviware.soapui.impl.wsdl.endpoint;
14  
15  import java.beans.PropertyChangeEvent;
16  import java.beans.PropertyChangeListener;
17  import java.util.Arrays;
18  import java.util.HashMap;
19  import java.util.HashSet;
20  import java.util.Map;
21  import java.util.Set;
22  
23  import javax.swing.JComponent;
24  
25  import org.apache.commons.httpclient.URI;
26  import org.apache.commons.httpclient.URIException;
27  
28  import com.eviware.soapui.SoapUI;
29  import com.eviware.soapui.config.DefaultEndpointStrategyConfig;
30  import com.eviware.soapui.config.EndpointConfig;
31  import com.eviware.soapui.config.ProjectConfig;
32  import com.eviware.soapui.impl.wsdl.WsdlInterface;
33  import com.eviware.soapui.impl.wsdl.WsdlProject;
34  import com.eviware.soapui.impl.wsdl.WsdlRequest;
35  import com.eviware.soapui.impl.wsdl.submit.filters.HttpAuthenticationRequestFilter;
36  import com.eviware.soapui.impl.wsdl.submit.filters.WssAuthenticationRequestFilter;
37  import com.eviware.soapui.impl.wsdl.submit.transports.http.BaseHttpRequestTransport;
38  import com.eviware.soapui.impl.wsdl.submit.transports.http.TimeablePostMethod;
39  import com.eviware.soapui.model.iface.Interface;
40  import com.eviware.soapui.model.iface.Response;
41  import com.eviware.soapui.model.iface.SubmitContext;
42  import com.eviware.soapui.model.project.EndpointStrategy;
43  import com.eviware.soapui.model.project.Project;
44  import com.eviware.soapui.model.project.ProjectListener;
45  import com.eviware.soapui.model.propertyexpansion.PropertyExpansionUtils;
46  import com.eviware.soapui.model.support.ProjectListenerAdapter;
47  import com.eviware.soapui.support.StringUtils;
48  import com.eviware.soapui.support.types.StringList;
49  
50  public class DefaultEndpointStrategy implements EndpointStrategy
51  {
52  	private WsdlProject project;
53  	private DefaultEndpointStrategyConfig config;
54  	private Map<String, EndpointDefaults> defaults = new HashMap<String, EndpointDefaults>();
55  	private PropertyChangeListener propertyChangeListener = new InternalPropertyChangeListener();
56  	private ProjectListener projectListener = new InternalProjectListener();
57  
58  	public void init( Project project )
59  	{
60  		this.project = ( WsdlProject ) project;
61  		initConfig();
62  
63  		project.addProjectListener( projectListener );
64  
65  		for( Interface iface : project.getInterfaceList() )
66  		{
67  			for( String endpoint : iface.getEndpoints() )
68  			{
69  				// ensure we have defaults
70  				getEndpointDefaults( endpoint );
71  			}
72  
73  			iface.addPropertyChangeListener( WsdlInterface.ENDPOINT_PROPERTY, propertyChangeListener );
74  		}
75  
76  		removeUnusedEndpoints();
77  	}
78  
79  	private void initConfig()
80  	{
81  		ProjectConfig projectConfig = this.project.getConfig();
82  
83  		if( !projectConfig.isSetEndpointStrategy() )
84  		{
85  			projectConfig.addNewEndpointStrategy();
86  		}
87  
88  		config = ( DefaultEndpointStrategyConfig ) projectConfig.getEndpointStrategy().changeType(
89  					DefaultEndpointStrategyConfig.type );
90  
91  		for( EndpointConfig endpointConfig : config.getEndpointList() )
92  		{
93  			defaults.put( endpointConfig.getStringValue(), new EndpointDefaults( endpointConfig ) );
94  		}
95  	}
96  
97  	private void removeUnusedEndpoints()
98  	{
99  		if( config == null )
100 			return;
101 
102 		Set<String> endpoints = new HashSet<String>();
103 
104 		for( Interface iface : project.getInterfaceList() )
105 		{
106 			endpoints.addAll( Arrays.asList( iface.getEndpoints() ) );
107 		}
108 
109 		StringList keys = new StringList();
110 
111 		for( String key : defaults.keySet() )
112 		{
113 			if( !endpoints.contains( key ) )
114 			{
115 				keys.add( key );
116 			}
117 		}
118 
119 		for( String key : keys )
120 		{
121 			EndpointDefaults def = defaults.remove( key );
122 			config.getEndpointList().remove( def );
123 		}
124 	}
125 
126 	public void filterRequest( SubmitContext context, WsdlRequest wsdlRequest )
127 	{
128 		TimeablePostMethod postMethod = ( TimeablePostMethod ) context.getProperty( BaseHttpRequestTransport.POST_METHOD );
129 		URI uri = null;
130 		try
131 		{
132 			uri = postMethod.getURI();
133 		}
134 		catch( URIException e )
135 		{
136 			SoapUI.logError( e );
137 			return;
138 		}
139 
140 		if( !defaults.containsKey( uri.toString() ) )
141 		{
142 			return;
143 		}
144 
145 		EndpointDefaults def = defaults.get( uri.toString() );
146 		applyDefaultsToRequest( context, wsdlRequest, def );
147 	}
148 
149 	protected void applyDefaultsToRequest( SubmitContext context, WsdlRequest wsdlRequest, EndpointDefaults def )
150 	{
151 		String requestUsername = PropertyExpansionUtils.expandProperties( context, wsdlRequest.getUsername() );
152 		String requestPassword = PropertyExpansionUtils.expandProperties( context, wsdlRequest.getPassword() );
153 		String requestDomain = PropertyExpansionUtils.expandProperties( context, wsdlRequest.getDomain() );
154 
155 		String defUsername = PropertyExpansionUtils.expandProperties( context, def.getUsername() );
156 		String defPassword = PropertyExpansionUtils.expandProperties( context, def.getPassword() );
157 		String defDomain = PropertyExpansionUtils.expandProperties( context, def.getDomain() );
158 
159 		if( def.getMode() == EndpointConfig.Mode.OVERRIDE )
160 		{
161 			overrideRequest( context, wsdlRequest, def, requestUsername, requestPassword, requestDomain, defUsername,
162 						defPassword, defDomain );
163 		}
164 		else if( def.getMode() == EndpointConfig.Mode.COPY )
165 		{
166 			copyToRequest( context, wsdlRequest, def, requestUsername, requestPassword, requestDomain, defUsername,
167 						defPassword, defDomain );
168 		}
169 		else if( def.getMode() == EndpointConfig.Mode.COMPLEMENT )
170 		{
171 			complementRequest( context, wsdlRequest, def, requestUsername, requestPassword, requestDomain, defUsername,
172 						defPassword, defDomain );
173 		}
174 	}
175 
176 	private void overrideRequest( SubmitContext context, WsdlRequest wsdlRequest, EndpointDefaults def,
177 				String requestUsername, String requestPassword, String requestDomain, String defUsername,
178 				String defPassword, String defDomain )
179 	{
180 		String username = StringUtils.hasContent( defUsername ) ? defUsername : requestUsername;
181 		String password = StringUtils.hasContent( defPassword ) ? defPassword : requestPassword;
182 		
183 		if( StringUtils.hasContent( username ) || StringUtils.hasContent( password ))
184 		{
185 			// only set if not set in request
186 			String wssType = def.getWssType();
187 			String wssTimeToLive = def.getWssTimeToLive();
188 			
189 			if( wssType == null )
190 			{
191 				String domain = StringUtils.hasContent( defDomain ) ? defDomain : requestDomain;
192 				HttpAuthenticationRequestFilter.initRequestCredentials( context, username, project.getSettings(), password,
193 							domain );
194 			}
195 
196 			if( StringUtils.hasContent( wssType ) || StringUtils.hasContent( wssTimeToLive ) )
197 			{
198 				try
199 				{
200 					// set to null so existing don't get removed
201 					if( wssTimeToLive != null && wssTimeToLive.length() == 0 )
202 						wssTimeToLive = null;
203 					
204 					WssAuthenticationRequestFilter
205 								.setWssHeaders( context, username, password, wssType, wssTimeToLive );
206 				}
207 				catch( Exception e )
208 				{
209 					SoapUI.logError( e );
210 				}
211 			}
212 		}
213 	}
214 
215 	private void copyToRequest( SubmitContext context, WsdlRequest wsdlRequest, EndpointDefaults def,
216 				String requestUsername, String requestPassword, String requestDomain, String defUsername,
217 				String defPassword, String defDomain )
218 	{
219 		// only set if not set in request
220 		String wssType = def.getWssType();
221 	
222 		if( wssType != null )
223 		{
224 			HttpAuthenticationRequestFilter.initRequestCredentials( context, null, project.getSettings(), null, null );
225 		}
226 		else
227 		{
228 			HttpAuthenticationRequestFilter.initRequestCredentials( context, defUsername, project.getSettings(), defPassword,
229 						defDomain );
230 		}
231 		
232 		String wssTimeToLive = def.getWssTimeToLive();
233 		if( wssTimeToLive == null )
234 			wssTimeToLive = "";
235 
236 		try
237 		{
238 			WssAuthenticationRequestFilter.setWssHeaders( context, defUsername, defPassword, wssType, wssTimeToLive );
239 		}
240 		catch( Exception e )
241 		{
242 			SoapUI.logError( e );
243 		}
244 	}
245 
246 	private void complementRequest( SubmitContext context, WsdlRequest wsdlRequest, EndpointDefaults def,
247 				String requestUsername, String requestPassword, String requestDomain, String defUsername,
248 				String defPassword, String defDomain )
249 	{
250 		String username = StringUtils.hasContent( requestUsername ) ? requestUsername : defUsername;
251 		String password = StringUtils.hasContent( requestPassword ) ? requestPassword : defPassword;
252 		
253 		// only set if not set in request
254 		String wssType = StringUtils.isNullOrEmpty( wsdlRequest.getWssPasswordType() ) ? def.getWssType() : ( StringUtils
255 					.hasContent( username ) && StringUtils.hasContent( password ) ) ? null : wsdlRequest
256 					.getWssPasswordType();
257 
258 		String wssTimeToLive = StringUtils.isNullOrEmpty( wsdlRequest.getWssTimeToLive() ) ? def.getWssTimeToLive()
259 					: null;
260 
261 		if( !StringUtils.hasContent( wssType ) && (StringUtils.hasContent( username ) || StringUtils.hasContent( password ) ))
262 		{
263 			String domain = StringUtils.hasContent( requestDomain ) ? requestDomain : defDomain;
264 			HttpAuthenticationRequestFilter.initRequestCredentials( context, username, project.getSettings(), password,
265 						domain );
266 		}
267 		else if( StringUtils.hasContent( wssType ) || StringUtils.hasContent( wssTimeToLive ) )
268 		{
269 			try
270 			{
271 				// set to null so existing don't get removed
272 				if( wssTimeToLive != null && wssTimeToLive.length() == 0 )
273 					wssTimeToLive = null;
274 					
275 				if( StringUtils.hasContent( username ) || StringUtils.hasContent( password ) )
276 					WssAuthenticationRequestFilter
277 								.setWssHeaders( context, username, password, wssType, wssTimeToLive );
278 			}
279 			catch( Exception e )
280 			{
281 				SoapUI.logError( e );
282 			}
283 		}
284 	}
285 
286 	public void release()
287 	{
288 		project.removeProjectListener( projectListener );
289 		for( Interface iface : project.getInterfaceList() )
290 			iface.removePropertyChangeListener( WsdlInterface.ENDPOINT_PROPERTY, propertyChangeListener );
291 	}
292 
293 	private class InternalProjectListener extends ProjectListenerAdapter
294 	{
295 		@Override
296 		public void interfaceAdded( Interface iface )
297 		{
298 			for( String endpoint : iface.getEndpoints() )
299 			{
300 				// ensure we have defaults
301 				getEndpointDefaults( endpoint );
302 			}
303 
304 			iface.addPropertyChangeListener( WsdlInterface.ENDPOINT_PROPERTY, propertyChangeListener );
305 		}
306 
307 		@Override
308 		public void interfaceRemoved( Interface iface )
309 		{
310 			iface.removePropertyChangeListener( WsdlInterface.ENDPOINT_PROPERTY, propertyChangeListener );
311 			removeUnusedEndpoints();
312 		}
313 	}
314 
315 	private class InternalPropertyChangeListener implements PropertyChangeListener
316 	{
317 		public void propertyChange( PropertyChangeEvent evt )
318 		{
319 			// new endpoint?
320 			if( evt.getOldValue() == null )
321 			{
322 				getEndpointDefaults( evt.getNewValue().toString() );
323 			}
324 			// changed endpoint?
325 			else if( evt.getNewValue() != null )
326 			{
327 				String oldValue = evt.getOldValue().toString();
328 				EndpointDefaults def = getEndpointDefaults( oldValue );
329 				def.endpointConfig.setStringValue( evt.getNewValue().toString() );
330 				defaults.remove( oldValue );
331 				defaults.put( evt.getNewValue().toString(), def );
332 			}
333 			else
334 			{
335 				removeUnusedEndpoints();
336 			}
337 		}
338 	}
339 
340 	public class EndpointDefaults
341 	{
342 		private final EndpointConfig endpointConfig;
343 
344 		public EndpointDefaults( EndpointConfig endpointConfig )
345 		{
346 			this.endpointConfig = endpointConfig;
347 
348 			if( !endpointConfig.isSetMode() )
349 				endpointConfig.setMode( EndpointConfig.Mode.COMPLEMENT );
350 		}
351 
352 		public String getDomain()
353 		{
354 			return endpointConfig.getDomain();
355 		}
356 
357 		public String getPassword()
358 		{
359 			return endpointConfig.getPassword();
360 		}
361 
362 		public String getUsername()
363 		{
364 			return endpointConfig.getUsername();
365 		}
366 
367 		public String getWssTimeToLive()
368 		{
369 			return endpointConfig.getWssTimeToLive();
370 		}
371 
372 		public String getWssType()
373 		{
374 			String wssPasswordType = endpointConfig.getWssType();
375 			return StringUtils.isNullOrEmpty( wssPasswordType ) || WsdlRequest.PW_TYPE_NONE.equals( wssPasswordType ) ? null : wssPasswordType;
376 		}
377 
378 		public void setDomain( String arg0 )
379 		{
380 			endpointConfig.setDomain( arg0 );
381 		}
382 
383 		public void setPassword( String arg0 )
384 		{
385 			endpointConfig.setPassword( arg0 );
386 		}
387 
388 		public void setUsername( String arg0 )
389 		{
390 			endpointConfig.setUsername( arg0 );
391 		}
392 
393 		public void setWssTimeToLive( String arg0 )
394 		{
395 			endpointConfig.setWssTimeToLive( arg0 );
396 		}
397 
398 		public String getIncomingWss()
399 		{
400 			return endpointConfig.getIncomingWss();
401 		}
402 
403 		public String getOutgoingWss()
404 		{
405 			return endpointConfig.getOutgoingWss();
406 		}
407 
408 		public void setIncomingWss( String arg0 )
409 		{
410 			endpointConfig.setIncomingWss( arg0 );
411 		}
412 
413 		public void setOutgoingWss( String arg0 )
414 		{
415 			endpointConfig.setOutgoingWss( arg0 );
416 		}
417 
418 		public void setWssType( String wssPasswordType )
419 		{
420 			if( wssPasswordType == null || wssPasswordType.equals( WsdlRequest.PW_TYPE_NONE ))
421 			{
422 				if( endpointConfig.isSetWssType() )
423 					endpointConfig.unsetWssType();
424 			}
425 			else
426 			{
427 				endpointConfig.setWssType( wssPasswordType );
428 			}
429 		}
430 
431 		public EndpointConfig.Mode.Enum getMode()
432 		{
433 			return endpointConfig.getMode();
434 		}
435 
436 		public void setMode( EndpointConfig.Mode.Enum mode )
437 		{
438 			endpointConfig.setMode( mode );
439 		}
440 
441 		protected EndpointConfig getConfig()
442 		{
443 			return endpointConfig;
444 		}
445 	}
446 
447 	public EndpointDefaults getEndpointDefaults( String endpoint )
448 	{
449 		if( config == null )
450 			initConfig();
451 
452 		if( !defaults.containsKey( endpoint ) )
453 		{
454 			EndpointConfig newEndpoint = config.addNewEndpoint();
455 			newEndpoint.setStringValue( endpoint );
456 			defaults.put( endpoint, new EndpointDefaults( newEndpoint ) );
457 		}
458 
459 		return defaults.get( endpoint );
460 	}
461 
462 	public void onSave()
463 	{
464 		if( config == null )
465 			return;
466 
467 		removeUnusedEndpoints();
468 
469 		// remove unused
470 		for( int c = 0; c < config.sizeOfEndpointArray(); c++ )
471 		{
472 			EndpointConfig ec = config.getEndpointArray( c );
473 			if( StringUtils.isNullOrEmpty( ec.getDomain() ) && StringUtils.isNullOrEmpty( ec.getUsername() )
474 						&& StringUtils.isNullOrEmpty( ec.getPassword() ) && StringUtils.isNullOrEmpty( ec.getWssType() )
475 						&& StringUtils.isNullOrEmpty( ec.getWssTimeToLive() ) )
476 			{
477 				defaults.remove( ec.getStringValue() );
478 				config.removeEndpoint( c );
479 				c--;
480 			}
481 		}
482 
483 		if( config.sizeOfEndpointArray() == 0 )
484 		{
485 			project.getConfig().unsetEndpointStrategy();
486 			config = null;
487 		}
488 	}
489 
490 	public void importEndpoints( Interface iface )
491 	{
492 		EndpointStrategy ep = iface.getProject().getEndpointStrategy();
493 		if( ep instanceof DefaultEndpointStrategy )
494 		{
495 			DefaultEndpointStrategy dep = ( DefaultEndpointStrategy ) ep;
496 			String[] endpoints = iface.getEndpoints();
497 
498 			for( String endpoint : endpoints )
499 			{
500 				getEndpointDefaults( endpoint ).getConfig().set( dep.getEndpointDefaults( endpoint ).getConfig() );
501 			}
502 		}
503 	}
504 
505 	public JComponent getConfigurationPanel( Interface iface )
506 	{
507 		return new DefaultEndpointStrategyConfigurationPanel( ( WsdlInterface ) iface, this );
508 	}
509 
510 	public void afterRequest( SubmitContext context, Response response )
511 	{
512 		// TODO Auto-generated method stub
513 		
514 	}
515 }