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 {
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();

View File

@ -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;
}
/**

View File

@ -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<String> 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<String> getExtensions() {
return extensions;
}
}

View File

@ -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);
}
}

View File

@ -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;
}

View File

@ -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<String> 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<String, LanguageConfig> LANGUAGE_CONFIGS_BY_LABEL = new HashMap<String, LanguageConfig>(LANGUAGE_SETS.length);

View File

@ -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<String> getExtensions();
}

View File

@ -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<Language> 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;
}

View File

@ -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<AbstractButton> e = xpathVersionButtonGroup.getElements(); e.hasMoreElements();) {
AbstractButton button = e.nextElement();

View File

@ -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");
}
}

View File

@ -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");
}
}

View File

@ -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");
}
}

View File

@ -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");
}
}

View File

@ -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);
}

View File

@ -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");
}
}

View File

@ -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");
}
}

View File

@ -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");
}
}

View File

@ -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

View File

@ -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");
}
}