Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

chore: Address Sonar issues post-nullness (Part 2) #1197

Merged
merged 7 commits into from
Nov 12, 2024
Merged
Show file tree
Hide file tree
Changes from 6 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
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@
import ai.timefold.solver.benchmark.api.PlannerBenchmarkFactory;
import ai.timefold.solver.benchmark.config.PlannerBenchmarkConfig;
import ai.timefold.solver.benchmark.config.SolverBenchmarkConfig;
import ai.timefold.solver.benchmark.config.blueprint.SolverBenchmarkBluePrintConfig;
import ai.timefold.solver.benchmark.config.report.BenchmarkReportConfig;
import ai.timefold.solver.benchmark.impl.report.BenchmarkReport;
import ai.timefold.solver.benchmark.impl.report.BenchmarkReportFactory;
Expand Down Expand Up @@ -148,20 +147,22 @@ protected void generateSolverBenchmarkConfigNames() {
}

protected List<SolverBenchmarkConfig> buildEffectiveSolverBenchmarkConfigList() {
List<SolverBenchmarkConfig> effectiveSolverBenchmarkConfigList = new ArrayList<>(0);
if (plannerBenchmarkConfig.getSolverBenchmarkConfigList() != null) {
effectiveSolverBenchmarkConfigList.addAll(plannerBenchmarkConfig.getSolverBenchmarkConfigList());
var effectiveSolverBenchmarkConfigList = new ArrayList<SolverBenchmarkConfig>(0);
var solverBenchmarkConfigList = plannerBenchmarkConfig.getSolverBenchmarkConfigList();
if (solverBenchmarkConfigList != null) {
effectiveSolverBenchmarkConfigList.addAll(solverBenchmarkConfigList);
}
if (plannerBenchmarkConfig.getSolverBenchmarkBluePrintConfigList() != null) {
for (SolverBenchmarkBluePrintConfig solverBenchmarkBluePrintConfig : plannerBenchmarkConfig
.getSolverBenchmarkBluePrintConfigList()) {
var solverBenchmarkBluePrintConfigList = plannerBenchmarkConfig.getSolverBenchmarkBluePrintConfigList();
if (solverBenchmarkBluePrintConfigList != null) {
for (var solverBenchmarkBluePrintConfig : solverBenchmarkBluePrintConfigList) {
effectiveSolverBenchmarkConfigList.addAll(solverBenchmarkBluePrintConfig.buildSolverBenchmarkConfigList());
}
}
if (plannerBenchmarkConfig.getInheritedSolverBenchmarkConfig() != null) {
for (SolverBenchmarkConfig solverBenchmarkConfig : effectiveSolverBenchmarkConfigList) {
var inheritedSolverBenchmarkConfig = plannerBenchmarkConfig.getInheritedSolverBenchmarkConfig();
if (inheritedSolverBenchmarkConfig != null) {
for (var solverBenchmarkConfig : effectiveSolverBenchmarkConfigList) {
// Side effect: changes the unmarshalled solverBenchmarkConfig
solverBenchmarkConfig.inherit(plannerBenchmarkConfig.getInheritedSolverBenchmarkConfig());
solverBenchmarkConfig.inherit(inheritedSolverBenchmarkConfig);
}
}
return effectiveSolverBenchmarkConfigList;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,10 @@
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Objects;

import ai.timefold.solver.benchmark.api.PlannerBenchmarkFactory;
import ai.timefold.solver.benchmark.config.ProblemBenchmarksConfig;
import ai.timefold.solver.benchmark.config.statistic.ProblemStatisticType;
import ai.timefold.solver.benchmark.config.statistic.SingleStatisticType;
import ai.timefold.solver.benchmark.impl.loader.FileProblemProvider;
import ai.timefold.solver.benchmark.impl.loader.InstanceProblemProvider;
Expand All @@ -30,6 +30,7 @@ public ProblemBenchmarksFactory(ProblemBenchmarksConfig config) {
this.config = config;
}

@SuppressWarnings({ "rawtypes", "unchecked" })
public <Solution_> void buildProblemBenchmarkList(SolverBenchmarkResult solverBenchmarkResult,
Solution_[] extraProblems) {
PlannerBenchmarkResult plannerBenchmarkResult = solverBenchmarkResult.getPlannerBenchmarkResult();
Expand Down Expand Up @@ -61,9 +62,8 @@ private <Solution_> List<ProblemProvider<Solution_>> buildProblemProviderList(
+ "Or maybe pass at least one problem to " + PlannerBenchmarkFactory.class.getSimpleName()
+ ".buildPlannerBenchmark().");
}
List<ProblemProvider<Solution_>> problemProviderList = new ArrayList<>(
extraProblems.length
+ (config.getInputSolutionFileList() == null ? 0 : config.getInputSolutionFileList().size()));
List<ProblemProvider<Solution_>> problemProviderList = new ArrayList<>(extraProblems.length
+ Objects.requireNonNullElse(config.getInputSolutionFileList(), Collections.emptyList()).size());
DefaultSolverFactory<Solution_> defaultSolverFactory =
new DefaultSolverFactory<>(solverBenchmarkResult.getSolverConfig());
SolutionDescriptor<Solution_> solutionDescriptor = defaultSolverFactory.getSolutionDescriptor();
Expand Down Expand Up @@ -94,42 +94,47 @@ private <Solution_> List<ProblemProvider<Solution_>> buildProblemProviderList(
return problemProviderList;
}

@SuppressWarnings("unchecked")
private <Solution_> SolutionFileIO<Solution_> buildSolutionFileIO() {
if (config.getSolutionFileIOClass() == null) {
throw new IllegalArgumentException(
"The solutionFileIOClass (" + config.getSolutionFileIOClass() + ") cannot be null.");
var solutionFileIOClass = config.getSolutionFileIOClass();
if (solutionFileIOClass == null) {
throw new IllegalArgumentException("The solutionFileIOClass cannot be null.");
}
return (SolutionFileIO<Solution_>) ConfigUtils.newInstance(config, "solutionFileIOClass",
config.getSolutionFileIOClass());
return (SolutionFileIO<Solution_>) ConfigUtils.newInstance(config, "solutionFileIOClass", solutionFileIOClass);
}

private <Solution_> ProblemBenchmarkResult<Solution_> buildProblemBenchmark(
PlannerBenchmarkResult plannerBenchmarkResult, ProblemProvider<Solution_> problemProvider) {
@SuppressWarnings("rawtypes")
private <Solution_> ProblemBenchmarkResult<Solution_> buildProblemBenchmark(PlannerBenchmarkResult plannerBenchmarkResult,
ProblemProvider<Solution_> problemProvider) {
ProblemBenchmarkResult<Solution_> problemBenchmarkResult = new ProblemBenchmarkResult<>(plannerBenchmarkResult);
problemBenchmarkResult.setName(problemProvider.getProblemName());
problemBenchmarkResult.setProblemProvider(problemProvider);
problemBenchmarkResult.setWriteOutputSolutionEnabled(
config.getWriteOutputSolutionEnabled() == null ? false : config.getWriteOutputSolutionEnabled());
List<ProblemStatistic> problemStatisticList;
if (config.getProblemStatisticEnabled() != null && !config.getProblemStatisticEnabled()) {
problemBenchmarkResult
.setWriteOutputSolutionEnabled(Objects.requireNonNullElse(config.getWriteOutputSolutionEnabled(), false));
List<ProblemStatistic> problemStatisticList = getProblemStatisticList(problemBenchmarkResult);
problemBenchmarkResult.setProblemStatisticList(problemStatisticList);
problemBenchmarkResult.setSingleBenchmarkResultList(new ArrayList<>());
return problemBenchmarkResult;
}

@SuppressWarnings("rawtypes")
private List<ProblemStatistic> getProblemStatisticList(ProblemBenchmarkResult problemBenchmarkResult) {
var problemStatisticEnabled = config.getProblemStatisticEnabled();
if (problemStatisticEnabled != null && !problemStatisticEnabled) {
if (!ConfigUtils.isEmptyCollection(config.getProblemStatisticTypeList())) {
throw new IllegalArgumentException("The problemStatisticEnabled (" + config.getProblemStatisticEnabled()
+ ") and problemStatisticTypeList (" + config.getProblemStatisticTypeList()
+ ") cannot be used together.");
throw new IllegalArgumentException(
"The problemStatisticEnabled (%b) and problemStatisticTypeList (%s) cannot be used together."
.formatted(problemStatisticEnabled, config.getProblemStatisticTypeList()));
}
problemStatisticList = Collections.emptyList();
return Collections.emptyList();
} else {
List<ProblemStatisticType> problemStatisticTypeList_ = config.determineProblemStatisticTypeList();
problemStatisticList = new ArrayList<>(problemStatisticTypeList_.size());
for (ProblemStatisticType problemStatisticType : problemStatisticTypeList_) {
problemStatisticList.add(problemStatisticType.buildProblemStatistic(problemBenchmarkResult));
}
return config.determineProblemStatisticTypeList().stream()
.map(problemStatisticType -> problemStatisticType.buildProblemStatistic(problemBenchmarkResult))
.toList();
}
problemBenchmarkResult.setProblemStatisticList(problemStatisticList);
problemBenchmarkResult.setSingleBenchmarkResultList(new ArrayList<>());
return problemBenchmarkResult;
}

@SuppressWarnings({ "rawtypes", "unchecked" })
private void buildSingleBenchmark(SolverBenchmarkResult solverBenchmarkResult,
ProblemBenchmarkResult problemBenchmarkResult) {
SingleBenchmarkResult singleBenchmarkResult = new SingleBenchmarkResult(solverBenchmarkResult, problemBenchmarkResult);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Objects;
import java.util.Optional;

import ai.timefold.solver.benchmark.config.ProblemBenchmarksConfig;
Expand All @@ -15,7 +16,6 @@
import ai.timefold.solver.core.config.solver.monitoring.MonitoringConfig;
import ai.timefold.solver.core.config.solver.monitoring.SolverMetric;
import ai.timefold.solver.core.config.util.ConfigUtils;
import ai.timefold.solver.core.impl.domain.solution.descriptor.SolutionDescriptor;
import ai.timefold.solver.core.impl.solver.DefaultSolverFactory;

public class SolverBenchmarkFactory {
Expand All @@ -28,59 +28,60 @@ public SolverBenchmarkFactory(SolverBenchmarkConfig config) {
public <Solution_> void buildSolverBenchmark(ClassLoader classLoader, PlannerBenchmarkResult plannerBenchmark,
Solution_[] extraProblems) {
validate();
SolverBenchmarkResult solverBenchmarkResult = new SolverBenchmarkResult(plannerBenchmark);
var solverBenchmarkResult = new SolverBenchmarkResult(plannerBenchmark);
solverBenchmarkResult.setName(config.getName());
solverBenchmarkResult.setSubSingleCount(ConfigUtils.inheritOverwritableProperty(config.getSubSingleCount(), 1));
if (config.getSolverConfig().getClassLoader() == null) {
config.getSolverConfig().setClassLoader(classLoader);
var solverConfig = Objects.requireNonNullElseGet(config.getSolverConfig(), SolverConfig::new);
if (solverConfig.getClassLoader() == null) {
solverConfig.setClassLoader(classLoader);
}
if (config.getSolverConfig().getMonitoringConfig() != null &&
config.getSolverConfig().getMonitoringConfig().getSolverMetricList() != null &&
!config.getSolverConfig().getMonitoringConfig().getSolverMetricList().isEmpty()) {
throw new IllegalArgumentException(
"The solverBenchmarkConfig (" + config + ") has a " + SolverConfig.class.getSimpleName() +
" (" + config.getSolverConfig() + " ) with a non-empty " + MonitoringConfig.class.getSimpleName() +
" (" + config.getSolverConfig().getMonitoringConfig() + ").");
var monitoringConfig = solverConfig.getMonitoringConfig();
var monitoringSolverMetricList =
monitoringConfig == null ? Collections.<SolverMetric> emptyList() : monitoringConfig.getSolverMetricList();
if (monitoringConfig != null && monitoringSolverMetricList != null && !monitoringSolverMetricList.isEmpty()) {
throw new IllegalArgumentException("The solverBenchmarkConfig (%s) has a %s (%s) with a non-empty %s (%s)."
.formatted(config, SolverConfig.class.getSimpleName(), solverConfig, MonitoringConfig.class.getSimpleName(),
monitoringConfig));
}
List<SolverMetric> solverMetricList = getSolverMetrics(config.getProblemBenchmarksConfig());
solverBenchmarkResult.setSolverConfig(config.getSolverConfig()
.copyConfig().withMonitoringConfig(
new MonitoringConfig()
.withSolverMetricList(solverMetricList)));
DefaultSolverFactory<Solution_> defaultSolverFactory = new DefaultSolverFactory<>(config.getSolverConfig());
SolutionDescriptor<Solution_> solutionDescriptor = defaultSolverFactory.getSolutionDescriptor();
for (Solution_ extraProblem : extraProblems) {
var solverMetricList = getSolverMetrics(config.getProblemBenchmarksConfig());
solverBenchmarkResult.setSolverConfig(
solverConfig.copyConfig().withMonitoringConfig(new MonitoringConfig().withSolverMetricList(solverMetricList)));
var defaultSolverFactory = new DefaultSolverFactory<Solution_>(solverConfig);
var solutionDescriptor = defaultSolverFactory.getSolutionDescriptor();
for (var extraProblem : extraProblems) {
if (!solutionDescriptor.getSolutionClass().isInstance(extraProblem)) {
throw new IllegalArgumentException("The solverBenchmark name (" + config.getName()
+ ") for solution class (" + solutionDescriptor.getSolutionClass()
+ ") cannot solve a problem (" + extraProblem
+ ") of class (" + (extraProblem == null ? null : extraProblem.getClass()) + ").");
throw new IllegalArgumentException(
"The solverBenchmark name (%s) for solution class (%s) cannot solve a problem (%s) of class (%s)."
.formatted(config.getName(), solutionDescriptor.getSolutionClass(), extraProblem,
extraProblem == null ? null : extraProblem.getClass()));
}
}
solverBenchmarkResult.setScoreDefinition(solutionDescriptor.getScoreDefinition());
solverBenchmarkResult.setSingleBenchmarkResultList(new ArrayList<>());
ProblemBenchmarksConfig problemBenchmarksConfig_ =
config.getProblemBenchmarksConfig() == null ? new ProblemBenchmarksConfig()
: config.getProblemBenchmarksConfig();
var problemBenchmarksConfig =
Objects.requireNonNullElseGet(config.getProblemBenchmarksConfig(), ProblemBenchmarksConfig::new);
plannerBenchmark.getSolverBenchmarkResultList().add(solverBenchmarkResult);
ProblemBenchmarksFactory problemBenchmarksFactory = new ProblemBenchmarksFactory(problemBenchmarksConfig_);
var problemBenchmarksFactory = new ProblemBenchmarksFactory(problemBenchmarksConfig);
problemBenchmarksFactory.buildProblemBenchmarkList(solverBenchmarkResult, extraProblems);
}

protected void validate() {
if (!DefaultPlannerBenchmarkFactory.VALID_NAME_PATTERN.matcher(config.getName()).matches()) {
throw new IllegalStateException("The solverBenchmark name (" + config.getName()
+ ") is invalid because it does not follow the nameRegex ("
+ DefaultPlannerBenchmarkFactory.VALID_NAME_PATTERN.pattern() + ")" +
" which might cause an illegal filename.");
var configName = config.getName();
if (configName == null || !DefaultPlannerBenchmarkFactory.VALID_NAME_PATTERN.matcher(configName).matches()) {
throw new IllegalStateException(
"The solverBenchmark name (%s) is invalid because it does not follow the nameRegex (%s) which might cause an illegal filename."
.formatted(configName, DefaultPlannerBenchmarkFactory.VALID_NAME_PATTERN.pattern()));
}
if (!config.getName().trim().equals(config.getName())) {
throw new IllegalStateException("The solverBenchmark name (" + config.getName()
+ ") is invalid because it starts or ends with whitespace.");
if (!configName.trim().equals(configName)) {
throw new IllegalStateException(
"The solverBenchmark name (%s) is invalid because it starts or ends with whitespace."
.formatted(configName));
}
if (config.getSubSingleCount() != null && config.getSubSingleCount() < 1) {
throw new IllegalStateException("The solverBenchmark name (" + config.getName()
+ ") is invalid because the subSingleCount (" + config.getSubSingleCount() + ") must be greater than 1.");
var subSingleCount = config.getSubSingleCount();
if (subSingleCount != null && subSingleCount < 1) {
throw new IllegalStateException(
"The solverBenchmark name (%s) is invalid because the subSingleCount (%d) must be greater than 1."
.formatted(configName, subSingleCount));
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ public ResilientScoreComparator(ScoreDefinition aScoreDefinition) {
this.aScoreDefinition = aScoreDefinition;
}

@SuppressWarnings({ "rawtypes", "unchecked" })
@Override
public int compare(Score a, Score b) {
if (a == null) {
Expand All @@ -25,14 +26,16 @@ public int compare(Score a, Score b) {
}
if (!aScoreDefinition.isCompatibleArithmeticArgument(a) ||
!aScoreDefinition.isCompatibleArithmeticArgument(b)) {
Number[] aNumbers = a.toLevelNumbers();
Number[] bNumbers = b.toLevelNumbers();
for (int i = 0; i < aNumbers.length || i < bNumbers.length; i++) {
Number aToken = i < aNumbers.length ? aNumbers[i] : 0;
Number bToken = i < bNumbers.length ? bNumbers[i] : 0;
var aNumbers = a.toLevelNumbers();
var bNumbers = b.toLevelNumbers();
for (var i = 0; i < aNumbers.length || i < bNumbers.length; i++) {
var aToken = i < aNumbers.length ? aNumbers[i] : 0;
var bToken = i < bNumbers.length ? bNumbers[i] : 0;
int comparison;
if (aToken.getClass().equals(bToken.getClass())) {
comparison = ((Comparable) aToken).compareTo(bToken);
if (aToken.getClass().equals(bToken.getClass())
&& aToken instanceof Comparable aTokenComparable
&& bToken instanceof Comparable bTokenComparable) {
comparison = aTokenComparable.compareTo(bTokenComparable);
} else {
comparison = Double.compare(aToken.doubleValue(), bToken.doubleValue());
}
Expand Down
Loading
Loading