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 org.apache.commons.httpclient.URI;
24  import org.apache.commons.httpclient.URIException;
25  
26  import com.eviware.soapui.SoapUI;
27  import com.eviware.soapui.config.DefaultEndpointStrategyConfig;
28  import com.eviware.soapui.config.EndpointConfig;
29  import com.eviware.soapui.config.ProjectConfig;
30  import com.eviware.soapui.impl.wsdl.WsdlInterface;
31  import com.eviware.soapui.impl.wsdl.WsdlProject;
32  import com.eviware.soapui.impl.wsdl.WsdlRequest;
33  import com.eviware.soapui.impl.wsdl.submit.filters.HttpAuthenticationRequestFilter;
34  import com.eviware.soapui.impl.wsdl.submit.filters.PropertyExpansionRequestFilter;
35  import com.eviware.soapui.impl.wsdl.submit.filters.WsSecurityAuthenticationRequestFilter;
36  import com.eviware.soapui.impl.wsdl.submit.transports.http.BaseHttpRequestTransport;
37  import com.eviware.soapui.impl.wsdl.submit.transports.http.TimeablePostMethod;
38  import com.eviware.soapui.model.iface.Interface;
39  import com.eviware.soapui.model.iface.SubmitContext;
40  import com.eviware.soapui.model.project.EndpointStrategy;
41  import com.eviware.soapui.model.project.Project;
42  import com.eviware.soapui.model.project.ProjectListener;
43  import com.eviware.soapui.model.support.ProjectListenerAdapter;
44  import com.eviware.soapui.support.StringUtils;
45  import com.eviware.soapui.support.types.StringList;
46  
47  public class DefaultEndpointStrategy implements EndpointStrategy
48  {
49  	private WsdlProject project;
50  	private DefaultEndpointStrategyConfig config;
51  	private Map<String,EndpointDefaults> defaults = new HashMap<String,EndpointDefaults>();
52  	private PropertyChangeListener propertyChangeListener = new InternalPropertyChangeListener();
53  	private ProjectListener projectListener = new InternalProjectListener() ;
54  
55  	public void configure( Interface iface )
56  	{
57  		SoapUI.getActionRegistry().getAction( DefaultEndpointStrategyConfigureAction.SOAPUI_ACTION_ID ).perform( iface, this );
58  	}
59  
60  	public void init( Project project )
61  	{
62  		this.project = ( WsdlProject ) project;
63  		initConfig();
64  		
65  		project.addProjectListener( projectListener  );
66  		
67  		for( Interface iface : project.getInterfaces() )
68  		{
69  			for( String endpoint : iface.getEndpoints() )
70  			{
71  				// ensure we have defaults
72  				getEndpointDefaults( endpoint );
73  			}
74  			
75  			iface.addPropertyChangeListener( WsdlInterface.ENDPOINT_PROPERTY, propertyChangeListener );
76  		}
77  		
78  		removeUnusedEndpoints();
79  	}
80  
81  	private void initConfig()
82  	{
83  		ProjectConfig projectConfig = this.project.getConfig();
84  		
85  		if( !projectConfig.isSetEndpointStrategy() )
86  		{
87  			projectConfig.addNewEndpointStrategy();
88  		}
89  		
90  		config = ( DefaultEndpointStrategyConfig ) projectConfig.getEndpointStrategy().changeType( DefaultEndpointStrategyConfig.type  );
91  		
92  		for( EndpointConfig endpointConfig : config.getEndpointList())
93  		{
94  			defaults.put( endpointConfig.getStringValue(), new EndpointDefaults( endpointConfig ) );
95  		}
96  	}
97  
98  	private void removeUnusedEndpoints()
99  	{
100 		if( config == null )
101 			return;
102 		
103 		Set<String> endpoints = new HashSet<String>();
104 		
105 		for( Interface iface : project.getInterfaces() )
106 		{
107 			endpoints.addAll( Arrays.asList( iface.getEndpoints() ));
108 		}
109 		
110 		StringList keys = new StringList();
111 		
112 		for( String key : defaults.keySet() )
113 		{
114 			if( !endpoints.contains( key ))
115 			{
116 				keys.add(  key );
117 			}
118 		}
119 		
120 		for( String key : keys )
121 		{
122 			EndpointDefaults def = defaults.remove( key );
123 			config.getEndpointList().remove( def );
124 		}
125 	}
126 
127 	public void filterRequest( SubmitContext context, WsdlRequest wsdlRequest )
128 	{
129 		TimeablePostMethod postMethod = (TimeablePostMethod) context.getProperty( BaseHttpRequestTransport.POST_METHOD );
130 		URI uri = null;
131 		try
132 		{
133 			uri = postMethod.getURI();
134 		}
135 		catch( URIException e )
136 		{
137 			SoapUI.logError( e );
138 			return;
139 		}
140 		
141 		if( !defaults.containsKey( uri.toString() ))
142 		{
143 			return;
144 		}
145 		
146 		EndpointDefaults def = defaults.get( uri.toString() );
147 		applyDefaultsToRequest( context, wsdlRequest, def );
148 	}
149 
150 	protected void applyDefaultsToRequest( SubmitContext context, WsdlRequest wsdlRequest, EndpointDefaults def )
151 	{
152 		String requestUsername = PropertyExpansionRequestFilter.expandProperties( context, wsdlRequest.getUsername());
153 		String requestPassword = PropertyExpansionRequestFilter.expandProperties( context, wsdlRequest.getPassword());
154 		String requestDomain = PropertyExpansionRequestFilter.expandProperties( context, wsdlRequest.getDomain());
155 		
156 		String defUsername = PropertyExpansionRequestFilter.expandProperties( context, def.getUsername());
157 		String defPassword = PropertyExpansionRequestFilter.expandProperties( context, def.getPassword());
158 		String defDomain = PropertyExpansionRequestFilter.expandProperties( context, def.getDomain());
159 		
160 		if( (StringUtils.hasContent( defUsername ) && StringUtils.isNullOrEmpty( requestUsername )) ||
161 			 (StringUtils.hasContent( defPassword ) && StringUtils.isNullOrEmpty( requestPassword )) || 
162 			 (StringUtils.hasContent( defDomain ) && StringUtils.isNullOrEmpty( requestDomain )) )
163 		{
164 			String username = StringUtils.hasContent( requestUsername ) ? requestUsername : defUsername;
165 			String password = StringUtils.hasContent( requestPassword ) ? requestPassword : defPassword;
166 			String domain = StringUtils.hasContent( requestDomain ) ? requestDomain : defDomain;
167 			
168 			HttpAuthenticationRequestFilter.initRequestCredentials( 
169 						context, username, project.getSettings(), password, domain );
170 		}
171 		
172 		// only set if not set in request
173 		String wssType = StringUtils.isNullOrEmpty( wsdlRequest.getWssPasswordType() ) ? def.getWssType() :
174 					(StringUtils.hasContent( requestUsername ) && StringUtils.hasContent( requestPassword )) ? null : 
175 						wsdlRequest.getWssPasswordType();
176 		
177 		String wssTimeToLive = StringUtils.isNullOrEmpty( wsdlRequest.getWssTimeToLive() ) ? def.getWssTimeToLive() : null;
178 		
179 		if( StringUtils.hasContent( wssType ) || StringUtils.hasContent( wssTimeToLive ))
180 		{
181 			try
182 			{
183 				String username = StringUtils.hasContent( requestUsername ) ? requestUsername : defUsername;
184 				String password = StringUtils.hasContent( requestPassword ) ? requestPassword : defPassword;
185 				
186 				if( StringUtils.hasContent( username ) || StringUtils.hasContent( password ))
187 					WsSecurityAuthenticationRequestFilter.addWssHeaders( context, username, password, wssType, wssTimeToLive  );
188 			}
189 			catch( Exception e )
190 			{
191 				SoapUI.logError( e );
192 			}
193 		}
194 	}
195 
196 	public void release()
197 	{
198 		project.removeProjectListener( projectListener );
199 		for( Interface iface : project.getInterfaces() )
200 			iface.removePropertyChangeListener( WsdlInterface.ENDPOINT_PROPERTY, propertyChangeListener );
201 	}
202 	
203 	private class InternalProjectListener extends ProjectListenerAdapter
204 	{
205 		@Override
206 		public void interfaceAdded( Interface iface )
207 		{
208 			for( String endpoint : iface.getEndpoints() )
209 			{
210 				// ensure we have defaults
211 				getEndpointDefaults( endpoint );
212 			}
213 			
214 			iface.addPropertyChangeListener( WsdlInterface.ENDPOINT_PROPERTY, propertyChangeListener );
215 		}
216 
217 		@Override
218 		public void interfaceRemoved( Interface iface )
219 		{
220 			iface.removePropertyChangeListener( WsdlInterface.ENDPOINT_PROPERTY, propertyChangeListener );
221 			removeUnusedEndpoints();
222 		}
223 	}
224 	
225 	private class InternalPropertyChangeListener implements PropertyChangeListener
226 	{
227 		public void propertyChange( PropertyChangeEvent evt )
228 		{
229 			// new endpoint?
230 			if( evt.getOldValue() == null )
231 			{
232 				getEndpointDefaults( evt.getNewValue().toString() );
233 			}
234 			// changed endpoint?
235 			else if( evt.getNewValue() != null )
236 			{
237 				String oldValue = evt.getOldValue().toString();
238 				EndpointDefaults def = getEndpointDefaults( oldValue );
239 				def.endpointConfig.setStringValue( evt.getNewValue().toString() );
240 				defaults.remove( oldValue );
241 				defaults.put( evt.getNewValue().toString(), def );
242 			}
243 			else 
244 			{
245 				removeUnusedEndpoints();
246 			}
247 		}
248 	}
249 	
250 	public class EndpointDefaults
251 	{
252 		private final EndpointConfig endpointConfig;
253 
254 		public EndpointDefaults( EndpointConfig endpointConfig )
255 		{
256 			this.endpointConfig = endpointConfig;
257 		}
258 
259 		public String getDomain()
260 		{
261 			return endpointConfig.getDomain();
262 		}
263 
264 		public String getPassword()
265 		{
266 			return endpointConfig.getPassword();
267 		}
268 
269 		public String getUsername()
270 		{
271 			return endpointConfig.getUsername();
272 		}
273 
274 		public String getWssTimeToLive()
275 		{
276 			return endpointConfig.getWssTimeToLive();
277 		}
278 
279 		public String getWssType()
280 		{
281 			return endpointConfig.getWssType();
282 		}
283 
284 		public void setDomain( String arg0 )
285 		{
286 			endpointConfig.setDomain( arg0 );
287 		}
288 
289 		public void setPassword( String arg0 )
290 		{
291 			endpointConfig.setPassword( arg0 );
292 		}
293 
294 		public void setUsername( String arg0 )
295 		{
296 			endpointConfig.setUsername( arg0 );
297 		}
298 
299 		public void setWssTimeToLive( String arg0 )
300 		{
301 			endpointConfig.setWssTimeToLive( arg0 );
302 		}
303 
304 		public void setWssType( String arg0 )
305 		{
306 			endpointConfig.setWssType( arg0 );
307 		}
308 
309 		protected EndpointConfig getConfig()
310 		{
311 			return endpointConfig;
312 		}
313 	}
314 
315 	public EndpointDefaults getEndpointDefaults( String endpoint )
316 	{
317 		if( config == null )
318 			initConfig();
319 		
320 		if( !defaults.containsKey( endpoint ))
321 		{
322 			EndpointConfig newEndpoint = config.addNewEndpoint();
323 			newEndpoint.setStringValue( endpoint );
324 			defaults.put( endpoint, new EndpointDefaults( newEndpoint ));
325 		}
326 		
327 		return defaults.get( endpoint );
328 	}
329 
330 	public void onSave()
331 	{
332 		if( config == null )
333 			return;
334 		
335 		removeUnusedEndpoints();
336 		
337 		// remove unused
338 		for( int c = 0; c < config.sizeOfEndpointArray(); c++ )
339 		{
340 			EndpointConfig ec = config.getEndpointArray( c );
341 			if( StringUtils.isNullOrEmpty( ec.getDomain() ) && StringUtils.isNullOrEmpty( ec.getUsername() ) &&
342 						StringUtils.isNullOrEmpty( ec.getPassword() ) && StringUtils.isNullOrEmpty( ec.getWssType() ) && 
343 						StringUtils.isNullOrEmpty( ec.getWssTimeToLive() ))
344 			{
345 				defaults.remove( ec.getStringValue() );
346 				config.removeEndpoint( c );
347 				c--;
348 			}
349 		}
350 		
351 		if( config.sizeOfEndpointArray() == 0 )
352 		{
353 			project.getConfig().unsetEndpointStrategy();
354 			config = null;
355 		}
356 	}
357 
358 	public void importEndpoints( Interface iface )
359 	{
360 		EndpointStrategy ep = iface.getProject().getEndpointStrategy();
361 		if( ep instanceof DefaultEndpointStrategy )
362 		{
363 			DefaultEndpointStrategy dep = ( DefaultEndpointStrategy ) ep;
364 			String[] endpoints = iface.getEndpoints();
365 			
366 			for( String endpoint : endpoints )
367 			{
368 				getEndpointDefaults( endpoint ).getConfig().set( dep.getEndpointDefaults( endpoint ).getConfig() );
369 			}
370 		}
371 	}
372 }