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.InputStream;
028import java.io.OutputStream;
029import java.nio.ByteBuffer;
030import java.nio.charset.StandardCharsets;
031
032import org.eclipse.aether.spi.io.FileProcessor;
033
034/**
035 * A simple file processor implementation to help satisfy component requirements during tests.
036 */
037public class TestFileProcessor
038    implements FileProcessor
039{
040
041    public boolean mkdirs( File directory )
042    {
043        if ( directory == null )
044        {
045            return false;
046        }
047
048        if ( directory.exists() )
049        {
050            return false;
051        }
052        if ( directory.mkdir() )
053        {
054            return true;
055        }
056
057        File canonDir = null;
058        try
059        {
060            canonDir = directory.getCanonicalFile();
061        }
062        catch ( IOException e )
063        {
064            return false;
065        }
066
067        File parentDir = canonDir.getParentFile();
068        return ( parentDir != null && ( mkdirs( parentDir ) || parentDir.exists() ) && canonDir.mkdir() );
069    }
070
071    public void write( File file, String data )
072        throws IOException
073    {
074        mkdirs( file.getParentFile() );
075
076        FileOutputStream fos = null;
077        try
078        {
079            fos = new FileOutputStream( file );
080
081            if ( data != null )
082            {
083                fos.write( data.getBytes( StandardCharsets.UTF_8 ) );
084            }
085
086            fos.close();
087            fos = null;
088        }
089        finally
090        {
091            try
092            {
093                if ( fos != null )
094                {
095                    fos.close();
096                }
097            }
098            catch ( final IOException e )
099            {
100                // Suppressed due to an exception already thrown in the try block.
101            }
102        }
103    }
104
105    public void write( File target, InputStream source )
106        throws IOException
107    {
108        mkdirs( target.getAbsoluteFile().getParentFile() );
109
110        OutputStream fos = null;
111        try
112        {
113            fos = new BufferedOutputStream( new FileOutputStream( target ) );
114
115            copy( fos, source, null );
116
117            fos.close();
118            fos = null;
119        }
120        finally
121        {
122            try
123            {
124                if ( fos != null )
125                {
126                    fos.close();
127                }
128            }
129            catch ( final IOException e )
130            {
131                // Suppressed due to an exception already thrown in the try block.
132            }
133        }
134    }
135
136    public void copy( File source, File target )
137        throws IOException
138    {
139        copy( source, target, null );
140    }
141
142    public long copy( File source, File target, ProgressListener listener )
143        throws IOException
144    {
145        long total = 0;
146
147        InputStream fis = null;
148        OutputStream fos = null;
149        try
150        {
151            fis = new FileInputStream( source );
152
153            mkdirs( target.getAbsoluteFile().getParentFile() );
154
155            fos = new BufferedOutputStream( new FileOutputStream( target ) );
156
157            total = copy( fos, fis, listener );
158
159            fos.close();
160            fos = null;
161
162            fis.close();
163            fis = null;
164        }
165        finally
166        {
167            try
168            {
169                if ( fos != null )
170                {
171                    fos.close();
172                }
173            }
174            catch ( final IOException e )
175            {
176                // Suppressed due to an exception already thrown in the try block.
177            }
178            finally
179            {
180                try
181                {
182                    if ( fis != null )
183                    {
184                        fis.close();
185                    }
186                }
187                catch ( final IOException e )
188                {
189                    // Suppressed due to an exception already thrown in the try block.
190                }
191            }
192        }
193
194        return total;
195    }
196
197    private long copy( OutputStream os, InputStream is, ProgressListener listener )
198        throws IOException
199    {
200        long total = 0L;
201
202        ByteBuffer buffer = ByteBuffer.allocate( 1024 * 32 );
203        byte[] array = buffer.array();
204
205        while ( true )
206        {
207            int bytes = is.read( array );
208            if ( bytes < 0 )
209            {
210                break;
211            }
212
213            os.write( array, 0, bytes );
214
215            total += bytes;
216
217            if ( listener != null && bytes > 0 )
218            {
219                try
220                {
221                    buffer.rewind();
222                    buffer.limit( bytes );
223                    listener.progressed( buffer );
224                }
225                catch ( Exception e )
226                {
227                    // too bad
228                }
229            }
230        }
231
232        return total;
233    }
234
235    public void move( File source, File target )
236        throws IOException
237    {
238        target.delete();
239
240        if ( !source.renameTo( target ) )
241        {
242            copy( source, target );
243
244            target.setLastModified( source.lastModified() );
245
246            source.delete();
247        }
248    }
249
250}