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