Skip to content
New issue

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

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

Already on GitHub? Sign in to your account

[205] UseFetchTypeLazyRule #48

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 3 additions & 16 deletions src/main/java/fr/greencodeinitiative/java/JavaCheckRegistrar.java
Original file line number Diff line number Diff line change
Expand Up @@ -20,21 +20,7 @@
import java.util.Collections;
import java.util.List;

import fr.greencodeinitiative.java.checks.ArrayCopyCheck;
import fr.greencodeinitiative.java.checks.AvoidFullSQLRequest;
import fr.greencodeinitiative.java.checks.AvoidGettingSizeCollectionInLoop;
import fr.greencodeinitiative.java.checks.AvoidMultipleIfElseStatement;
import fr.greencodeinitiative.java.checks.AvoidRegexPatternNotStatic;
import fr.greencodeinitiative.java.checks.AvoidSQLRequestInLoop;
import fr.greencodeinitiative.java.checks.AvoidSetConstantInBatchUpdate;
import fr.greencodeinitiative.java.checks.AvoidSpringRepositoryCallInLoopOrStreamCheck;
import fr.greencodeinitiative.java.checks.AvoidStatementForDMLQueries;
import fr.greencodeinitiative.java.checks.AvoidUsageOfStaticCollections;
import fr.greencodeinitiative.java.checks.FreeResourcesOfAutoCloseableInterface;
import fr.greencodeinitiative.java.checks.IncrementCheck;
import fr.greencodeinitiative.java.checks.InitializeBufferWithAppropriateSize;
import fr.greencodeinitiative.java.checks.NoFunctionCallWhenDeclaringForLoop;
import fr.greencodeinitiative.java.checks.OptimizeReadFileExceptions;
import fr.greencodeinitiative.java.checks.*;
import org.sonar.plugins.java.api.CheckRegistrar;
import org.sonar.plugins.java.api.JavaCheck;
import org.sonarsource.api.sonarlint.SonarLintSide;
Expand Down Expand Up @@ -62,7 +48,8 @@ public class JavaCheckRegistrar implements CheckRegistrar {
InitializeBufferWithAppropriateSize.class,
AvoidSetConstantInBatchUpdate.class,
FreeResourcesOfAutoCloseableInterface.class,
AvoidMultipleIfElseStatement.class
AvoidMultipleIfElseStatement.class,
UseFetchTypeLazyRule.class
);

/**
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
/*
* ecoCode - Java language - Provides rules to reduce the environmental footprint of your Java programs
* Copyright © 2023 Green Code Initiative (https://www.ecocode.io)
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package fr.greencodeinitiative.java.checks;

import org.sonar.check.Rule;
import org.sonar.plugins.java.api.JavaFileScanner;
import org.sonar.plugins.java.api.JavaFileScannerContext;
import org.sonar.plugins.java.api.tree.*;

@Rule(key = "EC205")
public class UseFetchTypeLazyRule extends BaseTreeVisitor implements JavaFileScanner {
protected static final String ONE_TO_MANY = "OneToMany";
protected static final String MESSAGE_RULE = "Avoid Using FetchType.EAGER instead of FetchType.LAZY on collections in JPA Entity";
protected static final String JPA_ANNOTATION_WITHOUT_FETCH_TYPE_DETECTED = "JPA annotation without FetchType detected";
protected static final String LAZY = "LAZY";
protected static final String MANY_TO_MANY = "ManyToMany";
private JavaFileScannerContext context;

@Override
public void scanFile(JavaFileScannerContext javaFileScannerContext) {
this.context = javaFileScannerContext;
// The call to the scan method on the root of the tree triggers the visit of the AST by this visitor
scan(context.getTree());
}

@Override
public void visitAnnotation(AnnotationTree annotationTree) {
String annotationName = ((IdentifierTree) annotationTree.annotationType()).name();
if (ONE_TO_MANY.equals(annotationName)
|| MANY_TO_MANY.equals(annotationName)) {
boolean fetchExist = false;
ExpressionTree fetchTypeArg = null;

for (ExpressionTree argument : annotationTree.arguments()) {
if (argument.is(Tree.Kind.ASSIGNMENT)) {
AssignmentExpressionTree assignmentInvocation = (AssignmentExpressionTree) argument;
if (assignmentInvocation.variable().toString().equals("fetch")) {
fetchExist = true;
fetchTypeArg = assignmentInvocation.expression();
}
}
}

this.reportFetchTypeIssue(fetchExist,fetchTypeArg,annotationTree);
}
super.visitAnnotation(annotationTree);
}

private void reportFetchTypeIssue(boolean fetchExist, ExpressionTree fetchTypeArg, AnnotationTree annotationTree){
if (!fetchExist) {
context.reportIssue(this, annotationTree, JPA_ANNOTATION_WITHOUT_FETCH_TYPE_DETECTED);
} else if (fetchTypeArg != null) {
String fetchType = ((MemberSelectExpressionTree) fetchTypeArg).identifier().name();
if (!LAZY.equals(fetchType.strip())) {
context.reportIssue(this, annotationTree, MESSAGE_RULE);
}
}
}
}
50 changes: 50 additions & 0 deletions src/test/files/UseFetchTypeLazyRule.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
/*
* ecoCode - Java language - Provides rules to reduce the environmental footprint of your Java programs
* Copyright © 2023 Green Code Initiative (https://www.ecocode.io)
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package fr.greencodeinitiative.java.checks;

import javax.persistence.OneToMany;
import javax.persistence.ManyToOne;
import java.util.Collections;

public class UseFetchTypeLazyRuleTest {

@OneToMany(mappedBy = "firstEntity") // Noncompliant
private Collection<SomeEntity> firstEntities;

@ManyToMany(mappedBy = "firstEntity1") // Noncompliant
private Collection<SomeEntity> firstEntities1;

@OneToMany // Noncompliant
private Collection<SomeEntity> secondEntities1;

@ManyToMany // Noncompliant
private Collection<SomeEntity> secondEntities2;

@OneToMany(mappedBy = "thirdEntity1", fetch= FetchType.EAGER) // Noncompliant
private Collection<SomeEntity> thirdEntities1;

@ManyToMany(mappedBy = "thirdEntity1", fetch= FetchType.EAGER) // Noncompliant
private Collection<SomeEntity> thirdEntities2;

@OneToMany(fetch = FetchType.LAZY) // Compliant
private Collection<SomeEntity> fourthEntities1;

@ManyToMany(fetch = FetchType.LAZY) // Compliant
private Collection<SomeEntity> fourthEntities2;

}
Original file line number Diff line number Diff line change
Expand Up @@ -31,9 +31,8 @@ void checkNumberRules() {
final JavaCheckRegistrar registrar = new JavaCheckRegistrar();
registrar.register(context);

assertThat(context.checkClasses()).hasSize(15);
assertThat(context.checkClasses()).hasSize(16);
assertThat(context.testCheckClasses()).isEmpty();

}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
/*
* ecoCode - Java language - Provides rules to reduce the environmental footprint of your Java programs
* Copyright © 2023 Green Code Initiative (https://www.ecocode.io)
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package fr.greencodeinitiative.java.checks;

import org.junit.jupiter.api.Test;
import org.sonar.java.checks.verifier.CheckVerifier;

class UseFetchTypeLazyRuleTest {

@Test
void test() {
CheckVerifier.newVerifier()
.onFile("src/test/files/UseFetchTypeLazyRule.java")
.withCheck(new UseFetchTypeLazyRule())
.verifyIssues();
}
}