/* * Converter.java * * Created on February 12, 2007, 3:57 PM * * To change this template, choose Tools | Template Manager * and open the template in the editor. */ import java.io.BufferedInputStream; import java.io.BufferedReader; import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.FilenameFilter; import java.io.IOException; import java.io.InputStreamReader; import java.util.StringTokenizer; import java.util.Vector; /** * Reads all java files in a directory specified by the users and removes all * instances of package. * * @author Matt DesVoigne */ public class OrgFilter { // TODO Make Swing a parameter to the application or get rid of Swing in // org. public static final String[] ORG_PACKAGES = { "data", "events", "gui11", "io", "javaws", "layout", "listeners", "math11", "util11" }; // All classes in a package may not be deleted or else the buildQA script // will not work. private int[] numClassesUsedInPackage = new int[ORG_PACKAGES.length]; public static final String IMPORT = "import"; private FilenameFilter filter; private File[] appletFiles; private Vector appletOrg; private Vector orgClasses; /** * Creates a new instance of Converter */ public OrgFilter(String directory) { filter = new FilenameFilter() { public boolean accept(File dir, String name) { return (name.endsWith("java") /* * || (new File(dir, * name).isDirectory()) */); } }; appletOrg = new Vector(); File dir = new File(directory); System.out.println("Directory is " + dir.getAbsolutePath()); if (!dir.isDirectory()) { throw new IllegalArgumentException("Converter: No such directory: " + dir.getAbsolutePath()); } // Get the filtered file names. appletFiles = dir.listFiles(filter); // Fill a vector of all org classes orgClasses = new Vector(); for (int i = 0; i < ORG_PACKAGES.length; i++) { File orgDir = new File("org/shodor/" + ORG_PACKAGES[i]); if (!orgDir.isDirectory()) { System.out.println("DEV ERROR: org/shodor/" + ORG_PACKAGES[i] + " is not a directory."); continue; } File[] packageFiles = orgDir.listFiles(filter); numClassesUsedInPackage[i] = 0; for (int j = 0; j < packageFiles.length; j++) { String orgClassName = packageFiles[j].getAbsolutePath(); // Extract the class name from the path to the org file. orgClasses.addElement(orgClassName.substring( orgClassName.indexOf("org"), orgClassName.indexOf(".java")).replace( File.separatorChar, '/')); } } // for (int i = 0; i < orgClasses.size(); i++) { // System.out.println("org class : " // + (String) orgClasses.elementAt(i)); // } } /** * Adds the orgclasses * * @param orgClass */ private void getOrgInterDependencies(String orgClass) { // System.out.println("Getting org dependencies of " + orgClass); Vector orgDependencies = getOrgImports(new File(orgClass.trim() .replace(";", "") + ".java")); for (int i = 0; i < orgDependencies.size(); i++) { String nextOrg = (String) orgDependencies.elementAt(i); if (!appletOrg.contains(nextOrg)) { appletOrg.addElement(nextOrg); } getOrgInterDependencies(nextOrg); } } public static boolean isOrgImport(String line) { return line.startsWith(IMPORT) && line.indexOf("org.shodor") != -1; } /** * Retrieves all import statements in a given file. * * @param f * @return */ public Vector getOrgImports(File f) { Vector retValue = new Vector(); BufferedReader in; try { in = new BufferedReader(new InputStreamReader( new BufferedInputStream(new FileInputStream(f)))); } catch (FileNotFoundException fnfe) { System.out.println("The file: " + f.getAbsolutePath() + " cannot be found. Returning empty import set."); return null; } String input; try { while ((input = in.readLine()) != null) { if (isOrgImport(input.trim())) { String importClass = importToFileName(input); if (!appletOrg.contains(importClass)) { retValue.addElement(importClass); } } if (f.getAbsolutePath().indexOf("shodor") != -1) { // We are getting the imports of an org class. We must // search for classes within the same org package that // do not need to be imported. for (int k = 0; k < orgClasses.size(); k++) { String orgPath = (String) orgClasses.elementAt(k); String orgClassName = orgPath.substring(orgPath .lastIndexOf('/') + 1); if ((input.trim().indexOf(orgClassName) != -1) && !appletOrg.contains(orgPath)) { retValue.addElement(orgPath); } } } } } catch (IOException ioe) { System.out.println("ERROR: Parsing data file " + f.getAbsolutePath()); System.out.println(ioe.getMessage()); ioe.printStackTrace(); } catch (Exception e) { e.printStackTrace(); } try { in.close(); } catch (IOException ioe) { System.out.println("Error closing file: " + f.getAbsolutePath()); System.out.println(ioe.getMessage()); ioe.printStackTrace(); return null; } return retValue; } /** * Removes "import ". Removes semi-colon, Replaces "." with ";" * * @param input * e.g. "import org.shodor.gui11.ShodorGraphPaper;" * @return e.g. "org/shodor/gui11/ShodorGraphPaper" */ public static String importToFileName(String input) { return ((input.substring(IMPORT.length()).trim()).replace('.', '/')) .replace(";", ""); } /** * Populates the appletOrg Vector with the org classes */ public void getOrgDependencies() { for (int i = 0; i < appletFiles.length; i++) { // Read the contents of each file into a vector, omitting any lines // beginning with the word "package." Vector appletFileOrg = getOrgImports(appletFiles[i]); for (int j = 0; j < appletFileOrg.size(); j++) { String nextOrg = (String) appletFileOrg.elementAt(j); if (!appletOrg.contains(nextOrg)) { appletOrg.addElement(nextOrg); } } String[] appletFileImports = new String[appletOrg.size()]; for (int j = 0; j < appletFileImports.length; j++) { appletFileImports[j] = (String) appletOrg.elementAt(j); } for (int j = 0; j < appletFileImports.length; j++) { getOrgInterDependencies(appletFileImports[j]); } } // for (int j = 0; j < appletOrg.size(); j++) { // System.out.println("---> " + (String) appletOrg.elementAt(j)); // } System.out.println("Number of org classes available: " + orgClasses.size()); System.out.println("Number of org classes needed: " + appletOrg.size()); } public void deleteUnusedFiles(String directory) { if (orgClasses.isEmpty()) { System.out.println("DEV ERROR: Empty orgclasses vector for " + directory); return; } if (appletOrg.isEmpty()) { System.out.println("DEV ERROR: Empty appletOrg vector for " + directory); return; } // At least one file must remain in each package for the script to work. for (int i = 0; i < appletOrg.size(); i++) { String nextOrg = (String) appletOrg.elementAt(i); for (int j = 0; j < ORG_PACKAGES.length; j++) { if (pathContains(nextOrg, ORG_PACKAGES[j])) { numClassesUsedInPackage[j]++; } } } // If true, no classes in this package are used by the applet. boolean[] packageEmpty = new boolean[ORG_PACKAGES.length]; for (int i = 0; i < packageEmpty.length; i++) { packageEmpty[i] = (numClassesUsedInPackage[i] == 0); } for (int i = 0; i < orgClasses.size(); i++) { String nextOrg = (String) orgClasses.elementAt(i); if (!appletOrg.contains(nextOrg)) { // Delete the file nextOrg. It is not needed for this applet. // System.out.println("The class "+nextOrg+" is not used for // this applet."); File unusedFile = new File(nextOrg + ".java"); // Do not delete the file if it will create an empty package. boolean deleteFile = true; for (int j = 0; j < ORG_PACKAGES.length; j++) { if (pathContains(nextOrg, ORG_PACKAGES[j])) { if (packageEmpty[j]) { if (!ORG_PACKAGES[j].trim().equalsIgnoreCase("io")) { // Don't delete the file if none of the classes // in a // package are used so there will be at least // one // class in each package. deleteFile = false; // OK to delete the rest of the classes as long // as // we keep one. packageEmpty[j] = false; } else { // If it is the io package that is not used (as // in life), then let ShodorFileExtensions be // the class that is left in the package as it // is just a bunch of constants and does not // depend on anything that may have been // deleted. deleteFile = nextOrg .indexOf("ShodorFileExtensions") == -1; } } } } if (deleteFile) { //System.out.println("Del: " + unusedFile.getAbsolutePath()); if (!unusedFile.delete()) { System.out .println("Could not delete the unused org class " + nextOrg); } } } } } /** * Determines if the package name is included in the path * * @param nextOrg * @param string * @return */ private boolean pathContains(String path, String packageName) { boolean retValue = false; StringTokenizer st = new StringTokenizer(path, "/"); while (st.hasMoreTokens()) { if (st.nextToken().trim().equalsIgnoreCase(packageName.trim())) { retValue = true; } } return retValue; } /** * @param args * the command line arguments */ public static void main(String[] args) { OrgFilter myConverter = null; String directory = null; if (args.length != 1) usage(); directory = args[0]; if (directory == null) directory = System.getProperty("user.dir"); (myConverter = new OrgFilter(directory)).getOrgDependencies(); myConverter.deleteUnusedFiles(directory); } /** * Notify user of proper usage and exit. */ public static void usage() { System.out .println("Usage: java OrgFilter [applet_directory]. Try again."); System.exit(0); } }