Skip to content

Commit

Permalink
Merge pull request WorksApplications#18 from eller86/nullable-primitive
Browse files Browse the repository at this point in the history
Detector for nullable primitive
  • Loading branch information
wliyongfeng committed Mar 20, 2014
2 parents ab0d5f7 + 40f2c0a commit 2700f49
Show file tree
Hide file tree
Showing 14 changed files with 252 additions and 12 deletions.
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ To use this product, please configure your findbugs-maven-plugin like below.
- added ImplicitLengthDetector
- added ImplicitNullnessDetector
- added ColumnDefinitionDetector
- added NullablePrimitiveDetector

## 0.0.1

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
package jp.co.worksap.oss.findbugs.jpa;

import java.util.Map;

import org.apache.bcel.classfile.ElementValue;
import org.apache.bcel.generic.ObjectType;
import org.apache.bcel.generic.Type;

import edu.umd.cs.findbugs.BugInstance;
import edu.umd.cs.findbugs.BugReporter;

public class NullablePrimitiveDetector extends AbstractColumnDetector {

public NullablePrimitiveDetector(BugReporter bugReporter) {
super(bugReporter);
}

@Override
protected void verifyColumn(Type columnType,
Map<String, ElementValue> elements) {
if (! isPrimitive(columnType)) {
return;
}

boolean isNullableColumn = detectNullability(elements);
if (isNullableColumn) {
reportNullablePrimitive(columnType);
}
}

private void reportNullablePrimitive(Type columnType) {
BugInstance bug = new BugInstance(this, "NULLABLE_PRIMITIVE", NORMAL_PRIORITY);
if (visitingMethod()) {
bug.addMethod(this);
}
getBugReporter().reportBug(bug);

}

private boolean detectNullability(Map<String, ElementValue> elements) {
if (! elements.containsKey("nullable")) {
// in JPA 1.0 specification, default value of 'nullable' parameter is true
// note that this case will be reported by ImplicitNullnessDetector.
return true;
}

String nullability = elements.get("nullable").stringifyValue();
return "true".equals(nullability);
}

/**
* @return true if column type is primitive value (not reference type).
*/
private boolean isPrimitive(Type columnType) {
return ! (columnType instanceof ObjectType); // looks bad, but simple way to check primitive or not.
}

}
1 change: 1 addition & 0 deletions src/main/meta/bugrank.txt
Original file line number Diff line number Diff line change
Expand Up @@ -11,3 +11,4 @@
0 BugPattern IMPLICIT_LENGTH
0 BugPattern ILLEGAL_LENGTH
0 BugPattern USE_COLUMN_DEFINITION
0 BugPattern NULLABLE_PRIMITIVE
5 changes: 5 additions & 0 deletions src/main/meta/findbugs.xml
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,11 @@
<BugPattern type="USE_COLUMN_DEFINITION" abbrev="JPA"
category="BAD_PRACTICE" />

<Detector class="jp.co.worksap.oss.findbugs.jpa.NullablePrimitiveDetector"
speed="fast" hidden="false" />
<BugPattern type="NULLABLE_PRIMITIVE" abbrev="JPA"
category="CORRECTNESS" />

<Detector class="jp.co.worksap.oss.findbugs.junit.UndocumentedIgnoreDetector"
speed="fast" hidden="false" />
<BugPattern type="UNDOCUMENTED_IGNORE" abbrev="JUNIT"
Expand Down
45 changes: 33 additions & 12 deletions src/main/meta/messages.xml
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
<LongDescription>we can not use System.out and System.err, please use log to
output information
</LongDescription>
<Details>
<Details>
<![CDATA[
<p>System.out and System.err are forbidden, please use log</p>
]]>
Expand All @@ -39,7 +39,7 @@
</ShortDescription>
<LongDescription>To prevent from bad extending, immutable class should be final.
</LongDescription>
<Details>
<Details>
<![CDATA[
<p>To prevent from bad extending, immutable class should be final.</p>
]]>
Expand All @@ -52,7 +52,7 @@
<LongDescription>
Field ({1}) in class ({2}) should be final to make a class ({3}) immutable.
</LongDescription>
<Details>
<Details>
<![CDATA[
<p>Field of immutable class should be final.</p>
]]>
Expand All @@ -70,7 +70,7 @@
</ShortDescription>
<LongDescription>Nullness of this parameter is unknown.
</LongDescription>
<Details>
<Details>
<![CDATA[
<p>Nullness of this parameter is unknown.</p>
]]>
Expand All @@ -83,7 +83,7 @@
<LongDescription>
Nullness of this returned value is unknown.
</LongDescription>
<Details>
<Details>
<![CDATA[
<p>Nullness of this returned value is unknown.</p>
]]>
Expand All @@ -103,7 +103,7 @@
<LongDescription>
Index name should be shorter than or equal to 30 bytes.
</LongDescription>
<Details>
<Details>
<![CDATA[
<p>Index name should be shorter than or equal to 30 bytes.</p>
]]>
Expand All @@ -123,7 +123,7 @@
<LongDescription>
Table name should be shorter than or equal to 30 bytes.
</LongDescription>
<Details>
<Details>
<![CDATA[
<p>Table name should be shorter than or equal to 30 bytes.</p>
]]>
Expand All @@ -143,7 +143,7 @@
<LongDescription>
Column name should be shorter than or equal to 30 bytes.
</LongDescription>
<Details>
<Details>
<![CDATA[
<p>Column name should be shorter than or equal to 30 bytes.</p>
]]>
Expand All @@ -163,7 +163,7 @@
<LongDescription>
Specify length of column, its default (255) might be not enough.
</LongDescription>
<Details>
<Details>
<![CDATA[
<p>Specify length of column, its default (255) might be not enough.</p>
]]>
Expand Down Expand Up @@ -197,7 +197,7 @@
<LongDescription>
It is good to specify the value of nullable element clear, it tells that you have considered about it.
</LongDescription>
<Details>
<Details>
<![CDATA[
<p>It is good to specify the value of nullable element clear, it tells that you have considered about it.</p>
]]>
Expand All @@ -217,13 +217,34 @@
<LongDescription>
@Column annotation has columnDefinition property, it might break RDBMS portability.
</LongDescription>
<Details>
<Details>
<![CDATA[
<p>@Column annotation has columnDefinition property, it might break RDBMS portability.</p>
]]>
</Details>
</BugPattern>

<Detector class="jp.co.worksap.oss.findbugs.jpa.NullablePrimitiveDetector">
<Details>
This detector will find illegal nullable property of primitive type.
When developer changes type of field from primitive type to reference type (ex. from int to Integer),
he/she might forget to care about this property. This detector helps developer to find this human-error.
</Details>
</Detector>

<BugPattern type="NULLABLE_PRIMITIVE">
<ShortDescription>Nullable property of primitive type should be false.
</ShortDescription>
<LongDescription>
Nullable property of primitive type should be false.
</LongDescription>
<Details>
<![CDATA[
<p>Nullable property of primitive type should be false.</p>
]]>
</Details>
</BugPattern>

<Detector class="jp.co.worksap.oss.findbugs.junit.UndocumentedIgnoreDetector">
<Details>
This detector will find ignored test case which has no explanation about why it is ignored.
Expand All @@ -236,7 +257,7 @@
<LongDescription>
To tell why test case is ignored, put explanation as a parameter.
</LongDescription>
<Details>
<Details>
<![CDATA[
<p>To tell why test case is ignored, put explanation as a parameter.</p>
]]>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
package jp.co.worksap.oss.findbugs.jpa;

import javax.persistence.Column;
import javax.persistence.Entity;

@Entity
public class NonNullablePrimitiveColumn {
@Column(nullable = false)
private boolean booleanValue;

@Column(nullable = false)
private byte byteValue;

@Column(nullable = false)
private short shortValue;

@Column(nullable = false)
private int intValue;

@Column(nullable = false)
private long longValue;

@Column(nullable = false)
private float floatValue;

@Column(nullable = false)
private double doubleValue;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
package jp.co.worksap.oss.findbugs.jpa;

import javax.persistence.Column;
import javax.persistence.Entity;

@Entity
public class NullableBooleanColumn {
@Column(nullable = true)
private boolean booleanValue;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
package jp.co.worksap.oss.findbugs.jpa;

import javax.persistence.Column;
import javax.persistence.Entity;

@Entity
public class NullableByteColumn {
@Column(nullable = true)
private byte byteValue;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
package jp.co.worksap.oss.findbugs.jpa;

import javax.persistence.Column;
import javax.persistence.Entity;

@Entity
public class NullableDoubleColumn {
@Column(nullable = true)
private double doubleValue;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
package jp.co.worksap.oss.findbugs.jpa;

import javax.persistence.Column;
import javax.persistence.Entity;

@Entity
public class NullableFloatColumn {
@Column(nullable = true)
private float floatValue;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
package jp.co.worksap.oss.findbugs.jpa;

import javax.persistence.Column;
import javax.persistence.Entity;

@Entity
public class NullableIntColumn {
@Column(nullable = true)
private int intValue;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
package jp.co.worksap.oss.findbugs.jpa;

import javax.persistence.Column;
import javax.persistence.Entity;

@Entity
public class NullableLongColumn {
@Column(nullable = true)
private long longValue;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
package jp.co.worksap.oss.findbugs.jpa;

import static com.youdevise.fbplugins.tdd4fb.DetectorAssert.assertBugReported;
import static com.youdevise.fbplugins.tdd4fb.DetectorAssert.assertNoBugsReported;
import static com.youdevise.fbplugins.tdd4fb.DetectorAssert.bugReporterForTesting;
import static com.youdevise.fbplugins.tdd4fb.DetectorAssert.ofType;

import org.junit.Before;
import org.junit.Test;

import edu.umd.cs.findbugs.BugReporter;

public class NullablePrimitiveDetectorTest {
private BugReporter bugReporter;
private NullablePrimitiveDetector detector;

@Before
public void before() {
this.bugReporter = bugReporterForTesting();
this.detector = new NullablePrimitiveDetector(bugReporter);
}

@Test
public void testNullableObject() throws Exception {
assertNoBugsReported(UseColumnDefinition.class, detector, bugReporter);
}

@Test
public void testNullableInt() throws Exception {
assertBugReported(NullableBooleanColumn.class, detector,
bugReporter, ofType("NULLABLE_PRIMITIVE"));
assertBugReported(NullableByteColumn.class, detector,
bugReporter, ofType("NULLABLE_PRIMITIVE"));
assertBugReported(NullableShortColumn.class, detector,
bugReporter, ofType("NULLABLE_PRIMITIVE"));
assertBugReported(NullableIntColumn.class, detector,
bugReporter, ofType("NULLABLE_PRIMITIVE"));
assertBugReported(NullableLongColumn.class, detector,
bugReporter, ofType("NULLABLE_PRIMITIVE"));
assertBugReported(NullableFloatColumn.class, detector,
bugReporter, ofType("NULLABLE_PRIMITIVE"));
assertBugReported(NullableDoubleColumn.class, detector,
bugReporter, ofType("NULLABLE_PRIMITIVE"));
}

@Test
public void testNonNullableObject() throws Exception {
assertNoBugsReported(ColumnWithNullable.class, detector, bugReporter);
}

@Test
public void testNonNullableInt() throws Exception {
assertNoBugsReported(NonNullablePrimitiveColumn.class, detector, bugReporter);
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
package jp.co.worksap.oss.findbugs.jpa;

import javax.persistence.Column;
import javax.persistence.Entity;

@Entity
public class NullableShortColumn {
@Column(nullable = true)
private short shortValue;
}

0 comments on commit 2700f49

Please sign in to comment.