View Javadoc

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