--- /dev/null 2012-12-05 17:14:48.000000000 -0800 +++ new/src/share/classes/com/sun/tools/jdeps/Archive.java 2012-12-05 17:14:48.000000000 -0800 @@ -0,0 +1,156 @@ +/* + * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package com.sun.tools.jdeps; + +import com.sun.tools.classfile.Dependency; +import com.sun.tools.classfile.Dependency.Location; +import java.io.File; +import java.util.Comparator; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Map; +import java.util.Set; +import java.util.SortedMap; +import java.util.SortedSet; +import java.util.TreeMap; +import java.util.TreeSet; + +/** + * Represents the source of the class files. + */ +public class Archive { + private static Map archiveForClass = new HashMap<>(); + public static Archive find(String classname) { + return archiveForClass.get(classname); + } + + private final File file; + private final String filename; + private final DependencyRecorder recorder; + private final ClassFileReader reader; + public Archive(File f, ClassFileReader reader) { + this.file = f; + this.filename = f != null ? f.getName() : "not found"; + this.recorder = new DependencyRecorder(); + this.reader = reader; + } + + public ClassFileReader reader() { + return reader; + } + + public String getFileName() { + return filename; + } + + public void addClass(String cn) { + Archive a = archiveForClass.get(cn); + assert(a != null && a != this); // ## issue warning? + if (!archiveForClass.containsKey(cn)) { + archiveForClass.put(cn, this); + } + } + + public void addDependency(Dependency d) { + recorder.addDependency(d); + } + + public SortedMap> getDependencies() { + DependencyRecorder.Filter filter = new DependencyRecorder.Filter() { + public boolean accept(Location origin, Location target) { + String o = origin.getClassName(); + String t = target.getClassName(); + return archiveForClass.get(o) != archiveForClass.get(t); + }}; + + SortedMap> result = new TreeMap<>(locationComparator); + for (Map.Entry> e : recorder.dependencies().entrySet()) { + Location o = e.getKey(); + for (Location t : e.getValue()) { + if (filter.accept(o, t)) { + SortedSet odeps = result.get(o); + if (odeps == null) { + result.put(o, odeps = new TreeSet<>(locationComparator)); + } + odeps.add(t); + } + } + } + return result; + } + + public Set getRequiredArchives() { + SortedSet deps = new TreeSet<>(new Comparator() { + public int compare(Archive a1, Archive a2) { + return a1.toString().compareTo(a2.toString()); + } + }); + + for (Map.Entry> e : recorder.dependencies().entrySet()) { + Location o = e.getKey(); + Archive origin = Archive.find(o.getClassName()); + for (Location t : e.getValue()) { + Archive target = Archive.find(t.getClassName()); + if (origin != target) { + if (!deps.contains(target)) { + deps.add(target); + } + } + } + } + return deps; + } + + public String toString() { + return file != null ? file.getPath() : "not found"; + } + + private static class DependencyRecorder { + static interface Filter { + boolean accept(Location origin, Location target); + } + + public void addDependency(Dependency d) { + Set odeps = map.get(d.getOrigin()); + if (odeps == null) { + map.put(d.getOrigin(), odeps = new HashSet<>()); + } + odeps.add(d.getTarget()); + } + + public Map> dependencies() { + return map; + } + + private final Map> map = new HashMap<>(); + } + + private static Comparator locationComparator = + new Comparator() { + public int compare(Location o1, Location o2) { + return o1.toString().compareTo(o2.toString()); + } + }; +}