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 final 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( 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 getContentAsString()
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 if( prettyPrint )
186 {
187 responseContent = XmlUtils.prettyPrintXml( responseContent );
188 }
189
190 return responseContent;
191 }
192 catch( Exception e )
193 {
194 SoapUI.logError( e );
195 }
196 }
197
198 return responseContent;
199 }
200
201 public void setResponseContent( String responseContent )
202 {
203 this.responseContent = responseContent;
204 }
205
206 public Attachment getAttachmentWithContentId( String contentId )
207 {
208 for( Attachment attachment : attachments )
209 if( contentId.equals( attachment.getContentID() ) )
210 return attachment;
211
212 return null;
213 }
214 }