View Javadoc

1   /*
2    *  soapUI, copyright (C) 2004-2008 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.rest;
14  
15  import com.eviware.soapui.config.RestMethodConfig;
16  import com.eviware.soapui.config.RestResourceConfig;
17  import com.eviware.soapui.impl.rest.support.RestUtils;
18  import com.eviware.soapui.impl.rest.support.XmlBeansRestParamsTestPropertyHolder;
19  import com.eviware.soapui.impl.rest.support.XmlBeansRestParamsTestPropertyHolder.RestParamProperty;
20  import com.eviware.soapui.impl.support.AbstractHttpOperation;
21  import com.eviware.soapui.impl.wsdl.AbstractWsdlModelItem;
22  import com.eviware.soapui.impl.wsdl.MutableTestPropertyHolder;
23  import com.eviware.soapui.model.ModelItem;
24  import com.eviware.soapui.model.iface.Attachment.AttachmentEncoding;
25  import com.eviware.soapui.model.iface.MessagePart;
26  import com.eviware.soapui.model.iface.Request;
27  import com.eviware.soapui.model.propertyexpansion.PropertyExpansionContext;
28  import com.eviware.soapui.model.testsuite.TestProperty;
29  import com.eviware.soapui.model.testsuite.TestPropertyListener;
30  import com.eviware.soapui.support.StringUtils;
31  
32  import java.beans.PropertyChangeEvent;
33  import java.beans.PropertyChangeListener;
34  import java.util.*;
35  
36  /***
37   * WSDL implementation of Operation, maps to a WSDL BindingOperation
38   * 
39   * @author Ole.Matzura
40   */
41  
42  public class RestResource extends AbstractWsdlModelItem<RestResourceConfig> implements AbstractHttpOperation,
43  	MutableTestPropertyHolder, RestResourceContainer, PropertyChangeListener
44  {
45  	public static final String PATH_PROPERTY = "path";
46  	private List<RestRequest> requests = new ArrayList<RestRequest>();
47  	private List<RestResource> resources = new ArrayList<RestResource>();
48  	private RestResource parentResource;
49  	private XmlBeansRestParamsTestPropertyHolder params;
50  	
51     public RestResource( RestService service, RestResourceConfig resourceConfig )
52     {
53     	super( resourceConfig, service, "/rest_resource.gif" );
54     	
55     	for( RestMethodConfig config : resourceConfig.getRequestList())
56     	{
57     		requests.add( new RestRequest( this, config, false ));
58     	}
59     	
60     	for( RestResourceConfig config : resourceConfig.getResourceList())
61     	{
62     		resources.add( new RestResource( this, config ));
63     	}
64     	
65     	if( resourceConfig.getParameters() == null )
66     		resourceConfig.addNewParameters();
67     	
68     	params = new XmlBeansRestParamsTestPropertyHolder( this, resourceConfig.getParameters());
69  
70        service.addPropertyChangeListener( this );
71     }
72  
73  	public RestResource(RestResource restResource, RestResourceConfig config)
74  	{
75  		this( restResource.getInterface(), config );
76  		this.parentResource = restResource;
77  
78        parentResource.addPropertyChangeListener( this );
79     }
80  
81  	public RestResource getParentResource()
82  	{
83  		return parentResource;
84  	}
85  	
86  	public RestResourceContainer getResourceContainer()
87  	{
88  		return parentResource == null ? getInterface() : parentResource;
89  	}
90  
91  	public List<? extends ModelItem> getChildren()
92  	{
93  		List<ModelItem> result = new ArrayList<ModelItem>();
94  		
95  		result.addAll( getRequestList());
96  		result.addAll( getChildResourceList());
97  		
98  		return result;
99  	}
100 
101 	public MessagePart[] getDefaultRequestParts()
102 	{
103 		return new MessagePart[0];
104 	}
105 
106 	public MessagePart[] getDefaultResponseParts()
107 	{
108 		return new MessagePart[0];
109 	}
110 
111 	public RestService getInterface()
112 	{
113 		return (RestService) getParent();
114 	}
115 	
116 	public String [] getRequestMediaTypes()
117 	{
118 		return new String[0];
119 	}
120 	
121 	public String [] getResponseMediaTypes()
122 	{
123 		return new String[0];
124 	}
125 
126 	public RestResource getChildResourcetAt(int index)
127 	{
128 		return resources.get(index);
129 	}
130 
131 	public RestResource getChildResourceByName(String name)
132 	{
133 		return ( RestResource ) getWsdlModelItemByName( resources, name );
134 	}
135 	
136 	public RestResource addNewChildResource(String name, String path)
137 	{
138 		RestResourceConfig resourceConfig = getConfig().addNewResource();
139 		resourceConfig.setName(name);
140 		resourceConfig.setPath(path);
141 		
142 		RestResource resource = new RestResource( this, resourceConfig);
143 		resources.add( resource );
144 		
145 		getInterface().fireOperationAdded( resource );
146 
147       notifyPropertyChanged( "childResources", null, resource );
148 		
149 		return resource;
150 	}
151 
152 	public int getChildResourceCount()
153 	{
154 		return resources.size();
155 	}
156 
157 	public List<RestResource> getChildResourceList()
158 	{
159 		return new ArrayList<RestResource>( resources );
160 	}
161 
162 	public RestRequest getRequestAt(int index)
163 	{
164 		return requests.get(index);
165 	}
166 
167 	public RestRequest getRequestByName(String name)
168 	{
169 		return ( RestRequest ) getWsdlModelItemByName( requests, name );
170 	}
171 	
172 	public RestRequest addNewRequest(String name)
173 	{
174 		RestMethodConfig resourceConfig = getConfig().addNewRequest();
175 		resourceConfig.setName(name);
176 		
177 		RestRequest request = new RestRequest( this, resourceConfig, false);
178 		requests.add( request );
179 		
180 		for( RestParamProperty prop : getDefaultParams())
181 		{
182          if( !request.hasProperty( prop.getName() ))
183             request.addProperty(prop);
184 		}
185 		
186 		 String[] endpoints = getInterface().getEndpoints();
187 		 if( endpoints.length > 0 )
188 			 request.setEndpoint(endpoints[0]);
189 		
190 		getInterface().fireRequestAdded(request);
191 		return request;
192 	}
193 
194 	public int getRequestCount()
195 	{
196 		return requests.size();
197 	}
198 
199 	public List<Request> getRequestList()
200 	{
201 		return new ArrayList<Request>( requests );
202 	}
203 
204 	public String getPath()
205 	{
206 		return getConfig().getPath();
207 	}
208 	
209 	public void setPath( String path )
210 	{
211 		String old = getPath();
212 		getConfig().setPath(path);
213 		notifyPropertyChanged("path", old, path);
214 		
215 		for( String param : RestUtils.extractTemplateParams(path))
216 		{
217 			if( !hasProperty(param))
218 				addProperty(param);
219 		}
220 	}
221 	
222 	public boolean isBidirectional()
223 	{
224 		return false;
225 	}
226 
227 	public boolean isNotification()
228 	{
229 		return false;
230 	}
231 
232 	public boolean isOneWay()
233 	{
234 		return false;
235 	}
236 
237 	public boolean isRequestResponse()
238 	{
239 		return true;
240 	}
241 
242 	public boolean isSolicitResponse()
243 	{
244 		return false;
245 	}
246 
247 	public boolean isUnidirectional()
248 	{
249 		return false;
250 	}
251 
252 	public AttachmentEncoding getAttachmentEncoding(String part, boolean isRequest)
253 	{
254 		return AttachmentEncoding.NONE;
255 	}
256 
257 	public RestParamProperty[] getDefaultParams()
258 	{
259 		List<RestParamProperty> result = new ArrayList<RestParamProperty>();
260       Set<String> names = new HashSet<String>();
261 
262       if( parentResource != null )
263 			result.addAll( Arrays.asList( parentResource.getDefaultParams() ));
264 		
265 		for( int c = 0; c < getPropertyCount(); c++ )
266       {
267          if( names.contains( getPropertyAt( c ).getName()))
268             continue;
269 
270          result.add( getPropertyAt(c));
271          names.add( getPropertyAt( c ).getName());
272       }
273 		
274       return result.toArray( new RestParamProperty[result.size()]);
275 	}
276 
277    public String getFullPath()
278    {
279       return getFullPath( true );
280    }
281 
282 	public String getFullPath( boolean includeBasePath )
283 	{
284 		String base = parentResource == null ?
285               ( includeBasePath ? getInterface().getBasePath() : "" ) : parentResource.getFullPath( includeBasePath );
286       
287 		String path = getPath();
288 		if( StringUtils.hasContent(path) && base != null && !base.endsWith("/") && !path.startsWith("/"))
289 			base += "/";
290 		
291 		return path == null ? base : base + path;
292 	}
293 	
294 	public RestParamProperty addProperty(String name)
295 	{
296 		return params.addProperty(name);
297 	}
298 
299 	public void moveProperty(String propertyName, int targetIndex)
300 	{
301 		params.moveProperty(propertyName, targetIndex);
302 	}
303 
304 	public RestParamProperty removeProperty(String propertyName)
305 	{
306 		return params.removeProperty(propertyName);
307 	}
308 
309 	public boolean renameProperty(String name, String newName)
310 	{
311 		return params.renameProperty(name, newName);
312 	}
313 
314 	public void addTestPropertyListener(TestPropertyListener listener)
315 	{
316 		params.addTestPropertyListener(listener);
317 	}
318 
319 	public XmlBeansRestParamsTestPropertyHolder getParams()
320 	{
321 		return params;
322 	}
323 
324 	public ModelItem getModelItem()
325 	{
326 		return this;
327 	}
328 
329 	public Map<String, TestProperty> getProperties()
330 	{
331 		return params.getProperties();
332 	}
333 
334 	public RestParamProperty getProperty(String name)
335 	{
336 		return params.getProperty(name);
337 	}
338 
339 	public RestParamProperty getPropertyAt(int index)
340 	{
341 		return params.getPropertyAt(index);
342 	}
343 
344 	public int getPropertyCount()
345 	{
346 		return params.getPropertyCount();
347 	}
348 
349 	public String[] getPropertyNames()
350 	{
351 		return params.getPropertyNames();
352 	}
353 
354 	public String getPropertyValue(String name)
355 	{
356 		return params.getPropertyValue(name);
357 	}
358 
359 	public boolean hasProperty(String name)
360 	{
361 		return params.hasProperty(name);
362 	}
363 
364 	public void removeTestPropertyListener(TestPropertyListener listener)
365 	{
366 		params.removeTestPropertyListener(listener);
367 	}
368 
369 	public void setPropertyValue(String name, String value)
370 	{
371 		params.setPropertyValue(name, value);
372 	}
373 
374 	public String getPropertiesLabel()
375 	{
376 		return "Resource Params";
377 	}
378 
379 	public String buildPath(PropertyExpansionContext context)
380 	{
381 		return getFullPath( true );
382 	}
383 
384 	public void removeRequest(RestRequest request)
385 	{
386       int ix = requests.indexOf(request);
387 		requests.remove(ix);
388 
389 		try
390 		{
391 			(getInterface()).fireRequestRemoved(request);
392 		}
393 		finally
394 		{
395 			request.release();
396 			getConfig().removeRequest(ix);
397 		}
398 	}
399 	
400 	public RestRequest cloneRequest( RestRequest request, String name )
401 	{
402 		RestMethodConfig requestConfig = (RestMethodConfig) getConfig().addNewRequest().set(request.getConfig());
403 		requestConfig.setName(name);
404 		
405 		RestRequest newRequest = new RestRequest( this, requestConfig, false);
406 		requests.add( newRequest );
407 		
408 		getInterface().fireRequestAdded(newRequest);
409 		return newRequest;
410 	}
411 
412    public RestResource cloneChildResource( RestResource resource, String name )
413    {
414       return cloneResource( resource, name );
415    }
416 
417    public RestResource cloneResource(RestResource resource, String name)
418 	{
419 		RestResourceConfig resourceConfig = (RestResourceConfig) getConfig().addNewResource().set(resource.getConfig());
420 		resourceConfig.setName(name);
421 		
422 		RestResource newResource = new RestResource( this, resourceConfig);
423 		resources.add( newResource );
424 		
425 		getInterface().fireOperationAdded( newResource );
426 		return newResource;
427 	}
428 
429 	@Override
430 	public void release()
431 	{
432 		super.release();
433 		params.release();
434       getService().removePropertyChangeListener( this );
435       if( parentResource != null )
436          parentResource.removePropertyChangeListener( this );
437 
438       for( RestResource resource : resources )
439 		{
440 			resource.release();
441 		}
442 		
443 		for( RestRequest request : requests )
444 		{
445 			request.release();
446 		}
447 	}
448 
449    public void deleteChildResource( RestResource resource )
450    {
451       deleteResource( resource );
452    }
453 
454    public void deleteResource(RestResource resource)
455 	{
456       int ix = resources.indexOf( resource );
457 		if( !resources.remove(resource))
458 			return;
459 
460 		getInterface().fireOperationRemoved(resource);
461 
462       notifyPropertyChanged( "childResources", resource, null );
463 
464       getConfig().removeResource( ix );
465 		resource.release();
466 	}
467 
468 	public String createRequest(boolean b)
469 	{
470 		return null;
471 	}
472 
473 	public String createResponse(boolean b)
474 	{
475 		return null;
476 	}
477 
478 	public RestResource getChildResourceAt(int c)
479 	{
480 		return resources.get( c );
481 	}
482 
483    public RestService getService()
484    {
485       return (RestService) (getParentResource() == null ? getParent() : getParentResource().getService());
486    }
487 
488    public void propertyChange( PropertyChangeEvent evt )
489    {
490       if( evt.getPropertyName().equals( "path" ) || evt.getPropertyName().equals( "basePath" ))
491       {
492          notifyPropertyChanged( "path", null, getPath() );
493       }
494    }
495 
496    public RestResource[] getAllChildResources()
497    {
498      List<RestResource> result = new ArrayList<RestResource>();
499       for( RestResource resource : resources )
500       {
501          addResourcesToResult( resource, result );
502       }
503 
504       return result.toArray( new RestResource[result.size()] );
505    }
506 
507    private void addResourcesToResult( RestResource resource, List<RestResource> result )
508    {
509       result.add( resource );
510 
511       for( RestResource res : resource.getChildResourceList() )
512       {
513          addResourcesToResult( res, result );
514       }
515    }
516 
517    public Map<String, RestRequest> getRequests()
518    {
519       Map<String,RestRequest> result = new HashMap<String,RestRequest>();
520 
521       for( RestRequest request : requests )
522       {
523          result.put( request.getName(), request );
524       }
525 
526       return result;
527    }
528 }