1 package moduleDependencyFixture; 2 3 import fit.Parse; 4 import fit.exception.FitFailureException; 5 import fitnesse.fixtures.TableFixture; 6 import jdepend.framework.*; 7 8 import java.util.*; 9 10 public class ModuleDependencies extends TableFixture { 11 private StringBuffer components; 12 private JDepend jd; 13 private int modules; 14 private HashMap moduleTable; 15 boolean[][] dependencies; 16 String prefix; 17 18 public ModuleDependencies() { 19 components = new StringBuffer (); 20 moduleTable = new HashMap(); 21 prefix = null; 22 } 23 24 protected void doStaticTable(int rows) { 25 modules = rows - 1; 26 getArguments(); 27 checkFirstCellIsBlank(); 28 checkForModuleRows(); 29 jd = new JDepend(); 30 addPaths(jd); 31 processComponents(); 32 drawDiagonal(); 33 jd.analyze(); 34 checkForCycles(); 35 if (checkModulesArePresent()) { 36 checkAllDependencies(); 37 } 38 } 39 40 private void getArguments() { 41 String args[] = getArgs(); 42 if (args != null && args.length >= 1) 43 prefix = args[0]; 44 } 45 46 private void drawDiagonal() { 47 for (int module = 0; module < modules; module++) { 48 int modulePosition = module + 1; 49 Parse diagonalCell = getCell(modulePosition, modulePosition); 50 ignore(diagonalCell); 51 } 52 } 53 54 private void checkAllDependencies() { 55 for (int from = 0; from < modules; from++) { 56 for (int to = 0; to < modules; to++) { 57 checkOneDependency(from, to); 58 } 59 } 60 } 61 62 private void checkOneDependency(int from, int to) { 63 int fromRow = from + 1; 64 int toCol = to + 1; 65 boolean dependencyExists = depends(fromRow, toCol); 66 Parse dependencyCell = getCell(fromRow, toCol); 67 if (dependencyCell.text().equals("") && dependencyExists) 68 wrong(dependencyCell); 69 else if (dependencyExists && isNotBlank(dependencyCell)) 70 right(dependencyCell); 71 } 72 73 private boolean isNotBlank(Parse dependencyCell) { 74 return !dependencyCell.text().equals(""); 75 } 76 77 boolean depends(int fromRow, int toCol) { 78 JavaPackage fromPackage = jd.getPackage(getModuleName(0, fromRow)); 79 JavaPackage toPackage = jd.getPackage(getModuleName(toCol, 0)); 80 boolean depends = false; 81 if (fromPackage != null) { 82 Collection efferents = fromPackage.getEfferents(); 83 depends = efferents.contains(toPackage); 84 } 85 return depends; 86 } 87 88 private boolean checkModulesArePresent() { 89 boolean allPresent = true; 90 for (int module = 0; module < modules; module++) { 91 int modulePosition = module + 1; 92 String rowName = getModuleName(0, modulePosition); 93 JavaPackage p = jd.getPackage(rowName); 94 if (p == null) { 95 getCell(0, modulePosition).addToBody("<hr>" + label("no such module")); 96 wrong(getCell(0, modulePosition)); 97 allPresent = false; 98 } else { 99 right(getCell(0, modulePosition)); 100 right(getCell(modulePosition, 0)); 101 } 102 } 103 return allPresent; 104 } 105 106 String getModuleName(int row, int column) { 107 String cellContents = getText(row, column); 108 if (cellContents.startsWith(".") && prefix != null) 109 return prefix + cellContents; 110 else 111 return cellContents; 112 } 113 114 private void checkForModuleRows() { 115 if (modules < 1) 116 throw new FitFailureException("no module rows"); 117 } 118 119 private void processComponents() { 120 for (int module = 0; module < modules; module++) { 121 int modulePosition = module + 1; 122 String rowName = getModuleName(0, modulePosition); 123 String colName = getModuleName(modulePosition, 0); 124 if (!rowName.equals(colName)) 125 throw new FitFailureException("Table is unbalanced. Rows and Columns must be in the same order."); 126 addComponent(rowName); 127 moduleTable.put(rowName, new Integer (module)); 128 } 129 jd.setComponents(getComponents()); 130 } 131 132 private void checkFirstCellIsBlank() { 133 String firstCell = getText(0, 0); 134 if (!firstCell.equals("")) 135 throw new FitFailureException("first cell must be blank"); 136 } 137 138 private void addPaths(JDepend jd) { 139 for (Iterator i = ModuleDependencyPaths.paths.iterator(); i.hasNext();) { 140 String path = (String ) i.next(); 141 try { 142 jd.addDirectory(path); 143 } catch (Exception e) { 144 exception(getCell(0, 0), e); 145 } 146 } 147 } 148 149 public String getComponents() { 150 return components.toString(); 151 } 152 153 public void addComponent(String component) { 154 if (components.length() > 0) 155 components.append(","); 156 components.append(component); 157 } 158 159 public int getModuleNumber(String name) { 160 Integer number = (Integer ) moduleTable.get(name); 161 if (number == null) 162 throw new Error ("invalid module name:" + name); 163 return number.intValue(); 164 } 165 166 void checkForCycles() { 167 dependencies = getDependencyMap(); 168 removeNonCyclicDependencies(); 169 markCyclicDependencies(); 170 } 171 172 private void markCyclicDependencies() { 173 boolean cyclePresent = false; 174 for (int from = 0; from < dependencies.length; from++) { 175 for (int to = 0; to < dependencies.length; to++) { 176 if (dependencies[from][to]) { 177 Parse cyclicCell = getCell(from + 1, to + 1); 178 wrong(cyclicCell); 179 cyclicCell.addToBody("<hr>cycle"); 180 cyclePresent = true; 181 } 182 } 183 } 184 if (cyclePresent) { 185 Parse cellZero = getCell(0, 0); 186 wrong(cellZero); 187 cellZero.addToBody("There are cycles."); 188 } 189 } 190 191 boolean[][] getDependencyMap() { 192 boolean dependencies[][] = new boolean[modules][modules]; 193 for (int from = 0; from < modules; from++) { 194 for (int to = 0; to < modules; to++) { 195 dependencies[from][to] = depends(from + 1, to + 1); 196 } 197 } 198 return dependencies; 199 } 200 201 public void removeNonCyclicDependencies() { 202 for (int instable = findNonCyclicPackage(); instable >= 0; instable = findNonCyclicPackage()) { 203 removeModuleDependencies(instable); 204 } 205 } 206 207 private void removeModuleDependencies(int instable) { 208 for (int module = 0; module < dependencies.length; module++) { 209 dependencies[module][instable] = false; 210 dependencies[instable][module] = false; 211 } 212 } 213 214 int findNonCyclicPackage() { 215 for (int module = 0; module < dependencies.length; module++) { 216 if (isIrresponsible(module) && isDependent(module)) 217 return module; 218 if (!isDependent(module) && !isIrresponsible(module)) 219 return module; 220 } 221 return -1; 222 } 223 224 private boolean isDependent(int module) { 225 boolean doesDepend = false; 226 for (int target = 0; target < dependencies.length; target++) 227 if (dependencies[module][target]) 228 doesDepend = true; 229 return doesDepend; 230 } 231 232 private boolean isIrresponsible(int module) { 233 for (int source = 0; source < dependencies.length; source++) 234 if (dependencies[source][module]) 235 return false; 236 return true; 237 } 238 } 239 | Popular Tags |