|
20 | 20 | package org.ossreviewtoolkit.model |
21 | 21 |
|
22 | 22 | 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 |
23 | 29 |
|
24 | 30 | import org.ossreviewtoolkit.model.config.RepositoryConfiguration |
25 | 31 | import org.ossreviewtoolkit.utils.ort.ORT_REPO_CONFIG_FILENAME |
26 | 32 |
|
27 | 33 | /** |
28 | 34 | * A description of the source code repository that was used as input for ORT. |
29 | 35 | */ |
| 36 | +@JsonDeserialize(using = RepositoryDeserializer::class) |
30 | 37 | data class Repository( |
31 | 38 | /** |
32 | 39 | * Provenance wrapper for original VCS information, if present. |
@@ -74,3 +81,38 @@ data class Repository( |
74 | 81 | return nestedRepositories.entries.find { (_, nestedVcs) -> nestedVcs.normalize().matches(normalizedVcs) }?.key |
75 | 82 | } |
76 | 83 | } |
| 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