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 config.setContentId( file.getName() );
96
97
98 if( cache )
99 {
100 cacheFileLocally( file );
101 }
102
103 urlProperty.set( file.getPath(), false );
104 }
105
106 public void setName( String value )
107 {
108 config.setName( value );
109 }
110
111 public void setUrl( String url )
112 {
113 urlProperty.set( url, true );
114 }
115
116 public void reload( File file, boolean cache ) throws IOException
117 {
118 config.setName( file.getName() );
119 config.setContentType( ContentTypeHandler.getContentTypeFromFilename( file.getName() ) );
120 config.setContentId( file.getName() );
121
122
123 if( cache )
124 {
125 cacheFileLocally( file );
126 }
127 else
128 {
129 urlProperty.set( file.getPath(), false );
130 config.unsetData();
131 }
132 }
133
134 public T getModelItem()
135 {
136 return modelItem;
137 }
138
139 public void cacheFileLocally( File file ) throws FileNotFoundException, IOException
140 {
141
142 ByteArrayOutputStream data = new ByteArrayOutputStream();
143 ZipOutputStream out = new ZipOutputStream( data );
144 out.putNextEntry( new ZipEntry( config.getName() ) );
145
146 InputStream in = new FileInputStream( file );
147 long sz = file.length();
148 config.setSize( sz );
149
150 Tools.writeAll( out, in );
151
152 in.close();
153 out.closeEntry();
154 out.finish();
155 out.close();
156 data.close();
157
158 config.setData( data.toByteArray() );
159 }
160
161 public String getContentType()
162 {
163 AttachmentEncoding encoding = getEncoding();
164 if( encoding == AttachmentEncoding.NONE )
165 return config.getContentType();
166 else
167 return "application/octet-stream";
168 }
169
170 public InputStream getInputStream() throws IOException
171 {
172 BufferedInputStream inputStream = null;
173
174 if( isCached() )
175 {
176 ZipInputStream zipInputStream = new ZipInputStream( new ByteArrayInputStream( config.getData() ) );
177 zipInputStream.getNextEntry();
178 inputStream = new BufferedInputStream( zipInputStream );
179 }
180 else
181 {
182 String url = urlProperty.expand();
183 inputStream = new BufferedInputStream( url == null ? new ByteArrayInputStream( new byte[0] )
184 : new FileInputStream( url ) );
185 }
186
187 AttachmentEncoding encoding = getEncoding();
188 if( encoding == AttachmentEncoding.BASE64 )
189 {
190 ByteArrayOutputStream data = Tools.readAll( inputStream, Tools.READ_ALL );
191 return new ByteArrayInputStream( Base64.encodeBase64( data.toByteArray() ) );
192 }
193 else if( encoding == AttachmentEncoding.HEX )
194 {
195 ByteArrayOutputStream data = Tools.readAll( inputStream, Tools.READ_ALL );
196 return new ByteArrayInputStream( new String( Hex.encodeHex( data.toByteArray() ) ).getBytes() );
197 }
198
199 return inputStream;
200 }
201
202 public String getName()
203 {
204 return config.getName();
205 }
206
207 public long getSize()
208 {
209 if( isCached() )
210 {
211 return config.getSize();
212 }
213 else
214 {
215 String url = urlProperty.expand();
216 if( url != null )
217 {
218 File file = new File( url );
219 if( file.exists() )
220 return file.length();
221 }
222 }
223
224 return -1;
225 }
226
227 public void release()
228 {
229 if( isCached() )
230 new File( config.getTempFilename() ).delete();
231 }
232
233 public String getPart()
234 {
235 return config.getPart();
236 }
237
238 public void setContentType( String contentType )
239 {
240 config.setContentType( contentType );
241 }
242
243 public void setPart( String part )
244 {
245 config.setPart( part );
246 }
247
248 public void setData( byte[] data )
249 {
250 try
251 {
252
253 ByteArrayOutputStream tempData = new ByteArrayOutputStream();
254 ZipOutputStream out = new ZipOutputStream( tempData );
255 out.putNextEntry( new ZipEntry( config.getName() ) );
256 config.setSize( data.length );
257 out.write( data );
258 out.closeEntry();
259 out.finish();
260 out.close();
261 config.setData( tempData.toByteArray() );
262 }
263 catch( Exception e )
264 {
265 SoapUI.logError( e );
266 }
267 }
268
269 public byte[] getData() throws IOException
270 {
271 ByteArrayOutputStream out = new ByteArrayOutputStream();
272 Tools.writeAll( out, getInputStream() );
273 return out.toByteArray();
274 }
275
276 public String getUrl()
277 {
278 return urlProperty.get();
279 }
280
281 public boolean isCached()
282 {
283 return config.isSetData();
284 }
285
286 abstract public AttachmentType getAttachmentType();
287
288 public void updateConfig( AttachmentConfig config )
289 {
290 this.config = config;
291 urlProperty.setConfig( config );
292 }
293
294 public AttachmentConfig getConfig()
295 {
296 return config;
297 }
298
299 public void setContentID( String contentID )
300 {
301 if( ( contentID == null || contentID.length() == 0 ) && config.isSetContentId() )
302 config.unsetContentId();
303 else
304 config.setContentId( contentID );
305 }
306
307 public String getContentID()
308 {
309 return config.getContentId();
310 }
311
312 public void resolve( ResolveContext<?> context )
313 {
314 if( isCached() )
315 return;
316
317 urlProperty.resolveFile( context, "Missing attachment [" + getName() + "]", null, null, false );
318 }
319
320 public String getContentEncoding()
321 {
322 AttachmentEncoding encoding = getEncoding();
323 if( encoding == AttachmentEncoding.BASE64 )
324 return "base64";
325 else if( encoding == AttachmentEncoding.HEX )
326 return "hex";
327 else
328 return "binary";
329 }
330 }