Package org.pomizer.application

Source Code of org.pomizer.application.JarIndexer

package org.pomizer.application;

import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.Enumeration;
import java.util.List;
import java.util.jar.JarEntry;
import java.util.jar.JarFile;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import org.apache.commons.io.FileUtils;
import org.pomizer.comparator.JarIndexComparator;
import org.pomizer.comparator.RawClassInfoComparator;
import org.pomizer.constant.GlobalSettings;
import org.pomizer.model.PackageInfo;
import org.pomizer.model.RawClassInfo;
import org.pomizer.model.RawJarInfo;
import org.pomizer.render.JarIndexRenderer;
import org.pomizer.util.ClassUtils;
import org.pomizer.util.JavaUtils;
import org.pomizer.util.StringUtils;

public class JarIndexer {

    public static void main(String[] args) {

        if (args.length < 2) {
            System.out
                    .println("Application usage: <program> <version> <base path 1> [<base path 2> ... [<base path N>]] \n");
            System.exit(1);
        }

        String version = args[0];

        List<String> basePaths = new ArrayList<String>();
        for (int i = 1; i < args.length; i++) {
            JavaUtils.checkDirectoryExists(args[i]);
            if (args[i].endsWith(File.separator)) {
                basePaths.add(args[i]);
            }
            else {
                basePaths.add(args[i] + File.separator);
            }
        }

        processJarDirectory(version, basePaths);
    }

    private static void processJarDirectory(final String version, final List<String> basePaths) {

        List<RawJarInfo> jarNames = new ArrayList<RawJarInfo>();
        List<PackageInfo> packageNames = new ArrayList<PackageInfo>();
        List<RawClassInfo> classNames = new ArrayList<RawClassInfo>();

        try {

            Collections.sort(basePaths);

            for (int i = 0; i < basePaths.size(); i++) {

                JavaUtils.printToConsole("Scanning directory \"" + basePaths.get(i) + "\" for JAR files...");

                Collection<File> jarFiles = FileUtils.listFiles(new File(basePaths.get(i)), new String[] { "jar" },
                        true);

                JavaUtils.printToConsole("Found " + jarFiles.size() + " files");
                processClasses(basePaths.get(i), i, jarFiles, jarNames, packageNames, classNames);
            }
            sortIndeces(jarNames, packageNames, classNames);
            saveIndeces(version, basePaths, jarNames, packageNames, classNames);

            JavaUtils.printToConsole("Finished");

        }
        catch (IOException e) {
            e.printStackTrace();
        }
        catch (Exception e) {
            e.printStackTrace();
        }
    }

    private static void saveIndeces(final String version, final List<String> basePaths, final List<RawJarInfo> jarNames,
            final List<PackageInfo> packageNames, final List<RawClassInfo> classNames) throws IOException {

        JavaUtils.printToConsole("Saving index to file ...");
        FileWriter fileWritter = null;
        try {
            fileWritter = new FileWriter(JavaUtils.getPathToFileInCurrentDirectory(GlobalSettings.INDEX_FILE_NAME));
            JarIndexRenderer.writeHeader(fileWritter, version, basePaths.size(), jarNames.size(), packageNames.size(),
                    classNames.size());
            JarIndexRenderer.writeBasePaths(fileWritter, basePaths);
            JarIndexRenderer.writeJarFiles(fileWritter, jarNames);
            JarIndexRenderer.writePackageNames(fileWritter, packageNames);
            JarIndexRenderer.writeClassNames(fileWritter, classNames);
        }
        finally {
            if (null != fileWritter) {
                try {
                    fileWritter.flush();
                    fileWritter.close();
                }
                catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }

    private static void sortIndeces(final List<RawJarInfo> jarNames, final List<PackageInfo> packageNames,
            final List<RawClassInfo> classNames) throws Exception {
        JavaUtils.printToConsole("Sorting indeces ...");
       
        RawClassInfoComparator rawClassInfoComparator = new RawClassInfoComparator();
       
        Collections.sort(jarNames);
        Collections.sort(packageNames);
        Collections.sort(classNames, rawClassInfoComparator);
       
        JavaUtils.printToConsole("Calculating index information ...");
        int classListLength = classNames.size();
        for (int i = 0; i < classListLength; i++) {
            RawClassInfo classInfo = classNames.get(i);
            int j = i + 1;
            while ((j < classListLength) && (0 == rawClassInfoComparator.compare(classInfo, classNames.get(j)))) {
                RawClassInfo classInfoToMerge = classNames.get(j);
                for (int k = 0; k < classInfoToMerge.jarInfoList.size(); k++) {
                    if (-1 == classInfo.jarInfoList.indexOf(classInfoToMerge.jarInfoList.get(k))) {
                        classInfo.jarInfoList.add(classInfoToMerge.jarInfoList.get(k));
                    }
                }
                classNames.remove(j);
                classListLength--;
            }
        }

        adjustSortedIndeces(jarNames, packageNames, classNames);
    }

    private static void adjustSortedIndeces(final List<RawJarInfo> jarNames, final List<PackageInfo> packageNames,
            final List<RawClassInfo> classNames) throws Exception {
       
        JarIndexComparator jarIndexComparator = new JarIndexComparator(jarNames);
        for (int i = 0; i < classNames.size(); i++) {
            RawClassInfo classInfo = classNames.get(i);
           
            List<Integer> jarFileIndeces = new ArrayList<Integer>();
            for (int j = 0; j < classInfo.jarInfoList.size(); j++) {
                int jarIndex = Collections.binarySearch(jarNames, classInfo.jarInfoList.get(j));
                if (jarIndex < 0) {
                    throw new Exception("Unknown jar \"" + classInfo.jarInfoList.get(j).name + "\" for class \"" + classInfo.name
                            + "\"");
                }
                jarFileIndeces.add(jarIndex);
            }
            Collections.sort(jarFileIndeces, jarIndexComparator);
            classInfo.jarFileIndeces = new int[jarFileIndeces.size()];
            for (int j = 0; j < jarFileIndeces.size(); j++) {
                classInfo.jarFileIndeces[j] = jarFileIndeces.get(j);
            }
               
            int packageIndex = Collections.binarySearch(packageNames, classInfo.packageInfo);
            if (packageIndex < 0) {
                throw new Exception("Unknown package \"" + classInfo.packageInfo.name + "\" for class \""
                        + classInfo.name + "\"");
            }
            classInfo.packageIndex = packageIndex;
           
            List<Integer> packageJarIndeces = packageNames.get(packageIndex).jarIndeces;
            for (int j = 0; j < jarFileIndeces.size(); j++) {
                if (-1 == packageJarIndeces.indexOf(jarFileIndeces.get(j))) {
                    packageJarIndeces.add(jarFileIndeces.get(j));
                }
            }
        }

        for (int i = 0; i < packageNames.size(); i++) {
            Collections.sort(packageNames.get(i).jarIndeces, jarIndexComparator);
        }
    }

    private static void processClasses(final String basePath, final int basePathIndex, Collection<File> jarFiles,
            List<RawJarInfo> jarNames, List<PackageInfo> packageNames, List<RawClassInfo> classNames) throws IOException {
        final String CLASS_EXTENSION = ".class";
        final Pattern ANONYMOUS_CLASS_NAME = Pattern.compile("^([a-zA-Z_][a-zA-Z\\d_]*)\\$?\\d*$");

        int basePathLength = basePath.length();
        for (File foundFile : jarFiles) {
            JavaUtils.printToConsole("Processing " + foundFile.getAbsolutePath() + "...");

            String relativeJarFileName = foundFile.getAbsolutePath().substring(basePathLength);
            if (!JavaUtils.containsDirectoriesInPath(relativeJarFileName, "JRE", "JRE64", "TMP")) {
                RawJarInfo currentJarInfo = new RawJarInfo(relativeJarFileName, basePathIndex,
                        foundFile.lastModified());
                jarNames.add(currentJarInfo);

                JarFile jarFile = new JarFile(foundFile);
                final Enumeration<JarEntry> entries = jarFile.entries();
                while (entries.hasMoreElements()) {
                    final JarEntry entry = entries.nextElement();
                    String entryName = entry.getName();
                    if (entryName.endsWith(CLASS_EXTENSION)) {
                        entryName = entryName.substring(0, entryName.length() - CLASS_EXTENSION.length());
                        entryName = entryName.replace('/', '.');

                        String packageName = ClassUtils.getPackageFromFullName(entryName);
                        String className = ClassUtils.getClassNameFromFullName(entryName);

                        if (!StringUtils.isNullOrEmpty(packageName)) {

                            // Handling only full class name and nested class names
                            if (StringUtils.getCharOccurenceCount(className, '$') < 2) {
                               
                                Matcher anonymousClassNameMatcher = ANONYMOUS_CLASS_NAME.matcher(className);
                                if (anonymousClassNameMatcher.find()) {
                                    className = anonymousClassNameMatcher.group(1);
                                }
                                else {
                                    className = className.replace('$', '.');
                                }
   
                                PackageInfo packageInfo = new PackageInfo();
                                packageInfo.name = packageName;
                                int packageIndex = packageNames.indexOf(packageInfo);
                                if (-1 == packageIndex) {
                                    packageNames.add(packageInfo);
                                }
                                else {
                                    packageInfo = packageNames.get(packageIndex);
                                }
   
                                RawClassInfo classInfo = new RawClassInfo();
                                classInfo.name = className;
                                classInfo.jarInfoList.add(currentJarInfo);
                                classInfo.packageInfo = packageInfo;
                                classNames.add(classInfo);
                            }
                        }
                    }
                }
            }
        }
    }
}
TOP

Related Classes of org.pomizer.application.JarIndexer

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.