final URLClassLoader classLoader, final String className)
throws IOException, NoSuchMethodException, IllegalAccessException,
InvocationTargetException, InstantiationException,
InterruptedException, ExecutionException, ClassNotFoundException,
MalformedURLException {
ClassHierarchyProcessor finder = new ClassHierarchyProcessor(
classLoader, progress);
if (simple) {
return finder.computeGraph(className);
} else {
// Find all descendant classes of className.
// Create a class loader from the classpath.
Map<String, Set<String>> subclassMap = CodeAnalysisUtils
.generateSubclassMap(classLoader);
// Generate a subclass map using the runtime jar file.
Map<String, Set<String>> runtimeSubclassMap = CodeAnalysisUtils
.generateSubclassMap(new URLClassLoaderX(
new URL[] { RuntimeJar.getRuntimeJar().toURI()
.toURL() }));
subclassMap.putAll(runtimeSubclassMap);
// Find the topmost superclass of className below Object.
Class<?> klass = classLoader.loadClass(className);
while (true) {
if (klass.getSuperclass() != null
&& klass.getSuperclass() != Object.class) {
klass = klass.getSuperclass();
} else {
break;
}
}
// There is a possibility that the class we are drawing the
// class-diagram of is not part of the classMetaDataGraph.
// The
// way to check this is to see if className is present in
// subclassMap.get(superClassOf(className)).
String superclassOfClass = classLoader.loadClass(className)
.getSuperclass().getName();
Set<String> subclasses = subclassMap.get(superclassOfClass);
final Graph<ClassMetaData> classMetaDataGraph = finder
.computeGraph(klass.getName());
updateSubclasses(classLoader, classMetaDataGraph, subclassMap,
klass.getName());
boolean containsClassName = !(subclasses == null || !subclasses
.contains(superclassOfClass));
if (!containsClassName) {
final Graph<ClassMetaData> thisClassMetaDataGraph = finder
.computeGraph(className);
// Locate the node containing the parent class of
// className
// in classMetaDataGraph. Add thisClassMetaDataGraph as
// a