9fad2a52a8
X-SVN-Rev: 15953
303 lines
9.9 KiB
Java
303 lines
9.9 KiB
Java
/*
|
|
*****************************************************************************
|
|
* Copyright (C) 2000-2004, International Business Machines Corporation and *
|
|
* others. All Rights Reserved. *
|
|
*****************************************************************************
|
|
*/
|
|
package com.ibm.rbm;
|
|
|
|
|
|
import java.io.*;
|
|
import java.util.*;
|
|
|
|
import org.apache.xerces.parsers.*;
|
|
import org.apache.xerces.dom.*;
|
|
import org.w3c.dom.*;
|
|
import org.xml.sax.*;
|
|
|
|
/**
|
|
* RBReporterScaner is a utility class for RBReporter. It creates a report from an xml settings
|
|
* file that scans code for resources and compares them against a resource bundle.
|
|
*
|
|
* @author Jared Jackson
|
|
* @see com.ibm.rbm.RBReporter
|
|
*/
|
|
public class RBReporterScanner {
|
|
private Bundle bundle;
|
|
private DocumentImpl config;
|
|
private Hashtable fileRules;
|
|
private Hashtable parseRules;
|
|
private Hashtable results;
|
|
private Hashtable missing;
|
|
private boolean resultsFound;
|
|
|
|
protected RBReporterScanner(Bundle bundle, File configFile) throws IOException {
|
|
resultsFound = false;
|
|
this.bundle = bundle;
|
|
|
|
try {
|
|
InputSource is = new InputSource(new FileInputStream(configFile));
|
|
DOMParser parser = new DOMParser();
|
|
parser.parse(is);
|
|
config = (DocumentImpl)parser.getDocument();
|
|
} catch (SAXException saxe) {
|
|
throw new IOException("Illegal XML Document: " + saxe.getMessage());
|
|
}
|
|
|
|
ElementImpl root = (ElementImpl)config.getDocumentElement();
|
|
fileRules = getFileRules(root);
|
|
parseRules = getParseRules(root);
|
|
|
|
results = new Hashtable();
|
|
Enumeration enum = bundle.allItems.keys();
|
|
while (enum.hasMoreElements()) {
|
|
String key = (String)enum.nextElement();
|
|
BundleItem item = (BundleItem)bundle.allItems.get(key);
|
|
results.put(key, new ScanResult(item));
|
|
}
|
|
|
|
missing = new Hashtable();
|
|
}
|
|
|
|
protected int getNumberResourcesFound() {
|
|
return results.size();
|
|
}
|
|
|
|
protected int getNumberMissingResources() {
|
|
return missing.size();
|
|
}
|
|
|
|
protected int getNumberUnusedResources() {
|
|
int count = 0;
|
|
Enumeration enum = results.elements();
|
|
while (enum.hasMoreElements()) {
|
|
ScanResult result = (ScanResult)enum.nextElement();
|
|
if (result.getOccurances().size() < 1) count++;
|
|
}
|
|
return count;
|
|
}
|
|
|
|
protected Vector getMissingResources() {
|
|
Enumeration enum = missing.elements();
|
|
Vector v = new Vector();
|
|
while (enum.hasMoreElements()) v.addElement(enum.nextElement());
|
|
return v;
|
|
}
|
|
|
|
protected Vector getUnusedResources() {
|
|
Enumeration enum = results.elements();
|
|
Vector v = new Vector();
|
|
while (enum.hasMoreElements()) {
|
|
ScanResult result = (ScanResult)enum.nextElement();
|
|
if (result.getOccurances().size() < 1) {
|
|
v.addElement(result);
|
|
}
|
|
}
|
|
return v;
|
|
}
|
|
|
|
protected boolean performScan() throws IOException {
|
|
resultsFound = false;
|
|
|
|
ElementImpl root = (ElementImpl)config.getDocumentElement();
|
|
NodeList nl = root.getElementsByTagName("Scan");
|
|
if (nl.getLength() < 1) return resultsFound;
|
|
ElementImpl scan_elem = (ElementImpl)nl.item(0);
|
|
nl = scan_elem.getElementsByTagName("Directory");
|
|
for (int i=0; i < nl.getLength(); i++) {
|
|
ElementImpl dir_elem = (ElementImpl)nl.item(i);
|
|
File directory = new File(dir_elem.getAttribute("location"));
|
|
boolean recurse = dir_elem.getAttribute("recurse_directories").equalsIgnoreCase("true");
|
|
NodeList rules_list = dir_elem.getElementsByTagName("Rules");
|
|
if (rules_list.getLength() < 1) continue;
|
|
ElementImpl rules_elem = (ElementImpl)rules_list.item(0);
|
|
NodeList frules_list = rules_elem.getElementsByTagName("ApplyFileRule");
|
|
// For each file rule
|
|
for (int j=0; j < frules_list.getLength(); j++) {
|
|
ElementImpl frule_elem = (ElementImpl)frules_list.item(j);
|
|
FileRule frule = (FileRule)fileRules.get(frule_elem.getAttribute("name"));
|
|
if (frule == null) continue;
|
|
NodeList prules_list = frule_elem.getElementsByTagName("ApplyParseRule");
|
|
Vector prules_v = new Vector();
|
|
// For each parse rule
|
|
for (int k=0; k < prules_list.getLength(); k++) {
|
|
ElementImpl prule_elem = (ElementImpl)prules_list.item(k);
|
|
ParseRule prule = (ParseRule)parseRules.get(prule_elem.getAttribute("name"));
|
|
if (prule == null) continue;
|
|
prules_v.addElement(prule);
|
|
}
|
|
if (prules_v.size() < 1) continue;
|
|
scanDirectory(directory, frule, prules_v, recurse);
|
|
}
|
|
}
|
|
|
|
return resultsFound;
|
|
}
|
|
|
|
private void scanDirectory(File directory, FileRule frule, Vector prules, boolean recurse) throws IOException {
|
|
|
|
// Recursion step
|
|
if (recurse) {
|
|
File children[] = directory.listFiles(new java.io.FileFilter(){
|
|
public boolean accept(File f) {
|
|
return f.isDirectory();
|
|
}
|
|
|
|
public String getDescription() {
|
|
return "";
|
|
}
|
|
});
|
|
for (int i=0; i < children.length; i++) {
|
|
File new_directory = children[i];
|
|
scanDirectory(new_directory, frule, prules, recurse);
|
|
}
|
|
}
|
|
// Go through each acceptable file
|
|
File children[] = directory.listFiles();
|
|
for (int i=0; i < children.length; i++) {
|
|
File f = children[i];
|
|
if (f.isDirectory() || !(frule.applyRule(f.getName()))) continue;
|
|
FileReader fr = new FileReader(f);
|
|
BufferedReader br = new BufferedReader(fr);
|
|
String line = null;
|
|
int line_count = 0;
|
|
// Read the file line by line
|
|
while ((line = br.readLine()) != null) {
|
|
line_count++;
|
|
Vector findings = new Vector();
|
|
// Apply all parse rules to each line
|
|
for (int j=0; j < prules.size(); j++) {
|
|
ParseRule prule = (ParseRule)prules.elementAt(j);
|
|
Vector temp_results = prule.applyRule(line);
|
|
for (int k=0; k < temp_results.size(); k++) {
|
|
findings.addElement(temp_results.elementAt(k));
|
|
}
|
|
}
|
|
for (int j=0; j < findings.size(); j++) {
|
|
String name = (String)findings.elementAt(j);
|
|
Occurance occ = new Occurance(f.getName(), f.getAbsolutePath(), line_count);
|
|
// If the name is found in the resource bundles derived hashtable
|
|
if (results.containsKey(name)) {
|
|
ScanResult scan_res = (ScanResult)results.get(name);
|
|
scan_res.addOccurance(occ);
|
|
} else {
|
|
// Add it to the missing results
|
|
ScanResult scan_res = new ScanResult(new BundleItem(null, name, "*unknown*"));
|
|
scan_res.addOccurance(occ);
|
|
missing.put(name, scan_res);
|
|
results.put(name, scan_res);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
private Hashtable getFileRules(ElementImpl root) {
|
|
Hashtable result = new Hashtable();
|
|
NodeList frules_list = root.getElementsByTagName("FileRules");
|
|
ElementImpl frules_elem = null;
|
|
if (frules_list.getLength() > 0) frules_elem = (ElementImpl)frules_list.item(0);
|
|
if (frules_elem == null) return result;
|
|
frules_list = frules_elem.getElementsByTagName("FileRule");
|
|
for (int i=0; i < frules_list.getLength(); i++) {
|
|
ElementImpl elem = (ElementImpl)frules_list.item(i);
|
|
FileRule frule = new FileRule(elem.getAttribute("name"), elem.getAttribute("starts_with"),
|
|
elem.getAttribute("ends_with"), elem.getAttribute("contains"));
|
|
result.put(elem.getAttribute("name"), frule);
|
|
}
|
|
return result;
|
|
}
|
|
|
|
private Hashtable getParseRules(ElementImpl root) {
|
|
Hashtable result = new Hashtable();
|
|
NodeList prules_list = root.getElementsByTagName("ParseRules");
|
|
ElementImpl prules_elem = null;
|
|
if (prules_list.getLength() > 0) prules_elem = (ElementImpl)prules_list.item(0);
|
|
if (prules_elem == null) return result;
|
|
prules_list = prules_elem.getElementsByTagName("ParseRule");
|
|
for (int i=0; i < prules_list.getLength(); i++) {
|
|
ElementImpl elem = (ElementImpl)prules_list.item(i);
|
|
ParseRule prule = new ParseRule(elem.getAttribute("name"), elem.getAttribute("follows"),
|
|
elem.getAttribute("precedes"));
|
|
result.put(elem.getAttribute("name"), prule);
|
|
}
|
|
return result;
|
|
}
|
|
}
|
|
|
|
class FileRule {
|
|
String name;
|
|
String starts_with;
|
|
String ends_with;
|
|
String contains;
|
|
|
|
FileRule(String name, String starts_with, String ends_with, String contains) {
|
|
this.name = name;
|
|
this.starts_with = starts_with;
|
|
this.ends_with = ends_with;
|
|
this.contains = contains;
|
|
}
|
|
|
|
boolean applyRule(String source) {
|
|
boolean accept = true;
|
|
if (starts_with != null && starts_with.length() > 0 && !(source.startsWith(starts_with))) accept = false;
|
|
if (ends_with != null && ends_with.length() > 0 && !(source.endsWith(ends_with))) accept = false;
|
|
if (contains != null && contains.length() > 0 && source.indexOf(contains) < 0) accept = false;
|
|
return accept;
|
|
}
|
|
}
|
|
|
|
class ParseRule {
|
|
String name;
|
|
String before;
|
|
String after;
|
|
|
|
ParseRule(String name, String before, String after) {
|
|
this.name = name;
|
|
this.before = before;
|
|
this.after = after;
|
|
}
|
|
|
|
// returns the vector of strings found after before and before after
|
|
|
|
Vector applyRule(String source) {
|
|
Vector v = new Vector();
|
|
if (before != null && before.length() > 0) {
|
|
if (after != null && after.length() > 0) {
|
|
// Both before and after non-empty
|
|
int before_index = -1;
|
|
int after_index = -1;
|
|
while ((before_index = source.indexOf(before, ++before_index)) >= 0) {
|
|
//before_index = source.indexOf(before, before_index);
|
|
after_index = -1;
|
|
after_index = source.indexOf(after, before_index + before.length()+1);
|
|
if (after_index < 0 || before_index < 0 || before.length() < 0) {
|
|
break;
|
|
}
|
|
v.addElement(source.substring(before_index + before.length(), after_index));
|
|
before_index = after_index;
|
|
}
|
|
} else {
|
|
// Before non-empty, after empty
|
|
int index = -1;
|
|
while (source.indexOf(before, ++index) >= 0) {
|
|
index = source.indexOf(before, index);
|
|
String result = source.substring(index + before.length(), source.length());
|
|
if (result != null && result.length() > 0) v.addElement(result);
|
|
}
|
|
}
|
|
} else if (after != null && after.length() > 0) {
|
|
// Before empty, after not
|
|
int index = -1;
|
|
while (source.indexOf(after, ++index) >= 0) {
|
|
index = source.indexOf(before, index);
|
|
String result = source.substring(0, index);
|
|
if (result != null && result.length() > 0) v.addElement(result);
|
|
}
|
|
} else {
|
|
// Before and after empty
|
|
v.addElement(source);
|
|
}
|
|
return v;
|
|
}
|
|
} |