MavenToCpeMapper.kt
package com.depanalyzer.repository
object MavenToCpeMapper {
private val KNOWN_MAPPINGS = mapOf(
"junit:junit" to "junit:junit",
"org.junit:junit" to "junit:junit",
"org.junit.jupiter:junit-jupiter-api" to "junit:junit",
"org.junit.jupiter:junit-jupiter-engine" to "junit:junit",
"org.junit.vintage:junit-vintage-engine" to "junit:junit",
"org.mockito:mockito-core" to "mockito:mockito",
"org.mockito:mockito-all" to "mockito:mockito",
"org.apache.logging.log4j:log4j-core" to "apache:log4j",
"org.apache.logging.log4j:log4j-api" to "apache:log4j",
"org.slf4j:slf4j-api" to "slf4j:slf4j",
"org.slf4j:slf4j-simple" to "slf4j:slf4j",
"org.springframework:spring-core" to "springframework:spring",
"org.springframework:spring-beans" to "springframework:spring",
"org.springframework.boot:spring-boot-starter" to "springframework:spring_boot",
"com.fasterxml.jackson.core:jackson-databind" to "fasterxml:jackson_databind",
"com.fasterxml.jackson.core:jackson-core" to "fasterxml:jackson_core",
"com.google.guava:guava" to "google:guava",
"com.squareup.okhttp3:okhttp" to "squareup:okhttp",
"com.google.code.gson:gson" to "google:gson",
"org.projectlombok:lombok" to "projectlombok:lombok"
)
fun mapToCpe(groupId: String, artifactId: String, version: String): String {
val key = "$groupId:$artifactId"
val knownMapping = KNOWN_MAPPINGS[key]
if (knownMapping != null) {
val (vendor, product) = knownMapping.split(":")
return buildCpe(vendor, product, version)
}
val vendor = extractVendor(groupId)
val product = extractProduct(artifactId)
return buildCpe(vendor, product, version)
}
private fun extractVendor(groupId: String): String {
val parts = groupId.split(".")
return when {
parts.size == 1 -> parts[0].lowercase()
"apache" in parts -> "apache"
"springframework" in parts -> "springframework"
"junit" in parts -> "junit"
"google" in parts -> "google"
"squareup" in parts -> "squareup"
"fasterxml" in parts -> "fasterxml"
"slf4j" in parts -> "slf4j"
parts.size >= 2 -> parts[parts.size - 2].lowercase()
else -> parts.last().lowercase()
}
}
private fun extractProduct(artifactId: String): String {
var product = artifactId.lowercase()
product = product.replace(Regex("-?v?\\d+$"), "")
product = when {
product.endsWith("-starter") -> product.dropLast("-starter".length)
product.endsWith("-client") -> product.dropLast("-client".length)
product.endsWith("-core") && product != "jackson-core" -> product.dropLast("-core".length)
else -> product
}
product = product.replace("-", "_")
return product
}
private fun buildCpe(vendor: String, product: String, version: String): String {
return "cpe:2.3:a:$vendor:$product:$version:*:*:*:*:*:*:*"
}
}