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