package org.yajul.dependency; import jdepend.framework.JDepend; import jdepend.framework.JavaPackage; import jdepend.framework.PackageFilter; import java.io.File; import java.util.ArrayList; import java.util.Collection; import java.util.List; import java.util.logging.Level; import java.util.logging.Logger; /** * Provides simplified dependency analysis checking based on JDepend. * <br> * User: josh * Date: 5/25/12 * Time: 11:50 AM */ public class DependencyAnalyzer { private static final Logger log = Logger.getLogger(DependencyAnalyzer.class.getName()); private final String moduleName; private final Collection<String> filters = new ArrayList<String>(); private JDepend jdepend; private Collection<JavaPackage> packages; public DependencyAnalyzer(String moduleName) { if (moduleName == null || moduleName.isEmpty()) throw new IllegalArgumentException("moduleName cannot be null or empty!"); this.moduleName = moduleName; addFilter("java.*"); addFilter("javax.*"); } public void init() throws Exception { PackageFilter packageFilter = new PackageFilter(filters); this.jdepend = new JDepend(packageFilter); // We need to try a few different directories, as the test might be running in Maven, or in IDEA. [jsd] List<File> path = new ArrayList<File>(); final String targetClasses = "/target/classes"; path.add(new File("./" + moduleName + targetClasses)); path.add(new File("./" + targetClasses)); path.add(new File("../" + moduleName + targetClasses)); File classDir = null; for (File file : path) { classDir = file; if (file.exists() && file.isDirectory()) break; } if (classDir == null || !classDir.exists() || !classDir.isDirectory()) throw new Exception("Cannot find classes for JDepend in " + path); log.info("Module " + moduleName + " classes: " + classDir.getAbsolutePath()); jdepend.addDirectory(classDir.getAbsolutePath()); } public void assertNoCircularDependencies() { Collection<JavaPackage> packages = getPackages(); int cycles = 0; for (JavaPackage javaPackage : packages) { if (javaPackage.containsCycle()) { log.log(Level.SEVERE, "Cyclic dependency detected in: " + javaPackage.getName()); cycles++; } else { log.info(javaPackage.getName() + " OK"); } } if (cycles > 0) throw new AssertionError("Cyclic dependencies detected in " + moduleName); log.info("No circular dependencies in " + moduleName + ", yay!"); } private Collection<JavaPackage> getPackages() { if (jdepend == null) throw new IllegalStateException("Dependency analyzer not initialized. Did you forget to call init()?"); if (packages == null) packages = jdepend.analyze(); return packages; } public void addFilter(String packageFilter) { filters.add(packageFilter); } }