├── tool_stop.sh ├── tool_compile.sh ├── tool_start.sh ├── tool_docker-logs.sh ├── tool_build.sh ├── tool_docker-clean.sh ├── tool_docker-init.sh ├── CODE_STYLE.md ├── RULES.md ├── tool_start_withtoken.sh ├── CONTRIBUTING.md ├── .gitignore ├── .default.docker.env ├── tool_release_1_prepare.sh ├── src ├── main │ ├── resources │ │ └── org │ │ │ └── greencodeinitiative │ │ │ └── creedengo │ │ │ └── java │ │ │ └── creedengo_way_profile.json │ └── java │ │ └── org │ │ └── greencodeinitiative │ │ └── creedengo │ │ └── java │ │ ├── JavaPlugin.java │ │ ├── utils │ │ ├── StringUtils.java │ │ └── PrinterVisitor.java │ │ ├── JavaCreedengoWayProfile.java │ │ ├── checks │ │ ├── InitializeBufferWithAppropriateSize.java │ │ ├── IncrementCheck.java │ │ ├── AvoidFullSQLRequest.java │ │ ├── UseOptionalOrElseGetVsOrElse.java │ │ ├── AvoidUsageOfStaticCollections.java │ │ ├── AvoidStatementForDMLQueries.java │ │ ├── AvoidRegexPatternNotStatic.java │ │ ├── FreeResourcesOfAutoCloseableInterface.java │ │ ├── AvoidSetConstantInBatchUpdate.java │ │ ├── OptimizeReadFileExceptions.java │ │ └── AvoidSQLRequestInLoop.java │ │ ├── JavaRulesDefinition.java │ │ └── JavaCheckRegistrar.java ├── it │ ├── test-projects │ │ └── creedengo-java-plugin-test-project │ │ │ ├── tool_send_to_sonar.sh │ │ │ ├── src │ │ │ └── main │ │ │ │ └── java │ │ │ │ └── org │ │ │ │ └── greencodeinitiative │ │ │ │ └── creedengo │ │ │ │ └── java │ │ │ │ └── checks │ │ │ │ ├── AvoidRegexPatternNotStaticValid2.java │ │ │ │ ├── AvoidRegexPatternNotStaticValid1.java │ │ │ │ ├── AvoidRegexPatternNotStatic.java │ │ │ │ ├── AvoidRegexPatternNotStaticValid3.java │ │ │ │ ├── AvoidGettingSizeCollectionInForLoopBad.java │ │ │ │ ├── AvoidUsageOfStaticCollectionsGoodWay.java │ │ │ │ ├── AvoidUsageOfStaticCollections.java │ │ │ │ ├── AvoidGettingSizeCollectionInWhileLoopBad.java │ │ │ │ ├── AvoidGettingSizeCollectionInForLoopIgnored.java │ │ │ │ ├── AvoidGettingSizeCollectionInForEachLoopIgnored.java │ │ │ │ ├── AvoidStatementForDMLQueries.java │ │ │ │ ├── AvoidGettingSizeCollectionInWhileLoopIgnored.java │ │ │ │ ├── AvoidGettingSizeCollectionInForLoopGood.java │ │ │ │ ├── AvoidGettingSizeCollectionInWhileLoopGood.java │ │ │ │ ├── OptimizeReadFileExceptionCheck4.java │ │ │ │ ├── OptimizeReadFileExceptionCheck5.java │ │ │ │ ├── OptimizeReadFileExceptionCheck3.java │ │ │ │ ├── OptimizeReadFileExceptionCheck.java │ │ │ │ ├── OptimizeReadFileExceptionCheck2.java │ │ │ │ ├── InitializeBufferWithAppropriateSize.java │ │ │ │ ├── AvoidMultipleIfElseStatementInterfaceNoIssue.java │ │ │ │ ├── AvoidFullSQLRequestCheck.java │ │ │ │ ├── AvoidMultipleIfElseStatementNoBlockNoIssue.java │ │ │ │ ├── ZzzDDCToCheckOptimizeSQLQueriesWithLimit.java │ │ │ │ ├── FreeResourcesOfAutoCloseableInterface.java │ │ │ │ ├── UseOptionalOrElseGetVsOrElse.java │ │ │ │ ├── IncrementCheck.java │ │ │ │ ├── AvoidMultipleIfElseStatementCompareMethodNoIssue.java │ │ │ │ └── AvoidSpringRepositoryCallInLoopCheck.java │ │ │ └── pom.xml │ └── java │ │ └── org │ │ └── greencodeinitiative │ │ └── creedengo │ │ └── java │ │ └── integration │ │ └── tests │ │ ├── profile │ │ ├── RuleMetadata.java │ │ └── ProfileMetadata.java │ │ └── GCIRulesBase.java └── test │ ├── files │ ├── AvoidGettingSizeCollectionInForLoopBad.java │ ├── AvoidMultipleIfElseStatementNotBlock.java │ ├── AvoidMultipleIfElseStatementInterface.java │ ├── AvoidRegexPatternNotStaticValid2.java │ ├── AvoidRegexPatternNotStaticValid1.java │ ├── AvoidRegexPatternNotStatic.java │ ├── AvoidRegexPatternNotStaticValid3.java │ ├── OptimizeReadFileExceptionCheck.java │ ├── OptimizeReadFileExceptionCheck4.java │ ├── OptimizeReadFileExceptionCheck5.java │ ├── OptimizeReadFileExceptionCheck3.java │ ├── OptimizeReadFileExceptionCheck2.java │ ├── AvoidStatementForDMLQueries.java │ ├── AvoidUsageOfStaticCollectionsGoodWay.java │ ├── AvoidUsageOfStaticCollections.java │ ├── UseOptionalOrElseGetVsOrElse.java │ ├── AvoidGettingSizeCollectionInForLoopIgnored.java │ ├── AvoidGettingSizeCollectionInWhileLoopBad.java │ ├── AvoidGettingSizeCollectionInWhileLoopIgnored.java │ ├── AvoidGettingSizeCollectionInForEachLoopIgnored.java │ ├── AvoidGettingSizeCollectionInForLoopGood.java │ ├── AvoidGettingSizeCollectionInWhileLoopGood.java │ ├── InitializeBufferWithAppropriateSize.java │ ├── FreeResourcesOfAutoCloseableInterface.java │ ├── AvoidFullSQLRequestCheck.java │ ├── AvoidSpringRepositoryCallInLoopCheck.java │ ├── AvoidMultipleIfElseStatementCompareMethod.java │ └── IncrementCheck.java │ └── java │ └── org │ └── greencodeinitiative │ └── creedengo │ └── java │ ├── checks │ ├── IncrementCheckTest.java │ ├── AvoidFullSQLRequestCheckTest.java │ ├── AvoidSQLRequestInLoopCheckTest.java │ ├── AvoidStatementForDMLQueriesTest.java │ ├── UseOptionalOrElseGetVsOrElseTest.java │ ├── ArrayCopyCheckTest.java │ ├── AvoidSetConstantInBatchInsertTest.java │ ├── NoFunctionCallWhenDeclaringForLoopTest.java │ ├── InitializeBufferWithAppropriateSizeTest.java │ ├── MakeNonReassignedVariablesConstantsTest.java │ ├── AvoidSpringRepositoryCallInLoopCheckTest.java │ ├── AvoidSpringRepositoryCallInStreamCheckTest.java │ ├── AvoidUsageOfStaticCollectionsTests.java │ ├── FreeResourcesOfAutoCloseableInterfaceTest.java │ ├── AvoidRegexPatternNotStaticTest.java │ ├── OptimizeReadFileExceptionCheckTest.java │ ├── AvoidMultipleIfElseStatementTest.java │ └── AvoidGettingSizeCollectionInLoopTest.java │ ├── JavaPluginTest.java │ ├── utils │ ├── StringUtilsTest.java │ └── FilesUtils.java │ ├── JavaCheckRegistrarTest.java │ ├── JavaCreedengoWayProfileTest.java │ └── JavaRulesDefinitionTest.java ├── .gitattributes ├── tool_release_2_branch.sh ├── .github ├── ISSUE_TEMPLATE │ ├── feature_request.md │ └── bug_report.md ├── workflows │ ├── stale_tag.yml │ ├── build.yml │ ├── build_container.yml │ ├── tag_release.yml │ └── _BACKUP_manual_release.yml └── dependabot.yml ├── _TODOs_DDC.md ├── INSTALL.md ├── .mvn └── wrapper │ └── maven-wrapper.properties ├── docker-compose.yml ├── downloads-sonarsource.crt ├── Dockerfile └── README.md /tool_stop.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env sh 2 | 3 | docker-compose stop 4 | -------------------------------------------------------------------------------- /tool_compile.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env sh 2 | 3 | ./mvnw clean compile 4 | -------------------------------------------------------------------------------- /tool_start.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env sh 2 | 3 | docker-compose start 4 | -------------------------------------------------------------------------------- /tool_docker-logs.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env sh 2 | 3 | docker-compose logs -f 4 | -------------------------------------------------------------------------------- /tool_build.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env sh 2 | 3 | ./mvnw clean package -DskipTests 4 | -------------------------------------------------------------------------------- /tool_docker-clean.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env sh 2 | 3 | docker-compose down --volumes 4 | -------------------------------------------------------------------------------- /tool_docker-init.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env sh 2 | 3 | docker-compose up --build -d 4 | -------------------------------------------------------------------------------- /CODE_STYLE.md: -------------------------------------------------------------------------------- 1 | Please read common [CODE_STYLE.md](https://github.com/green-code-initiative/creedengo-common/blob/main/doc/CODE_STYLE.md) in `creedengo-common` repository. 2 | -------------------------------------------------------------------------------- /RULES.md: -------------------------------------------------------------------------------- 1 | Please read [RULES.md](https://github.com/green-code-initiative/creedengo-rules-specifications/blob/main/RULES.md) in `creedengo-rules-specifications` repository. 2 | -------------------------------------------------------------------------------- /tool_start_withtoken.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env sh 2 | 3 | # private TOKEN to change once generated in your local SonarQube 4 | TOKEN=MY_TOKEN_TO_REPLACE docker-compose up --build -d 5 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | Please read common [CONTRIBUTING.md](https://github.com/green-code-initiative/creedengo-common/blob/main/doc/CONTRIBUTING.md) in `creedengo-common` repository. 2 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Ignore all files and folders starting with ".", except a few exceptions 2 | .* 3 | !.mvn/ 4 | !.gitignore 5 | !.gitattributes 6 | !.github/ 7 | !.default.docker.env 8 | 9 | # Ignore generated files 10 | target 11 | bin 12 | dependency-reduced-pom.xml 13 | 14 | # Ignore IDE files 15 | *.iml 16 | -------------------------------------------------------------------------------- /.default.docker.env: -------------------------------------------------------------------------------- 1 | # Set default Sonarqube environment variables used by docker-compose 2 | # You can override these envvars by creating a '.override.docker.env' file 3 | # For available envvars list, see https://docs.sonarsource.com/sonarqube/latest/setup-and-upgrade/configure-and-operate-a-server/environment-variables/ 4 | 5 | SONAR_LOG_LEVEL_WEB=INFO 6 | -------------------------------------------------------------------------------- /tool_release_1_prepare.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env sh 2 | 3 | ### 4 | # PURPOSE : use maven plugin release to prepare locally next release and next SNAPSHOT 5 | ### 6 | 7 | # creation of 2 commits with release and next SNAPSHOT 8 | ./mvnw release:prepare -B -ff -DpushChanges=false -DtagNameFormat=@{project.version} 9 | 10 | sleep 2 11 | 12 | # clean temporary files 13 | ./mvnw release:clean 14 | -------------------------------------------------------------------------------- /src/main/resources/org/greencodeinitiative/creedengo/java/creedengo_way_profile.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "creedengo way", 3 | "language": "java", 4 | "ruleKeys": [ 5 | "GCI1", 6 | "GCI2", 7 | "GCI3", 8 | "GCI5", 9 | "GCI27", 10 | "GCI28", 11 | "GCI32", 12 | "GCI67", 13 | "GCI69", 14 | "GCI72", 15 | "GCI74", 16 | "GCI76", 17 | "GCI77", 18 | "GCI78", 19 | "GCI79", 20 | "GCI82", 21 | "GCI94" 22 | ] 23 | } 24 | -------------------------------------------------------------------------------- /src/it/test-projects/creedengo-java-plugin-test-project/tool_send_to_sonar.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env sh 2 | 3 | # "sonar.login" kept only for SONARQUBE < 10 4 | 5 | # mvn org.sonarsource.scanner.maven:sonar-maven-plugin:3.11.0.3922:sonar -Dsonar.host.url=http://localhost:$1 -Dsonar.login=$2 -Dsonar.token=$2 6 | mvn org.sonarsource.scanner.maven:sonar-maven-plugin:4.0.0.4121:sonar -Dsonar.host.url=http://localhost:$1 -Dsonar.login=$2 -Dsonar.token=$2 7 | -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | # Ensure all SH files are checked out with LF line endings (regardless of the 2 | # OS they were checked out on). 3 | *.sh text eol=lf 4 | 5 | # Ensure BAT files will always be checked out with CRLFs (regardless of the 6 | # OS they were checked out on). 7 | *.bat text eol=crlf 8 | 9 | # Ensure BAT files will always be checked out with CRLFs (regardless of the 10 | # OS they were checked out on). 11 | *.cmd text eol=crlf 12 | -------------------------------------------------------------------------------- /src/it/test-projects/creedengo-java-plugin-test-project/src/main/java/org/greencodeinitiative/creedengo/java/checks/AvoidRegexPatternNotStaticValid2.java: -------------------------------------------------------------------------------- 1 | package org.greencodeinitiative.creedengo.java.checks; 2 | 3 | import java.util.regex.Pattern; 4 | 5 | public class AvoidRegexPatternNotStaticValid2 { 6 | 7 | private final Pattern pattern = Pattern.compile("foo"); // Compliant 8 | 9 | public boolean foo() { 10 | return pattern.matcher("foo").find(); 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /src/it/test-projects/creedengo-java-plugin-test-project/src/main/java/org/greencodeinitiative/creedengo/java/checks/AvoidRegexPatternNotStaticValid1.java: -------------------------------------------------------------------------------- 1 | package org.greencodeinitiative.creedengo.java.checks; 2 | 3 | import java.util.regex.Pattern; 4 | 5 | public class AvoidRegexPatternNotStaticValid1 { 6 | 7 | private static final Pattern pattern = Pattern.compile("foo"); // Compliant 8 | 9 | public boolean foo() { 10 | return pattern.matcher("foo").find(); 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /tool_release_2_branch.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env sh 2 | 3 | ### 4 | # PURPOSE : create an push an new branch with commits previously prepared with `tool_release_1_prepare.sh` 5 | ### 6 | 7 | # checkout released tag and creation of branch to push (becasue of main protection) 8 | LAST_TAG=$(git tag --sort=-version:refname | head -n 1) 9 | BRANCH_NAME=$(echo "release_${LAST_TAG}") 10 | git checkout -b ${BRANCH_NAME} 11 | 12 | # push branch associated to new tag release 13 | git push --set-upstream origin ${BRANCH_NAME} 14 | -------------------------------------------------------------------------------- /src/it/test-projects/creedengo-java-plugin-test-project/src/main/java/org/greencodeinitiative/creedengo/java/checks/AvoidRegexPatternNotStatic.java: -------------------------------------------------------------------------------- 1 | package org.greencodeinitiative.creedengo.java.checks; 2 | 3 | import java.util.regex.Pattern; 4 | 5 | public class AvoidRegexPatternNotStatic { 6 | 7 | public boolean foo() { 8 | final Pattern pattern = Pattern.compile("foo"); // Noncompliant {{Avoid using Pattern.compile() in a non-static context.}} 9 | return pattern.matcher("foo").find(); 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /src/it/test-projects/creedengo-java-plugin-test-project/src/main/java/org/greencodeinitiative/creedengo/java/checks/AvoidRegexPatternNotStaticValid3.java: -------------------------------------------------------------------------------- 1 | package org.greencodeinitiative.creedengo.java.checks; 2 | 3 | import java.util.regex.Pattern; 4 | 5 | public class AvoidRegexPatternNotStaticValid3 { 6 | 7 | private final Pattern pattern; 8 | 9 | public AvoidRegexPatternNotStaticValid3() { 10 | pattern = Pattern.compile("foo"); // Compliant 11 | } 12 | 13 | public boolean foo() { 14 | return pattern.matcher("foo").find(); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /src/test/files/AvoidGettingSizeCollectionInForLoopBad.java: -------------------------------------------------------------------------------- 1 | package org.greencodeinitiative.creedengo.java.checks; 2 | 3 | import java.util.ArrayList; 4 | import java.util.List; 5 | 6 | class AvoidGettingSizeCollectionInForLoopBad { 7 | 8 | public void badForLoop() { 9 | final List numberList = new ArrayList(); 10 | numberList.add(10); 11 | numberList.add(20); 12 | 13 | for (int i = 0; i < numberList.size(); ++i) { // Noncompliant {{Avoid getting the size of the collection in the loop}} 14 | System.out.println("numberList.size()"); 15 | } 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /src/it/test-projects/creedengo-java-plugin-test-project/src/main/java/org/greencodeinitiative/creedengo/java/checks/AvoidGettingSizeCollectionInForLoopBad.java: -------------------------------------------------------------------------------- 1 | package org.greencodeinitiative.creedengo.java.checks; 2 | 3 | import java.util.ArrayList; 4 | import java.util.List; 5 | 6 | class AvoidGettingSizeCollectionInForLoopBad { 7 | 8 | public void badForLoop() { 9 | final List numberList = new ArrayList(); 10 | numberList.add(10); 11 | numberList.add(20); 12 | 13 | for (int i = 0; i < numberList.size(); ++i) { // Noncompliant 14 | System.out.println("numberList.size()"); 15 | } 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/feature_request.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Feature request 3 | about: Suggest an idea for this project 4 | title: '' 5 | labels: '' 6 | assignees: '' 7 | 8 | --- 9 | 10 | **Is your feature request related to a problem? Please describe.** 11 | A clear and concise description of what the problem is. Ex. I'm always frustrated when [...] 12 | 13 | **Describe the solution you'd like** 14 | A clear and concise description of what you want to happen. 15 | 16 | **Describe alternatives you've considered** 17 | A clear and concise description of any alternative solutions or features you've considered. 18 | 19 | **Additional context** 20 | Add any other context or screenshots about the feature request here. 21 | -------------------------------------------------------------------------------- /_TODOs_DDC.md: -------------------------------------------------------------------------------- 1 | # IDEAS 2 | 3 | .. to tranform into issues ? 4 | 5 | - [IN PROGRESS] check `pom.xml` dependencies (usefulness, scope, versions) 6 | - [DONE] first clean, check scopes, factorization 7 | - check usefulness 8 | - upgrade versions 9 | - enable github `dependabot` to create automatically PR with version upgrades of dependencides (when all dependencies will be ok) 10 | - ménage dans les branches de dev (local et remote) 11 | - docker-compose : ":9000" (génération port aléatoire pour l'IHM + repérage pour IHM) au lieu de "9000:9000" si erreur lors du démarrage "Error response from daemon: Ports are not available: exposing port TCP 0.0.0.0:9000 -> 0.0.0.0:0: listen tcp 0.0.0.0:9000: bind: address already in use" -------------------------------------------------------------------------------- /src/it/test-projects/creedengo-java-plugin-test-project/src/main/java/org/greencodeinitiative/creedengo/java/checks/AvoidUsageOfStaticCollectionsGoodWay.java: -------------------------------------------------------------------------------- 1 | package org.greencodeinitiative.creedengo.java.checks; 2 | 3 | import java.util.*; 4 | 5 | /** 6 | * Compliant 7 | */ 8 | public class AvoidUsageOfStaticCollectionsGoodWay { 9 | public static volatile AvoidUsageOfStaticCollectionsGoodWay INSTANCE = new AvoidUsageOfStaticCollectionsGoodWay(); 10 | 11 | public final List LIST = new ArrayList(); // Compliant 12 | public final Set SET = new HashSet(); // Compliant 13 | public final Map MAP = new HashMap(); // Compliant 14 | 15 | private AvoidUsageOfStaticCollectionsGoodWay() { 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /src/it/test-projects/creedengo-java-plugin-test-project/src/main/java/org/greencodeinitiative/creedengo/java/checks/AvoidUsageOfStaticCollections.java: -------------------------------------------------------------------------------- 1 | package org.greencodeinitiative.creedengo.java.checks; 2 | 3 | import java.util.*; 4 | 5 | /** 6 | * Not compliant 7 | */ 8 | public class AvoidUsageOfStaticCollections { 9 | 10 | public static final List LIST = new ArrayList(); // Noncompliant {{Avoid usage of static collections.}} 11 | 12 | public static final Set SET = new HashSet(); // Noncompliant {{Avoid usage of static collections.}} 13 | 14 | public static final Map MAP = new HashMap(); // Noncompliant {{Avoid usage of static collections.}} 15 | 16 | public AvoidUsageOfStaticCollections() { 17 | } 18 | 19 | } 20 | -------------------------------------------------------------------------------- /INSTALL.md: -------------------------------------------------------------------------------- 1 | Common installation notes / requirements 2 | ======================================== 3 | 4 | Please read common [INSTALL.md](https://github.com/green-code-initiative/creedengo-common/blob/main/doc/INSTALL.md) 5 | in `creedengo-common` repository. Please follow the specific guides below for additional information on installing the 6 | desired plugins. 7 | 8 | Special points for Standard plugins 9 | ================================= 10 | 11 | Project structure 12 | ----------------- 13 | 14 | Here is a preview of project tree : 15 | 16 | ```txt 17 | creedengo-java # Root directory 18 | | 19 | +--src # source directory 20 | | 21 | \--docker-compose.yml # Docker compose file 22 | ``` 23 | 24 | You will find more information about the plugins’ architecture in their folders 25 | -------------------------------------------------------------------------------- /src/it/test-projects/creedengo-java-plugin-test-project/src/main/java/org/greencodeinitiative/creedengo/java/checks/AvoidGettingSizeCollectionInWhileLoopBad.java: -------------------------------------------------------------------------------- 1 | package org.greencodeinitiative.creedengo.java.checks; 2 | 3 | import java.util.ArrayList; 4 | import java.util.List; 5 | 6 | class AvoidGettingSizeCollectionInWhileLoopBad { 7 | AvoidGettingSizeCollectionInWhileLoopBad() { 8 | 9 | } 10 | 11 | public void badWhileLoop() { 12 | List numberList = new ArrayList(); 13 | numberList.add(10); 14 | numberList.add(20); 15 | 16 | int i = 0; 17 | while (i < numberList.size()) { // Noncompliant {{Avoid getting the size of the collection in the loop}} 18 | System.out.println("numberList.size()"); 19 | i++; 20 | } 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /src/it/test-projects/creedengo-java-plugin-test-project/src/main/java/org/greencodeinitiative/creedengo/java/checks/AvoidGettingSizeCollectionInForLoopIgnored.java: -------------------------------------------------------------------------------- 1 | package org.greencodeinitiative.creedengo.java.checks; 2 | 3 | import java.util.ArrayList; 4 | import java.util.Iterator; 5 | import java.util.List; 6 | 7 | class AvoidGettingSizeCollectionInForLoopIgnored { 8 | AvoidGettingSizeCollectionInForLoopIgnored() { 9 | 10 | } 11 | 12 | public void badForLoop() { 13 | final List numberList = new ArrayList(); 14 | numberList.add(10); 15 | numberList.add(20); 16 | 17 | final Iterator it = numberList.iterator(); 18 | for (; it.hasNext(); ) { // Ignored => compliant 19 | System.out.println(it.next()); 20 | } 21 | } 22 | 23 | 24 | } 25 | -------------------------------------------------------------------------------- /src/it/test-projects/creedengo-java-plugin-test-project/src/main/java/org/greencodeinitiative/creedengo/java/checks/AvoidGettingSizeCollectionInForEachLoopIgnored.java: -------------------------------------------------------------------------------- 1 | package org.greencodeinitiative.creedengo.java.checks; 2 | 3 | import java.util.ArrayList; 4 | import java.util.List; 5 | 6 | class AvoidGettingSizeCollectionInForEachLoopIgnored { 7 | AvoidGettingSizeCollectionInForEachLoopIgnored(AvoidGettingSizeCollectionInForEachLoopIgnored obj) { 8 | 9 | } 10 | 11 | public void ignoredLoop() { 12 | List numberList = new ArrayList(); 13 | numberList.add(10); 14 | numberList.add(20); 15 | 16 | for (Integer i : numberList) { // Ignored 17 | int size = numberList.size(); // Compliant with this rule 18 | System.out.println("numberList.size()"); 19 | } 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /src/it/test-projects/creedengo-java-plugin-test-project/src/main/java/org/greencodeinitiative/creedengo/java/checks/AvoidStatementForDMLQueries.java: -------------------------------------------------------------------------------- 1 | package org.greencodeinitiative.creedengo.java.checks; 2 | 3 | import java.sql.Connection; 4 | import java.sql.DriverManager; 5 | import java.sql.*; 6 | import java.sql.PreparedStatement; 7 | 8 | import javax.sql.DataSource; 9 | 10 | 11 | class AvoidStatementForDMLQueries { 12 | AvoidStatementForDMLQueries(AvoidStatementForDMLQueries mc) { 13 | } 14 | 15 | public void insert() throws SQLException { 16 | Connection connection = DriverManager.getConnection("URL"); 17 | Statement statement = connection.createStatement(); 18 | statement.executeUpdate("INSERT INTO persons(id, name) VALUES(2, 'Toto')"); // Noncompliant {{You must not use Statement for a DML query}} 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/bug_report.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Bug report 3 | about: Create a report to help us improve 4 | title: '' 5 | labels: bug 6 | assignees: '' 7 | 8 | --- 9 | 10 | **Describe the bug** 11 | A clear and concise description of what the bug is. 12 | 13 | **To Reproduce** 14 | Steps to reproduce the behavior: 15 | 16 | 1. Go to '...' 17 | 2. Click on '....' 18 | 3. Scroll down to '....' 19 | 4. See error 20 | 21 | **Expected behavior** 22 | A clear and concise description of what you expected to happen. 23 | 24 | **Screenshots** 25 | If applicable, add screenshots to help explain your problem. 26 | 27 | **Software Versions** 28 | 29 | - SonarQube Version: [e.g. Version 7.8 (build 26217)] 30 | - Plugin Version: [e.g. 1.1.0, or custom build from master at commit 004AD34FAA] 31 | 32 | **Additional context** 33 | Add any other context about the problem here. 34 | -------------------------------------------------------------------------------- /src/it/test-projects/creedengo-java-plugin-test-project/src/main/java/org/greencodeinitiative/creedengo/java/checks/AvoidGettingSizeCollectionInWhileLoopIgnored.java: -------------------------------------------------------------------------------- 1 | package org.greencodeinitiative.creedengo.java.checks; 2 | 3 | import java.util.ArrayList; 4 | import java.util.Iterator; 5 | import java.util.List; 6 | 7 | class AvoidGettingSizeCollectionInWhileLoopIgnored { 8 | AvoidGettingSizeCollectionInWhileLoopIgnored() { 9 | 10 | } 11 | 12 | public void badWhileLoop() { 13 | List numberList = new ArrayList(); 14 | numberList.add(10); 15 | numberList.add(20); 16 | 17 | Iterator it = numberList.iterator(); 18 | int i = 0; 19 | while (it.hasNext()) { // Ignored => compliant 20 | it.next(); 21 | System.out.println("numberList.size()"); 22 | } 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /.github/workflows/stale_tag.yml: -------------------------------------------------------------------------------- 1 | name: "Label stale PRs" 2 | on: 3 | schedule: 4 | - cron: "30 1 * * *" 5 | workflow_dispatch: 6 | 7 | jobs: 8 | stale: 9 | runs-on: ubuntu-latest 10 | steps: 11 | - uses: actions/stale@v8.0.0 12 | with: 13 | repo-token: ${{ secrets.GITHUB_TOKEN }} 14 | days-before-issue-stale: -1 # We don't want to address issues 15 | days-before-pr-stale: 30 16 | days-before-issue-close: -1 # We don't want to close issues in this action 17 | days-before-pr-close: -1 # We don't want to close PR in this action 18 | stale-pr-label: stale 19 | stale-pr-message: | 20 | This PR has been automatically marked as stale because it has no activity for 30 days. 21 | Please add a comment if you want to keep the issue open. Thank you for your contributions! -------------------------------------------------------------------------------- /src/it/test-projects/creedengo-java-plugin-test-project/src/main/java/org/greencodeinitiative/creedengo/java/checks/AvoidGettingSizeCollectionInForLoopGood.java: -------------------------------------------------------------------------------- 1 | package org.greencodeinitiative.creedengo.java.checks; 2 | 3 | import java.util.Collection; 4 | import java.util.ArrayList; 5 | import java.util.List; 6 | 7 | class AvoidGettingSizeCollectionInForLoopGood { 8 | AvoidGettingSizeCollectionInForLoopGood(AvoidGettingSizeCollectionInForLoopGood obj) { 9 | 10 | } 11 | 12 | public void goodForLoop() { 13 | List numberList = new ArrayList(); 14 | numberList.add(10); 15 | numberList.add(20); 16 | 17 | int size = numberList.size(); 18 | for (int i = 0; i < size; i++) { // Compliant 19 | System.out.println("numberList.size()"); 20 | int size2 = numberList.size(); // Compliant with this rule 21 | } 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /src/it/test-projects/creedengo-java-plugin-test-project/src/main/java/org/greencodeinitiative/creedengo/java/checks/AvoidGettingSizeCollectionInWhileLoopGood.java: -------------------------------------------------------------------------------- 1 | package org.greencodeinitiative.creedengo.java.checks; 2 | 3 | import java.util.ArrayList; 4 | import java.util.List; 5 | 6 | class AvoidGettingSizeCollectionInWhileLoopGood { 7 | AvoidGettingSizeCollectionInWhileLoopGood(AvoidGettingSizeCollectionInWhileLoopGood obj) { 8 | 9 | } 10 | 11 | public void goodWhileLoop() { 12 | List numberList = new ArrayList(); 13 | numberList.add(10); 14 | numberList.add(20); 15 | 16 | int size = numberList.size(); 17 | int i = 0; 18 | while (i < size) { // Compliant 19 | System.out.println("numberList.size()"); 20 | int size2 = numberList.size(); // Compliant with this rule 21 | i++; 22 | } 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /src/it/test-projects/creedengo-java-plugin-test-project/src/main/java/org/greencodeinitiative/creedengo/java/checks/OptimizeReadFileExceptionCheck4.java: -------------------------------------------------------------------------------- 1 | package org.greencodeinitiative.creedengo.java.checks; 2 | 3 | import java.io.FileInputStream; 4 | import java.io.InputStream; 5 | import java.util.Arrays; 6 | import java.util.List; 7 | import java.util.logging.Logger; 8 | 9 | class OptimizeReadFileExceptionCheck4 { 10 | 11 | Logger logger = Logger.getLogger(""); 12 | 13 | OptimizeReadFileExceptionCheck4(OptimizeReadFileExceptionCheck4 readFile) { 14 | } 15 | 16 | public void readPreferences(String filename) { 17 | //... 18 | try (InputStream in = new FileInputStream(filename)) { // Noncompliant {{Optimize Read File Exceptions}} 19 | logger.info("my log"); 20 | } catch (Exception e) { 21 | logger.info(e.getMessage()); 22 | } 23 | //... 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /src/it/test-projects/creedengo-java-plugin-test-project/src/main/java/org/greencodeinitiative/creedengo/java/checks/OptimizeReadFileExceptionCheck5.java: -------------------------------------------------------------------------------- 1 | package org.greencodeinitiative.creedengo.java.checks; 2 | 3 | import java.io.FileInputStream; 4 | import java.io.InputStream; 5 | import java.util.Arrays; 6 | import java.util.List; 7 | import java.util.logging.Logger; 8 | 9 | class OptimizeReadFileExceptionCheck5 { 10 | 11 | Logger logger = Logger.getLogger(""); 12 | 13 | OptimizeReadFileExceptionCheck5(OptimizeReadFileExceptionCheck5 readFile) { 14 | } 15 | 16 | public void readPreferences(String filename) { 17 | //... 18 | try (InputStream in = new FileInputStream(filename)) { // Noncompliant {{Optimize Read File Exceptions}} 19 | logger.info("my log"); 20 | } catch (Throwable e) { 21 | logger.info(e.getMessage()); 22 | } 23 | //... 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /src/it/test-projects/creedengo-java-plugin-test-project/src/main/java/org/greencodeinitiative/creedengo/java/checks/OptimizeReadFileExceptionCheck3.java: -------------------------------------------------------------------------------- 1 | package org.greencodeinitiative.creedengo.java.checks; 2 | 3 | import java.io.FileInputStream; 4 | import java.io.IOException; 5 | import java.io.InputStream; 6 | import java.util.Arrays; 7 | import java.util.List; 8 | import java.util.logging.Logger; 9 | 10 | class OptimizeReadFileExceptionCheck3 { 11 | 12 | Logger logger = Logger.getLogger(""); 13 | 14 | OptimizeReadFileExceptionCheck3(OptimizeReadFileExceptionCheck3 readFile) { 15 | } 16 | 17 | public void readPreferences(String filename) { 18 | //... 19 | try (InputStream in = new FileInputStream(filename)) { // Noncompliant {{Optimize Read File Exceptions}} 20 | logger.info("my log"); 21 | } catch (IOException e) { 22 | logger.info(e.getMessage()); 23 | } 24 | //... 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /src/it/test-projects/creedengo-java-plugin-test-project/src/main/java/org/greencodeinitiative/creedengo/java/checks/OptimizeReadFileExceptionCheck.java: -------------------------------------------------------------------------------- 1 | package org.greencodeinitiative.creedengo.java.checks; 2 | 3 | import java.io.FileInputStream; 4 | import java.io.FileNotFoundException; 5 | import java.io.InputStream; 6 | import java.util.Arrays; 7 | import java.util.List; 8 | import java.util.logging.Logger; 9 | 10 | import static java.lang.System.Logger.Level.ERROR; 11 | 12 | class OptimizeReadFileExceptionCheck { 13 | 14 | Logger logger = Logger.getLogger(""); 15 | 16 | OptimizeReadFileExceptionCheck(OptimizeReadFileExceptionCheck readFile) { 17 | } 18 | 19 | public void readPreferences(String filename) { 20 | //... 21 | InputStream in = null; 22 | try { 23 | in = new FileInputStream(filename); // Noncompliant {{Optimize Read File Exceptions}} 24 | } catch (FileNotFoundException e) { 25 | logger.info(e.getMessage()); 26 | } 27 | //... 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /.github/dependabot.yml: -------------------------------------------------------------------------------- 1 | # To get started with Dependabot version updates, you'll need to specify which 2 | # package ecosystems to update and where the package manifests are located. 3 | # Please see the documentation for all configuration options: 4 | # https://docs.github.com/code-security/dependabot/dependabot-version-updates/configuration-options-for-the-dependabot.yml-file 5 | 6 | version: 2 7 | updates: 8 | - package-ecosystem: "maven" # See documentation for possible values 9 | directory: "/" # Location of package manifests 10 | schedule: 11 | interval: "weekly" 12 | ignore: 13 | # Ignore all versions : cf pom.xml comments 14 | - dependency-name: "org.sonarsource.java:sonar-java-plugin" 15 | # Ignore all versions : cf pom.xml comments 16 | - dependency-name: "com.mycila:license-maven-plugin" 17 | - dependency-name: "org.springframework.data:spring-data-commons" 18 | update-types: ["version-update:semver-patch", "version-update:semver-minor"] 19 | -------------------------------------------------------------------------------- /src/it/java/org/greencodeinitiative/creedengo/java/integration/tests/profile/RuleMetadata.java: -------------------------------------------------------------------------------- 1 | package org.greencodeinitiative.creedengo.java.integration.tests.profile; 2 | 3 | public class RuleMetadata { 4 | private String key; 5 | private String type; 6 | private String defaultSeverity; 7 | 8 | public String getKey() { 9 | return key; 10 | } 11 | 12 | public void setKey(String key) { 13 | this.key = key; 14 | } 15 | 16 | public String getType() { 17 | return type; 18 | } 19 | 20 | public void setType(String type) { 21 | this.type = type; 22 | } 23 | 24 | public String getDefaultSeverity() { 25 | return defaultSeverity; 26 | } 27 | 28 | public void setDefaultSeverity(String defaultSeverity) { 29 | this.defaultSeverity = defaultSeverity; 30 | } 31 | 32 | @Override 33 | public String toString() { 34 | return "RuleMetadata{" + 35 | "key='" + key + '\'' + 36 | ", type='" + type + '\'' + 37 | ", defaultSeverity='" + defaultSeverity + '\'' + 38 | '}'; 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /src/it/test-projects/creedengo-java-plugin-test-project/src/main/java/org/greencodeinitiative/creedengo/java/checks/OptimizeReadFileExceptionCheck2.java: -------------------------------------------------------------------------------- 1 | package org.greencodeinitiative.creedengo.java.checks; 2 | 3 | import java.io.FileInputStream; 4 | import java.io.FileNotFoundException; 5 | import java.io.IOException; 6 | import java.io.InputStream; 7 | import java.util.Arrays; 8 | import java.util.List; 9 | import java.util.logging.Logger; 10 | 11 | class OptimizeReadFileExceptionCheck2 { 12 | 13 | Logger logger = Logger.getLogger(""); 14 | 15 | OptimizeReadFileExceptionCheck2(OptimizeReadFileExceptionCheck2 readFile) { 16 | } 17 | 18 | public void readPreferences(String filename) throws IOException { 19 | //... 20 | try (InputStream in = new FileInputStream(filename)) { // Noncompliant {{Optimize Read File Exceptions}} 21 | logger.info("my log"); 22 | } catch (FileNotFoundException e) { 23 | logger.info(e.getMessage()); 24 | } 25 | //... 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /src/it/java/org/greencodeinitiative/creedengo/java/integration/tests/profile/ProfileMetadata.java: -------------------------------------------------------------------------------- 1 | package org.greencodeinitiative.creedengo.java.integration.tests.profile; 2 | 3 | import java.util.List; 4 | 5 | public class ProfileMetadata { 6 | private String name; 7 | private String language; 8 | private List ruleKeys; 9 | 10 | public String getName() { 11 | return name; 12 | } 13 | 14 | public void setName(String name) { 15 | this.name = name; 16 | } 17 | 18 | public String getLanguage() { 19 | return language; 20 | } 21 | 22 | public void setLanguage(String language) { 23 | this.language = language; 24 | } 25 | 26 | public List getRuleKeys() { 27 | return ruleKeys; 28 | } 29 | 30 | public void setRuleKeys(List ruleKeys) { 31 | this.ruleKeys = ruleKeys; 32 | } 33 | 34 | @Override 35 | public String toString() { 36 | return "ProfileMetadata{" + 37 | "name='" + name + '\'' + 38 | ", language='" + language + '\'' + 39 | ", ruleKeys=" + ruleKeys + 40 | '}'; 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /.mvn/wrapper/maven-wrapper.properties: -------------------------------------------------------------------------------- 1 | # Licensed to the Apache Software Foundation (ASF) under one 2 | # or more contributor license agreements. See the NOTICE file 3 | # distributed with this work for additional information 4 | # regarding copyright ownership. The ASF licenses this file 5 | # to you under the Apache License, Version 2.0 (the 6 | # "License"); you may not use this file except in compliance 7 | # with the License. You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, 12 | # software distributed under the License is distributed on an 13 | # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | # KIND, either express or implied. See the License for the 15 | # specific language governing permissions and limitations 16 | # under the License. 17 | wrapperVersion=3.3.2 18 | distributionType=only-script 19 | distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.9.9/apache-maven-3.9.9-bin.zip 20 | -------------------------------------------------------------------------------- /src/it/test-projects/creedengo-java-plugin-test-project/src/main/java/org/greencodeinitiative/creedengo/java/checks/InitializeBufferWithAppropriateSize.java: -------------------------------------------------------------------------------- 1 | package org.greencodeinitiative.creedengo.java.checks; 2 | 3 | class InitializeBufferWithAppropriateSize { 4 | InitializeBufferWithAppropriateSize(InitializeBufferWithAppropriateSize mc) { 5 | } 6 | 7 | public void testBufferCompliant() { 8 | StringBuffer stringBuffer = new StringBuffer(16); 9 | } 10 | 11 | public void testBufferCompliant2() { 12 | StringBuffer stringBuffer = new StringBuffer(Integer.valueOf(16)); 13 | } 14 | 15 | public void testBufferNonCompliant() { 16 | StringBuffer stringBuffer = new StringBuffer(); // Noncompliant {{Initialize StringBuilder or StringBuffer with appropriate size}} 17 | } 18 | 19 | public void testBuilderCompliant() { 20 | StringBuilder stringBuilder = new StringBuilder(16); 21 | } 22 | 23 | public void testBuilderNonCompliant() { 24 | StringBuilder stringBuilder = new StringBuilder(); // Noncompliant {{Initialize StringBuilder or StringBuffer with appropriate size}} 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /src/test/files/AvoidMultipleIfElseStatementNotBlock.java: -------------------------------------------------------------------------------- 1 | /* 2 | * creedengo - Java language - Provides rules to reduce the environmental footprint of your Java programs 3 | * Copyright © 2024 Green Code Initiative (https://green-code-initiative.org/) 4 | * 5 | * This program is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU General Public License as published by 7 | * the Free Software Foundation, either version 3 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU General Public License 16 | * along with this program. If not, see . 17 | */ 18 | package org.greencodeinitiative.creedengo.java.checks; 19 | 20 | class AvoidMultipleIfElseStatementNotBlock { 21 | 22 | public boolean equals(Object obj) { 23 | if (this == obj) 24 | return true; 25 | } 26 | 27 | } 28 | -------------------------------------------------------------------------------- /src/test/files/AvoidMultipleIfElseStatementInterface.java: -------------------------------------------------------------------------------- 1 | /* 2 | * creedengo - Java language - Provides rules to reduce the environmental footprint of your Java programs 3 | * Copyright © 2024 Green Code Initiative (https://green-code-initiative.org/) 4 | * 5 | * This program is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU General Public License as published by 7 | * the Free Software Foundation, either version 3 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU General Public License 16 | * along with this program. If not, see . 17 | */ 18 | package org.greencodeinitiative.creedengo.java.checks; 19 | 20 | interface AvoidMultipleIfElseStatementCheck { 21 | 22 | TransactionMetaData initMetaData(ITransactionFoundation transactionFoundation) throws ProgramException, MnemonicTemplateShellException; 23 | 24 | } 25 | -------------------------------------------------------------------------------- /src/it/test-projects/creedengo-java-plugin-test-project/src/main/java/org/greencodeinitiative/creedengo/java/checks/AvoidMultipleIfElseStatementInterfaceNoIssue.java: -------------------------------------------------------------------------------- 1 | /* 2 | * creedengo - Java language - Provides rules to reduce the environmental footprint of your Java programs 3 | * Copyright © 2024 Green Code Initiative (https://green-code-initiative.org/) 4 | * 5 | * This program is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU General Public License as published by 7 | * the Free Software Foundation, either version 3 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU General Public License 16 | * along with this program. If not, see . 17 | */ 18 | package org.greencodeinitiative.creedengo.java.checks; 19 | 20 | interface AvoidMultipleIfElseStatementInterfaceNoIssue { 21 | 22 | Object initMetaData(Object transactionFoundation) throws IllegalAccessException; 23 | 24 | } 25 | -------------------------------------------------------------------------------- /src/test/files/AvoidRegexPatternNotStaticValid2.java: -------------------------------------------------------------------------------- 1 | /* 2 | * creedengo - Java language - Provides rules to reduce the environmental footprint of your Java programs 3 | * Copyright © 2024 Green Code Initiative (https://green-code-initiative.org/) 4 | * 5 | * This program is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU General Public License as published by 7 | * the Free Software Foundation, either version 3 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU General Public License 16 | * along with this program. If not, see . 17 | */ 18 | package org.greencodeinitiative.creedengo.java.checks; 19 | 20 | import java.util.regex.Pattern; 21 | 22 | public class AvoidRegexPatternNotStaticValid2 { 23 | 24 | private final Pattern pattern = Pattern.compile("foo"); // Compliant 25 | 26 | public boolean foo() { 27 | return pattern.matcher("foo").find(); 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /src/test/files/AvoidRegexPatternNotStaticValid1.java: -------------------------------------------------------------------------------- 1 | /* 2 | * creedengo - Java language - Provides rules to reduce the environmental footprint of your Java programs 3 | * Copyright © 2024 Green Code Initiative (https://green-code-initiative.org/) 4 | * 5 | * This program is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU General Public License as published by 7 | * the Free Software Foundation, either version 3 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU General Public License 16 | * along with this program. If not, see . 17 | */ 18 | package org.greencodeinitiative.creedengo.java.checks; 19 | 20 | import java.util.regex.Pattern; 21 | 22 | public class AvoidRegexPatternNotStaticValid1 { 23 | 24 | private static final Pattern pattern = Pattern.compile("foo"); // Compliant 25 | 26 | public boolean foo() { 27 | return pattern.matcher("foo").find(); 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /src/it/test-projects/creedengo-java-plugin-test-project/src/main/java/org/greencodeinitiative/creedengo/java/checks/AvoidFullSQLRequestCheck.java: -------------------------------------------------------------------------------- 1 | package org.greencodeinitiative.creedengo.java.checks; 2 | 3 | class AvoidFullSQLRequestCheck { 4 | AvoidFullSQLRequestCheck(AvoidFullSQLRequestCheck mc) { 5 | } 6 | 7 | public void literalSQLrequest() { 8 | dummyCall(" sElEcT * fRoM myTable"); // Noncompliant {{Don't use the query SELECT * FROM}} 9 | dummyCall(" sElEcT user fRoM myTable"); 10 | 11 | dummyCall("SELECTABLE 2*2 FROMAGE"); //not sql 12 | dummyCall("SELECT *FROM table"); // Noncompliant {{Don't use the query SELECT * FROM}} 13 | } 14 | 15 | 16 | public void variableSQLrequest() { 17 | String requestNonCompiliant = " SeLeCt * FrOm myTable"; // Noncompliant {{Don't use the query SELECT * FROM}} 18 | String requestCompiliant = " SeLeCt user FrOm myTable"; 19 | dummyCall(requestNonCompiliant); 20 | dummyCall(requestCompiliant); 21 | 22 | String noSqlCompiliant = "SELECTABLE 2*2 FROMAGE"; //not sql 23 | String requestNonCompiliant_nSpace = "SELECT *FROM table"; // Noncompliant {{Don't use the query SELECT * FROM}} 24 | } 25 | 26 | private void dummyCall(String request) { 27 | 28 | } 29 | 30 | } 31 | -------------------------------------------------------------------------------- /src/it/test-projects/creedengo-java-plugin-test-project/src/main/java/org/greencodeinitiative/creedengo/java/checks/AvoidMultipleIfElseStatementNoBlockNoIssue.java: -------------------------------------------------------------------------------- 1 | /* 2 | * creedengo - Java language - Provides rules to reduce the environmental footprint of your Java programs 3 | * Copyright © 2024 Green Code Initiative (https://green-code-initiative.org/) 4 | * 5 | * This program is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU General Public License as published by 7 | * the Free Software Foundation, either version 3 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU General Public License 16 | * along with this program. If not, see . 17 | */ 18 | package org.greencodeinitiative.creedengo.java.checks; 19 | 20 | class AvoidMultipleIfElseStatementNoBlockNoIssue { 21 | 22 | public boolean equals(Object obj) { 23 | if (this == obj) 24 | return true; 25 | return false; 26 | } 27 | 28 | } 29 | -------------------------------------------------------------------------------- /src/test/files/AvoidRegexPatternNotStatic.java: -------------------------------------------------------------------------------- 1 | /* 2 | * creedengo - Java language - Provides rules to reduce the environmental footprint of your Java programs 3 | * Copyright © 2024 Green Code Initiative (https://green-code-initiative.org/) 4 | * 5 | * This program is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU General Public License as published by 7 | * the Free Software Foundation, either version 3 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU General Public License 16 | * along with this program. If not, see . 17 | */ 18 | package org.greencodeinitiative.creedengo.java.checks; 19 | 20 | import java.util.regex.Pattern; 21 | 22 | public class AvoidRegexPatternNotStatic { 23 | 24 | public boolean foo() { 25 | final Pattern pattern = Pattern.compile("foo"); // Noncompliant {{Avoid using Pattern.compile() in a non-static context.}} 26 | return pattern.matcher("foo").find(); 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /src/it/test-projects/creedengo-java-plugin-test-project/src/main/java/org/greencodeinitiative/creedengo/java/checks/ZzzDDCToCheckOptimizeSQLQueriesWithLimit.java: -------------------------------------------------------------------------------- 1 | package org.greencodeinitiative.creedengo.java.checks; 2 | 3 | import org.springframework.data.jpa.repository.Query; 4 | 5 | import java.util.ArrayList; 6 | import java.util.List; 7 | 8 | class ZzzDDCToCheckOptimizeSQLQueriesWithLimit { 9 | 10 | public void literalSQLrequest() { 11 | dummyCall("SELECT user FROM myTable"); // Noncompliant {{Optimize Database SQL Queries (Clause LIMIT)}} 12 | dummyCall("SELECT user FROM myTable LIMIT 50"); // Compliant 13 | } 14 | 15 | @Query("select t from Todo t where t.status != 'COMPLETED'") // Noncompliant {{Optimize Database SQL Queries (Clause LIMIT)}} 16 | public List findAllUsers() { 17 | return new ArrayList<>(); 18 | } 19 | 20 | @Query("select t from Todo t where t.status != 'COMPLETED' LIMIT 25") // Compliant 21 | public List findFirstUsers() { 22 | return new ArrayList<>(); 23 | } 24 | 25 | private void callQuery() { 26 | String sql1 = "SELECT user FROM myTable"; // Noncompliant {{Optimize Database SQL Queries (Clause LIMIT)}} 27 | String sql2 = "SELECT user FROM myTable LIMIT 50"; // Compliant 28 | } 29 | 30 | private void dummyCall(String request) { 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /src/test/files/AvoidRegexPatternNotStaticValid3.java: -------------------------------------------------------------------------------- 1 | /* 2 | * creedengo - Java language - Provides rules to reduce the environmental footprint of your Java programs 3 | * Copyright © 2024 Green Code Initiative (https://green-code-initiative.org/) 4 | * 5 | * This program is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU General Public License as published by 7 | * the Free Software Foundation, either version 3 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU General Public License 16 | * along with this program. If not, see . 17 | */ 18 | package org.greencodeinitiative.creedengo.java.checks; 19 | 20 | import java.util.regex.Pattern; 21 | 22 | public class AvoidRegexPatternNotStaticValid3 { 23 | 24 | private final Pattern pattern; 25 | 26 | public AvoidRegexPatternNotStaticValid3() { 27 | pattern = Pattern.compile("foo"); // Compliant 28 | } 29 | 30 | public boolean foo() { 31 | return pattern.matcher("foo").find(); 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /src/it/test-projects/creedengo-java-plugin-test-project/src/main/java/org/greencodeinitiative/creedengo/java/checks/FreeResourcesOfAutoCloseableInterface.java: -------------------------------------------------------------------------------- 1 | package org.greencodeinitiative.creedengo.java.checks; 2 | 3 | import java.io.*; 4 | 5 | class FreeResourcesOfAutoCloseableInterface { 6 | FreeResourcesOfAutoCloseableInterface(FreeResourcesOfAutoCloseableInterface mc) { 7 | 8 | } 9 | 10 | public void foo1() { 11 | String fileName = "./FreeResourcesOfAutoCloseableInterface.java"; 12 | try (FileReader fr = new FileReader(fileName); 13 | BufferedReader br = new BufferedReader(fr)) { 14 | } catch (IOException e) { 15 | System.err.println(e.getMessage()); 16 | } 17 | } 18 | 19 | public void foo2() throws IOException { 20 | String fileName = "./FreeResourcesOfAutoCloseableInterface.java"; 21 | FileReader fr = null; 22 | BufferedReader br = null; 23 | try { // Noncompliant 24 | fr = new FileReader(fileName); 25 | br = new BufferedReader(fr); 26 | System.out.println(br.readLine()); 27 | } catch (IOException e) { 28 | System.err.println(e.getMessage()); 29 | } finally { 30 | if (fr != null) { 31 | fr.close(); 32 | } 33 | if (br != null) { 34 | br.close(); 35 | } 36 | } 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /src/test/java/org/greencodeinitiative/creedengo/java/checks/IncrementCheckTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * creedengo - Java language - Provides rules to reduce the environmental footprint of your Java programs 3 | * Copyright © 2024 Green Code Initiative (https://green-code-initiative.org/) 4 | * 5 | * This program is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU General Public License as published by 7 | * the Free Software Foundation, either version 3 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU General Public License 16 | * along with this program. If not, see . 17 | */ 18 | package org.greencodeinitiative.creedengo.java.checks; 19 | 20 | import org.junit.jupiter.api.Test; 21 | import org.sonar.java.checks.verifier.CheckVerifier; 22 | 23 | class IncrementCheckTest { 24 | 25 | @Test 26 | void test() { 27 | CheckVerifier.newVerifier() 28 | .onFile("src/test/files/IncrementCheck.java") 29 | .withCheck(new IncrementCheck()) 30 | .verifyIssues(); 31 | } 32 | 33 | } 34 | -------------------------------------------------------------------------------- /src/test/files/OptimizeReadFileExceptionCheck.java: -------------------------------------------------------------------------------- 1 | /* 2 | * creedengo - Java language - Provides rules to reduce the environmental footprint of your Java programs 3 | * Copyright © 2024 Green Code Initiative (https://green-code-initiative.org/) 4 | * 5 | * This program is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU General Public License as published by 7 | * the Free Software Foundation, either version 3 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU General Public License 16 | * along with this program. If not, see . 17 | */ 18 | package org.greencodeinitiative.creedengo.java.checks; 19 | 20 | import java.util.Arrays; 21 | import java.util.List; 22 | 23 | class ReadFile { 24 | ReadFile(ReadFile readFile) { 25 | } 26 | 27 | public void readPreferences(String filename) { 28 | //... 29 | InputStream in = null; 30 | try { 31 | in = new FileInputStream(filename); // Noncompliant {{Optimize Read File Exceptions}} 32 | } catch (FileNotFoundException e) { 33 | logger.log(e); 34 | } 35 | //... 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /docker-compose.yml: -------------------------------------------------------------------------------- 1 | name: sonarqube_creedengo_java 2 | 3 | services: 4 | sonar: 5 | build: . 6 | container_name: sonar_creedengo_java 7 | ports: 8 | - ":9000" 9 | networks: 10 | - sonarnet 11 | depends_on: 12 | db: 13 | condition: service_healthy 14 | environment: 15 | SONAR_JDBC_USERNAME: sonar 16 | SONAR_JDBC_PASSWORD: sonar 17 | SONAR_JDBC_URL: jdbc:postgresql://db:5432/sonarqube 18 | SONAR_ES_BOOTSTRAP_CHECKS_DISABLE: 'true' 19 | env_file: 20 | - path: ./.default.docker.env 21 | required: true 22 | - path: ./.override.docker.env 23 | required: false 24 | volumes: 25 | - "extensions:/opt/sonarqube/extensions" 26 | - "logs:/opt/sonarqube/logs" 27 | - "data:/opt/sonarqube/data" 28 | 29 | db: 30 | image: postgres:12 31 | container_name: postgresql_creedengo_java 32 | networks: 33 | - sonarnet 34 | volumes: 35 | - pg_data:/var/lib/postgresql/data 36 | environment: 37 | POSTGRES_USER: sonar 38 | POSTGRES_PASSWORD: sonar 39 | POSTGRES_DB: sonarqube 40 | PGDATA: pg_data:/var/lib/postgresql/data/pgdata 41 | healthcheck: 42 | test: [ "CMD-SHELL", "pg_isready -U sonar -d sonarqube" ] 43 | interval: 5s 44 | timeout: 5s 45 | retries: 5 46 | 47 | networks: 48 | sonarnet: 49 | driver: bridge 50 | 51 | volumes: 52 | data: 53 | logs: 54 | extensions: 55 | pg_data: 56 | -------------------------------------------------------------------------------- /src/test/java/org/greencodeinitiative/creedengo/java/checks/AvoidFullSQLRequestCheckTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * creedengo - Java language - Provides rules to reduce the environmental footprint of your Java programs 3 | * Copyright © 2024 Green Code Initiative (https://green-code-initiative.org/) 4 | * 5 | * This program is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU General Public License as published by 7 | * the Free Software Foundation, either version 3 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU General Public License 16 | * along with this program. If not, see . 17 | */ 18 | package org.greencodeinitiative.creedengo.java.checks; 19 | 20 | import org.junit.jupiter.api.Test; 21 | import org.sonar.java.checks.verifier.CheckVerifier; 22 | 23 | class AvoidFullSQLRequestCheckTest { 24 | 25 | @Test 26 | void test() { 27 | CheckVerifier.newVerifier() 28 | .onFile("src/test/files/AvoidFullSQLRequestCheck.java") 29 | .withCheck(new AvoidFullSQLRequest()) 30 | .verifyIssues(); 31 | } 32 | 33 | } 34 | -------------------------------------------------------------------------------- /src/test/java/org/greencodeinitiative/creedengo/java/checks/AvoidSQLRequestInLoopCheckTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * creedengo - Java language - Provides rules to reduce the environmental footprint of your Java programs 3 | * Copyright © 2024 Green Code Initiative (https://green-code-initiative.org/) 4 | * 5 | * This program is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU General Public License as published by 7 | * the Free Software Foundation, either version 3 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU General Public License 16 | * along with this program. If not, see . 17 | */ 18 | package org.greencodeinitiative.creedengo.java.checks; 19 | 20 | import org.junit.jupiter.api.Test; 21 | import org.sonar.java.checks.verifier.CheckVerifier; 22 | 23 | class AvoidSQLRequestInLoopCheckTest { 24 | 25 | @Test 26 | void test() { 27 | CheckVerifier.newVerifier() 28 | .onFile("src/test/files/AvoidSQLRequestInLoopCheck.java") 29 | .withCheck(new AvoidSQLRequestInLoop()) 30 | .verifyIssues(); 31 | } 32 | 33 | } 34 | -------------------------------------------------------------------------------- /src/test/java/org/greencodeinitiative/creedengo/java/checks/AvoidStatementForDMLQueriesTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * creedengo - Java language - Provides rules to reduce the environmental footprint of your Java programs 3 | * Copyright © 2024 Green Code Initiative (https://green-code-initiative.org/) 4 | * 5 | * This program is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU General Public License as published by 7 | * the Free Software Foundation, either version 3 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU General Public License 16 | * along with this program. If not, see . 17 | */ 18 | package org.greencodeinitiative.creedengo.java.checks; 19 | 20 | import org.junit.jupiter.api.Test; 21 | import org.sonar.java.checks.verifier.CheckVerifier; 22 | 23 | class AvoidStatementForDMLQueriesTest { 24 | @Test 25 | void test() { 26 | CheckVerifier.newVerifier() 27 | .onFile("src/test/files/AvoidStatementForDMLQueries.java") 28 | .withCheck(new AvoidStatementForDMLQueries()) 29 | .verifyIssues(); 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /src/test/java/org/greencodeinitiative/creedengo/java/checks/UseOptionalOrElseGetVsOrElseTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * creedengo - Java language - Provides rules to reduce the environmental footprint of your Java programs 3 | * Copyright © 2024 Green Code Initiative (https://green-code-initiative.org/) 4 | * 5 | * This program is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU General Public License as published by 7 | * the Free Software Foundation, either version 3 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU General Public License 16 | * along with this program. If not, see . 17 | */ 18 | package org.greencodeinitiative.creedengo.java.checks; 19 | 20 | import org.junit.jupiter.api.Test; 21 | import org.sonar.java.checks.verifier.CheckVerifier; 22 | 23 | class UseOptionalOrElseGetVsOrElseTest { 24 | @Test 25 | void test() { 26 | CheckVerifier.newVerifier() 27 | .onFile("src/test/files/UseOptionalOrElseGetVsOrElse.java") 28 | .withCheck(new UseOptionalOrElseGetVsOrElse()) 29 | .verifyIssues(); 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /src/test/java/org/greencodeinitiative/creedengo/java/checks/ArrayCopyCheckTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * creedengo - Java language - Provides rules to reduce the environmental footprint of your Java programs 3 | * Copyright © 2024 Green Code Initiative (https://green-code-initiative.org/) 4 | * 5 | * This program is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU General Public License as published by 7 | * the Free Software Foundation, either version 3 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU General Public License 16 | * along with this program. If not, see . 17 | */ 18 | package org.greencodeinitiative.creedengo.java.checks; 19 | 20 | import org.junit.jupiter.api.Test; 21 | import org.sonar.java.checks.verifier.CheckVerifier; 22 | 23 | class ArrayCopyCheckTest { 24 | 25 | /** 26 | * @formatter:off 27 | */ 28 | @Test 29 | void test() { 30 | CheckVerifier.newVerifier() 31 | .onFile("src/test/files/ArrayCopyCheck.java") 32 | .withCheck(new ArrayCopyCheck()) 33 | .verifyIssues(); 34 | } 35 | 36 | } 37 | -------------------------------------------------------------------------------- /src/test/files/OptimizeReadFileExceptionCheck4.java: -------------------------------------------------------------------------------- 1 | /* 2 | * creedengo - Java language - Provides rules to reduce the environmental footprint of your Java programs 3 | * Copyright © 2024 Green Code Initiative (https://green-code-initiative.org/) 4 | * 5 | * This program is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU General Public License as published by 7 | * the Free Software Foundation, either version 3 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU General Public License 16 | * along with this program. If not, see . 17 | */ 18 | package org.greencodeinitiative.creedengo.java.checks; 19 | 20 | import java.util.Arrays; 21 | import java.util.List; 22 | 23 | class ReadFile { 24 | ReadFile(ReadFile readFile) { 25 | } 26 | 27 | public void readPreferences(String filename) { 28 | //... 29 | try (InputStream in = new FileInputStream(filename)) { // Noncompliant {{Optimize Read File Exceptions}} 30 | logger.log("my log"); 31 | } catch (Exception e) { 32 | logger.log(e); 33 | } 34 | //... 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /src/test/files/OptimizeReadFileExceptionCheck5.java: -------------------------------------------------------------------------------- 1 | /* 2 | * creedengo - Java language - Provides rules to reduce the environmental footprint of your Java programs 3 | * Copyright © 2024 Green Code Initiative (https://green-code-initiative.org/) 4 | * 5 | * This program is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU General Public License as published by 7 | * the Free Software Foundation, either version 3 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU General Public License 16 | * along with this program. If not, see . 17 | */ 18 | package org.greencodeinitiative.creedengo.java.checks; 19 | 20 | import java.util.Arrays; 21 | import java.util.List; 22 | 23 | class ReadFile { 24 | ReadFile(ReadFile readFile) { 25 | } 26 | 27 | public void readPreferences(String filename) { 28 | //... 29 | try (InputStream in = new FileInputStream(filename)) { // Noncompliant {{Optimize Read File Exceptions}} 30 | logger.log("my log"); 31 | } catch (Throwable e) { 32 | logger.log(e); 33 | } 34 | //... 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /src/main/java/org/greencodeinitiative/creedengo/java/JavaPlugin.java: -------------------------------------------------------------------------------- 1 | /* 2 | * creedengo - Java language - Provides rules to reduce the environmental footprint of your Java programs 3 | * Copyright © 2024 Green Code Initiative (https://green-code-initiative.org/) 4 | * 5 | * This program is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU General Public License as published by 7 | * the Free Software Foundation, either version 3 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU General Public License 16 | * along with this program. If not, see . 17 | */ 18 | package org.greencodeinitiative.creedengo.java; 19 | 20 | import org.sonar.api.Plugin; 21 | 22 | public class JavaPlugin implements Plugin { 23 | 24 | @Override 25 | public void define(Context context) { 26 | // server extensions -> objects are instantiated during server startup 27 | context.addExtension(JavaRulesDefinition.class); 28 | 29 | // batch extensions -> objects are instantiated during code analysis 30 | context.addExtension(JavaCheckRegistrar.class); 31 | 32 | } 33 | 34 | } 35 | -------------------------------------------------------------------------------- /src/test/files/OptimizeReadFileExceptionCheck3.java: -------------------------------------------------------------------------------- 1 | /* 2 | * creedengo - Java language - Provides rules to reduce the environmental footprint of your Java programs 3 | * Copyright © 2024 Green Code Initiative (https://green-code-initiative.org/) 4 | * 5 | * This program is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU General Public License as published by 7 | * the Free Software Foundation, either version 3 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU General Public License 16 | * along with this program. If not, see . 17 | */ 18 | package org.greencodeinitiative.creedengo.java.checks; 19 | 20 | import java.util.Arrays; 21 | import java.util.List; 22 | 23 | class ReadFile { 24 | ReadFile(ReadFile readFile) { 25 | } 26 | 27 | public void readPreferences(String filename) { 28 | //... 29 | try (InputStream in = new FileInputStream(filename)) { // Noncompliant {{Optimize Read File Exceptions}} 30 | logger.log("my log"); 31 | } catch (IOException e) { 32 | logger.log(e); 33 | } 34 | //... 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /src/test/java/org/greencodeinitiative/creedengo/java/checks/AvoidSetConstantInBatchInsertTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * creedengo - Java language - Provides rules to reduce the environmental footprint of your Java programs 3 | * Copyright © 2024 Green Code Initiative (https://green-code-initiative.org/) 4 | * 5 | * This program is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU General Public License as published by 7 | * the Free Software Foundation, either version 3 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU General Public License 16 | * along with this program. If not, see . 17 | */ 18 | package org.greencodeinitiative.creedengo.java.checks; 19 | 20 | import org.junit.jupiter.api.Test; 21 | import org.sonar.java.checks.verifier.CheckVerifier; 22 | 23 | class AvoidSetConstantInBatchInsertTest { 24 | 25 | @Test 26 | void test() { 27 | CheckVerifier.newVerifier() 28 | .onFile("src/test/files/AvoidSetConstantInBatchUpdateCheck.java") 29 | .withCheck(new AvoidSetConstantInBatchUpdate()) 30 | .verifyIssues(); 31 | } 32 | 33 | } 34 | -------------------------------------------------------------------------------- /src/test/java/org/greencodeinitiative/creedengo/java/checks/NoFunctionCallWhenDeclaringForLoopTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * creedengo - Java language - Provides rules to reduce the environmental footprint of your Java programs 3 | * Copyright © 2024 Green Code Initiative (https://green-code-initiative.org/) 4 | * 5 | * This program is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU General Public License as published by 7 | * the Free Software Foundation, either version 3 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU General Public License 16 | * along with this program. If not, see . 17 | */ 18 | package org.greencodeinitiative.creedengo.java.checks; 19 | 20 | import org.junit.jupiter.api.Test; 21 | import org.sonar.java.checks.verifier.CheckVerifier; 22 | 23 | class NoFunctionCallWhenDeclaringForLoopTest { 24 | @Test 25 | void test() { 26 | CheckVerifier.newVerifier() 27 | .onFile("src/test/files/NoFunctionCallWhenDeclaringForLoop.java") 28 | .withCheck(new NoFunctionCallWhenDeclaringForLoop()) 29 | .verifyIssues(); 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /src/test/files/OptimizeReadFileExceptionCheck2.java: -------------------------------------------------------------------------------- 1 | /* 2 | * creedengo - Java language - Provides rules to reduce the environmental footprint of your Java programs 3 | * Copyright © 2024 Green Code Initiative (https://green-code-initiative.org/) 4 | * 5 | * This program is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU General Public License as published by 7 | * the Free Software Foundation, either version 3 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU General Public License 16 | * along with this program. If not, see . 17 | */ 18 | package org.greencodeinitiative.creedengo.java.checks; 19 | 20 | import java.util.Arrays; 21 | import java.util.List; 22 | 23 | class ReadFile { 24 | ReadFile(ReadFile readFile) { 25 | } 26 | 27 | public void readPreferences(String filename) { 28 | //... 29 | try (InputStream in = new FileInputStream(filename)) { // Noncompliant {{Optimize Read File Exceptions}} 30 | logger.log("my log"); 31 | } catch (FileNotFoundException e) { 32 | logger.log(e); 33 | } 34 | //... 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /src/test/java/org/greencodeinitiative/creedengo/java/checks/InitializeBufferWithAppropriateSizeTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * creedengo - Java language - Provides rules to reduce the environmental footprint of your Java programs 3 | * Copyright © 2024 Green Code Initiative (https://green-code-initiative.org/) 4 | * 5 | * This program is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU General Public License as published by 7 | * the Free Software Foundation, either version 3 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU General Public License 16 | * along with this program. If not, see . 17 | */ 18 | package org.greencodeinitiative.creedengo.java.checks; 19 | 20 | import org.junit.jupiter.api.Test; 21 | import org.sonar.java.checks.verifier.CheckVerifier; 22 | 23 | class InitializeBufferWithAppropriateSizeTest { 24 | 25 | @Test 26 | void test() { 27 | CheckVerifier.newVerifier() 28 | .onFile("src/test/files/InitializeBufferWithAppropriateSize.java") 29 | .withCheck(new InitializeBufferWithAppropriateSize()) 30 | .verifyIssues(); 31 | } 32 | 33 | } 34 | -------------------------------------------------------------------------------- /src/test/java/org/greencodeinitiative/creedengo/java/checks/MakeNonReassignedVariablesConstantsTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * creedengo - Java language - Provides rules to reduce the environmental footprint of your Java programs 3 | * Copyright © 2024 Green Code Initiative (https://green-code-initiative.org/) 4 | * 5 | * This program is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU General Public License as published by 7 | * the Free Software Foundation, either version 3 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU General Public License 16 | * along with this program. If not, see . 17 | */ 18 | package org.greencodeinitiative.creedengo.java.checks; 19 | 20 | import org.junit.jupiter.api.Test; 21 | import org.sonar.java.checks.verifier.CheckVerifier; 22 | 23 | class MakeNonReassignedVariablesConstantsTest { 24 | 25 | @Test 26 | void test() { 27 | CheckVerifier.newVerifier() 28 | .onFile("src/test/files/MakeNonReassignedVariablesConstants.java") 29 | .withCheck(new MakeNonReassignedVariablesConstants()) 30 | .verifyIssues(); 31 | } 32 | 33 | } 34 | -------------------------------------------------------------------------------- /src/main/java/org/greencodeinitiative/creedengo/java/utils/StringUtils.java: -------------------------------------------------------------------------------- 1 | /* 2 | * creedengo - Java language - Provides rules to reduce the environmental footprint of your Java programs 3 | * Copyright © 2024 Green Code Initiative (https://green-code-initiative.org/) 4 | * 5 | * This program is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU General Public License as published by 7 | * the Free Software Foundation, either version 3 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU General Public License 16 | * along with this program. If not, see . 17 | */ 18 | package org.greencodeinitiative.creedengo.java.utils; 19 | 20 | public final class StringUtils { 21 | 22 | private StringUtils() { 23 | // Utility class 24 | } 25 | 26 | public static String spaces(int number) { 27 | StringBuilder sb = new StringBuilder(); 28 | for (int i = 0; i < number; i++) { 29 | sb.append(' '); 30 | } 31 | return sb.toString(); 32 | } 33 | 34 | public static boolean isNotEmpty(String string) { 35 | return string != null && !string.isEmpty(); 36 | } 37 | 38 | } 39 | -------------------------------------------------------------------------------- /src/test/files/AvoidStatementForDMLQueries.java: -------------------------------------------------------------------------------- 1 | /* 2 | * creedengo - Java language - Provides rules to reduce the environmental footprint of your Java programs 3 | * Copyright © 2024 Green Code Initiative (https://green-code-initiative.org/) 4 | * 5 | * This program is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU General Public License as published by 7 | * the Free Software Foundation, either version 3 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU General Public License 16 | * along with this program. If not, see . 17 | */ 18 | package org.greencodeinitiative.creedengo.java.checks; 19 | 20 | import java.sql.Connection; 21 | import java.sql.DriverManager; 22 | import java.sql.*; 23 | import java.sql.PreparedStatement; 24 | 25 | 26 | class AvoidStatementForDMLQueries { 27 | AvoidStatementForDMLQueries(AvoidStatementForDMLQueries mc) { 28 | } 29 | 30 | public void insert() { 31 | Statement statement = connection.createStatement(); 32 | statement.executeUpdate("INSERT INTO persons(id, name) VALUES(2, 'Toto')"); // Noncompliant {{You must not use Statement for a DML query}} 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /src/test/files/AvoidUsageOfStaticCollectionsGoodWay.java: -------------------------------------------------------------------------------- 1 | /* 2 | * creedengo - Java language - Provides rules to reduce the environmental footprint of your Java programs 3 | * Copyright © 2024 Green Code Initiative (https://green-code-initiative.org/) 4 | * 5 | * This program is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU General Public License as published by 7 | * the Free Software Foundation, either version 3 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU General Public License 16 | * along with this program. If not, see . 17 | */ 18 | package org.greencodeinitiative.creedengo.java.checks; 19 | 20 | import java.util.*; 21 | 22 | /** 23 | * Compliant 24 | */ 25 | public class AvoidUsageOfStaticCollectionsGoodWay { 26 | public static volatile AvoidUsageOfStaticCollectionsGoodWay INSTANCE = new AvoidUsageOfStaticCollectionsGoodWay(); 27 | 28 | public final List LIST = new ArrayList(); // Compliant 29 | public final Set SET = new HashSet(); // Compliant 30 | public final Map MAP = new HashMap(); // Compliant 31 | 32 | private AvoidUsageOfStaticCollectionsGoodWay() { 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /.github/workflows/build.yml: -------------------------------------------------------------------------------- 1 | name: Build and Tests 2 | 3 | on: 4 | push: 5 | branches: 6 | - main 7 | paths-ignore: 8 | - "*.md" 9 | - ".github/**/*.yml" 10 | tags: 11 | - "[0-9]+.[0-9]+.[0-9]+" 12 | pull_request: 13 | types: [opened, synchronize, reopened] 14 | 15 | jobs: 16 | build: 17 | name: Build 18 | runs-on: ubuntu-latest 19 | permissions: 20 | pull-requests: read # allows SonarCloud to decorate PRs with analysis results 21 | steps: 22 | - name: Checkout 23 | uses: actions/checkout@v4 24 | with: 25 | fetch-depth: 0 # Shallow clones should be disabled for a better relevancy of analysis 26 | 27 | - name: Set up JDK 17 28 | uses: actions/setup-java@v4 29 | with: 30 | distribution: "temurin" 31 | java-version: 17 32 | cache: maven 33 | 34 | - name: Verify 35 | run: ./mvnw -e -B verify 36 | 37 | - name: Cache SonarQube packages 38 | uses: actions/cache@v4 39 | with: 40 | path: ~/.sonar/cache 41 | key: ${{ runner.os }}-sonar 42 | restore-keys: ${{ runner.os }}-sonar 43 | 44 | - name: SonarQube Scan 45 | if: github.event_name != 'pull_request' || github.event.pull_request.head.repo.full_name == github.repository 46 | env: 47 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 48 | SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }} 49 | run: ./mvnw -e -B org.sonarsource.scanner.maven:sonar-maven-plugin:sonar -Dsonar.projectKey=green-code-initiative_creedengo-java 50 | -------------------------------------------------------------------------------- /src/it/test-projects/creedengo-java-plugin-test-project/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 4.0.0 5 | 6 | org.green-code-initiative 7 | creedengo-java-plugin-test-project 8 | 0.0.1-SNAPSHOT 9 | 10 | creedengo Java Sonar Plugin Test Project 11 | 12 | 13 | 17 14 | ${java.version} 15 | ${java.version} 16 | 17 | target 18 | 19 | UTF-8 20 | ${encoding} 21 | ${encoding} 22 | 23 | 24 | 25 | 26 | org.springframework.data 27 | spring-data-jpa 28 | 3.3.0 29 | 30 | 31 | org.springframework 32 | spring-beans 33 | 5.3.25 34 | 35 | 36 | 37 | -------------------------------------------------------------------------------- /src/test/files/AvoidUsageOfStaticCollections.java: -------------------------------------------------------------------------------- 1 | /* 2 | * creedengo - Java language - Provides rules to reduce the environmental footprint of your Java programs 3 | * Copyright © 2024 Green Code Initiative (https://green-code-initiative.org/) 4 | * 5 | * This program is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU General Public License as published by 7 | * the Free Software Foundation, either version 3 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU General Public License 16 | * along with this program. If not, see . 17 | */ 18 | package org.greencodeinitiative.creedengo.java.checks; 19 | 20 | import java.util.*; 21 | 22 | /** 23 | * Not compliant 24 | */ 25 | public class AvoidUsageOfStaticCollections { 26 | 27 | public static final List LIST = new ArrayList(); // Noncompliant {{Avoid usage of static collections.}} 28 | 29 | public static final Set SET = new HashSet(); // Noncompliant {{Avoid usage of static collections.}} 30 | 31 | public static final Map MAP = new HashMap(); // Noncompliant {{Avoid usage of static collections.}} 32 | 33 | public AvoidUsageOfStaticCollections() { 34 | } 35 | 36 | } 37 | -------------------------------------------------------------------------------- /src/test/files/UseOptionalOrElseGetVsOrElse.java: -------------------------------------------------------------------------------- 1 | /* 2 | * creedengo - Java language - Provides rules to reduce the environmental footprint of your Java programs 3 | * Copyright © 2024 Green Code Initiative (https://green-code-initiative.org/) 4 | * 5 | * This program is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU General Public License as published by 7 | * the Free Software Foundation, either version 3 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU General Public License 16 | * along with this program. If not, see . 17 | */ 18 | 19 | import java.util.Optional; 20 | 21 | class UseOptionalOrElseGetVsOrElse { 22 | 23 | private static Optional variable = Optional.empty(); 24 | 25 | public static final String NAME = Optional.of("creedengo").orElse(getUnpredictedMethod()); // Noncompliant {{Use optional orElseGet instead of orElse.}} 26 | 27 | public static final String NAME2 = Optional.of("creedengo").orElseGet(() -> getUnpredictedMethod()); // Compliant 28 | 29 | public static final String NAME3 = variable.orElse(getUnpredictedMethod()); // Compliant 30 | 31 | private static String getUnpredictedMethod() { 32 | return "unpredicted"; 33 | } 34 | 35 | } 36 | -------------------------------------------------------------------------------- /src/test/files/AvoidGettingSizeCollectionInForLoopIgnored.java: -------------------------------------------------------------------------------- 1 | /* 2 | * creedengo - Java language - Provides rules to reduce the environmental footprint of your Java programs 3 | * Copyright © 2024 Green Code Initiative (https://green-code-initiative.org/) 4 | * 5 | * This program is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU General Public License as published by 7 | * the Free Software Foundation, either version 3 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU General Public License 16 | * along with this program. If not, see . 17 | */ 18 | package org.greencodeinitiative.creedengo.java.checks; 19 | 20 | import java.util.Collection; 21 | import java.util.ArrayList; 22 | import java.util.List; 23 | 24 | class GCI69AvoidGettingSizeCollectionInForLoopBad { 25 | AvoidGettingSizeCollectionInForLoopBad() { 26 | 27 | } 28 | 29 | public void badForLoop() { 30 | final List numberList = new ArrayList(); 31 | numberList.add(10); 32 | numberList.add(20); 33 | 34 | final Iterator it = numberList.iterator(); 35 | for (; it.hasNext(); ) { // Ignored => compliant 36 | System.out.println(it.next()); 37 | } 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /src/test/files/AvoidGettingSizeCollectionInWhileLoopBad.java: -------------------------------------------------------------------------------- 1 | /* 2 | * creedengo - Java language - Provides rules to reduce the environmental footprint of your Java programs 3 | * Copyright © 2024 Green Code Initiative (https://green-code-initiative.org/) 4 | * 5 | * This program is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU General Public License as published by 7 | * the Free Software Foundation, either version 3 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU General Public License 16 | * along with this program. If not, see . 17 | */ 18 | package org.greencodeinitiative.creedengo.java.checks; 19 | 20 | import java.util.Collection; 21 | import java.util.ArrayList; 22 | import java.util.List; 23 | 24 | class AvoidGettingSizeCollectionInWhileLoopBad { 25 | AvoidGettingSizeCollectionInWhileLoopBad() { 26 | 27 | } 28 | 29 | public void badWhileLoop() { 30 | List numberList = new ArrayList(); 31 | numberList.add(10); 32 | numberList.add(20); 33 | 34 | int i = 0; 35 | while (i < numberList.size()) { // Noncompliant {{Avoid getting the size of the collection in the loop}} 36 | System.out.println("numberList.size()"); 37 | i++; 38 | } 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /src/test/files/AvoidGettingSizeCollectionInWhileLoopIgnored.java: -------------------------------------------------------------------------------- 1 | /* 2 | * creedengo - Java language - Provides rules to reduce the environmental footprint of your Java programs 3 | * Copyright © 2024 Green Code Initiative (https://green-code-initiative.org/) 4 | * 5 | * This program is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU General Public License as published by 7 | * the Free Software Foundation, either version 3 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU General Public License 16 | * along with this program. If not, see . 17 | */ 18 | package org.greencodeinitiative.creedengo.java.checks; 19 | 20 | import java.util.Collection; 21 | import java.util.ArrayList; 22 | import java.util.List; 23 | 24 | class AvoidGettingSizeCollectionInWhileLoopBad { 25 | AvoidGettingSizeCollectionInWhileLoopBad() { 26 | 27 | } 28 | 29 | public void badWhileLoop() { 30 | List numberList = new ArrayList(); 31 | numberList.add(10); 32 | numberList.add(20); 33 | 34 | Iterator it = numberList.iterator(); 35 | int i = 0; 36 | while (it.hasNext()) { // Ignored => compliant 37 | it.next(); 38 | System.out.println("numberList.size()"); 39 | } 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /src/test/java/org/greencodeinitiative/creedengo/java/checks/AvoidSpringRepositoryCallInLoopCheckTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * creedengo - Java language - Provides rules to reduce the environmental footprint of your Java programs 3 | * Copyright © 2024 Green Code Initiative (https://green-code-initiative.org/) 4 | * 5 | * This program is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU General Public License as published by 7 | * the Free Software Foundation, either version 3 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU General Public License 16 | * along with this program. If not, see . 17 | */ 18 | package org.greencodeinitiative.creedengo.java.checks; 19 | 20 | import org.greencodeinitiative.creedengo.java.utils.FilesUtils; 21 | import org.junit.jupiter.api.Test; 22 | import org.sonar.java.checks.verifier.CheckVerifier; 23 | 24 | class AvoidSpringRepositoryCallInLoopCheckTest { 25 | 26 | @Test 27 | void test() { 28 | CheckVerifier.newVerifier() 29 | .onFile("src/test/files/AvoidSpringRepositoryCallInLoopCheck.java") 30 | .withCheck(new AvoidSpringRepositoryCallInLoopOrStreamCheck()) 31 | .withClassPath(FilesUtils.getClassPath("target/test-jars")) 32 | .verifyIssues(); 33 | } 34 | 35 | } 36 | -------------------------------------------------------------------------------- /src/test/java/org/greencodeinitiative/creedengo/java/checks/AvoidSpringRepositoryCallInStreamCheckTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * creedengo - Java language - Provides rules to reduce the environmental footprint of your Java programs 3 | * Copyright © 2024 Green Code Initiative (https://green-code-initiative.org/) 4 | * 5 | * This program is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU General Public License as published by 7 | * the Free Software Foundation, either version 3 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU General Public License 16 | * along with this program. If not, see . 17 | */ 18 | package org.greencodeinitiative.creedengo.java.checks; 19 | 20 | import org.greencodeinitiative.creedengo.java.utils.FilesUtils; 21 | import org.junit.jupiter.api.Test; 22 | import org.sonar.java.checks.verifier.CheckVerifier; 23 | 24 | class AvoidSpringRepositoryCallInStreamCheckTest { 25 | 26 | @Test 27 | void test() { 28 | CheckVerifier.newVerifier() 29 | .onFile("src/test/files/AvoidSpringRepositoryCallInStreamCheck.java") 30 | .withCheck(new AvoidSpringRepositoryCallInLoopOrStreamCheck()) 31 | .withClassPath(FilesUtils.getClassPath("target/test-jars")) 32 | .verifyIssues(); 33 | } 34 | 35 | } 36 | -------------------------------------------------------------------------------- /downloads-sonarsource.crt: -------------------------------------------------------------------------------- 1 | -----BEGIN CERTIFICATE----- 2 | MIIEZzCCA0+gAwIBAgIQb93rHKoediFVBatlARo+izANBgkqhkiG9w0BAQsFADCB 3 | hzELMAkGA1UEBhMCRlIxFjAUBgNVBAgTDUlsZS1kZS1mcmFuY2UxDjAMBgNVBAcT 4 | BVBhcmlzMRIwEAYDVQQKEwlDYXBnZW1pbmkxFDASBgNVBAsTC0dyb3VwIEluZnJh 5 | MSYwJAYDVQQDEx16dG56aWEtaW50ZXJuZXQuY2FwZ2VtaW5pLmNvbTAeFw0yNTAz 6 | MjAxOTUyNDVaFw0yNTA0MDMyMDUyNDVaMFExITAfBgNVBAMTGGJpbmFyaWVzLnNv 7 | bmFyc291cmNlLmNvbTEVMBMGA1UECgwMWnNjYWxlciBJbmMuMRUwEwYDVQQLDAxa 8 | c2NhbGVyIEluYy4wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDPn2/p 9 | TD/pccqvIL7ek6xkyRJz+GV2a5BhZLHBzErFyUE+UyT3h4jxkwHTnSDcFHPynyud 10 | MxpBdPxpbAAmzp+kqs/kOjMiSoRdgjv4U/Lerypiox+wYns/zvN/9tUuHPSdbRu7 11 | 5BZZw7GotNwN0i8eQy0MZsoy+T5dCFEy2xwKVUqJtg0seiHFrr6jp7RVfLwdAmkE 12 | Zg1+vPYLB2iDzii3Me1ym71ewcG/Ow+QavNUjOprwJpxLOwfeeX9SYt0KcpW0FXV 13 | PriGAGLLcko1X8JS1AwlKCNdS6QesX2uGxATHFK1tncj974n+ogHaVdjRP5wGNyx 14 | p9SnpWN3jFM8l7YpAgMBAAGjggECMIH/MD4GA1UdEQQ3MDWCGGJpbmFyaWVzLnNv 15 | bmFyc291cmNlLmNvbYIZZG93bmxvYWRzLnNvbmFyc291cmNlLmNvbTAOBgNVHQ8B 16 | Af8EBAMCBaAwEwYDVR0lBAwwCgYIKwYBBQUHAwEwDAYDVR0TAQH/BAIwADBKBgNV 17 | HR8EQzBBMD+gPaA7hjlodHRwOi8vZ2F0ZXdheS56c2NhbGVyLm5ldC96c2NhbGVy 18 | LXpzY3JsLTgxMjQyNTk5LTkxMC5jcmwwHQYDVR0OBBYEFHaP8PqoHXC3EtPdtrNB 19 | G5mJm2JYMB8GA1UdIwQYMBaAFLD7L1k58j8FcvBXLU2Z4ZbZvg8IMA0GCSqGSIb3 20 | DQEBCwUAA4IBAQBGHb5Xw5VKtAoJbWY/irUgsXmgtNRioJreF5vX97/lbngJpk1C 21 | VtMPI0OrF8UHtgZkJuf/aK5NwOshqVHNxQ56Y+qF5ctd379mkvvnGuNVs2t8NpgW 22 | pOOoRqLH+f4SF2/5bzZkwlMjfxs6h2AJuW3iNNgns7mG8pQ3/chK99+tqwLZ4E+J 23 | uRVmeCcFHgy2BdvspB7QZE9J8cWjMrkk7q5JH2PTj1ksst5XhdjoS3lI8sbRBlbV 24 | hkctVQHpKr3ksnHycoboqNHbcAimYtYjsvDi/JV9rIOLnGelttfZtrDB0nCL0p/u 25 | Ir+1+11jcCSCkqo+cj+kkZshTmduOrU+soBN 26 | -----END CERTIFICATE----- 27 | -------------------------------------------------------------------------------- /src/test/files/AvoidGettingSizeCollectionInForEachLoopIgnored.java: -------------------------------------------------------------------------------- 1 | /* 2 | * creedengo - Java language - Provides rules to reduce the environmental footprint of your Java programs 3 | * Copyright © 2024 Green Code Initiative (https://green-code-initiative.org/) 4 | * 5 | * This program is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU General Public License as published by 7 | * the Free Software Foundation, either version 3 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU General Public License 16 | * along with this program. If not, see . 17 | */ 18 | package org.greencodeinitiative.creedengo.java.checks; 19 | 20 | import java.util.Collection; 21 | import java.util.ArrayList; 22 | import java.util.List; 23 | 24 | class AvoidGettingSizeCollectionInForEachLoopIgnored { 25 | AvoidGettingSizeCollectionInForEachLoopIgnored(AvoidGettingSizeCollectionInForEachLoopIgnored obj) { 26 | 27 | } 28 | 29 | public void ignoredLoop() { 30 | List numberList = new ArrayList(); 31 | numberList.add(10); 32 | numberList.add(20); 33 | 34 | for (Integer i : numberList) { // Ignored 35 | int size = numberList.size(); // Compliant with this rule 36 | System.out.println("numberList.size()"); 37 | } 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /src/it/test-projects/creedengo-java-plugin-test-project/src/main/java/org/greencodeinitiative/creedengo/java/checks/UseOptionalOrElseGetVsOrElse.java: -------------------------------------------------------------------------------- 1 | /* 2 | * creedengo - Java language - Provides rules to reduce the environmental footprint of your Java programs 3 | * Copyright © 2024 Green Code Initiative (https://green-code-initiative.org/) 4 | * 5 | * This program is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU General Public License as published by 7 | * the Free Software Foundation, either version 3 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU General Public License 16 | * along with this program. If not, see . 17 | */ 18 | 19 | import java.util.Optional; 20 | 21 | class UseOptionalOrElseGetVsOrElse { 22 | 23 | private static Optional variable = Optional.empty(); 24 | 25 | public static final String NAME = Optional.of("creedengo").orElse(getUnpredictedMethod()); // Noncompliant {{Use optional orElseGet instead of orElse.}} 26 | 27 | public static final String NAME2 = Optional.of("creedengo").orElseGet(() -> getUnpredictedMethod()); // Compliant 28 | 29 | public static final String NAME3 = variable.orElse(getUnpredictedMethod()); // Compliant 30 | 31 | private static String getUnpredictedMethod() { 32 | return "unpredicted"; 33 | } 34 | 35 | } 36 | -------------------------------------------------------------------------------- /src/test/files/AvoidGettingSizeCollectionInForLoopGood.java: -------------------------------------------------------------------------------- 1 | /* 2 | * creedengo - Java language - Provides rules to reduce the environmental footprint of your Java programs 3 | * Copyright © 2024 Green Code Initiative (https://green-code-initiative.org/) 4 | * 5 | * This program is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU General Public License as published by 7 | * the Free Software Foundation, either version 3 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU General Public License 16 | * along with this program. If not, see . 17 | */ 18 | package org.greencodeinitiative.creedengo.java.checks; 19 | 20 | import java.util.Collection; 21 | import java.util.ArrayList; 22 | import java.util.List; 23 | 24 | class AvoidGettingSizeCollectionInForLoopGood { 25 | AvoidGettingSizeCollectionInForLoopGood(AvoidGettingSizeCollectionInForLoopGood obj) { 26 | 27 | } 28 | 29 | public void goodForLoop() { 30 | List numberList = new ArrayList(); 31 | numberList.add(10); 32 | numberList.add(20); 33 | 34 | int size = numberList.size(); 35 | for (int i = 0; i < size; i++) { // Compliant 36 | System.out.println("numberList.size()"); 37 | int size = numberList.size(); // Compliant with this rule 38 | } 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /src/test/java/org/greencodeinitiative/creedengo/java/JavaPluginTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * creedengo - Java language - Provides rules to reduce the environmental footprint of your Java programs 3 | * Copyright © 2024 Green Code Initiative (https://green-code-initiative.org/) 4 | * 5 | * This program is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU General Public License as published by 7 | * the Free Software Foundation, either version 3 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU General Public License 16 | * along with this program. If not, see . 17 | */ 18 | package org.greencodeinitiative.creedengo.java; 19 | 20 | import org.junit.jupiter.api.BeforeEach; 21 | import org.junit.jupiter.api.Test; 22 | import org.sonar.api.Plugin; 23 | import org.sonar.api.SonarRuntime; 24 | 25 | import static org.assertj.core.api.Assertions.assertThat; 26 | import static org.mockito.Mockito.mock; 27 | 28 | class JavaPluginTest { 29 | private Plugin.Context context; 30 | 31 | @BeforeEach 32 | void init() { 33 | SonarRuntime sonarRuntime = mock(SonarRuntime.class); 34 | context = new Plugin.Context(sonarRuntime); 35 | new JavaPlugin().define(context); 36 | } 37 | 38 | @Test 39 | void test() { 40 | assertThat(context.getExtensions()).hasSize(2); 41 | } 42 | 43 | } 44 | -------------------------------------------------------------------------------- /src/test/java/org/greencodeinitiative/creedengo/java/utils/StringUtilsTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * creedengo - Java language - Provides rules to reduce the environmental footprint of your Java programs 3 | * Copyright © 2024 Green Code Initiative (https://green-code-initiative.org/) 4 | * 5 | * This program is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU General Public License as published by 7 | * the Free Software Foundation, either version 3 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU General Public License 16 | * along with this program. If not, see . 17 | */ 18 | package org.greencodeinitiative.creedengo.java.utils; 19 | 20 | import static org.assertj.core.api.Assertions.assertThat; 21 | import org.junit.jupiter.api.Test; 22 | 23 | class StringUtilsTest { 24 | 25 | @Test 26 | void spaces() { 27 | assertThat(StringUtils.spaces(5)) 28 | .hasSize(5) 29 | .containsOnlyWhitespaces(); 30 | } 31 | 32 | @Test 33 | void isNotEmpty() { 34 | assertThat(StringUtils.isNotEmpty(null)).isFalse(); 35 | assertThat(StringUtils.isNotEmpty("")).isFalse(); 36 | assertThat(StringUtils.isNotEmpty(" ")).isTrue(); 37 | assertThat(StringUtils.isNotEmpty("bob")).isTrue(); 38 | assertThat(StringUtils.isNotEmpty(" bob ")).isTrue(); 39 | } 40 | 41 | } 42 | -------------------------------------------------------------------------------- /src/test/files/AvoidGettingSizeCollectionInWhileLoopGood.java: -------------------------------------------------------------------------------- 1 | /* 2 | * creedengo - Java language - Provides rules to reduce the environmental footprint of your Java programs 3 | * Copyright © 2024 Green Code Initiative (https://green-code-initiative.org/) 4 | * 5 | * This program is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU General Public License as published by 7 | * the Free Software Foundation, either version 3 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU General Public License 16 | * along with this program. If not, see . 17 | */ 18 | package org.greencodeinitiative.creedengo.java.checks; 19 | 20 | import java.util.Collection; 21 | import java.util.ArrayList; 22 | import java.util.List; 23 | 24 | class AvoidGettingSizeCollectionInWhileLoopGood { 25 | AvoidGettingSizeCollectionInWhileLoopGood(AvoidGettingSizeCollectionInWhileLoopGood obj) { 26 | 27 | } 28 | 29 | public void goodWhileLoop() { 30 | List numberList = new ArrayList(); 31 | numberList.add(10); 32 | numberList.add(20); 33 | 34 | int size = numberList.size(); 35 | int i = 0; 36 | while (i < size) { // Compliant 37 | System.out.println("numberList.size()"); 38 | int size2 = numberList.size(); // Compliant with this rule 39 | i++; 40 | } 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /src/test/java/org/greencodeinitiative/creedengo/java/checks/AvoidUsageOfStaticCollectionsTests.java: -------------------------------------------------------------------------------- 1 | /* 2 | * creedengo - Java language - Provides rules to reduce the environmental footprint of your Java programs 3 | * Copyright © 2024 Green Code Initiative (https://green-code-initiative.org/) 4 | * 5 | * This program is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU General Public License as published by 7 | * the Free Software Foundation, either version 3 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU General Public License 16 | * along with this program. If not, see . 17 | */ 18 | package org.greencodeinitiative.creedengo.java.checks; 19 | 20 | import org.junit.jupiter.api.Test; 21 | import org.sonar.java.checks.verifier.CheckVerifier; 22 | 23 | class AvoidUsageOfStaticCollectionsTests { 24 | 25 | @Test 26 | void testHasIssues() { 27 | CheckVerifier.newVerifier() 28 | .onFile("src/test/files/AvoidUsageOfStaticCollections.java") 29 | .withCheck(new AvoidUsageOfStaticCollections()) 30 | .verifyIssues(); 31 | } 32 | 33 | @Test 34 | void testNoIssues() { 35 | CheckVerifier.newVerifier() 36 | .onFile("src/test/files/AvoidUsageOfStaticCollectionsGoodWay.java") 37 | .withCheck(new AvoidUsageOfStaticCollections()) 38 | .verifyNoIssues(); 39 | } 40 | 41 | } 42 | -------------------------------------------------------------------------------- /src/test/java/org/greencodeinitiative/creedengo/java/checks/FreeResourcesOfAutoCloseableInterfaceTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * creedengo - Java language - Provides rules to reduce the environmental footprint of your Java programs 3 | * Copyright © 2024 Green Code Initiative (https://green-code-initiative.org/) 4 | * 5 | * This program is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU General Public License as published by 7 | * the Free Software Foundation, either version 3 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU General Public License 16 | * along with this program. If not, see . 17 | */ 18 | package org.greencodeinitiative.creedengo.java.checks; 19 | 20 | import org.junit.jupiter.api.Test; 21 | import org.sonar.java.checks.verifier.CheckVerifier; 22 | 23 | class FreeResourcesOfAutoCloseableInterfaceTest { 24 | 25 | @Test 26 | void test() { 27 | CheckVerifier.newVerifier() 28 | .onFile("src/test/files/FreeResourcesOfAutoCloseableInterface.java") 29 | .withCheck(new FreeResourcesOfAutoCloseableInterface()) 30 | .withJavaVersion(7) 31 | .verifyIssues(); 32 | } 33 | 34 | @Test 35 | void test_no_java_version() { 36 | CheckVerifier.newVerifier() 37 | .onFile("src/test/files/FreeResourcesOfAutoCloseableInterface.java") 38 | .withCheck(new FreeResourcesOfAutoCloseableInterface()) 39 | .verifyIssues(); 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /Dockerfile: -------------------------------------------------------------------------------- 1 | ARG MAVEN_BUILDER=3-openjdk-17-slim 2 | 3 | #ARG SONARQUBE_VERSION=9.9.0-community 4 | #ARG SONARQUBE_VERSION=24.12.0.100206-community 5 | #ARG SONARQUBE_VERSION=25.1.0.102122-community 6 | #ARG SONARQUBE_VERSION=25.2.0.102705-community 7 | #ARG SONARQUBE_VERSION=25.3.0.104237-community 8 | ARG SONARQUBE_VERSION=25.9.0.112764-community 9 | 10 | FROM maven:${MAVEN_BUILDER} AS builder 11 | 12 | COPY . /usr/src/creedengo 13 | 14 | WORKDIR /usr/src/creedengo 15 | COPY src src/ 16 | COPY pom.xml tool_build.sh ./ 17 | 18 | RUN ./tool_build.sh 19 | 20 | FROM sonarqube:${SONARQUBE_VERSION} 21 | 22 | COPY --from=builder /usr/src/creedengo/target/creedengo-*.jar /opt/sonarqube/extensions/plugins/ 23 | 24 | # Install the ca-certificate package 25 | USER root 26 | # RUN apt-get update && apt-get install -y ca-certificates 27 | # Copy SSL certificates to the container 28 | COPY downloads-sonarsource.crt /usr/local/share/ca-certificates/ 29 | # Update SSL certificates in system inside the container 30 | # RUN update-ca-certificates 31 | 32 | ## Update SSL certificates in the JDK inside the container 33 | RUN $JAVA_HOME/bin/keytool -import -trustcacerts -file /usr/local/share/ca-certificates/downloads-sonarsource.crt -alias downloads-sonarsource -keystore $JAVA_HOME/lib/security/cacerts -storepass changeit -noprompt 34 | 35 | ## Process manuel 36 | # GENERATION CERTIFICAT 37 | # openssl s_client -showcerts -connect downloads.sonarsource.com:443 /dev/null | openssl x509 > downloads-sonarsource.crt 38 | # COPIE CERTIFICAT SUR CONTENEUR 39 | # dk cp downloads-sonarsource.crt sonar_creedengo_java:/tmp/. 40 | # AJOUT CERTIFICAT DANS LE KEYSTORE (en root) 41 | # dk exec -u root -it sonar_creedengo_java /bin/bash 42 | # $JAVA_HOME/bin/keytool -import -trustcacerts -file /tmp/downloads-sonarsource.crt -alias downloads-sonarsource -keystore $JAVA_HOME/lib/security/cacerts -storepass changeit -noprompt 43 | # RELANCE CONTENEUR pour relancer le service sonarqube 44 | 45 | USER sonarqube -------------------------------------------------------------------------------- /src/test/java/org/greencodeinitiative/creedengo/java/checks/AvoidRegexPatternNotStaticTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * creedengo - Java language - Provides rules to reduce the environmental footprint of your Java programs 3 | * Copyright © 2024 Green Code Initiative (https://green-code-initiative.org/) 4 | * 5 | * This program is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU General Public License as published by 7 | * the Free Software Foundation, either version 3 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU General Public License 16 | * along with this program. If not, see . 17 | */ 18 | package org.greencodeinitiative.creedengo.java.checks; 19 | 20 | import org.junit.jupiter.api.Test; 21 | import org.sonar.java.checks.verifier.CheckVerifier; 22 | 23 | class AvoidRegexPatternNotStaticTest { 24 | 25 | @Test 26 | void testHasIssues() { 27 | CheckVerifier.newVerifier() 28 | .onFile("src/test/files/AvoidRegexPatternNotStatic.java") 29 | .withCheck(new AvoidRegexPatternNotStatic()) 30 | .verifyIssues(); 31 | } 32 | 33 | @Test 34 | void testHasNoIssues() { 35 | CheckVerifier.newVerifier() 36 | .onFiles( 37 | "src/test/files/AvoidRegexPatternNotStaticValid1.java", 38 | "src/test/files/AvoidRegexPatternNotStaticValid2.java", 39 | "src/test/files/AvoidRegexPatternNotStaticValid3.java" 40 | ) 41 | .withCheck(new AvoidRegexPatternNotStatic()) 42 | .verifyNoIssues(); 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /src/test/files/InitializeBufferWithAppropriateSize.java: -------------------------------------------------------------------------------- 1 | /* 2 | * creedengo - Java language - Provides rules to reduce the environmental footprint of your Java programs 3 | * Copyright © 2024 Green Code Initiative (https://green-code-initiative.org/) 4 | * 5 | * This program is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU General Public License as published by 7 | * the Free Software Foundation, either version 3 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU General Public License 16 | * along with this program. If not, see . 17 | */ 18 | package org.greencodeinitiative.creedengo.java.checks; 19 | 20 | import java.sql.Connection; 21 | import java.sql.DriverManager; 22 | import java.sql.ResultSet; 23 | import java.sql.Statement; 24 | 25 | class InitializeBufferWithAppropriateSize { 26 | InitializeBufferWithAppropriateSize(InitializeBufferWithAppropriateSize mc) { 27 | } 28 | 29 | public void testBufferCompliant() { 30 | StringBuffer stringBuffer = new StringBuffer(16); 31 | } 32 | 33 | public void testBufferCompliant2() { 34 | StringBuffer stringBuffer = new StringBuffer(Integer.valueOf(16)); 35 | } 36 | 37 | public void testBufferNonCompliant() { 38 | StringBuffer stringBuffer = new StringBuffer(); // Noncompliant {{Initialize StringBuilder or StringBuffer with appropriate size}} 39 | } 40 | 41 | public void testBuilderCompliant() { 42 | StringBuilder stringBuilder = new StringBuilder(16); 43 | } 44 | 45 | public void testBuilderNonCompliant() { 46 | StringBuilder stringBuilder = new StringBuilder(); // Noncompliant {{Initialize StringBuilder or StringBuffer with appropriate size}} 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /src/main/java/org/greencodeinitiative/creedengo/java/JavaCreedengoWayProfile.java: -------------------------------------------------------------------------------- 1 | /* 2 | * creedengo - Java language - Provides rules to reduce the environmental footprint of your Java programs 3 | * Copyright © 2024 Green Code Initiative (https://green-code-initiative.org/) 4 | * 5 | * This program is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU General Public License as published by 7 | * the Free Software Foundation, either version 3 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU General Public License 16 | * along with this program. If not, see . 17 | */ 18 | package org.greencodeinitiative.creedengo.java; 19 | 20 | import org.sonar.api.server.profile.BuiltInQualityProfilesDefinition; 21 | import org.sonarsource.analyzer.commons.BuiltInQualityProfileJsonLoader; 22 | 23 | import static org.greencodeinitiative.creedengo.java.JavaRulesDefinition.LANGUAGE; 24 | import static org.greencodeinitiative.creedengo.java.JavaRulesDefinition.REPOSITORY_KEY; 25 | 26 | public final class JavaCreedengoWayProfile implements BuiltInQualityProfilesDefinition { 27 | static final String PROFILE_NAME = "creedengo way"; 28 | static final String PROFILE_PATH = JavaCreedengoWayProfile.class.getPackageName().replace('.', '/') + "/creedengo_way_profile.json"; 29 | 30 | @Override 31 | public void define(Context context) { 32 | NewBuiltInQualityProfile creedengoProfile = context.createBuiltInQualityProfile(PROFILE_NAME, LANGUAGE); 33 | loadProfile(creedengoProfile); 34 | creedengoProfile.done(); 35 | } 36 | 37 | private void loadProfile(NewBuiltInQualityProfile profile) { 38 | BuiltInQualityProfileJsonLoader.load(profile, REPOSITORY_KEY, PROFILE_PATH); 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /src/test/files/FreeResourcesOfAutoCloseableInterface.java: -------------------------------------------------------------------------------- 1 | /* 2 | * creedengo - Java language - Provides rules to reduce the environmental footprint of your Java programs 3 | * Copyright © 2024 Green Code Initiative (https://green-code-initiative.org/) 4 | * 5 | * This program is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU General Public License as published by 7 | * the Free Software Foundation, either version 3 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU General Public License 16 | * along with this program. If not, see . 17 | */ 18 | package org.greencodeinitiative.creedengo.java.checks; 19 | 20 | import java.io.*; 21 | 22 | class FreeResourcesOfAutoCloseableInterface { 23 | FreeResourcesOfAutoCloseableInterface(FreeResourcesOfAutoCloseableInterface mc) { 24 | 25 | } 26 | 27 | public void foo1() { 28 | String fileName = "./FreeResourcesOfAutoCloseableInterface.java"; 29 | try (FileReader fr = new FileReader(fileName); 30 | BufferedReader br = new BufferedReader(fr)) { 31 | } catch (IOException e) { 32 | System.err.println(e.getMessage()); 33 | } 34 | } 35 | 36 | public void foo2() { 37 | String fileName = "./FreeResourcesOfAutoCloseableInterface.java"; 38 | try { // Noncompliant 39 | FileReader fr = new FileReader(fileName); 40 | BufferedReader br = new BufferedReader(fr); 41 | System.out.printl(br.readLine()); 42 | } catch (IOException e) { 43 | System.err.println(e.getMessage()); 44 | } finally { 45 | if (fr) { 46 | org.close(); 47 | } 48 | if (br) { 49 | br.close(); 50 | } 51 | } 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /src/test/java/org/greencodeinitiative/creedengo/java/JavaCheckRegistrarTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * creedengo - Java language - Provides rules to reduce the environmental footprint of your Java programs 3 | * Copyright © 2024 Green Code Initiative (https://green-code-initiative.org/) 4 | * 5 | * This program is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU General Public License as published by 7 | * the Free Software Foundation, either version 3 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU General Public License 16 | * along with this program. If not, see . 17 | */ 18 | package org.greencodeinitiative.creedengo.java; 19 | 20 | import java.util.Set; 21 | 22 | import org.junit.jupiter.api.Test; 23 | import org.reflections.Reflections; 24 | import org.sonar.check.Rule; 25 | import org.sonar.plugins.java.api.CheckRegistrar; 26 | 27 | import static org.assertj.core.api.Assertions.assertThat; 28 | 29 | class JavaCheckRegistrarTest { 30 | 31 | @Test 32 | void checkNumberRules() { 33 | final CheckRegistrar.RegistrarContext context = new CheckRegistrar.RegistrarContext(); 34 | 35 | final JavaCheckRegistrar registrar = new JavaCheckRegistrar(); 36 | registrar.register(context); 37 | assertThat(context.checkClasses()) 38 | .describedAs("All implemented rules must be registered into " + JavaCheckRegistrar.class) 39 | .containsExactlyInAnyOrder(getDefinedRules().toArray(new Class[0])); 40 | assertThat(context.testCheckClasses()).isEmpty(); 41 | 42 | } 43 | 44 | static Set> getDefinedRules() { 45 | Reflections r = new Reflections(JavaCheckRegistrar.class.getPackageName() + ".checks"); 46 | return r.getTypesAnnotatedWith(Rule.class); 47 | } 48 | 49 | } 50 | -------------------------------------------------------------------------------- /src/test/files/AvoidFullSQLRequestCheck.java: -------------------------------------------------------------------------------- 1 | /* 2 | * creedengo - Java language - Provides rules to reduce the environmental footprint of your Java programs 3 | * Copyright © 2024 Green Code Initiative (https://green-code-initiative.org/) 4 | * 5 | * This program is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU General Public License as published by 7 | * the Free Software Foundation, either version 3 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU General Public License 16 | * along with this program. If not, see . 17 | */ 18 | package org.greencodeinitiative.creedengo.java.checks; 19 | 20 | import java.util.regex.Pattern; 21 | 22 | class AvoidFullSQLRequestCheck { 23 | AvoidFullSQLRequestCheck(AvoidFullSQLRequestCheck mc) { 24 | } 25 | 26 | public void literalSQLrequest() { 27 | dummyCall(" sElEcT * fRoM myTable"); // Noncompliant {{Don't use the query SELECT * FROM}} 28 | dummyCall(" sElEcT user fRoM myTable"); 29 | 30 | dummyCall("SELECTABLE 2*2 FROMAGE"); //not sql 31 | dummyCall("SELECT *FROM table"); // Noncompliant {{Don't use the query SELECT * FROM}} 32 | } 33 | 34 | 35 | public void variableSQLrequest() { 36 | String requestNonCompiliant = " SeLeCt * FrOm myTable"; // Noncompliant {{Don't use the query SELECT * FROM}} 37 | String requestCompiliant = " SeLeCt user FrOm myTable"; 38 | dummyCall(requestNonCompiliant); 39 | dummyCall(requestCompiliant); 40 | 41 | String noSqlCompiliant = "SELECTABLE 2*2 FROMAGE"; //not sql 42 | String requestNonCompiliant_nSpace = "SELECT *FROM table"; // Noncompliant {{Don't use the query SELECT * FROM}} 43 | } 44 | 45 | private void dummyCall(String request) { 46 | 47 | } 48 | 49 | } 50 | -------------------------------------------------------------------------------- /src/it/test-projects/creedengo-java-plugin-test-project/src/main/java/org/greencodeinitiative/creedengo/java/checks/IncrementCheck.java: -------------------------------------------------------------------------------- 1 | package org.greencodeinitiative.creedengo.java.checks; 2 | 3 | class IncrementCheck { 4 | IncrementCheck(IncrementCheck mc) { 5 | } 6 | 7 | int foo1() { 8 | int counter = 0; 9 | return counter++; // Noncompliant {{Use ++i instead of i++}} 10 | } 11 | 12 | private int j = 0; 13 | int foo10() { 14 | return this.j++; // Compliant because maybe the use case needs to return j AND increment it 15 | } 16 | 17 | int foo11() { 18 | int counter = 0; 19 | return ++counter; 20 | } 21 | 22 | int foo2() { 23 | int counter = 0; 24 | counter++; // Noncompliant {{Use ++i instead of i++}} 25 | return counter; 26 | } 27 | 28 | int foo22() { 29 | int counter = 0; 30 | ++counter; 31 | return counter; 32 | } 33 | 34 | int foo3() { 35 | int counter = 0; 36 | counter = counter + 197845 ; 37 | return counter; 38 | } 39 | 40 | int foo4() { 41 | int counter = 0; 42 | counter = counter + 35 + 78 ; 43 | return counter; 44 | } 45 | 46 | void foo50() { 47 | for (int i=0; i < 10; i++) { // Noncompliant {{Use ++i instead of i++}} 48 | System.out.println(i); //NOSONAR 49 | } 50 | } 51 | 52 | void foo51() { 53 | for (int i=0; i < 10; ++i) { 54 | System.out.println(i); //NOSONAR 55 | } 56 | } 57 | 58 | void bar61(int value) { 59 | // For test purpose 60 | } 61 | 62 | int foo61() { 63 | int i = 0; 64 | bar61(i++); // Compliant because maybe bar61 needs the unincremented value 65 | return i; 66 | } 67 | 68 | int foo62() { 69 | int i = 0; 70 | bar61(2 + i++); // Compliant because maybe bar61 needs the unincremented value 71 | return i; 72 | } 73 | 74 | void foo71() { 75 | int counter = 0; 76 | int a = 2 + counter++; // Compliant because we probably want to increment counter 77 | // then to add it to 2 to initialize a 78 | } 79 | } 80 | -------------------------------------------------------------------------------- /src/test/files/AvoidSpringRepositoryCallInLoopCheck.java: -------------------------------------------------------------------------------- 1 | /* 2 | * creedengo - Java language - Provides rules to reduce the environmental footprint of your Java programs 3 | * Copyright © 2024 Green Code Initiative (https://green-code-initiative.org/) 4 | * 5 | * This program is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU General Public License as published by 7 | * the Free Software Foundation, either version 3 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU General Public License 16 | * along with this program. If not, see . 17 | */ 18 | package org.greencodeinitiative.creedengo.java.checks; 19 | 20 | import org.springframework.beans.factory.annotation.Autowired; 21 | import org.springframework.data.jpa.repository.JpaRepository; 22 | 23 | import java.util.*; 24 | 25 | public class AvoidSpringRepositoryCallInLoopCheck { 26 | @Autowired 27 | private EmployeeRepository employeeRepository; 28 | 29 | public List smellGetAllEmployeesByIds(List ids) { 30 | List employees = new ArrayList<>(); 31 | for (Integer id : ids) { 32 | Optional employee = employeeRepository.findById(id); // Noncompliant {{Avoid Spring repository call in loop or stream}} 33 | if (employee.isPresent()) { 34 | employees.add(employee.get()); 35 | } 36 | } 37 | return employees; 38 | } 39 | 40 | public class Employee { 41 | private Integer id; 42 | private String name; 43 | 44 | public Employee(Integer id, String name) { 45 | this.id = id; 46 | this.name = name; 47 | } 48 | 49 | public Integer getId() { return id; } 50 | public String getName() { return name; } 51 | } 52 | 53 | public interface EmployeeRepository extends JpaRepository { 54 | 55 | } 56 | 57 | } 58 | -------------------------------------------------------------------------------- /src/it/test-projects/creedengo-java-plugin-test-project/src/main/java/org/greencodeinitiative/creedengo/java/checks/AvoidMultipleIfElseStatementCompareMethodNoIssue.java: -------------------------------------------------------------------------------- 1 | package org.greencodeinitiative.creedengo.java.checks; 2 | 3 | class AvoidMultipleIfElseStatementCompareMethodNoIssue { 4 | 5 | public int compare(FieldVo o1, FieldVo o2) { 6 | 7 | if (o1.getIdBlock().equals(o2.getIdBlock())) { 8 | if (o1.getIdField().equals(o2.getIdField())) { 9 | return 0; 10 | } 11 | // First original 12 | if (o1.isOriginal() && !o2.isOriginal()) { 13 | return -1; 14 | } else if (!o1.isOriginal() && o2.isOriginal()) { 15 | return 1; 16 | } 17 | // First min posgafld 18 | Long result = o1.getColumnPos() - o2.getColumnPos(); 19 | if (result != 0) { 20 | return result.intValue(); 21 | } 22 | 23 | // First min ordgaflc 24 | result = o1.getIndex() - o2.getIndex(); 25 | return result.intValue(); 26 | } 27 | // First BQRY block 28 | if (o1.getIdBlock().startsWith("BQRY") && !o2.getIdBlock().startsWith("BQRY")) { 29 | return -1; 30 | } else if (!o1.getIdBlock().startsWith("BQRY") && o2.getIdBlock().startsWith("BQRY")) { 31 | return 1; 32 | } 33 | // If both block don't start with BQRY, sort alpha with String.compareTo method 34 | return o1.getIdBlock().compareTo(o2.getIdBlock()); 35 | } 36 | 37 | public static class FieldVo { 38 | 39 | private String idBlock; 40 | 41 | private String idField; 42 | 43 | private boolean original; 44 | 45 | private long columnPos; 46 | 47 | private long index; 48 | 49 | public String getIdBlock() { 50 | return idBlock; 51 | } 52 | 53 | public String getIdField() { 54 | return idField; 55 | } 56 | 57 | public boolean isOriginal() { 58 | return original; 59 | } 60 | 61 | public long getColumnPos() { 62 | return columnPos; 63 | } 64 | 65 | public long getIndex() { 66 | return index; 67 | } 68 | } 69 | 70 | } 71 | -------------------------------------------------------------------------------- /src/test/files/AvoidMultipleIfElseStatementCompareMethod.java: -------------------------------------------------------------------------------- 1 | /* 2 | * creedengo - Java language - Provides rules to reduce the environmental footprint of your Java programs 3 | * Copyright © 2024 Green Code Initiative (https://green-code-initiative.org/) 4 | * 5 | * This program is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU General Public License as published by 7 | * the Free Software Foundation, either version 3 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU General Public License 16 | * along with this program. If not, see . 17 | */ 18 | package org.greencodeinitiative.creedengo.java.checks; 19 | 20 | class AvoidMultipleIfElseStatementCompareMethod { 21 | 22 | public int compare(FieldVo o1, FieldVo o2) { 23 | 24 | if (o1.getIdBlock().equals(o2.getIdBlock())) { 25 | if (o1.getIdField().equals(o2.getIdField())) { 26 | return 0; 27 | } 28 | // First original 29 | if (o1.isOriginal() && !o2.isOriginal()) { 30 | return -1; 31 | } else if (!o1.isOriginal() && o2.isOriginal()) { 32 | return 1; 33 | } 34 | // First min posgafld 35 | Long result = o1.getColumnPos() - o2.getColumnPos(); 36 | if (result != 0) { 37 | return result.intValue(); 38 | } 39 | 40 | // First min ordgaflc 41 | result = o1.getIndex() - o2.getIndex(); 42 | return result.intValue(); 43 | } 44 | // First BQRY block 45 | if (o1.getIdBlock().startsWith("BQRY") && !o2.getIdBlock().startsWith("BQRY")) { 46 | return -1; 47 | } else if (!o1.getIdBlock().startsWith("BQRY") && o2.getIdBlock().startsWith("BQRY")) { 48 | return 1; 49 | } 50 | // If both block don't start with BQRY, sort alpha with String.compareTo method 51 | return o1.getIdBlock().compareTo(o2.getIdBlock()); 52 | } 53 | 54 | } 55 | -------------------------------------------------------------------------------- /src/it/test-projects/creedengo-java-plugin-test-project/src/main/java/org/greencodeinitiative/creedengo/java/checks/AvoidSpringRepositoryCallInLoopCheck.java: -------------------------------------------------------------------------------- 1 | /* 2 | * creedengo - Java language - Provides rules to reduce the environmental footprint of your Java programs 3 | * Copyright © 2024 Green Code Initiative (https://green-code-initiative.org/) 4 | * 5 | * This program is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU General Public License as published by 7 | * the Free Software Foundation, either version 3 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU General Public License 16 | * along with this program. If not, see . 17 | */ 18 | package org.greencodeinitiative.creedengo.java.checks; 19 | 20 | import org.springframework.beans.factory.annotation.Autowired; 21 | import org.springframework.data.jpa.repository.JpaRepository; 22 | 23 | import java.util.*; 24 | 25 | public class AvoidSpringRepositoryCallInLoopCheck { 26 | @Autowired 27 | private EmployeeRepository employeeRepository; 28 | 29 | public List smellGetAllEmployeesByIds(List ids) { 30 | List employees = new ArrayList<>(); 31 | for (Integer id : ids) { 32 | Optional employee = employeeRepository.findById(id); // Noncompliant {{Avoid Spring repository call in loop or stream}} 33 | if (employee.isPresent()) { 34 | employees.add(employee.get()); 35 | } 36 | } 37 | return employees; 38 | } 39 | 40 | public class Employee { 41 | private Integer id; 42 | private String name; 43 | 44 | public Employee(Integer id, String name) { 45 | this.id = id; 46 | this.name = name; 47 | } 48 | 49 | public Integer getId() { return id; } 50 | public String getName() { return name; } 51 | } 52 | 53 | public interface EmployeeRepository extends JpaRepository { 54 | 55 | } 56 | 57 | } 58 | -------------------------------------------------------------------------------- /src/main/java/org/greencodeinitiative/creedengo/java/checks/InitializeBufferWithAppropriateSize.java: -------------------------------------------------------------------------------- 1 | /* 2 | * creedengo - Java language - Provides rules to reduce the environmental footprint of your Java programs 3 | * Copyright © 2024 Green Code Initiative (https://green-code-initiative.org/) 4 | * 5 | * This program is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU General Public License as published by 7 | * the Free Software Foundation, either version 3 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU General Public License 16 | * along with this program. If not, see . 17 | */ 18 | package org.greencodeinitiative.creedengo.java.checks; 19 | 20 | import java.util.Collections; 21 | import java.util.List; 22 | 23 | import org.sonar.check.Rule; 24 | import org.sonar.plugins.java.api.IssuableSubscriptionVisitor; 25 | import org.sonar.plugins.java.api.tree.NewClassTree; 26 | import org.sonar.plugins.java.api.tree.Tree; 27 | import org.sonar.plugins.java.api.tree.Tree.Kind; 28 | import org.sonarsource.analyzer.commons.annotations.DeprecatedRuleKey; 29 | 30 | @Rule(key = "GCI32") 31 | @DeprecatedRuleKey(repositoryKey = "ecocode-java", ruleKey = "EC32") 32 | @DeprecatedRuleKey(repositoryKey = "greencodeinitiative-java", ruleKey = "GRSP0032") 33 | public class InitializeBufferWithAppropriateSize extends IssuableSubscriptionVisitor { 34 | 35 | protected static final String RULE_MESSAGE = "Initialize StringBuilder or StringBuffer with appropriate size"; 36 | 37 | @Override 38 | public List nodesToVisit() { 39 | return Collections.singletonList(Kind.NEW_CLASS); 40 | } 41 | 42 | @Override 43 | public void visitNode(Tree tree) { 44 | NewClassTree newClassTree = (NewClassTree) tree; 45 | if ((newClassTree.symbolType().is("java.lang.StringBuffer") 46 | || newClassTree.symbolType().is("java.lang.StringBuilder")) 47 | && newClassTree.arguments().isEmpty()) { 48 | reportIssue(tree, RULE_MESSAGE); 49 | } 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /src/main/java/org/greencodeinitiative/creedengo/java/JavaRulesDefinition.java: -------------------------------------------------------------------------------- 1 | /* 2 | * creedengo - Java language - Provides rules to reduce the environmental footprint of your Java programs 3 | * Copyright © 2024 Green Code Initiative (https://green-code-initiative.org/) 4 | * 5 | * This program is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU General Public License as published by 7 | * the Free Software Foundation, either version 3 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU General Public License 16 | * along with this program. If not, see . 17 | */ 18 | package org.greencodeinitiative.creedengo.java; 19 | 20 | import java.util.ArrayList; 21 | 22 | import org.sonar.api.SonarRuntime; 23 | import org.sonar.api.server.rule.RulesDefinition; 24 | import org.sonarsource.analyzer.commons.RuleMetadataLoader; 25 | 26 | /** 27 | * Declare rule metadata in server repository of rules. 28 | * That allows to list the rules in the page "Rules". 29 | */ 30 | public class JavaRulesDefinition implements RulesDefinition { 31 | private static final String RESOURCE_BASE_PATH = "org/green-code-initiative/rules/java"; 32 | 33 | private static final String NAME = "creedengo"; 34 | static final String LANGUAGE = "java"; 35 | static final String REPOSITORY_KEY = "creedengo-java"; 36 | 37 | private final SonarRuntime sonarRuntime; 38 | 39 | public JavaRulesDefinition(SonarRuntime sonarRuntime) { 40 | this.sonarRuntime = sonarRuntime; 41 | } 42 | 43 | @Override 44 | public void define(Context context) { 45 | NewRepository repository = context.createRepository(REPOSITORY_KEY, LANGUAGE).setName(NAME); 46 | 47 | RuleMetadataLoader ruleMetadataLoader = new RuleMetadataLoader(RESOURCE_BASE_PATH, sonarRuntime); 48 | 49 | ruleMetadataLoader.addRulesByAnnotatedClass(repository, new ArrayList<>(JavaCheckRegistrar.checkClasses())); 50 | repository.done(); 51 | } 52 | 53 | public String repositoryKey() { 54 | return REPOSITORY_KEY; 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /src/main/java/org/greencodeinitiative/creedengo/java/checks/IncrementCheck.java: -------------------------------------------------------------------------------- 1 | /* 2 | * creedengo - Java language - Provides rules to reduce the environmental footprint of your Java programs 3 | * Copyright © 2024 Green Code Initiative (https://green-code-initiative.org/) 4 | * 5 | * This program is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU General Public License as published by 7 | * the Free Software Foundation, either version 3 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU General Public License 16 | * along with this program. If not, see . 17 | */ 18 | package org.greencodeinitiative.creedengo.java.checks; 19 | 20 | import java.util.Collections; 21 | import java.util.List; 22 | 23 | import org.sonar.check.Rule; 24 | import org.sonar.plugins.java.api.IssuableSubscriptionVisitor; 25 | import org.sonar.plugins.java.api.tree.Arguments; 26 | import org.sonar.plugins.java.api.tree.BinaryExpressionTree; 27 | import org.sonar.plugins.java.api.tree.Tree; 28 | import org.sonar.plugins.java.api.tree.UnaryExpressionTree; 29 | import org.sonar.plugins.java.api.tree.Tree.Kind; 30 | import org.sonarsource.analyzer.commons.annotations.DeprecatedRuleKey; 31 | 32 | @Rule(key = "GCI67") 33 | @DeprecatedRuleKey(repositoryKey = "ecocode-java", ruleKey = "EC67") 34 | @DeprecatedRuleKey(repositoryKey = "greencodeinitiative-java", ruleKey = "S67") 35 | public class IncrementCheck extends IssuableSubscriptionVisitor { 36 | 37 | protected static final String MESSAGERULE = "Use ++i instead of i++"; 38 | 39 | @Override 40 | public List nodesToVisit() { 41 | return Collections.singletonList(Kind.POSTFIX_INCREMENT); 42 | } 43 | 44 | @Override 45 | public void visitNode(Tree tree) { 46 | UnaryExpressionTree unaryExprTree = (UnaryExpressionTree) tree; 47 | 48 | if (unaryExprTree.parent() instanceof BinaryExpressionTree 49 | || unaryExprTree.parent() instanceof Arguments 50 | || unaryExprTree.expression().is(Tree.Kind.MEMBER_SELECT)) { 51 | return ; 52 | } 53 | reportIssue(tree, MESSAGERULE); 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /src/main/java/org/greencodeinitiative/creedengo/java/checks/AvoidFullSQLRequest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * creedengo - Java language - Provides rules to reduce the environmental footprint of your Java programs 3 | * Copyright © 2024 Green Code Initiative (https://green-code-initiative.org/) 4 | * 5 | * This program is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU General Public License as published by 7 | * the Free Software Foundation, either version 3 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU General Public License 16 | * along with this program. If not, see . 17 | */ 18 | package org.greencodeinitiative.creedengo.java.checks; 19 | 20 | import java.util.List; 21 | import java.util.function.Predicate; 22 | 23 | import static java.util.Collections.singletonList; 24 | import static java.util.regex.Pattern.CASE_INSENSITIVE; 25 | import static java.util.regex.Pattern.compile; 26 | 27 | import org.sonar.check.Rule; 28 | import org.sonar.plugins.java.api.IssuableSubscriptionVisitor; 29 | import org.sonar.plugins.java.api.tree.LiteralTree; 30 | import org.sonar.plugins.java.api.tree.Tree; 31 | import org.sonar.plugins.java.api.tree.Tree.Kind; 32 | import org.sonarsource.analyzer.commons.annotations.DeprecatedRuleKey; 33 | 34 | @Rule(key = "GCI74") 35 | @DeprecatedRuleKey(repositoryKey = "ecocode-java", ruleKey = "EC74") 36 | @DeprecatedRuleKey(repositoryKey = "greencodeinitiative-java", ruleKey = "S74") 37 | public class AvoidFullSQLRequest extends IssuableSubscriptionVisitor { 38 | 39 | protected static final String MESSAGERULE = "Don't use the query SELECT * FROM"; 40 | private static final Predicate SELECT_FROM_REGEXP = 41 | compile("select\\s*\\*\\s*from", CASE_INSENSITIVE).asPredicate(); //simple regexp, more precision 42 | 43 | @Override 44 | public List nodesToVisit() { 45 | return singletonList(Tree.Kind.STRING_LITERAL); 46 | } 47 | 48 | @Override 49 | public void visitNode(Tree tree) { 50 | String value = ((LiteralTree) tree).value(); 51 | if (SELECT_FROM_REGEXP.test(value)) { 52 | reportIssue(tree, MESSAGERULE); 53 | } 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /src/test/java/org/greencodeinitiative/creedengo/java/checks/OptimizeReadFileExceptionCheckTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * creedengo - Java language - Provides rules to reduce the environmental footprint of your Java programs 3 | * Copyright © 2024 Green Code Initiative (https://green-code-initiative.org/) 4 | * 5 | * This program is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU General Public License as published by 7 | * the Free Software Foundation, either version 3 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU General Public License 16 | * along with this program. If not, see . 17 | */ 18 | package org.greencodeinitiative.creedengo.java.checks; 19 | 20 | import org.junit.jupiter.api.Test; 21 | import org.sonar.java.checks.verifier.CheckVerifier; 22 | 23 | class OptimizeReadFileExceptionCheckTest { 24 | 25 | @Test 26 | void test() { 27 | CheckVerifier.newVerifier() 28 | .onFile("src/test/files/OptimizeReadFileExceptionCheck.java") 29 | .withCheck(new OptimizeReadFileExceptions()) 30 | .verifyIssues(); 31 | } 32 | 33 | @Test 34 | void test2() { 35 | CheckVerifier.newVerifier() 36 | .onFile("src/test/files/OptimizeReadFileExceptionCheck2.java") 37 | .withCheck(new OptimizeReadFileExceptions()) 38 | .verifyIssues(); 39 | } 40 | 41 | @Test 42 | void test3() { 43 | CheckVerifier.newVerifier() 44 | .onFile("src/test/files/OptimizeReadFileExceptionCheck3.java") 45 | .withCheck(new OptimizeReadFileExceptions()) 46 | .verifyIssues(); 47 | } 48 | 49 | @Test 50 | void test4() { 51 | CheckVerifier.newVerifier() 52 | .onFile("src/test/files/OptimizeReadFileExceptionCheck4.java") 53 | .withCheck(new OptimizeReadFileExceptions()) 54 | .verifyIssues(); 55 | } 56 | 57 | @Test 58 | void test5() { 59 | CheckVerifier.newVerifier() 60 | .onFile("src/test/files/OptimizeReadFileExceptionCheck5.java") 61 | .withCheck(new OptimizeReadFileExceptions()) 62 | .verifyIssues(); 63 | } 64 | 65 | } 66 | -------------------------------------------------------------------------------- /src/test/java/org/greencodeinitiative/creedengo/java/checks/AvoidMultipleIfElseStatementTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * creedengo - Java language - Provides rules to reduce the environmental footprint of your Java programs 3 | * Copyright © 2024 Green Code Initiative (https://green-code-initiative.org/) 4 | * 5 | * This program is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU General Public License as published by 7 | * the Free Software Foundation, either version 3 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU General Public License 16 | * along with this program. If not, see . 17 | */ 18 | package org.greencodeinitiative.creedengo.java.checks; 19 | 20 | import org.junit.jupiter.api.Test; 21 | import org.sonar.java.checks.verifier.CheckVerifier; 22 | 23 | class AvoidMultipleIfElseStatementTest { 24 | @Test 25 | void test() { 26 | CheckVerifier.newVerifier() 27 | .onFile("src/test/files/AvoidMultipleIfElseStatement.java") 28 | .withCheck(new AvoidMultipleIfElseStatement()) 29 | .verifyIssues(); 30 | CheckVerifier.newVerifier() 31 | .onFile("src/test/files/AvoidMultipleIfElseStatementNoIssue.java") 32 | .withCheck(new AvoidMultipleIfElseStatement()) 33 | .verifyNoIssues(); 34 | } 35 | 36 | @Test 37 | void testInterfaceMethodStatement() { 38 | CheckVerifier.newVerifier() 39 | .onFile("src/test/files/AvoidMultipleIfElseStatementInterface.java") 40 | .withCheck(new AvoidMultipleIfElseStatement()) 41 | .verifyNoIssues(); 42 | } 43 | 44 | @Test 45 | void testNotBlockStatement() { 46 | CheckVerifier.newVerifier() 47 | .onFile("src/test/files/AvoidMultipleIfElseStatementNotBlock.java") 48 | .withCheck(new AvoidMultipleIfElseStatement()) 49 | .verifyNoIssues(); 50 | } 51 | 52 | @Test 53 | void testCompareMethod() { 54 | CheckVerifier.newVerifier() 55 | .onFile("src/test/files/AvoidMultipleIfElseStatementCompareMethod.java") 56 | .withCheck(new AvoidMultipleIfElseStatement()) 57 | .verifyNoIssues(); 58 | } 59 | 60 | 61 | } 62 | -------------------------------------------------------------------------------- /.github/workflows/build_container.yml: -------------------------------------------------------------------------------- 1 | --- 2 | # template source: https://github.com/bretfisher/docker-build-workflow/blob/main/templates/call-docker-build.yaml 3 | name: Docker Build 4 | 5 | on: 6 | push: 7 | branches: 8 | - main 9 | tags: 10 | - '*' 11 | # pull_request: 12 | # branches: 13 | # - main 14 | 15 | env: 16 | # github.repository as / 17 | # IMAGE_NAME: sonarqube-creedengo 18 | # IMAGES: | 19 | # ghcr.io/${{ github.repository_owner }}/sonarqube-creedengo 20 | IMAGE_NAME: sonarqube-creedengo-java 21 | IMAGES: | 22 | ghcr.io/${{ github.repository_owner }}/sonarqube-creedengo-java 23 | 24 | jobs: 25 | Build: 26 | runs-on: ubuntu-latest 27 | if: github.event_name != 'pull_request' || github.event.pull_request.head.repo.full_name == github.repository 28 | permissions: 29 | contents: read 30 | packages: write 31 | # This is used to complete the identity challenge 32 | # with sigstore/fulcio when running outside of PRs. 33 | id-token: write 34 | 35 | steps: 36 | - name: Login to GitHub Container Registry 37 | uses: docker/login-action@v2 38 | with: 39 | registry: ghcr.io 40 | username: ${{ github.actor }} 41 | password: ${{ secrets.GITHUB_TOKEN }} 42 | 43 | - name: Checkout repository 44 | uses: actions/checkout@v3 45 | with: 46 | fetch-depth: 0 47 | 48 | - name: Set up QEMU 49 | uses: docker/setup-qemu-action@v2 50 | 51 | - name: Set up Docker Buildx 52 | uses: docker/setup-buildx-action@v2 53 | 54 | - name: Docker metadata 55 | id: meta 56 | uses: docker/metadata-action@v4 57 | with: 58 | github-token: ${{ secrets.GITHUB_TOKEN }} 59 | images: ${{ env.IMAGES }} 60 | flavor: | 61 | latest=auto 62 | tags: | 63 | type=raw,value=latest,enable=${{ github.ref == format('refs/heads/{0}', 'main') }} 64 | type=semver,event=tag,pattern={{version}} 65 | type=semver,event=tag,pattern={{major}}.{{minor}} 66 | type=semver,event=tag,pattern={{major}} 67 | type=ref,event=branch 68 | type=ref,event=pr 69 | type=sha 70 | 71 | - name: Publish image 72 | id: push 73 | uses: docker/build-push-action@v4 74 | with: 75 | push: true 76 | tags: ${{ steps.meta.outputs.tags }} 77 | labels: ${{ steps.meta.outputs.labels }} 78 | pull: true 79 | cache-to: type=gha,mode=max 80 | cache-from: type=gha,mode=max 81 | -------------------------------------------------------------------------------- /.github/workflows/tag_release.yml: -------------------------------------------------------------------------------- 1 | name: Tag Release 2 | 3 | on: 4 | push: 5 | tags: 6 | - '[0-9]+.[0-9]+.[0-9]+' 7 | 8 | jobs: 9 | checks: 10 | name: Requirements 11 | runs-on: ubuntu-latest 12 | steps: 13 | - name: Check user permissions 14 | uses: 74th/workflow-permission-action@1.0.0 15 | with: 16 | users: dedece35,glalloue,jhertout,jules-delecour-dav,olegoaer,zippy1978,utarwyn 17 | build: 18 | name: Build And Release 19 | runs-on: ubuntu-latest 20 | needs: checks 21 | outputs: 22 | upload_url: ${{ steps.create_release.outputs.upload_url }} 23 | steps: 24 | - name: Checkout tag "${{ github.ref_name }}" 25 | uses: actions/checkout@v3 26 | with: 27 | ref: ${{ github.ref_name }} 28 | - name: Extract release notes 29 | id: extract-release-notes 30 | uses: ffurrer2/extract-release-notes@v1 31 | - name: Build project 32 | run: ./mvnw -e -B clean package -DskipTests 33 | - name: Create release 34 | id: create_release 35 | uses: actions/create-release@v1 36 | env: 37 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 38 | with: 39 | tag_name: ${{ github.ref_name }} 40 | release_name: Release ${{ github.ref_name }} 41 | draft: false 42 | prerelease: false 43 | body: ${{ steps.extract-release-notes.outputs.release_notes }} 44 | - name: Export plugin Jar files 45 | id: export_jar_files 46 | uses: actions/upload-artifact@v4 47 | with: 48 | name: creedengo-plugins 49 | path: target 50 | - name: Export UPLOAD_URL 51 | id: export_upload_url 52 | run: echo "upload_url=${{ steps.create_release.outputs.upload_url }}" >> $GITHUB_OUTPUT 53 | 54 | upload: 55 | name: Upload Java Plugin 56 | runs-on: ubuntu-latest 57 | needs: build 58 | steps: 59 | - name: Import plugin JAR files 60 | id: import_jar_files 61 | uses: actions/download-artifact@v4 62 | with: 63 | name: creedengo-plugins 64 | path: target 65 | - name: Upload Release Asset - Java Plugin 66 | id: upload-release-asset 67 | uses: actions/upload-release-asset@v1 68 | env: 69 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 70 | with: 71 | upload_url: ${{needs.build.outputs.upload_url}} 72 | asset_path: target/creedengo-java-plugin-${{ github.ref_name }}.jar 73 | asset_name: creedengo-java-plugin-${{ github.ref_name }}.jar 74 | asset_content_type: application/zip 75 | -------------------------------------------------------------------------------- /src/main/java/org/greencodeinitiative/creedengo/java/utils/PrinterVisitor.java: -------------------------------------------------------------------------------- 1 | /* 2 | * creedengo - Java language - Provides rules to reduce the environmental footprint of your Java programs 3 | * Copyright © 2024 Green Code Initiative (https://green-code-initiative.org/) 4 | * 5 | * This program is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU General Public License as published by 7 | * the Free Software Foundation, either version 3 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU General Public License 16 | * along with this program. If not, see . 17 | */ 18 | package org.greencodeinitiative.creedengo.java.utils; 19 | 20 | import java.util.List; 21 | import java.util.function.Consumer; 22 | 23 | import javax.annotation.Nullable; 24 | 25 | import org.sonar.plugins.java.api.tree.BaseTreeVisitor; 26 | import org.sonar.plugins.java.api.tree.Tree; 27 | 28 | public class PrinterVisitor extends BaseTreeVisitor { 29 | private static final int INDENT_SPACES = 2; 30 | 31 | private final StringBuilder sb; 32 | private int indentLevel; 33 | 34 | public PrinterVisitor() { 35 | sb = new StringBuilder(); 36 | indentLevel = 0; 37 | } 38 | 39 | public static void print(Tree tree, Consumer output) { 40 | PrinterVisitor pv = new PrinterVisitor(); 41 | pv.scan(tree); 42 | output.accept(pv.sb.toString()); 43 | } 44 | 45 | private StringBuilder indent() { 46 | return sb.append(StringUtils.spaces(INDENT_SPACES * indentLevel)); 47 | } 48 | 49 | @Override 50 | protected void scan(List trees) { 51 | if (!trees.isEmpty()) { 52 | sb.deleteCharAt(sb.length() - 1); 53 | sb.append(" : [\n"); 54 | super.scan(trees); 55 | indent().append("]\n"); 56 | } 57 | } 58 | 59 | @Override 60 | protected void scan(@Nullable Tree tree) { 61 | if (tree != null) { 62 | Class[] interfaces = tree.getClass().getInterfaces(); 63 | if (interfaces.length > 0) { 64 | indent().append(interfaces[0].getSimpleName()).append("\n"); 65 | } 66 | } 67 | indentLevel++; 68 | super.scan(tree); 69 | indentLevel--; 70 | } 71 | } 72 | -------------------------------------------------------------------------------- /src/test/java/org/greencodeinitiative/creedengo/java/JavaCreedengoWayProfileTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * creedengo - Java language - Provides rules to reduce the environmental footprint of your Java programs 3 | * Copyright © 2024 Green Code Initiative (https://green-code-initiative.org/) 4 | * 5 | * This program is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU General Public License as published by 7 | * the Free Software Foundation, either version 3 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU General Public License 16 | * along with this program. If not, see . 17 | */ 18 | package org.greencodeinitiative.creedengo.java; 19 | 20 | import java.util.List; 21 | import java.util.stream.Collectors; 22 | 23 | import org.junit.jupiter.api.Test; 24 | import org.sonar.api.server.profile.BuiltInQualityProfilesDefinition; 25 | import org.sonar.check.Rule; 26 | 27 | import static org.greencodeinitiative.creedengo.java.JavaCheckRegistrarTest.getDefinedRules; 28 | import static org.greencodeinitiative.creedengo.java.JavaCreedengoWayProfile.PROFILE_NAME; 29 | import static org.greencodeinitiative.creedengo.java.JavaCreedengoWayProfile.PROFILE_PATH; 30 | import static org.greencodeinitiative.creedengo.java.JavaRulesDefinition.LANGUAGE; 31 | import static org.assertj.core.api.Assertions.assertThat; 32 | 33 | class JavaCreedengoWayProfileTest { 34 | @Test 35 | void should_create_creedengo_profile() { 36 | BuiltInQualityProfilesDefinition.Context context = new BuiltInQualityProfilesDefinition.Context(); 37 | 38 | JavaCreedengoWayProfile definition = new JavaCreedengoWayProfile(); 39 | definition.define(context); 40 | 41 | BuiltInQualityProfilesDefinition.BuiltInQualityProfile profile = context.profile(LANGUAGE, PROFILE_NAME); 42 | 43 | assertThat(profile.language()).isEqualTo(LANGUAGE); 44 | assertThat(profile.name()).isEqualTo(PROFILE_NAME); 45 | List definedRuleIds = getDefinedRules().stream().map(c -> c.getAnnotation(Rule.class).key()).collect(Collectors.toList()); 46 | assertThat(profile.rules()) 47 | .describedAs("All implemented rules must be declared in '%s' profile file: %s", PROFILE_NAME, PROFILE_PATH) 48 | .map(BuiltInQualityProfilesDefinition.BuiltInActiveRule::ruleKey) 49 | .containsExactlyInAnyOrderElementsOf(definedRuleIds); 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /src/main/java/org/greencodeinitiative/creedengo/java/checks/UseOptionalOrElseGetVsOrElse.java: -------------------------------------------------------------------------------- 1 | /* 2 | * creedengo - Java language - Provides rules to reduce the environmental footprint of your Java programs 3 | * Copyright © 2024 Green Code Initiative (https://green-code-initiative.org/) 4 | * 5 | * This program is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU General Public License as published by 7 | * the Free Software Foundation, either version 3 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU General Public License 16 | * along with this program. If not, see . 17 | */ 18 | package org.greencodeinitiative.creedengo.java.checks; 19 | 20 | import org.sonar.check.Rule; 21 | import org.sonar.plugins.java.api.IssuableSubscriptionVisitor; 22 | import org.sonar.plugins.java.api.tree.BaseTreeVisitor; 23 | import org.sonar.plugins.java.api.tree.MemberSelectExpressionTree; 24 | import org.sonar.plugins.java.api.tree.MethodInvocationTree; 25 | import org.sonar.plugins.java.api.tree.Tree; 26 | import javax.annotation.Nonnull; 27 | import java.util.Collections; 28 | import java.util.List; 29 | import java.util.Objects; 30 | 31 | @Rule(key = "GCI94") 32 | public class UseOptionalOrElseGetVsOrElse extends IssuableSubscriptionVisitor { 33 | 34 | private static final String MESSAGE_RULE = "Use optional orElseGet instead of orElse."; 35 | private final UseOptionalOrElseGetVsOrElseVisitor visitorInFile = new UseOptionalOrElseGetVsOrElseVisitor(); 36 | 37 | @Override 38 | public List nodesToVisit() { 39 | return Collections.singletonList(Tree.Kind.METHOD_INVOCATION); 40 | } 41 | 42 | @Override 43 | public void visitNode(@Nonnull Tree tree) { 44 | tree.accept(visitorInFile); 45 | } 46 | 47 | private class UseOptionalOrElseGetVsOrElseVisitor extends BaseTreeVisitor { 48 | @Override 49 | public void visitMethodInvocation(MethodInvocationTree tree) { 50 | if (tree.methodSelect().is(Tree.Kind.MEMBER_SELECT) && 51 | Objects.requireNonNull(tree.methodSelect().firstToken()).text().equals("Optional")) { 52 | MemberSelectExpressionTree memberSelect = (MemberSelectExpressionTree) tree.methodSelect(); 53 | if (memberSelect.identifier().name().equals("orElse")) { 54 | reportIssue(memberSelect, MESSAGE_RULE); 55 | } 56 | } 57 | } 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /src/main/java/org/greencodeinitiative/creedengo/java/checks/AvoidUsageOfStaticCollections.java: -------------------------------------------------------------------------------- 1 | /* 2 | * creedengo - Java language - Provides rules to reduce the environmental footprint of your Java programs 3 | * Copyright © 2024 Green Code Initiative (https://green-code-initiative.org/) 4 | * 5 | * This program is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU General Public License as published by 7 | * the Free Software Foundation, either version 3 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU General Public License 16 | * along with this program. If not, see . 17 | */ 18 | package org.greencodeinitiative.creedengo.java.checks; 19 | 20 | import java.util.Collections; 21 | import java.util.List; 22 | import java.util.Map; 23 | 24 | import javax.annotation.Nonnull; 25 | 26 | import org.sonar.check.Rule; 27 | import org.sonar.plugins.java.api.IssuableSubscriptionVisitor; 28 | import org.sonar.plugins.java.api.tree.BaseTreeVisitor; 29 | import org.sonar.plugins.java.api.tree.Tree; 30 | import org.sonar.plugins.java.api.tree.VariableTree; 31 | import org.sonarsource.analyzer.commons.annotations.DeprecatedRuleKey; 32 | 33 | @Rule(key = "GCI76") 34 | @DeprecatedRuleKey(repositoryKey = "ecocode-java", ruleKey = "EC76") 35 | @DeprecatedRuleKey(repositoryKey = "greencodeinitiative-java", ruleKey = "S76") 36 | public class AvoidUsageOfStaticCollections extends IssuableSubscriptionVisitor { 37 | 38 | protected static final String MESSAGE_RULE = "Avoid usage of static collections."; 39 | 40 | private final AvoidUsageOfStaticCollectionsVisitor visitor = new AvoidUsageOfStaticCollectionsVisitor(); 41 | 42 | @Override 43 | public List nodesToVisit() { 44 | return Collections.singletonList( 45 | Tree.Kind.VARIABLE 46 | ); 47 | } 48 | 49 | @Override 50 | public void visitNode(@Nonnull Tree tree) { 51 | tree.accept(visitor); 52 | } 53 | 54 | private class AvoidUsageOfStaticCollectionsVisitor extends BaseTreeVisitor { 55 | 56 | @Override 57 | public void visitVariable(@Nonnull VariableTree tree) { 58 | if (tree.symbol().isStatic() && 59 | (tree.type().symbolType().isSubtypeOf(Iterable.class.getName()) || 60 | tree.type().symbolType().is(Map.class.getName())) 61 | ) { 62 | reportIssue(tree, MESSAGE_RULE); 63 | } else { 64 | super.visitVariable(tree); 65 | } 66 | } 67 | 68 | } 69 | 70 | } 71 | -------------------------------------------------------------------------------- /src/main/java/org/greencodeinitiative/creedengo/java/checks/AvoidStatementForDMLQueries.java: -------------------------------------------------------------------------------- 1 | /* 2 | * creedengo - Java language - Provides rules to reduce the environmental footprint of your Java programs 3 | * Copyright © 2024 Green Code Initiative (https://green-code-initiative.org/) 4 | * 5 | * This program is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU General Public License as published by 7 | * the Free Software Foundation, either version 3 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU General Public License 16 | * along with this program. If not, see . 17 | */ 18 | package org.greencodeinitiative.creedengo.java.checks; 19 | 20 | import java.util.Collections; 21 | import java.util.List; 22 | 23 | import com.google.re2j.Pattern; 24 | import org.sonar.check.Rule; 25 | import org.sonar.plugins.java.api.IssuableSubscriptionVisitor; 26 | import org.sonar.plugins.java.api.semantic.MethodMatchers; 27 | import org.sonar.plugins.java.api.tree.Arguments; 28 | import org.sonar.plugins.java.api.tree.ExpressionTree; 29 | import org.sonar.plugins.java.api.tree.LiteralTree; 30 | import org.sonar.plugins.java.api.tree.MethodInvocationTree; 31 | import org.sonar.plugins.java.api.tree.Tree; 32 | import org.sonarsource.analyzer.commons.annotations.DeprecatedRuleKey; 33 | 34 | @Rule(key = "GCI5") 35 | @DeprecatedRuleKey(repositoryKey = "ecocode-java", ruleKey = "EC5") 36 | @DeprecatedRuleKey(repositoryKey = "greencodeinitiative-java", ruleKey = "SDMLQ1") 37 | public class AvoidStatementForDMLQueries extends IssuableSubscriptionVisitor { 38 | 39 | protected static final String MESSAGERULE = "You must not use Statement for a DML query"; 40 | 41 | private static final Pattern PATTERN = Pattern.compile("(SELECT|INSERT INTO|UPDATE|DELETE FROM)\\s?.*", Pattern.CASE_INSENSITIVE); 42 | 43 | private static final MethodMatchers EXECUTE_METHOD = MethodMatchers.or( 44 | MethodMatchers.create().ofSubTypes("java.sql.Statement").names("executeUpdate") 45 | .withAnyParameters().build()); 46 | 47 | @Override 48 | public List nodesToVisit() { 49 | return Collections.singletonList(Tree.Kind.METHOD_INVOCATION); 50 | } 51 | 52 | @Override 53 | public void visitNode(Tree tree) { 54 | MethodInvocationTree methodInvocationTree = (MethodInvocationTree) tree; 55 | if (!EXECUTE_METHOD.matches(methodInvocationTree)) 56 | return; 57 | Arguments arguments = methodInvocationTree.arguments(); 58 | if (arguments.isEmpty()) 59 | return; 60 | ExpressionTree first = arguments.get(0); 61 | if (first.is(Tree.Kind.STRING_LITERAL)) { 62 | LiteralTree literalTree = (LiteralTree) first; 63 | String str = literalTree.value(); 64 | if (PATTERN.matcher(str).find()) 65 | reportIssue(literalTree, MESSAGERULE); 66 | } 67 | } 68 | } 69 | -------------------------------------------------------------------------------- /src/main/java/org/greencodeinitiative/creedengo/java/checks/AvoidRegexPatternNotStatic.java: -------------------------------------------------------------------------------- 1 | /* 2 | * creedengo - Java language - Provides rules to reduce the environmental footprint of your Java programs 3 | * Copyright © 2024 Green Code Initiative (https://green-code-initiative.org/) 4 | * 5 | * This program is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU General Public License as published by 7 | * the Free Software Foundation, either version 3 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU General Public License 16 | * along with this program. If not, see . 17 | */ 18 | package org.greencodeinitiative.creedengo.java.checks; 19 | 20 | import java.util.Collections; 21 | import java.util.List; 22 | import java.util.regex.Pattern; 23 | 24 | import javax.annotation.Nonnull; 25 | 26 | import org.sonar.check.Rule; 27 | import org.sonar.plugins.java.api.IssuableSubscriptionVisitor; 28 | import org.sonar.plugins.java.api.semantic.MethodMatchers; 29 | import org.sonar.plugins.java.api.tree.BaseTreeVisitor; 30 | import org.sonar.plugins.java.api.tree.MethodInvocationTree; 31 | import org.sonar.plugins.java.api.tree.MethodTree; 32 | import org.sonar.plugins.java.api.tree.Tree; 33 | import org.sonarsource.analyzer.commons.annotations.DeprecatedRuleKey; 34 | 35 | @Rule(key = "GCI77") 36 | @DeprecatedRuleKey(repositoryKey = "ecocode-java", ruleKey = "EC77") 37 | @DeprecatedRuleKey(repositoryKey = "greencodeinitiative-java", ruleKey = "S77") 38 | public class AvoidRegexPatternNotStatic extends IssuableSubscriptionVisitor { 39 | 40 | public static final String MESSAGE_RULE = "Avoid using Pattern.compile() in a non-static context."; 41 | 42 | private static final MethodMatchers PATTERN_COMPILE = MethodMatchers.create() 43 | .ofTypes(Pattern.class.getName()) 44 | .names("compile") 45 | .withAnyParameters() 46 | .build(); 47 | 48 | private final AvoidRegexPatternNotStaticVisitor visitor = new AvoidRegexPatternNotStaticVisitor(); 49 | 50 | @Override 51 | public List nodesToVisit() { 52 | return Collections.singletonList(Tree.Kind.METHOD); 53 | } 54 | 55 | @Override 56 | public void visitNode(@Nonnull Tree tree) { 57 | if (tree instanceof MethodTree) { 58 | final MethodTree methodTree = (MethodTree) tree; 59 | 60 | if (!methodTree.is(Tree.Kind.CONSTRUCTOR)) { 61 | methodTree.accept(visitor); 62 | } 63 | } 64 | } 65 | 66 | private class AvoidRegexPatternNotStaticVisitor extends BaseTreeVisitor { 67 | 68 | @Override 69 | public void visitMethodInvocation(@Nonnull MethodInvocationTree tree) { 70 | if (PATTERN_COMPILE.matches(tree)) { 71 | reportIssue(tree, MESSAGE_RULE); 72 | } else { 73 | super.visitMethodInvocation(tree); 74 | } 75 | } 76 | 77 | } 78 | } 79 | -------------------------------------------------------------------------------- /src/test/java/org/greencodeinitiative/creedengo/java/checks/AvoidGettingSizeCollectionInLoopTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * creedengo - Java language - Provides rules to reduce the environmental footprint of your Java programs 3 | * Copyright © 2024 Green Code Initiative (https://green-code-initiative.org/) 4 | * 5 | * This program is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU General Public License as published by 7 | * the Free Software Foundation, either version 3 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU General Public License 16 | * along with this program. If not, see . 17 | */ 18 | package org.greencodeinitiative.creedengo.java.checks; 19 | 20 | import org.junit.jupiter.api.Test; 21 | import org.sonar.java.checks.verifier.CheckVerifier; 22 | 23 | class AvoidGettingSizeCollectionInLoopTest { 24 | @Test 25 | void testBadForLoop() { 26 | CheckVerifier.newVerifier() 27 | .onFile("src/test/files/AvoidGettingSizeCollectionInForLoopBad.java") 28 | .withCheck(new AvoidGettingSizeCollectionInLoop()) 29 | .verifyIssues(); 30 | } 31 | 32 | @Test 33 | void testIgnoredForLoop() { 34 | CheckVerifier.newVerifier() 35 | .onFile("src/test/files/AvoidGettingSizeCollectionInForLoopIgnored.java") 36 | .withCheck(new AvoidGettingSizeCollectionInLoop()) 37 | .verifyNoIssues(); 38 | } 39 | 40 | @Test 41 | void testGoodForLoop() { 42 | CheckVerifier.newVerifier() 43 | .onFile("src/test/files/AvoidGettingSizeCollectionInForLoopGood.java") 44 | .withCheck(new AvoidGettingSizeCollectionInLoop()) 45 | .verifyNoIssues(); 46 | } 47 | 48 | @Test 49 | void testBadWhileFoop() { 50 | CheckVerifier.newVerifier() 51 | .onFile("src/test/files/AvoidGettingSizeCollectionInWhileLoopBad.java") 52 | .withCheck(new AvoidGettingSizeCollectionInLoop()) 53 | .verifyIssues(); 54 | } 55 | 56 | @Test 57 | void testIgnoredWhileFoop() { 58 | CheckVerifier.newVerifier() 59 | .onFile("src/test/files/AvoidGettingSizeCollectionInWhileLoopIgnored.java") 60 | .withCheck(new AvoidGettingSizeCollectionInLoop()) 61 | .verifyNoIssues(); 62 | } 63 | 64 | @Test 65 | void testGoodWhileLoop() { 66 | CheckVerifier.newVerifier() 67 | .onFile("src/test/files/AvoidGettingSizeCollectionInWhileLoopGood.java") 68 | .withCheck(new AvoidGettingSizeCollectionInLoop()) 69 | .verifyNoIssues(); 70 | } 71 | 72 | @Test 73 | void testIgnoredForEachLoop() { 74 | CheckVerifier.newVerifier() 75 | .onFile("src/test/files/AvoidGettingSizeCollectionInForEachLoopIgnored.java") 76 | .withCheck(new AvoidGettingSizeCollectionInLoop()) 77 | .verifyNoIssues(); 78 | } 79 | } 80 | -------------------------------------------------------------------------------- /src/test/files/IncrementCheck.java: -------------------------------------------------------------------------------- 1 | /* 2 | * creedengo - Java language - Provides rules to reduce the environmental footprint of your Java programs 3 | * Copyright © 2024 Green Code Initiative (https://green-code-initiative.org/) 4 | * 5 | * This program is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU General Public License as published by 7 | * the Free Software Foundation, either version 3 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU General Public License 16 | * along with this program. If not, see . 17 | */ 18 | package org.greencodeinitiative.creedengo.java.checks; 19 | 20 | private class Foo { 21 | public int i; //NOSONAR 22 | } 23 | 24 | class IncrementCheck { 25 | 26 | IncrementCheck(IncrementCheck mc) { 27 | } 28 | 29 | int foo1() { 30 | int counter = 0; 31 | return counter++; // Noncompliant {{Use ++i instead of i++}} 32 | } 33 | 34 | private int j = 0; 35 | int foo10() { 36 | return this.j++; // Compliant because maybe the use case needs to return j AND increment it 37 | } 38 | 39 | int foo11() { 40 | int counter = 0; 41 | return ++counter; 42 | } 43 | 44 | int foo12() { 45 | Foo f; 46 | return f.i++; // Compliant because maybe the use case needs to return j AND increment it 47 | } 48 | 49 | int foo2() { 50 | int counter = 0; 51 | counter++; // Noncompliant {{Use ++i instead of i++}} 52 | return counter; 53 | } 54 | 55 | int foo22() { 56 | int counter = 0; 57 | ++counter; 58 | return counter; 59 | } 60 | 61 | int foo3() { 62 | int counter = 0; 63 | counter = counter + 197845 ; 64 | return counter; 65 | } 66 | 67 | int foo4() { 68 | int counter = 0; 69 | counter = counter + 35 + 78 ; 70 | return counter; 71 | } 72 | 73 | void foo50() { 74 | for (int i=0; i < 10; i++) { // Noncompliant {{Use ++i instead of i++}} 75 | System.out.println(i); //NOSONAR 76 | } 77 | } 78 | 79 | void foo51() { 80 | for (int i=0; i < 10; ++i) { 81 | System.out.println(i); //NOSONAR 82 | } 83 | } 84 | 85 | void bar61(int value) { 86 | // For test purpose 87 | } 88 | 89 | int foo61() { 90 | int i = 0; 91 | bar61(i++); // Compliant because maybe bar61 needs the unincremented value 92 | return i; 93 | } 94 | 95 | int foo62() { 96 | int i = 0; 97 | bar61(2 + i++); // Compliant because maybe bar61 needs the unincremented value 98 | return i; 99 | } 100 | 101 | void foo71() { 102 | int counter = 0; 103 | int a = 2 + counter++; // Compliant because we probably want to increment counter 104 | // then to add it to 2 to initialize a 105 | } 106 | } 107 | -------------------------------------------------------------------------------- /src/main/java/org/greencodeinitiative/creedengo/java/JavaCheckRegistrar.java: -------------------------------------------------------------------------------- 1 | /* 2 | * creedengo - Java language - Provides rules to reduce the environmental footprint of your Java programs 3 | * Copyright © 2024 Green Code Initiative (https://green-code-initiative.org/) 4 | * 5 | * This program is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU General Public License as published by 7 | * the Free Software Foundation, either version 3 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU General Public License 16 | * along with this program. If not, see . 17 | */ 18 | package org.greencodeinitiative.creedengo.java; 19 | 20 | import java.util.Collections; 21 | import java.util.List; 22 | 23 | import org.greencodeinitiative.creedengo.java.checks.*; 24 | import org.sonar.plugins.java.api.CheckRegistrar; 25 | import org.sonar.plugins.java.api.JavaCheck; 26 | import org.sonarsource.api.sonarlint.SonarLintSide; 27 | 28 | /** 29 | * Provide the "checks" (implementations of rules) classes that are going be executed during 30 | * source code analysis. 31 | *

32 | * This class is a batch extension by implementing the {@link org.sonar.plugins.java.api.CheckRegistrar} interface. 33 | */ 34 | @SonarLintSide 35 | public class JavaCheckRegistrar implements CheckRegistrar { 36 | static final List> ANNOTATED_RULE_CLASSES = List.of( 37 | ArrayCopyCheck.class, 38 | IncrementCheck.class, 39 | AvoidUsageOfStaticCollections.class, 40 | AvoidGettingSizeCollectionInLoop.class, 41 | AvoidRegexPatternNotStatic.class, 42 | NoFunctionCallWhenDeclaringForLoop.class, 43 | AvoidStatementForDMLQueries.class, 44 | AvoidSpringRepositoryCallInLoopOrStreamCheck.class, 45 | AvoidSQLRequestInLoop.class, 46 | AvoidFullSQLRequest.class, 47 | OptimizeReadFileExceptions.class, 48 | InitializeBufferWithAppropriateSize.class, 49 | AvoidSetConstantInBatchUpdate.class, 50 | FreeResourcesOfAutoCloseableInterface.class, 51 | AvoidMultipleIfElseStatement.class, 52 | UseOptionalOrElseGetVsOrElse.class, 53 | MakeNonReassignedVariablesConstants.class 54 | ); 55 | 56 | /** 57 | * Register the classes that will be used to instantiate checks during analysis. 58 | */ 59 | @Override 60 | public void register(RegistrarContext registrarContext) { 61 | // Call to registerClassesForRepository to associate the classes with the correct repository key 62 | registrarContext.registerClassesForRepository(JavaRulesDefinition.REPOSITORY_KEY, checkClasses(), testCheckClasses()); 63 | } 64 | 65 | /** 66 | * Lists all the main checks provided by the plugin 67 | */ 68 | public static List> checkClasses() { 69 | return ANNOTATED_RULE_CLASSES; 70 | } 71 | 72 | /** 73 | * Lists all the test checks provided by the plugin 74 | */ 75 | public static List> testCheckClasses() { 76 | return Collections.emptyList(); 77 | } 78 | } 79 | -------------------------------------------------------------------------------- /src/test/java/org/greencodeinitiative/creedengo/java/utils/FilesUtils.java: -------------------------------------------------------------------------------- 1 | /* 2 | * creedengo - Java language - Provides rules to reduce the environmental footprint of your Java programs 3 | * Copyright © 2024 Green Code Initiative (https://green-code-initiative.org/) 4 | * 5 | * This program is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU General Public License as published by 7 | * the Free Software Foundation, either version 3 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU General Public License 16 | * along with this program. If not, see . 17 | */ 18 | package org.greencodeinitiative.creedengo.java.utils; 19 | 20 | import java.io.File; 21 | import java.io.IOException; 22 | import java.nio.file.FileVisitResult; 23 | import java.nio.file.FileVisitor; 24 | import java.nio.file.Files; 25 | import java.nio.file.Path; 26 | import java.nio.file.Paths; 27 | import java.nio.file.SimpleFileVisitor; 28 | import java.nio.file.attribute.BasicFileAttributes; 29 | import java.util.ArrayList; 30 | import java.util.LinkedList; 31 | import java.util.List; 32 | 33 | /** 34 | * Duplicates org.sonar.java.checks.verifier.FilesUtils to locate test jars within the custom-rules plugin 35 | */ 36 | public class FilesUtils { 37 | 38 | private FilesUtils() { 39 | } 40 | 41 | /** 42 | * Default location of the jars/zips to be taken into account when performing the analysis. 43 | */ 44 | private static final String DEFAULT_TEST_JARS_DIRECTORY = "target/test-jars"; 45 | 46 | public static List getClassPath(String jarsDirectory) { 47 | List classpath = new LinkedList<>(); 48 | Path testJars = Paths.get(jarsDirectory); 49 | if (testJars.toFile().exists()) { 50 | classpath = getFilesRecursively(testJars, "jar", "zip"); 51 | } else if (!DEFAULT_TEST_JARS_DIRECTORY.equals(jarsDirectory)) { 52 | throw new AssertionError("The directory to be used to extend class path does not exists (" 53 | + testJars.toAbsolutePath() 54 | + ")."); 55 | } 56 | classpath.add(new File("target/test-classes")); 57 | return classpath; 58 | } 59 | 60 | private static List getFilesRecursively(Path root, String... extensions) { 61 | final List files = new ArrayList<>(); 62 | 63 | FileVisitor visitor = new SimpleFileVisitor<>() { 64 | @Override 65 | public FileVisitResult visitFile(Path filePath, BasicFileAttributes attrs) { 66 | for (String extension : extensions) { 67 | if (filePath.toString().endsWith("." 68 | + extension)) { 69 | files.add(filePath.toFile()); 70 | break; 71 | } 72 | } 73 | return FileVisitResult.CONTINUE; 74 | } 75 | 76 | @Override 77 | public FileVisitResult visitFileFailed(Path file, IOException exc) { 78 | return FileVisitResult.CONTINUE; 79 | } 80 | }; 81 | 82 | try { 83 | Files.walkFileTree(root, visitor); 84 | } catch (IOException e) { 85 | // we already ignore errors in the visitor 86 | } 87 | 88 | return files; 89 | } 90 | 91 | } 92 | -------------------------------------------------------------------------------- /.github/workflows/_BACKUP_manual_release.yml: -------------------------------------------------------------------------------- 1 | name: Manual Release 2 | on: 3 | workflow_dispatch: 4 | inputs: 5 | confirmeRelease: 6 | description: 'Confirm manual release creation (by typing "true") ? ----- WARNING : check version (in pom.xml files) and release notes (in CHANGELOG.md file) before confirm' 7 | default: 'false' 8 | jobs: 9 | checks: 10 | name: Requirements 11 | if: github.event.inputs.confirmeRelease == 'true' 12 | runs-on: ubuntu-latest 13 | steps: 14 | - name: Check user permissions 15 | uses: 74th/workflow-permission-action@1.0.0 16 | with: 17 | users: dedece35,glalloue,jhertout,jules-delecour-dav,olegoaer,zippy1978 18 | build: 19 | name: Build And Release 20 | needs: checks 21 | runs-on: ubuntu-latest 22 | permissions: write-all 23 | outputs: 24 | last_tag: ${{ steps.export_last_tag.outputs.last_tag }} 25 | upload_url: ${{ steps.export_upload_url.outputs.upload_url }} 26 | steps: 27 | - name: Checkout 28 | uses: actions/checkout@v3 29 | - name: Change commiter 30 | run: | 31 | git config user.name 'github-actions[bot]' 32 | git config user.email '' 33 | - name: Maven release 34 | run: ./mvnw release:prepare -B -ff -DtagNameFormat=@{project.version} 35 | - name: Maven release clean 36 | run: ./mvnw release:clean 37 | - name: Get last TAG 38 | run: echo "LAST_TAG=$(git tag --sort=-version:refname | head -n 1)" >> $GITHUB_ENV 39 | - name: Extract release notes 40 | id: extract-release-notes 41 | uses: ffurrer2/extract-release-notes@v1 42 | - name: Checkout tag "${{ env.LAST_TAG }}" 43 | uses: actions/checkout@v3 44 | with: 45 | ref: ${{ env.LAST_TAG }} 46 | - name: Build project 47 | run: ./mvnw -e -B clean package -DskipTests 48 | - name: Create release 49 | id: create_release 50 | uses: actions/create-release@v1 51 | env: 52 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 53 | with: 54 | tag_name: ${{ env.LAST_TAG }} 55 | release_name: Release ${{ env.LAST_TAG }} 56 | draft: false 57 | prerelease: false 58 | body: ${{ steps.extract-release-notes.outputs.release_notes }} 59 | - name: Export plugin Jar files 60 | id: export_jar_files 61 | uses: actions/upload-artifact@v3 62 | with: 63 | name: creedengo-plugins 64 | path: lib 65 | - name: Export LAST_TAG 66 | id: export_last_tag 67 | run: echo "last_tag=${{ env.LAST_TAG }}" >> $GITHUB_OUTPUT 68 | - name: Export UPLOAD_URL 69 | id: export_upload_url 70 | run: echo "upload_url=${{ steps.create_release.outputs.upload_url }}" >> $GITHUB_OUTPUT 71 | upload-java: 72 | name: Upload Java Plugin 73 | runs-on: ubuntu-latest 74 | needs: build 75 | steps: 76 | - name: Import plugin JAR files 77 | id: import_jar_files 78 | uses: actions/download-artifact@v3 79 | with: 80 | name: creedengo-plugins 81 | path: lib 82 | - name: Upload Release Asset - Java Plugin 83 | id: upload-release-asset 84 | uses: actions/upload-release-asset@v1 85 | env: 86 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 87 | with: 88 | upload_url: ${{needs.build.outputs.upload_url}} 89 | asset_path: lib/creedengo-java-plugin-${{ needs.build.outputs.last_tag }}.jar 90 | asset_name: creedengo-java-plugin-${{ needs.build.outputs.last_tag }}.jar 91 | asset_content_type: application/zip 92 | -------------------------------------------------------------------------------- /src/test/java/org/greencodeinitiative/creedengo/java/JavaRulesDefinitionTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * creedengo - Java language - Provides rules to reduce the environmental footprint of your Java programs 3 | * Copyright © 2024 Green Code Initiative (https://green-code-initiative.org/) 4 | * 5 | * This program is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU General Public License as published by 7 | * the Free Software Foundation, either version 3 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU General Public License 16 | * along with this program. If not, see . 17 | */ 18 | package org.greencodeinitiative.creedengo.java; 19 | 20 | import org.assertj.core.api.SoftAssertions; 21 | import org.junit.jupiter.api.BeforeEach; 22 | import org.junit.jupiter.api.DisplayName; 23 | import org.junit.jupiter.api.Test; 24 | import org.sonar.api.SonarRuntime; 25 | import org.sonar.api.rules.RuleType; 26 | import org.sonar.api.server.debt.DebtRemediationFunction.Type; 27 | import org.sonar.api.server.rule.RulesDefinition; 28 | import org.sonar.api.server.rule.RulesDefinition.Rule; 29 | import org.sonar.api.utils.Version; 30 | 31 | import static org.greencodeinitiative.creedengo.java.JavaCheckRegistrar.ANNOTATED_RULE_CLASSES; 32 | import static org.assertj.core.api.Assertions.assertThat; 33 | import static org.mockito.Mockito.doReturn; 34 | import static org.mockito.Mockito.mock; 35 | 36 | class JavaRulesDefinitionTest { 37 | 38 | private RulesDefinition.Repository repository; 39 | 40 | @BeforeEach 41 | void init() { 42 | final SonarRuntime sonarRuntime = mock(SonarRuntime.class); 43 | doReturn(Version.create(0, 0)).when(sonarRuntime).getApiVersion(); 44 | JavaRulesDefinition rulesDefinition = new JavaRulesDefinition(sonarRuntime); 45 | RulesDefinition.Context context = new RulesDefinition.Context(); 46 | rulesDefinition.define(context); 47 | repository = context.repository(rulesDefinition.repositoryKey()); 48 | } 49 | 50 | @Test 51 | @DisplayName("Test repository metadata") 52 | void testMetadata() { 53 | assertThat(repository.name()).isEqualTo("creedengo"); 54 | assertThat(repository.language()).isEqualTo("java"); 55 | assertThat(repository.key()).isEqualTo("creedengo-java"); 56 | } 57 | 58 | @Test 59 | void testRegistredRules() { 60 | assertThat(repository.rules()).hasSize(ANNOTATED_RULE_CLASSES.size()); 61 | } 62 | 63 | @Test 64 | @DisplayName("All rule keys must be prefixed by 'GCI'") 65 | void testRuleKeyPrefix() { 66 | SoftAssertions assertions = new SoftAssertions(); 67 | repository.rules().forEach( 68 | rule -> assertions.assertThat(rule.key()).startsWith("GCI") 69 | ); 70 | assertions.assertAll(); 71 | } 72 | 73 | @Test 74 | void assertRuleProperties() { 75 | Rule rule = repository.rule("GCI67"); 76 | assertThat(rule).isNotNull(); 77 | assertThat(rule.name()).isEqualTo("Use ++i instead of i++"); 78 | assertThat(rule.debtRemediationFunction().type()).isEqualTo(Type.CONSTANT_ISSUE); 79 | assertThat(rule.type()).isEqualTo(RuleType.CODE_SMELL); 80 | } 81 | 82 | @Test 83 | void testAllRuleParametersHaveDescription() { 84 | SoftAssertions assertions = new SoftAssertions(); 85 | repository.rules().stream() 86 | .flatMap(rule -> rule.params().stream()) 87 | .forEach(param -> assertions.assertThat(param.description()).as("description for " + param.key()).isNotEmpty()); 88 | assertions.assertAll(); 89 | } 90 | 91 | } 92 | -------------------------------------------------------------------------------- /src/main/java/org/greencodeinitiative/creedengo/java/checks/FreeResourcesOfAutoCloseableInterface.java: -------------------------------------------------------------------------------- 1 | /* 2 | * creedengo - Java language - Provides rules to reduce the environmental footprint of your Java programs 3 | * Copyright © 2024 Green Code Initiative (https://green-code-initiative.org/) 4 | * 5 | * This program is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU General Public License as published by 7 | * the Free Software Foundation, either version 3 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU General Public License 16 | * along with this program. If not, see . 17 | */ 18 | package org.greencodeinitiative.creedengo.java.checks; 19 | 20 | import java.util.ArrayList; 21 | import java.util.Arrays; 22 | import java.util.Deque; 23 | import java.util.LinkedList; 24 | import java.util.List; 25 | 26 | import javax.annotation.ParametersAreNonnullByDefault; 27 | 28 | import org.sonar.check.Rule; 29 | import org.sonar.plugins.java.api.IssuableSubscriptionVisitor; 30 | import org.sonar.plugins.java.api.JavaFileScannerContext; 31 | import org.sonar.plugins.java.api.JavaVersion; 32 | import org.sonar.plugins.java.api.tree.NewClassTree; 33 | import org.sonar.plugins.java.api.tree.Tree; 34 | import org.sonar.plugins.java.api.tree.TryStatementTree; 35 | import org.sonarsource.analyzer.commons.annotations.DeprecatedRuleKey; 36 | 37 | 38 | @Rule(key = "GCI79") 39 | @DeprecatedRuleKey(repositoryKey = "ecocode-java", ruleKey = "EC79") 40 | @DeprecatedRuleKey(repositoryKey = "greencodeinitiative-java", ruleKey = "S79") 41 | public class FreeResourcesOfAutoCloseableInterface extends IssuableSubscriptionVisitor { 42 | private final Deque withinTry = new LinkedList<>(); 43 | private final Deque> toReport = new LinkedList<>(); 44 | 45 | private static final String JAVA_LANG_AUTOCLOSEABLE = "java.lang.AutoCloseable"; 46 | protected static final String MESSAGE_RULE = "try-with-resources Statement needs to be implemented for any object that implements the AutoClosable interface."; 47 | 48 | @Override 49 | @ParametersAreNonnullByDefault 50 | public void leaveFile(JavaFileScannerContext context) { 51 | withinTry.clear(); 52 | toReport.clear(); 53 | } 54 | 55 | @Override 56 | public List nodesToVisit() { 57 | return Arrays.asList(Tree.Kind.TRY_STATEMENT, Tree.Kind.NEW_CLASS); 58 | } 59 | 60 | @Override 61 | public void visitNode(Tree tree) { 62 | if (tree.is(Tree.Kind.TRY_STATEMENT)) { 63 | withinTry.push((TryStatementTree) tree); 64 | if (withinTry.size() != toReport.size()) { 65 | toReport.push(new ArrayList<>()); 66 | } 67 | } 68 | if (tree.is(Tree.Kind.NEW_CLASS) && ((NewClassTree) tree).symbolType().isSubtypeOf(JAVA_LANG_AUTOCLOSEABLE) && withinStandardTryWithFinally()) { 69 | assert toReport.peek() != null; 70 | toReport.peek().add(tree); 71 | } 72 | } 73 | 74 | @Override 75 | public void leaveNode(Tree tree) { 76 | if (tree.is(Tree.Kind.TRY_STATEMENT)) { 77 | List secondaryTrees = toReport.pop(); 78 | if (!secondaryTrees.isEmpty()) { 79 | reportIssue(tree, MESSAGE_RULE); 80 | } 81 | } 82 | } 83 | 84 | private boolean withinStandardTryWithFinally() { 85 | if (withinTry.isEmpty() || !withinTry.peek().resourceList().isEmpty()) return false; 86 | assert withinTry.peek() != null; 87 | return withinTry.peek().finallyBlock() != null; 88 | } 89 | 90 | public boolean isCompatibleWithJavaVersion(JavaVersion version) { 91 | return version.isJava7Compatible(); 92 | } 93 | } 94 | -------------------------------------------------------------------------------- /src/it/java/org/greencodeinitiative/creedengo/java/integration/tests/GCIRulesBase.java: -------------------------------------------------------------------------------- 1 | package org.greencodeinitiative.creedengo.java.integration.tests; 2 | 3 | import org.assertj.core.groups.Tuple; 4 | import org.sonarqube.ws.Common; 5 | import org.sonarqube.ws.Components; 6 | import org.sonarqube.ws.Issues; 7 | 8 | import java.util.ArrayList; 9 | import java.util.List; 10 | 11 | import static org.assertj.core.api.Assertions.assertThat; 12 | import static org.sonarqube.ws.Common.RuleType.CODE_SMELL; 13 | import static org.sonarqube.ws.Common.Severity.MINOR; 14 | 15 | class GCIRulesBase extends BuildProjectEngine { 16 | 17 | protected static final String[] EXTRACT_FIELDS = new String[]{ 18 | "rule", "message", 19 | // "line" 20 | "textRange.startLine", "textRange.endLine", 21 | // "textRange.startOffset", "textRange.endOffset", 22 | "severity", "type", 23 | // "debt", 24 | "effort" 25 | }; 26 | protected static final Common.Severity SEVERITY = MINOR; 27 | protected static final Common.RuleType TYPE = CODE_SMELL; 28 | protected static final String EFFORT_1MIN = "1min"; 29 | protected static final String EFFORT_5MIN = "5min"; 30 | protected static final String EFFORT_10MIN = "10min"; 31 | protected static final String EFFORT_15MIN = "15min"; 32 | protected static final String EFFORT_20MIN = "20min"; 33 | protected static final String EFFORT_50MIN = "50min"; 34 | 35 | protected void checkIssuesForFile(String filePath, String ruleId, String ruleMsg, int[] startLines, int[] endLines) { 36 | checkIssuesForFile(filePath, ruleId, ruleMsg, startLines, endLines, SEVERITY, TYPE, EFFORT_5MIN); 37 | } 38 | 39 | protected void checkIssuesForFile(String filePath, String ruleId, String ruleMsg, int[] startLines, int[] endLines, Common.Severity severity, Common.RuleType type, String effort) { 40 | 41 | assertThat(startLines.length) 42 | .isEqualTo(endLines.length); 43 | 44 | String projectKey = analyzedProjects.get(0).getProjectKey(); 45 | 46 | String componentKey = projectKey + ":" + filePath; 47 | 48 | // System.out.println("--- COMPONENT KEY : " + componentKey); 49 | 50 | // launch the search 51 | Components.ShowWsResponse respComponent = showComponent(componentKey); 52 | Components.Component comp = respComponent.getComponent(); 53 | // System.out.println("--- COMPONENT --- " + comp); 54 | // System.out.println("--- COMPONENT KEY --- " + comp.getKey()); 55 | // System.out.println("--- COMPONENT PATH --- " + comp.getPath()); 56 | // System.out.println("--- PATH ok --- " + filePath.equals(comp.getPath())); 57 | assertThat(filePath) 58 | .withFailMessage("File not found: " + filePath) 59 | .isEqualTo(comp.getPath()); 60 | 61 | // check issues 62 | Issues.SearchWsResponse respIssues = searchIssuesForComponent(componentKey, ruleId); 63 | 64 | // System.out.println("--- NB ISSUES : " + respIssues.getIssuesCount()); 65 | // System.out.println("--- NB ISSUES_LIST : " + respIssues.getIssuesList().size()); 66 | // respIssues.getIssuesList().forEach(issue -> { 67 | //// if (issue.getRule().equals("creedengo-java:GCI27")) { 68 | // System.out.println("--- Issue --- " + issue.getRule() + " / " + issue.getLine()); 69 | //// } 70 | // }); 71 | 72 | // List issues = issuesForFile(projectKey, filePath, ruleId); 73 | List issues = respIssues.getIssuesList(); 74 | 75 | List expectedTuples = new ArrayList<>(); 76 | for (int i = 0; i < startLines.length; i++) { 77 | expectedTuples.add(Tuple.tuple(ruleId, ruleMsg, startLines[i], endLines[i], severity, type, effort)); 78 | } 79 | 80 | assertThat(issues) 81 | .hasSizeGreaterThanOrEqualTo(startLines.length) 82 | // .hasSize(lines.length) 83 | .extracting(EXTRACT_FIELDS) 84 | .containsAll(expectedTuples); 85 | // .containsExactlyElementsOf(expectedTuples); 86 | } 87 | 88 | } 89 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | creedengo-java 2 | =========== 3 | 4 | _creedengo_ is a collective project aiming to reduce environmental footprint of software at the code level. The goal of 5 | the project is to provide a list of static code analyzers to highlight code structures that may have a negative 6 | ecological impact: energy and resources over-consumption, "fatware", shortening terminals' lifespan, etc. 7 | 8 | _creedengo_ is based on evolving catalogs 9 | of [good practices](https://github.com/green-code-initiative/creedengo-rules-specifications/blob/main/docs/rules), for various technologies. 10 | This 11 | SonarQube plugin then implements these catalogs as rules for scanning your Java projects. 12 | 13 | > ⚠️ This is still a very early stage project. Any feedback or contribution will be highly appreciated. Please 14 | > refer to the contribution section. 15 | 16 | [![License: GPL v3](https://img.shields.io/badge/License-GPLv3-blue.svg)](https://www.gnu.org/licenses/gpl-3.0) 17 | [![Contributor Covenant](https://img.shields.io/badge/Contributor%20Covenant-2.1-4baaaa.svg)](https://github.com/green-code-initiative/creedengo-common/blob/main/doc/CODE_OF_CONDUCT.md) 18 | 19 | 🌿 SonarQube Plugins 20 | ------------------- 21 | 22 | This plugin is part of the creedengo project.\ 23 | You can find a list of all our other plugins in 24 | the [creedengo repository](https://github.com/green-code-initiative/creedengo-rules-specifications#-sonarqube-plugins) 25 | 26 | 🚀 Getting Started 27 | ------------------ 28 | 29 | You can give a try with a one command: 30 | 31 | ```sh 32 | ./mvnw verify -Pkeep-running 33 | ``` 34 | 35 | ... then you can use Java test project repository to test the environment : see [Java test project in `./src/it/test-projects/creedengo-java-plugin-test-project`](./src/it/test-projects/creedengo-java-plugin-test-project) 36 | 37 | NB: To install other `creedengo` plugins, you can : 38 | 39 | - add JAVA System properties `Dtest-it.additional-plugins` with a comma separated list of plugin IDs (`groupId:artifactId:version`), or plugins JAR (`file://....`) to install. 40 | 41 | For example : 42 | 43 | ```sh 44 | ./mvnw verify -Pkeep-running -Dtest-it.additional-plugins=org.sonarsource.javascript:sonar-plugin:10.1.0.21143 45 | ``` 46 | - install different creedengo plugins with Marketplace (inside admin panel of SonarQube) 47 | 48 | You can also directly use a [all-in-one docker-compose](https://github.com/green-code-initiative/creedengo-common/blob/main/doc/INSTALL.md#start-sonarqube-if-first-time) 49 | 50 | ... and configure local SonarQube (security config and quality profile : see [configuration](https://github.com/green-code-initiative/creedengo-common/blob/main/doc/INSTALL.md#configuration-sonarqube) for more details). 51 | 52 | 🛒 Distribution 53 | ------------------ 54 | 55 | Ready to use binaries are available [from GitHub](https://github.com/green-code-initiative/creedengo-java/releases). 56 | 57 | 🧩 Compatibility 58 | ----------------- 59 | 60 | | Plugin version | SonarQube version | Java version | 61 | |----------------|---------------------|------------------------------------------------------------------------------------------------| 62 | | 1.6.+ | 9.4.+ LTS to 10.6.0 | 11 / 17 | 63 | | 1.7.+ | 9.9.+ LTS to 10.6.0 | [17](https://docs.sonarsource.com/sonarqube/9.9/requirements/prerequisites-and-overview/#java) | 64 | | 2.+ | 9.9.0 LTS to 25.9.0 | [17](https://docs.sonarsource.com/sonarqube/9.9/requirements/prerequisites-and-overview/#java) | 65 | 66 | > Compatibility table of versions lower than 1.4.+ are available from the 67 | > main [creedengo repository](https://github.com/green-code-initiative/creedengo-rules-specifications#-plugins-version-compatibility). 68 | 69 | 🤝 Contribution 70 | --------------- 71 | 72 | check [creedengo repository](https://github.com/green-code-initiative/creedengo-rules-specifications#-contribution) 73 | 74 | 🤓 Main contributors 75 | -------------------- 76 | 77 | check [creedengo repository](https://github.com/green-code-initiative/creedengo-rules-specifications#-main-contributors) 78 | 79 | Links 80 | ----- 81 | 82 | - https://docs.sonarqube.org/latest/analysis/overview/ 83 | -------------------------------------------------------------------------------- /src/main/java/org/greencodeinitiative/creedengo/java/checks/AvoidSetConstantInBatchUpdate.java: -------------------------------------------------------------------------------- 1 | /* 2 | * creedengo - Java language - Provides rules to reduce the environmental footprint of your Java programs 3 | * Copyright © 2024 Green Code Initiative (https://green-code-initiative.org/) 4 | * 5 | * This program is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU General Public License as published by 7 | * the Free Software Foundation, either version 3 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU General Public License 16 | * along with this program. If not, see . 17 | */ 18 | package org.greencodeinitiative.creedengo.java.checks; 19 | 20 | import java.sql.PreparedStatement; 21 | import java.util.List; 22 | import java.util.stream.Stream; 23 | 24 | import org.greencodeinitiative.creedengo.java.checks.enums.ConstOrLiteralDeclare; 25 | import static org.greencodeinitiative.creedengo.java.checks.enums.ConstOrLiteralDeclare.isLiteral; 26 | import static java.util.Arrays.asList; 27 | 28 | import org.sonar.check.Rule; 29 | import org.sonar.plugins.java.api.IssuableSubscriptionVisitor; 30 | import org.sonar.plugins.java.api.semantic.MethodMatchers; 31 | import static org.sonar.plugins.java.api.semantic.Type.Primitives.INT; 32 | import org.sonar.plugins.java.api.tree.BaseTreeVisitor; 33 | import org.sonar.plugins.java.api.tree.MemberSelectExpressionTree; 34 | import org.sonar.plugins.java.api.tree.MethodInvocationTree; 35 | import org.sonar.plugins.java.api.tree.Tree; 36 | import org.sonar.plugins.java.api.tree.Tree.Kind; 37 | import org.sonarsource.analyzer.commons.annotations.DeprecatedRuleKey; 38 | 39 | import static org.sonar.plugins.java.api.tree.Tree.Kind.MEMBER_SELECT; 40 | import static org.sonar.plugins.java.api.tree.Tree.Kind.METHOD_INVOCATION; 41 | 42 | @Rule(key = "GCI78") 43 | @DeprecatedRuleKey(repositoryKey = "ecocode-java", ruleKey = "EC78") 44 | @DeprecatedRuleKey(repositoryKey = "greencodeinitiative-java", ruleKey = "S78") 45 | public class AvoidSetConstantInBatchUpdate extends IssuableSubscriptionVisitor { 46 | 47 | protected static final String MESSAGE_RULE = "Avoid setting constants in batch update"; 48 | private final AvoidSetConstantInBatchUpdateVisitor visitorInFile = new AvoidSetConstantInBatchUpdateVisitor(); 49 | 50 | @Override 51 | public List nodesToVisit() { 52 | return asList( 53 | Tree.Kind.FOR_EACH_STATEMENT, 54 | Tree.Kind.FOR_STATEMENT, 55 | Tree.Kind.WHILE_STATEMENT, 56 | Tree.Kind.DO_STATEMENT); 57 | } 58 | 59 | @Override 60 | public void visitNode(Tree tree) { 61 | tree.accept(visitorInFile); 62 | } 63 | 64 | private class AvoidSetConstantInBatchUpdateVisitor extends BaseTreeVisitor { 65 | 66 | private final MethodMatchers setters = MethodMatchers.create().ofSubTypes(PreparedStatement.class.getName()) 67 | .names("setBoolean", "setByte", "setShort", "setInt", "setLong", "setFloat", "setDouble", 68 | "setBigDecimal", "setString") 69 | .addParametersMatcher(args -> args.size() == 2 && args.get(0).isPrimitive(INT)).build(); 70 | 71 | @Override 72 | public void visitMethodInvocation(MethodInvocationTree tree) { 73 | if (setters.matches(tree) && isConstant(tree.arguments().get(1))) { 74 | reportIssue(tree, MESSAGE_RULE); 75 | } else { 76 | super.visitMethodInvocation(tree); 77 | } 78 | } 79 | } 80 | 81 | private static boolean isConstant(Tree arg) { 82 | 83 | if (arg.is(METHOD_INVOCATION)) { 84 | MethodInvocationTree m = (MethodInvocationTree) arg; 85 | return Stream.of(ConstOrLiteralDeclare.values()).anyMatch(o -> o.isLiteralDeclare(m)); 86 | } else if (arg.is(MEMBER_SELECT)) { 87 | MemberSelectExpressionTree m = (MemberSelectExpressionTree) arg; 88 | return Stream.of(ConstOrLiteralDeclare.values()).anyMatch(o -> o.isPublicMember(m)); 89 | } 90 | return isLiteral(arg); 91 | } 92 | } 93 | -------------------------------------------------------------------------------- /src/main/java/org/greencodeinitiative/creedengo/java/checks/OptimizeReadFileExceptions.java: -------------------------------------------------------------------------------- 1 | /* 2 | * creedengo - Java language - Provides rules to reduce the environmental footprint of your Java programs 3 | * Copyright © 2024 Green Code Initiative (https://green-code-initiative.org/) 4 | * 5 | * This program is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU General Public License as published by 7 | * the Free Software Foundation, either version 3 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU General Public License 16 | * along with this program. If not, see . 17 | */ 18 | package org.greencodeinitiative.creedengo.java.checks; 19 | 20 | 21 | import java.util.Arrays; 22 | import java.util.List; 23 | 24 | import org.sonar.api.utils.log.Logger; 25 | import org.sonar.api.utils.log.Loggers; 26 | import org.sonar.check.Rule; 27 | import org.sonar.plugins.java.api.IssuableSubscriptionVisitor; 28 | import org.sonar.plugins.java.api.tree.CatchTree; 29 | import org.sonar.plugins.java.api.tree.NewClassTree; 30 | import org.sonar.plugins.java.api.tree.Tree; 31 | import org.sonar.plugins.java.api.tree.Tree.Kind; 32 | import org.sonar.plugins.java.api.tree.TryStatementTree; 33 | import org.sonarsource.analyzer.commons.annotations.DeprecatedRuleKey; 34 | 35 | @Rule(key = "GCI28") 36 | @DeprecatedRuleKey(repositoryKey = "ecocode-java", ruleKey = "EC28") 37 | @DeprecatedRuleKey(repositoryKey = "greencodeinitiative-java", ruleKey = "GRSP0028") 38 | public class OptimizeReadFileExceptions extends IssuableSubscriptionVisitor { 39 | 40 | protected static final String MESSAGERULE = "Optimize Read File Exceptions"; 41 | private static final Logger LOGGER = Loggers.get(OptimizeReadFileExceptions.class); 42 | private boolean isExceptionFound = false; 43 | 44 | @Override 45 | public List nodesToVisit() { 46 | return Arrays.asList(Kind.TRY_STATEMENT, Kind.NEW_CLASS); 47 | } 48 | 49 | @Override 50 | public void visitNode(Tree tree) { 51 | LOGGER.debug("--------------------_____-----_____----- OptimizeReadFileExceptions.visitNode METHOD - BEGIN"); 52 | if (tree.kind().getAssociatedInterface().equals(NewClassTree.class)) { 53 | LOGGER.debug("interface NewClassTree found"); 54 | NewClassTree newClassTree = (NewClassTree) tree; 55 | if (newClassTree.identifier().symbolType().toString().equals("FileInputStream")) { 56 | LOGGER.debug("identifier 'FileInputStream' found"); 57 | if (this.isExceptionFound) { 58 | LOGGER.debug("exception found => launching 'reportIssue'"); 59 | reportIssue(tree, MESSAGERULE); 60 | } else { 61 | LOGGER.debug("exception NOT found"); 62 | } 63 | } else { 64 | LOGGER.debug("identifier 'FileInputStream' NOT found (real identifier : {}) => No issue launched", newClassTree.identifier().symbolType()); 65 | } 66 | } else { 67 | LOGGER.debug("interface NewClassTree NOT found (real interface : {}) => casting to TryStatementTree", tree.kind().getAssociatedInterface()); 68 | TryStatementTree tryStatementTree = (TryStatementTree) tree; 69 | List catchTreeList = tryStatementTree.catches(); 70 | 71 | LOGGER.debug("compute 'isExceptionFound'"); 72 | this.isExceptionFound = computeIsExceptionFound(catchTreeList); 73 | LOGGER.debug("isExceptionFound : " + isExceptionFound); 74 | } 75 | LOGGER.debug("--------------------_____-----_____----- OptimizeReadFileExceptions.visitNode METHOD - END"); 76 | } 77 | 78 | private boolean computeIsExceptionFound(List catchTreeList) { 79 | return catchTreeList.stream().anyMatch(catchTree -> 80 | catchTree.parameter().type().symbolType().toString().equals("FileNotFoundException") 81 | || catchTree.parameter().type().symbolType().toString().equals("IOException") 82 | || catchTree.parameter().type().symbolType().toString().equals("Exception") 83 | || catchTree.parameter().type().symbolType().toString().equals("Throwable") 84 | ); 85 | } 86 | } 87 | -------------------------------------------------------------------------------- /src/main/java/org/greencodeinitiative/creedengo/java/checks/AvoidSQLRequestInLoop.java: -------------------------------------------------------------------------------- 1 | /* 2 | * creedengo - Java language - Provides rules to reduce the environmental footprint of your Java programs 3 | * Copyright © 2024 Green Code Initiative (https://green-code-initiative.org/) 4 | * 5 | * This program is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU General Public License as published by 7 | * the Free Software Foundation, either version 3 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU General Public License 16 | * along with this program. If not, see . 17 | */ 18 | package org.greencodeinitiative.creedengo.java.checks; 19 | 20 | import java.util.Arrays; 21 | import java.util.List; 22 | 23 | import org.sonar.check.Rule; 24 | import org.sonar.plugins.java.api.IssuableSubscriptionVisitor; 25 | import org.sonar.plugins.java.api.semantic.MethodMatchers; 26 | import static org.sonar.plugins.java.api.semantic.MethodMatchers.CONSTRUCTOR; 27 | import org.sonar.plugins.java.api.tree.BaseTreeVisitor; 28 | import org.sonar.plugins.java.api.tree.MethodInvocationTree; 29 | import org.sonar.plugins.java.api.tree.Tree; 30 | import org.sonar.plugins.java.api.tree.Tree.Kind; 31 | import org.sonarsource.analyzer.commons.annotations.DeprecatedRuleKey; 32 | 33 | @Rule(key = "GCI72") 34 | @DeprecatedRuleKey(repositoryKey = "ecocode-java", ruleKey = "EC72") 35 | @DeprecatedRuleKey(repositoryKey = "greencodeinitiative-java", ruleKey = "S72") 36 | public class AvoidSQLRequestInLoop extends IssuableSubscriptionVisitor { 37 | 38 | protected static final String MESSAGERULE = "Avoid SQL request in loop"; 39 | private static final String JAVA_SQL_STATEMENT = "java.sql.Statement"; 40 | private static final String JAVA_SQL_CONNECTION = "java.sql.Connection"; 41 | private static final String SPRING_JDBC_OPERATIONS = "org.springframework.jdbc.core.JdbcOperations"; 42 | 43 | private static final MethodMatchers SQL_METHOD = MethodMatchers.or( 44 | MethodMatchers.create().ofSubTypes("org.hibernate.Session").names("createQuery", "createSQLQuery") 45 | .withAnyParameters().build(), 46 | MethodMatchers.create().ofSubTypes(JAVA_SQL_STATEMENT) 47 | .names("executeQuery", "execute", "executeUpdate", "executeLargeUpdate") // addBatch is recommended 48 | .withAnyParameters().build(), 49 | MethodMatchers.create().ofSubTypes(JAVA_SQL_CONNECTION) 50 | .names("prepareStatement", "prepareCall", "nativeSQL") 51 | .withAnyParameters().build(), 52 | MethodMatchers.create().ofTypes("javax.persistence.EntityManager") 53 | .names("createNativeQuery", "createQuery") 54 | .withAnyParameters().build(), 55 | MethodMatchers.create().ofSubTypes(SPRING_JDBC_OPERATIONS) 56 | .names("batchUpdate", "execute", "query", "queryForList", "queryForMap", "queryForObject", 57 | "queryForRowSet", "queryForInt", "queryForLong", "update") 58 | .withAnyParameters().build(), 59 | MethodMatchers.create().ofTypes("org.springframework.jdbc.core.PreparedStatementCreatorFactory") 60 | .names(CONSTRUCTOR, "newPreparedStatementCreator") 61 | .withAnyParameters().build(), 62 | MethodMatchers.create().ofSubTypes("javax.jdo.PersistenceManager").names("newQuery") 63 | .withAnyParameters().build(), 64 | MethodMatchers.create().ofSubTypes("javax.jdo.Query").names("setFilter", "setGrouping") 65 | .withAnyParameters().build()); 66 | 67 | private final AvoidSQLRequestInLoopVisitor visitorInFile = new AvoidSQLRequestInLoopVisitor(); 68 | 69 | @Override 70 | public List nodesToVisit() { 71 | return Arrays.asList( 72 | Tree.Kind.FOR_EACH_STATEMENT, Tree.Kind.FOR_STATEMENT, 73 | Tree.Kind.WHILE_STATEMENT, Tree.Kind.DO_STATEMENT); 74 | } 75 | 76 | @Override 77 | public void visitNode(Tree tree) { 78 | tree.accept(visitorInFile); 79 | } 80 | 81 | private class AvoidSQLRequestInLoopVisitor extends BaseTreeVisitor { 82 | 83 | @Override 84 | public void visitMethodInvocation(MethodInvocationTree tree) { 85 | if (SQL_METHOD.matches(tree)) { 86 | reportIssue(tree, MESSAGERULE); 87 | } else { 88 | super.visitMethodInvocation(tree); 89 | } 90 | } 91 | } 92 | } 93 | --------------------------------------------------------------------------------