package com.cku.util;

import java.io.File;
import java.io.FileFilter;
import java.io.IOException;
import java.net.URL;
import java.net.URLDecoder;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.List;
import java.util.regex.Pattern;

public class FileScanUtils 
{
	private static boolean excludeInner = true;
    private static boolean checkInOrEx = true;
    private static List<String> fileFilters = null;
    private static String fileExt;
    
    public static void main(String[] args) 
    {
    	printAllFiles("com.sunrise.lib.*.utils", ".class");
    }
    
    public static void printAllFiles(String packageName, String ext)
    {
    	List<File> list = scanAllFiles(packageName, ext);
    	if(list != null)
    	{
	    	for(File f : list)
	    	{
	    		System.out.println(f.getName());
	    	}
    	}
    }
    
    public static List<File> scanAllFiles(String packageName, String ext)
    {
    	fileFilters = null;
    	fileExt = ext;
    	int index = packageName.indexOf("*");
    	String basePackage = packageName;
    	if(index > -1)
    	{
    		fileFilters = getFileFilters(packageName);
    		basePackage = packageName.substring(0, index);
    	}
    	return getAllFiles(basePackage, true);
    }

	private static List<File> getAllFiles(String basePackage, boolean recursive) 
	{
		List<File> files = new ArrayList<File>();
        String packageName = basePackage;
        if (packageName.endsWith(".")) {
        	packageName = packageName.substring(0, packageName.lastIndexOf('.'));
        }
        String package2Path = packageName.replace('.', '/');
        Enumeration<URL> dirs;
        try {
            dirs = Thread.currentThread().getContextClassLoader().getResources(package2Path);
            while (dirs.hasMoreElements()) {
                URL url = dirs.nextElement();
                String protocol = url.getProtocol();
                if ("file".equals(protocol)) {
                    System.out.println("扫描file类型的文件....");
                    String filePath = URLDecoder.decode(url.getFile(), "UTF-8");
                    doScanFilesByFile(files, packageName, filePath, recursive);
                } else {
                    System.out.println("不支持的文件系统....");
                }
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
        return files;
	}

	private static void doScanFilesByFile(List<File> files, String packageName, String packagePath, boolean recursive) 
	{
		 File dir = new File(packagePath);
	        if (!dir.exists() || !dir.isDirectory()) {
	            return;
	        }
	        final boolean fileRecursive = recursive;
	        File[] dirfiles = dir.listFiles(new FileFilter() {

	            // 自定义文件过滤规则
	            public boolean accept(File file) {
	                if (file.isDirectory()) {
	                    return fileRecursive;
	                }
	                String filename = file.getPath() + File.separator + file.getName();
	                if (excludeInner && filename.indexOf('$') != -1) {
	                    return false;
	                }
	                return filterFileName(filename);
	            }
	        });
	        for (File file : dirfiles) {
	            if (file.isDirectory()) {
	            	doScanFilesByFile(files, packageName + "." + file.getName(), file.getAbsolutePath(), recursive);
	            } else {
	                files.add(file);
	            }
	        }
		
	}

	protected static boolean filterFileName(String fileName) {
		if (fileExt != null && !fileName.endsWith(fileExt)) {
            return false;
        }
        if (null == fileFilters || fileFilters.isEmpty()) {
            return true;
        }
        String tmpName = fileName.substring(0, (fileName.length() - ((fileExt != null) ? fileExt.length() : 0)));
        tmpName = tmpName.replaceAll("\\\\", "\\.");
        tmpName = tmpName.replaceAll("/", "\\.");
        boolean flag = false;
        for (String str : fileFilters) {
            String tmpreg = str;
            Pattern p = Pattern.compile(tmpreg);
            if (p.matcher(tmpName).find()) {
                flag = true;
            }
        }
        return (checkInOrEx && flag) || (!checkInOrEx && !flag);
	}

	private static List<String> getFileFilters(String pathName)
	{
		List<String> list = new ArrayList<String>();
    	String temp = pathName;
    	temp = temp.replaceAll("\\*", "[A-Za-z]+");
    	temp = temp.replaceAll("\\.", "\\\\.");
        list.add(temp);
		return list;
	}
}
