• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  *****************************************************************************
3  * Copyright (C) 2000-2007, International Business Machines Corporation and  *
4  * others. All Rights Reserved.                                              *
5  *****************************************************************************
6  */
7 package com.ibm.rbm;
8 
9 
10 import java.io.*;
11 import java.util.*;
12 
13 import org.apache.xerces.parsers.DOMParser;
14 import org.w3c.dom.*;
15 import org.xml.sax.*;
16 
17 /**
18  * RBReporterScaner is a utility class for RBReporter. It creates a report from an xml settings
19  * file that scans code for resources and compares them against a resource bundle.
20  *
21  * @author Jared Jackson
22  * @see com.ibm.rbm.RBReporter
23  */
24 public class RBReporterScanner {
25 	private Bundle       bundle;
26 	private Document     config;
27 	private Hashtable    fileRules;
28 	private Hashtable    parseRules;
29 	private Hashtable    results;
30 	private Hashtable    missing;
31 	private boolean      resultsFound;
32 
RBReporterScanner(Bundle bundle, File configFile)33 	protected RBReporterScanner(Bundle bundle, File configFile) throws IOException {
34 		resultsFound = false;
35 		this.bundle = bundle;
36 
37 		try {
38 			InputSource is = new InputSource(new FileInputStream(configFile));
39 			DOMParser parser = new DOMParser();
40 			parser.parse(is);
41 			config = parser.getDocument();
42 		} catch (SAXException saxe) {
43 			throw new IOException("Illegal XML Document: " + saxe.getMessage());
44 		}
45 
46 		Element root = config.getDocumentElement();
47 		fileRules = getFileRules(root);
48 		parseRules = getParseRules(root);
49 
50 		results = new Hashtable();
51 		Enumeration keys = bundle.allItems.keys();
52 		while (keys.hasMoreElements()) {
53 			String key = (String)keys.nextElement();
54 			BundleItem item = (BundleItem)bundle.allItems.get(key);
55 			results.put(key, new ScanResult(item));
56 		}
57 
58 		missing = new Hashtable();
59 	}
60 
getNumberResourcesFound()61 	protected int getNumberResourcesFound() {
62 		return results.size();
63 	}
64 
getNumberMissingResources()65 	protected int getNumberMissingResources() {
66 		return missing.size();
67 	}
68 
getNumberUnusedResources()69 	protected int getNumberUnusedResources() {
70 		int count = 0;
71 		Enumeration elems = results.elements();
72 		while (elems.hasMoreElements()) {
73 			ScanResult result = (ScanResult)elems.nextElement();
74 			if (result.getOccurances().size() < 1) count++;
75 		}
76 		return count;
77 	}
78 
getMissingResources()79 	protected Vector getMissingResources() {
80 		Enumeration elems = missing.elements();
81 		Vector v = new Vector();
82 		while (elems.hasMoreElements())
83 			v.addElement(elems.nextElement());
84 		return v;
85 	}
86 
getUnusedResources()87 	protected Vector getUnusedResources() {
88 		Enumeration elems = results.elements();
89 		Vector v = new Vector();
90 		while (elems.hasMoreElements()) {
91 			ScanResult result = (ScanResult)elems.nextElement();
92 			if (result.getOccurances().size() < 1) {
93 				v.addElement(result);
94 			}
95 		}
96 		return v;
97 	}
98 
performScan()99 	protected boolean performScan() throws IOException {
100 		resultsFound = false;
101 
102 		Element root = config.getDocumentElement();
103 		NodeList nl = root.getElementsByTagName("Scan");
104 		if (nl.getLength() < 1) return resultsFound;
105 		Element scan_elem = (Element)nl.item(0);
106 		nl = scan_elem.getElementsByTagName("Directory");
107 		for (int i=0; i < nl.getLength(); i++) {
108 			Element dir_elem = (Element)nl.item(i);
109 			File directory = new File(dir_elem.getAttribute("location"));
110 			boolean recurse = dir_elem.getAttribute("recurse_directories").equalsIgnoreCase("true");
111 			NodeList rules_list = dir_elem.getElementsByTagName("Rules");
112 			if (rules_list.getLength() < 1) continue;
113 			Element rules_elem = (Element)rules_list.item(0);
114 			NodeList frules_list = rules_elem.getElementsByTagName("ApplyFileRule");
115 			// For each file rule
116 			for (int j=0; j < frules_list.getLength(); j++) {
117 				Element frule_elem = (Element)frules_list.item(j);
118 				FileRule frule = (FileRule)fileRules.get(frule_elem.getAttribute("name"));
119 				if (frule == null) continue;
120 				NodeList prules_list = frule_elem.getElementsByTagName("ApplyParseRule");
121 				Vector prules_v = new Vector();
122 				// For each parse rule
123 				for (int k=0; k < prules_list.getLength(); k++) {
124 					Element prule_elem = (Element)prules_list.item(k);
125 					ParseRule prule = (ParseRule)parseRules.get(prule_elem.getAttribute("name"));
126 					if (prule == null) continue;
127 					prules_v.addElement(prule);
128 				}
129 				if (prules_v.size() < 1) continue;
130 				scanDirectory(directory, frule, prules_v, recurse);
131 			}
132 		}
133 
134 		return resultsFound;
135 	}
136 
scanDirectory(File directory, FileRule frule, Vector prules, boolean recurse)137 	private void scanDirectory(File directory, FileRule frule, Vector prules, boolean recurse) throws IOException {
138 
139 		// Recursion step
140 		if (recurse) {
141 			File children[] = directory.listFiles(new java.io.FileFilter(){
142 				public boolean accept(File f) {
143 					return f.isDirectory();
144 				}
145 
146 				public String getDescription() {
147 					return "";
148 				}
149 			});
150 			for (int i=0; i < children.length; i++) {
151 				File new_directory = children[i];
152 				scanDirectory(new_directory, frule, prules, recurse);
153 			}
154 		}
155 		// Go through each acceptable file
156 		File children[] = directory.listFiles();
157 		for (int i=0; i < children.length; i++) {
158 			File f = children[i];
159 			if (f.isDirectory() || !(frule.applyRule(f.getName()))) continue;
160 			FileReader fr = new FileReader(f);
161 			BufferedReader br = new BufferedReader(fr);
162 			String line = null;
163 			int line_count = 0;
164 			// Read the file line by line
165 			while ((line = br.readLine()) != null) {
166 				line_count++;
167 				Vector findings = new Vector();
168 				// Apply all parse rules to each line
169 				for (int j=0; j < prules.size(); j++) {
170 					ParseRule prule = (ParseRule)prules.elementAt(j);
171 					Vector temp_results = prule.applyRule(line);
172 					for (int k=0; k < temp_results.size(); k++) {
173 						findings.addElement(temp_results.elementAt(k));
174 					}
175 				}
176 				for (int j=0; j < findings.size(); j++) {
177 					String name = (String)findings.elementAt(j);
178 					Occurance occ = new Occurance(f.getName(), f.getAbsolutePath(), line_count);
179 					// If the name is found in the resource bundles derived hashtable
180 					if (results.containsKey(name)) {
181 						ScanResult scan_res = (ScanResult)results.get(name);
182 						scan_res.addOccurance(occ);
183 					} else {
184 						// Add it to the missing results
185 						ScanResult scan_res = new ScanResult(new BundleItem(null, name, "*unknown*"));
186 						scan_res.addOccurance(occ);
187 						missing.put(name, scan_res);
188 						results.put(name, scan_res);
189 					}
190 				}
191 			}
192 		}
193 	}
194 
getFileRules(Element root)195 	private Hashtable getFileRules(Element root) {
196 		Hashtable result = new Hashtable();
197 		NodeList frules_list = root.getElementsByTagName("FileRules");
198 		Element frules_elem = null;
199 		if (frules_list.getLength() > 0) frules_elem = (Element)frules_list.item(0);
200 		if (frules_elem == null) return result;
201 		frules_list = frules_elem.getElementsByTagName("FileRule");
202 		for (int i=0; i < frules_list.getLength(); i++) {
203 			Element elem = (Element)frules_list.item(i);
204 			FileRule frule = new FileRule(elem.getAttribute("name"), elem.getAttribute("starts_with"),
205 										  elem.getAttribute("ends_with"), elem.getAttribute("contains"));
206 			result.put(elem.getAttribute("name"), frule);
207 		}
208 		return result;
209 	}
210 
getParseRules(Element root)211 	private Hashtable getParseRules(Element root) {
212 		Hashtable result = new Hashtable();
213 		NodeList prules_list = root.getElementsByTagName("ParseRules");
214 		Element prules_elem = null;
215 		if (prules_list.getLength() > 0)
216 			prules_elem = (Element)prules_list.item(0);
217 		if (prules_elem == null)
218 			return result;
219 		prules_list = prules_elem.getElementsByTagName("ParseRule");
220 		for (int i=0; i < prules_list.getLength(); i++) {
221 			Element elem = (Element)prules_list.item(i);
222 			ParseRule prule = new ParseRule(elem.getAttribute("name"), elem.getAttribute("follows"),
223 											elem.getAttribute("precedes"));
224 			result.put(elem.getAttribute("name"), prule);
225 		}
226 		return result;
227 	}
228 }
229 
230 class FileRule {
231 	String name;
232 	String starts_with;
233 	String ends_with;
234 	String contains;
235 
FileRule(String name, String starts_with, String ends_with, String contains)236 	FileRule(String name, String starts_with, String ends_with, String contains) {
237 		this.name = name;
238 		this.starts_with = starts_with;
239 		this.ends_with = ends_with;
240 		this.contains = contains;
241 	}
242 
applyRule(String source)243 	boolean applyRule(String source) {
244 		boolean accept = true;
245 		if (starts_with != null && starts_with.length() > 0 && !(source.startsWith(starts_with))) accept = false;
246 		if (ends_with != null && ends_with.length() > 0 && !(source.endsWith(ends_with))) accept = false;
247 		if (contains != null && contains.length() > 0 && source.indexOf(contains) < 0) accept = false;
248 		return accept;
249 	}
250 }
251 
252 class ParseRule {
253 	String name;
254 	String before;
255 	String after;
256 
ParseRule(String name, String before, String after)257 	ParseRule(String name, String before, String after) {
258 		this.name = name;
259 		this.before = before;
260 		this.after = after;
261 	}
262 
263 	// returns the vector of strings found after before and before after
264 
applyRule(String source)265 	Vector applyRule(String source) {
266 		Vector v = new Vector();
267 		if (before != null && before.length() > 0) {
268 			if (after != null && after.length() > 0) {
269 				// Both before and after non-empty
270 				int before_index = -1;
271 				int after_index = -1;
272 				while ((before_index = source.indexOf(before, ++before_index)) >= 0) {
273 					//before_index = source.indexOf(before, before_index);
274 					after_index = -1;
275 					after_index = source.indexOf(after, before_index + before.length()+1);
276 					if (after_index < 0 || before_index < 0 || before.length() < 0) {
277 					    break;
278 					}
279 					v.addElement(source.substring(before_index + before.length(), after_index));
280 					before_index = after_index;
281 				}
282 			} else {
283 				// Before non-empty, after empty
284 				int index = -1;
285 				while (source.indexOf(before, ++index) >= 0) {
286 					index = source.indexOf(before, index);
287 					String result = source.substring(index + before.length(), source.length());
288 					if (result != null && result.length() > 0) v.addElement(result);
289 				}
290 			}
291 		} else if (after != null && after.length() > 0) {
292 			// Before empty, after not
293 			int index = -1;
294 			while (source.indexOf(after, ++index) >= 0) {
295 				index = source.indexOf(before, index);
296 				String result = source.substring(0, index);
297 				if (result != null && result.length() > 0) v.addElement(result);
298 			}
299 		} else {
300 			// Before and after empty
301 			v.addElement(source);
302 		}
303 		return v;
304 	}
305 }