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) { // 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){ // Test for Declared field for(Field f:b.getDeclaredFields()){ if(f.getGenericType().equals(a)) 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

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.