package org.rhq.enterprise.gui.legacy.util;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileReader;
import java.io.FilenameFilter;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import java.util.Set;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class ApplicationResourcesTest {
class BundleLeveragingFilenameFilter implements FilenameFilter {
public boolean accept(File dir, String name) {
if (dir.isHidden()) {
return false;
}
if (dir.getAbsolutePath().endsWith("target")) {
return false;
}
if (dir.getAbsolutePath().endsWith("svn")) {
return false;
}
if (name.endsWith("svn")) {
return false;
}
if (name.endsWith("class")) {
return false;
}
return true;
}
}
class PropertyFile implements Comparable<PropertyFile> {
public final String property;
public final String file;
public PropertyFile(String property, String file) {
this.file = file;
this.property = property;
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + getOuterType().hashCode();
result = prime * result + ((file == null) ? 0 : file.hashCode());
result = prime * result + ((property == null) ? 0 : property.hashCode());
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
PropertyFile other = (PropertyFile) obj;
if (!getOuterType().equals(other.getOuterType()))
return false;
if (file == null) {
if (other.file != null)
return false;
} else if (!file.equals(other.file))
return false;
if (property == null) {
if (other.property != null)
return false;
} else if (!property.equals(other.property))
return false;
return true;
}
private ApplicationResourcesTest getOuterType() {
return ApplicationResourcesTest.this;
}
public int compareTo(PropertyFile o) {
int result = this.property.compareTo(o.property);
if (result != 0) {
return result;
}
return this.file.compareTo(o.file);
}
}
Pattern patternXHTML = Pattern.compile("" + //
".*" + // some number of leading characters
"[\\$|#]" + // starting with a dollar sign or #, the characters supported by UEL
"\\{" + // wrapped in curly braces
"msg" + // followed by the literal 'msg'
"\\[" + // and then brackets
"(" + // start capture group
"[^\\]]+" + // one or more characters up to the first close brace
")" + // finish capture group
"\\]" + // and closing brackets
"\\}" + // and closing curly
".*", // some number of trailing characters
Pattern.CASE_INSENSITIVE | Pattern.DOTALL);
Pattern patternJAVA = null;
Pattern patternJSP = Pattern.compile("" + //
".*?" + // some number of leading characters
"fmt\\:message" + // starting with 'fmt:message' literal
"\\s+?" + // then some whitespace
"key=" + // and the 'key' attribute, with an equals sign, and open double-quote
"\"" + // an opening double-quote
"(" + // start capture group
"[^\"]+" + // one or more characters up to the first closing double-quote
")" + // finish capture group
"\"", // a closing double-quote
//"\\s*" + // then some optional whitespace
//" />", // and closing tag
Pattern.CASE_INSENSITIVE | Pattern.DOTALL);
public void test() {
File modulesDir = new File("F:\\ws\\rhq\\trunk\\modules");
List<File> toSearch = new LinkedList<File>();
toSearch.add(modulesDir);
FilenameFilter filter = new BundleLeveragingFilenameFilter();
Map<PropertyFile, Integer> counts = new HashMap<PropertyFile, Integer>();
int found = 0;
int matches = 0;
while (toSearch.size() > 0) {
File nextFile = toSearch.remove(0);
if (nextFile.isDirectory()) {
for (File child : nextFile.listFiles(filter)) {
toSearch.add(child);
}
} else if (nextFile.isFile()) {
found++;
//System.out.println("Search: " + nextFile.getAbsolutePath());
String path = nextFile.getAbsolutePath();
int extPos = path.lastIndexOf('.');
String ext = path.substring(extPos + 1);
Pattern pattern = null;
if (ext.equals("xhtml")) {
pattern = patternXHTML;
} else if (ext.equals("java")) {
pattern = patternJAVA;
} else if (ext.equals("jsp")) {
pattern = patternJSP;
}
if (pattern != null) {
matches += process(nextFile, pattern, counts);
}
}
}
List<PropertyFile> propertyNames = new ArrayList<PropertyFile>(counts.keySet());
Collections.sort(propertyNames);
for (PropertyFile pf : propertyNames) {
int count = counts.get(pf);
System.out.println("count: " + count + ", property: " + pf.property + ", file: " + pf.file);
}
Properties propertiesBundle = new Properties();
File propertyBundleFile = new File(
"F:/ws/rhq/trunk/modules/enterprise/gui/portal-war/src/main/webapp-filtered/WEB-INF/classes/ApplicationResources.properties");
FileInputStream propertyBundleInputStream = null;
try {
propertyBundleInputStream = new FileInputStream(propertyBundleFile);
propertiesBundle.load(propertyBundleInputStream);
} catch (Exception e) {
System.out.println("Could not load properties from file '" + propertyBundleFile.getAbsolutePath() + "'");
return;
} finally {
if (propertyBundleInputStream != null) {
try {
propertyBundleInputStream.close();
} catch (Exception e) {
System.out.println("Could not close bundle file '" + propertyBundleFile.getAbsolutePath() + "'");
}
}
}
List<String> extraProperties = new ArrayList<String>(); // found in bundle, not in source
List<String> missingProperties = new ArrayList<String>(); // found in source, not in bundle
Set<String> bundlePropertyNames = stringPropertyNames(propertiesBundle);
Set<String> foundPropertyNames = new HashSet<String>();
for (PropertyFile pf : counts.keySet()) {
foundPropertyNames.add(pf.property);
if (bundlePropertyNames.contains(pf.property) == false && missingProperties.contains(pf.property) == false) {
missingProperties.add(pf.property);
}
}
int shortBundleNames = 0;
for (String bundlePropertyName : bundlePropertyNames) {
if (foundPropertyNames.contains(bundlePropertyName) == false
&& extraProperties.contains(bundlePropertyName) == false) {
extraProperties.add(bundlePropertyName);
}
if (bundlePropertyName.split("\\.").length == 1) {
shortBundleNames++;
}
}
Collections.sort(extraProperties);
Collections.sort(missingProperties);
for (String extraProperty : extraProperties) {
if (extraProperty.toLowerCase().indexOf("") != -1) {
System.out.println("Extra: " + extraProperty);
}
}
/*
for (String missingProperty : missingProperties) {
System.out.println("Missing: " + missingProperty);
}
*/
System.out.println("Found " + found + " files");
System.out.println("Found " + matches + " matches");
System.out.println("Found " + extraProperties.size() + " extra");
System.out.println("Found " + missingProperties.size() + " missing");
System.out.println("Found " + shortBundleNames + " short bundle names");
System.out.println("Found " + bundlePropertyNames.size() + " total bundle names");
}
// alternative to using Properties.stringPropertyNames but it works on JDK 5
private Set<String> stringPropertyNames(Properties propertiesBundle) {
HashSet<String> tmpSet = new HashSet<String>();
for (Enumeration<?> allNames = propertiesBundle.propertyNames(); allNames.hasMoreElements();) {
Object name = allNames.nextElement();
tmpSet.add(name.toString());
}
return tmpSet;
}
private int process(File f, Pattern pattern, Map<PropertyFile, Integer> properties) {
BufferedReader lineReader = null;
int matches = 0;
try {
lineReader = new BufferedReader(new FileReader(f));
String nextLine = null;
while ((nextLine = lineReader.readLine()) != null) {
Matcher matcher = pattern.matcher(nextLine);
if (matcher.find()) {
//System.out.println("Matched line '" + nextLine + "' in file '" + f + "'");
String propertyCapture = matcher.group(1);
boolean startQuote = propertyCapture.startsWith("'") || propertyCapture.startsWith("\"");
boolean endQuote = propertyCapture.endsWith("'") || propertyCapture.endsWith("\"");
if (startQuote && endQuote) {
propertyCapture = propertyCapture.substring(1, propertyCapture.length() - 1);
} else if (startQuote) {
propertyCapture = propertyCapture.substring(1, propertyCapture.length());
} else if (endQuote) {
propertyCapture = propertyCapture.substring(0, propertyCapture.length() - 1);
}
PropertyFile nextCount = new PropertyFile(propertyCapture, f.getAbsolutePath());
if (properties.containsKey(nextCount)) {
int count = properties.get(nextCount);
properties.put(nextCount, count + 1);
} else {
properties.put(nextCount, 1);
matches++;
}
} else if (nextLine.indexOf("msg") != -1) {
System.out.println("No match, but found '" + nextLine + "'");
}
}
} catch (Exception e) {
System.out.println("Error opening file '" + f + "': " + e.getMessage());
} finally {
if (lineReader != null) {
try {
lineReader.close();
} catch (Exception e) {
System.out.println("Error closing file '" + f + "': " + e.getMessage());
}
}
}
return matches;
}
// \$ \{ msg \[ " [(^\])] " \] \}
public static void main(String[] args) {
ApplicationResourcesTest tester = new ApplicationResourcesTest();
tester.test();
}
}