Skip to content

Commit

Permalink
LicenseFinding: Add a custom deserializer
Browse files Browse the repository at this point in the history
The current approach of using multiple `@JsonCreator` annotations is wrong,
because Jackson supports only on creator function [1]. Replace it with a
custom deserializer because upcoming changes to `LicenseFinding` will make
it more complex to support old versions of the class.

[1] FasterXML/jackson-databind#421 (comment)

Signed-off-by: Martin Nonnenmacher <[email protected]>
  • Loading branch information
mnonnenmacher committed Jan 16, 2019
1 parent ba8c01a commit dce06c4
Show file tree
Hide file tree
Showing 5 changed files with 28 additions and 8 deletions.
29 changes: 24 additions & 5 deletions model/src/main/kotlin/LicenseFinding.kt
Original file line number Diff line number Diff line change
Expand Up @@ -19,11 +19,16 @@

package com.here.ort.model

import com.fasterxml.jackson.annotation.JsonCreator
import com.fasterxml.jackson.core.JsonParser
import com.fasterxml.jackson.databind.DeserializationContext
import com.fasterxml.jackson.databind.JsonNode
import com.fasterxml.jackson.databind.deser.std.StdDeserializer
import com.fasterxml.jackson.module.kotlin.treeToValue

import com.here.ort.model.config.CopyrightGarbage
import com.here.ort.utils.CopyrightStatementsProcessor
import com.here.ort.utils.SortedSetComparator
import com.here.ort.utils.textValueOrEmpty

import java.util.SortedMap
import java.util.SortedSet
Expand Down Expand Up @@ -51,20 +56,34 @@ fun LicenseFindingsMap.removeGarbage(copyrightGarbage: CopyrightGarbage) =
* A class to store a [license] finding along with its belonging [copyrights]. To support deserializing older versions
* of this class which did not include the copyrights a secondary constructor is only taking a [licenseName].
*/
data class LicenseFinding @JsonCreator constructor(
data class LicenseFinding(
val license: String,
val copyrights: SortedSet<String>
) : Comparable<LicenseFinding> {
companion object {
private val COPYRIGHTS_COMPARATOR = SortedSetComparator<String>()
}

@JsonCreator
constructor(licenseName: String) : this(licenseName, sortedSetOf())

override fun compareTo(other: LicenseFinding) =
when {
license != other.license -> license.compareTo(other.license)
else -> COPYRIGHTS_COMPARATOR.compare(copyrights, other.copyrights)
}
}

/**
* Custom deserializer to support old versions of the [LicenseFinding] class.
*/
class LicenseFindingDeserializer : StdDeserializer<LicenseFinding>(LicenseFinding::class.java) {
override fun deserialize(p: JsonParser, ctxt: DeserializationContext): LicenseFinding {
val node = p.codec.readTree<JsonNode>(p)
return when {
node.isTextual -> LicenseFinding(node.textValueOrEmpty(), sortedSetOf())
else -> {
val license = jsonMapper.treeToValue<String>(node["license"])
val copyrights = jsonMapper.treeToValue<SortedSet<String>>(node["copyrights"])
return LicenseFinding(license, copyrights)
}
}
}
}
1 change: 1 addition & 0 deletions model/src/main/kotlin/Mappers.kt
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ import com.here.ort.model.config.AnalyzerConfigurationDeserializer

private val ortModelModule = SimpleModule("OrtModelModule").apply {
addDeserializer(AnalyzerConfiguration::class.java, AnalyzerConfigurationDeserializer())
addDeserializer(LicenseFinding::class.java, LicenseFindingDeserializer())
addDeserializer(OrtIssue::class.java, OrtIssueDeserializer())
addDeserializer(VcsInfo::class.java, VcsInfoDeserializer())

Expand Down
2 changes: 1 addition & 1 deletion scanner/src/main/kotlin/scanners/Askalono.kt
Original file line number Diff line number Diff line change
Expand Up @@ -157,7 +157,7 @@ class Askalono(config: ScannerConfiguration) : LocalScanner(config) {
}

override fun generateSummary(startTime: Instant, endTime: Instant, result: JsonNode): ScanSummary {
val findings = result.map { LicenseFinding(it["License"].textValue()) }.toSortedSet()
val findings = result.map { LicenseFinding(it["License"].textValue(), sortedSetOf()) }.toSortedSet()
return ScanSummary(startTime, endTime, result.size(), findings, errors = mutableListOf())
}
}
2 changes: 1 addition & 1 deletion scanner/src/main/kotlin/scanners/BoyterLc.kt
Original file line number Diff line number Diff line change
Expand Up @@ -167,7 +167,7 @@ class BoyterLc(config: ScannerConfiguration) : LocalScanner(config) {

result.forEach { file ->
file["LicenseGuesses"].mapTo(findings) { license ->
LicenseFinding(license["LicenseId"].textValue())
LicenseFinding(license["LicenseId"].textValue(), sortedSetOf())
}
}

Expand Down
2 changes: 1 addition & 1 deletion scanner/src/main/kotlin/scanners/Licensee.kt
Original file line number Diff line number Diff line change
Expand Up @@ -138,7 +138,7 @@ class Licensee(config: ScannerConfiguration) : LocalScanner(config) {
val matchedFiles = result["matched_files"]

val findings = matchedFiles.map {
LicenseFinding(it["matched_license"].textValue())
LicenseFinding(it["matched_license"].textValue(), sortedSetOf())
}.toSortedSet()

return ScanSummary(startTime, endTime, matchedFiles.count(), findings, errors = mutableListOf())
Expand Down

0 comments on commit dce06c4

Please sign in to comment.