diff --git a/.gitignore b/.gitignore index 8ca894c..a4be9d1 100644 --- a/.gitignore +++ b/.gitignore @@ -34,3 +34,7 @@ out/ logs/ .java-version + + +### PVS-Studio ### +.PVS-Studio diff --git a/README.md b/README.md index 05c5815..3fe5028 100644 --- a/README.md +++ b/README.md @@ -70,6 +70,16 @@ Gradle configuration for spotbugs is located in [gradle/spotbugs.gradle](gradle/ Command: `gradle spotBugsMain` +### PVS-Studio +[PVS-Studio](https://www.viva64.com/en/pvs-studio/) is a promising static code analyzer. It can detect such problems as potential null object dereference, conditional expressions that are always true or false, unreachable code, infinite recursion, comparison of objects with incompatible types, and much more. In addition, the analyzer's strength is the search for copy-paste errors that are difficult to find during code review, for example, equivalent implementation of branches in an if-then-else statement or two completely different methods, comparing a variable with itself, etc. + +Gradle configuration for PVS-Studio is located in [gradle/pvsstudio.gradle](gradle/pvsstudio.gradle). + +Command: +`gradle pvsAnalyze` + +Output: +![PVS-Studio Report](results/pvsstudioReport.png) ## Practices diff --git a/build.gradle b/build.gradle index 2ef2a12..f90f999 100644 --- a/build.gradle +++ b/build.gradle @@ -19,7 +19,6 @@ repositories { dependencies { testImplementation 'org.junit.jupiter:junit-jupiter:5.6.0' testImplementation 'org.hamcrest:hamcrest-core:2.2' - } sourceSets { @@ -54,6 +53,7 @@ apply from: 'gradle/checkstyle.gradle' apply from: 'gradle/jacoco.gradle' apply from: 'gradle/pmd.gradle' apply from: 'gradle/spotbugs.gradle' +apply from: 'gradle/pvsstudio.gradle' integrationTest.dependsOn test jacocoTestCoverageVerification.dependsOn jacocoTestReport diff --git a/gradle/pvsstudio.gradle b/gradle/pvsstudio.gradle new file mode 100644 index 0000000..bb76efe --- /dev/null +++ b/gradle/pvsstudio.gradle @@ -0,0 +1,26 @@ +buildscript { + repositories { + mavenCentral() + maven { + url uri('http://files.viva64.com/java/pvsstudio-maven-repository/') + } + } + dependencies { + classpath group: 'com.pvsstudio', + name: 'pvsstudio-gradle-plugin', + version: '7.07.38241' + } +} + +apply plugin: com.pvsstudio.PvsStudioGradlePlugin +pvsstudio { + projectPath = "$projectDir" + + outputType = 'html' + outputFile = "${project.reportsDir}/pvsstudio/report.html" + + analyzeOnly = ["./src/main/java/com/qualitychecks/entity/RandomShapeFactory.java"] + + username = "PVS-Studio Free" + serialNumber ="FREE-FREE-FREE-FREE" +} \ No newline at end of file diff --git a/results/pvsstudioReport.png b/results/pvsstudioReport.png new file mode 100644 index 0000000..413d8d6 Binary files /dev/null and b/results/pvsstudioReport.png differ diff --git a/src/main/java/com/qualitychecks/entity/RandomShapeFactory.java b/src/main/java/com/qualitychecks/entity/RandomShapeFactory.java new file mode 100644 index 0000000..0281667 --- /dev/null +++ b/src/main/java/com/qualitychecks/entity/RandomShapeFactory.java @@ -0,0 +1,73 @@ +// This is an open source non-commercial project. Dear PVS-Studio, please check it. +// PVS-Studio Static Code Analyzer for C, C++, C#, and Java: http://www.viva64.com + +package com.qualitychecks.entity; + +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStreamReader; +import java.math.BigDecimal; +import java.util.*; +import java.util.function.Function; +import java.util.logging.Level; +import java.util.logging.LogManager; +import java.util.logging.Logger; + +public final class RandomShapeFactory { + public enum ShapeType { + Circle, Rectangle + } + + private static RandomShapeFactory factory = new RandomShapeFactory(); + private static Logger logger = LogManager.getLogManager().getLogger(RandomShapeFactory.class.getName()); + + private static final Map COLORS = new HashMap<>(); + + static { + COLORS.put("black", 0); + COLORS.put("red", 16711680); + COLORS.put("green", 65280); + COLORS.put("blue", 255); + COLORS.put("magenta", 16711935); + COLORS.put("blue", 16776960); + COLORS.put("cyan", 65535); + } + + private List values; + + private RandomShapeFactory() { + Function isNumeric = str -> str != null && str.matches("[-+]?\\d*\\.?\\d+"); + try { + BufferedReader reader = new BufferedReader(new InputStreamReader(getClass().getResourceAsStream("shapeFactoryValues"))); + for (String value : reader.readLine().split(" ")) { + if (isNumeric.apply(value)) { + values.add(value); + } else { + logger.warning(String.format("'%s' - invalid value", value)); + } + } + reader.close(); + } catch (IOException ex) { + // default values + values = Arrays.asList("1", "2", "3"); + logger.log(Level.SEVERE, ex.getMessage(), ex); + } + } + + public static RandomShapeFactory getInstance() { + return factory; + } + + public Shape getShapeRandomSize(final ShapeType type) { + switch (type) { + case Circle: + return new Circle(new BigDecimal(values.get(new Random().nextInt(values.size())))); + case Rectangle: + return new Rectangle(new BigDecimal(new Random().nextInt(values.size())), + new BigDecimal(new Random().nextInt(values.size()))); + /* other shapes*/ + default: + throw new IllegalArgumentException("Wrong shape type:" + type); + } + } +} diff --git a/src/main/resources/shapeFactoryValues b/src/main/resources/shapeFactoryValues new file mode 100644 index 0000000..ac5eb86 --- /dev/null +++ b/src/main/resources/shapeFactoryValues @@ -0,0 +1 @@ +1 3.2 5.7 9.6 4.5 9 \ No newline at end of file