/*
* 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);
System.out.println(" inDepth(C) instability(C) responsibility(C) workLoad(C)");
final Object[][] table = new String[thePackage.size()][];
int index = 0;
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){
// Test for Declared field
for(Field f:b.getDeclaredFields()){
if(f.getGenericType().equals(a))
return true;
}
// Test for Interfaces
for(Class<?> i : b.getInterfaces())
if(i.getName().equals(a.getName()))
return true;
// Test for Inherietence
if(b.getSuperclass().getName().equals(a.getName()))
return true;
// Test for constructors
for(Constructor<?> c: b.getDeclaredConstructors()){
for(Class<?> p : c.getParameterTypes())
if(p.getName().equals(a.getName()))
return true;
}
// Test for methods
for(Method m:b.getDeclaredMethods()){
for(Class<?> p:m.getParameterTypes())
if(p.getName().equals(a.getName()))
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.