Friday, August 10, 2012

ClassFind Utility

Often we come across need to search for a class file in ear and wars. This tool will help to search class file inside ears/jars/ears/rar

This is the next version of JarFind utility.



import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.util.Collection;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Map;
import java.util.Stack;
import java.util.TreeSet;
import java.util.jar.JarFile;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;

public class SearchArchive {

    static Map<String, String> locationMap = new HashMap<String, String>();
    public static final String intend = "------";
    private Stack<String> node = new Stack<String>();
    private File archive;

    public SearchArchive(File archive) {
        this.archive = archive;
        System.out.println();
        System.out.println("Scanning :" + archive.getAbsolutePath());
    }

    public SearchArchive(String archive) {
        this(new File(archive));
    }

    public InputStream find(String name) {

        ZipInputStream root;
        try {
            root = new ZipInputStream(new BufferedInputStream(
                    new FileInputStream(archive)));

            return find(root, name); // enter the recursion
        } catch (FileNotFoundException e) {
            // TODO Auto-generated catch block
            System.out.println("Error occured while searching "
                    + archive.getName());
            System.out.println(e.toString());
        }
        return null;

    }

    public static boolean isArchive(String name) {
        String s = name.toLowerCase();
        return s.endsWith(".jar") || s.endsWith(".war") || s.endsWith(".zip")
                || s.endsWith(".ear");
    }

    protected InputStream find(ZipInputStream in, String name) {

           try {
            ZipEntry entry;
            while ((entry = in.getNextEntry()) != null) {
                String entryName = entry.getName();

                if (entryName.endsWith(name)) {
                    node.push(entryName);
                    print(entryName + "*********");
                    String value = locationMap.get(archive.getAbsolutePath());
                    if (value == null)
                        value = "";
                    else
                        value = value + ",";

                    for (String nodeElement : node) {
                        value = value + ">>" + nodeElement;
                    }

                    locationMap.put(archive.getAbsolutePath(), value);
                    node.pop();
                    // return in;
                }

                if (isArchive(entryName)) {
                                       node.push(entryName);
                    print(entryName);
                    // System.out.println("Scanning file :" + entryName);
                    InputStream result = find(new ZipInputStream(in), name);
                    if (result != null) {
                        return result;
                    }
                }
                in.closeEntry();
            }
            if (node.size() > 0) {
                node.pop();
            }
        } catch (Exception e) {
            System.out.println("Error occured while searching "
                    + archive.getName() + " >>" + node.peek());
            System.out.println(e.toString());

        }
        return null; // nothing found
    }

    private void print(String entryName) {
        StringBuffer sb = new StringBuffer();
        for (int i = 0; i < node.size(); i++) {
            sb.append(intend);
        }
        sb.append(entryName);
        System.out.println(sb);
    }

    public static void main(String args[]) throws IOException {
        if (args.length != 2) {
            System.out
                    .println("Usage java SearchArchive <location> <classname>");
            System.out.println("Example");
            System.out
                    .println("java SearchArchive \"c:\\program files\\application\" MyClass.class");
            System.exit(0);
        }
        String location = args[0];
        String className = args[1];
        searchDir(location, className);
        printResult();
    }

    public static void searchDir(String location, String className)
            throws IOException {
        File file = new File(location);
        for (File afile : file.listFiles()) {

            if (!afile.isDirectory() && afile.getName().endsWith(".jar")) {
                // for Jar file JarFile.class is better than the ZipInputStream
                // in terms of performance.
                searchJarFile(afile, className);
            }

            else if (!afile.isDirectory() && isArchive(afile.getName())) {
                // since we have to deal with nested archive here
                // we are using ZipInputStream
                SearchArchive af = new SearchArchive(afile);
                af.find(className);
            }
            if (afile.isDirectory())
                searchDir(afile.getPath(), className);
        }
    }

    private static void searchJarFile(File afile, String className) {
        try {
            JarFile jarfile = new JarFile(afile);
            System.out.println();
            System.out.println("Scanning :" + afile);
            Enumeration enumeration = jarfile.entries();
            while (enumeration.hasMoreElements()) {

                String s2 = enumeration.nextElement().toString();
                s2 = s2.replace('/', '.');
                if (s2.indexOf(className) != -1) {
                    String value = locationMap.get(afile.getAbsolutePath());
                    if (value != null) {
                        value = value + "," + s2;
                    } else {
                        value = s2;
                    }
                    locationMap.put(afile.getAbsolutePath(), value);

                }
            }

        } catch (IOException e) {
            // TODO Auto-generated catch block
            System.out.println("Error occured while searching "
                    + afile.getName());
            System.out.println(e.toString());

        }
    }

    private static void printResult() {
        System.out.println("");
        System.out.println("");
        System.out.println("");
        System.out.println("------------------");
        System.out.println("Found in " + locationMap.size() + " files");
        System.out.println("------------------");
        System.out.println("");
        for (String key : new TreeSet<String>(locationMap.keySet())) {
            System.out.println(key);
            String value = locationMap.get(key);
            String splitValue[] = value.split(",");
            for (String sValue : splitValue) {
                System.out.println(intend + sValue);
            }
            System.out.println();

        }

    }
}

No comments: