1
2
3
4
5
6
7
8
9
10
11
12
13 package com.eviware.soapui.impl.wsdl.support;
14
15 import java.io.BufferedInputStream;
16 import java.io.ByteArrayInputStream;
17 import java.io.ByteArrayOutputStream;
18 import java.io.File;
19 import java.io.FileInputStream;
20 import java.io.FileNotFoundException;
21 import java.io.IOException;
22 import java.io.InputStream;
23 import java.util.zip.ZipEntry;
24 import java.util.zip.ZipInputStream;
25 import java.util.zip.ZipOutputStream;
26
27 import org.apache.commons.codec.binary.Base64;
28 import org.apache.commons.codec.binary.Hex;
29 import org.apache.log4j.Logger;
30
31 import com.eviware.soapui.SoapUI;
32 import com.eviware.soapui.config.AttachmentConfig;
33 import com.eviware.soapui.impl.wsdl.AbstractWsdlModelItem;
34 import com.eviware.soapui.impl.wsdl.teststeps.BeanPathPropertySupport;
35 import com.eviware.soapui.support.Tools;
36 import com.eviware.soapui.support.editor.inspectors.attachments.ContentTypeHandler;
37 import com.eviware.soapui.support.resolver.ResolveContext;
38
39 /***
40 * Attachments cached locally for each request
41 *
42 * @author Ole.Matzura
43 */
44
45 public abstract class FileAttachment<T extends AbstractWsdlModelItem<?>> implements WsdlAttachment
46 {
47 private AttachmentConfig config;
48 private final static Logger log = Logger.getLogger( FileAttachment.class );
49 private final T modelItem;
50 private BeanPathPropertySupport urlProperty;
51
52 public FileAttachment( T modelItem, AttachmentConfig config )
53 {
54 this.modelItem = modelItem;
55 this.config = config;
56
57 if( config.getTempFilename() != null )
58 {
59 try
60 {
61 log.info( "Moving locally cached file [" + config.getTempFilename() + "] to internal cache.." );
62 File tempFile = new File( config.getTempFilename() );
63 cacheFileLocally( tempFile );
64 }
65 catch( IOException e )
66 {
67 if( !config.isSetData() )
68 {
69 config.setData( new byte[0] );
70 config.setSize( 0 );
71 }
72
73 SoapUI.logError( e );
74 }
75 }
76
77 if( isCached() )
78 {
79 if( config.isSetTempFilename() )
80 config.unsetTempFilename();
81
82 if( config.isSetUrl() )
83 config.unsetUrl();
84 }
85
86 urlProperty = new BeanPathPropertySupport( modelItem, config, "url" );
87 }
88
89 public FileAttachment( T modelItem, File file, boolean cache, AttachmentConfig config ) throws IOException
90 {
91 this( modelItem, config );
92
93 config.setName( file.getName() );
94 config.setContentType( ContentTypeHandler.getContentTypeFromFilename( file.getName() ) );
95
96
97 if( cache )
98 {
99 cacheFileLocally( file );
100 }
101
102 urlProperty.set( file.getPath(), false );
103 }
104
105 public void setName( String value )
106 {
107 config.setName( value );
108 }
109
110 public void setUrl( String url )
111 {
112 urlProperty.set( url, true );
113 }
114
115 public void reload( File file, boolean cache ) throws IOException
116 {
117 config.setName( file.getName() );
118 config.setContentType( ContentTypeHandler.getContentTypeFromFilename( file.getName() ) );
119
120
121 if( cache )
122 {
123 cacheFileLocally( file );
124 }
125 else
126 {
127 urlProperty.set( file.getPath(), false );
128 config.unsetData();
129 }
130 }
131
132 public T getModelItem()
133 {
134 return modelItem;
135 }
136
137 public void cacheFileLocally( File file ) throws FileNotFoundException, IOException
138 {
139
140 ByteArrayOutputStream data = new ByteArrayOutputStream();
141 ZipOutputStream out = new ZipOutputStream( data );
142 out.putNextEntry( new ZipEntry( config.getName() ) );
143
144 InputStream in = new FileInputStream( file );
145 long sz = file.length();
146 config.setSize( sz );
147
148 Tools.writeAll( out, in );
149
150 in.close();
151 out.closeEntry();
152 out.finish();
153 out.close();
154 data.close();
155
156 config.setData( data.toByteArray() );
157 }
158
159 public String getContentType()
160 {
161 AttachmentEncoding encoding = getEncoding();
162 if( encoding == AttachmentEncoding.NONE )
163 return config.getContentType();
164 else
165 return "application/octet-stream";
166 }
167
168 public InputStream getInputStream() throws IOException
169 {
170 BufferedInputStream inputStream = null;
171
172 if( isCached() )
173 {
174 ZipInputStream zipInputStream = new ZipInputStream( new ByteArrayInputStream( config.getData() ) );
175 zipInputStream.getNextEntry();
176 inputStream = new BufferedInputStream( zipInputStream );
177 }
178 else
179 {
180 String url = urlProperty.expand();
181 inputStream = new BufferedInputStream( url == null ? new ByteArrayInputStream( new byte[0] )
182 : new FileInputStream( url ) );
183 }
184
185 AttachmentEncoding encoding = getEncoding();
186 if( encoding == AttachmentEncoding.BASE64 )
187 {
188 ByteArrayOutputStream data = Tools.readAll( inputStream, Tools.READ_ALL );
189 return new ByteArrayInputStream( Base64.encodeBase64( data.toByteArray() ) );
190 }
191 else if( encoding == AttachmentEncoding.HEX )
192 {
193 ByteArrayOutputStream data = Tools.readAll( inputStream, Tools.READ_ALL );
194 return new ByteArrayInputStream( new String( Hex.encodeHex( data.toByteArray() ) ).getBytes() );
195 }
196
197 return inputStream;
198 }
199
200 public String getName()
201 {
202 return config.getName();
203 }
204
205 public long getSize()
206 {
207 if( isCached() )
208 {
209 return config.getSize();
210 }
211 else
212 {
213 String url = urlProperty.expand();
214 if( url != null )
215 {
216 File file = new File( url );
217 if( file.exists() )
218 return file.length();
219 }
220 }
221
222 return -1;
223 }
224
225 public void release()
226 {
227 if( isCached() )
228 new File( config.getTempFilename() ).delete();
229 }
230
231 public String getPart()
232 {
233 return config.getPart();
234 }
235
236 public void setContentType( String contentType )
237 {
238 config.setContentType( contentType );
239 }
240
241 public void setPart( String part )
242 {
243 config.setPart( part );
244 }
245
246 public void setData( byte[] data )
247 {
248 try
249 {
250
251 ByteArrayOutputStream tempData = new ByteArrayOutputStream();
252 ZipOutputStream out = new ZipOutputStream( tempData );
253 out.putNextEntry( new ZipEntry( config.getName() ) );
254 config.setSize( data.length );
255 out.write( data );
256 out.closeEntry();
257 out.finish();
258 out.close();
259 config.setData( tempData.toByteArray() );
260 }
261 catch( Exception e )
262 {
263 SoapUI.logError( e );
264 }
265 }
266
267 public byte[] getData() throws IOException
268 {
269 ByteArrayOutputStream out = new ByteArrayOutputStream();
270 Tools.writeAll( out, getInputStream() );
271 return out.toByteArray();
272 }
273
274 public String getUrl()
275 {
276 return urlProperty.get();
277 }
278
279 public boolean isCached()
280 {
281 return config.isSetData();
282 }
283
284 abstract public AttachmentType getAttachmentType();
285
286 public void updateConfig( AttachmentConfig config )
287 {
288 this.config = config;
289 urlProperty.setConfig( config );
290 }
291
292 public AttachmentConfig getConfig()
293 {
294 return config;
295 }
296
297 public void setContentID( String contentID )
298 {
299 if( ( contentID == null || contentID.length() == 0 ) && config.isSetContentId() )
300 config.unsetContentId();
301 else
302 config.setContentId( contentID );
303 }
304
305 public String getContentID()
306 {
307 return config.getContentId();
308 }
309
310 public void resolve( ResolveContext<?> context )
311 {
312 if( isCached() )
313 return;
314
315 urlProperty.resolveFile( context, "Missing attachment [" + getName() + "]", null, null, false );
316 }
317
318 public String getContentEncoding()
319 {
320 AttachmentEncoding encoding = getEncoding();
321 if( encoding == AttachmentEncoding.BASE64 )
322 return "base64";
323 else if( encoding == AttachmentEncoding.HEX )
324 return "hex";
325 else
326 return "binary";
327 }
328 }