2020package org.ossreviewtoolkit.model
2121
2222import 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
2430import org.ossreviewtoolkit.model.config.RepositoryConfiguration
2531import 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 )
3037data class Repository (
3138 /* *
3239 * Provenance wrapper for original VCS information, if present.
3340 */
3441 val provenance : RepositoryProvenance ,
3542
36- /* *
37- * Original VCS-related information from the working tree containing the analyzer root.
38- */
39- val vcs : VcsInfo = provenance.vcsInfo,
40-
41- /* *
42- * Processed VCS-related information from the working tree containing the analyzer root that has e.g. common
43- * mistakes corrected.
44- */
45- val vcsProcessed : VcsInfo = vcs.normalize(),
46-
4743 /* *
4844 * A map of nested repositories, for example Git submodules or Git-Repo modules. The key is the path to the
4945 * nested repository relative to the root of the main repository.
@@ -66,8 +62,6 @@ data class Repository(
6662 vcsInfo = VcsInfo .EMPTY ,
6763 resolvedRevision = HashAlgorithm .SHA1 .emptyValue
6864 ),
69- vcs = VcsInfo .EMPTY ,
70- vcsProcessed = VcsInfo .EMPTY ,
7165 nestedRepositories = emptyMap(),
7266 config = RepositoryConfiguration ()
7367 )
@@ -82,8 +76,57 @@ data class Repository(
8276
8377 val normalizedVcs = vcs.normalize()
8478
85- if (vcsProcessed .matches(normalizedVcs)) return " "
79+ if (provenance.vcsInfo.normalize() .matches(normalizedVcs)) return " "
8680
8781 return nestedRepositories.entries.find { (_, nestedVcs) -> nestedVcs.normalize().matches(normalizedVcs) }?.key
8882 }
8983}
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 vcs = jsonMapper.treeToValue<VcsInfo >(node[" vcs" ])
95+ val vcsProcess = jsonMapper.treeToValue<VcsInfo >(node[" vcs_processed" ])
96+
97+ // Fall back to [vcsProcessed], if [vcs] is empty.
98+ val vcsInfo = if (vcs != VcsInfo .EMPTY ) vcs else vcsProcess
99+
100+ // Get the [vcs]'s revision.
101+ // Fall back to [vcsProcessed], if [vcs] has empty revision.
102+ val resolvedRevision = vcs.revision.ifEmpty {
103+ vcsProcess.revision.ifEmpty {
104+ HashAlgorithm .SHA1 .emptyValue
105+ }
106+ }
107+
108+ // Build a RepositoryProvenance from the parsed VcsInfo fields.
109+ RepositoryProvenance (vcsInfo, resolvedRevision)
110+ }
111+
112+ else -> {
113+ // Parse the [provenance], if no legacy fields are present.
114+ jsonMapper.treeToValue<RepositoryProvenance >(node[" provenance" ])
115+ }
116+ }
117+
118+ val nestedRepositories = if (node.has(" nested_repositories" )) {
119+ jsonMapper.treeToValue<Map <String , VcsInfo >>(node[" nested_repositories" ])
120+ } else {
121+ emptyMap()
122+ }
123+
124+ val config = if (node.has(" config" )) {
125+ jsonMapper.treeToValue<RepositoryConfiguration >(node[" config" ])
126+ } else {
127+ RepositoryConfiguration ()
128+ }
129+
130+ return Repository (provenance = parsedProvenance, nestedRepositories, config)
131+ }
132+ }
0 commit comments