Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions config/checkstyle.properties
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,4 @@ checkstyle.regexp.header.file=config/regexp-header.txt
checkstyle.importcontrol.file=config/import-control.xml
checkstyle.importcontroltest.file=config/import-control-test.xml
checkstyle.java.version=17
checkstyle.cache.file=.cache/checkstyle-cachefile
3 changes: 2 additions & 1 deletion src/main/java/org/checkstyle/autofix/CheckstyleAutoFix.java
Original file line number Diff line number Diff line change
Expand Up @@ -74,8 +74,9 @@ public String getPropertiesPath() {
public List<Recipe> getRecipeList() {
final List<CheckstyleViolation> violations = CheckstyleReportParser
.parse(Path.of(getViolationReportPath()));
final CheckConfiguration configuration = loadCheckstyleConfiguration();

return CheckstyleRecipeRegistry.getRecipes(violations);
return CheckstyleRecipeRegistry.getRecipes(violations, configuration);
}

private CheckConfiguration loadCheckstyleConfiguration() {
Expand Down
44 changes: 44 additions & 0 deletions src/main/java/org/checkstyle/autofix/CheckstyleCheck.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
///////////////////////////////////////////////////////////////////////////////////////////////
// checkstyle-openrewrite-recipes: Automatically fix Checkstyle violations with OpenRewrite.
// Copyright (C) 2025 The Checkstyle OpenRewrite Recipes Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
///////////////////////////////////////////////////////////////////////////////////////////////

package org.checkstyle.autofix;

import java.util.Arrays;
import java.util.Optional;

public enum CheckstyleCheck {
UPPERELL("com.puppycrawl.tools.checkstyle.checks.UpperEllCheck"),
HEADER("com.puppycrawl.tools.checkstyle.checks.header.HeaderCheck");

private final String id;

CheckstyleCheck(String id) {
this.id = id;
}

public String getId() {
return id;
}

public static Optional<CheckstyleCheck> fromSource(String source) {
return Arrays.stream(values())
.filter(check -> check.getId().equals(source))
.findFirst();

}

}
70 changes: 51 additions & 19 deletions src/main/java/org/checkstyle/autofix/CheckstyleRecipeRegistry.java
Original file line number Diff line number Diff line change
Expand Up @@ -17,24 +17,33 @@

package org.checkstyle.autofix;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.EnumMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Optional;
import java.util.function.BiFunction;
import java.util.function.Function;
import java.util.stream.Collectors;

import org.checkstyle.autofix.parser.CheckConfiguration;
import org.checkstyle.autofix.parser.CheckstyleViolation;
import org.checkstyle.autofix.recipe.Header;
import org.checkstyle.autofix.recipe.UpperEll;
import org.openrewrite.Recipe;

public final class CheckstyleRecipeRegistry {

private static final Map<String, Function<List<CheckstyleViolation>, Recipe>> RECIPE_MAP =
new HashMap<>();
private static final EnumMap<CheckstyleCheck, Function<List<CheckstyleViolation>,
Recipe>> RECIPE_MAP = new EnumMap<>(CheckstyleCheck.class);

private static final EnumMap<CheckstyleCheck, BiFunction<List<CheckstyleViolation>,
CheckConfiguration, Recipe>> RECIPE_MAP_WITH_CONFIG =
new EnumMap<>(CheckstyleCheck.class);

static {
RECIPE_MAP.put("UpperEllCheck", UpperEll::new);
RECIPE_MAP.put(CheckstyleCheck.UPPERELL, UpperEll::new);
RECIPE_MAP_WITH_CONFIG.put(CheckstyleCheck.HEADER, Header::new);
}

private CheckstyleRecipeRegistry() {
Expand All @@ -47,28 +56,51 @@ private CheckstyleRecipeRegistry() {
* using the simple name of the check, and applies the factory to generate Recipe instances.
*
* @param violations the list of Checkstyle violations
* @param config the checkstyle configuration
* @return a list of generated Recipe objects
*/
public static List<Recipe> getRecipes(List<CheckstyleViolation> violations) {
public static List<Recipe> getRecipes(List<CheckstyleViolation> violations,
CheckConfiguration config) {
return violations.stream()
.collect(Collectors.groupingBy(CheckstyleViolation::getSource))
.entrySet()
.stream()
.map(entry -> createRecipe(entry, config))
.filter(Objects::nonNull)
.collect(Collectors.toList());
}

private static Recipe createRecipe(Map.Entry<String, List<CheckstyleViolation>> entry,
CheckConfiguration config) {

Recipe recipe = null;

final Map<String, List<CheckstyleViolation>> violationsByCheck = violations.stream()
.collect(Collectors.groupingBy(CheckstyleViolation::getSource));
final Optional<CheckstyleCheck> check = CheckstyleCheck.fromSource(entry.getKey());

final List<Recipe> recipes = new ArrayList<>();
if (check.isPresent()) {

for (Map.Entry<String, List<CheckstyleViolation>> entry : violationsByCheck.entrySet()) {
final String checkName = entry.getKey();
final String simpleCheckName = checkName
.substring(checkName.lastIndexOf('.') + 1);
final List<CheckstyleViolation> checkViolations = entry.getValue();
final CheckstyleCheck checkstyleCheck = check.get();
final List<CheckstyleViolation> violations = entry.getValue();

final Function<List<CheckstyleViolation>, Recipe> recipeFactory =
RECIPE_MAP.get(simpleCheckName);
if (recipeFactory != null) {
recipes.add(recipeFactory.apply(checkViolations));
final BiFunction<List<CheckstyleViolation>, CheckConfiguration,
Recipe> configRecipeFactory = RECIPE_MAP_WITH_CONFIG.get(checkstyleCheck);

if (configRecipeFactory == null) {
final Function<List<CheckstyleViolation>, Recipe> simpleRecipeFactory =
RECIPE_MAP.get(checkstyleCheck);
recipe = simpleRecipeFactory.apply(violations);
}
else {
final CheckConfiguration subConfig =
extractCheckConfiguration(config, checkstyleCheck.name());
recipe = configRecipeFactory.apply(violations, subConfig);
}
}
return recipe;
}

return recipes;
private static CheckConfiguration extractCheckConfiguration(CheckConfiguration config,
String checkName) {
return config.getConfig(checkName);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,10 @@ private CheckConfiguration getParent() {
return parent;
}

private List<CheckConfiguration> getChildren() {
return children;
}

public String getProperty(String key) {
String value = null;

Expand Down Expand Up @@ -94,12 +98,19 @@ public int[] getIntArray(String propertyName) {
return result;
}

public CheckConfiguration getChildConfig(String childName) {
public CheckConfiguration getConfig(String childName) {
CheckConfiguration result = null;
for (CheckConfiguration child : children) {
if (childName.equals(child.getName())) {
result = child;
break;
if (name.equals(childName)) {
result = this;
}
else {
final List<CheckConfiguration> childrenList = getChildren();
for (final CheckConfiguration current : childrenList) {
if (childName.equals(current.getName())) {
result = current;
break;
}
childrenList.addAll(current.getChildren());
}
}
return result;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
import java.io.IOException;
import java.util.HashMap;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Properties;

Expand Down Expand Up @@ -56,7 +57,8 @@ public static CheckConfiguration mapConfiguration(Configuration config) {
simpleChildren[index] = mapConfiguration(checkstyleChildren[index]);
}

return new CheckConfiguration(config.getName(), properties, List.of(simpleChildren));
return new CheckConfiguration(config.getName().toUpperCase(Locale.ROOT),
properties, List.of(simpleChildren));
}

public static CheckConfiguration loadConfiguration(String checkstyleConfigurationPath,
Expand Down

This file was deleted.

Loading