forked from WorksApplications/findbugs-plugin
-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request WorksApplications#14 from eller86/detect-implicit-…
…length Detect implicit 'length' and 'nullable' of @column
- Loading branch information
Showing
17 changed files
with
445 additions
and
15 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
100 changes: 100 additions & 0 deletions
100
src/main/java/jp/co/worksap/oss/findbugs/jpa/AbstractColumnDetector.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,100 @@ | ||
package jp.co.worksap.oss.findbugs.jpa; | ||
|
||
import java.util.List; | ||
import java.util.Map; | ||
|
||
import javax.annotation.CheckReturnValue; | ||
import javax.annotation.Nonnull; | ||
|
||
import org.apache.bcel.classfile.AnnotationEntry; | ||
import org.apache.bcel.classfile.ElementValue; | ||
import org.apache.bcel.classfile.Field; | ||
import org.apache.bcel.classfile.FieldOrMethod; | ||
import org.apache.bcel.generic.Type; | ||
|
||
import com.google.common.base.Objects; | ||
import com.google.common.collect.Lists; | ||
|
||
import edu.umd.cs.findbugs.BugReporter; | ||
import edu.umd.cs.findbugs.bcel.AnnotationDetector; | ||
import edu.umd.cs.findbugs.internalAnnotations.DottedClassName; | ||
|
||
abstract class AbstractColumnDetector extends AnnotationDetector { | ||
private final BugReporter bugReporter; | ||
|
||
AbstractColumnDetector(BugReporter bugReporter) { | ||
this.bugReporter = bugReporter; | ||
} | ||
|
||
@Nonnull | ||
@CheckReturnValue | ||
protected final BugReporter getBugReporter() { | ||
return bugReporter; | ||
} | ||
|
||
@Override | ||
public final void visitAnnotation(@DottedClassName String annotationClass, | ||
Map<String, ElementValue> map, boolean runtimeVisible) { | ||
if (!Objects.equal(annotationClass, "javax.persistence.Column")) { | ||
return; | ||
} | ||
|
||
Type columnType = findVisitingColumnType(); | ||
verifyColumn(columnType, map); | ||
} | ||
|
||
protected boolean isVisitingLob() { | ||
List<FieldOrMethod> targetListToSearch = Lists.newArrayList(); | ||
if (visitingField()) { | ||
targetListToSearch.add(getField()); | ||
} else if (visitingMethod()) { | ||
targetListToSearch.add(getMethod()); | ||
targetListToSearch.add(findFieldInVisitingMethod()); | ||
} else { | ||
throw new IllegalStateException("@Column should annotate field or method."); | ||
} | ||
|
||
for (FieldOrMethod targetToSearch : targetListToSearch) { | ||
for (AnnotationEntry annotation : targetToSearch.getAnnotationEntries()) { | ||
if (!Objects.equal(annotation.getAnnotationType(), "Ljavax/persistence/Lob;")) { | ||
continue; | ||
} | ||
return true; | ||
} | ||
} | ||
|
||
return false; | ||
} | ||
|
||
private Type findVisitingColumnType() { | ||
final Type columnType; | ||
if (visitingField()) { | ||
columnType = getField().getType(); | ||
} else if (visitingMethod()) { | ||
Field visitingField = findFieldInVisitingMethod(); | ||
columnType = visitingField.getType(); | ||
} else { | ||
throw new IllegalStateException("@Column should annotate field or method."); | ||
} | ||
return columnType; | ||
} | ||
|
||
@Nonnull | ||
private Field findFieldInVisitingMethod() { | ||
String fieldName = VisitedFieldFinder.findFieldWhichisVisitedInVisitingMethod(this); | ||
Field visitingField = null; | ||
for (Field field : getThisClass().getFields()) { | ||
if (Objects.equal(field.getName(), fieldName)) { | ||
visitingField = field; | ||
break; | ||
} | ||
} | ||
if (visitingField == null) { | ||
throw new IllegalStateException("Cannot find field which named as " + fieldName + "."); | ||
} | ||
return visitingField; | ||
} | ||
|
||
protected abstract void verifyColumn(Type columnType, Map<String, ElementValue> elements); | ||
|
||
} |
67 changes: 67 additions & 0 deletions
67
src/main/java/jp/co/worksap/oss/findbugs/jpa/ImplicitLengthDetector.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,67 @@ | ||
package jp.co.worksap.oss.findbugs.jpa; | ||
|
||
import java.util.Map; | ||
|
||
import org.apache.bcel.classfile.ElementValue; | ||
import org.apache.bcel.generic.Type; | ||
|
||
import edu.umd.cs.findbugs.BugInstance; | ||
import edu.umd.cs.findbugs.BugReporter; | ||
|
||
public class ImplicitLengthDetector extends AbstractColumnDetector { | ||
/** | ||
* @see http://docs.oracle.com/cd/B28359_01/server.111/b28320/limits001.htm | ||
*/ | ||
private static final int MAX_LENGTH_OF_ORACLE_VARCHAR = 4000; | ||
/** | ||
* @see http://www-01.ibm.com/support/knowledgecenter/SSEPEK_10.0.0/com.ibm.db2z10.doc.intro/src/tpc/db2z_stringdatatypes.htm | ||
*/ | ||
private static final int MAX_LENGTH_OF_DB2_VARCHAR = 32704; | ||
|
||
private static final int MAX_LENGTH_OF_VARCHAR = Math.min(MAX_LENGTH_OF_ORACLE_VARCHAR, MAX_LENGTH_OF_DB2_VARCHAR); | ||
|
||
public ImplicitLengthDetector(BugReporter bugReporter) { | ||
super(bugReporter); | ||
} | ||
|
||
@Override | ||
protected void verifyColumn(Type columnType, | ||
Map<String, ElementValue> elements) { | ||
if (! isTarget(columnType)) { | ||
return; | ||
} | ||
|
||
if (! elements.containsKey("length")) { | ||
BugInstance bug = new BugInstance(this, "IMPLICIT_LENGTH", HIGH_PRIORITY); | ||
if (visitingMethod()) { | ||
bug.addMethod(this); | ||
} | ||
getBugReporter().reportBug(bug); | ||
} else { | ||
ElementValue value = elements.get("length"); | ||
int lengthValue = Integer.parseInt(value.stringifyValue()); | ||
|
||
if (lengthValue <= 0) { | ||
reportIllegalLength(lengthValue); | ||
} else if (MAX_LENGTH_OF_VARCHAR < lengthValue && !isVisitingLob()) { | ||
reportIllegalLength(lengthValue); | ||
} | ||
} | ||
} | ||
|
||
private void reportIllegalLength(int lengthValue) { | ||
BugInstance bug = new BugInstance(this, "ILLEGAL_LENGTH", HIGH_PRIORITY); | ||
if (visitingMethod()) { | ||
bug.addMethod(this); | ||
} | ||
getBugReporter().reportBug(bug); | ||
} | ||
|
||
/** | ||
* @return true if column type requires length property. | ||
*/ | ||
private boolean isTarget(Type columnType) { | ||
return Type.STRING.equals(columnType) || Type.STRINGBUFFER.equals(columnType); | ||
} | ||
|
||
} |
28 changes: 28 additions & 0 deletions
28
src/main/java/jp/co/worksap/oss/findbugs/jpa/ImplicitNullnessDetector.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
package jp.co.worksap.oss.findbugs.jpa; | ||
|
||
import java.util.Map; | ||
|
||
import org.apache.bcel.classfile.ElementValue; | ||
import org.apache.bcel.generic.Type; | ||
|
||
import edu.umd.cs.findbugs.BugInstance; | ||
import edu.umd.cs.findbugs.BugReporter; | ||
|
||
public class ImplicitNullnessDetector extends AbstractColumnDetector { | ||
|
||
public ImplicitNullnessDetector(BugReporter bugReporter) { | ||
super(bugReporter); | ||
} | ||
|
||
@Override | ||
protected void verifyColumn(Type columnType, | ||
Map<String, ElementValue> elements) { | ||
if (! elements.containsKey("nullable")) { | ||
BugInstance bug = new BugInstance(this, "IMPLICIT_NULLNESS", HIGH_PRIORITY); | ||
if (visitingMethod()) { | ||
bug.addMethod(this); | ||
} | ||
getBugReporter().reportBug(bug); | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
12 changes: 12 additions & 0 deletions
12
src/test/java/jp/co/worksap/oss/findbugs/jpa/ColumnWithLength.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
package jp.co.worksap.oss.findbugs.jpa; | ||
|
||
import javax.persistence.Column; | ||
|
||
public class ColumnWithLength { | ||
@Column(length = 100) | ||
private String name; | ||
|
||
public String getName() { | ||
return name; | ||
} | ||
} |
Oops, something went wrong.