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