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 Jun 26, 2017
1 parent a83475a commit 80e95f8
Show file tree
Hide file tree
Showing 17 changed files with 740 additions and 25 deletions.
1 change: 1 addition & 0 deletions config/import-control.xml
Expand Up @@ -93,6 +93,7 @@
<allow class="com.google.common.collect.ImmutableMap" local-only="true"/>

<allow class="com.puppycrawl.tools.checkstyle.Checker" local-only="true"/>
<allow class="com.puppycrawl.tools.checkstyle.ThreadModeSettings" local-only="true"/>
<!-- allowed till https://github.com/checkstyle/checkstyle/issues/3817 -->
<allow pkg="com.puppycrawl.tools.checkstyle.utils"/>
</subpackage>
Expand Down
6 changes: 5 additions & 1 deletion pom.xml
Expand Up @@ -1930,7 +1930,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 @@ -1943,6 +1943,8 @@
<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.MultiThreadModuleResolver</param>
<param>com.puppycrawl.tools.checkstyle.MultiThreadModeSettings</param>
</targetClasses>
<targetTests>
<param>com.puppycrawl.tools.checkstyle.AuditEventDefaultFormatterTest</param>
Expand All @@ -1958,6 +1960,8 @@
<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.MultiThreadModuleResolverTest</param>
<param>com.puppycrawl.tools.checkstyle.MultiThreadModeConfigurationTest</param>
</targetTests>
<excludedMethods>
<!-- till https://github.com/hcoles/pitest/issues/353 -->
Expand Down
Expand Up @@ -97,12 +97,16 @@ public final class ConfigurationLoader {

/** Property resolver. **/
private final PropertyResolver overridePropsResolver;

/** The loaded configurations. **/
private final Deque<DefaultConfiguration> configStack = new ArrayDeque<>();

/** Flags if modules with the severity 'ignore' should be omitted. */
private final boolean omitIgnoredModules;

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

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

Expand All @@ -111,15 +115,18 @@ public final class ConfigurationLoader {
* @param overrideProps resolver for overriding properties
* @param omitIgnoredModules {@code true} if ignored modules should be
* omitted
* @param threadModeSettings the multi thread mode configuration
* @throws ParserConfigurationException if an error occurs
* @throws SAXException if an error occurs
*/
private ConfigurationLoader(final PropertyResolver overrideProps,
final boolean omitIgnoredModules)
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 +169,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 multi 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 @@ -173,13 +194,32 @@ public static Configuration loadConfiguration(String config,
* @throws CheckstyleException if an error occurs
*/
public static Configuration loadConfiguration(String config,
PropertyResolver overridePropsResolver, boolean omitIgnoredModules)
PropertyResolver overridePropsResolver, boolean omitIgnoredModules)
throws CheckstyleException {
return loadConfiguration(config, overridePropsResolver, omitIgnoredModules,
ThreadModeSettings.getSingleThreadMode());
}

/**
* 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 multi 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 All @@ -195,7 +235,7 @@ public static Configuration loadConfiguration(String config,
*
* @deprecated As this method does not provide a valid system ID,
* preventing resolution of external entities, a
* {@link #loadConfiguration(InputSource,PropertyResolver,boolean)
* {@link #loadConfiguration(InputSource, PropertyResolver, boolean)
* version using an InputSource}
* should be used instead
*/
Expand All @@ -222,10 +262,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.getSingleThreadMode());
}

/**
* 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 multi 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 +472,16 @@ 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;
if (threadModeSettings == null) {
name = originalName;
}
else {
name = threadModeSettings.resolveName(originalName);
}
final DefaultConfiguration conf =
new DefaultConfiguration(name);
new DefaultConfiguration(name, threadModeSettings);

if (configuration == null) {
configuration = conf;
Expand Down
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 multi thread mode configuration. */
private final ThreadModeSettings threadModeSettings;

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

/**
* 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,13 @@ public void addMessage(String key, String value) {
public ImmutableMap<String, String> getMessages() {
return ImmutableMap.copyOf(messages);
}

/**
* Gets the multi thread mode configuration.
* @return the multi thread mode configuration.
*/
@Override
public ThreadModeSettings getThreadModeSettings() {
return threadModeSettings;
}
}
80 changes: 78 additions & 2 deletions src/main/java/com/puppycrawl/tools/checkstyle/Main.java
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);
try {
final int checkerThreadsNumber = Integer.parseInt(checkerThreadsNumberStr);
if (checkerThreadsNumber < 1) {
result.add(mustBeGreaterThanZeroMessage);
}
}
catch (NumberFormatException ignored) {
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 @@ -602,14 +661,27 @@ private static void printUsage() {
final HelpFormatter formatter = new HelpFormatter();
formatter.setWidth(HELP_WIDTH);
formatter.printHelp(String.format("java %s [options] -c <config.xml> file...",
Main.class.getName()), buildOptions());
Main.class.getName()), buildOptionsExcludeHidden());
}

/**
* Builds and returns list of parameters supported by cli Checkstyle.
* @return available options
*/
private static Options buildOptions() {
final Options options = buildOptionsExcludeHidden();
options.addOption(OPTION_CAPITAL_C_NAME, OPTION_CHECKER_THREADS_NUMBER_NAME, true,
"The number of Checker threads (must be greater than zero)");
options.addOption(OPTION_CAPITAL_W_NAME, OPTION_TREE_WALKER_THREADS_NUMBER_NAME, true,
"The number of TreeWalker threads (must be greater than zero)");
return options;
}

/**
* Builds and returns list of parameters supported by cli Checkstyle, excluding hidden options.
* @return available options (excluding hidden options)
*/
private static Options buildOptionsExcludeHidden() {
final Options options = new Options();
options.addOption(OPTION_C_NAME, true, "Sets the check configuration file to use.");
options.addOption(OPTION_O_NAME, true, "Sets the output file. Defaults to stdout");
Expand Down Expand Up @@ -651,5 +723,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;
}
}

0 comments on commit 80e95f8

Please sign in to comment.