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.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  		// cache locally if specified
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 		// cache locally if specified
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 		// write attachment-data to tempfile
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 			// write attachment-data to tempfile
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 }