Skip to content
45 changes: 44 additions & 1 deletion .github/scripts/generate-quality-report.py
Original file line number Diff line number Diff line change
Expand Up @@ -763,6 +763,7 @@ def main() -> None:
if spotbugs:
forbidden_rules = {
"NP_ALWAYS_NULL",
"NP_NULL_PARAM_DEREF",
"RCN_REDUNDANT_NULLCHECK_OF_NONNULL_VALUE",
"RCN_REDUNDANT_NULLCHECK_OF_NULL_VALUE",
"UWF_FIELD_NOT_INITIALIZED_IN_CONSTRUCTOR",
Expand All @@ -772,10 +773,12 @@ def main() -> None:
"IA_AMBIGUOUS_INVOCATION_OF_INHERITED_OR_OUTER_METHOD",
"LI_LAZY_INIT_STATIC",
"RpC_REPEATED_CONDITIONAL_TEST",
"NS_NON_SHORT_CIRCUIT",
"ES_COMPARING_PARAMETER_STRING_WITH_EQ",
"FE_FLOATING_POINT_EQUALITY",
"FE_TEST_IF_EQUAL_TO_NOT_A_NUMBER",
"ICAST_IDIV_CAST_TO_DOUBLE",
"ICAST_QUESTIONABLE_UNSIGNED_RIGHT_SHIFT",
"SA_FIELD_SELF_ASSIGNMENT",
"UC_USELESS_CONDITION",
"UC_USELESS_OBJECT",
Expand All @@ -787,7 +790,9 @@ def main() -> None:
"EQ_DOESNT_OVERRIDE_EQUALS",
"CO_COMPARETO_INCORRECT_FLOATING",
"DL_SYNCHRONIZATION_ON_SHARED_CONSTANT",
"SSD_DO_NOT_USE_INSTANCE_LOCK_ON_SHARED_STATIC_DATA",
"DLS_DEAD_LOCAL_STORE",
"DLS_DEAD_LOCAL_STORE_OF_NULL",
"DM_NUMBER_CTOR",
"DMI_INVOKING_TOSTRING_ON_ARRAY",
"EC_NULL_ARG",
Expand Down Expand Up @@ -815,26 +820,48 @@ def main() -> None:
"NM_CONFUSING",
"NM_FIELD_NAMING_CONVENTION",
"NM_METHOD_NAMING_CONVENTION",
"NN_NAKED_NOTIFY",
"NO_NOTIFY_NOT_NOTIFYALL",
"NP_LOAD_OF_KNOWN_NULL_VALUE",
"NP_BOOLEAN_RETURN_NULL",
"RC_REF_COMPARISON_BAD_PRACTICE_BOOLEAN",
"OS_OPEN_STREAM",
"REFLC_REFLECTION_MAY_INCREASE_ACCESSIBILITY_OF_CLASS",
"REC_CATCH_EXCEPTION",
"RCN_REDUNDANT_NULLCHECK_WOULD_HAVE_BEEN_A_NPE",
"RV_RETURN_VALUE_IGNORED_NO_SIDE_EFFECT",
"INT_VACUOUS_COMPARISON",
"DM_STRING_TOSTRING",
"HE_HASHCODE_USE_OBJECT_EQUALS",
"IM_BAD_CHECK_FOR_ODD",
"IM_AVERAGE_COMPUTATION_COULD_OVERFLOW",
"INT_VACUOUS_BIT_OPERATION",
"ICAST_INT_2_LONG_AS_INSTANT",
"ICAST_INT_CAST_TO_FLOAT_PASSED_TO_ROUND",
"IT_NO_SUCH_ELEMENT",
"FL_FLOATS_AS_LOOP_COUNTERS",
"UI_INHERITANCE_UNSAFE_GETRESOURCE",
"IS2_INCONSISTENT_SYNC",
"RR_NOT_CHECKED",
"URF_UNREAD_FIELD",
"URF_UNREAD_PUBLIC_OR_PROTECTED_FIELD",
"UR_UNINIT_READ",
"UUF_UNUSED_FIELD",
"UWF_NULL_FIELD",
"UW_UNCOND_WAIT",
"LI_LAZY_INIT_UPDATE_STATIC",
"SIC_INNER_SHOULD_BE_STATIC_ANON",
"SS_SHOULD_BE_STATIC",
"UPM_UNCALLED_PRIVATE_METHOD",
"RV_RETURN_VALUE_IGNORED_INFERRED",
"RV_CHECK_FOR_POSITIVE_INDEXOF",
"SF_SWITCH_FALLTHROUGH",
"SIC_INNER_SHOULD_BE_STATIC_NEEDS_THIS"
"SIC_INNER_SHOULD_BE_STATIC_NEEDS_THIS",
"SA_FIELD_DOUBLE_ASSIGNMENT",
"SA_FIELD_SELF_COMPARISON",
"SR_NOT_CHECKED",
"SWL_SLEEP_WITH_LOCK_HELD",
"UC_USELESS_CONDITION_TYPE"
}

def _is_exempt(f: Finding) -> bool:
Expand All @@ -851,6 +878,10 @@ def _is_exempt(f: Finding) -> bool:
return True
if f.rule == "URF_UNREAD_FIELD" and "GridBagLayoutInfo" in loc:
return True
if f.rule == "NN_NAKED_NOTIFY" and "Display.java" in loc:
return True
if f.rule == "ICAST_QUESTIONABLE_UNSIGNED_RIGHT_SHIFT" and "Deflate.java" in loc:
return True
return False


Expand All @@ -864,6 +895,18 @@ def _is_exempt(f: Finding) -> bool:
print(f" - {v.rule}: {v.location} - {v.message}")
exit(1)

pmd = parse_pmd()
if pmd:
forbidden_pmd_rules = {
"ClassWithOnlyPrivateConstructorsShouldBeFinal",
}
violations = [f for f in pmd.findings if f.rule in forbidden_pmd_rules]
if violations:
print("\n❌ Build failed due to forbidden PMD violations:")
for v in violations:
print(f" - {v.rule}: {v.location} - {v.message}")
exit(1)


if __name__ == "__main__":
main()
4 changes: 2 additions & 2 deletions CodenameOne/src/com/codename1/capture/Capture.java
Original file line number Diff line number Diff line change
Expand Up @@ -247,7 +247,7 @@ public static void captureVideo(ActionListener<ActionEvent> response) {

static class CallBack implements ActionListener<ActionEvent>, Runnable {
String url;
private boolean completed;
private volatile boolean completed;
private int targetWidth = -1;
private int targetHeight = -1;

Expand All @@ -257,8 +257,8 @@ public void actionPerformed(ActionEvent evt) {
} else {
url = (String) evt.getSource();
}
completed = true;
synchronized (this) {
completed = true;
this.notifyAll();
}
}
Expand Down
2 changes: 1 addition & 1 deletion CodenameOne/src/com/codename1/charts/util/MathHelper.java
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@
/**
* Utility class for math operations.
*/
public class MathHelper {
public final class MathHelper {
/** A value that is used a null value. */
public static final double NULL_VALUE = -Double.MAX_VALUE + 1;
/**
Expand Down
7 changes: 4 additions & 3 deletions CodenameOne/src/com/codename1/charts/views/PieSegment.java
Original file line number Diff line number Diff line change
Expand Up @@ -52,9 +52,10 @@ public boolean isInSegment(double angle) {
double cAngle = angle % 360;
double startAngle = mStartAngle;
double stopAngle = mEndAngle;
while (stopAngle > 360) {
startAngle -= 360;
stopAngle -= 360;
if (stopAngle > 360) {
int rotations = (int) Math.floor(stopAngle / 360d);
startAngle -= 360 * rotations;
stopAngle -= 360 * rotations;
}
return cAngle >= startAngle && cAngle <= stopAngle;
}
Expand Down
5 changes: 3 additions & 2 deletions CodenameOne/src/com/codename1/charts/views/RadarChart.java
Original file line number Diff line number Diff line change
Expand Up @@ -112,8 +112,9 @@ public void draw(Canvas canvas, int x, int y, int width, int height, Paint paint
paint.setColor(ColorUtil.GRAY);
float thisRad = (float) Math.toRadians(90 - currentAngle);
float nextRad = (float) Math.toRadians(90 - (currentAngle + angle));
for (double level = 0; level <= 1d; level += decCoef) { // PMD Fix: DontUseFloatTypeForLoopIndices switched to double
float levelFactor = (float) level;
int levelSteps = (int) Math.round(1d / decCoef);
for (int level = 0; level <= levelSteps; level++) {
float levelFactor = (float) (level * decCoef);
float thisX = (float) (centerX - Math.sin(thisRad) * radius * levelFactor);
float thisY = (float) (centerY - Math.cos(thisRad) * radius * levelFactor);
float nextX = (float) (centerX - Math.sin(nextRad) * radius * levelFactor);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@
*
* @author Shai Almog
*/
public class ClearableTextField extends Container {
public final class ClearableTextField extends Container {
private ClearableTextField() {
super(new BorderLayout());
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@
*
* @author Shai Almog
*/
public class FileEncodedImage extends EncodedImage {
public final class FileEncodedImage extends EncodedImage {
private final String fileName;
private final boolean keep;
private byte[] data;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@
*
* @author Shai Almog
*/
public class FileEncodedImageAsync extends EncodedImage {
public final class FileEncodedImageAsync extends EncodedImage {
private static final Object LOCK = new Object();
private final String fileName;
private boolean changePending;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@
*
* @author Shai Almog
*/
public class InfiniteScrollAdapter {
public final class InfiniteScrollAdapter {
private Container infiniteContainer;
private Runnable fetchMore;
private final Component ip;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@
*
* @author Shai Almog
*/
public class ReplaceableImage extends EncodedImage {
public final class ReplaceableImage extends EncodedImage {
private boolean replaced;
private byte[] data;
private final boolean opaque;
Expand Down
2 changes: 1 addition & 1 deletion CodenameOne/src/com/codename1/components/StorageImage.java
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@
*
* @author Shai Almog
*/
public class StorageImage extends EncodedImage {
public final class StorageImage extends EncodedImage {
private final String fileName;
private final boolean keep;
private byte[] data;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@
*
* @author Shai Almog
*/
public class StorageImageAsync extends EncodedImage {
public final class StorageImageAsync extends EncodedImage {
private static final Object LOCK = new Object();
private final String fileName;
private boolean changePending;
Expand Down
2 changes: 1 addition & 1 deletion CodenameOne/src/com/codename1/components/ToastBar.java
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@
*
* @author shannah
*/
public class ToastBar {
public final class ToastBar {

/**
* The default timeout for info/error messages
Expand Down
2 changes: 1 addition & 1 deletion CodenameOne/src/com/codename1/components/WebBrowser.java
Original file line number Diff line number Diff line change
Expand Up @@ -154,8 +154,8 @@ protected void readResponse(InputStream input) throws IOException {
if (callback != null) {
callback.streamReady(input, docInfo);
} else {
response[0] = input;
synchronized (LOCK) {
response[0] = input;
LOCK.notifyAll();
}
}
Expand Down
2 changes: 1 addition & 1 deletion CodenameOne/src/com/codename1/facebook/FaceBookAccess.java
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@
*
* @author Chen Fishbein
*/
public class FaceBookAccess {
public final class FaceBookAccess {

private static final String TEMP_STORAGE = "FaceBookAccesstmp";
private static String clientId = "132970916828080";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -239,8 +239,11 @@ public void numericToken(double tok) {
}

public void keyValue(String key, String value) {
if (key == null) {
return;
}
//make sure value is not null to prevent NPE
if (key != null && value == null) {
if (value == null) {
value = "";
}
getCurrent().put(key, value);
Expand Down
23 changes: 8 additions & 15 deletions CodenameOne/src/com/codename1/impl/CodenameOneImplementation.java
Original file line number Diff line number Diff line change
Expand Up @@ -1516,9 +1516,9 @@ public int getTranslateY(Object graphics) {
* said color value.
*
* @param graphics the graphics context
* @param RGB the RGB value for the color.
* @param rgb the RGB value for the color.
*/
public abstract void setColor(Object graphics, int RGB);
public abstract void setColor(Object graphics, int rgb);

/**
* Alpha value from 0-255 can be ignored for some operations
Expand Down Expand Up @@ -3966,22 +3966,19 @@ public Rectangle getDisplaySafeArea(Rectangle rect) {
* common constants in this class or be a user/implementation defined sound
*/
public void playBuiltinSound(String soundIdentifier) {
boolean played = playUserSound(soundIdentifier);
if (!played) {
return;
}
playUserSound(soundIdentifier);
}

/**
* Plays a sound defined by the user
*
* @param soundIdentifier the sound identifier which can match one of the
* common constants in this class or be a user/implementation defined sound
* @return true if a user sound exists and was sent to playback
*/
protected boolean playUserSound(String soundIdentifier) {
Object sound = builtinSounds.get(soundIdentifier);
return sound != null;
protected void playUserSound(String soundIdentifier) {
// TODO: Reintroduce builitin sound support
//Object sound = builtinSounds.get(soundIdentifier);
//return sound != null;
//playAudio(sound);
}

Expand Down Expand Up @@ -7177,13 +7174,9 @@ protected final void pushReceived(String data) {
* Sets the frequency for polling the server in case of polling based push notification
*
* @param freq the frequency in milliseconds
* @deprecated we no longer support push polling
*/
public void setPollingFrequency(int freq) {
if (callback != null && pollingThreadRunning) {
synchronized (callback) {
callback.notifyAll();
}
}
}

/**
Expand Down
10 changes: 8 additions & 2 deletions CodenameOne/src/com/codename1/impl/CodenameOneThread.java
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
package com.codename1.impl;

import com.codename1.io.Log;
import com.codename1.io.Util;
import com.codename1.ui.Display;

import java.io.DataInputStream;
Expand Down Expand Up @@ -133,6 +134,8 @@ public void storeStackForException(Throwable t, int currentStackFrame) {
* Prints the stack trace matching the given stack
*/
public String getStack(Throwable t) {
InputStream inp = null;
DataInputStream di = null;
try {
StringBuilder b = new StringBuilder();
int size;
Expand All @@ -145,11 +148,11 @@ public String getStack(Throwable t) {
}
String[] stk = new String[size];

InputStream inp = Display.getInstance().getResourceAsStream(getClass(), "/methodData.dat");
inp = Display.getInstance().getResourceAsStream(getClass(), "/methodData.dat");
if (inp == null) {
return t.toString();
}
DataInputStream di = new DataInputStream(inp);
di = new DataInputStream(inp);
int totalAmount = di.readInt();
String lastClass = "";
for (int x = 0; x < totalAmount; x++) {
Expand All @@ -172,6 +175,9 @@ public String getStack(Throwable t) {
return b.toString();
} catch (IOException ex) {
ex.printStackTrace();
} finally {
Util.cleanup(di);
Util.cleanup(inp);
}
return "Failed in stack generation for " + t;
}
Expand Down
Loading