Skip to content

Commit 2301ab2

Browse files
committed
fix(Repository): Add RepositoryDeserializer to support legacy attributes
With the `provenance` attribute replacing `vcs` and `vcsProcessed`, legacy `OrtResult` files containing the prior attributes will fail to parse with the default Deserializer. Therefore a custom Deserializer with support for both formats is required. Signed-off-by: Jens Keim <[email protected]>
1 parent 101b10c commit 2301ab2

File tree

1 file changed

+42
-0
lines changed

1 file changed

+42
-0
lines changed

model/src/main/kotlin/Repository.kt

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,13 +20,20 @@
2020
package org.ossreviewtoolkit.model
2121

2222
import com.fasterxml.jackson.annotation.JsonInclude
23+
import com.fasterxml.jackson.core.JsonParser
24+
import com.fasterxml.jackson.databind.DeserializationContext
25+
import com.fasterxml.jackson.databind.JsonNode
26+
import com.fasterxml.jackson.databind.annotation.JsonDeserialize
27+
import com.fasterxml.jackson.databind.deser.std.StdDeserializer
28+
import com.fasterxml.jackson.module.kotlin.treeToValue
2329

2430
import org.ossreviewtoolkit.model.config.RepositoryConfiguration
2531
import org.ossreviewtoolkit.utils.ort.ORT_REPO_CONFIG_FILENAME
2632

2733
/**
2834
* A description of the source code repository that was used as input for ORT.
2935
*/
36+
@JsonDeserialize(using = RepositoryDeserializer::class)
3037
data class Repository(
3138
/**
3239
* Provenance wrapper for original VCS information, if present.
@@ -74,3 +81,38 @@ data class Repository(
7481
return nestedRepositories.entries.find { (_, nestedVcs) -> nestedVcs.normalize().matches(normalizedVcs) }?.key
7582
}
7683
}
84+
85+
/**
86+
* A custom deserializer for [Repository] to support the legacy [vcs] and [vcsProcessed] attributes.
87+
*/
88+
private class RepositoryDeserializer : StdDeserializer<Repository>(Repository::class.java) {
89+
override fun deserialize(p: JsonParser, ctxt: DeserializationContext): Repository {
90+
val node = p.codec.readTree<JsonNode>(p)
91+
val parsedProvenance = when {
92+
node.has("vcs") -> {
93+
// Parse [vcs] and [vcsProcessed] attributes
94+
val vcsInfo = jsonMapper.treeToValue<VcsInfo>(node["vcs"])
95+
val vcsProcess = jsonMapper.treeToValue<VcsInfo>(node["vcs_processed"])
96+
97+
// Get the [vcs]'s revision
98+
val resolvedRevision = if (vcsInfo.revision != "") {
99+
vcsInfo.revision
100+
} else if (vcsProcess.revision != "") {
101+
// Fall back to [vcsProcessed], if [vcs] has empty revision
102+
vcsProcess.revision
103+
} else {
104+
HashAlgorithm.SHA1.emptyValue
105+
}
106+
107+
// Build a RepositoryProvenance from the parsed VcsInfo fields
108+
RepositoryProvenance(vcsInfo, resolvedRevision)
109+
}
110+
111+
else -> {
112+
// Parse the [provenance], if no legacy fields are present
113+
jsonMapper.treeToValue<RepositoryProvenance>(node["provenance"])
114+
}
115+
}
116+
return Repository(provenance = parsedProvenance)
117+
}
118+
}

0 commit comments

Comments
 (0)