View Javadoc

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