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

Replace 'org.json:json' lib with 'com.google.code.gson' lib #1437

Merged
merged 10 commits into from
Mar 3, 2021
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ Currently the versioning policy of this project follows [Semantic Versioning v2.

### Changed
* Bump ASM from 9.0 to 9.1 supporting JDK17
* Replace org.json:json:20201115 with com.google.code.gson:gson:2.8.6

## 4.2.1 - 2021-02-04

Expand Down
2 changes: 1 addition & 1 deletion spotbugs/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,7 @@ dependencies {
// If they're not repackaged, Ant task will report 'java.lang.ClassNotFoundException: edu.umd.cs.findbugs.annotations.CleanupObligation'
api project(':spotbugs-annotations')

api 'org.json:json:20201115'
api "com.google.code.gson:gson:2.8.6"
testImplementation 'junit:junit:4.13.1'
testImplementation 'org.apache.ant:ant:1.10.9'
testImplementation 'org.apache.logging.log4j:log4j-slf4j18-impl:2.14.0'
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@
import edu.umd.cs.findbugs.BugRanker;
import edu.umd.cs.findbugs.annotations.NonNull;
import edu.umd.cs.findbugs.ba.SourceFinder;
import org.json.JSONArray;
import org.json.JSONObject;
import com.google.gson.JsonObject;
import com.google.gson.JsonArray;

import java.net.URI;
import java.util.*;
Expand Down Expand Up @@ -39,18 +39,26 @@ class BugCollectionAnalyser {
});
}

JSONArray getRules() {
return new JSONArray(rules.stream().map(Rule::toJSONObject).collect(Collectors.toList()));
JsonArray getRules() {
JsonArray array = new JsonArray();
rules.stream().map(Rule::toJsonObject).forEach((jsonObject) -> array.add(jsonObject));
return array;
}

JSONArray getResults() {
return new JSONArray(results.stream().map(Result::toJSONObject).collect(Collectors.toList()));
JsonArray getResults() {
JsonArray array = new JsonArray();
results.stream().map(Result::toJsonObject).forEach((jsonObject) -> array.add(jsonObject));
return array;
}

@NonNull
JSONObject getOriginalUriBaseIds() {
JSONObject result = new JSONObject();
baseToId.forEach((uri, uriBaseId) -> result.put(uriBaseId, new JSONObject().put("uri", uri.toString())));
JsonObject getOriginalUriBaseIds() {
JsonObject result = new JsonObject();
baseToId.forEach((uri, uriBaseId) -> {
JsonObject uriJson = new JsonObject();
uriJson.addProperty("uri", uri.toString());
result.add(uriBaseId, uriJson);
});
return result;
}

Expand Down
26 changes: 18 additions & 8 deletions spotbugs/src/main/java/edu/umd/cs/findbugs/sarif/Extension.java
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
import edu.umd.cs.findbugs.Plugin;
import edu.umd.cs.findbugs.annotations.NonNull;
import edu.umd.cs.findbugs.annotations.Nullable;
import org.json.JSONObject;
import com.google.gson.JsonObject;

import java.net.URI;
import java.util.Objects;
Expand Down Expand Up @@ -32,16 +32,26 @@ class Extension {
this.organization = organization;
}

JSONObject toJSONObject() {
JsonObject toJsonObject() {
// TODO put 'fullDescription' with both of text and markdown representations
JSONObject desc = null;
JsonObject desc = null;
if (shortDescription != null) {
desc = new JSONObject().put("text", shortDescription);
desc = new JsonObject();
desc.addProperty("text", shortDescription);
}
return new JSONObject().put("version", version).put("name", name)
.putOpt("shortDescription", desc)
.putOpt("informationUri", informationUri)
.putOpt("organization", organization);
JsonObject extensionJson = new JsonObject();
extensionJson.addProperty("version", version);
extensionJson.addProperty("name", name);
if (desc != null) {
extensionJson.add("shortDescription", desc);
}
if (informationUri != null) {
extensionJson.addProperty("informationUri", informationUri.toString());
}
if (organization != null) {
extensionJson.addProperty("organization", String.valueOf(organization));
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is are any reason to prefer String.valueOf( ... ) over organization.toString()? If so, I want to make the intention clear.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed.
organization was declared as Object it should be String

}
return extensionJson;
}

static Extension fromPlugin(@NonNull Plugin plugin) {
Expand Down
31 changes: 21 additions & 10 deletions spotbugs/src/main/java/edu/umd/cs/findbugs/sarif/Invocation.java
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
package edu.umd.cs.findbugs.sarif;

import edu.umd.cs.findbugs.annotations.NonNull;
import org.json.JSONObject;
import com.google.gson.JsonObject;
import com.google.gson.JsonArray;

import java.util.Collections;
import java.util.List;
Expand Down Expand Up @@ -30,17 +31,27 @@ class Invocation {
}

@NonNull
JSONObject toJSONObject() {
JSONObject result = new JSONObject()
.put("exitCode", exitCode)
.put("exitSignalName", exitSignalName)
.put("executionSuccessful", executionSuccessful);
JsonObject toJsonObject() {
JsonObject result = new JsonObject();
result.addProperty("exitCode", exitCode);
result.addProperty("exitSignalName", exitSignalName);
result.addProperty("executionSuccessful", executionSuccessful);

JsonArray execNotificationArray = new JsonArray();
toolExecutionNotifications.stream()
.map(Notification::toJSONObject)
.forEach(json -> result.append("toolExecutionNotifications", json));
.map(Notification::toJsonObject)
.forEach(json -> execNotificationArray.add(json));
if (execNotificationArray.size() > 0) {
result.add("toolExecutionNotifications", execNotificationArray);
}

JsonArray configNotificationArray = new JsonArray();
toolConfigurationNotifications.stream()
.map(Notification::toJSONObject)
.forEach(json -> result.append("toolConfigurationNotifications", json));
.map(Notification::toJsonObject)
.forEach(json -> configNotificationArray.add(json));
if (configNotificationArray.size() > 0) {
result.add("toolConfigurationNotifications", configNotificationArray);
}
return result;
}
}
8 changes: 3 additions & 5 deletions spotbugs/src/main/java/edu/umd/cs/findbugs/sarif/Level.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,13 @@

import edu.umd.cs.findbugs.BugRankCategory;
import edu.umd.cs.findbugs.annotations.NonNull;
import org.json.JSONString;

/**
* An enum representing {@code level} property.
*
* @see <a href="https://docs.oasis-open.org/sarif/sarif/v2.1.0/cs01/sarif-v2.1.0-cs01.html#_Toc16012604">3.27.10 level property</a>
*/
enum Level implements JSONString {
enum Level {
/**
* The rule specified by ruleId was evaluated and a problem was found.
*/
Expand All @@ -27,9 +26,8 @@ enum Level implements JSONString {
*/
NONE;

@Override
public String toJSONString() {
return String.format("\"%s\"", name().toLowerCase());
public String toJsonString() {
return name().toLowerCase();
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we need this method? The old one was provided to configure the org.json's serializer.
So I assume what we need is not this method but similar way to configure the serialier, like SerializedName.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added SerializedName annotation to the enum. Its useful if we use Gson toJson/fromJson methods to serialize/deserialize objects.

Current we create/setup JsonObject instead serializing object. e.g.

        JsonObject result = new JsonObject();
        result.addProperty("ruleId", ruleId);
        result.addProperty("ruleIndex", ruleIndex);;
        result.addProperty("level", level.toJsonString());

I think after POJO classes are introduced we should be able to use object serialization/deserialization and not need this method anymore

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also tried
return new Gson().toJson(this);
but it returned string with double quotes "\"warning"\", but we need string without double quotes "warning"

}

@NonNull
Expand Down
57 changes: 40 additions & 17 deletions spotbugs/src/main/java/edu/umd/cs/findbugs/sarif/Location.java
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,8 @@
import edu.umd.cs.findbugs.ba.SourceFile;
import edu.umd.cs.findbugs.ba.SourceFinder;
import edu.umd.cs.findbugs.util.ClassName;
import org.json.JSONObject;
import com.google.gson.JsonObject;
import com.google.gson.JsonArray;

import java.io.File;
import java.io.IOException;
Expand Down Expand Up @@ -52,12 +53,17 @@ PhysicalLocation getPhysicalLocation() {
return physicalLocation;
}

JSONObject toJSONObject() {
JSONObject result = new JSONObject();
JsonObject toJsonObject() {
JsonObject result = new JsonObject();
if (physicalLocation != null) {
result.put("physicalLocation", physicalLocation.toJSONObject());
result.add("physicalLocation", physicalLocation.toJsonObject());
}

JsonArray logicalLocationArray = new JsonArray();
logicalLocations.stream().map(LogicalLocation::toJsonObject).forEach(logicalLocation -> logicalLocationArray.add(logicalLocation));
if (logicalLocationArray.size() > 0) {
result.add("logicalLocations", logicalLocationArray);
}
logicalLocations.stream().map(LogicalLocation::toJSONObject).forEach(logicalLocation -> result.append("logicalLocations", logicalLocation));
return result;
}

Expand Down Expand Up @@ -118,8 +124,11 @@ static final class ArtifactLocation {
this.uriBaseId = uriBaseId;
}

JSONObject toJSONObject() {
return new JSONObject().put("uri", uri).putOpt("uriBaseId", uriBaseId);
JsonObject toJsonObject() {
JsonObject locationJson = new JsonObject();
locationJson.addProperty("uri", uri.toString());
locationJson.addProperty("uriBaseId", uriBaseId);
return locationJson;
}

static Optional<ArtifactLocation> fromBugAnnotation(@NonNull ClassAnnotation classAnnotation, @NonNull SourceLineAnnotation bugAnnotation,
Expand Down Expand Up @@ -205,11 +214,12 @@ static Optional<Region> fromBugAnnotation(SourceLineAnnotation annotation) {
}
}

JSONObject toJSONObject() {
JSONObject json = new JSONObject().put("startLine", startLine);
JsonObject toJsonObject() {
JsonObject json = new JsonObject();
json.addProperty("startLine", startLine);

if (endLine != 0) {
json = json.put("endLine", endLine);
json.addProperty("endLine", endLine);
}

return json;
Expand All @@ -230,10 +240,11 @@ static final class PhysicalLocation {
this.region = region;
}

JSONObject toJSONObject() {
JSONObject result = new JSONObject().put("artifactLocation", artifactLocation.toJSONObject());
JsonObject toJsonObject() {
JsonObject result = new JsonObject();
result.add("artifactLocation", artifactLocation.toJsonObject());
if (region != null) {
result.put("region", region.toJSONObject());
result.add("region", region.toJsonObject());
}
return result;
}
Expand Down Expand Up @@ -275,10 +286,22 @@ static final class LogicalLocation {
}
}

JSONObject toJSONObject() {
JSONObject propertiesBag = new JSONObject(properties);
return new JSONObject().put("name", name).putOpt("decoratedName", decoratedName).put("kind", kind).putOpt("fullyQualifiedName",
fullyQualifiedName).putOpt("properties", propertiesBag.isEmpty() ? null : propertiesBag);
JsonObject toJsonObject() {
JsonObject propertiesBag = new JsonObject();
properties.forEach((k, v) -> propertiesBag.addProperty(k, v));
JsonObject locationJson = new JsonObject();
locationJson.addProperty("name", name);
if (decoratedName != null) {
locationJson.addProperty("decoratedName", decoratedName);
}
locationJson.addProperty("kind", kind);
if (fullyQualifiedName != null) {
locationJson.addProperty("fullyQualifiedName", fullyQualifiedName);
}
if (propertiesBag != null && propertiesBag.size() > 0) {
locationJson.add("properties", propertiesBag);
}
return locationJson;
}

@NonNull
Expand Down
17 changes: 12 additions & 5 deletions spotbugs/src/main/java/edu/umd/cs/findbugs/sarif/Message.java
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
package edu.umd.cs.findbugs.sarif;

import edu.umd.cs.findbugs.annotations.NonNull;
import org.json.JSONObject;
import com.google.gson.JsonObject;
import com.google.gson.JsonArray;

import java.util.Collections;
import java.util.List;
Expand All @@ -19,10 +20,16 @@ final class Message {
this.arguments = Collections.unmodifiableList(Objects.requireNonNull(arguments));
}

JSONObject toJSONObject() {
JSONObject jsonObject = new JSONObject().put("id", "default");
for (Object arg : arguments) {
jsonObject.append("arguments", arg);
JsonObject toJsonObject() {
JsonObject jsonObject = new JsonObject();
jsonObject.addProperty("id", "default");

JsonArray jsonArray = new JsonArray();
for (String arg : arguments) {
jsonArray.add(arg);
}
if (jsonArray.size() > 0) {
jsonObject.add("arguments", jsonArray);
}
return jsonObject;
}
Expand Down
18 changes: 13 additions & 5 deletions spotbugs/src/main/java/edu/umd/cs/findbugs/sarif/Notification.java
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
import edu.umd.cs.findbugs.annotations.NonNull;
import edu.umd.cs.findbugs.annotations.Nullable;
import edu.umd.cs.findbugs.ba.SourceFinder;
import org.json.JSONObject;
import com.google.gson.JsonObject;

import java.net.URI;
import java.util.Map;
Expand All @@ -31,11 +31,19 @@ class Notification {
this.exception = exception;
}

JSONObject toJSONObject() {
JSONObject result = new JSONObject().put("descriptor", new JSONObject().put("id", id)).put("message", new JSONObject().put("text", message))
.put("level", level);
JsonObject toJsonObject() {
JsonObject descriptorJson = new JsonObject();
descriptorJson.addProperty("id", id);

JsonObject messageJson = new JsonObject();
messageJson.addProperty("text", message);

JsonObject result = new JsonObject();
result.add("descriptor", descriptorJson);
result.add("message", messageJson);
result.addProperty("level", level.toJsonString());
if (exception != null) {
result.put("exception", exception.toJSONObject());
result.add("exception", exception.toJsonObject());
}
return result;
}
Expand Down
20 changes: 14 additions & 6 deletions spotbugs/src/main/java/edu/umd/cs/findbugs/sarif/Result.java
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
package edu.umd.cs.findbugs.sarif;

import edu.umd.cs.findbugs.annotations.NonNull;
import org.json.JSONObject;

import com.google.gson.JsonObject;
import com.google.gson.JsonArray;
import java.util.Collections;
import java.util.List;
import java.util.Objects;
Expand All @@ -27,10 +27,18 @@ final class Result {
this.level = Objects.requireNonNull(level);
}

JSONObject toJSONObject() {
JSONObject result = new JSONObject().put("ruleId", ruleId).put("ruleIndex", ruleIndex).put("message", message.toJSONObject()).put("level",
level);
locations.stream().map(Location::toJSONObject).forEach(location -> result.append("locations", location));
JsonObject toJsonObject() {
JsonObject result = new JsonObject();
result.addProperty("ruleId", ruleId);
result.addProperty("ruleIndex", ruleIndex);
result.add("message", message.toJsonObject());
result.addProperty("level", level.toJsonString());

JsonArray locationArray = new JsonArray();
locations.stream().map(Location::toJsonObject).forEach(location -> locationArray.add(location));
if (locationArray.size() > 0) {
result.add("locations", locationArray);
}
return result;
}
}