/*
 * FileUtils.java - 0.9.0     12/13/2000 - 15:41:52
 *
 * Copyright (C) 2000,,2003 2002 Matt Albrecht
 * groboclown@users.sourceforge.net
 * http://groboutils.sourceforge.net
 *
 *  Permission is hereby granted, free of charge, to any person obtaining a
 *  copy of this software and associated documentation files (the "Software"),
 *  to deal in the Software without restriction, including without limitation
 *  the rights to use, copy, modify, merge, publish, distribute, sublicense,
 *  and/or sell copies of the Software, and to permit persons to whom the
 *  Software is furnished to do so, subject to the following conditions:
 *
 *  The above copyright notice and this permission notice shall be included in
 *  all copies or substantial portions of the Software.
 *
 *  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 *  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 *  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
 *  THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 *  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 *  FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
 *  DEALINGS IN THE SOFTWARE.
 */
 
 
package net.sourceforge.groboutils.util.io.v1;
 
import java.util.Hashtable;
import java.util.Vector;
import java.util.Stack;

import java.io.IOException;
import java.io.FileNotFoundException;
import java.io.File;
import java.io.FilenameFilter;
import java.io.BufferedOutputStream;
import java.io.BufferedInputStream;
import java.io.FileOutputStream;
import java.io.FileInputStream;


/**
 * Simple and common file operations in a Utility class.
 *
 *
 * @author   Matt Albrecht <a href="mailto:groboclown@users.sourceforge.net">groboclown@users.sourceforge.net</a>
 * @since    December 13, 2000
 * @version  $Date: 2003/05/19 20:31:47 $
 */
public class FileUtils
{
    //---------------------------------------------------------------------
    // Public Static Fields
     
     
    //---------------------------------------------------------------------
    // Protected Static Fields
     
    protected static FileUtils s_instance = new FileUtils();
     
    //---------------------------------------------------------------------
    // Private Static Fields
     
     
    //---------------------------------------------------------------------
    // Public Fields
     
     
    //---------------------------------------------------------------------
    // Protected Fields
     
     
    //---------------------------------------------------------------------
    // Private Fields
     
     
     
     
    //---------------------------------------------------------------------
    // Constructors
     
     
    /**
     * Default Constructor
     */
    protected FileUtils()
    {
        // do nothing
    }
     
     
     
     
    //---------------------------------------------------------------------
    // Public Static Methods
     
    public static FileUtils getInstance()
    {
        return s_instance;
    }
     
     
     
    //---------------------------------------------------------------------
    // Public Methods
     
     
    /**
     * @param source the source file to copy
     * @param dir the target directory to copy the sourcefile into: the
     *     name will remain the same.
     */
    public void copyFileToDirectory( File source, File dir )
            throws IOException
    {
        copyFileToFile( source, new File( dir, source.getName() ) );
    }
    
    
    /**
     * @param source the source file to copy from.
     * @param target the target file to copy to.
     */
    public void copyFileToFile( File source, File target )
            throws IOException
    {
        FileInputStream fis = null;
        FileOutputStream fos = null;
        BufferedInputStream bis = null;
        BufferedOutputStream bos = null;

        try
        {
            fis = new FileInputStream( source );
            fos = new FileOutputStream( target );
            bis = new BufferedInputStream( fis );
            bos = new BufferedOutputStream( fos );
            
            byte buffer[] = new byte[ 4096 ];
            int size = bis.read( buffer, 0, 4096 );
            while (size > 0)
            {
                bos.write( buffer, 0, size );
                size = bis.read( buffer, 0, 4096 );
            }
        }
        finally
        {
            if (bis != null) bis.close();
            if (bos != null) bos.close();
            if (fis != null) fis.close();
            if (fos != null) fos.close();
        }
    }
    
    
    /**
     * Recursively descends into the base directory, looking for all files
     * that pass the filter.
     *
     * @param baseDir the base directory to start the search.
     * @param filter the filename filter to search. If <tt>null</tt>, then
     *      all files are allowed.
     */
    public File[] findFileRecurse( File baseDir, FilenameFilter filter )
//            throws IOException
    {
        if (baseDir == null)
        {
            throw new IllegalArgumentException( "no null arguments" );
        }
        if (filter == null)
        {
            filter = new AllFilenameFilter();
        }
        
        Stack dirStack = new Stack();
        Vector files = new Vector();
        
        dirStack.push( baseDir );
        
        while (!dirStack.empty())
        {
            baseDir = (File)dirStack.pop();
            String[] list = baseDir.list( filter );
            for (int i = list.length; --i >= 0;)
            {
                File f = new File( baseDir, list[i] );
                if (f.isDirectory())
                {
                    dirStack.push( f );
                }
                else
                if (f.isFile())
                {
                    files.addElement( f );
                }
            }
        }
        
        File[] flist = new File[ files.size() ];
        files.copyInto( flist );
        return flist;
    }
     
     
    //---------------------------------------------------------------------
    // Protected Methods
     
     
    //---------------------------------------------------------------------
    // Private Methods
     
     
 }
 
