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.transports.http.support.attachments;
14  
15  import java.io.ByteArrayOutputStream;
16  import java.io.InputStream;
17  import java.util.ArrayList;
18  import java.util.List;
19  
20  import javax.activation.DataSource;
21  import javax.mail.BodyPart;
22  import javax.mail.MessagingException;
23  import javax.mail.internet.MimeMessage;
24  import javax.mail.internet.MimeMultipart;
25  
26  import com.eviware.soapui.SoapUI;
27  import com.eviware.soapui.impl.support.AbstractHttpOperation;
28  import com.eviware.soapui.impl.wsdl.WsdlOperation;
29  import com.eviware.soapui.model.iface.Attachment;
30  import com.eviware.soapui.model.iface.Attachment.AttachmentType;
31  import com.eviware.soapui.support.StringUtils;
32  import com.eviware.soapui.support.Tools;
33  import com.eviware.soapui.support.xml.XmlUtils;
34  
35  /***
36   * Utility class for managing large MultiParts
37   * 
38   * @author ole.matzura
39   */
40  
41  public class MultipartMessageSupport
42  {
43  	private final List<BodyPartAttachment> attachments = new ArrayList<BodyPartAttachment>();
44  	private Attachment rootPart;
45  	private MimeMessage message;
46  	private String responseContent;
47  	private boolean prettyPrint;
48  
49  	public MultipartMessageSupport( DataSource dataSource, String rootPartId, AbstractHttpOperation operation,
50  			boolean isRequest, boolean prettyPrint ) throws MessagingException
51  	{
52  		this.prettyPrint = prettyPrint;
53  		MimeMultipart mp = new MimeMultipart( dataSource );
54  		message = new MimeMessage( AttachmentUtils.JAVAMAIL_SESSION );
55  		message.setContent( mp );
56  
57  		AttachmentType attachmentType = AttachmentType.MIME;
58  
59  		for( int c = 0; c < mp.getCount(); c++ )
60  		{
61  			BodyPart bodyPart = mp.getBodyPart( c );
62  
63  			String contentType = bodyPart.getContentType().toUpperCase();
64  			if( contentType.startsWith( "APPLICATION/XOP+XML" ) )
65  				attachmentType = AttachmentType.XOP;
66  
67  			if( contentType.startsWith( "MULTIPART/" ) )
68  			{
69  				MimeMultipart mp2 = new MimeMultipart( new BodyPartDataSource( bodyPart ) );
70  				for( int i = 0; i < mp2.getCount(); i++ )
71  				{
72  					attachments.add( new BodyPartAttachment( mp2.getBodyPart( i ), operation, isRequest, attachmentType ) );
73  				}
74  			}
75  			else
76  			{
77  				BodyPartAttachment attachment = new BodyPartAttachment( bodyPart, operation, isRequest, attachmentType );
78  
79  				String[] contentIdHeaders = bodyPart.getHeader( "Content-ID" );
80  				if( contentIdHeaders != null && contentIdHeaders.length > 0 && contentIdHeaders[0].equals( rootPartId ) )
81  				{
82  					rootPart = attachment;
83  				}
84  				else
85  					attachments.add( attachment );
86  			}
87  		}
88  
89  		// if no explicit root part has been set, use the first one in the result
90  		if( operation != null && rootPart == null )
91  			rootPart = attachments.remove( 0 );
92  
93  		if( rootPart != null )
94  		{
95  			( ( BodyPartAttachment )rootPart ).setAttachmentType( AttachmentType.CONTENT );
96  		}
97  	}
98  
99  	public void setOperation( WsdlOperation operation )
100 	{
101 		for( BodyPartAttachment attachment : attachments )
102 		{
103 			attachment.setOperation( operation );
104 		}
105 	}
106 
107 	public Attachment[] getAttachments()
108 	{
109 		return attachments.toArray( new Attachment[attachments.size()] );
110 	}
111 
112 	public Attachment getRootPart()
113 	{
114 		return rootPart;
115 	}
116 
117 	public Attachment[] getAttachmentsForPart( String partName )
118 	{
119 		List<Attachment> results = new ArrayList<Attachment>();
120 
121 		for( Attachment attachment : attachments )
122 		{
123 			if( attachment.getPart().equals( partName ) )
124 				results.add( attachment );
125 		}
126 
127 		return results.toArray( new Attachment[results.size()] );
128 	}
129 
130 	public String getResponseContent()
131 	{
132 		if( rootPart == null )
133 			return null;
134 
135 		if( responseContent == null )
136 		{
137 			try
138 			{
139 				InputStream in = rootPart.getInputStream();
140 				ByteArrayOutputStream out = Tools.readAll( in, Tools.READ_ALL );
141 				byte[] data = out.toByteArray();
142 				int contentOffset = 0;
143 
144 				String contentType = rootPart.getContentType();
145 				if( contentType != null && data.length > 0 )
146 				{
147 					String charset = null;
148 					if( contentType.indexOf( "charset=" ) > 0 )
149 					{
150 						try
151 						{
152 							int ix = contentType.indexOf( "charset=" );
153 							int ix2 = contentType.indexOf( ";", ix );
154 
155 							charset = ix2 == -1 ? contentType.substring( ix + 8 ) : contentType.substring( ix + 8, ix2 );
156 						}
157 						catch( Throwable e )
158 						{
159 							SoapUI.logError( e );
160 						}
161 					}
162 
163 					int ix = contentType.indexOf( ';' );
164 					if( ix > 0 )
165 					{
166 						contentType = contentType.substring( 0, ix );
167 						if( contentType.toLowerCase().endsWith( "xml" ) )
168 						{
169 							if( data.length > 3 && data[0] == ( byte )239 && data[1] == ( byte )187 && data[2] == ( byte )191 )
170 							{
171 								charset = "UTF-8";
172 								contentOffset = 3;
173 							}
174 						}
175 					}
176 
177 					charset = StringUtils.unquote( charset );
178 
179 					responseContent = charset == null ? new String( data ) : new String( data, contentOffset,
180 							( int )( data.length - contentOffset ), charset );
181 				}
182 
183 				if( responseContent == null )
184 				{
185 					responseContent = data.toString();
186 				}
187 
188 				return responseContent;
189 			}
190 			catch( Exception e )
191 			{
192 				SoapUI.logError( e );
193 			}
194 		}
195 
196 		return responseContent;
197 	}
198 
199 	public String getContentAsString()
200 	{
201 		if( responseContent == null )
202 			getResponseContent();
203 		
204 		if( prettyPrint )
205 		{
206 			responseContent = XmlUtils.prettyPrintXml( responseContent );
207 			prettyPrint = false;
208 		}
209 		
210 		return responseContent;
211 	}
212 	
213 	
214 	public void setResponseContent( String responseContent )
215 	{
216 		this.responseContent = responseContent;
217 	}
218 
219 	public Attachment getAttachmentWithContentId( String contentId )
220 	{
221 		for( Attachment attachment : attachments )
222 			if( contentId.equals( attachment.getContentID() ) )
223 				return attachment;
224 
225 		return null;
226 	}
227 }