1
2
3
4
5
6
7
8
9
10
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
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 }