View Javadoc

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