google-site-verification: google61fe8ba583a51912.html
SonarJava Analyzer: Complete Static Code Analysis Guide

SonarJava is a static code analyzer for Java that helps maintain code quality, security, and maintainability. This guide demonstrates comprehensive integration and usage of SonarJava in Java projects.

Why Use SonarJava?

  • Code Quality: Detect bugs, vulnerabilities, and code smells
  • Security: Identify security vulnerabilities and hotspots
  • Maintainability: Measure technical debt and code complexity
  • Consistency: Enforce coding standards and best practices
  • Continuous Inspection: Integrate with CI/CD pipelines

Prerequisites

  • SonarQube server (local or cloud)
  • Java 8+ project
  • Maven/Gradle build tool
  • SonarJava plugin installed in SonarQube

Step 1: Project Dependencies and Configuration

Maven (pom.xml):

<properties> <sonar.host.url>http://localhost:9000</sonar.host.url> <sonar.login>${env.SONAR_TOKEN}</sonar.login> <sonar.projectKey>my-java-app</sonar.projectKey> <sonar.projectName>My Java Application</sonar.projectName> <sonar.projectVersion>1.0.0</sonar.projectVersion> <sonar.sources>src/main/java</sonar.sources> <sonar.tests>src/test/java</sonar.tests> <sonar.java.source>11</sonar.java.source> <sonar.java.target>11</sonar.java.target> <sonar.coverage.jacoco.xmlReportPaths>target/site/jacoco/jacoco.xml</sonar.coverage.jacoco.xmlReportPaths> <sonar.junit.reportPaths>target/surefire-reports</sonar.junit.reportPaths> </properties> <build> <plugins> <!-- SonarQube Maven Plugin --> <plugin> <groupId>org.sonarsource.scanner.maven</groupId> <artifactId>sonar-maven-plugin</artifactId> <version>3.9.1.2184</version> </plugin> <!-- JaCoCo for Code Coverage --> <plugin> <groupId>org.jacoco</groupId> <artifactId>jacoco-maven-plugin</artifactId> <version>0.8.8</version> <executions> <execution> <goals> <goal>prepare-agent</goal> </goals> </execution> <execution> <id>report</id> <phase>prepare-package</phase> <goals> <goal>report</goal> </goals> </execution> </executions> </plugin> <!-- Surefire for Test Reports --> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-surefire-plugin</artifactId> <version>3.0.0-M9</version> <configuration> <reportFormat>xml</reportFormat> <includes> <include>**/*Test.java</include> </includes> </configuration> </plugin> </plugins> </build>

Gradle (build.gradle):

plugins { id 'java' id 'jacoco' id 'org.sonarqube' version '4.0.0.2929' } sonarqube { properties { property 'sonar.host.url', 'http://localhost:9000' property 'sonar.login', System.getenv('SONAR_TOKEN') property 'sonar.projectKey', 'my-java-app' property 'sonar.projectName', 'My Java Application' property 'sonar.sources', 'src/main/java' property 'sonar.tests', 'src/test/java' property 'sonar.java.source', '11' property 'sonar.java.target', '11' property 'sonar.coverage.jacoco.xmlReportPaths', 'build/reports/jacoco/test/jacocoTestReport.xml' property 'sonar.junit.reportPaths', 'build/test-results/test' } } jacocoTestReport { reports { xml.required = true html.required = true } } test { useJUnitPlatform() testLogging { events 'passed', 'skipped', 'failed' } finalizedBy jacocoTestReport }

Step 2: SonarQube Quality Profile Configuration

sonar-project.properties:

# Project identification sonar.projectKey=my-java-app sonar.projectName=My Java Application sonar.projectVersion=1.0.0 # Source code configuration sonar.sources=src/main/java sonar.tests=src/test/java sonar.java.binaries=target/classes sonar.java.libraries=target/dependency/*.jar # Language and version sonar.language=java sonar.java.source=11 sonar.java.target=11 # Test and coverage sonar.coverage.exclusions=**/test/**,**/generated/**,**/model/**,**/dto/** sonar.junit.reportPaths=target/surefire-reports sonar.coverage.jacoco.xmlReportPaths=target/site/jacoco/jacoco.xml # Exclusions sonar.exclusions=**/generated/**,**/target/**,**/test/**,**/resources/** sonar.test.exclusions=**/test/resources/** # Quality Gate sonar.qualitygate.wait=true sonar.qualitygate.timeout=300 # Custom rules configuration sonar.java.spotbugs.effort=max sonar.java.spotbugs.threshold=high # Security hotspots sonar.security.config=sonar-security.xml # Duplication sonar.cpd.exclusions=**/test/**,**/generated/** sonar.cpd.minimumTokens=100

Step 3: Custom Quality Gates and Rules

sonar-quality-gate.json:

{ "name": "My Java Application Quality Gate", "conditions": [ { "metric": "new_bugs", "op": "GT", "error": "0", "warning": "0" }, { "metric": "new_vulnerabilities", "op": "GT", "error": "0", "warning": "0" }, { "metric": "new_security_hotspots", "op": "GT", "error": "0", "warning": "0" }, { "metric": "new_code_smells", "op": "GT", "error": "10", "warning": "5" }, { "metric": "coverage", "op": "LT", "error": "80", "warning": "85" }, { "metric": "duplicated_lines_density", "op": "GT", "error": "5", "warning": "3" }, { "metric": "maintainability_rating", "op": "GT", "error": "2", "warning": "1" }, { "metric": "reliability_rating", "op": "GT", "error": "2", "warning": "1" }, { "metric": "security_rating", "op": "GT", "error": "2", "warning": "1" } ] }

Step 4: Security Configuration

sonar-security.xml:

<?xml version="1.0" encoding="UTF-8"?> <sonar-security-config> <!-- SQL Injection --> <rule> <key>sql-injection</key> <parameters> <parameter> <name>sinks</name> <value>java.sql.Statement, java.sql.PreparedStatement</value> </parameter> </parameters> </rule> <!-- XSS Protection --> <rule> <key>xss</key> <parameters> <parameter> <name>sinks</name> <value>javax.servlet.http.HttpServletResponse</value> </parameter> </parameters> </rule> <!-- Input Validation --> <rule> <key>input-validation</key> <parameters> <parameter> <name>sources</name> <value>javax.servlet.http.HttpServletRequest</value> </parameter> </parameters> </rule> <!-- Cryptographic Weakness --> <rule> <key>crypto-weak</key> <parameters> <parameter> <name>weakAlgorithms</name> <value>MD5,SHA1,DES</value> </parameter> </parameters> </rule> </sonar-security-config>

Step 5: Code Analysis Service

@Service @Slf4j public class SonarAnalysisService { private final ObjectMapper objectMapper; private final RestTemplate restTemplate; public SonarAnalysisService(ObjectMapper objectMapper, RestTemplateBuilder restTemplateBuilder) { this.objectMapper = objectMapper; this.restTemplate = restTemplateBuilder.build(); } // Analyze code quality metrics public CodeQualityReport analyzeCodeQuality(String projectKey) { try { Map<String, Object> measures = getProjectMeasures(projectKey); List<Issue> issues = getProjectIssues(projectKey); CodeCoverage coverage = getCodeCoverage(projectKey); return CodeQualityReport.builder() .projectKey(projectKey) .timestamp(Instant.now()) .measures(measures) .issues(issues) .coverage(coverage) .qualityGateStatus(evaluateQualityGate(measures)) .build(); } catch (Exception e) { log.error("Failed to analyze code quality for project: {}", projectKey, e); throw new SonarAnalysisException("Code quality analysis failed", e); } } // Get security hotspots public List<SecurityHotspot> getSecurityHotspots(String projectKey) { try { String url = String.format("/api/hotspots/search?projectKey=%s", projectKey); Map<String, Object> response = restTemplate.getForObject(url, Map.class); return parseSecurityHotspots(response); } catch (Exception e) { log.error("Failed to get security hotspots for project: {}", projectKey, e); return Collections.emptyList(); } } // Analyze technical debt public TechnicalDebtReport analyzeTechnicalDebt(String projectKey) { try { Map<String, Object> measures = getProjectMeasures(projectKey); return TechnicalDebtReport.builder() .projectKey(projectKey) .totalDebtMinutes(getLongMeasure(measures, "sqale_index")) .debtRatio(getDoubleMeasure(measures, "sqale_debt_ratio")) .reliabilityRemediation(getLongMeasure(measures, "reliability_remediation_effort")) .securityRemediation(getLongMeasure(measures, "security_remediation_effort")) .maintainabilityRating(getIntMeasure(measures, "sqale_rating")) .build(); } catch (Exception e) { log.error("Failed to analyze technical debt for project: {}", projectKey, e); throw new SonarAnalysisException("Technical debt analysis failed", e); } } // Code smell analysis public CodeSmellReport analyzeCodeSmells(String projectKey) { try { List<Issue> issues = getProjectIssues(projectKey); Map<String, Long> smellsByType = issues.stream() .filter(issue -> "CODE_SMELL".equals(issue.getType())) .collect(Collectors.groupingBy( Issue::getSeverity, Collectors.counting() )); return CodeSmellReport.builder() .projectKey(projectKey) .totalCodeSmells(smellsByType.values().stream().mapToLong(Long::longValue).sum()) .blockerSmells(smellsByType.getOrDefault("BLOCKER", 0L)) .criticalSmells(smellsByType.getOrDefault("CRITICAL", 0L)) .majorSmells(smellsByType.getOrDefault("MAJOR", 0L)) .minorSmells(smellsByType.getOrDefault("MINOR", 0L)) .build(); } catch (Exception e) { log.error("Failed to analyze code smells for project: {}", projectKey, e); throw new SonarAnalysisException("Code smell analysis failed", e); } } private Map<String, Object> getProjectMeasures(String projectKey) { String url = String.format("/api/measures/component?component=%s&metricKeys=%s", projectKey, "bugs,vulnerabilities,code_smells,coverage,duplicated_lines_density"); return restTemplate.getForObject(url, Map.class); } private List<Issue> getProjectIssues(String projectKey) { String url = String.format("/api/issues/search?componentKeys=%s", projectKey); Map<String, Object> response = restTemplate.getForObject(url, Map.class); return parseIssues(response); } private CodeCoverage getCodeCoverage(String projectKey) { Map<String, Object> measures = getProjectMeasures(projectKey); return CodeCoverage.builder() .lineCoverage(getDoubleMeasure(measures, "coverage")) .branchCoverage(getDoubleMeasure(measures, "branch_coverage")) .linesToCover(getIntMeasure(measures, "lines_to_cover")) .uncoveredLines(getIntMeasure(measures, "uncovered_lines")) .build(); } private QualityGateStatus evaluateQualityGate(Map<String, Object> measures) { // Implementation to evaluate quality gate status return QualityGateStatus.PASSED; } private Double getDoubleMeasure(Map<String, Object> measures, String metric) { // Implementation to extract double measure return 0.0; } private Integer getIntMeasure(Map<String, Object> measures, String metric) { // Implementation to extract integer measure return 0; } private Long getLongMeasure(Map<String, Object> measures, String metric) { // Implementation to extract long measure return 0L; } private List<Issue> parseIssues(Map<String, Object> response) { // Implementation to parse issues from response return Collections.emptyList(); } private List<SecurityHotspot> parseSecurityHotspots(Map<String, Object> response) { // Implementation to parse security hotspots return Collections.emptyList(); } } // Data models for analysis results @Data @Builder @NoArgsConstructor @AllArgsConstructor class CodeQualityReport { private String projectKey; private Instant timestamp; private Map<String, Object> measures; private List<Issue> issues; private CodeCoverage coverage; private QualityGateStatus qualityGateStatus; private String summary; } @Data @Builder @NoArgsConstructor @AllArgsConstructor class TechnicalDebtReport { private String projectKey; private Long totalDebtMinutes; private Double debtRatio; private Long reliabilityRemediation; private Long securityRemediation; private Integer maintainabilityRating; private String assessment; } @Data @Builder @NoArgsConstructor @AllArgsConstructor class CodeSmellReport { private String projectKey; private Long totalCodeSmells; private Long blockerSmells; private Long criticalSmells; private Long majorSmells; private Long minorSmells; private List<String> topSmellTypes; } @Data @Builder @NoArgsConstructor @AllArgsConstructor class CodeCoverage { private Double lineCoverage; private Double branchCoverage; private Integer linesToCover; private Integer uncoveredLines; private Integer coveredLines; } @Data @NoArgsConstructor @AllArgsConstructor class Issue { private String key; private String type; private String severity; private String component; private String message; private Integer line; private String rule; private String status; private String resolution; } @Data @NoArgsConstructor @AllArgsConstructor class SecurityHotspot { private String key; private String component; private String securityCategory; private String vulnerabilityProbability; private String message; private Integer line; } enum QualityGateStatus { PASSED, FAILED, WARNING, NONE } class SonarAnalysisException extends RuntimeException { public SonarAnalysisException(String message) { super(message); } public SonarAnalysisException(String message, Throwable cause) { super(message, cause); } }

Step 6: Custom Rules and Quality Checks

@Component @Slf4j public class CustomQualityChecks { private final SonarAnalysisService analysisService; public CustomQualityChecks(SonarAnalysisService analysisService) { this.analysisService = analysisService; } // Check if project meets quality standards public QualityAssessment assessProjectQuality(String projectKey) { CodeQualityReport qualityReport = analysisService.analyzeCodeQuality(projectKey); TechnicalDebtReport debtReport = analysisService.analyzeTechnicalDebt(projectKey); CodeSmellReport smellReport = analysisService.analyzeCodeSmells(projectKey); List<SecurityHotspot> hotspots = analysisService.getSecurityHotspots(projectKey); return QualityAssessment.builder() .projectKey(projectKey) .timestamp(Instant.now()) .overallScore(calculateOverallScore(qualityReport, debtReport, smellReport)) .qualityGateStatus(qualityReport.getQualityGateStatus()) .securityScore(calculateSecurityScore(hotspots, qualityReport)) .maintainabilityScore(calculateMaintainabilityScore(debtReport, smellReport)) .reliabilityScore(calculateReliabilityScore(qualityReport)) .recommendations(generateRecommendations(qualityReport, debtReport, smellReport, hotspots)) .build(); } // Security compliance check public SecurityCompliance checkSecurityCompliance(String projectKey) { List<SecurityHotspot> hotspots = analysisService.getSecurityHotspots(projectKey); CodeQualityReport qualityReport = analysisService.analyzeCodeQuality(projectKey); long criticalVulnerabilities = qualityReport.getIssues().stream() .filter(issue -> "VULNERABILITY".equals(issue.getType()) && "CRITICAL".equals(issue.getSeverity())) .count(); long blockerVulnerabilities = qualityReport.getIssues().stream() .filter(issue -> "VULNERABILITY".equals(issue.getType()) && "BLOCKER".equals(issue.getSeverity())) .count(); return SecurityCompliance.builder() .projectKey(projectKey) .timestamp(Instant.now()) .totalSecurityHotspots((long) hotspots.size()) .criticalVulnerabilities(criticalVulnerabilities) .blockerVulnerabilities(blockerVulnerabilities) .complianceScore(calculateSecurityComplianceScore(hotspots, criticalVulnerabilities, blockerVulnerabilities)) .securityRating(determineSecurityRating(hotspots, criticalVulnerabilities, blockerVulnerabilities)) .build(); } // Code review automation public CodeReviewReport generateCodeReviewReport(String projectKey) { CodeQualityReport qualityReport = analysisService.analyzeCodeQuality(projectKey); CodeSmellReport smellReport = analysisService.analyzeCodeSmells(projectKey); List<ReviewComment> comments = generateReviewComments(qualityReport.getIssues()); return CodeReviewReport.builder() .projectKey(projectKey) .timestamp(Instant.now()) .totalComments(comments.size()) .criticalComments((int) comments.stream().filter(c -> "CRITICAL".equals(c.getSeverity())).count()) .majorComments((int) comments.stream().filter(c -> "MAJOR".equals(c.getSeverity())).count()) .minorComments((int) comments.stream().filter(c -> "MINOR".equals(c.getSeverity())).count()) .comments(comments) .overallAssessment(generateOverallAssessment(qualityReport, smellReport)) .build(); } // Technical debt analysis public DebtAnalysis analyzeTechnicalDebt(String projectKey) { TechnicalDebtReport debtReport = analysisService.analyzeTechnicalDebt(projectKey); CodeSmellReport smellReport = analysisService.analyzeCodeSmells(projectKey); return DebtAnalysis.builder() .projectKey(projectKey) .timestamp(Instant.now()) .totalTechnicalDebt(debtReport.getTotalDebtMinutes()) .debtBreakdown(calculateDebtBreakdown(debtReport, smellReport)) .remediationPlan(generateRemediationPlan(debtReport, smellReport)) .priorityAreas(identifyPriorityAreas(debtReport, smellReport)) .build(); } private double calculateOverallScore(CodeQualityReport quality, TechnicalDebtReport debt, CodeSmellReport smells) { // Implementation to calculate overall quality score return 0.0; } private double calculateSecurityScore(List<SecurityHotspot> hotspots, CodeQualityReport quality) { // Implementation to calculate security score return 0.0; } private double calculateMaintainabilityScore(TechnicalDebtReport debt, CodeSmellReport smells) { // Implementation to calculate maintainability score return 0.0; } private double calculateReliabilityScore(CodeQualityReport quality) { // Implementation to calculate reliability score return 0.0; } private double calculateSecurityComplianceScore(List<SecurityHotspot> hotspots, long criticalVulns, long blockerVulns) { // Implementation to calculate security compliance score return 0.0; } private String determineSecurityRating(List<SecurityHotspot> hotspots, long criticalVulns, long blockerVulns) { // Implementation to determine security rating return "UNKNOWN"; } private List<ReviewComment> generateReviewComments(List<Issue> issues) { // Implementation to generate review comments from issues return Collections.emptyList(); } private String generateOverallAssessment(CodeQualityReport quality, CodeSmellReport smells) { // Implementation to generate overall assessment return "UNKNOWN"; } private Map<String, Double> calculateDebtBreakdown(TechnicalDebtReport debt, CodeSmellReport smells) { // Implementation to calculate debt breakdown return Collections.emptyMap(); } private List<String> generateRemediationPlan(TechnicalDebtReport debt, CodeSmellReport smells) { // Implementation to generate remediation plan return Collections.emptyList(); } private List<String> identifyPriorityAreas(TechnicalDebtReport debt, CodeSmellReport smells) { // Implementation to identify priority areas return Collections.emptyList(); } private List<String> generateRecommendations(CodeQualityReport quality, TechnicalDebtReport debt, CodeSmellReport smells, List<SecurityHotspot> hotspots) { // Implementation to generate recommendations return Collections.emptyList(); } } @Data @Builder @NoArgsConstructor @AllArgsConstructor class QualityAssessment { private String projectKey; private Instant timestamp; private Double overallScore; private QualityGateStatus qualityGateStatus; private Double securityScore; private Double maintainabilityScore; private Double reliabilityScore; private List<String> recommendations; } @Data @Builder @NoArgsConstructor @AllArgsConstructor class SecurityCompliance { private String projectKey; private Instant timestamp; private Long totalSecurityHotspots; private Long criticalVulnerabilities; private Long blockerVulnerabilities; private Double complianceScore; private String securityRating; } @Data @Builder @NoArgsConstructor @AllArgsConstructor class CodeReviewReport { private String projectKey; private Instant timestamp; private Integer totalComments; private Integer criticalComments; private Integer majorComments; private Integer minorComments; private List<ReviewComment> comments; private String overallAssessment; } @Data @Builder @NoArgsConstructor @AllArgsConstructor class DebtAnalysis { private String projectKey; private Instant timestamp; private Long totalTechnicalDebt; private Map<String, Double> debtBreakdown; private List<String> remediationPlan; private List<String> priorityAreas; } @Data @NoArgsConstructor @AllArgsConstructor class ReviewComment { private String component; private Integer line; private String severity; private String message; private String rule; private String suggestion; }

Step 7: CI/CD Integration Service

@Service @Slf4j public class CiCdIntegrationService { private final SonarAnalysisService analysisService; private final CustomQualityChecks qualityChecks; public CiCdIntegrationService(SonarAnalysisService analysisService, CustomQualityChecks qualityChecks) { this.analysisService = analysisService; this.qualityChecks = qualityChecks; } // Pre-merge quality check public MergeQualityCheck checkMergeQuality(String projectKey, String branch) { CodeQualityReport qualityReport = analysisService.analyzeCodeQuality(projectKey); QualityAssessment assessment = qualityChecks.assessProjectQuality(projectKey); SecurityCompliance security = qualityChecks.checkSecurityCompliance(projectKey); boolean canMerge = evaluateMergeCriteria(qualityReport, assessment, security); return MergeQualityCheck.builder() .projectKey(projectKey) .branch(branch) .timestamp(Instant.now()) .canMerge(canMerge) .qualityGateStatus(qualityReport.getQualityGateStatus()) .qualityScore(assessment.getOverallScore()) .securityScore(security.getComplianceScore()) .blockingIssues(identifyBlockingIssues(qualityReport, security)) .warnings(identifyWarnings(qualityReport, assessment)) .recommendations(generateMergeRecommendations(qualityReport, assessment, security)) .build(); } // Release quality gate public ReleaseQualityCheck checkReleaseQuality(String projectKey, String version) { CodeQualityReport qualityReport = analysisService.analyzeCodeQuality(projectKey); QualityAssessment assessment = qualityChecks.assessProjectQuality(projectKey); SecurityCompliance security = qualityChecks.checkSecurityCompliance(projectKey); boolean canRelease = evaluateReleaseCriteria(qualityReport, assessment, security); return ReleaseQualityCheck.builder() .projectKey(projectKey) .version(version) .timestamp(Instant.now()) .canRelease(canRelease) .qualityGateStatus(qualityReport.getQualityGateStatus()) .codeCoverage(qualityReport.getCoverage().getLineCoverage()) .securityRating(security.getSecurityRating()) .technicalDebt(analysisService.analyzeTechnicalDebt(projectKey).getTotalDebtMinutes()) .blockingIssues(identifyReleaseBlockers(qualityReport, security)) .metrics(generateReleaseMetrics(qualityReport, assessment, security)) .build(); } // Quality trend analysis public QualityTrend analyzeQualityTrend(String projectKey, Duration period) { // Implementation to analyze quality trends over time return QualityTrend.builder() .projectKey(projectKey) .period(period) .trendData(collectTrendData(projectKey, period)) .build(); } // Generate quality report for stakeholders public StakeholderReport generateStakeholderReport(String projectKey) { CodeQualityReport qualityReport = analysisService.analyzeCodeQuality(projectKey); QualityAssessment assessment = qualityChecks.assessProjectQuality(projectKey); TechnicalDebtReport debtReport = analysisService.analyzeTechnicalDebt(projectKey); SecurityCompliance security = qualityChecks.checkSecurityCompliance(projectKey); return StakeholderReport.builder() .projectKey(projectKey) .timestamp(Instant.now()) .executiveSummary(generateExecutiveSummary(qualityReport, assessment, debtReport, security)) .keyMetrics(generateKeyMetrics(qualityReport, assessment, debtReport, security)) .riskAssessment(assessRisks(qualityReport, assessment, security)) .recommendations(generateStakeholderRecommendations(qualityReport, assessment, debtReport, security)) .build(); } private boolean evaluateMergeCriteria(CodeQualityReport quality, QualityAssessment assessment, SecurityCompliance security) { return quality.getQualityGateStatus() == QualityGateStatus.PASSED && assessment.getOverallScore() >= 80.0 && security.getComplianceScore() >= 90.0 && security.getCriticalVulnerabilities() == 0 && security.getBlockerVulnerabilities() == 0; } private boolean evaluateReleaseCriteria(CodeQualityReport quality, QualityAssessment assessment, SecurityCompliance security) { return quality.getQualityGateStatus() == QualityGateStatus.PASSED && assessment.getOverallScore() >= 85.0 && security.getComplianceScore() >= 95.0 && security.getCriticalVulnerabilities() == 0 && security.getBlockerVulnerabilities() == 0 && quality.getCoverage().getLineCoverage() >= 80.0; } private List<String> identifyBlockingIssues(CodeQualityReport quality, SecurityCompliance security) { List<String> blockers = new ArrayList<>(); if (security.getCriticalVulnerabilities() > 0) { blockers.add("Critical security vulnerabilities detected"); } if (security.getBlockerVulnerabilities() > 0) { blockers.add("Blocker security vulnerabilities detected"); } if (quality.getQualityGateStatus() == QualityGateStatus.FAILED) { blockers.add("Quality gate failed"); } return blockers; } private List<String> identifyWarnings(CodeQualityReport quality, QualityAssessment assessment) { List<String> warnings = new ArrayList<>(); if (assessment.getOverallScore() < 90.0) { warnings.add("Quality score below optimal level"); } if (quality.getCoverage().getLineCoverage() < 80.0) { warnings.add("Code coverage below target"); } return warnings; } private List<String> identifyReleaseBlockers(CodeQualityReport quality, SecurityCompliance security) { List<String> blockers = identifyBlockingIssues(quality, security); if (quality.getCoverage().getLineCoverage() < 80.0) { blockers.add("Insufficient code coverage for release"); } return blockers; } private Map<String, Object> generateReleaseMetrics(CodeQualityReport quality, QualityAssessment assessment, SecurityCompliance security) { Map<String, Object> metrics = new HashMap<>(); metrics.put("quality_score", assessment.getOverallScore()); metrics.put("security_score", security.getComplianceScore()); metrics.put("code_coverage", quality.getCoverage().getLineCoverage()); metrics.put("technical_debt_minutes", analysisService.analyzeTechnicalDebt(quality.getProjectKey()).getTotalDebtMinutes()); metrics.put("total_issues", quality.getIssues().size()); return metrics; } private Map<String, Object> collectTrendData(String projectKey, Duration period) { // Implementation to collect trend data return Collections.emptyMap(); } private String generateExecutiveSummary(CodeQualityReport quality, QualityAssessment assessment, TechnicalDebtReport debt, SecurityCompliance security) { // Implementation to generate executive summary return "Quality assessment summary"; } private Map<String, Object> generateKeyMetrics(CodeQualityReport quality, QualityAssessment assessment, TechnicalDebtReport debt, SecurityCompliance security) { // Implementation to generate key metrics return Collections.emptyMap(); } private String assessRisks(CodeQualityReport quality, QualityAssessment assessment, SecurityCompliance security) { // Implementation to assess risks return "Risk assessment"; } private List<String> generateMergeRecommendations(CodeQualityReport quality, QualityAssessment assessment, SecurityCompliance security) { // Implementation to generate merge recommendations return Collections.emptyList(); } private List<String> generateStakeholderRecommendations(CodeQualityReport quality, QualityAssessment assessment, TechnicalDebtReport debt, SecurityCompliance security) { // Implementation to generate stakeholder recommendations return Collections.emptyList(); } } @Data @Builder @NoArgsConstructor @AllArgsConstructor class MergeQualityCheck { private String projectKey; private String branch; private Instant timestamp; private Boolean canMerge; private QualityGateStatus qualityGateStatus; private Double qualityScore; private Double securityScore; private List<String> blockingIssues; private List<String> warnings; private List<String> recommendations; } @Data @Builder @NoArgsConstructor @AllArgsConstructor class ReleaseQualityCheck { private String projectKey; private String version; private Instant timestamp; private Boolean canRelease; private QualityGateStatus qualityGateStatus; private Double codeCoverage; private String securityRating; private Long technicalDebt; private List<String> blockingIssues; private Map<String, Object> metrics; } @Data @Builder @NoArgsConstructor @AllArgsConstructor class QualityTrend { private String projectKey; private Duration period; private Map<String, Object> trendData; } @Data @Builder @NoArgsConstructor @AllArgsConstructor class StakeholderReport { private String projectKey; private Instant timestamp; private String executiveSummary; private Map<String, Object> keyMetrics; private String riskAssessment; private List<String> recommendations; }

Step 8: Code Quality Best Practices Enforcement

```java
@Component
@Slf4j
public class CodeQualityEnforcer {

private final SonarAnalysisService analysisService; private final CustomQualityChecks qualityChecks; public CodeQualityEnforcer(SonarAnalysisService analysisService, CustomQualityChecks qualityChecks) { this.analysisService = analysisService; this.qualityChecks = qualityChecks; } // Enforce coding standards public ComplianceReport enforceCodingStandards(String projectKey) { CodeQualityReport qualityReport = analysisService.analyzeCodeQuality(projectKey); CodeSmellReport smellReport = analysisService.analyzeCodeSmells(projectKey); return ComplianceReport.builder() .projectKey(projectKey) .timestamp(Instant.now()) .standardsCompliance(evaluateStandardsCompliance(qualityReport, smellReport)) .violations(identifyStandardsViolations(qualityReport)) .improvementAreas(identifyImprovementAreas(qualityReport, smellReport)) .enforcementActions(generateEnforcementActions(qualityReport, smellReport)) .build(); } // Security standards enforcement public SecurityComplianceReport enforceSecurityStandards(String projectKey) { List<SecurityHotspot> hotspots = analysisService.getSecurityHotspots(projectKey); CodeQualityReport qualityReport = analysisService.analyzeCodeQuality(projectKey); return SecurityComplianceReport.builder() .projectKey(projectKey) .timestamp(Instant.now()) .securityStandardsCompliance(evaluateSecurityCompliance(hotspots, qualityReport)) .securityViolations(identifySecurityViolations(hotspots, qualityReport)) .remediationRequirements(generateSecurityRemediation(hotspots, qualityReport)) .build(); } // Performance standards enforcement public PerformanceComplianceReport enforcePerformanceStandards(String projectKey) { CodeQualityReport qualityReport = analysisService.analyzeCodeQuality(projectKey); return PerformanceComplianceReport.builder() .projectKey(projectKey) .timestamp(Instant.now()) .performanceMetrics(extractPerformanceMetrics(qualityReport)) .performanceIssues(identifyPerformanceIssues(qualityReport)) .optimizationRecommendations(generateOptimizationRecommendations(qualityReport)) .build(); } // Architecture compliance public ArchitectureComplianceReport enforceArchitectureStandards(String projectKey) { CodeQualityReport qualityReport = analysisService.analyzeCodeQuality(projectKey); return ArchitectureComplianceReport.builder() .projectKey(projectKey) .timestamp(Instant.now()) .architectureMetrics(extractArchitectureMetrics(qualityReport)) .architectureViolations(identifyArchitectureViolations(qualityReport)) .refactoringRecommendations(generateRefactoringRecommendations(qualityReport)) .build(); } private Map<String, Object> evaluateStandardsCompliance(CodeQualityReport quality, CodeSmellReport smells)

Leave a Reply

Your email address will not be published. Required fields are marked *


Macro Nepal Helper