0

我需要返回 java 项目 (zip/jar) 包含的所有包、类...。我想 QDox 可以做到这一点。我找到了那个类:http ://www.jarvana.com/jarvana/view/com/ning/metrics.serialization-all/2.0.0-pre5/metrics.serialization-all-2.0.0-pre5-jar-with -dependencies-sources.jar!/com/thoughtworks/qdox/tools/QDoxTester.java?format=ok

package com.thoughtworks.qdox.tools;

import com.thoughtworks.qdox.JavaDocBuilder;
import com.thoughtworks.qdox.directorywalker.DirectoryScanner;
import com.thoughtworks.qdox.directorywalker.FileVisitor;
import com.thoughtworks.qdox.directorywalker.SuffixFilter;
import com.thoughtworks.qdox.parser.ParseException;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.PrintStream;
import java.util.Enumeration;
import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;

/**
 * Tool for testing that QDox can parse Java source code.
 *
 * @author Joe Walnes
 */
public class QDoxTester {

    public static interface Reporter {
        void success(String id);

        void parseFailure(String id, int line, int column, String reason);

        void error(String id, Throwable throwable);
    }

    private final Reporter reporter;

    public QDoxTester(Reporter reporter) {
        this.reporter = reporter;
    }

    public void checkZipOrJarFile(File file) throws IOException {
        ZipFile zipFile = new ZipFile(file);
        Enumeration entries = zipFile.entries();
        while (entries.hasMoreElements()) {
            ZipEntry zipEntry = (ZipEntry) entries.nextElement();
            InputStream inputStream = zipFile.getInputStream(zipEntry);
            try {
                verify(file.getName() + "!" + zipEntry.getName(), inputStream);
            } finally {
                inputStream.close();
            }
        }
    }

    public void checkDirectory(File dir) throws IOException {
        DirectoryScanner directoryScanner = new DirectoryScanner(dir);
        directoryScanner.addFilter(new SuffixFilter(".java"));
        directoryScanner.scan(new FileVisitor() {
            public void visitFile(File file) {
                try {
                    checkJavaFile(file);
                } catch (IOException e) {
                    // ?
                }
            }
        });
    }

    public void checkJavaFile(File file) throws IOException {
        InputStream inputStream = new FileInputStream(file);
        try {
            verify(file.getName(), inputStream);
        } finally {
            inputStream.close();
        }
    }

    private void verify(String id, InputStream inputStream) {
        try {
            JavaDocBuilder javaDocBuilder = new JavaDocBuilder();
            javaDocBuilder.addSource(new BufferedReader(new InputStreamReader(inputStream)));
            reporter.success(id);
        } catch (ParseException parseException) {
            reporter.parseFailure(id, parseException.getLine(), parseException.getColumn(), parseException.getMessage());
        } catch (Exception otherException) {
            reporter.error(id, otherException);
        }
    }

    public static void main(String[] args) throws IOException {
        if (args.length == 0) {
            System.err.println("Tool that verifies that QDox can parse some Java source.");
            System.err.println();
            System.err.println("Usage: java " + QDoxTester.class.getName() + " src1 [src2] [src3]...");
            System.err.println();
            System.err.println("Each src can be a single .java file, or a directory/zip/jar containing multiple source files");
            System.exit(-1);
        }

        ConsoleReporter reporter = new ConsoleReporter(System.out);
        QDoxTester qDoxTester = new QDoxTester(reporter);
        for (int i = 0; i < args.length; i++) {
            File file = new File(args[i]);
            if (file.isDirectory()) {
                qDoxTester.checkDirectory(file);
            } else if (file.getName().endsWith(".java")) {
                qDoxTester.checkJavaFile(file);
            } else if (file.getName().endsWith(".jar") || file.getName().endsWith(".zip")) {
                qDoxTester.checkZipOrJarFile(file);
            } else {
                System.err.println("Unknown input <" + file.getName() + ">. Should be zip, jar, java or directory");
            }
        }
        reporter.writeSummary();
    }

    private static class ConsoleReporter implements Reporter {

        private final PrintStream out;

        private int success;
        private int failure;
        private int error;

        private int dotsWrittenThisLine;

        public ConsoleReporter(PrintStream out) {
            this.out = out;
        }

        public void success(String id) {
            success++;
            if (++dotsWrittenThisLine > 80) {
                newLine();
            }
            out.print('.');
        }

        private void newLine() {
            dotsWrittenThisLine = 0;
            out.println();
            out.flush();
        }

        public void parseFailure(String id, int line, int column, String reason) {
            newLine();
            out.println("* " + id);
            out.println("  [" + line + ":" + column + "] " + reason);
            failure++;
        }

        public void error(String id, Throwable throwable) {
            newLine();
            out.println("* " + id);
            throwable.printStackTrace(out);
            error++;
        }

        public void writeSummary() {
            newLine();
            out.println("-- Summary --------------");
            out.println("Success: " + success);
            out.println("Failure: " + failure);
            out.println("Error  : " + error);
            out.println("Total  : " + (success + failure + error));
            out.println("-------------------------");
        }

    }
}

它包含一个名为 的方法checkZipOrJarFile(File file),也许它可以帮助我。但我找不到任何关于如何使用它的示例或教程。

欢迎任何帮助。

4

1 回答 1

1

QDox cannot do that for you, unfortunately (I came here looking for QDox support for jars). The source code for QDox that you list above is only for testing if the classes in the given jar can be parsed successfully by QDox. That code does, however, give you a clue on how to use standard java apis to do what you want: enumerate over classed in a jar.

Here's some code I'm using (which I cribbed from another SO answer here: analyze jar file programmatically)

// Your jar file
JarFile jar = new JarFile(jarFile);
// Getting the files into the jar
Enumeration<? extends JarEntry> enumeration = jar.entries();

// Iterates into the files in the jar file
while (enumeration.hasMoreElements()) {
    ZipEntry zipEntry = enumeration.nextElement();

    // Is this a class?
    if (zipEntry.getName().endsWith(".class")) {

    // Relative path of file into the jar.
    String className = zipEntry.getName();

    // Complete class name
    className = className.replace(".class", "").replace("/", ".");

    // Load class definition from JVM - you may not need this, but I want to introspect the class
    try {
        Class<?> clazz = getClass().getClassLoader().loadClass(className);
        // ... I then go on to do some intropsection

If you don't actually want to introspect the class as I do, you can stop at getName(). Also, if you specifically want to find packages, you could use zipEntry.isDirectory() on your zip entries.

于 2013-09-23T18:46:00.927 回答