Skip to content

Commit

Permalink
Issue checkstyle#4370: Add multi thread mode to checkstyle launcher
Browse files Browse the repository at this point in the history
  • Loading branch information
soon committed Jul 2, 2017
1 parent e27816f commit 48f9931
Show file tree
Hide file tree
Showing 17 changed files with 714 additions and 36 deletions.
4 changes: 3 additions & 1 deletion pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -1977,7 +1977,7 @@
<configuration>
<targetClasses>
<param>com.puppycrawl.tools.checkstyle.AuditEventDefaultFormatter</param>
<param>com.puppycrawl.tools.checkstyle.ConfigurationLoader</param>
<param>com.puppycrawl.tools.checkstyle.ConfigurationLoader*</param>
<param>com.puppycrawl.tools.checkstyle.PackageNamesLoader</param>
<param>com.puppycrawl.tools.checkstyle.DefaultConfiguration</param>
<param>com.puppycrawl.tools.checkstyle.DefaultContext</param>
Expand All @@ -1990,6 +1990,7 @@
<param>com.puppycrawl.tools.checkstyle.Checker</param>
<param>com.puppycrawl.tools.checkstyle.ant.*</param>
<param>com.puppycrawl.tools.checkstyle.doclets.*</param>
<param>com.puppycrawl.tools.checkstyle.ThreadModeSettings</param>
</targetClasses>
<targetTests>
<param>com.puppycrawl.tools.checkstyle.AuditEventDefaultFormatterTest</param>
Expand All @@ -2005,6 +2006,7 @@
<param>com.puppycrawl.tools.checkstyle.CheckerTest</param>
<param>com.puppycrawl.tools.checkstyle.ant.*</param>
<param>com.puppycrawl.tools.checkstyle.doclets.*</param>
<param>com.puppycrawl.tools.checkstyle.ThreadModeSettingsTest</param>
</targetTests>
<excludedMethods>
<!-- till https://github.com/hcoles/pitest/issues/353 -->
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,9 @@ public final class ConfigurationLoader {
/** Flags if modules with the severity 'ignore' should be omitted. */
private final boolean omitIgnoredModules;

/** The thread mode configuration. */
private final ThreadModeSettings threadModeSettings;

/** The Configuration that is being built. */
private Configuration configuration;

Expand All @@ -117,9 +120,26 @@ public final class ConfigurationLoader {
private ConfigurationLoader(final PropertyResolver overrideProps,
final boolean omitIgnoredModules)
throws ParserConfigurationException, SAXException {
this(overrideProps, omitIgnoredModules, ThreadModeSettings.SINGLE_THREAD_MODE_INSTANCE);
}

/**
* Creates a new {@code ConfigurationLoader} instance.
* @param overrideProps resolver for overriding properties
* @param omitIgnoredModules {@code true} if ignored modules should be
* omitted
* @param threadModeSettings the thread mode configuration
* @throws ParserConfigurationException if an error occurs
* @throws SAXException if an error occurs
*/
private ConfigurationLoader(final PropertyResolver overrideProps,
final boolean omitIgnoredModules,
final ThreadModeSettings threadModeSettings)
throws ParserConfigurationException, SAXException {
saxHandler = new InternalLoader();
overridePropsResolver = overrideProps;
this.omitIgnoredModules = omitIgnoredModules;
this.threadModeSettings = threadModeSettings;
}

/**
Expand Down Expand Up @@ -162,6 +182,20 @@ public static Configuration loadConfiguration(String config,
return loadConfiguration(config, overridePropsResolver, false);
}

/**
* Returns the module configurations in a specified file.
* @param config location of config file, can be either a URL or a filename
* @param overridePropsResolver overriding properties
* @param threadModeSettings the thread mode configuration
* @return the check configurations
* @throws CheckstyleException if an error occurs
*/
public static Configuration loadConfiguration(String config,
PropertyResolver overridePropsResolver, ThreadModeSettings threadModeSettings)
throws CheckstyleException {
return loadConfiguration(config, overridePropsResolver, false, threadModeSettings);
}

/**
* Returns the module configurations in a specified file.
*
Expand All @@ -175,11 +209,30 @@ public static Configuration loadConfiguration(String config,
public static Configuration loadConfiguration(String config,
PropertyResolver overridePropsResolver, boolean omitIgnoredModules)
throws CheckstyleException {
return loadConfiguration(config, overridePropsResolver, omitIgnoredModules,
ThreadModeSettings.SINGLE_THREAD_MODE_INSTANCE);
}

/**
* Returns the module configurations in a specified file.
*
* @param config location of config file, can be either a URL or a filename
* @param overridePropsResolver overriding properties
* @param omitIgnoredModules {@code true} if modules with severity
* 'ignore' should be omitted, {@code false} otherwise
* @param threadModeSettings the thread mode configuration
* @return the check configurations
* @throws CheckstyleException if an error occurs
*/
public static Configuration loadConfiguration(String config,
PropertyResolver overridePropsResolver,
boolean omitIgnoredModules, ThreadModeSettings threadModeSettings)
throws CheckstyleException {
// figure out if this is a File or a URL
final URI uri = CommonUtils.getUriByFilename(config);
final InputSource source = new InputSource(uri.toString());
return loadConfiguration(source, overridePropsResolver,
omitIgnoredModules);
omitIgnoredModules, threadModeSettings);
}

/**
Expand Down Expand Up @@ -222,10 +275,31 @@ public static Configuration loadConfiguration(InputStream configStream,
public static Configuration loadConfiguration(InputSource configSource,
PropertyResolver overridePropsResolver, boolean omitIgnoredModules)
throws CheckstyleException {
return loadConfiguration(configSource, overridePropsResolver,
omitIgnoredModules, ThreadModeSettings.SINGLE_THREAD_MODE_INSTANCE);
}

/**
* Returns the module configurations from a specified input source.
* Note that if the source does wrap an open byte or character
* stream, clients are required to close that stream by themselves
*
* @param configSource the input stream to the Checkstyle configuration
* @param overridePropsResolver overriding properties
* @param omitIgnoredModules {@code true} if modules with severity
* 'ignore' should be omitted, {@code false} otherwise
* @param threadModeSettings the thread mode configuration
* @return the check configurations
* @throws CheckstyleException if an error occurs
*/
public static Configuration loadConfiguration(InputSource configSource,
PropertyResolver overridePropsResolver,
boolean omitIgnoredModules, ThreadModeSettings threadModeSettings)
throws CheckstyleException {
try {
final ConfigurationLoader loader =
new ConfigurationLoader(overridePropsResolver,
omitIgnoredModules);
omitIgnoredModules, threadModeSettings);
loader.parseInputSource(configSource);
return loader.configuration;
}
Expand Down Expand Up @@ -411,9 +485,10 @@ public void startElement(String uri,
throws SAXException {
if (qName.equals(MODULE)) {
//create configuration
final String name = attributes.getValue(NAME);
final String originalName = attributes.getValue(NAME);
final String name = threadModeSettings.resolveName(originalName);
final DefaultConfiguration conf =
new DefaultConfiguration(name);
new DefaultConfiguration(name, threadModeSettings);

if (configuration == null) {
configuration = conf;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -48,12 +48,26 @@ public final class DefaultConfiguration implements Configuration {
/** The map containing custom messages. */
private final Map<String, String> messages = new HashMap<>();

/** The thread mode configuration. */
private final ThreadModeSettings threadModeSettings;

/**
* Instantiates a DefaultConfiguration.
* @param name the name for this DefaultConfiguration.
*/
public DefaultConfiguration(String name) {
this(name, ThreadModeSettings.SINGLE_THREAD_MODE_INSTANCE);
}

/**
* Instantiates a DefaultConfiguration.
* @param name the name for this DefaultConfiguration.
* @param threadModeSettings the thread mode configuration.
*/
public DefaultConfiguration(String name,
ThreadModeSettings threadModeSettings) {
this.name = name;
this.threadModeSettings = threadModeSettings;
}

@Override
Expand Down Expand Up @@ -131,4 +145,12 @@ public void addMessage(String key, String value) {
public ImmutableMap<String, String> getMessages() {
return ImmutableMap.copyOf(messages);
}

/**
* Gets the thread mode configuration.
* @return the thread mode configuration.
*/
public ThreadModeSettings getThreadModeSettings() {
return threadModeSettings;
}
}
69 changes: 68 additions & 1 deletion src/main/java/com/puppycrawl/tools/checkstyle/Main.java
Original file line number Diff line number Diff line change
Expand Up @@ -127,12 +127,28 @@ public final class Main {
/** Name for the option '--exclude-regexp'. */
private static final String OPTION_EXCLUDE_REGEXP_NAME = "exclude-regexp";

/** Name for the option '-C'. */
private static final String OPTION_CAPITAL_C_NAME = "C";

/** Name for the option '--checker-threads-number'. */
private static final String OPTION_CHECKER_THREADS_NUMBER_NAME = "checker-threads-number";

/** Name for the option '-W'. */
private static final String OPTION_CAPITAL_W_NAME = "W";

/** Name for the option '--tree-walker-threads-number'. */
private static final String OPTION_TREE_WALKER_THREADS_NUMBER_NAME =
"tree-walker-threads-number";

/** Name for 'xml' format. */
private static final String XML_FORMAT_NAME = "xml";

/** Name for 'plain' format. */
private static final String PLAIN_FORMAT_NAME = "plain";

/** A string value of 1. */
private static final String ONE_STRING_VALUE = "1";

/** Don't create instance of this class, use {@link #main(String[])} method instead. */
private Main() {
}
Expand Down Expand Up @@ -293,6 +309,12 @@ else if (cmdLine.hasOption(OPTION_C_NAME)) {
result.add(String.format("Could not find file '%s'.", propertiesLocation));
}
}
verifyThreadsNumberParameter(cmdLine, result, OPTION_CAPITAL_C_NAME,
"Checker threads number must be greater than zero",
"Invalid Checker threads number");
verifyThreadsNumberParameter(cmdLine, result, OPTION_CAPITAL_W_NAME,
"TreeWalker threads number must be greater than zero",
"Invalid TreeWalker threads number");
}
else {
result.add("Must specify a config XML file.");
Expand All @@ -301,6 +323,34 @@ else if (cmdLine.hasOption(OPTION_C_NAME)) {
return result;
}

/**
* Verifies threads number CLI parameter value.
* @param cmdLine a command line
* @param result a resulting list of errors
* @param cliParameterName a CLI parameter name
* @param mustBeGreaterThanZeroMessage a message which should be reported
* if the number of threads is less than or equal to zero
* @param invalidNumberMessage a message which should be reported if the passed value
* is not a valid number
*/
private static void verifyThreadsNumberParameter(CommandLine cmdLine, List<String> result,
String cliParameterName, String mustBeGreaterThanZeroMessage,
String invalidNumberMessage) {
if (cmdLine.hasOption(cliParameterName)) {
final String checkerThreadsNumberStr =
cmdLine.getOptionValue(cliParameterName);
if (CommonUtils.isInt(checkerThreadsNumberStr)) {
final int checkerThreadsNumber = Integer.parseInt(checkerThreadsNumberStr);
if (checkerThreadsNumber < 1) {
result.add(mustBeGreaterThanZeroMessage);
}
}
else {
result.add(invalidNumberMessage);
}
}
}

/**
* Do execution of CheckStyle based on Command line options.
* @param commandLine command line object
Expand Down Expand Up @@ -382,6 +432,12 @@ private static CliOptions convertCliToPojo(CommandLine cmdLine, List<File> files
conf.propertiesLocation = cmdLine.getOptionValue(OPTION_P_NAME);
conf.files = filesToProcess;
conf.executeIgnoredModules = cmdLine.hasOption(OPTION_EXECUTE_IGNORED_MODULES_NAME);
final String checkerThreadsNumber = cmdLine.getOptionValue(
OPTION_CAPITAL_C_NAME, ONE_STRING_VALUE);
conf.checkerThreadsNumber = Integer.parseInt(checkerThreadsNumber);
final String treeWalkerThreadsNumber = cmdLine.getOptionValue(
OPTION_CAPITAL_W_NAME, ONE_STRING_VALUE);
conf.treeWalkerThreadsNumber = Integer.parseInt(treeWalkerThreadsNumber);
return conf;
}

Expand All @@ -408,9 +464,12 @@ private static int runCheckstyle(CliOptions cliOptions)
}

// create a configuration
final ThreadModeSettings multiThreadModeSettings =
new ThreadModeSettings(
cliOptions.checkerThreadsNumber, cliOptions.treeWalkerThreadsNumber);
final Configuration config = ConfigurationLoader.loadConfiguration(
cliOptions.configLocation, new PropertiesExpander(props),
!cliOptions.executeIgnoredModules);
!cliOptions.executeIgnoredModules, multiThreadModeSettings);

// create a listener for output
final AuditListener listener = createListener(cliOptions.format, cliOptions.outputLocation);
Expand Down Expand Up @@ -634,6 +693,10 @@ private static Options buildOptions() {
"Regular expression of directory to exclude from CheckStyle");
options.addOption(OPTION_EXECUTE_IGNORED_MODULES_NAME, false,
"Allows ignored modules to be run.");
options.addOption(OPTION_CAPITAL_C_NAME, OPTION_CHECKER_THREADS_NUMBER_NAME, true,
"(experimental) The number of Checker threads (must be greater than zero)");
options.addOption(OPTION_CAPITAL_W_NAME, OPTION_TREE_WALKER_THREADS_NUMBER_NAME, true,
"(experimental) The number of TreeWalker threads (must be greater than zero)");
return options;
}

Expand All @@ -651,5 +714,9 @@ private static class CliOptions {
private List<File> files;
/** Switch whether to execute ignored modules or not. */
private boolean executeIgnoredModules;
/** The checker threads number. */
private int checkerThreadsNumber;
/** The tree walker threads number. */
private int treeWalkerThreadsNumber;
}
}
Loading

0 comments on commit 48f9931

Please sign in to comment.