From 9ade75a621f58c22e6aa2eeb71419c7901d1076d Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Sun, 12 Oct 2014 10:43:53 +0200 Subject: [PATCH] Refactor CPDGui to detect available languages dynamically --- .../main/java/net/sourceforge/pmd/PMD.java | 2 +- .../pmd/cli/PMDCommandLineInterface.java | 3 +- .../sourceforge/pmd/cpd/AbstractLanguage.java | 16 +++- .../net/sourceforge/pmd/cpd/AnyLanguage.java | 4 +- .../pmd/cpd/CPDCommandLineInterface.java | 11 ++- .../java/net/sourceforge/pmd/cpd/GUI.java | 92 ++++++++++--------- .../net/sourceforge/pmd/cpd/Language.java | 5 + .../sourceforge/pmd/cpd/LanguageFactory.java | 7 +- .../pmd/util/designer/Designer.java | 3 +- .../sourceforge/pmd/cpd/CpddummyLanguage.java | 2 +- .../net/sourceforge/pmd/cpd/CPPLanguage.java | 2 +- .../net/sourceforge/pmd/cpd/CsLanguage.java | 2 +- .../sourceforge/pmd/cpd/FortranLanguage.java | 2 +- .../net/sourceforge/pmd/cpd/JavaLanguage.java | 2 +- .../pmd/cpd/EcmascriptLanguage.java | 2 +- .../net/sourceforge/pmd/cpd/JSPLanguage.java | 2 +- .../net/sourceforge/pmd/cpd/PHPLanguage.java | 2 +- .../sourceforge/pmd/cpd/PLSQLLanguage.java | 2 +- .../net/sourceforge/pmd/cpd/RubyLanguage.java | 2 +- 19 files changed, 93 insertions(+), 70 deletions(-) diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/PMD.java b/pmd-core/src/main/java/net/sourceforge/pmd/PMD.java index 78ee467f41..f9db1cea55 100644 --- a/pmd-core/src/main/java/net/sourceforge/pmd/PMD.java +++ b/pmd-core/src/main/java/net/sourceforge/pmd/PMD.java @@ -457,7 +457,7 @@ public class PMD { */ static { String pmdVersion = null; - InputStream stream = PMD.class.getResourceAsStream("/META-INF/maven/net.sourceforge.pmd/pmd/pom.properties"); + InputStream stream = PMD.class.getResourceAsStream("/META-INF/maven/net.sourceforge.pmd/pmd-core/pom.properties"); if (stream != null) { try { Properties properties = new Properties(); diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/cli/PMDCommandLineInterface.java b/pmd-core/src/main/java/net/sourceforge/pmd/cli/PMDCommandLineInterface.java index ab53c5d980..ed1ab3f7e2 100644 --- a/pmd-core/src/main/java/net/sourceforge/pmd/cli/PMDCommandLineInterface.java +++ b/pmd-core/src/main/java/net/sourceforge/pmd/cli/PMDCommandLineInterface.java @@ -119,8 +119,7 @@ public class PMDCommandLineInterface { private static String supportedVersions() { return "Languages and version suported:" + PMD.EOL + - LanguageRegistry.commaSeparatedTerseNamesForLanguage(LanguageRegistry.findWithRuleSupport()) + PMD.EOL + - "Note that some language are not supported by PMD - only by CPD" + PMD.EOL; + LanguageRegistry.commaSeparatedTerseNamesForLanguage(LanguageRegistry.findWithRuleSupport()) + PMD.EOL; } /** diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/cpd/AbstractLanguage.java b/pmd-core/src/main/java/net/sourceforge/pmd/cpd/AbstractLanguage.java index 0bddb4d8d0..07d161f254 100644 --- a/pmd-core/src/main/java/net/sourceforge/pmd/cpd/AbstractLanguage.java +++ b/pmd-core/src/main/java/net/sourceforge/pmd/cpd/AbstractLanguage.java @@ -4,19 +4,25 @@ package net.sourceforge.pmd.cpd; import java.io.FilenameFilter; +import java.util.Arrays; +import java.util.List; import java.util.Properties; import net.sourceforge.pmd.util.filter.Filters; public abstract class AbstractLanguage implements Language { private final String name; + private final String terseName; private final Tokenizer tokenizer; private final FilenameFilter fileFilter; + private final List extensions; - public AbstractLanguage(String name, Tokenizer tokenizer, String... extensions) { + public AbstractLanguage(String name, String terseName, Tokenizer tokenizer, String... extensions) { this.name = name; + this.terseName = terseName; this.tokenizer = tokenizer; fileFilter = Filters.toFilenameFilter(Filters.getFileExtensionOrDirectoryFilter(extensions)); + this.extensions = Arrays.asList(extensions); } public FilenameFilter getFileFilter() { @@ -34,4 +40,12 @@ public abstract class AbstractLanguage implements Language { public String getName() { return name; } + + public String getTerseName() { + return terseName; + } + + public List getExtensions() { + return extensions; + } } diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/cpd/AnyLanguage.java b/pmd-core/src/main/java/net/sourceforge/pmd/cpd/AnyLanguage.java index 2b73080b44..addc51b283 100644 --- a/pmd-core/src/main/java/net/sourceforge/pmd/cpd/AnyLanguage.java +++ b/pmd-core/src/main/java/net/sourceforge/pmd/cpd/AnyLanguage.java @@ -4,7 +4,7 @@ package net.sourceforge.pmd.cpd; public class AnyLanguage extends AbstractLanguage { - public AnyLanguage(String... extension) { - super("any", new AnyTokenizer(), extension); + public AnyLanguage(String... extensions) { + super("Any Language", "any", new AnyTokenizer(), extensions); } } diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/cpd/CPDCommandLineInterface.java b/pmd-core/src/main/java/net/sourceforge/pmd/cpd/CPDCommandLineInterface.java index c8c2aa9313..50854db38d 100644 --- a/pmd-core/src/main/java/net/sourceforge/pmd/cpd/CPDCommandLineInterface.java +++ b/pmd-core/src/main/java/net/sourceforge/pmd/cpd/CPDCommandLineInterface.java @@ -4,13 +4,15 @@ package net.sourceforge.pmd.cpd; import java.io.IOException; +import java.net.URISyntaxException; +import java.util.Arrays; import java.util.List; +import java.util.logging.Logger; + +import net.sourceforge.pmd.util.database.DBURI; import com.beust.jcommander.JCommander; import com.beust.jcommander.ParameterException; -import java.net.URISyntaxException; -import java.util.logging.Logger; -import net.sourceforge.pmd.util.database.DBURI; public class CPDCommandLineInterface { private final static Logger LOGGER = Logger.getLogger(CPDCommandLineInterface.class.getName()); @@ -135,6 +137,9 @@ public class CPDCommandLineInterface { helpText += "or: " + EOL; helpText += " java net.sourceforge.pmd.cpd.CPD --minimum-tokens 100 --encoding UTF-16LE --files /path/to/java/code --format xml" + EOL; + helpText += EOL; + + helpText += EOL + " Supported languages: " + Arrays.toString(LanguageFactory.supportedLanguages) + EOL; return helpText; } diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/cpd/GUI.java b/pmd-core/src/main/java/net/sourceforge/pmd/cpd/GUI.java index 9fad19ba35..eaef527a97 100644 --- a/pmd-core/src/main/java/net/sourceforge/pmd/cpd/GUI.java +++ b/pmd-core/src/main/java/net/sourceforge/pmd/cpd/GUI.java @@ -86,51 +86,55 @@ public class GUI implements CPDListener { public boolean canIgnoreLiterals() { return false; } public boolean canIgnoreAnnotations() { return false; } public abstract String[] extensions(); - }; + } - private static final Object[][] LANGUAGE_SETS = new Object[][] { - {"Java", new LanguageConfig() { - public Language languageFor(Properties p) { return LanguageFactory.createLanguage("java", p); } - 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() { - public Language languageFor(Properties p) { return LanguageFactory.createLanguage("jsp", p); } - public String[] extensions() { return new String[] {".jsp" }; }; } }, - {"C++", new LanguageConfig() { - public Language languageFor(Properties p) { return LanguageFactory.createLanguage("cpp", p); } - public String[] extensions() { return new String[] {".cpp", ".c" }; }; } }, - {"Ruby", new LanguageConfig() { - public Language languageFor(Properties p) { return LanguageFactory.createLanguage("ruby", p); } - public String[] extensions() { return new String[] {".rb" }; }; } }, - {"Fortran", new LanguageConfig() { - public Language languageFor(Properties p) { return LanguageFactory.createLanguage("fortran", p); } - public String[] extensions() { return new String[] {".for", ".f", ".f66", ".f77", ".f90" }; }; } }, - {"PHP", new LanguageConfig() { - public Language languageFor(Properties p) { return LanguageFactory.createLanguage("php", p); } - public String[] extensions() { return new String[] {".php" }; }; } }, - {"C#", new LanguageConfig() { - public Language languageFor(Properties p) { return LanguageFactory.createLanguage("cs", p); } - public String[] extensions() { return new String[] {".cs" }; }; } }, - {"PLSQL", new LanguageConfig() { - public Language languageFor(Properties p) { return LanguageFactory.createLanguage("plsql", p); } - public String[] extensions() { return new String[] {".sql" - ,".trg" - ,".prc",".fnc" - ,".pld" - ,".pls",".plh",".plb" - ,".pck",".pks",".pkh",".pkb" - ,".typ",".tyb" - ,".tps",".tpb" - }; }; } }, - {"Ecmascript", new LanguageConfig() { - public Language languageFor(Properties p) { return LanguageFactory.createLanguage("js", p); } - public String[] extensions() { return new String[] {".js" }; }; } }, - {"by extension...", new LanguageConfig() { - public Language languageFor(Properties p) { return LanguageFactory.createLanguage(LanguageFactory.BY_EXTENSION, p); } - public String[] extensions() { return new String[] {"" }; }; } }, - }; + private static final Object[][] LANGUAGE_SETS; + + static { + LANGUAGE_SETS = new Object[LanguageFactory.supportedLanguages.length + 1][2]; + + int index; + for (index = 0; index < LanguageFactory.supportedLanguages.length; index++) { + final String terseName = LanguageFactory.supportedLanguages[index]; + final Language lang = LanguageFactory.createLanguage(terseName); + LANGUAGE_SETS[index][0] = lang.getName(); + LANGUAGE_SETS[index][1] = new LanguageConfig() { + @Override + public Language languageFor(Properties p) { + lang.setProperties(p); + return lang; + } + @Override + public String[] extensions() { + List exts = lang.getExtensions(); + return exts.toArray(new String[exts.size()]); + } + @Override + public boolean canIgnoreAnnotations() { + return "java".equals(terseName); + } + @Override + public boolean canIgnoreIdentifiers() { + return "java".equals(terseName); + } + @Override + public boolean canIgnoreLiterals() { + return "java".equals(terseName); + } + }; + } + LANGUAGE_SETS[index][0] = "by extension..."; + LANGUAGE_SETS[index][1] = new LanguageConfig() { + @Override + public Language languageFor(Properties p) { + return LanguageFactory.createLanguage(LanguageFactory.BY_EXTENSION, p); + } + @Override + public String[] extensions() { + return new String[] {"" }; + } + }; + } private static final int DEFAULT_CPD_MINIMUM_LENGTH = 75; private static final Map LANGUAGE_CONFIGS_BY_LABEL = new HashMap(LANGUAGE_SETS.length); diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/cpd/Language.java b/pmd-core/src/main/java/net/sourceforge/pmd/cpd/Language.java index fc449592b6..917c88270a 100644 --- a/pmd-core/src/main/java/net/sourceforge/pmd/cpd/Language.java +++ b/pmd-core/src/main/java/net/sourceforge/pmd/cpd/Language.java @@ -4,14 +4,19 @@ package net.sourceforge.pmd.cpd; import java.io.FilenameFilter; +import java.util.List; import java.util.Properties; public interface Language { String getName(); + String getTerseName(); + Tokenizer getTokenizer(); FilenameFilter getFileFilter(); void setProperties(Properties properties); + + List getExtensions(); } diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/cpd/LanguageFactory.java b/pmd-core/src/main/java/net/sourceforge/pmd/cpd/LanguageFactory.java index 8cf89f4c5d..a930e53f86 100644 --- a/pmd-core/src/main/java/net/sourceforge/pmd/cpd/LanguageFactory.java +++ b/pmd-core/src/main/java/net/sourceforge/pmd/cpd/LanguageFactory.java @@ -3,7 +3,6 @@ */ package net.sourceforge.pmd.cpd; -import java.io.File; import java.util.HashMap; import java.util.Map; import java.util.Properties; @@ -26,7 +25,7 @@ public class LanguageFactory { private LanguageFactory() { ServiceLoader languageLoader = ServiceLoader.load(Language.class); for (Language language : languageLoader) { - languages.put(language.getName().toLowerCase(), language); + languages.put(language.getTerseName().toLowerCase(), language); } } @@ -62,11 +61,9 @@ public class LanguageFactory { private Language getLanguageByExtension(String extension) { Language result = null; - File dir = new File("."); - String filename = "file." + extension; for (Language language : languages.values()) { - if (language.getFileFilter().accept(dir, filename)) { + if (language.getExtensions().contains(extension)) { result = language; break; } diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/util/designer/Designer.java b/pmd-core/src/main/java/net/sourceforge/pmd/util/designer/Designer.java index c4ec4152db..b6732a2f93 100644 --- a/pmd-core/src/main/java/net/sourceforge/pmd/util/designer/Designer.java +++ b/pmd-core/src/main/java/net/sourceforge/pmd/util/designer/Designer.java @@ -968,8 +968,7 @@ public class Designer implements ClipboardOwner { String xpathVersion = xpathElement.getAttribute("version"); codeEditorPane.setText(code); -// TODO: Fix this. -// setLanguageVersion(LanguageRegistry.findByTerseName(languageVersion)); + setLanguageVersion(LanguageRegistry.findLanguageVersionByTerseName(languageVersion)); xpathQueryArea.setText(xpath); for (Enumeration e = xpathVersionButtonGroup.getElements(); e.hasMoreElements();) { AbstractButton button = e.nextElement(); diff --git a/pmd-core/src/test/java/net/sourceforge/pmd/cpd/CpddummyLanguage.java b/pmd-core/src/test/java/net/sourceforge/pmd/cpd/CpddummyLanguage.java index 8c42a4bab2..0a8e985e7d 100644 --- a/pmd-core/src/test/java/net/sourceforge/pmd/cpd/CpddummyLanguage.java +++ b/pmd-core/src/test/java/net/sourceforge/pmd/cpd/CpddummyLanguage.java @@ -10,6 +10,6 @@ package net.sourceforge.pmd.cpd; public class CpddummyLanguage extends AbstractLanguage { public CpddummyLanguage() { - super("Cpddummy", new AnyTokenizer(), "dummy"); + super("CPD Dummy Language used in tests", "Cpddummy", new AnyTokenizer(), "dummy"); } } diff --git a/pmd-cpp/src/main/java/net/sourceforge/pmd/cpd/CPPLanguage.java b/pmd-cpp/src/main/java/net/sourceforge/pmd/cpd/CPPLanguage.java index bed4336d55..a997ed2bf5 100644 --- a/pmd-cpp/src/main/java/net/sourceforge/pmd/cpd/CPPLanguage.java +++ b/pmd-cpp/src/main/java/net/sourceforge/pmd/cpd/CPPLanguage.java @@ -5,6 +5,6 @@ package net.sourceforge.pmd.cpd; public class CPPLanguage extends AbstractLanguage { public CPPLanguage() { - super("cpp", new CPPTokenizer(), ".h", ".hpp", ".hxx",".c", ".cpp", ".cxx", ".cc", ".C"); + super("C++", "cpp", new CPPTokenizer(), ".h", ".hpp", ".hxx",".c", ".cpp", ".cxx", ".cc", ".C"); } } diff --git a/pmd-cs/src/main/java/net/sourceforge/pmd/cpd/CsLanguage.java b/pmd-cs/src/main/java/net/sourceforge/pmd/cpd/CsLanguage.java index 60554b6089..549324dc73 100644 --- a/pmd-cs/src/main/java/net/sourceforge/pmd/cpd/CsLanguage.java +++ b/pmd-cs/src/main/java/net/sourceforge/pmd/cpd/CsLanguage.java @@ -5,6 +5,6 @@ package net.sourceforge.pmd.cpd; public class CsLanguage extends AbstractLanguage { public CsLanguage() { - super("cs", new CsTokenizer(), ".cs"); + super("C#", "cs", new CsTokenizer(), ".cs"); } } diff --git a/pmd-fortran/src/main/java/net/sourceforge/pmd/cpd/FortranLanguage.java b/pmd-fortran/src/main/java/net/sourceforge/pmd/cpd/FortranLanguage.java index b142cfde0b..3e02053648 100644 --- a/pmd-fortran/src/main/java/net/sourceforge/pmd/cpd/FortranLanguage.java +++ b/pmd-fortran/src/main/java/net/sourceforge/pmd/cpd/FortranLanguage.java @@ -9,6 +9,6 @@ package net.sourceforge.pmd.cpd; */ public class FortranLanguage extends AbstractLanguage { public FortranLanguage() { - super("fortran", new FortranTokenizer(), ".for", ".f", ".f66", ".f77", ".f90"); + super("Fortran", "fortran", new FortranTokenizer(), ".for", ".f", ".f66", ".f77", ".f90"); } } diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/cpd/JavaLanguage.java b/pmd-java/src/main/java/net/sourceforge/pmd/cpd/JavaLanguage.java index 06780b3f86..49e99d963b 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/cpd/JavaLanguage.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/cpd/JavaLanguage.java @@ -11,7 +11,7 @@ public class JavaLanguage extends AbstractLanguage { } public JavaLanguage(Properties properties) { - super("java", new JavaTokenizer(), ".java"); + super("Java", "java", new JavaTokenizer(), ".java"); setProperties(properties); } diff --git a/pmd-javascript/src/main/java/net/sourceforge/pmd/cpd/EcmascriptLanguage.java b/pmd-javascript/src/main/java/net/sourceforge/pmd/cpd/EcmascriptLanguage.java index 3890606e4a..c0bc21f9ac 100644 --- a/pmd-javascript/src/main/java/net/sourceforge/pmd/cpd/EcmascriptLanguage.java +++ b/pmd-javascript/src/main/java/net/sourceforge/pmd/cpd/EcmascriptLanguage.java @@ -9,6 +9,6 @@ package net.sourceforge.pmd.cpd; */ public class EcmascriptLanguage extends AbstractLanguage { public EcmascriptLanguage() { - super("ecmascript", new EcmascriptTokenizer(), ".js"); + super("JavaScript", "ecmascript", new EcmascriptTokenizer(), ".js"); } } diff --git a/pmd-jsp/src/main/java/net/sourceforge/pmd/cpd/JSPLanguage.java b/pmd-jsp/src/main/java/net/sourceforge/pmd/cpd/JSPLanguage.java index 872fa7d633..65ed20b772 100644 --- a/pmd-jsp/src/main/java/net/sourceforge/pmd/cpd/JSPLanguage.java +++ b/pmd-jsp/src/main/java/net/sourceforge/pmd/cpd/JSPLanguage.java @@ -5,6 +5,6 @@ package net.sourceforge.pmd.cpd; public class JSPLanguage extends AbstractLanguage { public JSPLanguage() { - super("jsp", new JSPTokenizer(), ".jsp", ".jspx"); + super("JSP", "jsp", new JSPTokenizer(), ".jsp", ".jspx"); } } diff --git a/pmd-php/src/main/java/net/sourceforge/pmd/cpd/PHPLanguage.java b/pmd-php/src/main/java/net/sourceforge/pmd/cpd/PHPLanguage.java index 6e625aab94..aaf40e87dd 100644 --- a/pmd-php/src/main/java/net/sourceforge/pmd/cpd/PHPLanguage.java +++ b/pmd-php/src/main/java/net/sourceforge/pmd/cpd/PHPLanguage.java @@ -5,6 +5,6 @@ package net.sourceforge.pmd.cpd; public class PHPLanguage extends AbstractLanguage { public PHPLanguage() { - super("php", new PHPTokenizer(), ".php", ".class"); + super("PHP", "php", new PHPTokenizer(), ".php", ".class"); } } diff --git a/pmd-plsql/src/main/java/net/sourceforge/pmd/cpd/PLSQLLanguage.java b/pmd-plsql/src/main/java/net/sourceforge/pmd/cpd/PLSQLLanguage.java index df1b5af84b..43a70139b0 100755 --- a/pmd-plsql/src/main/java/net/sourceforge/pmd/cpd/PLSQLLanguage.java +++ b/pmd-plsql/src/main/java/net/sourceforge/pmd/cpd/PLSQLLanguage.java @@ -11,7 +11,7 @@ import java.util.Properties; */ public class PLSQLLanguage extends AbstractLanguage { public PLSQLLanguage() { - super("plsql", new PLSQLTokenizer() + super("PL/SQL", "plsql", new PLSQLTokenizer() ,".sql" ,".trg" //Triggers ,".prc",".fnc" // Standalone Procedures and Functions diff --git a/pmd-ruby/src/main/java/net/sourceforge/pmd/cpd/RubyLanguage.java b/pmd-ruby/src/main/java/net/sourceforge/pmd/cpd/RubyLanguage.java index 106993a673..d5e643891e 100644 --- a/pmd-ruby/src/main/java/net/sourceforge/pmd/cpd/RubyLanguage.java +++ b/pmd-ruby/src/main/java/net/sourceforge/pmd/cpd/RubyLanguage.java @@ -9,6 +9,6 @@ package net.sourceforge.pmd.cpd; */ public class RubyLanguage extends AbstractLanguage { public RubyLanguage() { - super("ruby", new RubyTokenizer(), ".rb", ".cgi", ".class"); + super("Ruby", "ruby", new RubyTokenizer(), ".rb", ".cgi", ".class"); } }