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.BufferedOutputStream;
16  import java.io.ByteArrayInputStream;
17  import java.io.File;
18  import java.io.FileOutputStream;
19  import java.io.InputStream;
20  import java.io.OutputStream;
21  import java.net.MalformedURLException;
22  
23  import javax.mail.BodyPart;
24  import javax.mail.MessagingException;
25  
26  import org.apache.commons.codec.binary.Base64;
27  import org.apache.commons.codec.binary.Hex;
28  
29  import com.eviware.soapui.SoapUI;
30  import com.eviware.soapui.impl.support.AbstractHttpOperation;
31  import com.eviware.soapui.impl.wsdl.WsdlOperation;
32  import com.eviware.soapui.model.iface.Attachment;
33  import com.eviware.soapui.support.Tools;
34  
35  /***
36   * Attachment for a BodyPart
37   * 
38   * @author ole.matzura
39   */
40  
41  public class BodyPartAttachment implements Attachment
42  {
43  	private final BodyPart bodyPart;
44  	private File tempFile;
45  	private AbstractHttpOperation operation;
46  	private final boolean isRequest;
47  	private byte[] data;
48  	private AttachmentType attachmentType;
49  
50  	public BodyPartAttachment( BodyPart bodyPart, AbstractHttpOperation operation, boolean isRequest,
51  			AttachmentType attachmentType )
52  	{
53  		this.bodyPart = bodyPart;
54  		this.operation = operation;
55  		this.isRequest = isRequest;
56  		this.attachmentType = attachmentType;
57  	}
58  
59  	public String getContentType()
60  	{
61  		try
62  		{
63  			return bodyPart.getContentType();
64  		}
65  		catch( MessagingException e )
66  		{
67  			SoapUI.logError( e );
68  			return null;
69  		}
70  	}
71  
72  	public AttachmentEncoding getEncoding()
73  	{
74  		return operation == null ? AttachmentEncoding.NONE : operation.getAttachmentEncoding( getPart(), !isRequest );
75  	}
76  
77  	public synchronized InputStream getInputStream() throws Exception
78  	{
79  		if( data != null )
80  			return new ByteArrayInputStream( data );
81  
82  		AttachmentEncoding encoding = getEncoding();
83  		if( encoding == AttachmentEncoding.NONE )
84  			return bodyPart.getInputStream();
85  
86  		data = Tools.readAll( bodyPart.getInputStream(), Tools.READ_ALL ).toByteArray();
87  
88  		if( encoding == AttachmentEncoding.BASE64 )
89  		{
90  			if( Base64.isArrayByteBase64( data ) )
91  				data = Tools.readAll( new ByteArrayInputStream( Base64.decodeBase64( data ) ), Tools.READ_ALL )
92  						.toByteArray();
93  			else
94  				throw new Exception( "Attachment content for part [" + getPart() + "] is not base64 encoded" );
95  		}
96  		else if( encoding == AttachmentEncoding.HEX )
97  		{
98  			data = Hex.decodeHex( new String( data ).toCharArray() );
99  		}
100 
101 		return new ByteArrayInputStream( data );
102 	}
103 
104 	public String getName()
105 	{
106 		try
107 		{
108 			String[] header = bodyPart.getHeader( "Content-Id" );
109 			if( header == null || header.length == 0 )
110 				return "<missing name>";
111 
112 			if( header[0].startsWith( "<" ) && header[0].endsWith( ">" ) )
113 				header[0] = header[0].substring( 1, header[0].length() - 1 );
114 
115 			return header[0];
116 		}
117 		catch( MessagingException e )
118 		{
119 			SoapUI.logError( e );
120 			return null;
121 		}
122 	}
123 
124 	public String getPart()
125 	{
126 		String name = getName();
127 		int ix = name.indexOf( '=' );
128 		if( ix > 0 )
129 		{
130 			name = name.substring( 0, ix );
131 		}
132 
133 		return name;
134 	}
135 
136 	public long getSize()
137 	{
138 		try
139 		{
140 			getInputStream();
141 			return data == null ? bodyPart.getSize() : data.length;
142 		}
143 		catch( Exception e )
144 		{
145 			SoapUI.logError( e );
146 			return -1;
147 		}
148 	}
149 
150 	public String getUrl()
151 	{
152 		if( tempFile == null )
153 		{
154 			String contentType = getContentType();
155 			int ix = contentType.lastIndexOf( '/' );
156 			int iy = -1;
157 			if( ix != -1 )
158 				iy = contentType.indexOf( ';', ix );
159 
160 			try
161 			{
162 				tempFile = File.createTempFile( "response-attachment", ( ix == -1 ? ".dat" : "."
163 						+ ( iy == -1 ? contentType.substring( ix + 1 ) : contentType.substring( ix + 1, iy ) ) ) );
164 
165 				OutputStream out = new BufferedOutputStream( new FileOutputStream( tempFile ) );
166 				InputStream inputStream = getInputStream();
167 				out.write( Tools.readAll( inputStream, 0 ).toByteArray() );
168 				out.flush();
169 				out.close();
170 
171 				inputStream.reset();
172 			}
173 			catch( Exception e )
174 			{
175 				SoapUI.logError( e );
176 			}
177 		}
178 
179 		try
180 		{
181 			return tempFile.toURI().toURL().toString();
182 		}
183 		catch( MalformedURLException e )
184 		{
185 			SoapUI.logError( e );
186 			return null;
187 		}
188 	}
189 
190 	public void setContentType( String contentType )
191 	{
192 	}
193 
194 	public void setPart( String part )
195 	{
196 	}
197 
198 	public boolean isCached()
199 	{
200 		return true;
201 	}
202 
203 	public AttachmentType getAttachmentType()
204 	{
205 		return attachmentType == null ? AttachmentType.UNKNOWN : attachmentType;
206 	}
207 
208 	public void release()
209 	{
210 		operation = null;
211 	}
212 
213 	public String getContentID()
214 	{
215 		try
216 		{
217 			String[] header = bodyPart.getHeader( "Content-ID" );
218 			if( header != null && header.length > 0 )
219 				return header[0];
220 		}
221 		catch( MessagingException e )
222 		{
223 			SoapUI.logError( e );
224 		}
225 
226 		return null;
227 	}
228 
229 	public void setOperation( WsdlOperation operation )
230 	{
231 		this.operation = operation;
232 	}
233 
234 	public void setAttachmentType( AttachmentType attachmentType )
235 	{
236 		this.attachmentType = attachmentType;
237 	}
238 
239 	public String getContentEncoding()
240 	{
241 		AttachmentEncoding encoding = getEncoding();
242 		if( encoding == AttachmentEncoding.BASE64 )
243 			return "base64";
244 		else if( encoding == AttachmentEncoding.HEX )
245 			return "hex";
246 		else
247 			return "binary";
248 	}
249 }