Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance. Project price only 1 $
You can buy this project and download/modify it how often you want.
package io.codemodder.remediation;
import com.github.javaparser.ast.CompilationUnit;
import com.github.javaparser.ast.Node;
import io.codemodder.CodemodChange;
import io.codemodder.CodemodFileScanningResult;
import io.codemodder.codetf.DetectorRule;
import io.codemodder.codetf.FixedFinding;
import io.codemodder.codetf.UnfixedFinding;
import java.util.*;
import java.util.function.BiFunction;
import java.util.function.Function;
import java.util.function.Predicate;
import org.javatuples.Pair;
/**
* Remediates issues with pairs of searchers and strategies. Searchers will associate an issue with
* a node from the AST, while a strategy will try to fix an issue.
*
* @param
*/
public class SearcherStrategyRemediator implements Remediator {
public static final class Builder {
private final Map, RemediationStrategy> searcherRemediatorMap;
public Builder() {
this.searcherRemediatorMap = new HashMap<>();
}
public Builder withSearcherStrategyPair(
final FixCandidateSearcher searcher, final RemediationStrategy strategy) {
this.searcherRemediatorMap.put(
Objects.requireNonNull(searcher), Objects.requireNonNull(strategy));
return this;
}
public Builder withFunctions(
final Predicate searcherMatcher,
final BiFunction fixer) {
this.searcherRemediatorMap.put(
new FixCandidateSearcher.Builder()
.withMatcher(Objects.requireNonNull(searcherMatcher))
.build(),
new ModularRemediationStrategy(fixer));
return this;
}
public SearcherStrategyRemediator build() {
return new SearcherStrategyRemediator<>(searcherRemediatorMap);
}
}
private final Map, RemediationStrategy> searcherRemediatorMap;
protected SearcherStrategyRemediator(
Map, RemediationStrategy> searcherRemediatorMap) {
this.searcherRemediatorMap = searcherRemediatorMap;
}
/** Remediate with a chosen searcher-strategy pair. */
private Pair, List> remediateWithStrategy(
final CompilationUnit cu,
final String path,
final DetectorRule detectorRule,
final Collection findingsForPath,
final Function findingIdExtractor,
final Function findingStartLineExtractor,
final Function> findingEndLineExtractor,
final Function> findingColumnExtractor,
final FixCandidateSearcher searcher,
final RemediationStrategy strategy) {
FixCandidateSearchResults results =
searcher.search(
cu,
path,
detectorRule,
new ArrayList<>(findingsForPath),
findingIdExtractor,
findingStartLineExtractor,
findingEndLineExtractor,
findingColumnExtractor);
if (findingsForPath.isEmpty()) {
return Pair.with(List.of(), List.of());
}
final List unfixedFindings = new ArrayList<>(results.unfixableFindings());
final List changes = new ArrayList<>();
for (FixCandidate fixCandidate : results.fixCandidates()) {
List issues = fixCandidate.issues();
Integer line = findingStartLineExtractor.apply(issues.get(0));
if (line == null) {
issues.forEach(
issue -> {
final String id = findingIdExtractor.apply(issue);
final UnfixedFinding unfixableFinding =
new UnfixedFinding(id, detectorRule, path, null, "No line number provided");
unfixedFindings.add(unfixableFinding);
});
continue;
}
// Try to fix, gathering the added dependencies if successful
var maybeDeps = strategy.fix(cu, fixCandidate.node());
if (maybeDeps.isSuccess()) {
List fixedFindings =
issues.stream()
.map(findingIdExtractor)
.map(findingId -> new FixedFinding(findingId, detectorRule))
.toList();
changes.add(CodemodChange.from(line, maybeDeps.getDependencies(), fixedFindings));
} else {
issues.forEach(
issue -> {
final String id = findingIdExtractor.apply(issue);
final UnfixedFinding unfixableFinding =
new UnfixedFinding(id, detectorRule, path, line, maybeDeps.getReason());
unfixedFindings.add(unfixableFinding);
});
}
}
return Pair.with(changes, unfixedFindings);
}
public CodemodFileScanningResult remediateAll(
final CompilationUnit cu,
final String path,
final DetectorRule detectorRule,
final Collection findingsForPath,
final Function findingIdExtractor,
final Function findingStartLineExtractor,
final Function> findingEndLineExtractor,
final Function> findingColumnExtractor) {
List allChanges = new ArrayList<>();
List allUnfixed = new ArrayList<>();
for (var searcherAndStrategy : searcherRemediatorMap.entrySet()) {
var pairResult =
remediateWithStrategy(
cu,
path,
detectorRule,
findingsForPath,
findingIdExtractor,
findingStartLineExtractor,
findingEndLineExtractor,
findingColumnExtractor,
searcherAndStrategy.getKey(),
searcherAndStrategy.getValue());
allChanges.addAll(pairResult.getValue0());
allUnfixed.addAll(pairResult.getValue1());
}
return CodemodFileScanningResult.from(allChanges, allUnfixed);
}
}