package jlibs.core.io;

import jlibs.core.lang.ImpossibleException;
import jlibs.core.graph.WalkerUtil;
import jlibs.core.graph.Processor;
import jlibs.core.graph.Path;
import jlibs.core.graph.Walker;
import jlibs.core.graph.walkers.PreorderWalker;

import java.io.File;
import java.io.IOException;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.net.URL;
import java.net.MalformedURLException;

import org.jetbrains.annotations.NotNull;

/**
 * @author Santhosh Kumar T
 */
public class FileUtil{
    public static final String PATH_SEPARATOR = File.pathSeparator;
    public static final String SEPARATOR = File.separator;
    public static final String LINE_SEPARATOR = System.getProperty("line.separator");

    public static @NotNull URL toURL(@NotNull File file){
        try{
            return file.toURI().toURL();
        }catch(MalformedURLException ex){
            throw new ImpossibleException(ex);
        }
    }

    public static void delete(@NotNull File file) throws IOException{
        if(!file.exists())
            return;
        
        if(file.isFile()){
            if(!file.delete())
                throw new IOException("couldn't delete file :"+file);
        }else{
            try{
                WalkerUtil.walk(new PreorderWalker<File>(file, FileNavigator.INSTANCE), new Processor<File>(){
                    @Override
                    public boolean preProcess(File file, Path path){
                        return true;
                    }

                    @Override
                    public void postProcess(File file, Path path){
                        try{
                            if(!file.delete())
                                throw new IOException("couldn't delete file :"+file);
                        }catch(IOException ex){
                            throw new RuntimeException(ex);
                        }
                    }
                });
            }catch(RuntimeException ex){
                if(ex.getCause() instanceof IOException)
                    throw (IOException)ex.getCause();
                else
                    throw ex;
            }
        }
    }

    public static void mkdir(File file) throws IOException{
        if(!file.mkdir())
            throw new IOException("couldn't create directory: "+file);
    }

    public static void mkdirs(File file) throws IOException{
        if(!file.mkdirs())
            throw new IOException("couldn't create directory: "+file);
    }

    public static void copy(File sourceFile, final File targetFile) throws IOException{
        if(sourceFile.isFile())
            IOUtil.pump(new FileInputStream(sourceFile), new FileOutputStream(targetFile), true, true);
        else{
            try{
                mkdirs(targetFile);

                Walker<File> walker = new PreorderWalker<File>(sourceFile, FileNavigator.INSTANCE);
                walker.next();
                WalkerUtil.walk(walker, new Processor<File>(){
                    File target = targetFile;

                    @Override
                    public boolean preProcess(File source, Path path){
                        target = new File(target, source.getName());
                        try{
                            if(source.isDirectory())
                                mkdir(target);
                            else
                                IOUtil.pump(new FileInputStream(source), new FileOutputStream(target), true, true);
                        }catch(IOException ex){
                            throw new RuntimeException(ex);
                        }
                        return true;
                    }

                    @Override
                    public void postProcess(File source, Path path){
                        target = target.getParentFile();
                    }
                });
            }catch(IOException ex){
                if(ex.getCause() instanceof IOException)
                    throw (IOException)ex.getCause();
                else
                    throw ex;
            }
        }
    }

    public static void main(String[] args) throws IOException{
        copy(new File("/Users/santhosh/Downloads/xml-schemas"), new File("/Users/santhosh/Downloads/xml-schemas1"));
    }
}

@@ -262,105 +262,9 @@
 .io.
-File;%0Aimport java.io.IOException;%0Aimport java.io.FileInputStream;%0Aimport java.io.FileOutputStream
+*
 ;%0Aim
@@ -848,32 +848,156 @@
        %7D%0A    %7D%0A%0A
+    /*-------------------------------------------------%5B Delete %5D---------------------------------------------------*/%0A    %0A
     public stati
@@ -2197,32 +2197,1298 @@
        %7D%0A    %7D%0A%0A
+    public static void deleteEmptyDirs(File directory) throws IOException%7B%0A        if(directory.isFile())%0A            return;%0A        Walker%3CFile%3E walker = new PreorderWalker%3CFile%3E(directory, new FileNavigator(new FileFilter()%7B%0A            @Override%0A            public boolean accept(File file)%7B%0A                return file.isDirectory();%0A            %7D%0A        %7D));%0A        try%7B%0A            WalkerUtil.walk(walker, new Processor%3CFile%3E()%7B%0A                @Override%0A                public boolean preProcess(File file, Path path)%7B%0A                    return true;%0A                %7D%0A%0A                @Override%0A                public void postProcess(File file, Path path)%7B%0A                    try%7B%0A                        if(file.list().length==0)%0A                            delete(file);%0A                    %7Dcatch(IOException ex)%7B%0A                        throw new RuntimeException(ex);%0A                    %7D%0A                %7D%0A            %7D);%0A        %7Dcatch(RuntimeException ex)%7B%0A            if(ex.getCause() instanceof IOException)%0A                throw (IOException)ex.getCause();%0A            else%0A                throw ex;%0A        %7D%0A    %7D%0A%0A    /*-------------------------------------------------%5B MkDir %5D---------------------------------------------------*/%0A    %0A
     public stati

delete empty dirs method