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( rootPart == null )
91  			rootPart = attachments.remove( 0 );
92  
93  		( ( BodyPartAttachment )rootPart ).setAttachmentType( AttachmentType.CONTENT );
94  	}
95  
96  	public void setOperation( WsdlOperation operation )
97  	{
98  		for( BodyPartAttachment attachment : attachments )
99  		{
100 			attachment.setOperation( operation );
101 		}
102 	}
103 
104 	public Attachment[] getAttachments()
105 	{
106 		return attachments.toArray( new Attachment[attachments.size()] );
107 	}
108 
109 	public Attachment getRootPart()
110 	{
111 		return rootPart;
112 	}
113 
114 	public Attachment[] getAttachmentsForPart( String partName )
115 	{
116 		List<Attachment> results = new ArrayList<Attachment>();
117 
118 		for( Attachment attachment : attachments )
119 		{
120 			if( attachment.getPart().equals( partName ) )
121 				results.add( attachment );
122 		}
123 
124 		return results.toArray( new Attachment[results.size()] );
125 	}
126 
127 	public String getResponseContent()
128 	{
129 		if( rootPart == null )
130 			return null;
131 
132 		if( responseContent == null )
133 		{
134 			try
135 			{
136 				InputStream in = rootPart.getInputStream();
137 				ByteArrayOutputStream out = Tools.readAll( in, Tools.READ_ALL );
138 				byte[] data = out.toByteArray();
139 				int contentOffset = 0;
140 
141 				String contentType = rootPart.getContentType();
142 				if( contentType != null && data.length > 0 )
143 				{
144 					String charset = null;
145 					if( contentType.indexOf( "charset=" ) > 0 )
146 					{
147 						try
148 						{
149 							int ix = contentType.indexOf( "charset=" );
150 							int ix2 = contentType.indexOf( ";", ix );
151 
152 							charset = ix2 == -1 ? contentType.substring( ix + 8 ) : contentType.substring( ix + 8, ix2 );
153 						}
154 						catch( Throwable e )
155 						{
156 							SoapUI.logError( e );
157 						}
158 					}
159 
160 					int ix = contentType.indexOf( ';' );
161 					if( ix > 0 )
162 					{
163 						contentType = contentType.substring( 0, ix );
164 						if( contentType.toLowerCase().endsWith( "xml" ) )
165 						{
166 							if( data.length > 3 && data[0] == ( byte )239 && data[1] == ( byte )187 && data[2] == ( byte )191 )
167 							{
168 								charset = "UTF-8";
169 								contentOffset = 3;
170 							}
171 						}
172 					}
173 
174 					charset = StringUtils.unquote( charset );
175 
176 					responseContent = charset == null ? new String( data ) : new String( data, contentOffset,
177 							( int )( data.length - contentOffset ), charset );
178 				}
179 
180 				if( responseContent == null )
181 				{
182 					responseContent = data.toString();
183 				}
184 
185 				return responseContent;
186 			}
187 			catch( Exception e )
188 			{
189 				SoapUI.logError( e );
190 			}
191 		}
192 
193 		return responseContent;
194 	}
195 
196 	public String getContentAsString()
197 	{
198 		if( responseContent == null )
199 			getResponseContent();
200 		
201 		if( prettyPrint )
202 		{
203 			responseContent = XmlUtils.prettyPrintXml( responseContent );
204 			prettyPrint = false;
205 		}
206 		
207 		return responseContent;
208 	}
209 	
210 	
211 	public void setResponseContent( String responseContent )
212 	{
213 		this.responseContent = responseContent;
214 	}
215 
216 	public Attachment getAttachmentWithContentId( String contentId )
217 	{
218 		for( Attachment attachment : attachments )
219 			if( contentId.equals( attachment.getContentID() ) )
220 				return attachment;
221 
222 		return null;
223 	}
224 }