001package org.eclipse.aether.internal.test.util; 002 003/* 004 * Licensed to the Apache Software Foundation (ASF) under one 005 * or more contributor license agreements. See the NOTICE file 006 * distributed with this work for additional information 007 * regarding copyright ownership. The ASF licenses this file 008 * to you under the Apache License, Version 2.0 (the 009 * "License"); you may not use this file except in compliance 010 * with the License. You may obtain a copy of the License at 011 * 012 * http://www.apache.org/licenses/LICENSE-2.0 013 * 014 * Unless required by applicable law or agreed to in writing, 015 * software distributed under the License is distributed on an 016 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 017 * KIND, either express or implied. See the License for the 018 * specific language governing permissions and limitations 019 * under the License. 020 */ 021 022import java.io.BufferedOutputStream; 023import java.io.File; 024import java.io.FileInputStream; 025import java.io.FileOutputStream; 026import java.io.IOException; 027import java.io.OutputStream; 028import java.io.RandomAccessFile; 029import java.nio.charset.StandardCharsets; 030import java.util.ArrayList; 031import java.util.Collection; 032import java.util.Properties; 033import java.util.UUID; 034 035/** 036 * Provides utility methods to read and write (temporary) files. 037 */ 038public class TestFileUtils 039{ 040 041 private static final File TMP = new File( System.getProperty( "java.io.tmpdir" ), "aether-" 042 + UUID.randomUUID().toString().substring( 0, 8 ) ); 043 044 static 045 { 046 Runtime.getRuntime().addShutdownHook( new Thread() 047 { 048 @Override 049 public void run() 050 { 051 try 052 { 053 deleteFile( TMP ); 054 } 055 catch ( IOException e ) 056 { 057 e.printStackTrace(); 058 } 059 } 060 } ); 061 } 062 063 private TestFileUtils() 064 { 065 // hide constructor 066 } 067 068 public static void deleteTempFiles() 069 throws IOException 070 { 071 deleteFile( TMP ); 072 } 073 074 public static void deleteFile( File file ) 075 throws IOException 076 { 077 if ( file == null ) 078 { 079 return; 080 } 081 082 Collection<File> undeletables = new ArrayList<File>(); 083 084 delete( file, undeletables ); 085 086 if ( !undeletables.isEmpty() ) 087 { 088 throw new IOException( "Failed to delete " + undeletables ); 089 } 090 } 091 092 private static void delete( File file, Collection<File> undeletables ) 093 { 094 String[] children = file.list(); 095 if ( children != null ) 096 { 097 for ( String child : children ) 098 { 099 delete( new File( file, child ), undeletables ); 100 } 101 } 102 103 if ( !del( file ) ) 104 { 105 undeletables.add( file.getAbsoluteFile() ); 106 } 107 } 108 109 private static boolean del( File file ) 110 { 111 for ( int i = 0; i < 10; i++ ) 112 { 113 if ( file.delete() || !file.exists() ) 114 { 115 return true; 116 } 117 } 118 return false; 119 } 120 121 public static boolean mkdirs( File directory ) 122 { 123 if ( directory == null ) 124 { 125 return false; 126 } 127 128 if ( directory.exists() ) 129 { 130 return false; 131 } 132 if ( directory.mkdir() ) 133 { 134 return true; 135 } 136 137 File canonDir = null; 138 try 139 { 140 canonDir = directory.getCanonicalFile(); 141 } 142 catch ( IOException e ) 143 { 144 return false; 145 } 146 147 File parentDir = canonDir.getParentFile(); 148 return ( parentDir != null && ( mkdirs( parentDir ) || parentDir.exists() ) && canonDir.mkdir() ); 149 } 150 151 public static File createTempFile( String contents ) 152 throws IOException 153 { 154 return createTempFile( contents.getBytes( StandardCharsets.UTF_8 ), 1 ); 155 } 156 157 public static File createTempFile( byte[] pattern, int repeat ) 158 throws IOException 159 { 160 mkdirs( TMP ); 161 File tmpFile = File.createTempFile( "tmpfile-", ".data", TMP ); 162 writeBytes( tmpFile, pattern, repeat ); 163 return tmpFile; 164 } 165 166 public static File createTempDir() 167 throws IOException 168 { 169 return createTempDir( "" ); 170 } 171 172 public static File createTempDir( String suffix ) 173 throws IOException 174 { 175 mkdirs( TMP ); 176 File tmpFile = File.createTempFile( "tmpdir-", suffix, TMP ); 177 deleteFile( tmpFile ); 178 mkdirs( tmpFile ); 179 return tmpFile; 180 } 181 182 public static long copyFile( File source, File target ) 183 throws IOException 184 { 185 long total = 0; 186 187 FileInputStream fis = null; 188 OutputStream fos = null; 189 try 190 { 191 fis = new FileInputStream( source ); 192 193 mkdirs( target.getParentFile() ); 194 195 fos = new BufferedOutputStream( new FileOutputStream( target ) ); 196 197 for ( byte[] buffer = new byte[ 1024 * 32 ];; ) 198 { 199 int bytes = fis.read( buffer ); 200 if ( bytes < 0 ) 201 { 202 break; 203 } 204 205 fos.write( buffer, 0, bytes ); 206 207 total += bytes; 208 } 209 210 fos.close(); 211 fos = null; 212 213 fis.close(); 214 fis = null; 215 } 216 finally 217 { 218 try 219 { 220 if ( fos != null ) 221 { 222 fos.close(); 223 } 224 } 225 catch ( final IOException e ) 226 { 227 // Suppressed due to an exception already thrown in the try block. 228 } 229 finally 230 { 231 try 232 { 233 if ( fis != null ) 234 { 235 fis.close(); 236 } 237 } 238 catch ( final IOException e ) 239 { 240 // Suppressed due to an exception already thrown in the try block. 241 } 242 } 243 } 244 245 return total; 246 } 247 248 public static byte[] readBytes( File file ) 249 throws IOException 250 { 251 RandomAccessFile in = null; 252 try 253 { 254 in = new RandomAccessFile( file, "r" ); 255 byte[] actual = new byte[ (int) in.length() ]; 256 in.readFully( actual ); 257 in.close(); 258 in = null; 259 return actual; 260 } 261 finally 262 { 263 try 264 { 265 if ( in != null ) 266 { 267 in.close(); 268 } 269 } 270 catch ( final IOException e ) 271 { 272 // Suppressed due to an exception already thrown in the try block. 273 } 274 } 275 } 276 277 public static void writeBytes( File file, byte[] pattern, int repeat ) 278 throws IOException 279 { 280 file.deleteOnExit(); 281 file.getParentFile().mkdirs(); 282 OutputStream out = null; 283 try 284 { 285 out = new BufferedOutputStream( new FileOutputStream( file ) ); 286 for ( int i = 0; i < repeat; i++ ) 287 { 288 out.write( pattern ); 289 } 290 out.close(); 291 out = null; 292 } 293 finally 294 { 295 try 296 { 297 if ( out != null ) 298 { 299 out.close(); 300 } 301 } 302 catch ( final IOException e ) 303 { 304 // Suppressed due to an exception already thrown in the try block. 305 } 306 } 307 } 308 309 public static String readString( File file ) 310 throws IOException 311 { 312 byte[] content = readBytes( file ); 313 return new String( content, StandardCharsets.UTF_8 ); 314 } 315 316 public static void writeString( File file, String content ) 317 throws IOException 318 { 319 writeBytes( file, content.getBytes( StandardCharsets.UTF_8 ), 1 ); 320 } 321 322 public static void readProps( File file, Properties props ) 323 throws IOException 324 { 325 FileInputStream fis = null; 326 try 327 { 328 fis = new FileInputStream( file ); 329 props.load( fis ); 330 fis.close(); 331 fis = null; 332 } 333 finally 334 { 335 try 336 { 337 if ( fis != null ) 338 { 339 fis.close(); 340 } 341 } 342 catch ( final IOException e ) 343 { 344 // Suppressed due to an exception already thrown in the try block. 345 } 346 } 347 } 348 349 public static void writeProps( File file, Properties props ) 350 throws IOException 351 { 352 file.getParentFile().mkdirs(); 353 354 FileOutputStream fos = null; 355 try 356 { 357 fos = new FileOutputStream( file ); 358 props.store( fos, "aether-test" ); 359 fos.close(); 360 fos = null; 361 } 362 finally 363 { 364 try 365 { 366 if ( fos != null ) 367 { 368 fos.close(); 369 } 370 } 371 catch ( final IOException e ) 372 { 373 // Suppressed due to an exception already thrown in the try block. 374 } 375 } 376 } 377 378}