View Javadoc

1   /*
2    *  soapUI, copyright (C) 2004-2009 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.support;
14  
15  import java.io.BufferedInputStream;
16  import java.io.BufferedOutputStream;
17  import java.io.ByteArrayOutputStream;
18  import java.io.File;
19  import java.io.FileInputStream;
20  import java.io.FileOutputStream;
21  import java.io.IOException;
22  import java.io.InputStream;
23  import java.io.OutputStream;
24  import java.lang.reflect.Method;
25  import java.net.URL;
26  import java.net.URLDecoder;
27  import java.util.ArrayList;
28  import java.util.Arrays;
29  import java.util.List;
30  
31  import com.eviware.soapui.support.editor.inspectors.attachments.ContentTypeHandler;
32  import com.eviware.soapui.support.types.StringToStringMap;
33  
34  public class Tools
35  {
36  	public static final int COPY_BUFFER_SIZE = 1000;
37  
38  	public static String[] tokenizeArgs( String args )
39  	{
40  		if( args == null || args.trim().length() == 0 )
41  			return null;
42  
43  		List<String> l = Arrays.asList( args.split( " " ) );
44  		List<String> result = new ArrayList<String>();
45  
46  		for( int c = 0; c < l.size(); c++ )
47  		{
48  			String s = l.get( c );
49  			if( s.startsWith( "\"" ) )
50  			{
51  				c++ ;
52  				s += " " + l.get( c );
53  				while( !( s.endsWith( "\"" ) && !s.endsWith( "//\"" ) ) && c < l.size() )
54  				{
55  					c++ ;
56  				}
57  
58  				// remove trailing/leading quotes
59  				s = c == l.size() ? s.substring( 1 ) : s.substring( 1, s.length() - 1 );
60  
61  				// replace backslashed quotes
62  				s = s.replace( "//\"", "\"" );
63  			}
64  
65  			result.add( s );
66  		}
67  
68  		return result.toArray( new String[result.size()] );
69  	}
70  
71  	public static String convertToHtml( String str )
72  	{
73  		StringBuffer result = new StringBuffer( "<html><body>" );
74  
75  		for( int c = 0; c < str.length(); c++ )
76  		{
77  			char ch = str.charAt( c );
78  			if( ch == '\n' )
79  				result.append( "<br>" );
80  			else
81  				result.append( ch );
82  		}
83  
84  		result.append( "</body></html>" );
85  		return result.toString();
86  	}
87  
88  	public static String getFilename( String filePath )
89  	{
90  		if( filePath == null || filePath.length() == 0 )
91  			return filePath;
92  
93  		int ix = filePath.lastIndexOf( File.separatorChar );
94  		if( ix <= 0 )
95  			return filePath;
96  
97  		return filePath.substring( ix + 1, filePath.length() );
98  	}
99  
100 	public static String getDir( String filePath )
101 	{
102 		if( filePath == null || filePath.length() == 0 )
103 			return filePath;
104 
105 		int ix = filePath.lastIndexOf( File.separatorChar );
106 		if( ix <= 0 )
107 			return filePath;
108 
109 		return ensureDir( filePath.substring( 0, ix ), "" );
110 	}
111 
112 	public static String ensureDir( String dir, String basedir )
113 	{
114 		if( dir == null || dir.length() == 0 )
115 			return "";
116 
117 		File dirFile = new File( dir );
118 		if( !dirFile.isAbsolute() )
119 		{
120 			if( basedir.length() == 0 )
121 				basedir = new File( "" ).getAbsolutePath();
122 
123 			dirFile = new File( basedir, dir );
124 		}
125 
126 		dirFile.mkdirs();
127 		return dirFile.getAbsolutePath();
128 	}
129 
130 	public static String ensureFileDir( String file, String basedir )
131 	{
132 		if( file == null || file.length() == 0 )
133 			return "";
134 
135 		File dirFile = new File( basedir, file );
136 		if( !dirFile.isAbsolute() )
137 		{
138 			if( basedir.length() == 0 )
139 				basedir = new File( "" ).getAbsolutePath();
140 
141 			dirFile = new File( basedir, file );
142 		}
143 
144 		String absolutePath = dirFile.getAbsolutePath();
145 		if( !dirFile.exists() )
146 		{
147 			int ix = absolutePath.lastIndexOf( File.separatorChar );
148 			File fileDir = new File( absolutePath.substring( 0, ix ) );
149 			fileDir.mkdirs();
150 		}
151 
152 		return absolutePath;
153 	}
154 
155 	public static String ensureDir( String outputDir )
156 	{
157 		if( outputDir == null )
158 			outputDir = "";
159 
160 		File output = new File( outputDir );
161 		output.mkdirs();
162 		return outputDir;
163 	}
164 
165 	// preallocate so it does not consume memory after out-of-memory errors
166 	private static final byte[] copyBuffer = new byte[8192];
167 	public static final long READ_ALL = 0;
168 
169 	public static void openURL( String url )
170 	{
171 		String osName = System.getProperty( "os.name" );
172 
173 		try
174 		{
175 			if( osName.startsWith( "Mac OS" ) )
176 			{
177 				Class<?> fileMgr = Class.forName( "com.apple.eio.FileManager" );
178 				Method openURL = fileMgr.getDeclaredMethod( "openURL", new Class[] { String.class } );
179 				openURL.invoke( null, new Object[] { url } );
180 			}
181 			else if( osName.startsWith( "Windows" ) )
182 			{
183 				if( url.startsWith( "file:" ) )
184 				{
185 					url = URLDecoder.decode( url.substring( 5 ), "utf-8" );
186 					while( url.startsWith( "/" ) )
187 						url = url.substring( 1 );
188 
189 					url = url.replace( '/', '//' );
190 
191 					if( !new File( url ).exists() )
192 					{
193 						UISupport.showErrorMessage( "File [" + url + "] not found" );
194 						return;
195 					}
196 				}
197 
198 				Runtime.getRuntime().exec( "rundll32 url.dll,FileProtocolHandler " + url );
199 			}
200 			else
201 			{ // assume Unix or Linux
202 				String[] browsers = { "firefox", "opera", "konqueror", "epiphany", "mozilla", "netscape" };
203 				String browser = null;
204 				for( int count = 0; count < browsers.length && browser == null; count++ )
205 					if( Runtime.getRuntime().exec( new String[] { "which", browsers[count] } ).waitFor() == 0 )
206 						browser = browsers[count];
207 				if( browser == null )
208 					throw new Exception( "Could not find web browser" );
209 				else
210 					Runtime.getRuntime().exec( new String[] { browser, url } );
211 			}
212 		}
213 		catch( Exception e )
214 		{
215 			UISupport.showErrorMessage( e );
216 		}
217 	}
218 
219 	public static ByteArrayOutputStream readAll( InputStream instream, long maxSize ) throws IOException
220 	{
221 		ByteArrayOutputStream outstream = new ByteArrayOutputStream( 4096 );
222 
223 		readAndWrite( instream, maxSize, outstream );
224 
225 		outstream.close();
226 		return outstream;
227 	}
228 
229 	public static void readAndWrite( InputStream instream, long maxSize, OutputStream outstream ) throws IOException
230 	{
231 		byte[] buffer = new byte[4096];
232 		int len;
233 		int read = 0;
234 		int toRead = 4096;
235 
236 		if( maxSize > 0 )
237 		{
238 			if( read + toRead > maxSize )
239 				toRead = ( int )( maxSize - read );
240 		}
241 
242 		while( ( len = instream.read( buffer, 0, toRead ) ) > 0 )
243 		{
244 			outstream.write( buffer, 0, len );
245 			read += toRead;
246 
247 			if( maxSize > 0 )
248 			{
249 				if( read + toRead > maxSize )
250 					toRead = ( int )( maxSize - read );
251 			}
252 		}
253 	}
254 
255 	public static int copyFile( File source, File target, boolean overwrite ) throws IOException
256 	{
257 		int bytes = 0;
258 
259 		if( target.exists() )
260 		{
261 			if( overwrite )
262 				target.delete();
263 			else
264 				return -1;
265 		}
266 		else
267 		{
268 			String path = target.getAbsolutePath();
269 			int ix = path.lastIndexOf( File.separatorChar );
270 			if( ix != -1 )
271 			{
272 				path = path.substring( 0, ix );
273 				File pathFile = new File( path );
274 				if( !pathFile.exists() )
275 					pathFile.mkdirs();
276 			}
277 		}
278 
279 		BufferedInputStream in = new BufferedInputStream( new FileInputStream( source ) );
280 		BufferedOutputStream out = new BufferedOutputStream( new FileOutputStream( target ) );
281 
282 		int read = in.read( copyBuffer );
283 		while( read != -1 )
284 		{
285 			if( read > 0 )
286 			{
287 				out.write( copyBuffer, 0, read );
288 				bytes += read;
289 			}
290 			read = in.read( copyBuffer );
291 		}
292 
293 		in.close();
294 		out.close();
295 
296 		return bytes;
297 	}
298 
299 	/***
300 	 * Joins a relative url to a base url.. needs improvements..
301 	 */
302 
303 	public static String joinRelativeUrl( String baseUrl, String url )
304 	{
305 		if( baseUrl.indexOf( '?' ) > 0 )
306 			baseUrl = baseUrl.substring( 0, baseUrl.indexOf( '?' ) );
307 
308 		boolean isWindowsUrl = baseUrl.indexOf( '//' ) >= 0;
309 		boolean isUsedInUnix = File.separatorChar == '/';
310 
311 		if( isUsedInUnix && isWindowsUrl )
312 		{
313 			baseUrl = baseUrl.replace( '//', '/' );
314 			url = url.replace( '//', '/' );
315 		}
316 
317 		boolean isFile = baseUrl.startsWith( "file:" );
318 
319 		int ix = baseUrl.lastIndexOf( '//' );
320 		if( ix == -1 )
321 			ix = baseUrl.lastIndexOf( '/' );
322 
323 		// absolute?
324 		if( url.startsWith( "/" ) && !isFile )
325 		{
326 			ix = baseUrl.indexOf( "/", baseUrl.indexOf( "//" ) + 2 );
327 			return baseUrl.substring( 0, ix ) + url;
328 		}
329 
330 		// remove leading "./"
331 		while( url.startsWith( ".//" ) || url.startsWith( "./" ) )
332 			url = url.substring( 2 );
333 
334 		// remove leading "../"
335 		while( url.startsWith( "../" ) || url.startsWith( "..//" ) )
336 		{
337 			int ix2 = baseUrl.lastIndexOf( '//', ix - 1 );
338 			if( ix2 == -1 )
339 				ix2 = baseUrl.lastIndexOf( '/', ix - 1 );
340 			if( ix2 == -1 )
341 				break;
342 
343 			baseUrl = baseUrl.substring( 0, ix2 + 1 );
344 			ix = ix2;
345 
346 			url = url.substring( 3 );
347 		}
348 
349 		// remove "/./"
350 		while( url.indexOf( "/./" ) != -1 || url.indexOf( "//.//" ) != -1 )
351 		{
352 			int ix2 = url.indexOf( "/./" );
353 			if( ix2 == -1 )
354 				ix2 = url.indexOf( "//.//" );
355 
356 			url = url.substring( 0, ix2 ) + url.substring( ix2 + 2 );
357 		}
358 
359 		// remove "/../"
360 		while( url.indexOf( "/../" ) != -1 || url.indexOf( "//..//" ) != -1 )
361 		{
362 			int ix2 = -1;
363 
364 			int ix3 = url.indexOf( "/../" );
365 			if( ix3 == -1 )
366 			{
367 				ix3 = url.indexOf( "//..//" );
368 				ix2 = url.lastIndexOf( '//', ix3 - 1 );
369 			}
370 			else
371 			{
372 				ix2 = url.lastIndexOf( '/', ix3 - 1 );
373 			}
374 
375 			if( ix2 == -1 )
376 				break;
377 
378 			url = url.substring( 0, ix2 ) + url.substring( ix3 + 3 );
379 		}
380 
381 		String result = baseUrl.substring( 0, ix + 1 ) + url;
382 		if( isFile )
383 			result = result.replace( '/', File.separatorChar );
384 
385 		return result;
386 	}
387 
388 	public static boolean isEmpty( String str )
389 	{
390 		return str == null || str.trim().length() == 0;
391 	}
392 
393 	public static long writeAll( OutputStream out, InputStream in ) throws IOException
394 	{
395 		byte[] buffer = new byte[COPY_BUFFER_SIZE];
396 		long total = 0;
397 
398 		int sz = in.read( buffer );
399 		while( sz != -1 )
400 		{
401 			out.write( buffer, 0, sz );
402 			total += sz;
403 			sz = in.read( buffer );
404 		}
405 
406 		return total;
407 	}
408 
409 	public static String expandProperties( StringToStringMap values, String content, boolean leaveMissing )
410 	{
411 		int ix = content.indexOf( "${" );
412 		if( ix == -1 )
413 			return content;
414 
415 		StringBuffer buf = new StringBuffer();
416 		int lastIx = 0;
417 		while( ix != -1 )
418 		{
419 			buf.append( content.substring( lastIx, ix ) );
420 
421 			int ix2 = content.indexOf( '}', ix + 2 );
422 			if( ix2 == -1 )
423 				break;
424 
425 			int ix3 = content.lastIndexOf( "${", ix2 );
426 			if( ix3 != ix )
427 			{
428 				buf.append( content.substring( ix, ix3 ) );
429 				ix = ix3;
430 			}
431 
432 			String propertyName = content.substring( ix + 2, ix2 );
433 			Object property = values.get( propertyName );
434 			if( property != null )
435 			{
436 				buf.append( property.toString() );
437 			}
438 			else if( leaveMissing )
439 			{
440 				buf.append( "${" ).append( propertyName ).append( '}' );
441 			}
442 
443 			lastIx = ix2 + 1;
444 			ix = content.indexOf( "${", lastIx );
445 		}
446 
447 		if( lastIx < content.length() )
448 			buf.append( content.substring( lastIx ) );
449 
450 		return buf.toString();
451 	}
452 
453 	/***
454 	 * Replaces the host part of the specified endpoint with the specified host
455 	 * 
456 	 * @param endpoint
457 	 *           the endpoint to modify
458 	 * @param host
459 	 *           the host to set
460 	 * @return the modified endpoint
461 	 */
462 
463 	public static String replaceHost( String endpoint, String host )
464 	{
465 		int ix1 = endpoint.indexOf( "://" );
466 		if( ix1 < 0 )
467 			return endpoint;
468 
469 		int ix2 = endpoint.indexOf( ":", ix1 + 3 );
470 		if( ix2 == -1 || host.indexOf( ":" ) > 0 )
471 		{
472 			ix2 = endpoint.indexOf( "/", ix1 + 3 );
473 			if( ix2 == ix1 + 3 )
474 				ix2 = -1;
475 		}
476 
477 		return endpoint.substring( 0, ix1 ) + "://" + host + ( ix2 == -1 ? "" : endpoint.substring( ix2 ) );
478 	}
479 
480 	public static String getEndpointFromUrl( URL baseUrl )
481 	{
482 		StringBuffer result = new StringBuffer();
483 		result.append( baseUrl.getProtocol() ).append( "://" );
484 		result.append( baseUrl.getHost() );
485 		if( baseUrl.getPort() > 0 )
486 			result.append( ':' ).append( baseUrl.getPort() );
487 
488 		return result.toString();
489 	}
490 
491 	public static String getContentTypeFromFilename( String fileName )
492 	{
493 		return ContentTypeHandler.getContentTypeFromFilename( fileName );
494 	}
495 
496 	public static String getExtensionForContentType( String contentType )
497 	{
498 		return ContentTypeHandler.getExtensionForContentType( contentType );
499 	}
500 }