| package org.eclipse.wtp.releng.tools.pii.internal; |
| |
| import java.io.BufferedReader; |
| import java.io.BufferedWriter; |
| import java.io.File; |
| import java.io.FileReader; |
| import java.io.FileWriter; |
| import java.io.IOException; |
| import java.util.Collection; |
| import java.util.Enumeration; |
| import java.util.HashSet; |
| import java.util.Hashtable; |
| import java.util.Iterator; |
| import java.util.Vector; |
| |
| public class KeyUtils |
| { |
| public Hashtable findUnusedKeys( String pathName, String[] excludes ) |
| { |
| File startPath = new File( pathName ); |
| Hashtable results = new Hashtable(); |
| |
| if( startPath == null || !startPath.isDirectory() ) |
| { |
| System.out.println( "Error: The first parameter must specify a plugins directory!" ); |
| return results; |
| } |
| |
| File[] pluginDirs = startPath.listFiles(); |
| |
| // Find all the property files and files containing strings. |
| for( int index = 0; index < pluginDirs.length; index++ ) |
| { |
| Vector propertyFiles = new Vector(); |
| Vector srcFiles = new Vector(); |
| File pluginDir = pluginDirs[index]; |
| |
| getFiles( pluginDir, propertyFiles, "properties", excludes ); |
| |
| // For now we only check java, jsp, and xml files. |
| getFiles( pluginDir, srcFiles, "java", new String[0] ); |
| getFiles( pluginDir, srcFiles, "jsp", new String[0] ); |
| getFiles( pluginDir, srcFiles, "xml", new String[0] ); |
| |
| HashSet srcKeys = new HashSet(); |
| |
| // Loop over all string source files. |
| for( int srcIndex = 0; srcIndex < srcFiles.size(); srcIndex++ ) |
| { |
| File srcFile = (File)srcFiles.elementAt( srcIndex ); |
| String[] srcLines = readLines( srcFile ); |
| |
| for( int lineIndex = 0; lineIndex < srcLines.length; lineIndex++ ) |
| { |
| findStrings( srcLines[lineIndex], srcKeys ); |
| } |
| } |
| |
| // Loop over all the property files to find unused keys. |
| for( int propIndex = 0; propIndex < propertyFiles.size(); propIndex++ ) |
| { |
| File propFile = (File)propertyFiles.elementAt( propIndex ); |
| String[] lines = readLines( propFile ); |
| |
| int lineIndex = 0; |
| |
| while( lineIndex < lines.length ) |
| { |
| String line = lines[lineIndex].trim(); |
| |
| boolean validKey = isLineKey( srcKeys, line ); |
| boolean hasKey = line.indexOf( '=' ) != -1; |
| boolean comment = line.startsWith( "#" ); |
| |
| if( !comment && !validKey && hasKey ) |
| { |
| addUnusedKey( results, propFile, line ); |
| } |
| |
| boolean continuation = false; |
| |
| // Skip over continuation lines. |
| while( lineIndex < lines.length && lines[lineIndex].endsWith( "\\" ) ) |
| { |
| lineIndex++; |
| continuation = true; |
| } |
| |
| if( !continuation ) |
| { |
| lineIndex++; |
| } |
| } |
| } |
| } |
| |
| return results; |
| } |
| |
| private void addUnusedKey( Hashtable table, File propFile, String line ) |
| { |
| int equalIndex = line.indexOf( '=' ); |
| String key = line.substring( 0, equalIndex ); |
| Vector entry = (Vector)table.get( propFile ); |
| |
| if( entry == null ) |
| { |
| entry = new Vector(); |
| table.put( propFile, entry ); |
| } |
| |
| entry.add( key ); |
| } |
| |
| private void findStrings( String line, HashSet keys ) |
| { |
| int quotestart = line.indexOf( '"' ); |
| int quoteend = line.indexOf( '"', quotestart + 1 ); |
| |
| while( quotestart != -1 && quoteend != -1 && quotestart < quoteend ) |
| { |
| // Find last real ending quote. |
| while( quotestart != -1 && quoteend != -1 && line.charAt( quoteend-1 ) == '\\' ) |
| { |
| quoteend = line.indexOf( '"', quoteend + 1 ); |
| } |
| |
| if( quotestart == -1 || quoteend == -1 || quotestart > quoteend ) break; |
| |
| String key = line.substring( quotestart+1, quoteend ); |
| |
| if( key.startsWith( "%" ) ) |
| { |
| // Remove the leading percent sign. |
| keys.add( key.substring( 1 ) ); |
| } |
| else |
| { |
| keys.add( key ); |
| } |
| |
| quotestart = line.indexOf( '"', quoteend+1 ); |
| quoteend = line.indexOf( '"', quotestart+1 ); |
| } |
| } |
| |
| private String[] readLines( File file ) |
| { |
| Vector files = new Vector(); |
| BufferedReader reader = null; |
| |
| try |
| { |
| reader = new BufferedReader( new FileReader( file ) ); |
| |
| String line = reader.readLine(); |
| |
| while( line != null ) |
| { |
| files.add( line ); |
| line = reader.readLine(); |
| } |
| } |
| catch( Exception exc ) |
| { |
| System.out.println( "Problem opening file:" + file ); |
| exc.printStackTrace(); |
| } |
| finally |
| { |
| try |
| { |
| if( reader != null ) reader.close(); |
| } |
| catch( Exception exc ) |
| { |
| exc.printStackTrace(); |
| } |
| } |
| |
| return (String[])files.toArray( new String[0] ); |
| |
| } |
| |
| private String[] readLines( String file ) |
| { |
| return readLines( new File( file ) ); |
| } |
| |
| private void getFiles( File file, Vector files, String fileSuffix, String[] excludeFiles ) |
| { |
| if( stringInArray( file.getName(), excludeFiles ) ) |
| { |
| // do nothing |
| } |
| else if( file.isDirectory() ) |
| { |
| File[] dirfiles = file.listFiles(); |
| |
| for( int index = 0; index < dirfiles.length; index++ ) |
| { |
| getFiles( dirfiles[index], files, fileSuffix, excludeFiles ); |
| } |
| } |
| else if( file.getName().endsWith( fileSuffix ) ) |
| { |
| files.add( file ); |
| } |
| } |
| |
| private boolean stringInArray( String name, String[] names ) |
| { |
| boolean found = false; |
| |
| for( int index = 0; index < names.length; index++ ) |
| { |
| if( name.equals( names[index] )) |
| { |
| found = true; |
| break; |
| } |
| } |
| |
| return found; |
| } |
| |
| private boolean isLineKey( Collection keys, String line ) |
| { |
| boolean result = false; |
| Iterator iter = keys.iterator(); |
| int equalIndex = line.indexOf( '=' ); |
| String key = null; |
| |
| if( equalIndex != -1 && !line.startsWith( "#" )) |
| { |
| key = line.substring( 0, equalIndex ).trim(); |
| } |
| |
| while( iter.hasNext() && key != null ) |
| { |
| String collectionKey = (String)iter.next(); |
| if( key.equals( collectionKey ) ) |
| { |
| result = true; |
| break; |
| } |
| } |
| |
| return result; |
| } |
| |
| public static void main( String[] args ) |
| { |
| KeyUtils utils = new KeyUtils(); |
| String pathName = args.length > 0 ? args[0] : ""; |
| String outputDir = args.length > 1 ? args[1] : ""; |
| String[] excludes = args.length > 1 ? new String[args.length - 1] : new String[0]; |
| if (excludes.length > 0) |
| System.arraycopy(args, 0, excludes, 0, excludes.length); |
| Hashtable results = utils.findUnusedKeys( pathName, excludes ); |
| Enumeration keys = results.keys(); |
| |
| while( keys.hasMoreElements() ) |
| { |
| File file = (File)keys.nextElement(); |
| Vector keyList = (Vector)results.get( file ); |
| |
| String absOutputPath = new File ( outputDir ).getAbsolutePath(); |
| StringBuffer sb = new StringBuffer( absOutputPath ); |
| if ( !absOutputPath.endsWith( "/" ) && !absOutputPath.endsWith( "\\" ) ) |
| sb.append( '/' ); |
| String absPath = file.getAbsolutePath(); |
| sb.append( absPath.substring( pathName.length(), absPath.length() ) ); |
| |
| BufferedWriter bw = null; |
| try |
| { |
| File outputFile = new File( sb.toString() ); |
| outputFile.getParentFile().mkdirs(); |
| bw = new BufferedWriter( new FileWriter( outputFile ) ); |
| for( int index = 0; index < keyList.size(); index++ ) |
| { |
| bw.write( keyList.elementAt( index ).toString() ); |
| bw.newLine(); |
| } |
| } |
| catch (IOException e) |
| { |
| e.printStackTrace(); |
| } |
| finally |
| { |
| if ( bw != null ) |
| { |
| try |
| { |
| bw.close(); |
| } |
| catch (IOException e) |
| { |
| e.printStackTrace(); |
| } |
| } |
| } |
| } |
| } |
| } |