316 lines
10 KiB
Java
316 lines
10 KiB
Java
|
/*
|
||
|
*****************************************************************************
|
||
|
* Copyright (C) 2000-2002, International Business Machines Corporation and *
|
||
|
* others. All Rights Reserved. *
|
||
|
*****************************************************************************
|
||
|
*
|
||
|
* $Source: /xsrl/Nsvn/icu/unicodetools/com/ibm/rbm/RBReporterScanner.java,v $
|
||
|
* $Date: 2002/05/20 18:53:09 $
|
||
|
* $Revision: 1.1 $
|
||
|
*
|
||
|
*****************************************************************************
|
||
|
*/
|
||
|
package com.ibm.rbm;
|
||
|
|
||
|
|
||
|
import javax.swing.*;
|
||
|
import java.awt.*;
|
||
|
import javax.swing.event.*;
|
||
|
import javax.swing.filechooser.*;
|
||
|
import java.awt.event.*;
|
||
|
import java.io.*;
|
||
|
import java.util.*;
|
||
|
|
||
|
import org.apache.xerces.parsers.*;
|
||
|
import org.apache.xerces.dom.*;
|
||
|
import org.apache.xml.serialize.*;
|
||
|
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 - Email: <a href="mailto:jjared@almaden.ibm.com">jjared@almaden.ibm.com</a>
|
||
|
* @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) {
|
||
|
if (f.isDirectory()) return true;
|
||
|
else return false;
|
||
|
}
|
||
|
|
||
|
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;
|
||
|
else {
|
||
|
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;
|
||
|
}
|
||
|
}
|