1
2
3
4
5
6
7
8
9
10
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 }