All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.rhq.test.DuplicatePackagesDetector Maven / Gradle / Ivy

The newest version!
package org.rhq.test;

import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;

/**
 * This will walk a set of jar files and directories and print out
 * packages that are found in more than one jar file.
 *
 * @author John Mazzitelli
 */
public class DuplicatePackagesDetector {

    static Visitor visitor;

    static boolean verbose = Boolean.getBoolean("rhq.verbose");

    private static void debug(String msg) {
        if (verbose) {
            System.out.println(msg);
        }
    }

    /**
     * Each argument is the name of a .jar file or a directory that will
     * be walked looking for jar files.
     */
    public static void main(String[] args) {
        visitor = new Visitor();

        if (args.length == 0) {
            // no arguments given, try to use the user's local maven repo of all the RHQ libraries
            String homeEnv = System.getenv("HOME");
            if (homeEnv != null && homeEnv.length() > 0) {
                String s = File.separator;
                args = new String[] { homeEnv + s + ".m2" + s + "repository" + s + "org" + s + "rhq" };
            }
        }

        for (String arg : args) {
            File file = new File(arg);
            debug("Processing [" + file.getAbsolutePath() + "]...");
            if (file.exists()) {
                if (file.isDirectory()) {
                    processDirectory(file);
                } else {
                    processFile(file);
                }
            } else {
                System.err.println("File does not exist: " + arg);
            }

        }

        // print out what we've found
        System.out.println("======================================================================");
        Map> map = visitor.getMap(); // key=dir (pkg) name; value=list of jars where dir is
        for (Entry> entry : map.entrySet()) {
            String packageName = entry.getKey();
            Set jarFiles = entry.getValue();
            if (jarFiles.size() > 1 || verbose) {
                System.out.println(packageName);
                for (String jarFile : jarFiles) {
                    System.out.println("\t" + jarFile);
                }
            }
        }
    }

    public static void processDirectory(File dir) {
        File[] dirEntries = dir.listFiles();
        if (dirEntries != null) {
            for (File dirEntry : dirEntries) {
                if (dirEntry.isDirectory()) {
                    processDirectory(dirEntry);
                } else {
                    processFile(dirEntry);
                }
            }
        }
    }

    public static void processFile(File file) {
        // if its not a .jar file, ignore it
        if (!file.getName().endsWith(".jar")) {
            debug("Not a jar file, skipping [" + file.getAbsolutePath() + "]");
            return;
        }

        try {
            walkZipFile(file, visitor);
        } catch (Exception e) {
            System.err.println("Cannot process jar file [" + file + "]:" + e.toString());
        }
    }

    /**
     * Walks the entries of a zip file, allowing a listener to "visit" each node and perform tasks on
     * the zip entry.
     *
     * @param zipFile the zip file to walk
     * @param visitor the object that will be notified for each entry in the zip file
     *
     * @throws Exception if any errors occur during the reading or visiting
     */
    public static void walkZipFile(File zipFile, Visitor visitor) throws Exception {
        FileInputStream fis = new FileInputStream(zipFile);
        try {
            InputStream zipContent = new BufferedInputStream(fis);
            try {
                ZipInputStream zis = new ZipInputStream(zipContent);

                ZipEntry e;
                while ((e = zis.getNextEntry()) != null) {
                    boolean keepGoing = visitor
                        .visit(e, zis, (verbose) ? zipFile.getAbsolutePath() : zipFile.getName());
                    if (!keepGoing) {
                        break; // visitor told us to stop
                    }
                }
            } finally {
                zipContent.close();
            }
        } finally {
            fis.close();
        }
    }

    public static class Visitor {
        // keyed on directory name - the value is all the jar files that had that directory in it
        private Map> map = new HashMap>();

        public Map> getMap() {
            return map;
        }

        /**
         * Visits a specific zip file entry. Implementations can read the entry content from the given stream but
         * must not close the stream - the caller of this method will handle the lifecycle of the stream.
         *
         * @param entry the entry being visited
         * @param stream the stream containing the zip content
         * @param zipFilePath the actual zip file that is being walked
         * @return the visitor should return true if everything is OK and processing of the zip content
         *         should continue; returning false will tell the walker to abort further traversing
         *         of the zip content.
         * @throws Exception if the visitation failed for some reason - this will abort further walking of the zip content
         */
        public boolean visit(ZipEntry entry, ZipInputStream stream, String zipFilePath) throws Exception {
            if (!entry.isDirectory()) {
                String[] dirAndName = splitPathName(entry.getName());
                if (dirAndName != null) {
                    String dirName = dirAndName[0];
                    Set zipFilePaths = map.get(dirName);
                    if (zipFilePaths == null) {
                        zipFilePaths = new HashSet();
                        map.put(dirName, zipFilePaths);
                    }
                    zipFilePaths.add(zipFilePath);
                }
            }
            return true;
        }

        /**
         * Splits the path from the filename and returns as a 2-dimension array.
         * If the full name does NOT end with .class, null is returned.
         * Thus, this only processes Java classes.
         * @param fullname the name to split
         * @return first element is the path, second element is the filename
         */
        private String[] splitPathName(String fullname) {
            if (fullname.endsWith(".class")) {
                int lastSlash = fullname.lastIndexOf('/');
                if (lastSlash >= 0) {
                    return new String[] { fullname.substring(0, lastSlash), fullname.substring(lastSlash + 1) };
                } else {
                    return new String[] { "", fullname };
                }
            } else {
                return null;
            }
        }
    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy