View Javadoc

1   /*
2    *  soapUI, copyright (C) 2004-2009 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  package com.eviware.soapui.impl.rest;
13  
14  import java.beans.PropertyChangeEvent;
15  import java.beans.PropertyChangeListener;
16  import java.util.ArrayList;
17  import java.util.Arrays;
18  import java.util.HashSet;
19  import java.util.List;
20  import java.util.Map;
21  import java.util.Set;
22  
23  import com.eviware.soapui.SoapUI;
24  import com.eviware.soapui.config.RestMethodConfig;
25  import com.eviware.soapui.config.RestRequestConfig;
26  import com.eviware.soapui.config.RestResourceRepresentationConfig;
27  import com.eviware.soapui.impl.rest.RestRepresentation.Type;
28  import com.eviware.soapui.impl.rest.support.OverlayRestParamsPropertyHolder;
29  import com.eviware.soapui.impl.rest.support.RestParamProperty;
30  import com.eviware.soapui.impl.rest.support.RestParamsPropertyHolder;
31  import com.eviware.soapui.impl.rest.support.XmlBeansRestParamsTestPropertyHolder;
32  import com.eviware.soapui.impl.wsdl.AbstractWsdlModelItem;
33  import com.eviware.soapui.impl.wsdl.MutableTestPropertyHolder;
34  import com.eviware.soapui.model.ModelItem;
35  import com.eviware.soapui.model.iface.Attachment;
36  import com.eviware.soapui.model.propertyexpansion.PropertyExpansion;
37  import com.eviware.soapui.model.testsuite.TestProperty;
38  import com.eviware.soapui.model.testsuite.TestPropertyListener;
39  import com.eviware.soapui.support.StringUtils;
40  import com.eviware.soapui.support.UISupport;
41  import com.eviware.soapui.support.types.StringList;
42  import com.eviware.soapui.ui.desktop.AbstractSoapUIDesktop;
43  
44  public class RestMethod extends AbstractWsdlModelItem<RestMethodConfig> implements MutableTestPropertyHolder,
45  		PropertyChangeListener
46  {
47  	private List<RestRequest> requests = new ArrayList<RestRequest>();
48  	private List<RestRepresentation> representations = new ArrayList<RestRepresentation>();
49  	private RestResource resource;
50  	private XmlBeansRestParamsTestPropertyHolder params;
51  	private RestParamsPropertyHolder overlayParams;
52  
53  	private PropertyChangeListener representationPropertyChangeListener = new RepresentationPropertyChangeListener();
54  
55  	public RestMethod( RestResource service, RestMethodConfig methodConfig )
56  	{
57  		super( methodConfig, service, "/"
58  				+ ( StringUtils.isNullOrEmpty( methodConfig.getMethod() ) ? "get" : methodConfig.getMethod().toLowerCase() )
59  				+ "_method.gif" );
60  		this.resource = service;
61  
62  		if( methodConfig.getParameters() == null )
63  			methodConfig.addNewParameters();
64  
65  		params = new XmlBeansRestParamsTestPropertyHolder( this, methodConfig.getParameters() );
66  
67  		for( RestResourceRepresentationConfig config : methodConfig.getRepresentationList() )
68  		{
69  			RestRepresentation representation = new RestRepresentation( this, config );
70  			representations.add( representation );
71  			notifyPropertyChanged( "representations", null, representation );
72  		}
73  
74  		for( RestRequestConfig config : methodConfig.getRequestList() )
75  		{
76  			RestRequest request = new RestRequest( this, config, false );
77  			requests.add( request );
78  			notifyPropertyChanged( "childRequests", null, request );
79  		}
80  	}
81  
82  	public RestParamsPropertyHolder getOverlayParams()
83  	{
84  		if( overlayParams == null )
85  			overlayParams = new OverlayRestParamsPropertyHolder( buildOverlay( getResource() ), params );
86  		return overlayParams;
87  	}
88  
89  	private RestParamsPropertyHolder buildOverlay( RestResource resource )
90  	{
91  		return resource.getParentResource() == null ? resource.getParams() : new OverlayRestParamsPropertyHolder(
92  				buildOverlay( resource.getParentResource() ), resource.getParams() );
93  	}
94  
95  	public RestResource getOperation()
96  	{
97  		return resource;
98  	}
99  
100 	public RestParamProperty addProperty( String name )
101 	{
102 		return params.addProperty( name );
103 	}
104 
105 	public void moveProperty( String propertyName, int targetIndex )
106 	{
107 		params.moveProperty( propertyName, targetIndex );
108 	}
109 
110 	public RestParamProperty removeProperty( String propertyName )
111 	{
112 		return params.removeProperty( propertyName );
113 	}
114 
115 	public boolean renameProperty( String name, String newName )
116 	{
117 		return params.renameProperty( name, newName );
118 	}
119 
120 	public void addTestPropertyListener( TestPropertyListener listener )
121 	{
122 		params.addTestPropertyListener( listener );
123 	}
124 
125 	public RestParamsPropertyHolder getParams()
126 	{
127 		return params;
128 	}
129 
130 	public ModelItem getModelItem()
131 	{
132 		return this;
133 	}
134 
135 	public Map<String, TestProperty> getProperties()
136 	{
137 		return params.getProperties();
138 	}
139 
140 	public RestParamProperty getProperty( String name )
141 	{
142 		return params.getProperty( name );
143 	}
144 
145 	public RestParamProperty getPropertyAt( int index )
146 	{
147 		return params.getPropertyAt( index );
148 	}
149 
150 	public int getPropertyCount()
151 	{
152 		return params.getPropertyCount();
153 	}
154 
155 	public String[] getPropertyNames()
156 	{
157 		return params.getPropertyNames();
158 	}
159 
160 	public String getPropertyValue( String name )
161 	{
162 		return params.getPropertyValue( name );
163 	}
164 
165 	public boolean hasProperty( String name )
166 	{
167 		return params.hasProperty( name );
168 	}
169 
170 	public void removeTestPropertyListener( TestPropertyListener listener )
171 	{
172 		params.removeTestPropertyListener( listener );
173 	}
174 
175 	public void setPropertyValue( String name, String value )
176 	{
177 		params.setPropertyValue( name, value );
178 	}
179 
180 	public String getPropertiesLabel()
181 	{
182 		return "Method Params";
183 	}
184 
185 	public boolean hasRequestBody()
186 	{
187 		RestRequestInterface.RequestMethod method = getMethod();
188 		return method == RestRequestInterface.RequestMethod.POST || method == RestRequestInterface.RequestMethod.PUT;
189 	}
190 
191 	public void propertyChange( PropertyChangeEvent arg0 )
192 	{
193 		// TODO Auto-generated method stub
194 
195 	}
196 
197 	public PropertyExpansion[] getPropertyExpansions()
198 	{
199 		return params.getPropertyExpansions();
200 	}
201 
202 	public RestRequestInterface.RequestMethod getMethod()
203 	{
204 		String method = getConfig().getMethod();
205 		return method == null ? null : RestRequestInterface.RequestMethod.valueOf( method );
206 	}
207 
208 	public void setMethod( RestRequestInterface.RequestMethod method )
209 	{
210 		RestRequestInterface.RequestMethod old = getMethod();
211 		getConfig().setMethod( method.toString() );
212 		setIcon( UISupport.createImageIcon( "/" + method.toString().toLowerCase() + "_method.gif" ) );
213 		notifyPropertyChanged( "method", old, method );
214 	}
215 
216 	public String getDefaultRequestMediaType()
217 	{
218 		RestRepresentation[] representations = getRepresentations( RestRepresentation.Type.REQUEST, null );
219 		if( representations.length >= 1 )
220 			return representations[0].getMediaType();
221 		return "application/xml";
222 	}
223 
224 	public RestRepresentation[] getRepresentations()
225 	{
226 		return getRepresentations( null, null );
227 	}
228 
229 	public RestRepresentation[] getRepresentations( RestRepresentation.Type type, String mediaType )
230 	{
231 		List<RestRepresentation> result = new ArrayList<RestRepresentation>();
232 		Set<String> addedTypes = new HashSet<String>();
233 
234 		for( RestRepresentation representation : representations )
235 		{
236 			if( ( type == null || type == representation.getType() )
237 					&& ( mediaType == null || mediaType.equals( representation.getMediaType() ) ) )
238 			{
239 				result.add( representation );
240 				addedTypes.add( representation.getMediaType() );
241 			}
242 		}
243 
244 		if( type == RestRepresentation.Type.REQUEST )
245 		{
246 			for( RestRequest request : requests )
247 			{
248 				for( Attachment attachment : request.getAttachments() )
249 				{
250 					if( ( mediaType == null || mediaType.equals( attachment.getContentType() ) )
251 							&& !addedTypes.contains( attachment.getContentType() ) )
252 					{
253 						RestRepresentation representation = new RestRepresentation( this,
254 								RestResourceRepresentationConfig.Factory.newInstance() );
255 						representation.setType( RestRepresentation.Type.REQUEST );
256 						representation.setMediaType( attachment.getContentType() );
257 						result.add( representation );
258 					}
259 				}
260 			}
261 		}
262 
263 		return result.toArray( new RestRepresentation[result.size()] );
264 	}
265 
266 	public String[] getResponseMediaTypes()
267 	{
268 		StringList result = new StringList();
269 
270 		for( RestRepresentation representation : getRepresentations( Type.RESPONSE, null ) )
271 		{
272 			if( !result.contains( representation.getMediaType() ) )
273 				result.add( representation.getMediaType() );
274 		}
275 
276 		return result.toStringArray();
277 	}
278 
279 	public RestRepresentation addNewRepresentation( Type type )
280 	{
281 		RestRepresentation representation = new RestRepresentation( this, getConfig().addNewRepresentation() );
282 		representation.setType( type );
283 
284 		representation.addPropertyChangeListener( representationPropertyChangeListener );
285 
286 		representations.add( representation );
287 
288 		notifyPropertyChanged( "representations", null, representation );
289 
290 		return representation;
291 	}
292 
293 	public void removeRepresentation( RestRepresentation representation )
294 	{
295 		int ix = representations.indexOf( representation );
296 
297 		representations.remove( ix );
298 		representation.removePropertyChangeListener( representationPropertyChangeListener );
299 
300 		notifyPropertyChanged( "representations", representation, null );
301 		getConfig().removeRepresentation( ix );
302 		representation.release();
303 	}
304 
305 	public void removeRequest( RestRequest request )
306 	{
307 		int ix = requests.indexOf( request );
308 		requests.remove( ix );
309 
310 		try
311 		{
312 			( getInterface() ).fireRequestRemoved( request );
313 			notifyPropertyChanged( "childRequests", request, null );
314 		}
315 		finally
316 		{
317 			request.release();
318 			getConfig().removeRequest( ix );
319 		}
320 	}
321 
322 	private class RepresentationPropertyChangeListener implements PropertyChangeListener
323 	{
324 		public void propertyChange( PropertyChangeEvent evt )
325 		{
326 			if( evt.getPropertyName().equals( "mediaType" )
327 					&& ( ( RestRepresentation )evt.getSource() ).getType() == Type.RESPONSE )
328 			{
329 				RestMethod.this.notifyPropertyChanged( "responseMediaTypes", null, getResponseMediaTypes() );
330 			}
331 		}
332 	}
333 
334 	public RestResource getResource()
335 	{
336 		return resource;
337 	}
338 
339 	public List<RestRequest> getRequestList()
340 	{
341 		return new ArrayList<RestRequest>( requests );
342 	}
343 
344 	public RestRequest getRequestAt( int index )
345 	{
346 		return requests.get( index );
347 	}
348 
349 	public RestRequest getRequestByName( String name )
350 	{
351 		return ( RestRequest )getWsdlModelItemByName( requests, name );
352 	}
353 
354 	public int getRequestCount()
355 	{
356 		return requests.size();
357 	}
358 
359 	public RestRequest addNewRequest( String name )
360 	{
361 		RestRequestConfig resourceConfig = getConfig().addNewRequest();
362 		resourceConfig.setName( name );
363 
364 		RestRequest request = new RestRequest( this, resourceConfig, false );
365 		requests.add( request );
366 		request.resetPropertyValues();
367 
368 		/*
369 		 * for (RestParamProperty prop : getDefaultParams()) { if
370 		 * (!request.hasProperty(prop.getName()))
371 		 * request.addProperty(prop.getName()).setValue(prop.getDefaultValue()); }
372 		 */
373 
374 		String[] endpoints = getInterface().getEndpoints();
375 		if( endpoints.length > 0 )
376 			request.setEndpoint( endpoints[0] );
377 
378 		// getInterface().fireRequestAdded(request);
379 		notifyPropertyChanged( "childRequests", null, request );
380 		return request;
381 	}
382 
383 	public RestRequest cloneRequest( RestRequest request, String name )
384 	{
385 		RestRequestConfig requestConfig = ( RestRequestConfig )getConfig().addNewRequest().set( request.getConfig() );
386 		requestConfig.setName( name );
387 
388 		RestRequest newRequest = new RestRequest( this, requestConfig, false );
389 		requests.add( newRequest );
390 
391 		// getInterface().fireRequestAdded(newRequest);
392 		notifyPropertyChanged( "childRequests", null, newRequest );
393 		return newRequest;
394 	}
395 
396 	public RestParamProperty[] getDefaultParams()
397 	{
398 		List<RestParamProperty> result = new ArrayList<RestParamProperty>();
399 		Set<String> names = new HashSet<String>();
400 
401 		result.addAll( Arrays.asList( resource.getDefaultParams() ) );
402 
403 		for( int c = 0; c < getPropertyCount(); c++ )
404 		{
405 			if( names.contains( getPropertyAt( c ).getName() ) )
406 				continue;
407 
408 			result.add( getPropertyAt( c ) );
409 			names.add( getPropertyAt( c ).getName() );
410 		}
411 
412 		return result.toArray( new RestParamProperty[result.size()] );
413 	}
414 
415 	public RestService getInterface()
416 	{
417 		return resource.getInterface();
418 	}
419 
420 	public List<? extends ModelItem> getChildren()
421 	{
422 		return getRequestList();
423 	}
424 
425 	@Override
426 	public void release()
427 	{
428 		( ( AbstractSoapUIDesktop )SoapUI.getDesktop() ).closeDependantPanels( this );
429 		super.release();
430 		for( int i = requests.size(); i > 0; i-- )
431 		{
432 			// removeRequest(requests.get(i-1));
433 			requests.get( i - 1 ).release();
434 		}
435 		getOperation().removePropertyChangeListener( this );
436 		params.release();
437 	}
438 
439 	public List<TestProperty> getPropertyList()
440 	{
441 		return params.getPropertyList();
442 	}
443 
444 }