/*
* Need to specify classpath
* export CLASSPATH=.:<path> on Mac
*/
public class DA{
private Set<Class<?>> thePackage;
public DA(String packageName){
try {
loadPackage(packageName);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
/*
* Prints out Metrics
*/
public void displayMetrics(){
// Format Numbers to nearest 2 decimal places (Round Down)
DecimalFormat df = new DecimalFormat("#.00");
df.setRoundingMode(RoundingMode.DOWN);
final Object[][] table = new String[thePackage.size() + 1][];
table[0] = new String[] {"C", "inDepth(C)","instability(C)","responsibility(C)"," workLoad(C)"};
int index = 1;
for(Class<?> c:thePackage){
table[index ++] = new String[]{
c.getName(),
String.valueOf(inDepth(c)),
String.valueOf(df.format(instability(c))),
String.valueOf(df.format(responsibility(c))),
String.valueOf(df.format(workLoad(c)))
};
}
for (final Object[] row : table) {
System.out.format("%-15s%-15s%-15s%-15s%-15s\n", row);
}
}
/*
* Provider is define as the number of classes
* Class "A" uses
*
* Begin with instance var count
*
* Loop through
*
*/
public int providers(Class<?> a){
int count = 0;
for(Class<?> c:thePackage)
if(uses(a, c))
count++;
return count;
}
/*
* Clients is define as number of
* classes that uses Class "A"
*
* Set count = 0
* Loop through Array
* If Class
*/
public int clients(Class<?> a){
int count = 0;
for(Class<?> c:thePackage)
if(uses(c, a))
count ++;
return count;
}
/*
* If Class B uses Class A
*
* Test for:
* 1.Field
* 2.Superclass
* 3.Constructors
* 4.Methods
*/
private boolean uses(Class<?> b, Class<?> a){
if (testForDeclaredFields(b, a)) return true;
if (testForInheritance(b, a)) return true;
if (testForConstructors(b, a)) return true;
if (testForMethods(b, a)) return true;
return false;
}
private boolean testForDeclaredFields(Class<?> b, Class<?> a){
for(Field f:b.getDeclaredFields()){
if(f.getGenericType().equals(a))
return true;
}
return false;
}
private boolean testForInheritance(Class<?> b, Class<?> a){
if(b.getSuperclass() == null) return false;
return b.getSuperclass().equals(a);
}
private boolean testForConstructors(Class<?> b, Class<?> a){
for(Constructor<?> c: b.getDeclaredConstructors()){
for(Class<?> p : c.getParameterTypes())
if(p == a)
return true;
}
return false;
}
private boolean testForMethods(Class<?> b, Class<?> a){
for(Method m:b.getDeclaredMethods()){
for(Class<?> p:m.getParameterTypes())
if(p == a)
return true;
}
return false;
}
/**
* Find the hierarchy
* of superclass
*
* @param Class a
* @return numberOfSuperClass
*/
public int inDepth(Class<?> a){
int numberOfSuperClass = 0;
while((a= a.getSuperclass()) != null)
numberOfSuperClass ++;
return numberOfSuperClass;
}
/**
*
* @param Class a
* @return # of Class A divided by total methods in package
*/
public double workLoad(Class<?> a){
int count = 0;
for(Class<?> c : thePackage)
count += c.getDeclaredMethods().length;
return (double) a.getDeclaredMethods().length/count;
}
/*
* The sum of providers in a class
*/
public int totalProviders(){
int total =0;
for(Class<?> c: thePackage)
total += providers(c);
return total;
}
/*
* The sum of clients in a class
*/
public int totalClients(){
int total =0;
for(Class<?> c:thePackage)
total += clients(c);
return total;
}
/*
Define as number of classes Class a uses
divided by package's total
*/
public double instability(Class<?> a){
return (double) providers(a)/(totalProviders());
}
public double responsibility(Class<?> a){
return (double) clients(a)/ (totalClients());
}
public Set<Class<?>> getClassesInPackage(){ return thePackage; }
public void loadPackage(String path) throws IOException {
thePackage = new HashSet<Class<?>>();
FilenameFilter classFilter = new FilenameFilter() {
public boolean accept(File dir, String name) {
return name.toLowerCase().endsWith(".class");
}
};
File f = new File(path);
String packageName = f.getName() + ".";
for (File file : f.listFiles(classFilter)){
String fileName = packageName + file.getName().substring(0, file.getName().lastIndexOf('.'));
try {
thePackage.add(Class.forName(fileName));
} catch (ClassNotFoundException e) { e.printStackTrace(); }
}
}
public static void main(String[] args){
if (args.length != 1) {
System.out.println("Usage FileLoader <path>");
} else {
DA da = new DA(args[0]);
da.displayMetrics();
}
}
}
1 Response
Use Java Reflection to measure these within a Package.
instability(A)
responsibility(A)
inDepth(A)
workLoad(A)
1.
Instability(A) is define as the provider of A or some class that class A uses divided by the total instability of the entire package.
2.
Responsibility(A) is define as the clients of A or classes that uses class A divided by the total clients of the package.
3.
inDepth(A) is compute the hierarchy of inheritance of A
4.
workLoad(A) is the number of methods class A has divided by the total of number of methods the entire package has.
Write a comment
You can use [html][/html], [css][/css], [php][/php] and more to embed the code. Urls are automatically hyperlinked. Line breaks and paragraphs are automatically generated.