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

aQute.bnd.make.calltree.CalltreeResource Maven / Gradle / Ivy

There is a newer version: 2.0.0.20130123-133441
Show newest version
package aQute.bnd.make.calltree;

import java.io.*;
import java.lang.reflect.*;
import java.util.*;

import aQute.lib.osgi.*;

/**
 * Create an XML call tree of a set of classes. The structure of the XML is:
 * 
 * 
 *    calltree ::= <using> <usedby>
 *    using    ::= <method> *
 *    usedby   ::= <method> *
 *    method   ::= <ref> 
 * 
* * The using element contains methods in the set of classes and * their references. The usedby element contains the used methods * and their references to the set of classes. The ref element * contains the class, the method name, the descriptor, and a pretty print * version of the method. * * The XML does not contain an XML processor instruction to make it easier to * include in other XML. The encoding is always UTF-8. * * This class can be used as a resource, just add it to a JAR and the data is * generated when the resource is written (saving time when the JAR is up to * date and does not have to be generated). However, the actual write method is * a static method and can be called as well: * {@link #writeCalltree(PrintWriter, Collection)}. */ public class CalltreeResource extends WriteResource { Collection classes; /** * Create a resource for inclusion that will print a call tree. * * @param values the classes for which the call tree is generated. */ public CalltreeResource(Collection values) { this.classes = values; System.out.println(values); } /** * We set the last modified to 0 so this resource does not force * a new JAR if all other resources are up to date. */ public long lastModified() { return 0; } /** * The write method is called to write the resource. We just call the static * method. */ public void write(OutputStream out) throws Exception { OutputStreamWriter osw = new OutputStreamWriter(out, Constants.DEFAULT_CHARSET); PrintWriter pw = new PrintWriter(osw); try { writeCalltree(pw, classes); } finally { pw.flush(); } } /** * Print the call tree in XML. * * @param out The output writer * @param classes The set of classes * @throws IOException Any errors */ public static void writeCalltree(PrintWriter out, Collection classes) throws Exception { final Map> using = new TreeMap>(); final Map> usedby = new TreeMap>(); ClassDataCollector cd = new ClassDataCollector() { Clazz.MethodDef source; // Before a method is parsed public void method(Clazz.MethodDef source) { this.source = source; xref(using, source, null); xref(usedby, source, null); } // For any reference in the previous method. public void reference(Clazz.MethodDef reference) { xref(using, source, reference); xref(usedby, reference, source); } }; for (Clazz clazz : classes) { clazz.parseClassFileWithCollector(cd); } out.println(""); xref(out, "using", using); xref(out, "usedby", usedby); out.println(""); } /* * Add a new reference */ private static void xref( Map> references, Clazz.MethodDef source, Clazz.MethodDef reference) { Set set = references.get(source); if (set == null) references.put(source, set=new TreeSet()); if ( reference != null) set.add(reference); } /* * Print out either using or usedby sets */ private static void xref(PrintWriter out, String group, Map> references) { out.println(" <" + group + ">"); for (Map.Entry> entry : references .entrySet()) { Clazz.MethodDef source = entry.getKey(); Set refs = entry.getValue(); method(out, "method", source, ">"); for (Clazz.MethodDef ref : refs) { method(out, "ref", ref, "/>"); } out.println(" "); } out.println(" "); } /* * Print out a method. */ private static void method(PrintWriter out, String element, Clazz.MethodDef source, String closeElement) { out.println(" <" + element + " class='" + source.clazz + "'" + getAccess(source.access) + ( source.isConstructor() ? "" : " name='" + source.name + "'") + " descriptor='" + source.descriptor + "' pretty='" + source.getPretty() + "'" + closeElement); } private static String getAccess(int access) { StringBuilder sb = new StringBuilder(); if ( Modifier.isPublic(access) ) sb.append(" public='true'"); if ( Modifier.isStatic(access) ) sb.append(" static='true'"); if ( Modifier.isProtected(access) ) sb.append(" protected='true'"); if ( Modifier.isInterface(access) ) sb.append(" interface='true'"); return sb.toString(); } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy