/*
* 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
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.