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.Closeable;
024import java.io.File;
025import java.io.FileInputStream;
026import java.io.FileOutputStream;
027import java.io.IOException;
028import java.io.OutputStream;
029import java.io.RandomAccessFile;
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( "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    private static void close( Closeable c )
183        throws IOException
184    {
185        if ( c != null )
186        {
187            try
188            {
189                c.close();
190            }
191            catch ( IOException e )
192            {
193                // ignore
194            }
195        }
196    }
197
198    public static long copyFile( File source, File target )
199        throws IOException
200    {
201        long total = 0;
202
203        FileInputStream fis = null;
204        OutputStream fos = null;
205        try
206        {
207            fis = new FileInputStream( source );
208
209            mkdirs( target.getParentFile() );
210
211            fos = new BufferedOutputStream( new FileOutputStream( target ) );
212
213            for ( byte[] buffer = new byte[1024 * 32];; )
214            {
215                int bytes = fis.read( buffer );
216                if ( bytes < 0 )
217                {
218                    break;
219                }
220
221                fos.write( buffer, 0, bytes );
222
223                total += bytes;
224            }
225
226            fos.close();
227        }
228        finally
229        {
230            close( fis );
231            close( fos );
232        }
233
234        return total;
235    }
236
237    public static byte[] readBytes( File file )
238        throws IOException
239    {
240        RandomAccessFile in = null;
241        try
242        {
243            in = new RandomAccessFile( file, "r" );
244            byte[] actual = new byte[(int) in.length()];
245            in.readFully( actual );
246            return actual;
247        }
248        finally
249        {
250            close( in );
251        }
252    }
253
254    public static void writeBytes( File file, byte[] pattern, int repeat )
255        throws IOException
256    {
257        file.deleteOnExit();
258        file.getParentFile().mkdirs();
259        OutputStream out = null;
260        try
261        {
262            out = new BufferedOutputStream( new FileOutputStream( file ) );
263            for ( int i = 0; i < repeat; i++ )
264            {
265                out.write( pattern );
266            }
267            out.close();
268        }
269        finally
270        {
271            close( out );
272        }
273    }
274
275    public static String readString( File file )
276        throws IOException
277    {
278        byte[] content = readBytes( file );
279        return new String( content, "UTF-8" );
280    }
281
282    public static void writeString( File file, String content )
283        throws IOException
284    {
285        writeBytes( file, content.getBytes( "UTF-8" ), 1 );
286    }
287
288    public static void readProps( File file, Properties props )
289        throws IOException
290    {
291        FileInputStream fis = null;
292        try
293        {
294            fis = new FileInputStream( file );
295            props.load( fis );
296        }
297        finally
298        {
299            close( fis );
300        }
301    }
302
303    public static void writeProps( File file, Properties props )
304        throws IOException
305    {
306        file.getParentFile().mkdirs();
307
308        FileOutputStream fos = null;
309        try
310        {
311            fos = new FileOutputStream( file );
312            props.store( fos, "aether-test" );
313            fos.close();
314        }
315        finally
316        {
317            close( fos );
318        }
319    }
320
321}