View Javadoc

1   /*
2    *  soapUI, copyright (C) 2004-2010 eviware.com 
3    *
4    *  soapUI is free software; you can redistribute it and/or modify it under the 
5    *  terms of version 2.1 of the GNU Lesser General Public License as published by 
6    *  the Free Software Foundation.
7    *
8    *  soapUI is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without 
9    *  even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 
10   *  See the GNU Lesser General Public License for more details at gnu.org.
11   */
12  
13  package com.eviware.soapui.impl.wsdl.submit.filters;
14  
15  import java.util.Arrays;
16  
17  import javax.activation.DataHandler;
18  import javax.mail.MessagingException;
19  import javax.mail.internet.MimeBodyPart;
20  import javax.mail.internet.MimeMessage;
21  import javax.mail.internet.MimeMultipart;
22  import javax.mail.internet.PreencodedMimeBodyPart;
23  
24  import org.apache.commons.httpclient.methods.ByteArrayRequestEntity;
25  
26  import com.eviware.soapui.SoapUI;
27  import com.eviware.soapui.impl.wsdl.WsdlRequest;
28  import com.eviware.soapui.impl.wsdl.submit.transports.http.BaseHttpRequestTransport;
29  import com.eviware.soapui.impl.wsdl.submit.transports.http.support.attachments.AttachmentUtils;
30  import com.eviware.soapui.impl.wsdl.submit.transports.http.support.attachments.WsdlRequestDataSource;
31  import com.eviware.soapui.impl.wsdl.submit.transports.http.support.attachments.WsdlRequestMimeMessageRequestEntity;
32  import com.eviware.soapui.impl.wsdl.submit.transports.http.support.methods.ExtendedPostMethod;
33  import com.eviware.soapui.impl.wsdl.support.MessageXmlObject;
34  import com.eviware.soapui.impl.wsdl.support.MessageXmlPart;
35  import com.eviware.soapui.model.iface.Attachment;
36  import com.eviware.soapui.model.iface.SubmitContext;
37  import com.eviware.soapui.model.iface.Attachment.AttachmentType;
38  import com.eviware.soapui.support.StringUtils;
39  import com.eviware.soapui.support.types.StringToStringMap;
40  
41  public class WsdlPackagingRequestFilter extends AbstractRequestFilter
42  {
43  
44  	@Override
45  	public void filterWsdlRequest( SubmitContext context, WsdlRequest request )
46  	{
47  		ExtendedPostMethod postMethod = ( ExtendedPostMethod )context.getProperty( BaseHttpRequestTransport.HTTP_METHOD );
48  		String requestContent = ( String )context.getProperty( BaseHttpRequestTransport.REQUEST_CONTENT );
49  
50  		try
51  		{
52  			String content = initWsdlRequest( request, postMethod, requestContent );
53  			if( content != null )
54  				context.setProperty( BaseHttpRequestTransport.REQUEST_CONTENT, content );
55  		}
56  		catch( Exception e )
57  		{
58  			SoapUI.logError( e );
59  		}
60  	}
61  
62  	protected String initWsdlRequest( WsdlRequest wsdlRequest, ExtendedPostMethod postMethod, String requestContent )
63  			throws Exception
64  	{
65  		MimeMultipart mp = null;
66  
67  		StringToStringMap contentIds = new StringToStringMap();
68  		boolean isXOP = wsdlRequest.isMtomEnabled() && wsdlRequest.isForceMtom();
69  
70  		// preprocess only if neccessary
71  		if( wsdlRequest.isMtomEnabled() || wsdlRequest.isInlineFilesEnabled() || wsdlRequest.getAttachmentCount() > 0 )
72  		{
73  			try
74  			{
75  				mp = new MimeMultipart();
76  
77  				MessageXmlObject requestXmlObject = new MessageXmlObject( wsdlRequest.getOperation(), requestContent, true );
78  				MessageXmlPart[] requestParts = requestXmlObject.getMessageParts();
79  				for( MessageXmlPart requestPart : requestParts )
80  				{
81  					if( AttachmentUtils.prepareMessagePart( wsdlRequest, mp, requestPart, contentIds ) )
82  						isXOP = true;
83  				}
84  				requestContent = requestXmlObject.getMessageContent();
85  			}
86  			catch( Throwable e )
87  			{
88  				SoapUI.log.warn( "Failed to process inline/MTOM attachments; " + e );
89  			}
90  		}
91  
92  		// non-multipart request?
93  		if( !isXOP && ( mp == null || mp.getCount() == 0 ) && hasContentAttachmentsOnly( wsdlRequest ) )
94  		{
95  			String encoding = System.getProperty( "soapui.request.encoding", StringUtils.unquote( wsdlRequest
96  					.getEncoding() ) );
97  			byte[] content = StringUtils.isNullOrEmpty( encoding ) ? requestContent.getBytes() : requestContent
98  					.getBytes( encoding );
99  			postMethod.setRequestEntity( new ByteArrayRequestEntity( content ) );
100 		}
101 		else
102 		{
103 			// make sure..
104 			if( mp == null )
105 				mp = new MimeMultipart();
106 
107 			// init root part
108 			initRootPart( wsdlRequest, requestContent, mp, isXOP );
109 
110 			// init mimeparts
111 			AttachmentUtils.addMimeParts( wsdlRequest, Arrays.asList( wsdlRequest.getAttachments() ), mp, contentIds );
112 
113 			// create request message
114 			MimeMessage message = new MimeMessage( AttachmentUtils.JAVAMAIL_SESSION );
115 			message.setContent( mp );
116 			message.saveChanges();
117 			WsdlRequestMimeMessageRequestEntity mimeMessageRequestEntity = new WsdlRequestMimeMessageRequestEntity(
118 					message, isXOP, wsdlRequest );
119 			postMethod.setRequestEntity( mimeMessageRequestEntity );
120 			postMethod.setRequestHeader( "Content-Type", mimeMessageRequestEntity.getContentType() );
121 			postMethod.setRequestHeader( "MIME-Version", "1.0" );
122 		}
123 
124 		return requestContent;
125 	}
126 
127 	private boolean hasContentAttachmentsOnly( WsdlRequest wsdlRequest )
128 	{
129 		for( Attachment attachment : wsdlRequest.getAttachments() )
130 		{
131 			if( attachment.getAttachmentType() != Attachment.AttachmentType.CONTENT
132 					&& !( attachment.getAttachmentType() == AttachmentType.UNKNOWN && wsdlRequest.isInlineFilesEnabled() ) )
133 				return false;
134 		}
135 
136 		return true;
137 	}
138 
139 	/***
140 	 * Creates root BodyPart containing message
141 	 */
142 
143 	protected void initRootPart( WsdlRequest wsdlRequest, String requestContent, MimeMultipart mp, boolean isXOP )
144 			throws MessagingException
145 	{
146 		MimeBodyPart rootPart = new PreencodedMimeBodyPart( "8bit" );
147 		rootPart.setContentID( AttachmentUtils.ROOTPART_SOAPUI_ORG );
148 		mp.addBodyPart( rootPart, 0 );
149 
150 		DataHandler dataHandler = new DataHandler( new WsdlRequestDataSource( wsdlRequest, requestContent, isXOP ) );
151 		rootPart.setDataHandler( dataHandler );
152 	}
153 }