Design Analyzer

/* * 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) { e.printStackTrace(); } } public void displayMetrics(){ 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); } public int providers(Class<?> a){ int count = 0; for(Class<?> c:thePackage) if(uses(a, c)) count++; return count; } public int clients(Class<?> a){ int count = 0; for(Class<?> c:thePackage) if(uses(c, a)) count ++; return count; } 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; } public int inDepth(Class<?> a){ int i = 0; while((a = a.getSuperclass()) != null){ i++; } return i; } public double workLoad(Class<?> a){ int count = 0; for(Class<?> c : thePackage) count += c.getDeclaredMethods().length; return (double) a.getDeclaredMethods().length/count; } public int totalProviders(){ int total =0; for(Class<?> c: thePackage) total += providers(c); return total; } public int totalClients(){ int total =0; for(Class<?> c:thePackage) total += clients(c); return 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; } private 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

Assignment:

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.