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