From 5dc9cbc324aa6a3c499f384d020cf38a9cf11bc9 Mon Sep 17 00:00:00 2001 From: Romain PELISSE Date: Fri, 21 Dec 2012 20:17:23 +0100 Subject: [PATCH] pmd: rework CPD CLI to use jcommander --- .../java/net/sourceforge/pmd/cpd/CPD.java | 88 +---- .../pmd/cpd/CPDCommandLineInterface.java | 93 ++++++ .../sourceforge/pmd/cpd/CPDConfiguration.java | 305 ++++++++++++------ .../java/net/sourceforge/pmd/cpd/CPDTask.java | 8 +- .../java/net/sourceforge/pmd/cpd/GUI.java | 193 +++++------ 5 files changed, 411 insertions(+), 276 deletions(-) create mode 100644 pmd/src/main/java/net/sourceforge/pmd/cpd/CPDCommandLineInterface.java diff --git a/pmd/src/main/java/net/sourceforge/pmd/cpd/CPD.java b/pmd/src/main/java/net/sourceforge/pmd/cpd/CPD.java index dd7fca85c9..6dac9e385e 100644 --- a/pmd/src/main/java/net/sourceforge/pmd/cpd/CPD.java +++ b/pmd/src/main/java/net/sourceforge/pmd/cpd/CPD.java @@ -10,7 +10,6 @@ import java.util.HashSet; import java.util.Iterator; import java.util.List; import java.util.Map; -import java.util.Properties; import java.util.Set; import java.util.TreeMap; @@ -18,12 +17,8 @@ import net.sourceforge.pmd.util.FileFinder; public class CPD { - private static final int MISSING_FILES = 1; - private static final int MISSING_ARGS = 2; - private static final int DUPLICATE_CODE_FOUND = 4; - private CPDConfiguration configuration; - + private Map source = new TreeMap(); private CPDListener listener = new CPDNullListener(); private Tokens tokens = new Tokens(); @@ -39,11 +34,7 @@ public class CPD { public void go() { TokenEntry.clearImages(); - matchAlgorithm = new MatchAlgorithm( - source, tokens, - configuration.minimumTileSize(), - listener - ); + matchAlgorithm = new MatchAlgorithm(source, tokens,configuration.getMinimumTileSize(),listener); matchAlgorithm.findMatches(); } @@ -82,7 +73,7 @@ public class CPD { private void add(int fileCount, File file) throws IOException { - if (configuration.skipDuplicates()) { + if (configuration.isSkipDuplicates()) { // TODO refactor this thing into a separate class String signature = file.getName() + '_' + file.length(); if (current.contains(signature)) { @@ -103,74 +94,7 @@ public class CPD { source.put(sourceCode.getFileName(), sourceCode); } - private static void setSystemProperties(String[] args) { - boolean ignoreLiterals = CPDConfiguration.findBooleanSwitch(args, "--ignore-literals"); - boolean ignoreIdentifiers = CPDConfiguration.findBooleanSwitch(args, "--ignore-identifiers"); - boolean ignoreAnnotations = CPDConfiguration.findBooleanSwitch(args, "--ignore-annotations"); - Properties properties = System.getProperties(); - if (ignoreLiterals) { - properties.setProperty(JavaTokenizer.IGNORE_LITERALS, "true"); - } - if (ignoreIdentifiers) { - properties.setProperty(JavaTokenizer.IGNORE_IDENTIFIERS, "true"); - } - if (ignoreAnnotations) { - properties.setProperty(JavaTokenizer.IGNORE_ANNOTATIONS, "true"); - } - System.setProperties(properties); - } - - public static void main(String[] args) { - if (args.length == 0) { - showUsage(); - System.exit(MISSING_ARGS); - } - - try { - CPDConfiguration config = new CPDConfiguration(args); - - // Pass extra parameters as System properties to allow language - // implementation to retrieve their associate values... - setSystemProperties(args); - - CPD cpd = new CPD(config); - - /* FIXME: Improve this !!! */ - boolean missingFiles = true; - for (int position = 0; position < args.length; position++) { - if (args[position].equals("--files")) { - cpd.addRecursively(args[position + 1]); - if ( missingFiles ) { - missingFiles = false; - } - } - } - - if ( missingFiles ) { - System.out.println("No " + "--files" + " value passed in"); - showUsage(); - System.exit(MISSING_FILES); - } - - cpd.go(); - if (cpd.getMatches().hasNext()) { - System.out.println(config.renderer().render(cpd.getMatches())); - System.exit(DUPLICATE_CODE_FOUND); - } - } catch (Exception e) { - e.printStackTrace(); - } - } - - public static void showUsage() { - System.out.println("Usage:"); - System.out.println(" java net.sourceforge.pmd.cpd.CPD --minimum-tokens xxx --files xxx [--language xxx] [--encoding xxx] [--format (xml|text|csv|vs)] [--skip-duplicate-files] "); - System.out.println("i.e: "); - System.out.println(" java net.sourceforge.pmd.cpd.CPD --minimum-tokens 100 --files c:\\jdk14\\src\\java "); - System.out.println("or: "); - System.out.println(" java net.sourceforge.pmd.cpd.CPD --minimum-tokens 100 --files /path/to/c/code --language c "); - System.out.println("or: "); - System.out.println(" java net.sourceforge.pmd.cpd.CPD --minimum-tokens 100 --encoding UTF-16LE --files /path/to/java/code --format xml"); - } - + public static void main(String[] args) { + CPDCommandLineInterface.main(args); + } } diff --git a/pmd/src/main/java/net/sourceforge/pmd/cpd/CPDCommandLineInterface.java b/pmd/src/main/java/net/sourceforge/pmd/cpd/CPDCommandLineInterface.java new file mode 100644 index 0000000000..5a923c4610 --- /dev/null +++ b/pmd/src/main/java/net/sourceforge/pmd/cpd/CPDCommandLineInterface.java @@ -0,0 +1,93 @@ +/** + * BSD-style license; for more info see http://pmd.sourceforge.net/license.html + */ +package net.sourceforge.pmd.cpd; + +import java.io.IOException; +import java.util.List; + +import com.beust.jcommander.JCommander; +import com.beust.jcommander.ParameterException; + +public class CPDCommandLineInterface { + + private static final int DUPLICATE_CODE_FOUND = 4; + + public static final String NO_EXIT_AFTER_RUN = "net.sourceforge.pmd.cli.noExit"; + public static final String STATUS_CODE_PROPERTY = "net.sourceforge.pmd.cli.status"; + + private static final String progName = "cpd"; + + public static void setStatusCodeOrExit(int status) { + if (isExitAfterRunSet()) + System.exit(status); + else + setStatusCode(status); + } + + private static boolean isExitAfterRunSet() { + return (System.getenv(NO_EXIT_AFTER_RUN) == null ? false : true); + } + + private static void setStatusCode(int statusCode) { + System.setProperty(STATUS_CODE_PROPERTY, Integer.toString(statusCode)); + } + + public static void main(String[] args) { + CPDConfiguration arguments = new CPDConfiguration(); + JCommander jcommander = new JCommander(arguments); + jcommander.setProgramName(progName); + + try { + jcommander.parse(args); + if (arguments.isHelp()) { + jcommander.usage(); + // System.out.println(buildUsageText()); + setStatusCodeOrExit(0); + } + } catch (ParameterException e) { + jcommander.usage(); + System.out.println(buildUsageText()); + System.out.println(e.getMessage()); + // setStatusCodeOrExit(ERROR_STATUS); + } + arguments.postContruct(); + // Pass extra parameters as System properties to allow language + // implementation to retrieve their associate values... + CPDConfiguration.setSystemProperties(arguments); + CPD cpd = new CPD(arguments); + addSourcesFilesToCPD(arguments.getFiles(),cpd); + cpd.go(); + if (cpd.getMatches().hasNext()) { + System.out.println(arguments.getRenderer().render(cpd.getMatches())); + System.exit(DUPLICATE_CODE_FOUND); + } + } + + private static void addSourcesFilesToCPD(List files, CPD cpd) { + try { + for (String file : files) + cpd.addRecursively(file); + } catch (IOException e) { + throw new IllegalStateException(e); + } + } + + private static final char EOL = '\n'; + public static String buildUsageText() { + String helpText = "Usage:"; + + helpText += " java net.sourceforge.pmd.cpd.CPD --minimum-tokens xxx --files xxx [--language xxx] [--encoding xxx] [--format (xml|text|csv|vs)] [--skip-duplicate-files] " + EOL; + helpText += "i.e: " + EOL; + + helpText += " java net.sourceforge.pmd.cpd.CPD --minimum-tokens 100 --files c:\\jdk14\\src\\java " + EOL; + helpText += "or: " + EOL; + + helpText += " java net.sourceforge.pmd.cpd.CPD --minimum-tokens 100 --files /path/to/c/code --language c " + EOL; + helpText += "or: " + EOL; + + helpText += " java net.sourceforge.pmd.cpd.CPD --minimum-tokens 100 --encoding UTF-16LE --files /path/to/java/code --format xml" + EOL; + return helpText; + } + +} diff --git a/pmd/src/main/java/net/sourceforge/pmd/cpd/CPDConfiguration.java b/pmd/src/main/java/net/sourceforge/pmd/cpd/CPDConfiguration.java index 2634789d8d..80fcbc1733 100644 --- a/pmd/src/main/java/net/sourceforge/pmd/cpd/CPDConfiguration.java +++ b/pmd/src/main/java/net/sourceforge/pmd/cpd/CPDConfiguration.java @@ -2,116 +2,229 @@ package net.sourceforge.pmd.cpd; import java.io.File; import java.io.FilenameFilter; +import java.util.List; +import java.util.Properties; import net.sourceforge.pmd.AbstractConfiguration; +import com.beust.jcommander.IStringConverter; +import com.beust.jcommander.Parameter; + /** - * + * * @author Brian Remedios + * @author Romain Pelisse - */ public class CPDConfiguration extends AbstractConfiguration { - private Language language; - private int minimumTileSize; - private boolean skipDuplicates; - private Renderer renderer; - - private static final int MISSING_REQUIRED_ARGUMENT = 3; - - public CPDConfiguration(String[] args) { + public final static String DEFAULT_LANGUAGE = "java"; - String languageString = findOptionalStringValue(args, "--language", "java"); - language = new LanguageFactory().createLanguage(languageString); - - String formatString = findOptionalStringValue(args, "--format", "text"); - renderer = getRendererFromString(formatString); - - final String systemDefaultEncoding = System.getProperty("file.encoding"); - setEncoding( findOptionalStringValue(args, "--encoding", systemDefaultEncoding) ); + public final static String DEFAULT_RENDERER = "text"; - minimumTileSize = Integer.parseInt(findRequiredStringValue(args, "--minimum-tokens")); - - skipDuplicates = findBooleanSwitch(args, "--skip-duplicate-files"); - } - - public CPDConfiguration(int theMinTileSize, Language theLanguage, String theEncoding) { - minimumTileSize = theMinTileSize; - language = theLanguage; - setEncoding(theEncoding); + @Parameter(names = "--language", description = "sources code language. Default value is" + + DEFAULT_LANGUAGE, required = false, converter = LanguageConverter.class) + private Language language; + + @Parameter(names = "--minimum-tokens", description = "minimum", required = true) + private int minimumTileSize; + + @Parameter(names = "--format", description = "report format. Default value is " + + DEFAULT_RENDERER, required = false) + private boolean skipDuplicates; + + @Parameter(names = "--skip-duplicate-files", description = "ToDo", required = false, converter = RendererConverter.class) + private Renderer renderer; + + @Parameter(names = "--encoding", description = "ToDo", required = false, converter = EncodingConverter.class) + private String encoding; + + @Parameter(names = "--ignore-literals", description = "ToDo", required = false) + private boolean ignoreLiterals; + + @Parameter(names = "--ignore-identifiers", description = "ToDo", required = false) + private boolean ignoreIdentifiers; + + @Parameter(names = "--ignore-annotations", description = "ToDo", required = false) + private boolean ignoreAnnotations; + + @Parameter(names = "--files", variableArity = true, description = "ToDo", required = true) + private List files; + + @Parameter(names = { "--help", "-h" }, description = "Print help text", required = false) + private boolean help; + + class LanguageConverter implements IStringConverter { + + public Language convert(String languageString) { + if (languageString == null || "".equals(languageString)) { + languageString = DEFAULT_LANGUAGE; + } + return new LanguageFactory().createLanguage(languageString); + } } - - public void setEncoding(String theEncoding) { - super.setSourceEncoding(theEncoding); - - if ( ! theEncoding.equals( System.getProperty("file.encoding") ) ) - System.setProperty("file.encoding", theEncoding); - } - - public SourceCode sourceCodeFor(File file) { - return new SourceCode( - new SourceCode.FileCodeLoader(file, getSourceEncoding()) - ); - } - - public Language language() { return language; } - - public int minimumTileSize() { return minimumTileSize; } - - public boolean skipDuplicates() { return skipDuplicates; } - public void skipDuplicates(boolean flag) { skipDuplicates = flag; } - - public FilenameFilter filenameFilter() { return language.getFileFilter(); } - - public Tokenizer tokenizer() { return language.getTokenizer(); } - - public Renderer renderer() { return renderer; } + class RendererConverter implements IStringConverter { - public static Renderer getRendererFromString(String name /*, String encoding*/) { - if (name.equalsIgnoreCase("text") || name.equals("")) { - return new SimpleRenderer(); - } else if ("xml".equals(name)) { - return new XMLRenderer(); - } else if ("csv".equals(name)) { - return new CSVRenderer(); - } else if ("vs".equals(name)) { - return new VSRenderer(); - } - try { - return (Renderer) Class.forName(name).newInstance(); - } catch (Exception e) { - System.out.println("Can't find class '" + name + "', defaulting to SimpleRenderer."); - } - return new SimpleRenderer(); - } + public Renderer convert(String formatString) { + if (formatString == null || "".equals(formatString)) { + formatString = DEFAULT_RENDERER; + } + return getRendererFromString(formatString); + } + } - public static boolean findBooleanSwitch(String[] args, String name) { - for (int i = 0; i < args.length; i++) { - if (args[i].equals(name)) { - return true; - } - } - return false; - } + class EncodingConverter implements IStringConverter { - public static String findOptionalStringValue(String[] args, String name, String defaultValue) { - for (int i = 0; i < args.length; i++) { - if (args[i].equals(name)) { - return args[i + 1]; - } - } - return defaultValue; - } + public String convert(String encoding) { + if (encoding == null || "".equals(encoding)) + encoding = System.getProperty("file.encoding"); + return setEncoding(encoding); + } + } - private static String findRequiredStringValue(String[] args, String name) { - for (int i = 0; i < args.length; i++) { - if (args[i].equals(name)) { - return args[i + 1]; - } - } - System.out.println("No " + name + " value passed in"); - CPD.showUsage(); - System.exit(MISSING_REQUIRED_ARGUMENT); - return ""; - } + public String setEncoding(String theEncoding) { + super.setSourceEncoding(theEncoding); + + if (!theEncoding.equals(System.getProperty("file.encoding"))) + System.setProperty("file.encoding", theEncoding); + return theEncoding; + } + + public SourceCode sourceCodeFor(File file) { + return new SourceCode(new SourceCode.FileCodeLoader(file, + getSourceEncoding())); + } + + public void postContruct() { + if ( this.getLanguage() == null ) + this.setLanguage(CPDConfiguration.getLanguageFromString(DEFAULT_LANGUAGE)); + if ( this.getRenderer() == null ) + this.setRenderer(getRendererFromString(DEFAULT_RENDERER)); + + } + + public static Renderer getRendererFromString(String name /* , String encoding */) { + if (name.equalsIgnoreCase(DEFAULT_RENDERER) || name.equals("")) { + return new SimpleRenderer(); + } else if ("xml".equals(name)) { + return new XMLRenderer(); + } else if ("csv".equals(name)) { + return new CSVRenderer(); + } else if ("vs".equals(name)) { + return new VSRenderer(); + } + try { + return (Renderer) Class.forName(name).newInstance(); + } catch (Exception e) { + System.out.println("Can't find class '" + name + + "', defaulting to SimpleRenderer."); + } + return new SimpleRenderer(); + } + + public static Language getLanguageFromString(String languageString) { + return new LanguageFactory().createLanguage(languageString); + } + + public static void setSystemProperties(CPDConfiguration configuration) { + Properties properties = System.getProperties(); + if (configuration.isIgnoreLiterals()) { + properties.setProperty(JavaTokenizer.IGNORE_LITERALS, "true"); + } + if (configuration.isIgnoreIdentifiers()) { + properties.setProperty(JavaTokenizer.IGNORE_IDENTIFIERS, "true"); + } + if (configuration.isIgnoreAnnotations()) { + properties.setProperty(JavaTokenizer.IGNORE_ANNOTATIONS, "true"); + } + System.setProperties(properties); + } + + public Language getLanguage() { + return language; + } + + public void setLanguage(Language language) { + this.language = language; + } + + public int getMinimumTileSize() { + return minimumTileSize; + } + + public void setMinimumTileSize(int minimumTileSize) { + this.minimumTileSize = minimumTileSize; + } + + public boolean isSkipDuplicates() { + return skipDuplicates; + } + + public void setSkipDuplicates(boolean skipDuplicates) { + this.skipDuplicates = skipDuplicates; + } + + public Renderer getRenderer() { + return renderer; + } + + public Tokenizer tokenizer() { + if ( language == null ) + throw new IllegalStateException("Language is null."); + return language.getTokenizer(); + } + + public FilenameFilter filenameFilter() { + if ( language == null ) + throw new IllegalStateException("Language is null."); + return language.getFileFilter(); + } + + public void setRenderer(Renderer renderer) { + this.renderer = renderer; + } + + public boolean isIgnoreLiterals() { + return ignoreLiterals; + } + + public void setIgnoreLiterals(boolean ignoreLiterals) { + this.ignoreLiterals = ignoreLiterals; + } + + public boolean isIgnoreIdentifiers() { + return ignoreIdentifiers; + } + + public void setIgnoreIdentifiers(boolean ignoreIdentifiers) { + this.ignoreIdentifiers = ignoreIdentifiers; + } + + public boolean isIgnoreAnnotations() { + return ignoreAnnotations; + } + + public void setIgnoreAnnotations(boolean ignoreAnnotations) { + this.ignoreAnnotations = ignoreAnnotations; + } + + public List getFiles() { + return files; + } + + public void setFiles(List files) { + this.files = files; + } + + public boolean isHelp() { + return help; + } + + public void setHelp(boolean help) { + this.help = help; + } + + public String getEncoding() { + return encoding; + } } diff --git a/pmd/src/main/java/net/sourceforge/pmd/cpd/CPDTask.java b/pmd/src/main/java/net/sourceforge/pmd/cpd/CPDTask.java index cebcbaafac..59a623e8bc 100644 --- a/pmd/src/main/java/net/sourceforge/pmd/cpd/CPDTask.java +++ b/pmd/src/main/java/net/sourceforge/pmd/cpd/CPDTask.java @@ -57,9 +57,11 @@ public class CPDTask extends Task { log("Starting run, minimumTokenCount is " + minimumTokenCount, Project.MSG_INFO); log("Tokenizing files", Project.MSG_INFO); - CPDConfiguration config = new CPDConfiguration( - minimumTokenCount, createLanguage(), encoding - ); + CPDConfiguration config = new CPDConfiguration(); + config.setMinimumTileSize(minimumTokenCount); + config.setLanguage(createLanguage()); + config.setEncoding(encoding); + CPD cpd = new CPD(config); tokenizeFiles(cpd); diff --git a/pmd/src/main/java/net/sourceforge/pmd/cpd/GUI.java b/pmd/src/main/java/net/sourceforge/pmd/cpd/GUI.java index 40a9b83b04..fb7852fe55 100644 --- a/pmd/src/main/java/net/sourceforge/pmd/cpd/GUI.java +++ b/pmd/src/main/java/net/sourceforge/pmd/cpd/GUI.java @@ -71,14 +71,14 @@ public class GUI implements CPDListener { // private interface Renderer { // String render(Iterator items); // } - + private static final Object[][] RENDERER_SETS = new Object[][] { { "Text", new Renderer() { public String render(Iterator items) { return new SimpleRenderer().render(items); } } }, { "XML", new Renderer() { public String render(Iterator items) { return new XMLRenderer().render(items); } } }, { "CSV (comma)",new Renderer() { public String render(Iterator items) { return new CSVRenderer(',').render(items); } } }, { "CSV (tab)", new Renderer() { public String render(Iterator items) { return new CSVRenderer('\t').render(items); } } } }; - + private static abstract class LanguageConfig { public abstract Language languageFor(LanguageFactory lf, Properties p); public boolean canIgnoreIdentifiers() { return false; } @@ -86,21 +86,21 @@ public class GUI implements CPDListener { public boolean canIgnoreAnnotations() { return false; } public abstract String[] extensions(); }; - + private static final Object[][] LANGUAGE_SETS = new Object[][] { - {"Java", new LanguageConfig() { + {"Java", new LanguageConfig() { public Language languageFor(LanguageFactory lf, Properties p) { return lf.createLanguage("java"); } public boolean canIgnoreIdentifiers() { return true; } public boolean canIgnoreLiterals() { return true; } public boolean canIgnoreAnnotations() { return true; } public String[] extensions() { return new String[] {".java", ".class" }; }; } }, - {"JSP", new LanguageConfig() { + {"JSP", new LanguageConfig() { public Language languageFor(LanguageFactory lf, Properties p) { return lf.createLanguage("jsp"); } public String[] extensions() { return new String[] {".jsp" }; }; } }, - {"C++", new LanguageConfig() { + {"C++", new LanguageConfig() { public Language languageFor(LanguageFactory lf, Properties p) { return lf.createLanguage("cpp"); } public String[] extensions() { return new String[] {".cpp", ".c" }; }; } }, - {"Ruby", new LanguageConfig() { + {"Ruby", new LanguageConfig() { public Language languageFor(LanguageFactory lf, Properties p) { return lf.createLanguage("ruby"); } public String[] extensions() { return new String[] {".rb" }; }; } }, {"Fortran", new LanguageConfig() { @@ -109,25 +109,25 @@ public class GUI implements CPDListener { {"by extension...", new LanguageConfig() { public Language languageFor(LanguageFactory lf, Properties p) { return lf.createLanguage(LanguageFactory.BY_EXTENSION, p); } public String[] extensions() { return new String[] {"" }; }; } }, - {"PHP", new LanguageConfig() { + {"PHP", new LanguageConfig() { public Language languageFor(LanguageFactory lf, Properties p) { return lf.createLanguage("php"); } public String[] extensions() { return new String[] {".php" }; }; } }, {"C#", new LanguageConfig() { public Language languageFor(LanguageFactory lf, Properties p) { return lf.createLanguage("cs"); } public String[] extensions() { return new String[] {".cs" }; }; } }, }; - + private static final int DEFAULT_CPD_MINIMUM_LENGTH = 75; private static final Map LANGUAGE_CONFIGS_BY_LABEL = new HashMap(LANGUAGE_SETS.length); private static final KeyStroke COPY_KEY_STROKE = KeyStroke.getKeyStroke(KeyEvent.VK_C,ActionEvent.CTRL_MASK,false); private static final KeyStroke DELETE_KEY_STROKE = KeyStroke.getKeyStroke(KeyEvent.VK_DELETE, 0); - + private class ColumnSpec { private String label; private int alignment; private int width; private Comparator sorter; - + public ColumnSpec(String aLabel, int anAlignment, int aWidth, Comparator aSorter) { label = aLabel; alignment = anAlignment; @@ -145,17 +145,17 @@ public class GUI implements CPDListener { new ColumnSpec("Matches", SwingConstants.RIGHT, 60, Match.MATCHES_COMPARATOR), new ColumnSpec("Lines", SwingConstants.RIGHT, 45, Match.LINES_COMPARATOR), }; - - static { + + static { for (int i=0; i matches = new ArrayList(); private void addSaveOptionsTo(JMenu menu) { - + JMenuItem saveItem; - + for (int i=0; i 0) { sb.append('\n'); @@ -467,55 +467,55 @@ public class GUI implements CPDListener { sb.append(resultsTable.getValueAt(selectionIndices[r], c)); } } - + StringSelection ss = new StringSelection(sb.toString()); Toolkit.getDefaultToolkit().getSystemClipboard().setContents(ss, null); } - + private void deleteMatchlistSelections() { - + int[] selectionIndices = resultsTable.getSelectedRows(); - + for (int i=selectionIndices.length-1; i >=0; i--) { matches.remove(selectionIndices[i]); } - + resultsTable.getSelectionModel().clearSelection(); resultsTable.addNotify(); } - + private JComponent makeMatchList() { - + resultsTable.getSelectionModel().addListSelectionListener(new ListSelectionListener() { public void valueChanged(ListSelectionEvent e) { - populateResultArea(); + populateResultArea(); }}); - + resultsTable.registerKeyboardAction(new ActionListener() { - public void actionPerformed(ActionEvent e) { copyMatchListSelectionsToClipboard(); } + public void actionPerformed(ActionEvent e) { copyMatchListSelectionsToClipboard(); } },"Copy", COPY_KEY_STROKE, JComponent.WHEN_FOCUSED); - + resultsTable.registerKeyboardAction(new ActionListener() { - public void actionPerformed(ActionEvent e) { deleteMatchlistSelections(); } + public void actionPerformed(ActionEvent e) { deleteMatchlistSelections(); } },"Del", DELETE_KEY_STROKE, JComponent.WHEN_FOCUSED); - + int[] alignments = new int[matchColumns.length]; for (int i=0; i sourceIDs = new HashSet(match.getMarkCount()); for (Iterator occurrences = match.iterator(); occurrences.hasNext();) { sourceIDs.add(occurrences.next().getTokenSrcID()); } String label; - + if (sourceIDs.size() == 1) { String sourceId = sourceIDs.iterator().next(); int separatorPos = sourceId.lastIndexOf(File.separatorChar); @@ -541,17 +541,17 @@ public class GUI implements CPDListener { } else { label = "(" + sourceIDs.size() + " separate files)"; } - + match.setLabel(label); return label; } - + private void setProgressControls(boolean isRunning) { progressPanel.setVisible(isRunning); goButton.setEnabled(!isRunning); cancelButton.setEnabled(isRunning); } - + private void go() { String dirPath = rootDirectoryField.getText(); try { @@ -561,20 +561,23 @@ public class GUI implements CPDListener { "Error", JOptionPane.ERROR_MESSAGE); return; } - + setProgressControls(true); Properties p = new Properties(); - p.setProperty(JavaTokenizer.IGNORE_IDENTIFIERS, String.valueOf(ignoreIdentifiersCheckbox.isSelected())); - p.setProperty(JavaTokenizer.IGNORE_LITERALS, String.valueOf(ignoreLiteralsCheckbox.isSelected())); - p.setProperty(JavaTokenizer.IGNORE_ANNOTATIONS, String.valueOf(ignoreAnnotationsCheckbox.isSelected())); + CPDConfiguration config = new CPDConfiguration(); + config.setMinimumTileSize(Integer.parseInt(minimumLengthField.getText())); + config.setEncoding(encodingField.getText()); + config.setIgnoreIdentifiers(ignoreIdentifiersCheckbox.isSelected()); + config.setIgnoreLiterals(ignoreLiteralsCheckbox.isSelected()); + config.setIgnoreAnnotations(ignoreAnnotationsCheckbox.isSelected()); + CPDConfiguration.setSystemProperties(config); p.setProperty(LanguageFactory.EXTENSION, extensionField.getText()); + LanguageConfig conf = languageConfigFor((String)languageBox.getSelectedItem()); Language language = conf.languageFor(new LanguageFactory(), p); - CPDConfiguration config = new CPDConfiguration( - Integer.parseInt(minimumLengthField.getText()), - language, encodingField.getText() - ); + config.setLanguage(language); + CPD cpd = new CPD(config); cpd.setCpdListener(this); tokenizingFilesBar.setMinimum(0); @@ -592,7 +595,7 @@ public class GUI implements CPDListener { t.start(); cpd.go(); t.stop(); - + matches = new ArrayList(); Match match; for (Iterator i = cpd.getMatches(); i.hasNext();) { @@ -608,7 +611,7 @@ public class GUI implements CPDListener { } else { resultsTextArea.setText(report); setListDataFrom(cpd.getMatches()); - + } } catch (IOException t) { t.printStackTrace(); @@ -621,9 +624,9 @@ public class GUI implements CPDListener { } private Timer createTimer() { - + final long start = System.currentTimeMillis(); - + Timer t = new Timer(1000, new ActionListener() { public void actionPerformed(ActionEvent e) { long now = System.currentTimeMillis(); @@ -636,9 +639,9 @@ public class GUI implements CPDListener { }); return t; } - + private static String formatTime(long minutes, long seconds) { - + StringBuilder sb = new StringBuilder(5); if (minutes < 10) { sb.append('0'); } sb.append(minutes).append(':'); @@ -646,7 +649,7 @@ public class GUI implements CPDListener { sb.append(seconds); return sb.toString(); } - + private interface SortingTableModel extends TableModel { int sortColumn(); void sortColumn(int column); @@ -654,14 +657,14 @@ public class GUI implements CPDListener { void sortDescending(boolean flag); void sort(Comparator comparator); } - + private TableModel tableModelFrom(final List items) { - + TableModel model = new SortingTableModel() { - + private int sortColumn; private boolean sortDescending; - + public Object getValueAt(int rowIndex, int columnIndex) { Match match = items.get(rowIndex); switch (columnIndex) { @@ -684,17 +687,17 @@ public class GUI implements CPDListener { public void sortColumn(int column) { sortColumn = column; }; public boolean sortDescending() { return sortDescending; }; public void sortDescending(boolean flag) { sortDescending = flag; }; - public void sort(Comparator comparator) { + public void sort(Comparator comparator) { Collections.sort(items, comparator); if (sortDescending) { Collections.reverse(items); } } }; - + return model; - } - + } + private void sortOnColumn(int columnIndex) { Comparator comparator = matchColumns[columnIndex].sorter(); SortingTableModel model = (SortingTableModel)resultsTable.getModel(); @@ -703,19 +706,19 @@ public class GUI implements CPDListener { } model.sortColumn(columnIndex); model.sort(comparator); - - resultsTable.getSelectionModel().clearSelection(); + + resultsTable.getSelectionModel().clearSelection(); resultsTable.repaint(); } - + private void setListDataFrom(Iterator iter) { resultsTable.setModel(tableModelFrom(matches)); - + TableColumnModel colModel = resultsTable.getColumnModel(); TableColumn column; int width; - + for (int i=0; i 0) { column = colModel.getColumn(i); @@ -724,9 +727,9 @@ public class GUI implements CPDListener { column.setMinWidth(width); column.setMaxWidth(width); } - } + } } - + // CPDListener public void phaseUpdate(int phase) { phaseLabel.setText(getPhaseText(phase)); @@ -755,7 +758,7 @@ public class GUI implements CPDListener { } // CPDListener - + public static void main(String[] args) { //this should prevent the disk not found popup // System.setSecurityManager(null);