1   package net.sf.jlayercheck;
2   
3   import java.io.File;
4   import java.io.InputStream;
5   import java.net.URL;
6   import java.util.Map;
7   import java.util.Set;
8   import java.util.TreeMap;
9   import java.util.logging.Logger;
10  
11  import junit.framework.TestCase;
12  import net.sf.jlayercheck.util.DependencyVisitor;
13  import net.sf.jlayercheck.util.StringUtils;
14  import net.sf.jlayercheck.util.XMLConfiguration;
15  import net.sf.jlayercheck.util.XMLConfigurationParser;
16  import net.sf.jlayercheck.util.model.ClassDependency;
17  import net.sf.jlayercheck.util.modeltree.ClassNode;
18  import net.sf.jlayercheck.util.modeltree.DefaultModelTree;
19  import net.sf.jlayercheck.util.modeltree.ModelTree;
20  import net.sf.jlayercheck.util.modeltree.ModuleNode;
21  import net.sf.jlayercheck.util.modeltree.PackageNode;
22  
23  public class XMLConfigurationParserTest extends TestCase {
24  	protected static Logger logger = Logger.getLogger("JLayerCheck");
25  	
26  	/**
27  	 * Tests the basic parsing functionality.
28  	 * 
29  	 * @throws Exception
30  	 */
31  	public void testParser() throws Exception {
32  		InputStream is = getClass().getResource("/jlayercheck_test.xml").openStream();
33  		
34  		XMLConfiguration xcp = new XMLConfigurationParser().parse(is);
35  		
36  		// test if loading of the configuration from the XML file works
37  		assertTrue(xcp.getModulePackages().containsKey("util"));
38  		assertTrue(xcp.getModulePackages().containsKey("main"));
39  		assertTrue(xcp.getModuleDependencies().containsKey("main"));
40  		assertTrue(xcp.getModuleDependencies().get("main").contains("util"));
41  		assertTrue(xcp.getExcludeList().contains("java.**"));
42  		
43  		// test if the ClassSource correctly implements calling a DependencyVisitor
44  		DependencyVisitor dv = new DependencyVisitor();
45  		xcp.getClassSources().get(0).call(dv);
46  		assertTrue(dv.getPackages().containsKey("net/sf/jlayercheck/util"));
47  
48  		// test if the java sources are correctly loaded
49  		Map<String, URL> javaSources = new TreeMap<String, URL>();
50  		javaSources.putAll(xcp.getClassSources().get(0).getSourceFiles());
51  		assertTrue(javaSources.containsKey("net/sf/jlayercheck/util/DependencyParser"));
52  	}
53  	
54  	/**
55  	 * Tests if dependency violations are found.
56  	 * 
57  	 * @throws Exception
58  	 */
59  	public void testFindViolations() throws Exception {
60  		// load and parse configuration, class and java files
61  		InputStream is = getClass().getResource("/jlayercheck_test.xml").openStream();
62  		XMLConfiguration xcp = new XMLConfigurationParser().parse(is);
63  		DependencyVisitor dv = new DependencyVisitor();
64  		xcp.getClassSources().get(0).call(dv);
65  		Map<String, URL> javaSources = new TreeMap<String, URL>();
66  		javaSources.putAll(xcp.getClassSources().get(0).getSourceFiles());
67  
68  		Set<String> unspecifiedPackages = xcp.getUnspecifiedPackages(dv.getDependencies());
69  		Map<String, Map<String, ClassDependency>> unallowedDependencies = xcp.getUnallowedDependencies(dv.getDependencies()); 
70  		
71  		// find violations
72  		for(String classPackageName : unspecifiedPackages) {
73  			logger.fine("Warning: Package "+classPackageName+" has no module.");
74  		}
75  		
76  		for(String classname : unallowedDependencies.keySet()) {
77  			for(String dependency : unallowedDependencies.get(classname).keySet()) {
78  				String classPackageName = StringUtils.getPackageName(classname);
79  				String dependencyPackageName = StringUtils.getPackageName(dependency);
80  
81  				String classmodule = xcp.getPackageModules().get(classPackageName);
82  				String dependencymodule = xcp.getPackageModules().get(dependencyPackageName);
83  
84  				logger.finer("Class "+classname+" ("+classmodule+") must not use class "+dependency+" ("+dependencymodule+") in line ");
85  				
86  				for(int line : unallowedDependencies.get(classname).get(dependency).getLineNumbers()) {
87  					logger.finest(" "+line);
88  				}
89  				logger.finest("");
90  			}
91  		}
92  		
93  		assertTrue(unspecifiedPackages.contains("net/sf/jlayercheck/util/model"));
94  		assertTrue(unallowedDependencies.get("net/sf/jlayercheck/util/XMLConfigurationParser").containsKey("org/w3c/dom/NodeList"));
95  	}
96  
97  	/**
98  	 * Test if the creation of a dependency model works.
99  	 * 
100 	 * @throws Exception
101 	 */
102 	public void testModel() throws Exception {
103 		// load and parse configuration, class and java files
104 		InputStream is = getClass().getResource("/jlayercheck_test.xml").openStream();
105 		XMLConfiguration xcp = new XMLConfigurationParser().parse(is);
106 		DependencyVisitor dv = new DependencyVisitor();
107 		xcp.getClassSources().get(0).call(dv);
108 
109 		ModelTree mt = xcp.getModelTree(dv);
110 		
111 		boolean moduleUtilFound = false;
112 		boolean packageJLayerCheckFound = false;
113 		boolean classXMLConfigurationFound = false;
114 		
115 		for(ModuleNode mn : mt.getModules()) {
116 			if (mn.getName().equals("util")) {
117 				moduleUtilFound = true;
118 			}
119 			
120 			for(PackageNode pn : mn.getPackages()) {
121 				if (pn.getName().equals("net/sf/jlayercheck/gui")) {
122 					assertEquals("main", mn.getName());
123 					packageJLayerCheckFound = true;
124 				}
125 				
126 				for(ClassNode cn: pn.getClasses()) {
127 					if (cn.getName().equals("net/sf/jlayercheck/util/XMLConfiguration")) {
128 						assertEquals("util", mn.getName());
129 						assertEquals("net/sf/jlayercheck/util", pn.getName());
130 						classXMLConfigurationFound = true;
131 					}
132 				}
133 			}
134 		}
135 		
136 		assertTrue(moduleUtilFound);
137 		assertTrue(packageJLayerCheckFound);
138 		assertTrue(classXMLConfigurationFound);
139 	}
140 	
141 	public void testModelUpdate() throws Exception {
142 		// load and parse configuration, class and java files
143 		InputStream is = getClass().getResource("/jlayercheck_test.xml").openStream();
144 		XMLConfiguration xcp = new XMLConfigurationParser().parse(is);
145 		DependencyVisitor dv = new DependencyVisitor();
146 		xcp.getClassSources().get(0).call(dv);
147 
148 		DefaultModelTree mt = (DefaultModelTree) xcp.getModelTree(dv);
149 		
150 		assertTrue(mt != null);
151 		assertTrue(mt.getChildCount() > 0);
152 		
153 		ClassNode cn = mt.getModule("util").getPackage("net/sf/jlayercheck/util").getClass("net/sf/jlayercheck/util/HTMLOutput");
154 		assertTrue(cn != null);
155 		
156 		xcp.updateModelTree(mt, new File("target/classes/net/sf/jlayercheck/util/HTMLOutput.class"));
157 		
158 		ClassNode cn2 = mt.getModule("util").getPackage("net/sf/jlayercheck/util").getClass("net/sf/jlayercheck/util/HTMLOutput");
159 		assertTrue(cn2 != null);
160 		assertTrue(cn != cn2);
161 	}
162 }