View Javadoc

1   /*
2    *  soapUI, copyright (C) 2004-2009 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.support.StringUtils;
38  import com.eviware.soapui.support.types.StringToStringMap;
39  
40  public class WsdlPackagingRequestFilter extends AbstractRequestFilter
41  {
42  
43  	@Override
44  	public void filterWsdlRequest( SubmitContext context, WsdlRequest request )
45  	{
46  		ExtendedPostMethod postMethod = ( ExtendedPostMethod )context.getProperty( BaseHttpRequestTransport.HTTP_METHOD );
47  		String requestContent = ( String )context.getProperty( BaseHttpRequestTransport.REQUEST_CONTENT );
48  
49  		try
50  		{
51  			String content = initWsdlRequest( request, postMethod, requestContent );
52  			if( content != null )
53  				context.setProperty( BaseHttpRequestTransport.REQUEST_CONTENT, content );
54  		}
55  		catch( Exception e )
56  		{
57  			SoapUI.logError( e );
58  		}
59  	}
60  
61  	protected String initWsdlRequest( WsdlRequest wsdlRequest, ExtendedPostMethod postMethod, String requestContent )
62  			throws Exception
63  	{
64  		MimeMultipart mp = null;
65  
66  		StringToStringMap contentIds = new StringToStringMap();
67  		boolean isXOP = wsdlRequest.isMtomEnabled() && wsdlRequest.isForceMtom();
68  
69  		// preprocess only if neccessary
70  		if( wsdlRequest.isMtomEnabled() || wsdlRequest.isInlineFilesEnabled() || wsdlRequest.getAttachmentCount() > 0 )
71  		{
72  			try
73  			{
74  				mp = new MimeMultipart();
75  
76  				MessageXmlObject requestXmlObject = new MessageXmlObject( wsdlRequest.getOperation(), requestContent, true );
77  				MessageXmlPart[] requestParts = requestXmlObject.getMessageParts();
78  				for( MessageXmlPart requestPart : requestParts )
79  				{
80  					if( AttachmentUtils.prepareMessagePart( wsdlRequest, mp, requestPart, contentIds ) )
81  						isXOP = true;
82  				}
83  				requestContent = requestXmlObject.getMessageContent();
84  			}
85  			catch( Throwable e )
86  			{
87  				SoapUI.log.warn( "Failed to process inline/MTOM attachments; " + e );
88  			}
89  		}
90  
91  		// non-multipart request?
92  		if( !isXOP && ( mp == null || mp.getCount() == 0 ) && hasContentAttachmentsOnly( wsdlRequest ) )
93  		{
94  			String encoding = System.getProperty( "soapui.request.encoding", StringUtils.unquote( wsdlRequest
95  					.getEncoding() ) );
96  			byte[] content = StringUtils.isNullOrEmpty( encoding ) ? requestContent.getBytes() : requestContent
97  					.getBytes( encoding );
98  			postMethod.setRequestEntity( new ByteArrayRequestEntity( content ) );
99  		}
100 		else
101 		{
102 			// make sure..
103 			if( mp == null )
104 				mp = new MimeMultipart();
105 
106 			// init root part
107 			initRootPart( wsdlRequest, requestContent, mp, isXOP );
108 
109 			// init mimeparts
110 			AttachmentUtils.addMimeParts( wsdlRequest, Arrays.asList( wsdlRequest.getAttachments() ), mp, contentIds );
111 
112 			// create request message
113 			MimeMessage message = new MimeMessage( AttachmentUtils.JAVAMAIL_SESSION );
114 			message.setContent( mp );
115 			message.saveChanges();
116 			WsdlRequestMimeMessageRequestEntity mimeMessageRequestEntity = new WsdlRequestMimeMessageRequestEntity(
117 					message, isXOP, wsdlRequest );
118 			postMethod.setRequestEntity( mimeMessageRequestEntity );
119 			postMethod.setRequestHeader( "Content-Type", mimeMessageRequestEntity.getContentType() );
120 			postMethod.setRequestHeader( "MIME-Version", "1.0" );
121 		}
122 
123 		return requestContent;
124 	}
125 
126 	private boolean hasContentAttachmentsOnly( WsdlRequest wsdlRequest )
127 	{
128 		for( Attachment attachment : wsdlRequest.getAttachments() )
129 		{
130 			if( attachment.getAttachmentType() != Attachment.AttachmentType.CONTENT )
131 				return false;
132 		}
133 
134 		return true;
135 	}
136 
137 	/***
138 	 * Creates root BodyPart containing message
139 	 */
140 
141 	protected void initRootPart( WsdlRequest wsdlRequest, String requestContent, MimeMultipart mp, boolean isXOP )
142 			throws MessagingException
143 	{
144 		MimeBodyPart rootPart = new PreencodedMimeBodyPart( "8bit" );
145 		rootPart.setContentID( AttachmentUtils.ROOTPART_SOAPUI_ORG );
146 		mp.addBodyPart( rootPart, 0 );
147 
148 		DataHandler dataHandler = new DataHandler( new WsdlRequestDataSource( wsdlRequest, requestContent, isXOP ) );
149 		rootPart.setDataHandler( dataHandler );
150 	}
151 }