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