Refactor CPDGui to detect available languages dynamically

This commit is contained in:
Andreas Dangel
2014-10-12 10:43:53 +02:00
parent 694258d7df
commit 9ade75a621
19 changed files with 93 additions and 70 deletions

View File

@ -457,7 +457,7 @@ public class PMD {
*/ */
static { static {
String pmdVersion = null; 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) { if (stream != null) {
try { try {
Properties properties = new Properties(); Properties properties = new Properties();

View File

@ -119,8 +119,7 @@ public class PMDCommandLineInterface {
private static String supportedVersions() { private static String supportedVersions() {
return "Languages and version suported:" + PMD.EOL + return "Languages and version suported:" + PMD.EOL +
LanguageRegistry.commaSeparatedTerseNamesForLanguage(LanguageRegistry.findWithRuleSupport()) + PMD.EOL + LanguageRegistry.commaSeparatedTerseNamesForLanguage(LanguageRegistry.findWithRuleSupport()) + PMD.EOL;
"Note that some language are not supported by PMD - only by CPD" + PMD.EOL;
} }
/** /**

View File

@ -4,19 +4,25 @@
package net.sourceforge.pmd.cpd; package net.sourceforge.pmd.cpd;
import java.io.FilenameFilter; import java.io.FilenameFilter;
import java.util.Arrays;
import java.util.List;
import java.util.Properties; import java.util.Properties;
import net.sourceforge.pmd.util.filter.Filters; import net.sourceforge.pmd.util.filter.Filters;
public abstract class AbstractLanguage implements Language { public abstract class AbstractLanguage implements Language {
private final String name; private final String name;
private final String terseName;
private final Tokenizer tokenizer; private final Tokenizer tokenizer;
private final FilenameFilter fileFilter; private final FilenameFilter fileFilter;
private final List<String> extensions;
public AbstractLanguage(String name, Tokenizer tokenizer, String... extensions) { public AbstractLanguage(String name, String terseName, Tokenizer tokenizer, String... extensions) {
this.name = name; this.name = name;
this.terseName = terseName;
this.tokenizer = tokenizer; this.tokenizer = tokenizer;
fileFilter = Filters.toFilenameFilter(Filters.getFileExtensionOrDirectoryFilter(extensions)); fileFilter = Filters.toFilenameFilter(Filters.getFileExtensionOrDirectoryFilter(extensions));
this.extensions = Arrays.asList(extensions);
} }
public FilenameFilter getFileFilter() { public FilenameFilter getFileFilter() {
@ -34,4 +40,12 @@ public abstract class AbstractLanguage implements Language {
public String getName() { public String getName() {
return name; return name;
} }
public String getTerseName() {
return terseName;
}
public List<String> getExtensions() {
return extensions;
}
} }

View File

@ -4,7 +4,7 @@
package net.sourceforge.pmd.cpd; package net.sourceforge.pmd.cpd;
public class AnyLanguage extends AbstractLanguage { public class AnyLanguage extends AbstractLanguage {
public AnyLanguage(String... extension) { public AnyLanguage(String... extensions) {
super("any", new AnyTokenizer(), extension); super("Any Language", "any", new AnyTokenizer(), extensions);
} }
} }

View File

@ -4,13 +4,15 @@
package net.sourceforge.pmd.cpd; package net.sourceforge.pmd.cpd;
import java.io.IOException; import java.io.IOException;
import java.net.URISyntaxException;
import java.util.Arrays;
import java.util.List; 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.JCommander;
import com.beust.jcommander.ParameterException; import com.beust.jcommander.ParameterException;
import java.net.URISyntaxException;
import java.util.logging.Logger;
import net.sourceforge.pmd.util.database.DBURI;
public class CPDCommandLineInterface { public class CPDCommandLineInterface {
private final static Logger LOGGER = Logger.getLogger(CPDCommandLineInterface.class.getName()); private final static Logger LOGGER = Logger.getLogger(CPDCommandLineInterface.class.getName());
@ -135,6 +137,9 @@ public class CPDCommandLineInterface {
helpText += "or: " + 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; 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; return helpText;
} }

View File

@ -86,51 +86,55 @@ public class GUI implements CPDListener {
public boolean canIgnoreLiterals() { return false; } public boolean canIgnoreLiterals() { return false; }
public boolean canIgnoreAnnotations() { return false; } public boolean canIgnoreAnnotations() { return false; }
public abstract String[] extensions(); public abstract String[] extensions();
}; }
private static final Object[][] LANGUAGE_SETS = new Object[][] { private static final Object[][] LANGUAGE_SETS;
{"Java", new LanguageConfig() {
public Language languageFor(Properties p) { return LanguageFactory.createLanguage("java", p); } static {
public boolean canIgnoreIdentifiers() { return true; } LANGUAGE_SETS = new Object[LanguageFactory.supportedLanguages.length + 1][2];
public boolean canIgnoreLiterals() { return true; }
public boolean canIgnoreAnnotations() { return true; } int index;
public String[] extensions() { return new String[] {".java", ".class" }; }; } }, for (index = 0; index < LanguageFactory.supportedLanguages.length; index++) {
{"JSP", new LanguageConfig() { final String terseName = LanguageFactory.supportedLanguages[index];
public Language languageFor(Properties p) { return LanguageFactory.createLanguage("jsp", p); } final Language lang = LanguageFactory.createLanguage(terseName);
public String[] extensions() { return new String[] {".jsp" }; }; } }, LANGUAGE_SETS[index][0] = lang.getName();
{"C++", new LanguageConfig() { LANGUAGE_SETS[index][1] = new LanguageConfig() {
public Language languageFor(Properties p) { return LanguageFactory.createLanguage("cpp", p); } @Override
public String[] extensions() { return new String[] {".cpp", ".c" }; }; } }, public Language languageFor(Properties p) {
{"Ruby", new LanguageConfig() { lang.setProperties(p);
public Language languageFor(Properties p) { return LanguageFactory.createLanguage("ruby", p); } return lang;
public String[] extensions() { return new String[] {".rb" }; }; } }, }
{"Fortran", new LanguageConfig() { @Override
public Language languageFor(Properties p) { return LanguageFactory.createLanguage("fortran", p); } public String[] extensions() {
public String[] extensions() { return new String[] {".for", ".f", ".f66", ".f77", ".f90" }; }; } }, List<String> exts = lang.getExtensions();
{"PHP", new LanguageConfig() { return exts.toArray(new String[exts.size()]);
public Language languageFor(Properties p) { return LanguageFactory.createLanguage("php", p); } }
public String[] extensions() { return new String[] {".php" }; }; } }, @Override
{"C#", new LanguageConfig() { public boolean canIgnoreAnnotations() {
public Language languageFor(Properties p) { return LanguageFactory.createLanguage("cs", p); } return "java".equals(terseName);
public String[] extensions() { return new String[] {".cs" }; }; } }, }
{"PLSQL", new LanguageConfig() { @Override
public Language languageFor(Properties p) { return LanguageFactory.createLanguage("plsql", p); } public boolean canIgnoreIdentifiers() {
public String[] extensions() { return new String[] {".sql" return "java".equals(terseName);
,".trg" }
,".prc",".fnc" @Override
,".pld" public boolean canIgnoreLiterals() {
,".pls",".plh",".plb" return "java".equals(terseName);
,".pck",".pks",".pkh",".pkb" }
,".typ",".tyb" };
,".tps",".tpb" }
}; }; } }, LANGUAGE_SETS[index][0] = "by extension...";
{"Ecmascript", new LanguageConfig() { LANGUAGE_SETS[index][1] = new LanguageConfig() {
public Language languageFor(Properties p) { return LanguageFactory.createLanguage("js", p); } @Override
public String[] extensions() { return new String[] {".js" }; }; } }, public Language languageFor(Properties p) {
{"by extension...", new LanguageConfig() { return LanguageFactory.createLanguage(LanguageFactory.BY_EXTENSION, p);
public Language languageFor(Properties p) { return LanguageFactory.createLanguage(LanguageFactory.BY_EXTENSION, p); } }
public String[] extensions() { return new String[] {"" }; }; } }, @Override
}; public String[] extensions() {
return new String[] {"" };
}
};
}
private static final int DEFAULT_CPD_MINIMUM_LENGTH = 75; private static final int DEFAULT_CPD_MINIMUM_LENGTH = 75;
private static final Map<String, LanguageConfig> LANGUAGE_CONFIGS_BY_LABEL = new HashMap<String, LanguageConfig>(LANGUAGE_SETS.length); private static final Map<String, LanguageConfig> LANGUAGE_CONFIGS_BY_LABEL = new HashMap<String, LanguageConfig>(LANGUAGE_SETS.length);

View File

@ -4,14 +4,19 @@
package net.sourceforge.pmd.cpd; package net.sourceforge.pmd.cpd;
import java.io.FilenameFilter; import java.io.FilenameFilter;
import java.util.List;
import java.util.Properties; import java.util.Properties;
public interface Language { public interface Language {
String getName(); String getName();
String getTerseName();
Tokenizer getTokenizer(); Tokenizer getTokenizer();
FilenameFilter getFileFilter(); FilenameFilter getFileFilter();
void setProperties(Properties properties); void setProperties(Properties properties);
List<String> getExtensions();
} }

View File

@ -3,7 +3,6 @@
*/ */
package net.sourceforge.pmd.cpd; package net.sourceforge.pmd.cpd;
import java.io.File;
import java.util.HashMap; import java.util.HashMap;
import java.util.Map; import java.util.Map;
import java.util.Properties; import java.util.Properties;
@ -26,7 +25,7 @@ public class LanguageFactory {
private LanguageFactory() { private LanguageFactory() {
ServiceLoader<Language> languageLoader = ServiceLoader.load(Language.class); ServiceLoader<Language> languageLoader = ServiceLoader.load(Language.class);
for (Language language : languageLoader) { 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) { private Language getLanguageByExtension(String extension) {
Language result = null; Language result = null;
File dir = new File(".");
String filename = "file." + extension;
for (Language language : languages.values()) { for (Language language : languages.values()) {
if (language.getFileFilter().accept(dir, filename)) { if (language.getExtensions().contains(extension)) {
result = language; result = language;
break; break;
} }

View File

@ -968,8 +968,7 @@ public class Designer implements ClipboardOwner {
String xpathVersion = xpathElement.getAttribute("version"); String xpathVersion = xpathElement.getAttribute("version");
codeEditorPane.setText(code); codeEditorPane.setText(code);
// TODO: Fix this. setLanguageVersion(LanguageRegistry.findLanguageVersionByTerseName(languageVersion));
// setLanguageVersion(LanguageRegistry.findByTerseName(languageVersion));
xpathQueryArea.setText(xpath); xpathQueryArea.setText(xpath);
for (Enumeration<AbstractButton> e = xpathVersionButtonGroup.getElements(); e.hasMoreElements();) { for (Enumeration<AbstractButton> e = xpathVersionButtonGroup.getElements(); e.hasMoreElements();) {
AbstractButton button = e.nextElement(); AbstractButton button = e.nextElement();

View File

@ -10,6 +10,6 @@ package net.sourceforge.pmd.cpd;
public class CpddummyLanguage extends AbstractLanguage { public class CpddummyLanguage extends AbstractLanguage {
public CpddummyLanguage() { public CpddummyLanguage() {
super("Cpddummy", new AnyTokenizer(), "dummy"); super("CPD Dummy Language used in tests", "Cpddummy", new AnyTokenizer(), "dummy");
} }
} }

View File

@ -5,6 +5,6 @@ package net.sourceforge.pmd.cpd;
public class CPPLanguage extends AbstractLanguage { public class CPPLanguage extends AbstractLanguage {
public CPPLanguage() { 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");
} }
} }

View File

@ -5,6 +5,6 @@ package net.sourceforge.pmd.cpd;
public class CsLanguage extends AbstractLanguage { public class CsLanguage extends AbstractLanguage {
public CsLanguage() { public CsLanguage() {
super("cs", new CsTokenizer(), ".cs"); super("C#", "cs", new CsTokenizer(), ".cs");
} }
} }

View File

@ -9,6 +9,6 @@ package net.sourceforge.pmd.cpd;
*/ */
public class FortranLanguage extends AbstractLanguage { public class FortranLanguage extends AbstractLanguage {
public FortranLanguage() { public FortranLanguage() {
super("fortran", new FortranTokenizer(), ".for", ".f", ".f66", ".f77", ".f90"); super("Fortran", "fortran", new FortranTokenizer(), ".for", ".f", ".f66", ".f77", ".f90");
} }
} }

View File

@ -11,7 +11,7 @@ public class JavaLanguage extends AbstractLanguage {
} }
public JavaLanguage(Properties properties) { public JavaLanguage(Properties properties) {
super("java", new JavaTokenizer(), ".java"); super("Java", "java", new JavaTokenizer(), ".java");
setProperties(properties); setProperties(properties);
} }

View File

@ -9,6 +9,6 @@ package net.sourceforge.pmd.cpd;
*/ */
public class EcmascriptLanguage extends AbstractLanguage { public class EcmascriptLanguage extends AbstractLanguage {
public EcmascriptLanguage() { public EcmascriptLanguage() {
super("ecmascript", new EcmascriptTokenizer(), ".js"); super("JavaScript", "ecmascript", new EcmascriptTokenizer(), ".js");
} }
} }

View File

@ -5,6 +5,6 @@ package net.sourceforge.pmd.cpd;
public class JSPLanguage extends AbstractLanguage { public class JSPLanguage extends AbstractLanguage {
public JSPLanguage() { public JSPLanguage() {
super("jsp", new JSPTokenizer(), ".jsp", ".jspx"); super("JSP", "jsp", new JSPTokenizer(), ".jsp", ".jspx");
} }
} }

View File

@ -5,6 +5,6 @@ package net.sourceforge.pmd.cpd;
public class PHPLanguage extends AbstractLanguage { public class PHPLanguage extends AbstractLanguage {
public PHPLanguage() { public PHPLanguage() {
super("php", new PHPTokenizer(), ".php", ".class"); super("PHP", "php", new PHPTokenizer(), ".php", ".class");
} }
} }

View File

@ -11,7 +11,7 @@ import java.util.Properties;
*/ */
public class PLSQLLanguage extends AbstractLanguage { public class PLSQLLanguage extends AbstractLanguage {
public PLSQLLanguage() { public PLSQLLanguage() {
super("plsql", new PLSQLTokenizer() super("PL/SQL", "plsql", new PLSQLTokenizer()
,".sql" ,".sql"
,".trg" //Triggers ,".trg" //Triggers
,".prc",".fnc" // Standalone Procedures and Functions ,".prc",".fnc" // Standalone Procedures and Functions

View File

@ -9,6 +9,6 @@ package net.sourceforge.pmd.cpd;
*/ */
public class RubyLanguage extends AbstractLanguage { public class RubyLanguage extends AbstractLanguage {
public RubyLanguage() { public RubyLanguage() {
super("ruby", new RubyTokenizer(), ".rb", ".cgi", ".class"); super("Ruby", "ruby", new RubyTokenizer(), ".rb", ".cgi", ".class");
} }
} }