Skip to content

Commit cf6aee8

Browse files
author
Francisco Solis
committed
DependencyDownloader Now Will Work With Any Repo!
1 parent 268db16 commit cf6aee8

File tree

5 files changed

+67
-90
lines changed

5 files changed

+67
-90
lines changed

src/main/kotlin/xyz/theprogramsrc/dependencydownloadermodule/DependencyDownloader.kt

Lines changed: 10 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@ package xyz.theprogramsrc.dependencydownloadermodule
33
import xyz.theprogramsrc.dependencydownloadermodule.objects.Dependency
44
import xyz.theprogramsrc.dependencydownloadermodule.objects.Repository
55
import xyz.theprogramsrc.filesmodule.utils.folder
6-
import xyz.theprogramsrc.simplecoreapi.libs.google.gson.JsonParser
76
import java.io.File
87
import java.net.URL
98
import java.security.MessageDigest
@@ -45,14 +44,15 @@ class DependencyDownloader {
4544
*/
4645
fun addRepository(repository: Repository) {
4746
val add = try {
48-
(JsonParser.parseString(URL("${if(repository.host.startsWith("http")) repository.host else "https://${repository.host}"}/service/rest/swagger.json").readText()).asJsonObject.get("info").asJsonObject.get("version").asString.substring(0,1).toIntOrNull() ?: 0) >= 3
49-
}catch (e: Exception) {
47+
URL(repository.url)
48+
true
49+
} catch (e: Exception) {
5050
false
5151
}
5252
if(add) {
5353
repositories.add(repository)
5454
} else {
55-
logger.severe("Repository ${repository.host} must be a supported repository!")
55+
logger.severe("Repository ${repository.url} must hava a valid url!")
5656
}
5757
}
5858

@@ -67,15 +67,14 @@ class DependencyDownloader {
6767
val file = File(File(librariesFolder, dependency.group.replace(".", "/")).folder(), "${dependency.artifactId}-${dependency.version}.jar")
6868
if(isLoaded(dependency)) return file
6969
if(!file.exists()){
70-
val repo = repositories.find { repo -> repo.findArtifact(dependency) != null } ?: return null
71-
val artifactData = repo.findArtifact(dependency) ?: return null
70+
val repo = repositories.firstOrNull { it.findArtifact(dependency) != null } ?: return null
71+
val artifactUrl = repo.findArtifact(dependency) ?: return null
7272
digest.reset()
73-
val downloadBytes = URL(artifactData.get("url").asString).readBytes()
74-
val md5 = if(artifactData.has("md5")) artifactData.get("md5").asString else null
75-
if(md5 != null){
73+
val downloadBytes = URL(artifactUrl).readBytes()
74+
if(dependency.md5Hash != null){
7675
val downloadMd5 = digest.digest(downloadBytes).joinToString("") { "%02x".format(it) }
77-
if(downloadMd5 != md5){
78-
logger.severe("MD5 mismatch for ${dependency.group}:${dependency.artifactId}! Expected: '$md5', Got: '$downloadMd5'")
76+
if(downloadMd5 != dependency.md5Hash){
77+
logger.severe("MD5 mismatch for ${dependency.group}:${dependency.artifactId}! Expected: '${dependency.md5Hash}', Got: '$downloadMd5'")
7978
return null
8079
}
8180
}
Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,10 @@
11
package xyz.theprogramsrc.dependencydownloadermodule.objects
22

3-
data class Dependency(val group: String, val artifactId: String, val version: String)
3+
/**
4+
* Representation of Dependency
5+
* @param group The group id of the dependency
6+
* @param artifactId The artifact id of the dependency
7+
* @param version The version of the dependency
8+
* @param md5Hash The md5 hash of the dependency, if null the downloader will not check the md5 hash (Which is not recommended)
9+
*/
10+
data class Dependency(val group: String, val artifactId: String, val version: String, val md5Hash: String? = null)
Lines changed: 46 additions & 75 deletions
Original file line numberDiff line numberDiff line change
@@ -1,98 +1,69 @@
11
package xyz.theprogramsrc.dependencydownloadermodule.objects
22

33
import org.json.XML
4-
import xyz.theprogramsrc.simplecoreapi.libs.google.gson.JsonObject
54
import xyz.theprogramsrc.simplecoreapi.libs.google.gson.JsonParser
65
import java.net.URL
76

87
/**
98
* Representation of a Repository
10-
* @param host The host of the repository
11-
* @param repository The repository id in the host
9+
* @param url The url of the repository. Example: https://repo1.maven.org/maven2/
1210
*/
13-
data class Repository(val host: String, val repository: String) {
11+
data class Repository(val url: String) {
1412

15-
/**
16-
* Checks if the repository is a Sonatype Nexus Repository
17-
* @param requiredVersion The required version of Nexus
18-
* @return true if the repository is a Sonatype Nexus Repository, false otherwise
19-
*/
20-
fun isNexus(requiredVersion: Int = 3): Boolean = if(requiredVersion == 3) {
21-
try {
22-
(JsonParser.parseString(URL("${if(host.startsWith("http")) host else "https://${host}"}/service/rest/swagger.json").readText()).asJsonObject.get("info").asJsonObject.get("version").asString.substring(0,1).toIntOrNull() ?: 0) >= 3
23-
}catch (e: Exception) {
24-
false
25-
}
26-
}else if(requiredVersion == 2) {
27-
// TODO: Check if the repository is a Sonatype Nexus Repository v2
28-
false
29-
} else{
30-
false // Unknown or older versions
31-
}
13+
private val mavenUrlFormat = "%s/%s/%s/%s-%s.jar"
3214

3315
/**
34-
* Finds the artifact and returns a JsonObject with the url, version and md5 hash if available
35-
* @return A [JsonObject] with the information, null if not found
16+
* Finds the artifact url to download
17+
* @return The artifact url to download
3618
*/
37-
fun findArtifact(dependency: Dependency): JsonObject? {
38-
if(isNexus(3)) {
39-
val host = if(this.host.startsWith("http")) this.host else "https://${this.host}"
40-
val version = try {
41-
if (dependency.version.endsWith("-SNAPSHOT")) {
42-
val json = JsonParser.parseString(XML.toJSONObject(URL("$host/repository/$repository/${dependency.group.replace(".", "/")}/${dependency.artifactId}/${dependency.version}/maven-metadata.xml").readText()).toString())
19+
fun findArtifact(dependency: Dependency): String? {
20+
return try {
21+
val parsedVersion = if(dependency.version.endsWith("-SNAPSHOT")){
22+
parseSnapshotVersion(dependency)
23+
} else if(dependency.version == "LATEST") {
24+
try {
25+
val result = JsonParser.parseString(XML.toJSONObject(URL("$url/${rewriteEscaping(dependency.group).replace('.','/')}/${dependency.artifactId}/maven-metadata.xml").readText()).toString())
4326
.asJsonObject
4427
.getAsJsonObject("metadata")
4528
.getAsJsonObject("versioning")
46-
.getAsJsonObject("snapshot")
47-
dependency.version.replace("-SNAPSHOT", "-${json.get("timestamp").asString}-${json.get("buildNumber").asString}")
48-
} else {
49-
dependency.version
50-
}
51-
}catch (e: Exception) {
52-
e.printStackTrace()
53-
null
54-
} ?: return null
55-
56-
val items = JsonParser.parseString(URL("$host/service/rest/v1/search?repository=$repository&group=${dependency.group}&format=maven2&maven.artifactId=${dependency.artifactId}&maven.extension=jar&sort=version&version=$version").readText()).asJsonObject.get("items").asJsonArray
57-
val item = items.firstOrNull { it.asJsonObject.get("version").asString == version } ?: return null
58-
val found = item.asJsonObject.get("assets").asJsonArray.firstOrNull {
59-
if(!it.asJsonObject.get("maven2").asJsonObject.get("version").asString.equals(version)) {
60-
return@firstOrNull false // Check that the current version matches
61-
}
62-
63-
if(!it.asJsonObject.get("maven2").asJsonObject.get("extension").asString.equals("jar")){
64-
return@firstOrNull false // Check that this is a jar file (not checksums or pom)
65-
}
66-
67-
if(it.asJsonObject.get("maven2").asJsonObject.has("classifier")){
68-
if(it.asJsonObject.get("maven2").asJsonObject.get("classifier").asString.equals("sources")){
69-
return@firstOrNull false // Check that this is not a sources jar file
70-
}
71-
72-
if(it.asJsonObject.get("maven2").asJsonObject.get("classifier").asString.equals("javadoc")){
73-
return@firstOrNull false // Check that this is not a javadoc jar file
29+
.get("latest")
30+
.asString
31+
if(result.endsWith("-SNAPSHOT")) {
32+
parseSnapshotVersion(Dependency(dependency.group, dependency.artifactId, result, dependency.md5Hash))
33+
}else {
34+
result
7435
}
36+
}catch (e: Exception){
37+
null
7538
}
39+
}else{
40+
dependency.version
41+
} ?: return null
7642

77-
if(!it.asJsonObject.get("maven2").asJsonObject.get("artifactId").asString.equals(dependency.artifactId)) {
78-
return@firstOrNull false // Check that this is the correct artifact
79-
}
80-
81-
if(!it.asJsonObject.get("contentType").asString.equals("application/java-archive")){
82-
return@firstOrNull false // Check that this is a jar file
83-
}
84-
85-
return@firstOrNull true
86-
}?.asJsonObject ?: return null
87-
val json = JsonObject()
88-
json.addProperty("url", found.get("downloadUrl").asString)
89-
if(found.has("md5")){
90-
json.addProperty("md5", found.get("md5").asString)
91-
}
92-
json.addProperty("version", version)
93-
return json
43+
val result = url + String.format(mavenUrlFormat,
44+
rewriteEscaping(dependency.group).replace('.', '/'),
45+
rewriteEscaping(dependency.artifactId),
46+
dependency.version,
47+
rewriteEscaping(dependency.artifactId),
48+
parsedVersion
49+
)
50+
URL(result)
51+
result
52+
}catch (e: Exception){
53+
null
9454
}
55+
}
56+
57+
private fun rewriteEscaping(data: String) = data.replace("{}", ".")
9558

96-
return null
59+
private fun parseSnapshotVersion(dependency: Dependency): String? = try {
60+
val json = JsonParser.parseString(XML.toJSONObject(URL("$url/${rewriteEscaping(dependency.group).replace('.','/')}/${dependency.artifactId}/${dependency.version}/maven-metadata.xml").readText()).toString())
61+
.asJsonObject
62+
.getAsJsonObject("metadata")
63+
.getAsJsonObject("versioning")
64+
.getAsJsonObject("snapshot")
65+
dependency.version.replace("-SNAPSHOT", "-${json.get("timestamp").asString}-${json.get("buildNumber").asString}")
66+
}catch (e: Exception){
67+
null
9768
}
9869
}

src/test/kotlin/xyz/theprogramsrc/dependencydownloadermodule/objects/DependencyTest.kt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,8 @@ internal class DependencyTest {
1010

1111
@Test
1212
fun nexusDependencyDownloadTest(){
13-
val repo = Repository("https://repo.theprogramsrc.xyz", "maven-public")
14-
val dependency = Dependency("cl.franciscosolis", "DiscordBotBase", "4.0.0-SNAPSHOT")
13+
val repo = Repository("https://repo.theprogramsrc.xyz/repository/maven-public/")
14+
val dependency = Dependency("cl.franciscosolis", "DiscordBotBase", "4.0.0-SNAPSHOT", "9e30f48ce1a9c11d2f64e223d9def2fd")
1515
val downloader = DependencyDownloader()
1616
downloader.addRepository(repo)
1717
val file = downloader.loadDependency(dependency)

src/test/kotlin/xyz/theprogramsrc/dependencydownloadermodule/objects/RepositoryTest.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,6 @@ internal class RepositoryTest {
77

88
@Test
99
fun findArtifact(){
10-
assertNotNull(Repository("https://repo.theprogramsrc.xyz", "maven-public").findArtifact(Dependency("xyz.theprogramsrc", "simplecoreapi", "0.1.10-SNAPSHOT")))
10+
assertNotNull(Repository("https://repo.theprogramsrc.xyz/repository/maven-public/").findArtifact(Dependency("xyz.theprogramsrc", "simplecoreapi", "0.1.10-SNAPSHOT")))
1111
}
1212
}

0 commit comments

Comments
 (0)