1
2
3
4
5
6
7
8
9
10
11
12
13 package com.eviware.soapui.impl.wsdl.mock;
14
15 import java.beans.PropertyChangeListener;
16 import java.io.ByteArrayOutputStream;
17 import java.io.File;
18 import java.io.IOException;
19 import java.io.StringWriter;
20 import java.util.ArrayList;
21 import java.util.Arrays;
22 import java.util.List;
23 import java.util.Map;
24
25 import javax.activation.DataHandler;
26 import javax.mail.MessagingException;
27 import javax.mail.internet.MimeBodyPart;
28 import javax.mail.internet.MimeMessage;
29 import javax.mail.internet.MimeMultipart;
30 import javax.mail.internet.PreencodedMimeBodyPart;
31 import javax.servlet.http.HttpServletResponse;
32 import javax.swing.ImageIcon;
33 import javax.wsdl.BindingOperation;
34 import javax.wsdl.BindingOutput;
35 import javax.wsdl.Message;
36
37 import org.apache.log4j.Logger;
38 import org.apache.xmlbeans.SchemaGlobalElement;
39 import org.apache.xmlbeans.SchemaType;
40 import org.w3c.dom.Document;
41
42 import com.eviware.soapui.SoapUI;
43 import com.eviware.soapui.config.AttachmentConfig;
44 import com.eviware.soapui.config.HeaderConfig;
45 import com.eviware.soapui.config.MockResponseConfig;
46 import com.eviware.soapui.impl.wsdl.AbstractWsdlModelItem;
47 import com.eviware.soapui.impl.wsdl.HttpAttachmentPart;
48 import com.eviware.soapui.impl.wsdl.MutableWsdlAttachmentContainer;
49 import com.eviware.soapui.impl.wsdl.WsdlContentPart;
50 import com.eviware.soapui.impl.wsdl.WsdlHeaderPart;
51 import com.eviware.soapui.impl.wsdl.WsdlOperation;
52 import com.eviware.soapui.impl.wsdl.submit.filters.RemoveEmptyContentRequestFilter;
53 import com.eviware.soapui.impl.wsdl.submit.transports.http.support.attachments.AttachmentUtils;
54 import com.eviware.soapui.impl.wsdl.submit.transports.http.support.attachments.BodyPartAttachment;
55 import com.eviware.soapui.impl.wsdl.submit.transports.http.support.attachments.MimeMessageMockResponseEntity;
56 import com.eviware.soapui.impl.wsdl.submit.transports.http.support.attachments.MockResponseDataSource;
57 import com.eviware.soapui.impl.wsdl.support.CompressedStringSupport;
58 import com.eviware.soapui.impl.wsdl.support.CompressionSupport;
59 import com.eviware.soapui.impl.wsdl.support.FileAttachment;
60 import com.eviware.soapui.impl.wsdl.support.MapTestPropertyHolder;
61 import com.eviware.soapui.impl.wsdl.support.MessageXmlObject;
62 import com.eviware.soapui.impl.wsdl.support.MessageXmlPart;
63 import com.eviware.soapui.impl.wsdl.support.MockFileAttachment;
64 import com.eviware.soapui.impl.wsdl.support.ModelItemIconAnimator;
65 import com.eviware.soapui.impl.wsdl.support.WsdlAttachment;
66 import com.eviware.soapui.impl.wsdl.support.soap.SoapUtils;
67 import com.eviware.soapui.impl.wsdl.support.soap.SoapVersion;
68 import com.eviware.soapui.impl.wsdl.support.wsa.WsaConfig;
69 import com.eviware.soapui.impl.wsdl.support.wsa.WsaContainer;
70 import com.eviware.soapui.impl.wsdl.support.wsa.WsaUtils;
71 import com.eviware.soapui.impl.wsdl.support.wsdl.WsdlContext;
72 import com.eviware.soapui.impl.wsdl.support.wsdl.WsdlUtils;
73 import com.eviware.soapui.impl.wsdl.support.wsdl.WsdlUtils.SoapHeader;
74 import com.eviware.soapui.impl.wsdl.support.wss.OutgoingWss;
75 import com.eviware.soapui.model.ModelItem;
76 import com.eviware.soapui.model.TestPropertyHolder;
77 import com.eviware.soapui.model.iface.Attachment;
78 import com.eviware.soapui.model.iface.MessagePart;
79 import com.eviware.soapui.model.iface.Attachment.AttachmentEncoding;
80 import com.eviware.soapui.model.mock.MockResponse;
81 import com.eviware.soapui.model.mock.MockRunContext;
82 import com.eviware.soapui.model.propertyexpansion.PropertyExpander;
83 import com.eviware.soapui.model.propertyexpansion.PropertyExpansion;
84 import com.eviware.soapui.model.propertyexpansion.PropertyExpansionContainer;
85 import com.eviware.soapui.model.propertyexpansion.PropertyExpansionUtils;
86 import com.eviware.soapui.model.testsuite.TestProperty;
87 import com.eviware.soapui.model.testsuite.TestPropertyListener;
88 import com.eviware.soapui.settings.CommonSettings;
89 import com.eviware.soapui.settings.WsdlSettings;
90 import com.eviware.soapui.support.StringUtils;
91 import com.eviware.soapui.support.Tools;
92 import com.eviware.soapui.support.UISupport;
93 import com.eviware.soapui.support.scripting.ScriptEnginePool;
94 import com.eviware.soapui.support.scripting.SoapUIScriptEngine;
95 import com.eviware.soapui.support.types.StringToStringMap;
96 import com.eviware.soapui.support.xml.XmlUtils;
97
98 /***
99 * A WsdlMockResponse contained by a WsdlMockOperation
100 *
101 * @author ole.matzura
102 */
103
104 public class WsdlMockResponse extends AbstractWsdlModelItem<MockResponseConfig> implements MockResponse,
105 MutableWsdlAttachmentContainer, PropertyExpansionContainer, TestPropertyHolder, WsaContainer
106 {
107 public static final String AUTO_RESPONSE_COMPRESSION = "<auto>";
108 public static final String NO_RESPONSE_COMPRESSION = "<none>";
109
110 private final static Logger log = Logger.getLogger( WsdlMockResponse.class );
111
112 public final static String MOCKRESULT_PROPERTY = WsdlMockResponse.class.getName() + "@mockresult";
113 public final static String SCRIPT_PROPERTY = WsdlMockResponse.class.getName() + "@script";
114 public final static String HEADERS_PROPERTY = WsdlMockResponse.class.getName() + "@headers";
115 public final static String DISABLE_MULTIPART_ATTACHMENTS = WsdlMockResponse.class.getName()
116 + "@disable-multipart-attachments";
117 public static final String FORCE_MTOM = WsdlMockResponse.class.getName() + "@force_mtom";
118 public static final String ENABLE_INLINE_FILES = WsdlMockResponse.class.getName() + "@enable_inline_files";
119 public final static String RESPONSE_DELAY_PROPERTY = WsdlMockResponse.class.getName() + "@response-delay";
120 public static final String STRIP_WHITESPACES = WsdlMockResponse.class.getName() + "@strip-whitespaces";
121 public static final String REMOVE_EMPTY_CONTENT = WsdlMockResponse.class.getName() + "@remove_empty_content";
122 public static final String ENCODE_ATTACHMENTS = WsdlMockResponse.class.getName() + "@encode_attachments";
123 public static final String RESPONSE_HTTP_STATUS = WsdlMockResponse.class.getName() + "@response-http-status";
124 public static final String OUGOING_WSS = WsdlMockResponse.class.getName() + "@outgoing-wss";
125
126 protected List<FileAttachment<WsdlMockResponse>> attachments = new ArrayList<FileAttachment<WsdlMockResponse>>();
127 private List<HttpAttachmentPart> definedAttachmentParts;
128 private ModelItemIconAnimator<WsdlMockResponse> iconAnimator;
129 private WsdlMockResult mockResult;
130 private String responseContent;
131 private ScriptEnginePool scriptEnginePool;
132 private MapTestPropertyHolder propertyHolder;
133 private WsaConfig wsaConfig;
134
135 public WsdlMockResponse( WsdlMockOperation operation, MockResponseConfig config )
136 {
137 super( config, operation, "/mockResponse.gif" );
138
139 for( AttachmentConfig ac : getConfig().getAttachmentList() )
140 {
141 attachments.add( new MockFileAttachment( ac, this ) );
142 }
143
144 if( !config.isSetEncoding() )
145 config.setEncoding( "UTF-8" );
146
147 iconAnimator = new ModelItemIconAnimator<WsdlMockResponse>( this, "/mockResponse.gif", "/exec_request", 4, "gif" );
148
149 scriptEnginePool = new ScriptEnginePool( this );
150 scriptEnginePool.setScript( getScript() );
151
152 propertyHolder = new MapTestPropertyHolder( this );
153 propertyHolder.addProperty( "Request" );
154 }
155
156 @Override
157 public void setConfig( MockResponseConfig config )
158 {
159 super.setConfig( config );
160
161 if( wsaConfig != null )
162 {
163 if( config.isSetWsaConfig() )
164 wsaConfig.setConfig( config.getWsaConfig() );
165 else
166 wsaConfig = null;
167 }
168
169 if( scriptEnginePool != null )
170 scriptEnginePool.setScript( getScript() );
171 }
172
173 public Attachment[] getAttachments()
174 {
175 return attachments.toArray( new Attachment[attachments.size()] );
176 }
177
178 public String getScript()
179 {
180 return getConfig().isSetScript() ? getConfig().getScript().getStringValue() : null;
181 }
182
183 public String getEncoding()
184 {
185 return getConfig().getEncoding();
186 }
187
188 public void setEncoding( String encoding )
189 {
190 String old = getEncoding();
191 getConfig().setEncoding( encoding );
192 notifyPropertyChanged( ENCODING_PROPERTY, old, encoding );
193 }
194
195 public String getResponseContent()
196 {
197 if( getConfig().getResponseContent() == null )
198 getConfig().addNewResponseContent();
199
200 if( responseContent == null )
201 responseContent = CompressedStringSupport.getString( getConfig().getResponseContent() );
202
203 return responseContent;
204 }
205
206 public void setResponseContent( String responseContent )
207 {
208 String oldContent = getResponseContent();
209 if( responseContent.equals( oldContent ) )
210 return;
211
212 this.responseContent = responseContent;
213 notifyPropertyChanged( RESPONSE_CONTENT_PROPERTY, oldContent, responseContent );
214 }
215
216 public void setResponseCompression( String compression )
217 {
218 if( CompressionSupport.ALG_DEFLATE.equals( compression ) || CompressionSupport.ALG_GZIP.equals( compression )
219 || NO_RESPONSE_COMPRESSION.equals( compression ) )
220 {
221 getConfig().setCompression( compression );
222 }
223 else if( getConfig().isSetCompression() )
224 {
225 getConfig().unsetCompression();
226 }
227 }
228
229 public String getResponseCompression()
230 {
231 if( getConfig().isSetCompression() )
232 return getConfig().getCompression();
233 else
234 return AUTO_RESPONSE_COMPRESSION;
235 }
236
237 @Override
238 public ImageIcon getIcon()
239 {
240 return iconAnimator.getIcon();
241 }
242
243 public WsdlMockOperation getMockOperation()
244 {
245 return ( WsdlMockOperation )getParent();
246 }
247
248 public WsdlMockResult execute( WsdlMockRequest request, WsdlMockResult result ) throws DispatchException
249 {
250 try
251 {
252 iconAnimator.start();
253
254 getProperty( "Request" ).setValue( request.getRequestContent() );
255
256 long delay = getResponseDelay();
257 if( delay > 0 )
258 Thread.sleep( delay );
259
260 String script = getScript();
261 if( script != null && script.trim().length() > 0 )
262 {
263 evaluateScript( request );
264 }
265
266 String responseContent = getResponseContent();
267
268
269 WsdlMockRunContext context = new WsdlMockRunContext( request.getContext().getMockService(), null );
270 context.setMockResponse( this );
271 context.putAll( request.getContext() );
272 context.putAll( request.getRequestContext() );
273
274 StringToStringMap responseHeaders = getResponseHeaders();
275 for( String name : responseHeaders.keySet() )
276 {
277 result.addHeader( name, PropertyExpander.expandProperties( context, responseHeaders.get( name ) ) );
278 }
279
280 responseContent = PropertyExpander.expandProperties( context, responseContent, isEntitizeProperties() );
281
282 if( this.getWsaConfig().isWsaEnabled() )
283 {
284 responseContent = new WsaUtils( responseContent, getSoapVersion(), getMockOperation().getOperation(),
285 context ).addWSAddressingMockResponse( this, request );
286 }
287
288 String outgoingWss = getOutgoingWss();
289 if( StringUtils.isNullOrEmpty( outgoingWss ) )
290 outgoingWss = getMockOperation().getMockService().getOutgoingWss();
291
292 if( StringUtils.hasContent( outgoingWss ) )
293 {
294 OutgoingWss outgoing = getMockOperation().getMockService().getProject().getWssContainer()
295 .getOutgoingWssByName( outgoingWss );
296 if( outgoing != null )
297 {
298 Document dom = XmlUtils.parseXml( responseContent );
299 outgoing.processOutgoing( dom, context );
300 StringWriter writer = new StringWriter();
301 XmlUtils.serialize( dom, writer );
302 responseContent = writer.toString();
303 }
304 }
305
306 if( !result.isCommitted() )
307 {
308 responseContent = writeResponse( result, responseContent );
309 }
310
311 result.setResponseContent( responseContent );
312
313 setMockResult( result );
314
315 return mockResult;
316 }
317 catch( Throwable e )
318 {
319 SoapUI.logError( e );
320 throw new DispatchException( e );
321 }
322 finally
323 {
324 iconAnimator.stop();
325 }
326 }
327
328 public void evaluateScript( WsdlMockRequest request ) throws Exception
329 {
330 String script = getScript();
331 if( script == null || script.trim().length() == 0 )
332 return;
333
334 WsdlMockService mockService = getMockOperation().getMockService();
335 WsdlMockRunner mockRunner = mockService.getMockRunner();
336 MockRunContext context = mockRunner == null ? new WsdlMockRunContext( mockService, null ) : mockRunner
337 .getMockContext();
338
339 SoapUIScriptEngine scriptEngine = scriptEnginePool.getScriptEngine();
340
341 try
342 {
343 scriptEngine.setVariable( "context", context );
344 scriptEngine.setVariable( "requestContext", request == null ? null : request.getRequestContext() );
345 scriptEngine.setVariable( "mockContext", context );
346 scriptEngine.setVariable( "mockRequest", request );
347 scriptEngine.setVariable( "mockResponse", this );
348 scriptEngine.setVariable( "log", SoapUI.ensureGroovyLog() );
349
350 scriptEngine.run();
351 }
352 catch( RuntimeException e )
353 {
354 throw new Exception( e.getMessage(), e );
355 }
356 finally
357 {
358 scriptEnginePool.returnScriptEngine( scriptEngine );
359 }
360 }
361
362 @Override
363 public void release()
364 {
365 super.release();
366 scriptEnginePool.release();
367 }
368
369 public void setScript( String script )
370 {
371 String oldScript = getScript();
372 if( !script.equals( oldScript ) )
373 {
374 if( !getConfig().isSetScript() )
375 getConfig().addNewScript();
376 getConfig().getScript().setStringValue( script );
377
378 scriptEnginePool.setScript( script );
379
380 notifyPropertyChanged( SCRIPT_PROPERTY, oldScript, script );
381 }
382 }
383
384 public void setResponseHeaders( StringToStringMap headers )
385 {
386 StringToStringMap oldHeaders = getResponseHeaders();
387
388 HeaderConfig[] headerConfigs = new HeaderConfig[headers.size()];
389 int ix = 0;
390 for( String header : headers.keySet() )
391 {
392 headerConfigs[ix] = HeaderConfig.Factory.newInstance();
393 headerConfigs[ix].setName( header );
394 headerConfigs[ix].setValue( headers.get( header ) );
395 ix++ ;
396 }
397
398 getConfig().setHeaderArray( headerConfigs );
399
400 notifyPropertyChanged( HEADERS_PROPERTY, oldHeaders, headers );
401 }
402
403 public StringToStringMap getResponseHeaders()
404 {
405 StringToStringMap result = new StringToStringMap();
406 List<HeaderConfig> headerList = getConfig().getHeaderList();
407 for( HeaderConfig header : headerList )
408 {
409 result.put( header.getName(), header.getValue() );
410 }
411
412 return result;
413 }
414
415 public MessagePart[] getRequestParts()
416 {
417 try
418 {
419 List<MessagePart> result = new ArrayList<MessagePart>();
420 result.addAll( Arrays.asList( getMockOperation().getOperation().getDefaultRequestParts() ) );
421
422 if( getMockResult() != null )
423 result.addAll( AttachmentUtils.extractAttachmentParts( getMockOperation().getOperation(), getMockResult()
424 .getMockRequest().getRequestContent(), true, false, isMtomEnabled() ) );
425
426 return result.toArray( new MessagePart[result.size()] );
427 }
428 catch( Exception e )
429 {
430 SoapUI.logError( e );
431 return new MessagePart[0];
432 }
433 }
434
435 public MessagePart[] getResponseParts()
436 {
437 try
438 {
439
440 WsdlOperation op = getMockOperation().getOperation();
441 if( op == null || op.isUnidirectional() )
442 return new MessagePart[0];
443
444 List<MessagePart> result = new ArrayList<MessagePart>();
445 WsdlContext wsdlContext = op.getInterface().getWsdlContext();
446 BindingOperation bindingOperation = op.findBindingOperation( wsdlContext.getDefinition() );
447
448 if( bindingOperation == null )
449 return new MessagePart[0];
450
451
452 BindingOutput bindingOutput = bindingOperation.getBindingOutput();
453 List<SoapHeader> headers = bindingOutput == null ? new ArrayList<SoapHeader>() : WsdlUtils
454 .getSoapHeaders( bindingOutput.getExtensibilityElements() );
455
456 for( int i = 0; i < headers.size(); i++ )
457 {
458 SoapHeader header = headers.get( i );
459
460 Message message = wsdlContext.getDefinition().getMessage( header.getMessage() );
461 if( message == null )
462 {
463 log.error( "Missing message for header: " + header.getMessage() );
464 continue;
465 }
466
467 javax.wsdl.Part part = message.getPart( header.getPart() );
468
469 if( part != null )
470 {
471 SchemaType schemaType = WsdlUtils.getSchemaTypeForPart( wsdlContext, part );
472 SchemaGlobalElement schemaElement = WsdlUtils.getSchemaElementForPart( wsdlContext, part );
473 if( schemaType != null )
474 result.add( new WsdlHeaderPart( part.getName(), schemaType, part.getElementName(), schemaElement ) );
475 }
476 else
477 log.error( "Missing part for header; " + header.getPart() );
478 }
479
480
481 javax.wsdl.Part[] parts = WsdlUtils.getOutputParts( bindingOperation );
482
483 for( int i = 0; i < parts.length; i++ )
484 {
485 javax.wsdl.Part part = parts[i];
486
487 if( !WsdlUtils.isAttachmentOutputPart( part, bindingOperation ) )
488 {
489 SchemaType schemaType = WsdlUtils.getSchemaTypeForPart( wsdlContext, part );
490 SchemaGlobalElement schemaElement = WsdlUtils.getSchemaElementForPart( wsdlContext, part );
491 if( schemaType != null )
492 result.add( new WsdlContentPart( part.getName(), schemaType, part.getElementName(), schemaElement ) );
493 }
494 }
495
496 result.addAll( Arrays.asList( getDefinedAttachmentParts() ) );
497
498 return result.toArray( new MessagePart[result.size()] );
499 }
500 catch( Exception e )
501 {
502 SoapUI.logError( e );
503 return new MessagePart[0];
504 }
505 }
506
507 public Attachment attachFile( File file, boolean cache ) throws IOException
508 {
509 FileAttachment<WsdlMockResponse> fileAttachment = new MockFileAttachment( file, cache, this );
510 attachments.add( fileAttachment );
511 notifyPropertyChanged( ATTACHMENTS_PROPERTY, null, fileAttachment );
512 return fileAttachment;
513 }
514
515 public int getAttachmentCount()
516 {
517 return attachments.size();
518 }
519
520 public WsdlAttachment getAttachmentAt( int index )
521 {
522 return attachments.get( index );
523 }
524
525 public void removeAttachment( Attachment attachment )
526 {
527 int ix = attachments.indexOf( attachment );
528 attachments.remove( ix );
529
530 try
531 {
532 notifyPropertyChanged( ATTACHMENTS_PROPERTY, attachment, null );
533 }
534 finally
535 {
536 getConfig().removeAttachment( ix );
537 }
538 }
539
540 public HttpAttachmentPart[] getDefinedAttachmentParts()
541 {
542 if( definedAttachmentParts == null )
543 {
544 try
545 {
546 WsdlOperation operation = getMockOperation().getOperation();
547 if( operation == null )
548 {
549 definedAttachmentParts = new ArrayList<HttpAttachmentPart>();
550 }
551 else
552 {
553 UISupport.setHourglassCursor();
554 definedAttachmentParts = AttachmentUtils.extractAttachmentParts( operation, getResponseContent(), true,
555 true, isMtomEnabled() );
556 }
557 }
558 catch( Exception e )
559 {
560 log.warn( e.toString() );
561 }
562 finally
563 {
564 UISupport.resetCursor();
565 }
566 }
567
568 return definedAttachmentParts.toArray( new HttpAttachmentPart[definedAttachmentParts.size()] );
569 }
570
571 public HttpAttachmentPart getAttachmentPart( String partName )
572 {
573 HttpAttachmentPart[] parts = getDefinedAttachmentParts();
574 for( HttpAttachmentPart part : parts )
575 {
576 if( part.getName().equals( partName ) )
577 return part;
578 }
579
580 return null;
581 }
582
583 public Attachment[] getAttachmentsForPart( String partName )
584 {
585 List<Attachment> result = new ArrayList<Attachment>();
586
587 for( Attachment attachment : attachments )
588 {
589 if( attachment.getPart().equals( partName ) )
590 result.add( attachment );
591 }
592
593 return result.toArray( new Attachment[result.size()] );
594 }
595
596 public boolean isMtomEnabled()
597 {
598 return getSettings().getBoolean( WsdlSettings.ENABLE_MTOM );
599 }
600
601 public void setMtomEnabled( boolean mtomEnabled )
602 {
603 boolean old = isMtomEnabled();
604 getSettings().setBoolean( WsdlSettings.ENABLE_MTOM, mtomEnabled );
605 definedAttachmentParts = null;
606 notifyPropertyChanged( MTOM_NABLED_PROPERTY, old, mtomEnabled );
607 }
608
609 private String writeResponse( WsdlMockResult response, String responseContent ) throws Exception
610 {
611 MimeMultipart mp = null;
612 WsdlOperation operation = getMockOperation().getOperation();
613 if( operation == null )
614 throw new Exception( "Missing WsdlOperation for mock response" );
615
616 SoapVersion soapVersion = operation.getInterface().getSoapVersion();
617
618 StringToStringMap contentIds = new StringToStringMap();
619 boolean isXOP = isMtomEnabled() && isForceMtom();
620
621
622 if( isMtomEnabled() || isInlineFilesEnabled() || getAttachmentCount() > 0 )
623 {
624 try
625 {
626 mp = new MimeMultipart();
627
628 MessageXmlObject requestXmlObject = new MessageXmlObject( operation, responseContent, false );
629 MessageXmlPart[] requestParts = requestXmlObject.getMessageParts();
630 for( MessageXmlPart requestPart : requestParts )
631 {
632 if( AttachmentUtils.prepareMessagePart( this, mp, requestPart, contentIds ) )
633 isXOP = true;
634 }
635 responseContent = requestXmlObject.getMessageContent();
636 }
637 catch( Exception e )
638 {
639 e.printStackTrace();
640 }
641 }
642
643 if( isRemoveEmptyContent() )
644 {
645 responseContent = RemoveEmptyContentRequestFilter.removeEmptyContent( responseContent, getSoapVersion()
646 .getEnvelopeNamespace() );
647 }
648
649 if( isStripWhitespaces() )
650 {
651 responseContent = XmlUtils.stripWhitespaces( responseContent );
652 }
653
654 String status = getResponseHttpStatus();
655 WsdlMockRequest request = response.getMockRequest();
656
657 if( status == null || status.trim().length() == 0 )
658 {
659 if( SoapUtils.isSoapFault( responseContent, request.getSoapVersion() ) )
660 {
661 request.getHttpResponse().setStatus( HttpServletResponse.SC_INTERNAL_SERVER_ERROR );
662 response.setResponseStatus( HttpServletResponse.SC_INTERNAL_SERVER_ERROR );
663 }
664 else
665 {
666 request.getHttpResponse().setStatus( HttpServletResponse.SC_OK );
667 response.setResponseStatus( HttpServletResponse.SC_OK );
668 }
669 }
670 else
671 {
672 try
673 {
674 int statusCode = Integer.parseInt( status );
675 request.getHttpResponse().setStatus( statusCode );
676 response.setResponseStatus( statusCode );
677 }
678 catch( RuntimeException e )
679 {
680 SoapUI.logError( e );
681 }
682 }
683
684 ByteArrayOutputStream outData = new ByteArrayOutputStream();
685
686
687 String responseCompression = getResponseCompression();
688 if( !isXOP && ( mp == null || mp.getCount() == 0 ) && getAttachmentCount() == 0 )
689 {
690 String encoding = getEncoding();
691 if( responseContent == null )
692 responseContent = "";
693
694 byte[] content = encoding == null ? responseContent.getBytes() : responseContent.getBytes( encoding );
695
696 response.setContentType( soapVersion.getContentTypeHttpHeader( encoding, null ) );
697
698 String acceptEncoding = response.getMockRequest().getRequestHeaders().get( "Accept-Encoding" );
699 if( AUTO_RESPONSE_COMPRESSION.equals( responseCompression ) && acceptEncoding != null
700 && acceptEncoding.toUpperCase().contains( "GZIP" ) )
701 {
702 response.addHeader( "Content-Encoding", "gzip" );
703 outData.write( CompressionSupport.compress( CompressionSupport.ALG_GZIP, content ) );
704 }
705 else if( AUTO_RESPONSE_COMPRESSION.equals( responseCompression ) && acceptEncoding != null
706 && acceptEncoding.toUpperCase().contains( "DEFLATE" ) )
707 {
708 response.addHeader( "Content-Encoding", "deflate" );
709 outData.write( CompressionSupport.compress( CompressionSupport.ALG_DEFLATE, content ) );
710 }
711 else
712 {
713 outData.write( content );
714 }
715 }
716 else
717 {
718
719 if( mp == null )
720 mp = new MimeMultipart();
721
722
723 initRootPart( responseContent, mp, isXOP );
724
725
726 AttachmentUtils.addMimeParts( this, Arrays.asList( getAttachments() ), mp, contentIds );
727
728
729 MimeMessage message = new MimeMessage( AttachmentUtils.JAVAMAIL_SESSION );
730 message.setContent( mp );
731 message.saveChanges();
732 MimeMessageMockResponseEntity mimeMessageRequestEntity = new MimeMessageMockResponseEntity( message, isXOP,
733 this );
734
735 response.addHeader( "Content-Type", mimeMessageRequestEntity.getContentType() );
736 response.addHeader( "MIME-Version", "1.0" );
737 mimeMessageRequestEntity.writeRequest( outData );
738 }
739
740 if( outData.size() > 0 )
741 {
742 byte[] data = outData.toByteArray();
743
744 if( responseCompression.equals( CompressionSupport.ALG_DEFLATE )
745 || responseCompression.equals( CompressionSupport.ALG_GZIP ) )
746 {
747 response.addHeader( "Content-Encoding", responseCompression );
748 data = CompressionSupport.compress( responseCompression, data );
749 }
750
751 response.writeRawResponseData( data );
752 }
753
754 return responseContent;
755 }
756
757 private void initRootPart( String requestContent, MimeMultipart mp, boolean isXOP ) throws MessagingException
758 {
759 MimeBodyPart rootPart = new PreencodedMimeBodyPart( "8bit" );
760 rootPart.setContentID( AttachmentUtils.ROOTPART_SOAPUI_ORG );
761 mp.addBodyPart( rootPart, 0 );
762
763 DataHandler dataHandler = new DataHandler( new MockResponseDataSource( this, requestContent, isXOP ) );
764 rootPart.setDataHandler( dataHandler );
765 }
766
767 @SuppressWarnings( "unchecked" )
768 public Attachment addAttachment( Attachment attachment )
769 {
770 if( attachment instanceof BodyPartAttachment )
771 {
772 try
773 {
774 BodyPartAttachment att = ( BodyPartAttachment )attachment;
775
776 AttachmentConfig newConfig = getConfig().addNewAttachment();
777 newConfig.setData( Tools.readAll( att.getInputStream(), 0 ).toByteArray() );
778 newConfig.setContentId( att.getContentID() );
779 newConfig.setContentType( att.getContentType() );
780 newConfig.setName( att.getName() );
781
782 FileAttachment<WsdlMockResponse> newAttachment = new MockFileAttachment( newConfig, this );
783 attachments.add( newAttachment );
784 return newAttachment;
785 }
786 catch( Exception e )
787 {
788 SoapUI.logError( e );
789 }
790 }
791 else if( attachment instanceof FileAttachment )
792 {
793 AttachmentConfig oldConfig = ( ( FileAttachment<WsdlMockResponse> )attachment ).getConfig();
794 AttachmentConfig newConfig = ( AttachmentConfig )getConfig().addNewAttachment().set( oldConfig );
795 FileAttachment<WsdlMockResponse> newAttachment = new MockFileAttachment( newConfig, this );
796 attachments.add( newAttachment );
797 return newAttachment;
798 }
799
800 return null;
801 }
802
803 public void setResponseDelay( long delay )
804 {
805 long oldDelay = getResponseDelay();
806
807 if( delay == 0 )
808 getSettings().clearSetting( RESPONSE_DELAY_PROPERTY );
809 else
810 getSettings().setLong( RESPONSE_DELAY_PROPERTY, delay );
811
812 notifyPropertyChanged( RESPONSE_DELAY_PROPERTY, oldDelay, delay );
813 }
814
815 public long getResponseDelay()
816 {
817 return getSettings().getLong( RESPONSE_DELAY_PROPERTY, 0 );
818 }
819
820 public void setResponseHttpStatus( String httpStatus )
821 {
822 String oldStatus = getResponseHttpStatus();
823
824 getConfig().setHttpResponseStatus( httpStatus );
825
826 notifyPropertyChanged( RESPONSE_HTTP_STATUS, oldStatus, httpStatus );
827 }
828
829 public String getResponseHttpStatus()
830 {
831 return getConfig().getHttpResponseStatus();
832 }
833
834 public void setMockResult( WsdlMockResult mockResult )
835 {
836 WsdlMockResult oldResult = this.mockResult;
837 this.mockResult = mockResult;
838 notifyPropertyChanged( MOCKRESULT_PROPERTY, oldResult, mockResult );
839 }
840
841 public WsdlMockResult getMockResult()
842 {
843 return mockResult;
844 }
845
846 public long getContentLength()
847 {
848 return getResponseContent() == null ? 0 : getResponseContent().length();
849 }
850
851 public boolean isMultipartEnabled()
852 {
853 return !getSettings().getBoolean( DISABLE_MULTIPART_ATTACHMENTS );
854 }
855
856 public void setMultipartEnabled( boolean multipartEnabled )
857 {
858 getSettings().setBoolean( DISABLE_MULTIPART_ATTACHMENTS, multipartEnabled );
859 }
860
861 public boolean isEntitizeProperties()
862 {
863 return getSettings().getBoolean( CommonSettings.ENTITIZE_PROPERTIES );
864 }
865
866 public void setEntitizeProperties( boolean entitizeProperties )
867 {
868 getSettings().setBoolean( CommonSettings.ENTITIZE_PROPERTIES, entitizeProperties );
869 }
870
871 public boolean isForceMtom()
872 {
873 return getSettings().getBoolean( FORCE_MTOM );
874 }
875
876 public void setForceMtom( boolean forceMtom )
877 {
878 boolean old = getSettings().getBoolean( FORCE_MTOM );
879 getSettings().setBoolean( FORCE_MTOM, forceMtom );
880 notifyPropertyChanged( FORCE_MTOM, old, forceMtom );
881 }
882
883 public boolean isRemoveEmptyContent()
884 {
885 return getSettings().getBoolean( REMOVE_EMPTY_CONTENT );
886 }
887
888 public void setRemoveEmptyContent( boolean removeEmptyContent )
889 {
890 boolean old = getSettings().getBoolean( REMOVE_EMPTY_CONTENT );
891 getSettings().setBoolean( REMOVE_EMPTY_CONTENT, removeEmptyContent );
892 notifyPropertyChanged( REMOVE_EMPTY_CONTENT, old, removeEmptyContent );
893 }
894
895 public boolean isEncodeAttachments()
896 {
897 return getSettings().getBoolean( ENCODE_ATTACHMENTS );
898 }
899
900 public void setEncodeAttachments( boolean encodeAttachments )
901 {
902 boolean old = getSettings().getBoolean( ENCODE_ATTACHMENTS );
903 getSettings().setBoolean( ENCODE_ATTACHMENTS, encodeAttachments );
904 notifyPropertyChanged( ENCODE_ATTACHMENTS, old, encodeAttachments );
905 }
906
907 public boolean isStripWhitespaces()
908 {
909 return getSettings().getBoolean( STRIP_WHITESPACES );
910 }
911
912 public void setStripWhitespaces( boolean stripWhitespaces )
913 {
914 boolean old = getSettings().getBoolean( STRIP_WHITESPACES );
915 getSettings().setBoolean( STRIP_WHITESPACES, stripWhitespaces );
916 notifyPropertyChanged( STRIP_WHITESPACES, old, stripWhitespaces );
917 }
918
919 public boolean isInlineFilesEnabled()
920 {
921 return getSettings().getBoolean( WsdlMockResponse.ENABLE_INLINE_FILES );
922 }
923
924 public void setInlineFilesEnabled( boolean inlineFilesEnabled )
925 {
926 getSettings().setBoolean( WsdlMockResponse.ENABLE_INLINE_FILES, inlineFilesEnabled );
927 }
928
929 @Override
930 public void beforeSave()
931 {
932 super.beforeSave();
933
934 if( responseContent != null )
935 {
936 CompressedStringSupport.setString( getConfig().getResponseContent(), responseContent );
937 }
938 }
939
940 public void addAttachmentsChangeListener( PropertyChangeListener listener )
941 {
942 addPropertyChangeListener( ATTACHMENTS_PROPERTY, listener );
943 }
944
945 public boolean isReadOnly()
946 {
947 return false;
948 }
949
950 public void removeAttachmentsChangeListener( PropertyChangeListener listener )
951 {
952 removePropertyChangeListener( ATTACHMENTS_PROPERTY, listener );
953 }
954
955 public SoapVersion getSoapVersion()
956 {
957 return getMockOperation().getOperation() == null ? SoapVersion.Soap11 : getMockOperation().getOperation()
958 .getInterface().getSoapVersion();
959 }
960
961 public PropertyExpansion[] getPropertyExpansions()
962 {
963 List<PropertyExpansion> result = new ArrayList<PropertyExpansion>();
964
965 result.addAll( PropertyExpansionUtils.extractPropertyExpansions( this, this, "responseContent" ) );
966
967 StringToStringMap responseHeaders = getResponseHeaders();
968 for( String key : responseHeaders.keySet() )
969 {
970 result.addAll( PropertyExpansionUtils.extractPropertyExpansions( this, new ResponseHeaderHolder(
971 responseHeaders, key ), "value" ) );
972 }
973
974 addWsaPropertyExpansions( result, getWsaConfig(), this );
975 return result.toArray( new PropertyExpansion[result.size()] );
976 }
977
978 public void addWsaPropertyExpansions( List<PropertyExpansion> result, WsaConfig wsaConfig, ModelItem modelItem )
979 {
980 result.addAll( PropertyExpansionUtils.extractPropertyExpansions( modelItem, wsaConfig, "action" ) );
981 result.addAll( PropertyExpansionUtils.extractPropertyExpansions( modelItem, wsaConfig, "from" ) );
982 result.addAll( PropertyExpansionUtils.extractPropertyExpansions( modelItem, wsaConfig, "to" ) );
983 result.addAll( PropertyExpansionUtils.extractPropertyExpansions( modelItem, wsaConfig, "replyTo" ) );
984 result.addAll( PropertyExpansionUtils.extractPropertyExpansions( modelItem, wsaConfig, "replyToRefParams" ) );
985 result.addAll( PropertyExpansionUtils.extractPropertyExpansions( modelItem, wsaConfig, "faultTo" ) );
986 result.addAll( PropertyExpansionUtils.extractPropertyExpansions( modelItem, wsaConfig, "faultToRefParams" ) );
987 result.addAll( PropertyExpansionUtils.extractPropertyExpansions( modelItem, wsaConfig, "relatesTo" ) );
988 result.addAll( PropertyExpansionUtils.extractPropertyExpansions( modelItem, wsaConfig, "relationshipType" ) );
989 result.addAll( PropertyExpansionUtils.extractPropertyExpansions( modelItem, wsaConfig, "messageID" ) );
990 }
991
992 public class ResponseHeaderHolder
993 {
994 private final StringToStringMap valueMap;
995 private final String key;
996
997 public ResponseHeaderHolder( StringToStringMap valueMap, String key )
998 {
999 this.valueMap = valueMap;
1000 this.key = key;
1001 }
1002
1003 public String getValue()
1004 {
1005 return valueMap.get( key );
1006 }
1007
1008 public void setValue( String value )
1009 {
1010 valueMap.put( key, value );
1011 setResponseHeaders( valueMap );
1012 }
1013 }
1014
1015 public void addTestPropertyListener( TestPropertyListener listener )
1016 {
1017 propertyHolder.addTestPropertyListener( listener );
1018 }
1019
1020 public ModelItem getModelItem()
1021 {
1022 return propertyHolder.getModelItem();
1023 }
1024
1025 public Map<String, TestProperty> getProperties()
1026 {
1027 return propertyHolder.getProperties();
1028 }
1029
1030 public TestProperty getProperty( String name )
1031 {
1032 return propertyHolder.getProperty( name );
1033 }
1034
1035 public String[] getPropertyNames()
1036 {
1037 return propertyHolder.getPropertyNames();
1038 }
1039
1040 public String getPropertyValue( String name )
1041 {
1042 return propertyHolder.getPropertyValue( name );
1043 }
1044
1045 public boolean hasProperty( String name )
1046 {
1047 return propertyHolder.hasProperty( name );
1048 }
1049
1050 public void removeTestPropertyListener( TestPropertyListener listener )
1051 {
1052 propertyHolder.removeTestPropertyListener( listener );
1053 }
1054
1055 public void setPropertyValue( String name, String value )
1056 {
1057 propertyHolder.setPropertyValue( name, value );
1058 }
1059
1060 public String getOutgoingWss()
1061 {
1062 return getConfig().getOutgoingWss();
1063 }
1064
1065 public void setOutgoingWss( String outgoingWss )
1066 {
1067 String old = getOutgoingWss();
1068 getConfig().setOutgoingWss( outgoingWss );
1069 notifyPropertyChanged( OUGOING_WSS, old, outgoingWss );
1070 }
1071
1072 public TestProperty getPropertyAt( int index )
1073 {
1074 return propertyHolder.getPropertyAt( index );
1075 }
1076
1077 public int getPropertyCount()
1078 {
1079 return propertyHolder.getPropertyCount();
1080 }
1081
1082 public List<TestProperty> getPropertyList()
1083 {
1084 return propertyHolder.getPropertyList();
1085 }
1086
1087 public String getPropertiesLabel()
1088 {
1089 return "Custom Properties";
1090 }
1091
1092 public AttachmentEncoding getAttachmentEncoding( String partName )
1093 {
1094 HttpAttachmentPart attachmentPart = getAttachmentPart( partName );
1095 if( attachmentPart == null )
1096 return AttachmentUtils.getAttachmentEncoding( getOperation(), partName, true );
1097 else
1098 return AttachmentUtils.getAttachmentEncoding( getOperation(), attachmentPart, true );
1099 }
1100
1101 public WsaConfig getWsaConfig()
1102 {
1103 if( wsaConfig == null )
1104 {
1105 if( !getConfig().isSetWsaConfig() )
1106 {
1107 getConfig().addNewWsaConfig();
1108 }
1109 wsaConfig = new WsaConfig( getConfig().getWsaConfig(), this );
1110
1111 }
1112 return wsaConfig;
1113 }
1114
1115 public boolean isWsAddressing()
1116 {
1117 return getConfig().getUseWsAddressing();
1118 }
1119
1120 public void setWsAddressing( boolean wsAddressing )
1121 {
1122 boolean old = getConfig().getUseWsAddressing();
1123 getConfig().setUseWsAddressing( wsAddressing );
1124 notifyPropertyChanged( "wsAddressing", old, wsAddressing );
1125 }
1126
1127 public boolean isWsaEnabled()
1128 {
1129 return isWsAddressing();
1130 }
1131
1132 public void setWsaEnabled( boolean arg0 )
1133 {
1134 setWsAddressing( arg0 );
1135
1136 }
1137
1138 public WsdlOperation getOperation()
1139 {
1140 return getMockOperation().getOperation();
1141 }
1142
1143 public void setOperation( WsdlOperation operation )
1144 {
1145 getMockOperation().setOperation( operation );
1146 }
1147
1148 }