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.net.MalformedURLException;
17 import java.net.URL;
18 import java.util.ArrayList;
19 import java.util.List;
20 import java.util.Map;
21
22 import javax.xml.namespace.QName;
23
24 import org.apache.xmlbeans.SchemaGlobalElement;
25 import org.apache.xmlbeans.SchemaType;
26 import org.apache.xmlbeans.XmlException;
27 import org.apache.xmlbeans.XmlString;
28
29 import com.eviware.soapui.config.AttachmentConfig;
30 import com.eviware.soapui.config.RestRequestConfig;
31 import com.eviware.soapui.config.StringToStringMapConfig;
32 import com.eviware.soapui.impl.rest.RestRepresentation.Type;
33 import com.eviware.soapui.impl.rest.support.RestParamProperty;
34 import com.eviware.soapui.impl.rest.support.RestParamsPropertyHolder;
35 import com.eviware.soapui.impl.rest.support.RestRequestParamsPropertyHolder;
36 import com.eviware.soapui.impl.support.AbstractHttpRequest;
37 import com.eviware.soapui.impl.wsdl.HttpAttachmentPart;
38 import com.eviware.soapui.impl.wsdl.WsdlSubmit;
39 import com.eviware.soapui.impl.wsdl.submit.RequestTransportRegistry;
40 import com.eviware.soapui.impl.wsdl.submit.transports.http.HttpResponse;
41 import com.eviware.soapui.impl.wsdl.support.PathUtils;
42 import com.eviware.soapui.model.ModelItem;
43 import com.eviware.soapui.model.iface.MessagePart;
44 import com.eviware.soapui.model.iface.SubmitContext;
45 import com.eviware.soapui.model.iface.MessagePart.ContentPart;
46 import com.eviware.soapui.model.propertyexpansion.PropertyExpander;
47 import com.eviware.soapui.model.propertyexpansion.PropertyExpansion;
48 import com.eviware.soapui.model.propertyexpansion.PropertyExpansionsResult;
49 import com.eviware.soapui.model.testsuite.TestProperty;
50 import com.eviware.soapui.model.testsuite.TestPropertyListener;
51 import com.eviware.soapui.support.StringUtils;
52 import com.eviware.soapui.support.UISupport;
53 import com.eviware.soapui.support.types.StringList;
54 import com.eviware.soapui.support.types.StringToStringMap;
55
56 /***
57 * Request implementation holding a SOAP request
58 *
59 * @author Ole.Matzura
60 */
61
62 public class RestRequest extends AbstractHttpRequest<RestRequestConfig> implements RestRequestInterface
63 {
64 private RestMethod method;
65 private RestParamsPropertyHolder params;
66 private ParamUpdater paramUpdater;
67
68 public RestRequest( RestMethod method, RestRequestConfig requestConfig, boolean forLoadTest )
69 {
70 super( requestConfig, method.getOperation(), "/rest_request.gif", false );
71 this.method = method;
72
73 if( requestConfig.getParameters() == null )
74 requestConfig.addNewParameters();
75
76 StringToStringMap paramValues = StringToStringMap.fromXml( requestConfig.getParameters() );
77 params = new RestRequestParamsPropertyHolder( method.getOverlayParams(), this, paramValues );
78 paramUpdater = new ParamUpdater( paramValues );
79 params.addTestPropertyListener( paramUpdater );
80
81 if( method != null )
82 method.addPropertyChangeListener( this );
83 }
84
85 public ModelItem getParent()
86 {
87 return getRestMethod();
88 }
89
90 public RestMethod getRestMethod()
91 {
92 return method;
93 }
94
95 protected RequestIconAnimator<?> initIconAnimator()
96 {
97 return new RequestIconAnimator<AbstractHttpRequest<?>>( this, "/rest_request.gif", "/exec_rest_request", 4, "gif" );
98 }
99
100 public MessagePart[] getRequestParts()
101 {
102 List<MessagePart> result = new ArrayList<MessagePart>();
103
104 for( int c = 0; c < getPropertyCount(); c++ )
105 {
106 result.add( new ParameterMessagePart( getPropertyAt( c ) ) );
107 }
108
109 if( getMethod() == RestRequestInterface.RequestMethod.POST
110 || getMethod() == RestRequestInterface.RequestMethod.PUT )
111 {
112 result.add( new RestContentPart() );
113 }
114
115 return result.toArray( new MessagePart[result.size()] );
116 }
117
118 public RestRepresentation[] getRepresentations()
119 {
120 return getRepresentations( null, null );
121 }
122
123 public RestRepresentation[] getRepresentations( RestRepresentation.Type type )
124 {
125 return getRepresentations( type, null );
126 }
127
128 public RestRepresentation[] getRepresentations( RestRepresentation.Type type, String mediaType )
129 {
130 return getRestMethod().getRepresentations( type, mediaType );
131 }
132
133 public MessagePart[] getResponseParts()
134 {
135 return new MessagePart[0];
136 }
137
138 public RestRequestInterface.RequestMethod getMethod()
139 {
140 return getRestMethod().getMethod();
141 }
142
143 public String getAccept()
144 {
145 String accept = getConfig().getAccept();
146 return accept == null ? "" : accept;
147 }
148
149 public void setAccept( String acceptEncoding )
150 {
151 String old = getAccept();
152 getConfig().setAccept( acceptEncoding );
153 notifyPropertyChanged( "accept", old, acceptEncoding );
154 }
155
156 public void setMediaType( String mediaType )
157 {
158 String old = getMediaType();
159 getConfig().setMediaType( mediaType );
160 notifyPropertyChanged( "mediaType", old, mediaType );
161 }
162
163 public String getMediaType()
164 {
165 if( getConfig().getMediaType() == null )
166 {
167 String mediaType = getRestMethod().getDefaultRequestMediaType();
168 getConfig().setMediaType( mediaType );
169 notifyPropertyChanged( "mediaType", null, mediaType );
170 }
171 return getConfig().getMediaType();
172 }
173
174 public void setMethod( RequestMethod method )
175 {
176 getRestMethod().setMethod( method );
177 }
178
179 public WsdlSubmit<RestRequest> submit( SubmitContext submitContext, boolean async ) throws SubmitException
180 {
181 String endpoint = PropertyExpander.expandProperties( submitContext, getEndpoint() );
182
183 if( StringUtils.isNullOrEmpty( endpoint ) )
184 {
185 try
186 {
187 endpoint = new URL( getPath() ).toString();
188 }
189 catch( MalformedURLException e )
190 {
191 }
192 }
193
194 if( StringUtils.isNullOrEmpty( endpoint ) )
195 {
196 UISupport.showErrorMessage( "Missing endpoint for request [" + getName() + "]" );
197 return null;
198 }
199
200 try
201 {
202 WsdlSubmit<RestRequest> submitter = new WsdlSubmit<RestRequest>( this, getSubmitListeners(),
203 RequestTransportRegistry.getTransport( endpoint, submitContext ) );
204 submitter.submitRequest( submitContext, async );
205 return submitter;
206 }
207 catch( Exception e )
208 {
209 throw new SubmitException( e.toString() );
210 }
211 }
212
213 public PropertyExpansion[] getPropertyExpansions()
214 {
215 PropertyExpansionsResult result = new PropertyExpansionsResult( this, this );
216 result.addAll( super.getPropertyExpansions() );
217 result.addAll( getRestMethod().getPropertyExpansions() );
218
219 return result.toArray();
220 }
221
222 public TestProperty addProperty( String name )
223 {
224 return params.addProperty( name );
225 }
226
227 public void moveProperty( String propertyName, int targetIndex )
228 {
229 params.moveProperty( propertyName, targetIndex );
230 }
231
232 public TestProperty removeProperty( String propertyName )
233 {
234 return params.removeProperty( propertyName );
235 }
236
237 public boolean renameProperty( String name, String newName )
238 {
239 return params.renameProperty( name, newName );
240 }
241
242 public void addTestPropertyListener( TestPropertyListener listener )
243 {
244 params.addTestPropertyListener( listener );
245 }
246
247 public ModelItem getModelItem()
248 {
249 return this;
250 }
251
252 @Override
253 public RestResource getOperation()
254 {
255 return ( RestResource )method.getOperation();
256 }
257
258 public Map<String, TestProperty> getProperties()
259 {
260 return params.getProperties();
261 }
262
263 public RestParamProperty getProperty( String name )
264 {
265 return params.getProperty( name );
266 }
267
268 public RestParamProperty getPropertyAt( int index )
269 {
270 return params.getPropertyAt( index );
271 }
272
273 public int getPropertyCount()
274 {
275 return params.getPropertyCount();
276 }
277
278 public String[] getPropertyNames()
279 {
280 return params.getPropertyNames();
281 }
282
283 public String getPropertyValue( String name )
284 {
285 return params.getPropertyValue( name );
286 }
287
288 public boolean hasProperty( String name )
289 {
290 return params.hasProperty( name );
291 }
292
293 public void removeTestPropertyListener( TestPropertyListener listener )
294 {
295 params.removeTestPropertyListener( listener );
296 }
297
298 public void setPropertyValue( String name, String value )
299 {
300 params.setPropertyValue( name, value );
301 }
302
303 public void resetPropertyValues()
304 {
305 params.clear();
306 for( String name : params.getPropertyNames() )
307 {
308 params.getProperty( name ).setValue( params.getProperty( name ).getDefaultValue() );
309 }
310 }
311
312 public void propertyChange( PropertyChangeEvent evt )
313 {
314 if( evt.getPropertyName().equals( "path" ) )
315 {
316 notifyPropertyChanged( "path", null, getPath() );
317 }
318 else if( evt.getPropertyName().equals( "method" ) )
319 {
320 notifyPropertyChanged( "method", evt.getOldValue(), evt.getNewValue() );
321 }
322 }
323
324 public String[] getResponseMediaTypes()
325 {
326 StringList result = new StringList();
327
328 for( RestRepresentation representation : getRepresentations( Type.RESPONSE, null ) )
329 {
330 if( !result.contains( representation.getMediaType() ) )
331 result.add( representation.getMediaType() );
332 }
333
334 return result.toStringArray();
335 }
336
337 public boolean isPostQueryString()
338 {
339 return hasRequestBody() && getConfig().getPostQueryString();
340 }
341
342 public void setPostQueryString( boolean b )
343 {
344 boolean old = isPostQueryString();
345 getConfig().setPostQueryString( b );
346 notifyPropertyChanged( "postQueryString", old, b );
347
348 if( !"multipart/form-data".equals( getMediaType() ) )
349 {
350 setMediaType( b ? "application/x-www-form-urlencoded" : getMediaType() );
351 }
352 }
353
354 public final static class ParameterMessagePart extends MessagePart.ParameterPart
355 {
356 private String name;
357
358 public ParameterMessagePart( TestProperty propertyAt )
359 {
360 this.name = propertyAt.getName();
361 }
362
363 @Override
364 public SchemaType getSchemaType()
365 {
366 return XmlString.type;
367 }
368
369 @Override
370 public SchemaGlobalElement getPartElement()
371 {
372 return null;
373 }
374
375 @Override
376 public QName getPartElementName()
377 {
378 return new QName( getName() );
379 }
380
381 public String getDescription()
382 {
383 return null;
384 }
385
386 public String getName()
387 {
388 return name;
389 }
390 }
391
392 public String getPropertiesLabel()
393 {
394 return "Request Params";
395 }
396
397 public RestParamsPropertyHolder getParams()
398 {
399 return params;
400 }
401
402 public HttpAttachmentPart getAttachmentPart( String partName )
403 {
404 return null;
405 }
406
407 public HttpAttachmentPart[] getDefinedAttachmentParts()
408 {
409 return new HttpAttachmentPart[0];
410 }
411
412 public class RestContentPart extends ContentPart implements MessagePart
413 {
414 @Override
415 public SchemaGlobalElement getPartElement()
416 {
417 return null;
418 }
419
420 @Override
421 public QName getPartElementName()
422 {
423 return null;
424 }
425
426 @Override
427 public SchemaType getSchemaType()
428 {
429 return null;
430 }
431
432 public String getDescription()
433 {
434 return null;
435 }
436
437 public String getName()
438 {
439 return null;
440 }
441
442 public String getMediaType()
443 {
444 return getConfig().getMediaType();
445 }
446 }
447
448 public boolean hasRequestBody()
449 {
450 return getRestMethod().hasRequestBody();
451 }
452
453 public RestResource getResource()
454 {
455 return getOperation();
456 }
457
458 public String getPath()
459 {
460 if( !StringUtils.isNullOrEmpty( getConfig().getFullPath() ) || getResource() == null )
461 return getConfig().getFullPath();
462 else
463 return getResource().getFullPath();
464 }
465
466 public void setPath( String fullPath )
467 {
468 String old = getPath();
469
470 if( getResource() != null && getResource().getFullPath().equals( fullPath ) )
471 getConfig().unsetFullPath();
472 else
473 getConfig().setFullPath( fullPath );
474
475 notifyPropertyChanged( "path", old, fullPath );
476 }
477
478 public String getResponseContentAsXml()
479 {
480 HttpResponse response = getResponse();
481 if( response == null )
482 return null;
483
484 return response.getContentAsXml();
485 }
486
487 @Override
488 public void release()
489 {
490 super.release();
491
492 if( getResource() != null )
493 getResource().removePropertyChangeListener( this );
494
495
496 }
497
498 public void updateConfig( RestRequestConfig request )
499 {
500 setConfig( request );
501
502 updateParams();
503
504 List<AttachmentConfig> attachmentConfigs = getConfig().getAttachmentList();
505 for( int i = 0; i < attachmentConfigs.size(); i++ )
506 {
507 AttachmentConfig config = attachmentConfigs.get( i );
508 getAttachmentsList().get( i ).updateConfig( config );
509 }
510 }
511
512 protected void updateParams()
513 {
514 if( params != null && paramUpdater != null )
515 params.removeTestPropertyListener( paramUpdater );
516
517 StringToStringMap paramValues = StringToStringMap.fromXml( getConfig().getParameters() );
518 params = new RestRequestParamsPropertyHolder( getRestMethod().getOverlayParams(), this, paramValues );
519 paramUpdater = new ParamUpdater( paramValues );
520 params.addTestPropertyListener( paramUpdater );
521 }
522
523 public boolean hasEndpoint()
524 {
525 return super.hasEndpoint() || PathUtils.isHttpPath( getPath() );
526 }
527
528 private class ParamUpdater implements TestPropertyListener
529 {
530 private StringToStringMap values;
531
532 public ParamUpdater( StringToStringMap paramValues )
533 {
534 values = paramValues;
535 }
536
537 private void sync()
538 {
539 try
540 {
541 getConfig().setParameters( StringToStringMapConfig.Factory.parse( values.toXml() ) );
542 }
543 catch( XmlException e )
544 {
545 e.printStackTrace();
546 }
547 }
548
549 public void propertyAdded( String name )
550 {
551 sync();
552 }
553
554 public void propertyMoved( String name, int oldIndex, int newIndex )
555 {
556 sync();
557 }
558
559 public void propertyRemoved( String name )
560 {
561 sync();
562 }
563
564 public void propertyRenamed( String oldName, String newName )
565 {
566 sync();
567 }
568
569 public void propertyValueChanged( String name, String oldValue, String newValue )
570 {
571 sync();
572 }
573 }
574
575 public List<TestProperty> getPropertyList()
576 {
577 return params.getPropertyList();
578 }
579
580 protected void setRestMethod( RestMethod restMethod )
581 {
582 if( this.method != null )
583 this.method.removePropertyChangeListener( this );
584
585 this.method = restMethod;
586
587 if( method != null )
588 method.addPropertyChangeListener( this );
589
590 updateParams();
591 }
592 }